Jelajahi Sumber

simplified gimme.sh, split out gimmes, _default support

Kyle P Davis 10 tahun lalu
induk
melakukan
801b440d8b
28 mengubah file dengan 315 tambahan dan 225 penghapusan
  1. 79 2
      README.md
  2. 68 223
      gimme.sh
  3. 14 0
      gimmes/_default
  4. 7 0
      gimmes/_node_pkg
  5. 11 0
      gimmes/_python_pkg
  6. 11 0
      gimmes/atom
  7. 6 0
      gimmes/firefox
  8. 6 0
      gimmes/gcc
  9. 11 0
      gimmes/git
  10. 13 0
      gimmes/git-extras
  11. 9 0
      gimmes/go
  12. 8 0
      gimmes/google-chrome
  13. 1 0
      gimmes/js-beautify
  14. 1 0
      gimmes/jscs
  15. 1 0
      gimmes/jshint
  16. 1 0
      gimmes/json
  17. 7 0
      gimmes/liquidprompt
  18. 1 0
      gimmes/mocha
  19. 2 0
      gimmes/mongodb
  20. 2 0
      gimmes/my/difftool
  21. 13 0
      gimmes/my/dotfiles
  22. 6 0
      gimmes/my/mergetool
  23. 10 0
      gimmes/my/tools
  24. 11 0
      gimmes/node
  25. 1 0
      gimmes/pep8
  26. 1 0
      gimmes/pylint
  27. 6 0
      gimmes/python
  28. 8 0
      gimmes/redis

+ 79 - 2
README.md

