diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..8fce0e1 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "assets/default/vim-settings"] + path = assets/default/vim-settings + url = https://github.com/ViViDboarder/vim-settings.git diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..d45ffc3 --- /dev/null +++ b/TODO.md @@ -0,0 +1,11 @@ +TODO +==== + +Refactor to have each application contained in a directory with their install script and assets so that they can be included in their own repos + +It would then be cool to distribute them individually and set them to be installed similar to Vundle + +recipe 'ViViDboarder/vim-settings' + +should clone that repo and run the install script inside + diff --git a/assets/default/abuse-the-force/atf-target b/assets/default/abuse-the-force/atf-target new file mode 100755 index 0000000..48ca592 --- /dev/null +++ b/assets/default/abuse-the-force/atf-target @@ -0,0 +1,96 @@ +#!/usr/bin/env ruby + +require 'base64' +require 'yaml' + +module AbuseTheForce + class Atf_Config + class << self + attr_accessor :targets, :active_target, :src, :root_dir, :notify + SETTINGS_FILE=".abusetheforce.yaml" + + def locate_root(path = '.') + + temp_path = path + + # Look for a settings file in this path and up to root + until File.file? File.join(temp_path, SETTINGS_FILE) + # If we hit root, stop + if temp_path == '/' + break + end + + # Didn't find one so go up one level + temp_path = File.absolute_path File.dirname(temp_path) + end + + # If we actually found it + if File.file? File.join(temp_path, SETTINGS_FILE) + # Return + return temp_path + else + # Return the original path + return path + end + + end + + # Loads configurations from yaml + def load() + + # Get the project root directory + @root_dir = locate_root + + if File.file? File.join(@root_dir, SETTINGS_FILE) + settings = YAML.load_file File.join(@root_dir, SETTINGS_FILE) + @targets = settings[:targets] + @src = settings[:src] + @notify = settings[:notify] + else + puts "No settings file found, creating one now" + # Settings file doesn't exist + # Create it + @targets = {} + @active_target = nil + @src = './src' + @notify = true + + dump_settings + end + + # Set the default target + @targets.values.each do |target| + # Check if this one is active + if target.active == true + # Set it if there is no default target set yet + if @active_target == nil + @active_target = target + else + puts "Two active targets set. Using #{@active_target.print}" + end + end + end + end + end + end + + # Class for holding a target + class Atf_Target + attr_accessor :name, :username, :password, :security_token, :host, :active + + def initialize(name, username, password, security_token, host="login.salesforce.com") + @name = name + @username = username + set_password(password) + @security_token = security_token + @host = host + @active = false; + end + end +end + +# Load config +AbuseTheForce::Atf_Config.load +# Print the target name +puts AbuseTheForce::Atf_Config.active_target.name + diff --git a/assets/default/bin/.gitkeep b/assets/default/bin/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/assets/default/bin/ghp b/assets/default/bin/ghp new file mode 100755 index 0000000..e31b07f --- /dev/null +++ b/assets/default/bin/ghp @@ -0,0 +1,21 @@ +# Function used to take a github http pull URL and automatically convert it to an ssh url + +if [[ "$1" == "" ]]; then + echo "Usage" + echo "ghp " + echo "Example" + echo "ghp https://github.com/user/repo branch" + echo + echo "This function will convert the URL into an ssh url and" + echo "then it will execute git pull --edit --no-ff to merge." + + return +fi + +# Expects $* to be in the form of htts://github.com/user/repo branch +URL=${1/http:\/\//git@} # Replace https:// with git@ at the beginning +URL=${URL/\//:} # Replace / with : before the user name + +# Echo the command so we can see what we actually executed +echo "git pull --edit --no-ff $URL $2" +git pull --edit --no-ff $URL $2 diff --git a/assets/default/bin/ghpr b/assets/default/bin/ghpr new file mode 100755 index 0000000..e651e53 --- /dev/null +++ b/assets/default/bin/ghpr @@ -0,0 +1,28 @@ +# Function used to checkout a pull request into it's own branch + +REMOTE="" +PRNUM="" + +if [[ "$1" == "" ]]; then + echo "Usage" + echo "ghpr " + echo "Example" + echo "ghpr origin 100" + echo + echo "This function will fetch and clone the pull request as" + echo "a branch." + + return +elif [[ "$2" == "" ]]; then + # No remote was supplied + PRNUM="$1" +else + REMOTE="$1" + PRNUM="$2" +fi + +echo "git fetch $REMOTE refs/pull/$PRNUM/head:PR_$PRNUM" +git fetch $REMOTE refs/pull/$PRNUM/head:PR_$PRNUM + +echo "Just fetched Pull Request #$PRNUM. To switch to this branch execute:" +echo "git checkout PR_$PRNUM" diff --git a/assets/default/bin/git-branch-name b/assets/default/bin/git-branch-name new file mode 100755 index 0000000..cf1e198 --- /dev/null +++ b/assets/default/bin/git-branch-name @@ -0,0 +1,3 @@ +#!/bin/bash +git rev-parse HEAD >&/dev/null || exit 1 +git branch --no-color | grep '^*' | cut -c 3- diff --git a/assets/default/bin/git-changed b/assets/default/bin/git-changed new file mode 100755 index 0000000..8b797aa --- /dev/null +++ b/assets/default/bin/git-changed @@ -0,0 +1,31 @@ +#! /bin/bash + +gitismerge () { + local sha=$1 + msha=$(git rev-list --merges ${sha}...${sha}~1) + # If commit returned is the one passed it, it is a merge + [ -z "$msha" ] && return 1 + return 0 +} + +if [ -z "$1" ]; then + + echo "Usage:" + echo "git-changed commit [commit 2]" + echo "" + echo "If one commit is provided:" + echo " Return a list of all files changed in that commit" + echo "" + echo "If two commits are provided:" + echo " Return a list of all files changed between commits" + + exit 0 +fi + +# If a merge, return only changes in that merge +if [ -z "$2" ] && gitismerge $1; then + git diff-tree --no-commit-id --name-only $1 +else + git diff --no-commit-id --name-only $1 $2 +fi + diff --git a/assets/default/bin/git-wtf b/assets/default/bin/git-wtf new file mode 100755 index 0000000..4a43548 --- /dev/null +++ b/assets/default/bin/git-wtf @@ -0,0 +1,365 @@ +#!/usr/bin/env ruby + +HELP = < +.git-wtfrc" and edit it. The config file is a YAML file that specifies the +integration branches, any branches to ignore, and the max number of commits to +display when --all-commits isn't used. git-wtf will look for a .git-wtfrc file +starting in the current directory, and recursively up to the root. + +IMPORTANT NOTE: all local branches referenced in .git-wtfrc must be prefixed +with heads/, e.g. "heads/master". Remote branches must be of the form +remotes//. +EOS + +COPYRIGHT = <. +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You can find the GNU General Public License at: http://www.gnu.org/licenses/ +EOS + +require 'yaml' +CONFIG_FN = ".git-wtfrc" + +class Numeric; def pluralize s; "#{to_s} #{s}" + (self != 1 ? "s" : "") end end + +if ARGV.delete("--help") || ARGV.delete("-h") + puts USAGE + exit +end + +## poor man's trollop +$long = ARGV.delete("--long") || ARGV.delete("-l") +$short = ARGV.delete("--short") || ARGV.delete("-s") +$all = ARGV.delete("--all") || ARGV.delete("-a") +$all_commits = ARGV.delete("--all-commits") || ARGV.delete("-A") +$dump_config = ARGV.delete("--dump-config") +$key = ARGV.delete("--key") || ARGV.delete("-k") +$show_relations = ARGV.delete("--relations") || ARGV.delete("-r") +ARGV.each { |a| abort "Error: unknown argument #{a}." if a =~ /^--/ } + +## search up the path for a file +def find_file fn + while true + return fn if File.exist? fn + fn2 = File.join("..", fn) + return nil if File.expand_path(fn2) == File.expand_path(fn) + fn = fn2 + end +end + +want_color = `git config color.wtf` +want_color = `git config color.ui` if want_color.empty? +$color = case want_color.chomp + when "true"; true + when "auto"; $stdout.tty? +end + +def red s; $color ? "\033[31m#{s}\033[0m" : s end +def green s; $color ? "\033[32m#{s}\033[0m" : s end +def yellow s; $color ? "\033[33m#{s}\033[0m" : s end +def cyan s; $color ? "\033[36m#{s}\033[0m" : s end +def grey s; $color ? "\033[1;30m#{s}\033[0m" : s end +def purple s; $color ? "\033[35m#{s}\033[0m" : s end + +## the set of commits in 'to' that aren't in 'from'. +## if empty, 'to' has been merged into 'from'. +def commits_between from, to + if $long + `git log --pretty=format:"- %s [#{yellow "%h"}] (#{purple "%ae"}; %ar)" #{from}..#{to}` + else + `git log --pretty=format:"- %s [#{yellow "%h"}]" #{from}..#{to}` + end.split(/[\r\n]+/) +end + +def show_commits commits, prefix=" " + if commits.empty? + puts "#{prefix} none" + else + max = $all_commits ? commits.size : $config["max_commits"] + max -= 1 if max == commits.size - 1 # never show "and 1 more" + commits[0 ... max].each { |c| puts "#{prefix}#{c}" } + puts grey("#{prefix}... and #{commits.size - max} more (use -A to see all).") if commits.size > max + end +end + +def ahead_behind_string ahead, behind + [ahead.empty? ? nil : "#{ahead.size.pluralize 'commit'} ahead", + behind.empty? ? nil : "#{behind.size.pluralize 'commit'} behind"]. + compact.join("; ") +end + +def widget merged_in, remote_only=false, local_only=false, local_only_merge=false + left, right = case + when remote_only; %w({ }) + when local_only; %w{( )} + else %w([ ]) + end + middle = case + when merged_in && local_only_merge; green("~") + when merged_in; green("x") + else " " + end + print left, middle, right +end + +def show b + have_both = b[:local_branch] && b[:remote_branch] + + pushc, pullc, oosync = if have_both + [x = commits_between(b[:remote_branch], b[:local_branch]), + y = commits_between(b[:local_branch], b[:remote_branch]), + !x.empty? && !y.empty?] + end + + if b[:local_branch] + puts "Local branch: " + green(b[:local_branch].sub(/^heads\//, "")) + + if have_both + if pushc.empty? + puts "#{widget true} in sync with remote" + else + action = oosync ? "push after rebase / merge" : "push" + puts "#{widget false} NOT in sync with remote (you should #{action})" + show_commits pushc unless $short + end + end + end + + if b[:remote_branch] + puts "Remote branch: #{cyan b[:remote_branch]} (#{b[:remote_url]})" + + if have_both + if pullc.empty? + puts "#{widget true} in sync with local" + else + action = pushc.empty? ? "merge" : "rebase / merge" + puts "#{widget false} NOT in sync with local (you should #{action})" + show_commits pullc unless $short + end + end + end + + puts "\n#{red "WARNING"}: local and remote branches have diverged. A merge will occur unless you rebase." if oosync +end + +def show_relations b, all_branches + ibs, fbs = all_branches.partition { |name, br| $config["integration-branches"].include?(br[:local_branch]) || +$config["integration-branches"].include?(br[:remote_branch]) } + if $config["integration-branches"].include? b[:local_branch] + puts "\nFeature branches:" unless fbs.empty? + fbs.each do |name, br| + next if $config["ignore"].member?(br[:local_branch]) || $config["ignore"].member?(br[:remote_branch]) + next if br[:ignore] + local_only = br[:remote_branch].nil? + remote_only = br[:local_branch].nil? + name = if local_only + purple br[:name] + elsif remote_only + cyan br[:name] + else + green br[:name] + end + + ## for remote_only branches, we'll compute wrt the remote branch head. otherwise, we'll + ## use the local branch head. + head = remote_only ? br[:remote_branch] : br[:local_branch] + + remote_ahead = b[:remote_branch] ? commits_between(b[:remote_branch], head) : [] + local_ahead = b[:local_branch] ? commits_between(b[:local_branch], head) : [] + + if local_ahead.empty? && remote_ahead.empty? + puts "#{widget true, remote_only, local_only} #{name} #{local_only ? "(local-only) " : ""}is merged in" + elsif local_ahead.empty? + puts "#{widget true, remote_only, local_only, true} #{name} merged in (only locally)" + else + behind = commits_between head, (br[:local_branch] || br[:remote_branch]) + ahead = remote_only ? remote_ahead : local_ahead + puts "#{widget false, remote_only, local_only} #{name} #{local_only ? "(local-only) " : ""}is NOT merged in (#{ahead_behind_string ahead, behind})" + show_commits ahead unless $short + end + end + else + puts "\nIntegration branches:" unless ibs.empty? # unlikely + ibs.sort_by { |v, br| v }.each do |v, br| + next if $config["ignore"].member?(br[:local_branch]) || $config["ignore"].member?(br[:remote_branch]) + next if br[:ignore] + local_only = br[:remote_branch].nil? + remote_only = br[:local_branch].nil? + name = remote_only ? cyan(br[:name]) : green(br[:name]) + + ahead = commits_between v, (b[:local_branch] || b[:remote_branch]) + if ahead.empty? + puts "#{widget true, local_only} merged into #{name}" + else + #behind = commits_between b[:local_branch], v + puts "#{widget false, local_only} NOT merged into #{name} (#{ahead.size.pluralize 'commit'} ahead)" + show_commits ahead unless $short + end + end + end +end + +#### EXECUTION STARTS HERE #### + +## find config file and load it +$config = { "integration-branches" => %w(heads/master heads/next heads/edge), "ignore" => [], "max_commits" => 5 }.merge begin + fn = find_file CONFIG_FN + if fn && (h = YAML::load_file(fn)) # yaml turns empty files into false + h["integration-branches"] ||= h["versions"] # support old nomenclature + h + else + {} + end +end + +if $dump_config + puts $config.to_yaml + exit +end + +## first, index registered remotes +remotes = `git config --get-regexp ^remote\.\*\.url`.split(/[\r\n]+/).inject({}) do |hash, l| + l =~ /^remote\.(.+?)\.url (.+)$/ or next hash + hash[$1] ||= $2 + hash +end + +## next, index followed branches +branches = `git config --get-regexp ^branch\.`.split(/[\r\n]+/).inject({}) do |hash, l| + case l + when /branch\.(.*?)\.remote (.+)/ + name, remote = $1, $2 + + hash[name] ||= {} + hash[name].merge! :remote => remote, :remote_url => remotes[remote] + when /branch\.(.*?)\.merge ((refs\/)?heads\/)?(.+)/ + name, remote_branch = $1, $4 + hash[name] ||= {} + hash[name].merge! :remote_mergepoint => remote_branch + end + hash +end + +## finally, index all branches +remote_branches = {} +`git show-ref`.split(/[\r\n]+/).each do |l| + sha1, ref = l.chomp.split " refs/" + + if ref =~ /^heads\/(.+)$/ # local branch + name = $1 + next if name == "HEAD" + branches[name] ||= {} + branches[name].merge! :name => name, :local_branch => ref + elsif ref =~ /^remotes\/(.+?)\/(.+)$/ # remote branch + remote, name = $1, $2 + remote_branches["#{remote}/#{name}"] = true + next if name == "HEAD" + ignore = !($all || remote == "origin") + + branch = name + if branches[name] && branches[name][:remote] == remote + # nothing + else + name = "#{remote}/#{branch}" + end + + branches[name] ||= {} + branches[name].merge! :name => name, :remote => remote, :remote_branch => "#{remote}/#{branch}", :remote_url => remotes[remote], :ignore => ignore + end +end + +## assemble remotes +branches.each do |k, b| + next unless b[:remote] && b[:remote_mergepoint] + b[:remote_branch] = if b[:remote] == "." + b[:remote_mergepoint] + else + t = "#{b[:remote]}/#{b[:remote_mergepoint]}" + remote_branches[t] && t # only if it's still alive + end +end + +show_dirty = ARGV.empty? +targets = if ARGV.empty? + [`git symbolic-ref HEAD`.chomp.sub(/^refs\/heads\//, "")] +else + ARGV.map { |x| x.sub(/^heads\//, "") } +end.map { |t| branches[t] or abort "Error: can't find branch #{t.inspect}." } + +targets.each do |t| + show t + show_relations t, branches if $show_relations || t[:remote_branch].nil? +end + +modified = show_dirty && `git ls-files -m` != "" +uncommitted = show_dirty && `git diff-index --cached HEAD` != "" + +if $key + puts + puts KEY +end + +puts if modified || uncommitted +puts "#{red "NOTE"}: working directory contains modified files." if modified +puts "#{red "NOTE"}: staging area contains staged but uncommitted files." if uncommitted + +# the end! diff --git a/assets/default/bin/reattach-to-user-namespace-tmux b/assets/default/bin/reattach-to-user-namespace-tmux new file mode 100755 index 0000000..485f751 --- /dev/null +++ b/assets/default/bin/reattach-to-user-namespace-tmux @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +if [[ "$(uname)" = "Darwin" ]]; then + reattach-to-user-namespace $@ +else + exec "$@" +fi diff --git a/assets/default/dotfiles/ackrc b/assets/default/dotfiles/ackrc new file mode 100644 index 0000000..3a8275b --- /dev/null +++ b/assets/default/dotfiles/ackrc @@ -0,0 +1,7 @@ +# Add support for sass +--type-set +sass=.sass,.scss + +# Add support for Salesforce +--type-set +apex=.cls,.trigger diff --git a/assets/default/dotfiles/antrc b/assets/default/dotfiles/antrc new file mode 100644 index 0000000..e7b2d66 --- /dev/null +++ b/assets/default/dotfiles/antrc @@ -0,0 +1,2 @@ +# Increase memory sizes for java using Ant +export ANT_OPTS="-Xmx2048m -Xms512m" diff --git a/assets/default/dotfiles/bash_alias b/assets/default/dotfiles/bash_alias new file mode 100644 index 0000000..94572ce --- /dev/null +++ b/assets/default/dotfiles/bash_alias @@ -0,0 +1,12 @@ +# git +alias gc='git commit $*' +alias gco='git checkout $*' +alias gl='git log $*' +alias gr='git rebase $*' +alias gs='git status $*' +alias gd='git diff $*' +alias tiga='tig --all' + +# cd +alias cd..='cd ..' + diff --git a/assets/default/dotfiles/bash_profile b/assets/default/dotfiles/bash_profile new file mode 100644 index 0000000..e5198c4 --- /dev/null +++ b/assets/default/dotfiles/bash_profile @@ -0,0 +1,70 @@ +# Set file as having been loaded to avoid looping +IS_BASH_PROFILE_LOADED=true +# If bashrc hasn't been loaded, load it +if [ -z "$IS_BASHRC_LOADED" ] ; then + source $HOME/.bashrc +fi + +# Some stuff is OS Dependent +DET_OS="unknown" +UNAME_STR=`uname` + +if [[ "$UNAME_STR" == "Darwin" ]]; then + DET_OS="mac" +elif [[ "$UNAME_STR" == "Linux" ]]; then + DET_OS="linux" +fi + +# Since this is a mac, source the bashrc +if [[ "$DET_OS" == "mac" ]]; then + # Bash Completion + if [ -f /opt/local/etc/profile.d/bash_completion.sh ]; then + . /opt/local/etc/profile.d/bash_completion.sh + fi + if [ -f /opt/local/share/bash-completion/completions/git-flow ]; then + . /opt/local/share/bash-completion/completions/git-flow + fi +fi + +# Git Branch PS +function parse_git_branch { + ref=$(git symbolic-ref HEAD 2> /dev/null) || return + echo " ("${ref#refs/heads/}")" +} + +function parse_atf_target { + #ignore for now + return + org=$(atf-target 2> /dev/null) || return + echo " [$org]" +} + +function parse_force_target { + `git config force.use 2> /dev/null` || return + org=$(force-target 2> /dev/null) || return + echo " [$org]" +} + +# Alias for colors +RED="\[\033[0;31m\]" +YELLOW="\[\033[0;33m\]" +GREEN="\[\033[0;32m\]" +ENDCOLOR="\[\e[0m\]" + +# New prompt format +PS1="\h \W$YELLOW\$(parse_git_branch)$ENDCOLOR$GREEN\$(parse_atf_target)$ENDCOLOR$GREEN\$(parse_force_target)$ENDCOLOR\$ " + +# Prompt Title +export PROMPT_COMMAND='echo -ne "\033]0;${PWD/#$HOME/~}\007"' + +# Set cursor colors +export CLICOLOR=1 +export LSCOLORS=ExFxCxDxBxegedabagacad + +# Set file as having been loaded to avoid looping +#IS_BASH_PROFILE_LOADED=true + +#if [ $IS_BASH_PROFILE_LOADED ] && [ $IS_BASHRC_LOADED ]; then +# IS_BASH_PROFILE_LOADED=false +# IS_BASHRC_LOADED=false +#fi diff --git a/assets/default/dotfiles/bashrc b/assets/default/dotfiles/bashrc new file mode 100644 index 0000000..5f37ccd --- /dev/null +++ b/assets/default/dotfiles/bashrc @@ -0,0 +1,44 @@ +DET_OS="unknown" +UNAME_STR=`uname` + +# Some settings are mac specific +if [[ "$UNAME_STR" == "Darwin" ]]; then + DET_OS="mac" +elif [[ "$UNAME_STR" == "Linux" ]]; then + DET_OS="linux" +fi + +# Source bash alaias +if [ -f ~/.bash_alias ]; then + . ~/.bash_alias +fi + +# Common paths for me +export PATH=$PATH:$ANT_HOME/bin +# Opt directory +export PATH=/opt/local/bin:/opt/local/sbin:$PATH +# Android SDK +if [[ "$DET_OS" == "linux" ]]; then + ANDROID_SDK=$HOME/workspace/adt-bundle-linux/sdk +elif [[ "$DET_OS" == "mac" ]]; then + ANDROID_SDK=$HOME/workspace/android-sdk-macosx + export PATH=$HOME/Library/Python/2.7/bin:$PATH +fi +export ANDROID_HOME=$ANDROID_SDK +export PATH=$PATH:$ANDROID_SDK/platform-tools:$ANDROID_SDK/tools +# Add RVM to PATH for scripting +export PATH=$PATH:$HOME/.rvm/bin +# Add ~/bin +export PATH=$HOME/bin:$PATH + +[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # Load RVM into a shell session *as a function* + +# Increase memory sizes for java using Ant +ANT_OPTS="-Xmx2048m -Xms512m" + +# Set file as having been loaded to avoid looping +IS_BASHRC_LOADED=true +# If an interactive shell and .bash_profile hasn't been loaded, load it +if [ -n "$PS1" ] && [ -z "$IS_BASH_PROFILE_LOADED" ] ; then + source $HOME/.bash_profile +fi diff --git a/assets/default/dotfiles/ctags b/assets/default/dotfiles/ctags new file mode 100644 index 0000000..5fb13ba --- /dev/null +++ b/assets/default/dotfiles/ctags @@ -0,0 +1,5 @@ +--langmap=c#:+.trigger +--langmap=c#:+.cls +--langmap=html:+.page +--langmap=html:+.component + diff --git a/assets/default/dotfiles/tmux.conf b/assets/default/dotfiles/tmux.conf new file mode 100644 index 0000000..469deaa --- /dev/null +++ b/assets/default/dotfiles/tmux.conf @@ -0,0 +1,58 @@ +# set default shell +set-option -g default-shell $SHELL + +# Sets xterm window title +set-option -g set-titles on +set-option -g set-titles-string '[#S:#I] #W' + +# copy and paster +set-option -g default-command "reattach-to-user-namespace-tmux bash" + +# look good +set -g default-terminal "screen-256color" + +# act like GNU screen +unbind C-b +#set -g prefix C-a +#set -g prefix C-Space +set -g prefix C-q +# Move thorugh panes with a repeat +#bind C-a select-pane -t :.+ +#bind C-Space select-pane -t :.+ +bind C-q select-pane -t :.+ + +# a mouse +set -g mode-mouse on +setw -g mouse-select-window on +setw -g mouse-select-pane on + +# easy splitting +bind | split-window -h -c "#{pane_current_path}" +bind - split-window -c "#{pane_current_path}" +bind _ split-window -c "#{pane_current_path}" + +# act like vim +setw -g mode-keys vi +# move between panes +bind h select-pane -L +bind j select-pane -D +bind k select-pane -U +bind l select-pane -R +# swap panes +bind-key -r J swap-pane -D +bind-key -r K swap-pane -U +# move between windows +bind-key -r C-h select-window -t :- +bind-key -r C-l select-window -t :+ +# use vim style copy mode +unbind [ +bind ` copy-mode +unbind p +bind p paste-buffer +bind -t vi-copy v begin-selection +bind -t vi-copy y copy-selection + +# after copying to a tmux buffer, hit y again to copy to clipboard +if-shell 'test "$(uname -s)" = "Darwin"' 'bind-key y run "tmux show-buffer | reattach-to-user-namespace pbcopy"' +if-shell 'test "$(uname -s)" = "Linux"' 'bind-key y run "tmux show-buffer | xclip -sel clip -i"' + diff --git a/assets/default/force-cli/force-target b/assets/default/force-cli/force-target new file mode 100755 index 0000000..a60fb89 --- /dev/null +++ b/assets/default/force-cli/force-target @@ -0,0 +1,3 @@ +#! /bin/bash + +force active | awk -F '.' '{ print $NF }' diff --git a/assets/default/vim-settings b/assets/default/vim-settings new file mode 160000 index 0000000..905e74f --- /dev/null +++ b/assets/default/vim-settings @@ -0,0 +1 @@ +Subproject commit 905e74f14a7af0ba632ecb3406af154e45e2a1a1 diff --git a/helpers/custom b/helpers/custom index 308df5a..fd052b1 100644 --- a/helpers/custom +++ b/helpers/custom @@ -3,3 +3,41 @@ ############################################################################## # Add your custom helpers here. Remember, this is just Bash! ############################################################################## + +function init_paths_and_vars { + # Directory for projects + WORKSPACE=$HOME/workspace + # This is in bashrc + USER_BIN=$HOME/bin + # Temp dir for downloads + TMP_DIR=$PROJECT_DIR/tmp + # System uname + UNAME_STR=`uname` + + # Create workspace dir + mkdir -p $WORKSPACE + mkdir -p $USER_BIN + mkdir -p $TMP_DIR +} + +function source_dotfile { + + local RC_PATH=$1 + local RC_NAME=`basename $1` + local SOURCE_CMD="source" + + # If a source command was passed in, we can use that + [ "$2" != "" ] && SOURCE_CMD=$2 + + # Check if .bash* file exists + if [[ ! ( -f "$HOME/.$RC_NAME" ) ]]; then + # Create a blank one + touch "$HOME/.$RC_NAME" + fi + + try_link "$RC_PATH" "$HOME/.${RC_NAME}_sync" + + add_line "#import $RC_NAME from synced" "$HOME/.$RC_NAME" + add_line "$SOURCE_CMD ~/.${RC_NAME}_sync" "$HOME/.$RC_NAME" +} + diff --git a/helpers/default b/helpers/default index 24a50da..ff0bf2d 100644 --- a/helpers/default +++ b/helpers/default @@ -135,6 +135,32 @@ package_update () { apt-get update -y elif [ "$PACKAGE_MANAGER" == 'yum' ]; then yum check-update -y + elif [ "$PACKAGE_MANAGER" == 'port' ]; then + port selfupdate + elif [ "$PACKAGE_MANAGER" == 'brew' ]; then + brew update + else + error "Unknown package manager: $PACKAGE_MANAGER" + fi + + if [ $? -ne 0 ]; then + error "An error occured while updating packages. Fail!" + else + spacer 2 + fi +} + + +sudo_package_update () { + log "Updating package manager..." 0 1 + detect_package_manager + + if [ "$PACKAGE_MANAGER" == 'apt-get' ]; then + sudo apt-get update -y + elif [ "$PACKAGE_MANAGER" == 'yum' ]; then + sudo yum check-update -y + elif [ "$PACKAGE_MANAGER" == 'port' ]; then + sudo port selfupdate elif [ "$PACKAGE_MANAGER" == 'brew' ]; then brew update else @@ -166,6 +192,39 @@ package () { DEBIAN_FRONTEND=noninteractive apt-get install -y --force-yes $1 elif [ "$PACKAGE_MANAGER" == 'yum' ]; then yum install -y $1 + elif [ "$PACKAGE_MANAGER" == 'port' ]; then + port install $1 + elif [ "$PACKAGE_MANAGER" == 'brew' ]; then + brew install $1 + else + error "Unknown package manager: $PACKAGE_MANAGER" + fi + + if [ $? -ne 0 ]; then + error "An error occured while installing package '$1'. Fail!" + else + spacer 2 + fi +} + + +sudo_package () { + log "Installing package '$1'..." + detect_package_manager + + test_package_installed $1 > /dev/null 2>&1 + + if [ $? -eq 0 ]; then + log "Package '$1' is already installed. Skipping." + return 0 + fi + + if [ "$PACKAGE_MANAGER" == 'apt-get' ]; then + DEBIAN_FRONTEND=noninteractive sudo apt-get install -y --force-yes $1 + elif [ "$PACKAGE_MANAGER" == 'yum' ]; then + sudo yum install -y $1 + elif [ "$PACKAGE_MANAGER" == 'port' ]; then + sudo port install $1 elif [ "$PACKAGE_MANAGER" == 'brew' ]; then brew install $1 else @@ -213,6 +272,8 @@ detect_package_manager () { PACKAGE_MANAGER='apt-get' elif command_exist yum; then PACKAGE_MANAGER='yum' + elif command_exist port; then + PACKAGE_MANAGER='port' elif command_exist brew; then PACKAGE_MANAGER='brew' else @@ -236,19 +297,76 @@ command_exist () { copy () { local cookbook_assets_source="$COOKBOOK_ASSETS_PATH/$1" local default_assets_source="$DEFAULT_ASSETS_PATH/$1" - local target=$2 + local target="$2" - if [ -f $cookbook_assets_source ]; then + if [ -f "$cookbook_assets_source" ]; then log "Copying $cookbook_assets_source to $target..." - cp $cookbook_assets_source $target - elif [ -f $default_assets_source ]; then + cp "$cookbook_assets_source" "$target" + elif [ -f "$default_assets_source" ]; then log "Copying $default_assets_source to $target..." - cp $default_assets_source $target + cp "$default_assets_source" "$target" else error "Could not find '$1' to copy. Fail!" fi } +# +# Link a file from the assets folder to the specified location. +# +link () { + local src="$1" + local cookbook_assets_source="$COOKBOOK_ASSETS_PATH/$1" + local default_assets_source="$DEFAULT_ASSETS_PATH/$1" + local target="$2" + + if [ -f "$src" ]; then + src="$src" + elif [ -f "$cookbook_assets_source" ]; then + src="$cookbook_assets_source" + elif [ -f $default_assets_source ]; then + src="$default_assets_source" + elif [ -d "$cookbook_assets_source" ]; then + src="$cookbook_assets_source" + elif [ -d $default_assets_source ]; then + src="$default_assets_source" + else + error "Could not find '$1' to link Fail!" + fi + + ln -s "$src" "$target" +} + +# +# Attempt to link a file if it doesn't already exist +# +try_link () { + local src="$1" + local cookbook_assets_source="$COOKBOOK_ASSETS_PATH/$1" + local default_assets_source="$DEFAULT_ASSETS_PATH/$1" + local target="$2" + + if [ -f "$src" ]; then + src="$src" + elif [ -f "$cookbook_assets_source" ]; then + src="$cookbook_assets_source" + elif [ -f $default_assets_source ]; then + src="$default_assets_source" + elif [ -d "$cookbook_assets_source" ]; then + src="$cookbook_assets_source" + elif [ -d $default_assets_source ]; then + src="$default_assets_source" + else + error "Could not find '$1' to link Fail!" + fi + + if [ -L "$2" ] && [ "$(readlink $2)" == "$src" ] ; then + log "Link already exists: $2" + else + log "Creating link: $2 -> $src" + link "$1" "$2" + fi +} + # # Add a user to the system. # @@ -299,13 +417,13 @@ run_as () { # Add line to a file if line is not already present # add_line () { - local line=$1 - local file=$2 - grep "$line" $file > /dev/null 2>&1 + local line="$1" + local file="$2" + grep "$line" "$file" > /dev/null 2>&1 if [ $? -ne 0 ]; then log "Adding '$line' to '$file'..." - echo "$line" >> $file + echo "$line" >> "$file" else log "'$line' already in '$file'. Skipping." fi @@ -330,7 +448,7 @@ fail_if_not_root () { # # Checks if a certain element has already been installed. # -function is_installed () { +is_installed () { local args=$* local name=${args//[ \/:@]/-} @@ -346,10 +464,24 @@ function is_installed () { # # Sets an element as installed. # -function set_installed () { +set_installed () { local args=$* local name=${args//[ \/:@]/-} mkdir -p ~/.shoestrap/installed touch ~/.shoestrap/installed/$name -} \ No newline at end of file +} + +# +# Promts a user for a Yn confirmation +# + +prompt_yn () { + read -p "$1 [y/n] " -n 1 -r + echo # move to a new line + if [[ $REPLY =~ ^[Yy]$ ]]; then + return 0 + fi + + return 1 +} diff --git a/my-cookbook b/my-cookbook index dad17d3..74a6ec6 100755 --- a/my-cookbook +++ b/my-cookbook @@ -7,28 +7,82 @@ ### Customizations start here ################################ ############################################################## -fail_if_not_root # Comment out if 'root' is not required. +# Get current directory for future use in links +cd $(dirname $0) +PROJECT_DIR=$(pwd) -### Install packages -# package_update -# package 'git-core' -# package 'vim screen htop curl wget traceroute' -# package 'build-essential' -# package 'libjpeg-progs' -# package 'libmagickwand-dev imagemagick' -# package 'libsqlite3-dev' +detect_package_manager -### Users -# add_user 'deploy' ; recipe 'setup_keys' 'deploy' ; recipe 'customize_bash' 'deploy' ; recipe 'add_sudoer' 'deploy' +init_paths_and_vars + +# Do prompting early to make longer install easier +install_packages=false +if ! is_installed "packages" || prompt_yn "Reinstall packages?" ; then + install_packages=true +fi + +install_vim_src=false +if [ "$PACKAGE_MANAGER" == 'apt-get' ]; then + # Optional + is_installed "vim-from-source" + if prompt_yn "Compile vim?" ; then + install_vim_src=true + fi +fi + +install_vim_settings=false +if ! is_installed "vim-settings" || prompt_yn "Reinstall vim-settings?" ; then + install_vim_settings=true +fi + +# Optional +install_sfdc=false +is_installed "salesforce" +if prompt_yn "Install Salesforce tools?" ; then + install_sfdc=true +fi + +# Optional +install_golang=false +is_installed "golang" +if prompt_yn "Install Go?" ; then + install_golang=true +fi ### Run recipes -# recipe 'secure_ssh' -# recipe 'rbenv' -# recipe 'ruby' '1.9.3-p125' -# recipe 'nginx' -# recipe 'memcached' '1.4.13' -# recipe 'mariadb' +recipe 'dotfiles' +recipe 'bin' +recipe 'git' + +git submodule init +git submodule update + +if $install_packages ; then + recipe 'packages' + set_installed "packages" +fi + +if $install_vim_src ; then + recipe 'compile-install-vim' + set_installed "vim-from-source" +fi + +if $install_vim_settings ; then + recipe 'vim-settings' + set_installed 'vim-settings' +fi + +if $install_sfdc ; then + recipe 'salesforce' + set_installed 'salesforce' +fi + +if $install_golang ; then + recipe 'golang' + set_installed 'golang' +fi ### Show the Finished banner finished +# vim: set tabstop=2:softtabstop=2:shiftwidth=2:expandtab diff --git a/no-sudo b/no-sudo new file mode 100755 index 0000000..0c5d2f5 --- /dev/null +++ b/no-sudo @@ -0,0 +1,57 @@ +#!/bin/bash + +# Initialization - DO NOT REMOVE +. helpers/initialize + +############################################################## +### Customizations start here ################################ +############################################################## + +# Get current directory for future use in links +cd $(dirname $0) +PROJECT_DIR=$(pwd) + +install_vim_src=false +if [ "$PACKAGE_MANAGER" == 'apt-get' ]; then + is_installed "vim-from-source" + if prompt_yn "Compile vim?" ; then + install_vim_src=true + fi +fi +install_vim_settings=false +if ! is_installed "vim-settings" || prompt_yn "Reinstall vim-settings?" ; then + install_vim_settings=true +fi +install_sfdc=false +is_installed "salesforce" +if prompt_yn "Install Salesforce tools?" ; then + install_sfdc=true +fi + +# Create workspace dir +mkdir -p ~/workspace + +### Run recipes +recipe 'dotfiles' +recipe 'bin' +recipe 'git' + +if $install_vim_src ; then + recipe 'compile-install-vim' + set_installed "vim-from-source" +fi + +if $install_vim_settings ; then + recipe 'vim-settings' + set_installed 'vim-settings' +fi + +if $install_sfdc ; then + recipe 'salesforce' + set_installed 'salesforce' +fi + +### Show the Finished banner +finished + +# vim: set tabstop=2:softtabstop=2:shiftwidth=2:expandtab diff --git a/recipes/default/abuse-the-force b/recipes/default/abuse-the-force new file mode 100644 index 0000000..592b1cb --- /dev/null +++ b/recipes/default/abuse-the-force @@ -0,0 +1,13 @@ +#! /bin/bash + +if [ ! -d $WORKSPACE/abuse-the-force ]; then + git clone https://github.com/ViViDboarder/abuse-the-force.git $WORKSPACE/abuse-the-force +fi + +cd $WORKSPACE/abuse-the-force && git pull && rake install + +# Ensure this is in the user PATH +for f in $DEFAULT_ASSETS_PATH/* ; do + try_link "$f" "$USER_BIN/$(basename $f)" +done + diff --git a/recipes/default/bin b/recipes/default/bin new file mode 100644 index 0000000..ba78b64 --- /dev/null +++ b/recipes/default/bin @@ -0,0 +1,6 @@ +#! /bin/bash + +for f in $DEFAULT_ASSETS_PATH/* ; do + try_link "$f" "$USER_BIN/$(basename $f)" +done + diff --git a/recipes/default/compile-install-vim b/recipes/default/compile-install-vim new file mode 100644 index 0000000..e73e4e3 --- /dev/null +++ b/recipes/default/compile-install-vim @@ -0,0 +1,37 @@ +#!/bin/bash + +local vim_dir="$WORKSPACE/vim" + +# Get the build dependencies +if [ "$PACKAGE_MANAGER" == 'apt-get' ]; then + sudo apt-get build-dep vim vim-gtk +fi +# TODO: Add pacman support + +# Build latest vim +if [ ! -d $vim_dir ]; then + hg clone https://vim.googlecode.com/ $vim_dir +fi + +# Go to workspace +cd $vim_dir + +# Use latest tagged source code +hg update -r 'max(tagged())' +# Configure vim with ruby, python and GTK +./configure --with-features=huge \ + --enable-pythoninterp \ + --enable-rubyinterp \ + --enable-gui=gtk2 + +# Compile +make +# Install newly compiled vim +sudo make install +# Link vi to vim out of convenience +vim_path=$(which vim) +sudo ln -s $vim_path ${vim_path:0:(-1)} + +# Go back to previous directory +cd $ROOT_DIR + diff --git a/recipes/default/dotfiles b/recipes/default/dotfiles new file mode 100644 index 0000000..93f511d --- /dev/null +++ b/recipes/default/dotfiles @@ -0,0 +1,12 @@ +#! /bin/bash + +# Link files that can't be sourced +try_link "ackrc" "$HOME/.ackrc" +try_link "antrc" "$HOME/.antrc" +try_link "ctags" "$HOME/.ctags" +try_link "tmux.conf" "$HOME/.tmux.conf" + +# Source files that can +source_dotfile "bashrc" +source_dotfile "bash_profile" +source_dotfile "bash_alias" diff --git a/recipes/default/force-cli b/recipes/default/force-cli new file mode 100644 index 0000000..b9e3bbf --- /dev/null +++ b/recipes/default/force-cli @@ -0,0 +1,15 @@ +#! /bin/bash + +# Some settings are mac specific +if [[ "$UNAME_STR" == "Darwin" ]]; then + wget -P $USER_BIN https://godist.herokuapp.com/projects/heroku/force/releases/current/darwin-amd64/force +elif [[ "$UNAME_STR" == "Linux" ]]; then + wget -P $USER_BIN https://godist.herokuapp.com/projects/heroku/force/releases/current/linux-amd64/force +fi + +chmod +x $USER_BIN/force + +for f in $DEFAULT_ASSETS_PATH/* ; do + try_link "$f" "$USER_BIN/$(basename $f)" +done + diff --git a/recipes/default/git b/recipes/default/git new file mode 100644 index 0000000..aef2dbc --- /dev/null +++ b/recipes/default/git @@ -0,0 +1,11 @@ +#! /bin/bash + +# Set some Git Config options +# Set vim as default git editor +git config --global core.editor "vim" +# Turn on colors +git config --global color.ui auto +# Set diff tool to vimdiff +git config --global diff.tool vimdiff +# Suppress launching prompt +git config --global difftool.prompt false diff --git a/recipes/default/golang b/recipes/default/golang new file mode 100644 index 0000000..ee65cb6 --- /dev/null +++ b/recipes/default/golang @@ -0,0 +1,13 @@ +#!/bin/bash + +version="1.3" + +if [[ "$UNAME_STR" == "Darwin" ]]; then + wget -P $TMP_DIR/ http://golang.org/dl/go${version}.darwin-amd64-osx10.8.pkg + installer -pkg $TMP_DIR/go${version}.darwin-amd64-osx10.8.pkg +elif [[ "$UNAME_STR" == "Linux" ]]; then + wget -P $TMP_DIR/ http://golang.org/dl/go${version}.linux-amd64.tar.gz + # Do something + echo "**** Install from $TMP_DIR/go${version}.linux-amd64.tar.gz" +fi + diff --git a/recipes/default/packages b/recipes/default/packages new file mode 100644 index 0000000..f23ee3a --- /dev/null +++ b/recipes/default/packages @@ -0,0 +1,29 @@ +#! /bin/bash + +sudo_package_update +sudo_package 'screen htop curl wget mercurial ctags tig pv' + +# Manager specific packages +case "$PACKAGE_MANAGER" in + "port") + sudo_package 'vim +ruby +python27' + sudo_package 'macvim +ruby +python27' + sudo_package 'git-core +bash_completion' + sudo_package 'the_silver_searcher' + ;; + "brew") + package 'vim' + sudo_package 'the_silver_searcher' + ;; + "apt-get") + if [ -n "$(apt-cache policy silversearcher-ag)" ] ; then + sudo_package 'silversearcher-ag' + fi + sudo_package 'build-essential bash-completion rubygems tmux vim gvim' + ;; +esac + +# Install ruby gems +# TODO: Install RVM and other ruby requirements and get ruby 1.9.2 +sudo gem install rake + diff --git a/recipes/default/salesforce b/recipes/default/salesforce new file mode 100644 index 0000000..2d8b61d --- /dev/null +++ b/recipes/default/salesforce @@ -0,0 +1,26 @@ +#! /bin/bash + +# TODO: Prompt for atf or force + +install_atf=false +if prompt_yn "Install Abuse the Force?" ; then + install_atf=true +fi + +install_fcli=false +if prompt_yn "Install Force Cli?" ; then + install_fcli=true +fi + +if $install_atf ; then + recipe 'abuse-the-force' +fi + +if $install_fcli ; then + recipe 'force-cli' +fi + +for f in $DEFAULT_ASSETS_PATH/* ; do + try_link "$f" "$USER_BIN/$(basename $f)" +done + diff --git a/recipes/default/vim-settings b/recipes/default/vim-settings new file mode 100644 index 0000000..2e97ed1 --- /dev/null +++ b/recipes/default/vim-settings @@ -0,0 +1,101 @@ +#! /bin/bash + +DET_OS="unknown" +UNAME_STR=`uname` + +# Some settings are mac specific +if [[ "$UNAME_STR" == "Darwin" ]]; then + DET_OS="mac" +elif [[ "$UNAME_STR" == "Linux" ]]; then + DET_OS="linux" +fi + +# Clone vundle if not done already +if [ ! -d ~/.vim/bundle/vundle ]; then + log "Installing vundle" + mkdir -p ~/.vim/bundle + git clone https://github.com/gmarik/vundle.git ~/.vim/bundle/vundle +fi + +# Make backup and tmp dirs +log "Building temp and backup dirs" +mkdir -p ~/.vim/backup +mkdir -p ~/.vim/tmp +mkdir -p ~/.vim/doc + +log "Link vim files" +try_link vimrc "$HOME/.vimrc_sync" +try_link vim "$HOME/.vim_sync" + +if [[ ( ! -f ~/.vimrc ) ]]; then + log "No ~/.vimrc found, creating one" + touch ~/.vimrc +fi + +# Source synced setting in vimrc +add_line '"import vimrc from synced' $HOME/.vimrc +add_line 'source ~/.vimrc_sync' $HOME/.vimrc + +add_line '"add vim directory from synced' ~/.vimrc +add_line 'set runtimepath+=$HOME/.vim_sync' ~/.vimrc + +log "Install all bundles" +vim +BundleInstall! +qall + +###### Possibly depreciate this section when using plug or neobundle + +# Compile CommandT if possible +# See if ruby is installed +if command -v ruby >/dev/null 2>&1; then + # Make sure GCC is installed + if command -v gcc >/dev/null 2>&1; then + # Use system ruby + command -v rvm >/dev/null 2>&1 && { rvm use system; } + log "Compile Command T's C extension" + cd ~/.vim/bundle/Command-T/ruby/command-t + ruby extconf.rb + make + fi +fi + +# Display warning methods related to Command T +vim --version | grep -q '\+ruby' || { log "Warning: Default vim does not include ruby as needed for Command T"; } +command -v ruby >/dev/null 2>&1 || { log "Warning: ruby required for Command T"; } +command -v gcc >/dev/null 2>&1 || { log "Warning: gcc required for Command T"; } + +# Execute vim's update of the helptags +VIM_RESULT=$(vim +"helptags ~/.vim/doc" +"q") + +if [[ "$VIM_RESULT" == *SEGV* ]]; then + log "Seg Faulted. Retry with different ruby" + cd ~/.vim/bundle/Command-T/ruby/command-t && /opt/local/bin/ruby* extconf.rb && make && cd - + + # Retry + vim +"helptags ~/.vim/doc" +"q" +fi + +# End command t + +log "Compile vimproc" +cd ~/.vim/bundle/vimproc.vim && make +cd - + +###### End compile plugins + +log "Install Powerline Fonts" +# Install Powerline Fonts +pf_dir="$workspace/powerline-fonts" +git clone https://github.com/Lokaltog/powerline-fonts $pf_dir + +# Setup vim-powerline with patched fonts +if [[ "$DET_OS" == "mac" ]]; then + #Install DejaVu + cp $pf_dir/DejaVuSansMono/*.ttf ~/Library/Fonts/ +elif [[ "$DET_OS" == "linux" ]]; then + #Install DejaVu + cp -r $pf_dir/DejaVuSansMono ~/.fonts/ + cp -r $pf_dir/UbuntuMono ~/.fonts/ + cp -r $pf_dir/SourceCodePro ~/.fonts/ + # Refresh cache + fc-cache -vf +fi diff --git a/test-cookbook b/test-cookbook new file mode 100755 index 0000000..9b5cad0 --- /dev/null +++ b/test-cookbook @@ -0,0 +1,25 @@ +#!/bin/bash + +# Initialization - DO NOT REMOVE +. helpers/initialize + +############################################################## +### Customizations start here ################################ +############################################################## + +# Get current directory for future use in links + +cd $(dirname $0) +PROJECT_DIR=$(pwd) + +WORKSPACE=$HOME/workspace +mkdir -p $WORKSPACE + +if prompt_yn "Install Salesforce tools?" ; then + recipe 'salesforce' +fi + +### Show the Finished banner +finished + +# vim: set tabstop=2:softtabstop=2:shiftwidth=2:expandtab