passgit.bash 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #!/bin/bash
  2. #------------------------------------------------------------------------------
  3. # Wrapper around git for pushing and pulling repositories. Using the 'pass'
  4. # password manager, it automatically inserts your token for authentication
  5. # (prompting for your password if required).
  6. #
  7. # TODO:
  8. # - Add autocompletion
  9. # - Expand to handle passwords and usernames
  10. # - Output a menu containing a password list, to allow for usage with an alias
  11. # or function (i.e "alias gpush='passgit -l $names && git push'")
  12. # - Remove error messages when there is nothing to commit or when there is
  13. # conflicting changes
  14. #
  15. # Dependencies:
  16. # - getopt
  17. # - pass
  18. # - expect
  19. #------------------------------------------------------------------------------
  20. shopt -s extglob
  21. die() { echo "$(basename $0): $@" && exit 1 ;}
  22. usage() {
  23. cat <<-USAGE
  24. Usage: passgit [push|pull]
  25. Automate pushing and pulling with the notes repository.
  26. Automatically prompts for password to
  27. push Pushes changes to git repository.
  28. pull Pull changes to git repository.
  29. -p Specify the password name
  30. -h prints this help message
  31. USAGE
  32. exit ${1}
  33. }
  34. if [[ $(getopt -T ; echo $?) != 4 ]] ; then
  35. die "$(cat <<-GETOPT_ERR_MSG_END
  36. Your getopt is not the enhanced version. Please install a more recent version
  37. version of getopt.
  38. GETOPT_ERR_MSG_END
  39. )"
  40. fi
  41. git rev-parse --is-inside-work-tree &>/dev/null || die 'directory is not a git repo.'
  42. command -v pass &>/dev/null || die 'pass command not found in PATH'
  43. declare action passname
  44. declare short='hn:' long='help,password-name:'
  45. declare parsed=$(getopt -o $short -l $long -n $0 -- "${@}")
  46. [[ $? != 0 ]] && die "Try $0 -h for more information"
  47. eval set -- "$parsed"
  48. while true ; do
  49. case "$1" in
  50. -n|--password-name)
  51. passname="$2"
  52. shift 2
  53. ;;
  54. --)
  55. shift
  56. break
  57. ;;
  58. -h|--help) usage 0 ;;
  59. *) die 'Internal Error' ;;
  60. esac
  61. done
  62. [[ -z "$passname" ]] && die 'Please specify a password name with the -p option.'
  63. [[ -z "$1" ]] && die "Missing action"
  64. [[ "$1" != @(push|pull) ]] && die "Invalid action '$1'"
  65. action=$1
  66. # Expect script to automate token insertion
  67. expect <(cat <<-EOF
  68. set timeout -1
  69. set token [exec pass $passname]
  70. spawn git $action
  71. expect {
  72. "Already up to date." { expect eof }
  73. -re "Username for 'https://.*':" {
  74. send "\${token}\r"
  75. exp_continue
  76. }
  77. -re "Password for 'https://.*':" {
  78. send "\r"
  79. expect eof
  80. }
  81. }
  82. EOF
  83. )