@@ -1,3 +1,80 @@
-gimme
-=====
+# gimme
+A micro meta package manager for the masses.
+
+
+## What. Does. __That__. MEAN?
+The `gimme` command is intended to run micro scripts that get stuff (or get
+stuff done). Ideally, it can do anything ~~that can be automated in shell~~.
+
+Think of it as glue between tiny little tasks that are easy to define.
+
+
+## No really... what does it do?
+It deals with the shell scripts so that the engineers don't have to.
+
+
+## Umm.. okay... how, then?
+
+
+### install it (you do read these scripts, right?)
+```bash
+curl -fsSL "http://git.kylepdavis.com/kylepdavis/gimme/raw/master/gimme" | bash -
+```
+
+### use it
+```bash
+gimme goodies
+# if it exists, it will run the "$GIMME_DIR/gimmes/goodies" script
+# otherwise, it will run the "$GIMME_DIR/gimmes/_default" script (which by default installs stuff with your package manager)
+```
+
+### shell integration
+You can get tab completion in bash by doing something like this (put it in your `.profile` to play for keeps):
+```bash
+source "$GIMME_DIR/gimme"
+```
+
+
+## What is in it for me?
+The idea here is that the what you use this for is really up to you.
+
+Here are some ideas for overall uses to get you started:
+* install tools to compliment your `dotfiles` (that's one way that I'm using it)
+* manage configurations for multiple machines (just make a new `config` "gimme" script that runs `gimme $HOST/install` and you're on your way to being able to run `gimme config`)
+* collaborate with a team on commands for dev, ops, support, etc. (e.g., `gimme dev`, `gimme qa`, `gimme test_data`, `gimme auth/new_user`, etc.)
+
+If that wasn't enough here are some ideas for the "gimmes":
+
+
+## How do I write gimmes?
+Simple:
+1. write a shell script that does something awesome
+  * helpers like `has` and `gimme_pkg` get inherited from the main `gimme` script if you want
+  * add a check to make sure that it does nothing on subsequent runs -- idempotence is sexy
+  * you can depend on other "gimmes" by simply calling `gimme that other thing` at the top
+2. put it into the `$GIMME_DIR/gimmes/` directory
+3. make it executable with something like `chmod 755 YOUR_GIMME_SCRIPT`
+
+
+## What else?
+Also, it prevents cycles so one of your "gimmes" could
+
+What you use this for could range from a small set of personal tools that you use to compliment your dotfiles
+rdotconfiguration management suite to compliment your dotfiles to a
+ getting stuff.
+You can take that to mean whatever you want. Use my defaults or fork this project and add your own scripts.
+
+
+## What makes it better than X?
+Maybe nothing. Lots of things do dependency tracking. I wanted to try this out.
+
+Some suggested using `Makefile` files but that felt a little clunky. Plus `make` isn't exactly installed everywhere.
+Neither is `bash` but it was good enough for me.
+
+You could technically use something like chef, puppet, ansible, salt, etc. but those felt *way* too heavy for my needs.
+
+Just trying to keep it simple and shell scripts are about as simple as it gets.
+
+Here's another project that somewhat agrees:
+ [https://github.com/brandonhilkert/fucking_shell_scripts](fucking_shell_scripts) project
 

+ 68 - 223
gimme.sh

@@ -1,18 +1,19 @@
 #!/bin/bash
-# a quick and dirty meta pkg installer
-#
-#TODO: output help if used wrong
-#
+# A micro meta package manager for the masses.
+# USAGE:
+#     gimme [stuff]
 ###############################################################################
-set -e
 
-[ "$GIMME_URL" ]  ||  GIMME_URL="http://git.kylepdavis.com/kylepdavis/gimme.git"
-[ "$GIMME_DIR" ]  ||  GIMME_DIR="$HOME/.gimme"
-[ "$GIMMES" ]  ||  GIMMES=""
+[ "$GIMME_URL" ]         ||  export GIMME_URL="http://git.kylepdavis.com/kylepdavis/gimme"
+[ "$GIMME_DIR" ]         ||  export GIMME_DIR="$HOME/.gimme"
+[ "$GIMME_GIMMES_DIR" ]  ||  export GIMME_GIMMES_DIR="$GIMME_DIR/gimmes"
+[ "$GIMME_LINK" ]        ||  export GIMME_LINK="$HOME/bin/gimme"
+[ "$GIMME_LINK_DIR" ]    ||  export GIMME_LINK_DIR=$(dirname "$GIMME_LINK")
+[ "$GIMMES" ]            ||  export GIMMES=""
+[ "$OS" ]                ||  export OS=$(uname -s)
+[ "$DEBUG" ]             ||  export DEBUG=0
 
-has() {
-	which "$1" >/dev/null
-}
+has() { which "$1" >/dev/null; }
 
 pkgtool() {
 	if [[ "$OS" = "Darwin" ]]; then
@@ -26,239 +27,83 @@ gimme_pkg() {
 	pkgtool install "$@"
 }
 
-__gimme() {
-	local PKG="$1"
-
-	! [[ "$_GIMMES" == *" $PKG "* ]]  ||  return 0
-	_GIMMES+=" $PKG "
-
-	case "$PKG" in
-
-	dotfiles)
-		#TODO: install my dotfiles
-	;;
+export -f has pkgtool gimme_pkg
 
-	gcc)
-		if [[ "$OS" = "Darwin" ]]; then
-			"xcode-select" --install 2>&1 | grep -q "already installed"
-		else
-			has gcc  ||  gimme_pkg build-essential
-			_gimme curl
-		fi
-	;;
 
-	bash_profile) _gimme liquidprompt
-		[[ -f "$HOME/.bash_profile" ]]  ||  ln -sv "$HOME/.profile" "$HOME/.bash_profile"
-		[[ -f "$HOME/.bashrc" ]]        ||  ln -sv "$HOME/.profile" "$HOME/.bashrc"
-	;;
+if [[ "$0" = "bash" ]]; then # sourced or piped
 
-	liquidprompt) _gimme bash_profile git
-		[[ -d "$HOME/.liquidprompt" ]]  ||  git clone "https://github.com/nojhan/liquidprompt.git" "$HOME/.liquidprompt"
-	;;
+	if [[ "$BASH_SOURCE" ]]; then # sourced
 
