Refactor global rakefiles

This commit is contained in:
Henrik Lissner 2014-08-31 02:50:03 -04:00
parent f27d4d09ec
commit 1ef01b1055
26 changed files with 617 additions and 303 deletions

View file

@ -1,6 +1,73 @@
# Rake install scripts
My global rakefiles for my macs. Installs homebrew, vim and zsh; configures OSX; and
sets up my gamedev/programming environments.
I use global rakefiles to provision my computers and servers. They
work for OSX and Ubuntu; a `rake -g -T` will reveal all the available
options.
I leave home without it.
Running `rake -g update` will run the rake task that matches your
computer's hostname; they can be found in
`rake/nodes/<hostname>.rake`. I have one for each of my computers.
Feel free to take from it what you like.
## Packages
This currently provides:
* Homebrew
* OSX settings
* Zsh + zprezto -- deploys my [zsh dotfiles](http://github.com/hlissner/dotfiles)
* Emacs (mac only) -- deploys my [emacs.d](http://github.com/hlissner/emacs.d)
* Vim -- deploys my [vimrc](https://github.com/hlissner/dotfiles/blob/master/vimrc)
* Pyenv
* Rbenv
Planned features:
* Gitlab
* Flexget seedbox
* Webserver stacks for vagrant
## Installation
Simply symlink `./rake` to `~/.rake`, then these commands will become
accessible globally via `rake -g [task]`.
```sh
git clone https://github.com/hlissner/dotfiles ~/.dotfiles
ln -sf ~/.dotfiles/rake ~/.rake
```
Or just cd into `./rake` and work from there.
## Usage
```sh
rake -g # Same as: rake -g setup:`hostname`
rake -g update # Same as: rake -g setup:`hostname`
# This will install all the things specified in
# rake/nodes/<hostname>.rake and/or update them if already installed.
rake -g setup:<hostname>
# Installs <package>, or updates it
rake -g pkg:<package>
# Package sub-commands
rake -g pkg:<package>:install
rake -g pkg:<package>:remove
rake -g pkg:<package>:update
rake -g destroy # Runs pkg:*:remove and deletes all packages
```
A couple examples:
```sh
# Install/update homebrew, zsh and emacs
rake -g pkg:homebrew
rake -g pkg:zsh
rake -g pkg:emacs
# Install/update my config for ganymede
rake -g setup:ganymede
```

View file

@ -1,24 +1,26 @@
module Project
class Project
def create(dirs=[])
template_folder = "templates"
def dirs(dirs=[])
dirs.each do |d|
mkdir_p d unless Dir.exists? d
end
end
def template(template, vars={}, dest="")
def template(template, dest="", vars={})
template_file = "#{template_folder}/#{template}.erb"
dest_file = "#{dest}/#{File.basename(template)}"
raise "Template file doesn't exist" unless File.exists? template_file
raise "Destination folder doesn't exist" unless Dir.exists? dest
raise "Destination file already exists" unless File.exists? dest_file
erb = ERB.new(File.read(template_file))
File.open(dest_file) do |f|
f.puts(erb.result(binding))
end
def update(name)
end
def remove(name)
end
class Template
end
end

9
rake/lib/os.rb Normal file
View file

@ -0,0 +1,9 @@
def is_mac?
RUBY_PLATFORM =~ /darwin/
end
def is_linux?
RUBY_PLATFORM =~ /linux/
end
# TODO Implement other linux distro tests

13
rake/lib/package.rb Normal file
View file

@ -0,0 +1,13 @@
require_relative "sh"
require_relative "os"
include Rake::DSL
if is_mac?
require_relative "package_adapters/homebrew.rb"
elsif is_linux?
require_relative "package_adapters/aptitude.rb"
# TODO Implement centos yum support
else
raise "Could not detect OS"
end

View file

@ -0,0 +1,16 @@
# Aptitude (ubuntu/debian) package adapter
module Package
module_function
def bootstrap; end
def install(package)
self.run("install", "-y", package)
end
# TODO Finish aptitude adapter
def run(*args)
system("sudo apt-get #{args.join(' ')}")
end
end

View file

@ -0,0 +1,58 @@
# Homebrew package adapter
module Package
module_function
@@brew_bin = "/usr/local/bin/brew"
def bootstrap
unless self.installed?
sh_safe 'ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"'
end
end
def install(package)
self.run("install", package) unless self.installed?(package)
end
def installed?(package = nil)
return File.exists?(@@brew_bin) if !package
self.run("list | grep -w '#{package}' >& /dev/null")
end
def remove(package)
self.run("remove", package)
end
def update(*args)
if args.length > 0
self.run("upgrade #{args.join(' ')}")
else
self.run("update")
self.run("upgrade")
end
end
# Homebrew-specific functions
def cask_install(cask)
self.run("cask", "install", cask) unless self.cask_installed?(cask)
end
def cask_installed?(cask)
self.run("cask list | grep -w '#{cask}' >& /dev/null")
end
def tap(repo)
self.run("tap", repo) unless self.tapped?(repo)
end
def tapped?(repo)
self.run("tap | grep -w '#{repo}' >& /dev/null")
end
def run(*args)
raise "Homebrew isn't installed!" unless self.installed?
`#{@@brew_bin} #{args.join(' ')}`
end
end

View file

@ -0,0 +1,16 @@
module Pyenv
BREWS = %w{pbenv pyenv-pip-rehash pyenv-virtualenv}
PIP_BIN = "/usr/local/opt/pyenv/shims/pip"
def self.bootstrap
end
def self.destroy
end
end

View file

@ -1,4 +1,3 @@
def load_all(glob)
Dir.glob("#{File.dirname(__FILE__)}/../#{glob}") { |file| load file }
end

View file

@ -1,4 +1,3 @@
require_relative 'output'
# A 'safe' sh function that won't stop rake in its tracks

View file

@ -1,8 +1,9 @@
desc "Provision home server"
task :callisto do
%w{
zsh
vim
update
pkg:zsh
pkg:vim
pkg:rbenv
}.each { |task| Rake::Task[task].invoke }
end

View file

@ -1,3 +1,2 @@
desc "Provision main laptop"
task :ganymede => :io

View file

@ -1,18 +1,16 @@
require_relative '../lib/homebrew'
desc "Provision main desktop"
task :io do
%w{
update
pkg:osx
pkg:homebrew
pkg:zsh
pkg:vim
pkg:emacs
pkg:rbenv:v1_9
pkg:rbenv:v2_0
pkg:rbenv:update
pkg:rbenv
pkg:pyenv
}.each { |task| Rake::Task[task].invoke }
if is_mac?
%w{
transmit
transmission
@ -21,10 +19,10 @@ task :io do
skype
adium
codekit
mongohub
sequel-pro
scrivener
omnigraffle
love
}.each { |app| Homebrew.install_cask app }
}.each { |app| Package.cask_install app }
end
end

View file

@ -1,3 +1,2 @@
desc "Provision 2nd desktop"
task :titan => :io

18
rake/packages.rake Normal file
View file

@ -0,0 +1,18 @@
require_relative "lib/rake"
require_relative "lib/os"
require_relative "lib/sh"
require_relative "lib/output"
verbose(false)
if is_mac?
desc 'Setup/update homebrew & packages'
task :update => 'pkg:homebrew:update'
elsif is_linux?
desc 'Setup/update packages'
task :update => 'pkg:aptitude:update'
end
namespace :pkg do
load_all("pkg/*.rake")
end

View file

@ -1,5 +0,0 @@
require_relative "lib/rake"
verbose(false)
namespace :pkg do load_all("pkg/*.rake") end

View file

@ -1,32 +1,42 @@
desc "Ensure emacs is installed and up to date"
task :emacs => "emacs:update"
if is_mac?
namespace :emacs do
ENV['EMACS_D'] = File.expand_path("~/.emacs.d")
desc "Ensure emacs is installed and up to date"
task :emacs => "emacs:update"
namespace :emacs do
task :install do
unless Dir.exists?(File.expand_path("~/.emacs.d"))
github('hlissner/emacs.d', '~/.emacs.d')
Homebrew.install("emacs", "--with-gnutls --cocoa --keep-ctags --srgb")
Homebrew.install("homebrew/dupes/tidy", "--HEAD")
Homebrew.install "aspell"
unless Dir.exists?(ENV[:EMACS_D])
github 'hlissner/emacs.d', '~/.emacs.d'
Package.install "emacs", "--with-gnutls --cocoa --keep-ctags --srgb"
Package.install "homebrew/dupes/tidy", "--HEAD"
emacs_reqs.each { |pkg| Package.install pkg }
sh_safe "/usr/local/bin/npm install jshint -g"
sh_safe "/usr/local/bin/npm install jsonlint -g"
sh_safe "cd ~/.emacs.d && cask"
end
end
task :update do
echo "Updating emacs.d"
sh_safe "cd ~/.emacs.d && git pull"
echo "You'll have to update emacs packages manually!"
echo "Updating emacs.d & packages"
sh_safe "cd ~/.emacs.d && git pull && cask update"
end
desc "Remove emacs & dependencies"
task :remove do
echo "Uninstalling emacs"
Homebrew.remove "emacs"
Homebrew.remove "aspell"
rm_rf "~/.emacs.d" if Dir.exists?(File.expand_path("~/.emacs.d"))
Package.remove "emacs"
Package.remove "homebrew/dupes/tidy"
emacs_reqs.each { |pkg| Package.remove pkg }
rm_rf "~/.emacs.d" if Dir.exists?(ENV['EMACS_D'])
end
end
def emacs_reqs
%w{aspell cask rsense}
end
end

View file

@ -1,65 +0,0 @@
if RUBY_PLATFORM =~ /darwin/
require_relative "../lib/output"
require_relative "../lib/homebrew"
require_relative "../lib/sh"
desc 'Install/update homebrew'
task :homebrew => 'homebrew:update'
namespace :homebrew do
task :install do
unless Homebrew.is_installed?
echo "Installing Homebrew..."
Homebrew.bootstrap
end
Homebrew.tap 'homebrew/dupes'
Homebrew.tap 'caskroom/cask'
Homebrew.install 'brew-cask'
%w{
coreutils
wget
curl
tree
git
the_silver_searcher
tmux
gist
lua
luajit
readline
openssl
node
}.each { |pkg| Homebrew.install pkg }
%w{
dropbox
appcleaner
vagrant
virtualbox
growlnotify
iterm2
java
launchbar
}.each { |app| Homebrew.install_cask app }
echo "Homebrew is installed. Moving on."
end
desc "Update homebrew and upgrade brews"
task :update => "homebrew:install" do
echo "Updating homebrew..."
Homebrew.update
end
desc "Remove homebrew cleanly"
task :remove do
Homebrew.destroy if Homebrew.is_installed?
end
end
end

View file

@ -1,6 +1,9 @@
require_relative '../lib/output'
desc "Set OSX default configuration"
task :osx do
next unless is_mac?
if system('defaults read com.apple.finder _FXShowPosixPathInTitle >&/dev/null')
echo 'OSX settings already applied!'
next

73
rake/pkg/package.rake Normal file
View file

@ -0,0 +1,73 @@
require_relative "../lib/package"
if is_mac?
namespace :homebrew do
task :setup do
unless Package.installed?
echo "Installing Homebrew..."
Package.bootstrap
Package.tap 'homebrew/dupes'
Package.tap 'caskroom/cask'
end
Package.install 'brew-cask'
# Essentials for all macs; specific brews are placed
# in the node/*.rake files
%w{
coreutils
wget
curl
tree
git
the_silver_searcher
tmux
gist
lua
luajit
readline
openssl
node
}.each { |pkg| Package.install pkg }
%w{
dropbox
appcleaner
vagrant
virtualbox
growlnotify
iterm2
java
launchbar
}.each { |app| Package.cask_install app }
echo "Homebrew is installed. Moving on."
end
task :update => "homebrew:setup" do
echo "Updating homebrew..."
Package.update
end
desc "Remove homebrew cleanly"
task :remove do
Package.destroy if Package.installed?
end
end
elsif is_linux?
namespace :aptitude do
task :setup do
# TODO Setup default linux package
end
task :update => 'aptitude:setup' do
echo "Updating packages..."
Package.update
end
end
end

54
rake/pkg/pyenv.rake Normal file
View file

@ -0,0 +1,54 @@
desc "Install/update pyenv & all pythons"
task :pyenv => 'pyenv:update'
namespace :pyenv do
task :install do
unless pyenv_installed?
echo "Installing pyenv"
if is_mac?
pyenv_reqs.each { |pkg| Package.install pkg }
elsif is_linux?
sh_safe "curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash"
end
end
end
task :update => "pyenv:install" do
pyenv_versions do |v|
echo "Updating python #{v}"
cmd = "pip"
cmd = "sudo #{cmd}" if v == "system"
sh_safe "PYENV_VERSION=#{v} #{cmd} freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs #{cmd} install -U"
end
end
desc "Remove pyenv & installed pythons"
task :remove do
if pyenv_installed?
echo "pyenv isn't installed!"
else
echo "Deleting pyenv"
if is_mac?
pyenv_reqs.each { |pkg| Package.remove pkg }
elsif is_linux?
sh_safe "rm -rf $PYENV_ROOT"
end
end
end
end
####
def pyenv_installed?
system("which pyenv")
end
def pyenv_versions
`ls -1 $PYENV_ROOT/versions`.split("\n")
end
def pyenv_reqs
%w{pyenv pyenv-pip-rehash pyenv-virtualenv}
end

View file

@ -1,31 +1,55 @@
require_relative '../lib/homebrew'
require_relative '../lib/rbenv'
desc "Install/update rbenv & all rubies"
task :rbenv => 'rbenv:update'
namespace :rbenv do
task :install do
unless Rbenv.is_installed?
unless rbenv_installed?
echo "Installing rbenv"
Rbenv.bootstrap
if is_mac?
rbenv_reqs.each { |pkg| Package.install pkg }
elsif is_linux?
sh_safe "curl https://raw.githubusercontent.com/fesplugas/rbenv-installer/master/bin/rbenv-installer | bash"
end
end
task :remove do
if Rbenv.is_installed?
echo "rbenv isn't installed!"
else
echo "Deleting rbenv"
Rbenv.destroy
end
end
task :update => "rbenv:install" do
Rbenv.installed_versions.each do |v|
rbenv_versions do |v|
echo "Updating ruby #{v}"
Rbenv.update v
cmd = "gem"
cmd = "sudo #{cmd}" if v == "system"
sh_safe "RBENV_VERSION=#{version} #{cmd} #{GEM_BIN} update"
sh_safe "RBENV_VERSION=#{version} #{cmd} #{GEM_BIN} clean"
end
end
desc "Remove rbenv & installed rubies"
task :remove do
if rbenv_installed?
echo "rbenv isn't installed!"
else
echo "Deleting rbenv"
if is_mac?
rbenv_reqs.each { |pkg| Package.remove pkg }
elsif is_linux?
sh_safe "rm -rf $RBENV_ROOT"
end
end
end
end
####
def rbenv_installed?
system("which rbenv")
end
def rbenv_versions
`ls -1 $RBENV_ROOT/versions`.split("\n")
end
def rbenv_reqs
%w{rbenv ruby-build rbenv-vars rbenv-gem-rehash}
end

View file

@ -1,19 +1,40 @@
require_relative "../lib/output"
require_relative "../lib/homebrew"
require_relative "../lib/sh"
desc "Ensure vim/macvim is installed and up to date"
task :vim => "vim:update"
namespace :vim do
task :install do
%w{lua luajit}.each { |pkg| Homebrew.install pkg }
%w{vim macvim}.each { |pkg| Homebrew.install(pkg, '--with-lua --with-luajit') }
vim_path = File.expand_path("~/.vim")
unless Dir.exists? (File.expand_path("~/.vim"))
github('hlissner/vim', '~/.vim')
github('Shougo/neobundle.vim', '~/.vim/bundle/neobundle.vim')
if is_mac?
Package.install "lua"
%w{vim macvim}.each { |pkg| Package.install "#{pkg} --with-lua --with-luajit" }
elsif is_linux?
Package.install "lua5.2"
unless Dir.exists?(vim_path)
sh_safe "sudo apt-get install libncurses5-dev libgnome2-dev libgnomeui-dev \
libgtk2.0-dev libatk1.0-dev libbonoboui2-dev \
libcairo2-dev libx11-dev libxpm-dev libxt-dev python-dev ruby1.9-dev mercurial"
sh_safe "hg clone https://code.google.com/p/vim/ /tmp/vim"
sh_safe "cd /tmp/vim && ./configure --with-features=huge \
--enable-multibyte \
--enable-rubyinterp \
--enable-pythoninterp \
--enable-perlinterp \
--enable-luainterp \
--enable-clipboard \
--enable-cscope --prefix=/usr \
&& make VIMRUNTIMEDIR=/usr/share/vim/vim74
&& sudo make install"
sh_safe "rm -rf /tmp/vim"
end
end
Package.install "luajit"
unless Dir.exists?(vim_path)
github('hlissner/vim', vim_path)
github('Shougo/neobundle.vim', "#{vim_path}/bundle/neobundle.vim")
end
end
@ -21,19 +42,25 @@ namespace :vim do
path = File.expand_path("~/.vim")
echo "Updating vim"
sh "cd #{path} && git pull"
sh_safe "cd #{path} && git pull"
echo "Updating vim plugins"
Dir.glob("#{path}/bundle/*") do |f|
echo ":: Updating #{File.basename(f)}:"
sh_safe "cd #{f} && git pull"
end
if is_linux?
echo "Can't update compiled vim itself! Use pkg:vim:install"
end
end
desc "Remove vim"
task :remove do
if is_mac?
echo "Uninstalling vim"
%w{vim macvim}.each { |pkg| Homebrew.remove pkg }
Package.remove "vim"
Package.remove "macvim"
end
end
end

View file

@ -5,7 +5,6 @@ desc "Ensure zsh and oh-my-zsh is installed and set"
task :zsh => 'zsh:update'
namespace :zsh do
task :install do
unless Dir.exists?(File.expand_path("~/.zprezto"))
echo "Installing prezto"
@ -23,11 +22,9 @@ namespace :zsh do
task :update => "zsh:install" do
echo "Updating zprezto"
sh_safe 'cd ~/.zprezto && git pull'
# TODO: pull from parent repo
end
task :remove do
sh_safe 'rm -rf ~/.zprezto' if Dir.exists?(File.expand_path("~/.zprezto"))
end
end

18
rake/provision.rake Normal file
View file

@ -0,0 +1,18 @@
require_relative 'lib/output'
desc "Update the node (based on hostname)"
task :default, :node do |t, args|
args.with_defaults(:node => `hostname`.gsub('.local', '').strip)
Rake::Task["setup:#{args.node}"].invoke
end
desc "Wipe the slate clean"
task :destroy do
# are you sure?
# are you really really sure?
# TODO: EXTERMINATE!
end
namespace :setup do
load_all("node/*.rake")
end

View file

@ -1,16 +0,0 @@
require_relative 'lib/output'
desc "Update the node (based on hostname)"
task :default, :node do |t, args|
args.with_defaults(:node => `hostname`.gsub('.local', '').strip)
Rake::Task["setup:#{args.node}"].invoke
end
desc "Wipe the slate clean"
task :destroy do
# are you sure?
# are you really really sure?
# TODO: EXTERMINATE!
end
namespace :setup do load_all("node/*.rake") end