gimme 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  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 brew cask cat "$@" &>/dev/null; then
  32. if brew cask list "$@" &>/dev/null; then
  33. if [[ "$FORCE" ]]; then
  34. brew cask reinstall "$@"
  35. else
  36. echo "# SKIPPED: $GIMME (force reinstall/upgrade via: gimme -f $GIMME)"
  37. fi
  38. else
  39. brew cask install "$@"
  40. fi
  41. elif brew cat "$@" &>/dev/null; then
  42. if brew list "$@" &>/dev/null; then
  43. if [[ "$FORCE" ]]; then
  44. brew upgrade "$@"
  45. else
  46. echo "# SKIPPED: $GIMME (force upgrade via: gimme -f $GIMME)"
  47. fi
  48. else
  49. brew install "$@"
  50. fi
  51. else
  52. brew search "$@"
  53. fi
  54. else
  55. sudo apt-get -y install "$@"
  56. fi
  57. }
  58. if [[ "$0" =~ [-]?bash ]]; then # sourced or piped
  59. if [[ "${BASH_SOURCE[@]}" ]]; then # sourced
  60. _gimme_completely() {
  61. if [[ "$2" = -* ]]; then
  62. COMPREPLY=( $(compgen -W "-v --verbose --debug --force --version --help -l --list --installed --old --outdated" -- "$2") )
  63. else
  64. COMPREPLY=( $(find "$GIMME_GIMMES_DIR" -type f -path "$GIMME_GIMMES_DIR/$2*" \! -name '.*' | cut -c$(( ${#GIMME_GIMMES_DIR} + 2))- ) )
  65. fi
  66. }
  67. complete -F _gimme_completely gimme
  68. else # piped
  69. set -o errexit -o pipefail
  70. # gimmes/gcc: inlined for curl-based installs
  71. if [[ "$OS" = "Darwin" ]]; then
  72. if ! "xcode-select" --version &>/dev/null; then
  73. echo "Try again after installing the Xcode command-line tools by running: xcode-select --install"
  74. exit 1
  75. fi
  76. if ! xcodebuild -help &>/dev/null; then
  77. echo "Try again after agreeing to the Xcode license by running: sudo xcodebuild -license"
  78. exit 1
  79. fi
  80. else
  81. has gcc || gimme_pkg build-essential
  82. fi
  83. # gimmes/git: inlined for curl-based installs
  84. has git || gimme_pkg git
  85. if ! [[ -d "$GIMME_DIR" ]]; then
  86. echo "Installing $GIMME_DIR/gimme ..."
  87. mkdir -p "$GIMME_DIR"
  88. git clone "$GIMME_URL" "$GIMME_DIR"
  89. mkdir -p "$(dirname "$GIMME_LINK")"
  90. ln -sf "$GIMME_DIR/gimme" "$GIMME_LINK"
  91. echo "Done! Now you can 'gimme stuff' or 'gimme dev/stuff' or even 'gimme gimme'!"
  92. else
  93. echo "Updating gimme (in $GIMME_DIR) ..."
  94. cd "$GIMME_DIR"
  95. git pull
  96. fi
  97. fi
  98. else # normal usage
  99. set -o errexit -o pipefail
  100. export -f has gimme_pkg
  101. [[ "$INIT_GIMMES" ]] || export INIT_GIMMES="$@"
  102. for GIMME; do
  103. case "$GIMME" in
  104. -v|--verbose|--debug)
  105. DEBUG=1
  106. continue
  107. ;;
  108. -f|--force)
  109. FORCE=1
  110. continue
  111. ;;
  112. --version)
  113. echo "Version:"
  114. git log -1
  115. exit 0
  116. ;;
  117. -h|--help)
  118. sed -n -e'/^#[[:space:]]/p' -e'/^###/q' "$0"
  119. echo "# GIMMES:"
  120. echo $(cd "$GIMME_GIMMES_DIR"; find . -type f -perm +1 | sed -e's/^..//' -e'/^_/d' | sort)
  121. exit 0
  122. ;;
  123. -l|--list|--installed)
  124. echo "# BREW (cask):"
  125. brew cask list
  126. echo
  127. echo "# BREW:"
  128. brew list
  129. echo
  130. echo "# NPM:"
  131. npm -g ls --depth 0
  132. echo
  133. echo "# PIP:"
  134. pip list --format=columns
  135. exit 0
  136. ;;
  137. --old|--outdated)
  138. echo "# BREW (cask):"
  139. brew cask outdated
  140. echo
  141. echo "# BREW:"
  142. brew outdated
  143. echo
  144. echo "# NPM:"
  145. npm outdated -g --depth 0
  146. echo
  147. echo "# PIP:"
  148. pip list --format=columns --outdated
  149. exit 0
  150. ;;
  151. esac
  152. ! [[ "$DEBUG" ]] || set -x
  153. echo "# WANT: $GIMME"
  154. ! [[ "$GIMMES" == *" $GIMME "* ]] || exit 0
  155. export GIMMES+=" $GIMME " GIMME
  156. P="$GIMME_GIMMES_DIR/$GIMME"
  157. if ! [[ -f "$P" ]]; then
  158. # find _default handler
  159. while P=$(dirname "$P") && [[ "$P" = "$GIMME_GIMMES_DIR"* ]]; do
  160. if [[ -f "$P/_default" ]]; then
  161. P="$P/_default"
  162. break;
  163. fi
  164. done
  165. # no default
  166. if ! [[ "$P" = "$GIMME_GIMMES_DIR"* ]]; then
  167. echo "# ERROR: Unable to find $GIMME_GIMMES_DIR/_default handler"
  168. exit 1
  169. fi
  170. fi
  171. if [[ -x "$P" ]]; then
  172. [[ "$PATH" = "$LINK_DIR"* ]] || export PATH="$LINK_DIR:$PATH"
  173. if (if [[ "$DEBUG" ]]; then bash -x "$P"; else bash "$P"; fi); then
  174. echo "# DONE: $GIMME"
  175. else
  176. OUCH=$?
  177. echo "# FAIL: Error for gimme \"$GIMME\" (EXIT_CODE=$OUCH)"
  178. exit $OUCH
  179. fi
  180. else
  181. echo "# WARN: the gimme \"$GIMME\" was SKIPPED because \"$P\" is not marked executable!"
  182. fi
  183. done
  184. fi