-	git)
-		has git  ||  gimme_pkg git
-		if ! [[ -f "$HOME/.gitconfig" ]]; then
-			git config --global color.ui true
-			if [[ "$OS" = "Darwin" ]]; then
-				git config --global credential.helper "osxkeychain"
+		_gimme_completely() {
+			if [[ "$2" = -* ]]; then
+				COMPREPLY=( $(compgen -W "--help --version" -- "$2") )
 			else
-				git config --global credential.helper "cache --timeout=3600"
+				COMPREPLY=( $(find "$GIMME_GIMMES_DIR" -type f -path "$GIMME_GIMMES_DIR/$2*" \! -name '.*' -printf "%P\n") )
 			fi
-		fi
-	;;
+		}
 
-	git-extras) _gimme git
-		has git-alias  ||  (cd /tmp && git clone --depth 1 https://github.com/tj/git-extras.git && cd git-extras && sudo make install)
-		if ! [[ "$(git alias)" ]]; then
-			git alias br branch
-			git alias ci commit
-			git alias co checkout
-			git alias di diff
-			git alias st status
-		fi
-	;;
+		complete -F _gimme_completely gimme
 
-	python)
-		if [[ "$OS" = "Darwin" ]]; then
-			mkdir -p "$PYTHONPATH"
-		fi
-		has python  ||  gimme_pkg python
-	;;
+	else # piped
 
-	pylint|pep8) _gimme python
-		if ! has "$PKG"; then
-			if [[ "$OS" = "Darwin" ]]; then
-				easy_install -d "$PYTHONPATH" "$PKG"
-				ln -sv "$PYTHONPATH/$PKG" "$(brew --prefix)/bin/$PKG"
-			else
-				easy_install "$PKG"
-			fi
-		fi
-	;;
+		if ! [[ -d "$GIMME_DIR" ]]; then
 
-	node)
-		if [[ "$OS" = "Darwin" ]]; then
-			has node  ||  gimme_pkg node
-		else #TODO: might get old version here ...
-			_gimme nodejs npm
-		fi
-	;;
+			echo "Installing $GIMME_DIR/gimme ..."
+			mkdir -p "$GIMME_DIR"
+			git clone "$GIMME_URL" "$GIMME_DIR"
+			mkdir -p "$(dirname "$GIMME_LINK")"
+			ln -sf "$GIMME_DIR/gimme" "$GIMME_LINK"
+			echo "Done! Now you can 'gimme stuff' or 'gimme dev/stuff' or even 'gimme gimme'!"
 
-	jshint|js-beautify|json)
-		if [[ "$OS" = "Darwin" ]]; then
-			has "$PKG"  ||  npm install -g "$PKG"
 		else
-			has "$PKG"  ||  sudo npm install -g "$PKG"
-		fi
-	;;
-
-	mongodb)
-		has "mongod"  ||  gimme_pkg mongodb
-	;;
-
-	redis)
-		if ! has "redis-server"; then
-			if [[ "$OS" = "Darwin" ]]; then
-				gimme_pkg redis
-			else
-				gimme_pkg redis-server
-			fi
-		fi
-	;;
 
-	go)
-		_gimme curl
-		#TODO: setup go vs golang dirs?
-		if ! which "$PKG" >/dev/null; then
-			if [[ "$OS" = "Darwin" ]]; then
-				gimme_pkg go --cross-compile-common
-			else
-				gimme_pkg golang
-			fi
-		fi
-	;;
-
-	difftool)
-		_gimme colordiff
-	;;
+			echo "Updating gimme (in $GIMME_DIR) ..."
+			cd "$GIMME_DIR"
+			git pull
 
-	mergetool)
-		if [[ "$OS" = "Darwin" ]]; then
-			true #TODO: usually use opendiff but SourceTree installer would be nice
-		else
-			_gimme meld
 		fi
-	;;
 
