gimme 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. #!/bin/bash
  2. # A meta micro manager for the masses.
  3. # USAGE:
  4. # gimme [-f|--force] stuff
  5. # gimme [-l|--list|--installed]
  6. # gimme [--old|--outdated]
  7. # gimme [-v|--verbose|--debug]
  8. # gimme [-h|--help|help]
  9. ###############################################################################
  10. [ "$GIMME_URL" ] || export GIMME_URL="https://github.com/KylePDavis/gimme"
  11. [ "$GIMME_DIR" ] || export GIMME_DIR="$HOME/.gimme"
  12. [ "$GIMME_GIMMES_DIR" ] || export GIMME_GIMMES_DIR="$GIMME_DIR/gimmes"
  13. [ "$GIMME_LINK" ] || export GIMME_LINK="$HOME/bin/gimme"
  14. [ "$GIMME_LINK_DIR" ] || export GIMME_LINK_DIR=$(dirname "$GIMME_LINK")
  15. [ "$GIMMES" ] || export GIMMES=""
  16. [ "$INIT_GIMMES" ] || export INIT_GIMMES=""
  17. [ "$OS" ] || export OS=$(uname -s)
  18. [ "$DEBUG" ] || export DEBUG=
  19. [ "$FORCE" ] || export FORCE=
  20. ###############################################################################
  21. ! [[ "$DEBUG" ]] || set -x
  22. has() {
  23. if [[ "$FORCE" ]] && echo " $INIT_GIMMES " | grep -q " $1 "; then
  24. false
  25. else
  26. which "$1" >/dev/null
  27. fi
  28. }
  29. gimme_pkg() {
  30. if [[ "$OS" = "Darwin" ]]; then
  31. if ! has brew; then
  32. has curl || gimme_pkg curl
  33. [[ -d "$HOME/homebrew" ]] || (mkdir "$HOME/homebrew" 2>/dev/null && curl -L "https://github.com/Homebrew/homebrew/tarball/master" | tar xz --strip 1 -C "$HOME/homebrew" && "$HOME/homebrew/bin/brew" update)
  34. fi
  35. if [[ "$1" ]]; then
  36. if brew cask cat "$1" &>/dev/null; then
  37. if brew cask list "$1" &>/dev/null; then
  38. if [[ "$FORCE" ]]; then
  39. brew cask reinstall "$@"
  40. else
  41. echo "# SKIPPED: $GIMME (force reinstall/upgrade via: gimme -f $GIMME)"
  42. fi
  43. else
  44. brew cask install "$@"
  45. fi
  46. elif brew cat "$1" &>/dev/null; then
  47. if brew list "$1" &>/dev/null; then
  48. if [[ "$FORCE" ]]; then
  49. brew upgrade "$@" || echo "# WARN: forced upgrade failed (it may already be up to date)"
  50. else
  51. echo "# SKIPPED: $GIMME (force upgrade via: gimme -f $GIMME)"
  52. fi
  53. else
  54. brew install "$@"
  55. fi
  56. else
  57. brew search "$1"
  58. fi
  59. fi
  60. else
  61. if ! has apt-get; then
  62. echo "ERROR: Your OS does not have 'apt-get' and is not currently supported."
  63. echo "For support please see the website: $GIMME_URL"
  64. fi
  65. if [[ "$1" ]]; then
  66. sudo apt-get -y install "$@"
  67. fi
  68. fi
  69. }
  70. if [[ "$0" =~ [-]?bash ]]; then # sourced or piped
  71. if [[ "${BASH_SOURCE[@]}" ]]; then # sourced
  72. # if 'gimme' is not Add gimme to the PATH if not already found
  73. if ! [[ "$PATH" == *"$GIMME_DIR"* ]]; then
  74. export PATH="$PATH:$GIMME_DIR"
  75. fi
  76. # setup autocompletion for gimmes
  77. _gimme_completely() {
  78. if [[ "$2" = -* ]]; then
  79. COMPREPLY=( $(compgen -W "-v --verbose --debug --force --version --help -l --list --installed --old --outdated" -- "$2") )
  80. else
  81. COMPREPLY=( $(cd "$GIMME_GIMMES_DIR"; find . -path "./$2*" \! -type d \! -name '.*' \! -name '_*' | cut -c3- ) )
  82. fi
  83. }
  84. complete -F _gimme_completely gimme
  85. else # piped
  86. set -o errexit -o pipefail
  87. # gimmes/gcc: inlined for curl-based installs
  88. if [[ "$OS" = "Darwin" ]]; then
  89. if ! "xcode-select" --version &>/dev/null; then
  90. echo "Try again after installing the Xcode command-line tools by running: xcode-select --install"
  91. exit 1
  92. fi
  93. if ! xcodebuild -help &>/dev/null; then
  94. echo "Try again after agreeing to the Xcode license by running: sudo xcodebuild -license"
  95. exit 1
  96. fi
  97. else
  98. has gcc || gimme_pkg build-essential
  99. fi
  100. # gimmes/git: inlined for curl-based installs
  101. has git || gimme_pkg git
  102. if ! [[ -d "$GIMME_DIR" ]]; then
  103. echo "Installing $GIMME_DIR/gimme ..."
  104. mkdir -p "$GIMME_DIR"
  105. git clone "$GIMME_URL" "$GIMME_DIR"
  106. mkdir -p "$(dirname "$GIMME_LINK")"
  107. ln -sf "$GIMME_DIR/gimme" "$GIMME_LINK"
  108. echo "Done! Now you can 'gimme stuff' or 'gimme dev/stuff' or even 'gimme gimme'!"
  109. else
  110. echo "Updating gimme (in $GIMME_DIR) ..."
  111. cd "$GIMME_DIR"
  112. OLD_REV=$(git rev-parse HEAD)
  113. git pull
  114. git log --oneline "$OLD_REV.."
  115. fi
  116. fi
  117. else # normal usage
  118. set -o errexit -o pipefail
  119. export -f has gimme_pkg
  120. [[ "$INIT_GIMMES" ]] || export INIT_GIMMES="$@"
  121. DID_GIMME=
  122. for GIMME; do
  123. case "$GIMME" in
  124. -v|--verbose|--debug)
  125. DEBUG=1
  126. continue
  127. ;;
  128. -f|--force)
  129. FORCE=1
  130. continue
  131. ;;
  132. --version)
  133. echo "Version:"
  134. git log -1
  135. exit 0
  136. ;;
  137. -h|--help|"")
  138. sed -n -e'/^#[[:space:]]/p' -e'/^###/q' "$0"
  139. echo "# GIMMES:"
  140. echo $(cd "$GIMME_GIMMES_DIR"; find . -type f -perm +1 | sed -e's/^..//' -e'/^_/d' | sort)
  141. exit 0
  142. ;;
  143. -l|--list|--installed)
  144. echo "# BREW (cask):"
  145. brew cask list
  146. echo
  147. echo "# BREW:"
  148. brew list
  149. echo
  150. echo "# NPM:"
  151. npm -g ls --depth 0
  152. echo
  153. echo "# PIP:"
  154. pip list --format=columns
  155. exit 0
  156. ;;
  157. --old|--outdated)
  158. echo "# BREW (cask):"
  159. brew cask outdated
  160. echo
  161. echo "# BREW:"
  162. brew outdated
  163. echo
  164. echo "# NPM:"
  165. npm outdated -g --depth 0
  166. echo
  167. echo "# PIP:"
  168. pip list --format=columns --outdated
  169. exit 0
  170. ;;
  171. -*)
  172. echo "# ERROR: Unknown option: $GIMME"
  173. continue
  174. ;;
  175. esac
  176. ! [[ "$DEBUG" ]] || set -x
  177. echo "# WANT: $GIMME"
  178. ! [[ "$GIMMES" == *" $GIMME "* ]] || exit 0
  179. export GIMMES+=" $GIMME " GIMME
  180. P="$GIMME_GIMMES_DIR/$GIMME"
  181. if ! [[ -f "$P" ]]; then
  182. # find _default handler
  183. while P=$(dirname "$P") && [[ "$P" = "$GIMME_GIMMES_DIR"* ]]; do
  184. if [[ -f "$P/_default" ]]; then
  185. P="$P/_default"
  186. break;
  187. fi
  188. done
  189. # no default
  190. if ! [[ "$P" = "$GIMME_GIMMES_DIR"* ]]; then
  191. echo "# ERROR: Unable to find $GIMME_GIMMES_DIR/_default handler"
  192. exit 1
  193. fi
  194. fi
  195. if [[ -x "$P" ]]; then
  196. DID_GIMME=1
  197. [[ "$PATH" = "$LINK_DIR"* ]] || export PATH="$LINK_DIR:$PATH"
  198. if (if [[ "$DEBUG" ]]; then bash -x "$P"; else bash "$P"; fi); then
  199. echo "# DONE: $GIMME"
  200. else
  201. OUCH=$?
  202. echo "# FAIL: Error for gimme \"$GIMME\" (EXIT_CODE=$OUCH)"
  203. exit $OUCH
  204. fi
  205. else
  206. echo "# WARN: the gimme \"$GIMME\" was SKIPPED because \"$P\" is not marked executable!"
  207. fi
  208. done
  209. [[ "$DID_GIMME" ]] || echo "# WARN: nothing to do... try: gimme --help"
  210. fi