-	tools)
-		_gimme bash_profile liquidprompt git tmux tree vim
-	;;
-
-	dev/generic)
-		_gimme gcc mergetool
-	;;
-
-	dev/js)
-		_gimme node jshint js-beautify json
-	;;
-
-	dev/sh)
-		_gimme shellcheck
-	;;
-
-	dev/py)
-		_gimme python pylint pep8
-	;;
-
-	dev/db)
-		_gimme mongodb redis postgresql
-	;;
-
-	dev/go)
-		_gimme go
-	;;
-
-	dev)
-		_gimme dev/generic dev+js dev+sh dev+py dev+db dev+go
-	;;
-
-	stuff)
-		_gimme tools dev
-	;;
-
-	homebrew) _gimme gcc git
-		[[ -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"  &&  brew update)
-		[[ "$BREW_PREFIX" ]]  ||  BREW_PREFIX=$(brew --prefix)
-		has brew-cask  ||  brew install caskroom/cask/brew-cask
-	;;
+	fi
 
-	pkgtool)
-		if [[ "$OS" = "Darwin" ]]; then
-			_gimme homebrew
-		else
-			has apt-get  ||  return 123
+else # normal usage
+	set -e
+	set -E
+	set -o pipefail
+
+	on_err() {
+		echo "ERROR: Unable to gimme \"$GIMME\" (EXIT=$?)" 1>&2
+	}
+	trap on_err ERR
+
+	for GIMME; do
+
+		! [[ "$GIMMES" == *" $GIMME "* ]]  ||  exit 0
+		export GIMMES+=" $GIMME " GIMME
+
+		P="$GIMME_GIMMES_DIR/$GIMME"
+
+		if ! [[ -f "$P" ]]; then
+			# find _default handler
+			while P=$(dirname "$P") && [[ "$P" = "$GIMME_GIMMES_DIR"* ]]; do
+				if [[ -f "$P/_default" ]]; then
+					P="$P/_default"
+					break;
+				fi
+			done
+			# no default
+			if ! [[ "$P" = "$GIMME_GIMMES_DIR"* ]]; then
+				echo "# ERROR: Unable to find $GIMME_GIMMES_DIR/_default handler" 1>&2
+				exit 1
+			fi
 		fi
-	;;
 
-	pkgtool_metadata)
-		pkgtool update
-	;;
-
-	gimme)
-		echo "Checking gimme ..."
-		_gimme git
-		if ! [[ -d "$GIMME_DIR" ]]; then
-			echo "Installing $HOME/bin/gimme ..."
-			mkdir -p "$GIMME_DIR"
-			git clone "$GIMME_URL" "$GIMME_DIR"
-			mkdir -p "$HOME/bin"
-			ln -sf "$GIMME_DIR/gimme.sh" "$HOME/bin/gimme"
+		if [[ -x "$P" ]]; then
+			[[ "$PATH" = "$LINK_DIR"* ]]  ||  export PATH="$LINK_DIR:$PATH"
+			"$P"
+			echo "# DONE: gimme $GIMME"
 		else
-			echo "Updating gimme ..."
-			pushd "$GIMME_DIR" >/dev/null
-			git pull
-			popd >/dev/null
+			echo "# WARN: gimme $GIMME was SKIPPED because $P is not marked executable!"
 		fi
-	;;
-
-	*)
-		_gimme pkgtool
-		#TODO: _gimme pkgtool_metadata
-		has "$PKG"  ||  gimme_pkg "$PKG"
-	;;
-
-	esac
 
-	echo "# DONE: gimme $PKG"
-}
-
-_gimme() {
-	local PKG
-	for PKG in "$@"; do
-		if ! __gimme "$PKG"; then
-			echo "ERROR: Unable to fulfill gimme for $PKG!"
-			return 123
-		fi
 	done
-}
-
-gimme() {
-	_GIMMES=
-	_gimme "$@"
-}
-
-if [[ "$0" = "bash" ]]; then
-	if [[ "$BASH_SOURCE" ]]; then
-		set +e
-		GIMME_GIMMES=$(type __gimme | grep ')$' | tr -d ')|*')
-		_gimme_complete() {
-			COMPREPLY=( $(compgen -W "$GIMME_GIMMES" -- "${COMP_WORDS[COMP_CWORD]}") )
-		}
-		complete -F _gimme_complete gimme
-	else
-		gimme gimme
-	fi
-else
-	gimme "$@"
 fi

+ 14 - 0
gimmes/_default

@@ -0,0 +1,14 @@
+#!/bin/bash
+has curl  ||  gimme_pkg curl
+
+if [[ "$OS" = "Darwin" ]]; then
+	[[ -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"  &&  brew update)
+	has brew-cask  ||  brew install caskroom/cask/brew-cask
+else
+	if ! has apt-get; then
+		echo "ERROR: Your OS does not have 'apt-get' and is not currently supported."
+		echo "For support please see the website: $GIMME_URL"
+	fi
+fi
+
+has "$GIMME"  ||  gimme_pkg "$GIMME"

+ 7 - 0
gimmes/_node_pkg

@@ -0,0 +1,7 @@
+#!/bin/bash
+PKG=$(basename "$0")
+if [[ "$OS" = "Darwin" ]]; then
+	has "$PKG"  ||  npm install -g "$PKG"
+else
+	has "$PKG"  ||  sudo npm install -g "$PKG"
+fi

+ 11 - 0
gimmes/_python_pkg

@@ -0,0 +1,11 @@
+#!/bin/bash
+gimme python
+PKG=$(basename "$0")
+if ! has "$PKG"; then
+	if [[ "$OS" = "Darwin" ]]; then
+		easy_install -d "$PYTHONPATH" "$PKG"
+		ln -sv "$PYTHONPATH/$PKG" "$(brew --prefix)/bin/$PKG"
+	else
+		easy_install "$PKG"
+	fi
+fi

+ 11 - 0
gimmes/atom

@@ -0,0 +1,11 @@
+#!/bin/bash
+if [[ "$OS" = "Darwin" ]]; then
+	[[ -d "$HOME/Applications/Atom.app" ]]  ||  brew cask install atom
+else
+	if ! has atom; then
+		TMP_FILE="/tmp/atom$$.deb"
+		curl -fSL https://atom.io/download/deb -o "$TMP_FILE"
+		sudo dpkg -i "$TMP_FILE"
+		rm "$TMP_FILE"
+	fi
+fi

+ 6 - 0
gimmes/firefox

@@ -0,0 +1,6 @@
+#!/bin/bash
+if [[ "$OS" = "Darwin" ]]; then
+	[[ -d "$HOME/Applications/Firefox.app" ]]  ||  brew cask install firefox
+else
+	has firefox  ||  gimme_pkg firefox
+fi

+ 6 - 0
gimmes/gcc

@@ -0,0 +1,6 @@
+#!/bin/bash
+if [[ "$OS" = "Darwin" ]]; then
+	"xcode-select" --install 2>&1 | grep -q "already installed"
+else
+	has gcc  ||  gimme_pkg build-essential
+fi

+ 11 - 0
gimmes/git

@@ -0,0 +1,11 @@
+#!/bin/bash
+has git  ||  gimme_pkg git
+if ! [[ -f "$HOME/.gitconfig" ]]; then
+	git config --global color.ui true
+	if [[ "$OS" = "Darwin" ]]; then
+		git config --global credential.helper "osxkeychain"
+	else
+		git config --global credential.helper "cache --timeout=3600"
+	fi
+fi
+

+ 13 - 0
gimmes/git-extras

@@ -0,0 +1,13 @@
+#!/bin/bash
+
+gimme git
+
+has git-alias  ||  gimme_pkg git-extras
+
+if ! [[ "$(git alias)" ]]; then
+	git alias br branch
+	git alias ci commit
+	git alias co checkout
+	git alias di diff
+	git alias st status
+fi

+ 9 - 0
gimmes/go

@@ -0,0 +1,9 @@
+#!/bin/bash
+#TODO: setup go vs golang dirs
+if ! has go; then
+	if [[ "$OS" = "Darwin" ]]; then
+		gimme_pkg go --cross-compile-common
+	else
+		gimme_pkg golang
+	fi
+fi

+ 8 - 0
gimmes/google-chrome

@@ -0,0 +1,8 @@
+#!/bin/bash
+if [[ "$OS" = "Darwin" ]]; then
+	[[ -d "$HOME/Applications/Google Chrome.app" ]]  ||  brew cask install google-chrome
+else
+	if ! has google-chrome && ! has chromium-browser; then
+		gimme_pkg chromium-browser
+	fi
+fi

+ 1 - 0
gimmes/js-beautify

@@ -0,0 +1 @@
+_node_pkg

+ 1 - 0
gimmes/jscs

@@ -0,0 +1 @@
+_node_pkg

+ 1 - 0
gimmes/jshint

@@ -0,0 +1 @@
+_node_pkg

+ 1 - 0
gimmes/json

@@ -0,0 +1 @@
+_node_pkg

+ 7 - 0
gimmes/liquidprompt

@@ -0,0 +1,7 @@
+#!/bin/bash
+
+gimme git
+
+REPO_URL="https://github.com/nojhan/liquidprompt"
+REPO_DIR="$HOME/.liquidprompt"
+[[ -d "$REPO_DIR" ]]  ||  git clone "$REPO_URL" "$REPO_DIR"

+ 1 - 0
gimmes/mocha

@@ -0,0 +1 @@
+_node_pkg

+ 2 - 0
gimmes/mongodb

@@ -0,0 +1,2 @@
+#!/bin/bash
+has mongod  ||  gimme_pkg mongodb

+ 2 - 0
gimmes/my/difftool

@@ -0,0 +1,2 @@
+#!/bin/bash
+has colordiff  ||  gimme colordiff

+ 13 - 0
gimmes/my/dotfiles

@@ -0,0 +1,13 @@
+#!/bin/bash
+REPO_URL="https://github.com/KylePDavis/dotfiles"
+REPO_DIR="$HOME/.dotfiles"
+
+if ! [[ -d "$REPO_DIR" ]]; then
+
+	git clone "$REPO_URL" "$REPO_DIR"
+
+	if [[ -x "$REPO_DIR/install.sh" ]]; then
+		"$REPO_DIR/install.sh"
+	fi
+
+fi

+ 6 - 0
gimmes/my/mergetool

@@ -0,0 +1,6 @@
+#!/bin/bash
+if [[ "$OS" = "Darwin" ]]; then
+	[[ -d "$HOME/Applications/SourceTree.app" ]]  ||  brew cask install sourcetree
+else
+	has meld  ||  gimme meld
+fi

+ 10 - 0
gimmes/my/tools

@@ -0,0 +1,10 @@
+#!/bin/bash
+
+# tools
+gimme \
+	my/dotfiles \
+	liquidprompt \
+	git \
+	tmux \
+	tree \
+	vim \

+ 11 - 0
gimmes/node

@@ -0,0 +1,11 @@
+#!/bin/bash
+gimme gcc git
+if ! has node; then
+	if [[ "$OS" = "Darwin" ]]; then
+		gimme_pkg node
+	else
+		gimme_pkg nodejs npm libgnome-keyring-dev fakeroot
+		sudo npm config set python /usr/bin/python2 -g
+		sudo update-alternatives --install /usr/bin/node node /usr/bin/nodejs 10
+	fi
+fi

+ 1 - 0
gimmes/pep8

@@ -0,0 +1 @@
+_python_pkg

+ 1 - 0
gimmes/pylint

@@ -0,0 +1 @@
+_python_pkg

+ 6 - 0
gimmes/python

@@ -0,0 +1,6 @@
+#!/bin/bash
+if [[ "$OS" = "Darwin" ]]; then
+	mkdir -p "$PYTHONPATH"
+fi
+has python  ||  gimme_pkg python
+has easy_install || gimme_pkg python-setuptools

+ 8 - 0
gimmes/redis

@@ -0,0 +1,8 @@
+#!/bin/bash
+if ! has redis-server; then
+	if [[ "$OS" = "Darwin" ]]; then
+		gimme_pkg redis
+	else
+		gimme_pkg redis-server
+	fi
+fi