diff --git a/bin/composer b/bin/composer new file mode 100755 index 0000000..5496f4b Binary files /dev/null and b/bin/composer differ diff --git a/bin/dcdebug b/bin/dcdebug new file mode 100755 index 0000000..9f38775 --- /dev/null +++ b/bin/dcdebug @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +COMMAND=$1; +shift 1 + +if [ ! -f $COMMAND ]; then + COMMAND=`which ${COMMAND}` +fi + +if [ ! -f "${COMMAND}" ]; then + echo "Usage: ${0} " + exit 1; +fi + +PHP_IDE_CONFIG="serverName=local" XDEBUG_CONFIG="remote_enable=1 remote_mode=req remote_port=9000 remote_host=127.0.0.1 remote_connect_back=0" php -d zend_extension=xdebug.so $COMMAND "$@" diff --git a/bin/docker-php b/bin/docker-php new file mode 100755 index 0000000..0dc0302 --- /dev/null +++ b/bin/docker-php @@ -0,0 +1,2 @@ +#!/bin/bash +docker run --rm -it --entrypoint /usr/bin/php --user $(id -u):$(id -g) -e HOME="${HOME}" -v ${HOME}:${HOME} --workdir $(pwd) php:70 $@ diff --git a/bin/git-fixup b/bin/git-fixup new file mode 100755 index 0000000..a1210f7 --- /dev/null +++ b/bin/git-fixup @@ -0,0 +1,5 @@ +#!/bin/bash +set -e +TARGET=$(git rev-parse ${1}) +git commit --fixup=${TARGET} ${@:2} +EDITOR=true git rebase -i --autostash --autosquash ${TARGET}^; diff --git a/includes/bash_aliases.bash b/includes/bash_aliases.bash index 51bb90e..5a3f92b 100644 --- a/includes/bash_aliases.bash +++ b/includes/bash_aliases.bash @@ -15,8 +15,16 @@ alias t="tmux" alias x+="chmod +x" alias +x="chmod +x" +# Devstack +alias comup='pushd ~/src/comandi/dashboard; vagrant up; popd' +alias comdown='pushd ~/src/comandi/dashboard; vagrant halt; popd' + + +if [ `uname` == 'Linux' ]; then + alias open='xdg-open' +fi # Remove all local branches already merged in master. -alias gitclean='git branch --merged master | grep -v "\smaster$" | grep -v "*" | xargs git branch -d' +alias gitclean='git branch --merged master | grep -v "\smaster$" | grep -v "*" | xargs --no-run-if-empty git branch -d' alias gist='gist -c' # Detect which `ls` flavor is in use @@ -77,7 +85,7 @@ alias get="curl -O" alias dos2unix="perl -pi -e 's/\r\n?/\n/g'" # Password generator -password() { cat /dev/urandom | tr -dc A-Za-z0-9_ | head -c ${1:-10}; } +password() { cat /dev/urandom 2>/dev/null | tr -dc A-Za-z0-9_ 2>/dev/null | head --bytes=${1:-10}; } # Show $PATH in a readable way alias path='echo -e ${PATH//:/\\n}' diff --git a/includes/bash_functions.bash b/includes/bash_functions.bash index 20113a9..3c97aac 100644 --- a/includes/bash_functions.bash +++ b/includes/bash_functions.bash @@ -179,3 +179,8 @@ function git-private() for cmd in password hex2hsl hex2rgb escape codepoint ssh-key myip; do eval "function $cmd+() { $cmd \$@ | c; }" done + +function jira() +{ + open "https://comandi.atlassian.net/browse/CMD-${1}" +} diff --git a/includes/bash_ssh.bash b/includes/bash_ssh.bash new file mode 100644 index 0000000..d3d07d1 --- /dev/null +++ b/includes/bash_ssh.bash @@ -0,0 +1,11 @@ +#!/bin/bash +if [ -z "$SSH_AUTH_SOCK" ] ; then + eval `ssh-agent -s` +fi + +KEY="$HOME/.ssh/work" + +[ -f $KEY ] || return; + +ssh-add -l | grep $KEY > /dev/null || ssh-add $KEY + diff --git a/resources/git-template/hooks b/resources/git-template/hooks deleted file mode 120000 index 3380b4a..0000000 --- a/resources/git-template/hooks +++ /dev/null @@ -1 +0,0 @@ -/Users/jacobkiers/dotfiles/resources/git-hooks \ No newline at end of file diff --git a/resources/git-template/hooks/README.txt b/resources/git-template/hooks/README.txt new file mode 100644 index 0000000..809b52c --- /dev/null +++ b/resources/git-template/hooks/README.txt @@ -0,0 +1 @@ +You can add global git hooks in this directory. \ No newline at end of file diff --git a/resources/git-template/hooks/pre-commit b/resources/git-template/hooks/pre-commit new file mode 100755 index 0000000..2c6950f --- /dev/null +++ b/resources/git-template/hooks/pre-commit @@ -0,0 +1,266 @@ +#!/usr/bin/env php + /dev/null')) { + $against = 'HEAD'; +} + +// Only run when we're on a branch (to avoid rebase hell) +// http://git-blame.blogspot.nl/2013/06/checking-current-branch-programatically.html +$branch = run('git symbolic-ref --short -q HEAD'); +if (!$branch) { + writeln('Not on any branch'); + exit(0); +} + +/* + * collect all files which have been added, copied or + * modified and store them in an array called output + */ +$diffLines = array(); +exec('git diff-index --cached --full-index --diff-filter=ACM '.$against, $diffLines); + +writeln(); + +// Filter files that don't need a check. +foreach ($diffLines as $line) { + $partList = preg_split('#\s+#', $line, 6); + $hash = $partList[3]; + $status = $partList[4]; + $fileName = $partList[5]; + if ('D' === $status) { + // deleted file; do nothing + continue; + } + + $type = strtolower(pathinfo($fileName, PATHINFO_EXTENSION)); + $validator = 'validator_'.$type; + if (!$type || !function_exists($validator)) { + $type = run("git cat-file -p ".$hash." | head -n1 | awk -F/ '/^#\!/ {print \$NF}' | sed 's/^env //g'"); + $validator = 'validator_'.$type; + if (!function_exists($validator)) { + // No validator + writeln(' Skipping "'.format($fileName, 'green').'" no validator available.'); + continue; + } + } + + write(' Checking "'.format($fileName, 'green').'" with validator '.format($type, 'green').'.'); + + $output = ''; + if (!$validator($hash, $fileName, $output)) { + writeln(PHP_EOL.'X ERROR '.implode(PHP_EOL.' ', explode(PHP_EOL, $output)).PHP_EOL, 'red'); + $exit = 1; + continue; + } + writeln(' OK', 'green'); +} + +if ($exit > 0) { + writeln(PHP_EOL."Please fix the above errors and run 'git add'.", 'gray'); +} + +exit($exit); + +function validator_php($hash, $fileName, &$output) +{ + if (validator_php_syntax($hash, $fileName, $output)) { + return validator_php_cs($hash, $fileName, $output); + } + + return false; +} + +function validator_php_syntax($hash, $fileName, &$output) +{ + $output = ''; + $exitCode = 0; + + $result = run('git cat-file -p '.escapeshellarg($hash).' | php -l', $output, $exitCode, "purge", "default"); + if ($result) { + return true; + } + + $output = 'Syntax Error'.PHP_EOL.$output; + + return false; +} + +function validator_php_cs($hash, $fileName, &$output) +{ + // Use .php_cs config if project has one. + $configFile = ''; + if (file_exists('.php_cs')) { + $configFile = ' --config-file='.escapeshellarg(realpath('.php_cs')); + } + + $tmpDir = '/tmp/cs-check/'.$hash; + $tmp = $tmpDir.'/'.$fileName; + run('mkdir -p '.dirname($tmp)); + run('git cat-file -p '.escapeshellarg($hash).' > '.$tmp); + + $return = null; + run('php-cs-fixer fix --dry-run --verbose --level=symfony'.$configFile.' '.escapeshellarg($tmp), $currentOutput, $return, 'default', 'default'); + + run('rm -rf '.escapeshellarg($tmpDir)); + + // Check output + if ($return !== 0) { + $out = explode(PHP_EOL, $currentOutput); + + $rule = null; + foreach ($out as $line) { + if (preg_match('#\s+[0-9]+\)\s#', $line)) { + $rule = $line; + break; + } + } + + if ($rule !== null && preg_match('#\((.*)\)#', $rule, $matches)) { + $output = 'Code Style errors'.PHP_EOL.$matches[1]; + } else { + $output = 'Code Style errors'.PHP_EOL.implode(PHP_EOL, $out).PHP_EOL; + } + + return false; + } + + return true; +} + +/** + * Runs like exec with a few changes: + * - Output is returned as a string. + * - Output is NOT appended. + * - STDERR is also added to the output. + * - STDERR and/or STDOUT can be disabled by passing purge. + * - Returns the first output line if successful and false when failed. + * - If no output is generated and the exit status equals 0 then true is returned. + * + * @param string $command + * @param string &$output + * @param int &$exitCode + * @param string $stdout + * @param string $stderr + * + * @return boolean + */ +function run($command, &$output = '', &$exitCode = 0, $stdout = 'default', $stderr = 'purge') +{ + $descriptors = array( + 0 => array("pipe", "r"), // stdin + 1 => array("pipe", "w"), // stdout + 2 => array("pipe", "w"), // stderr + ); + + $pipes = array(); + + $out = array(); + $process = proc_open($command, $descriptors, $pipes); + fclose($pipes[0]); + unset($pipes[0]); + + do { + $read = $pipes; + $write = $except = array(); + if (!stream_select($read, $write, $except, 5)) { + writeln('Timeout on process: '.$command, 'red'); + break; + } + + foreach ($read as $pipe) { + $pipeId = array_search($pipe, $pipes); + if ($pipeId === false) { + writeln('Unable to determine where the output came from.', 'red'); + } + + if (feof($pipe)) { + fclose($pipe); + if ($pipeId !== false) { + unset($pipes[$pipeId]); + } + continue; + } + + $line = fgets($pipe); + if ($line === false) { + continue; + } + + $color = $stderr; + if ($pipeId == 1) { + $color = $stdout; + } + + if ($color != 'purge') { + $out[] = format(rtrim($line), $color); + } + } + } while (count($pipes) > 0); + + $exitCode = proc_close($process); + $output = implode(PHP_EOL, $out); + + if ($exitCode == 0) { + if (!isset($out[0]) || $out[0] == '') { + return true; + } + + return $out[0]; + } + + return false; +} + +function format($string, $color = 'default') +{ + if ($color == 'default') { + return $string; + } + + if ($color == 'purge') { + return ''; + } + + $colors = array( + 'gray' => 37, + 'green' => 32, + 'red' => 31, + ); + + if (!isset($colors[$color])) { + writeln($color.' is not a valid color.'); + exit(1); + } + + return chr(0x1B).'['.$colors[$color].'m'.$string.chr(0x1B).'[m'; +} + +function writeln($write = '', $color = 'default') +{ + write($write.PHP_EOL, $color); +} + +function write($write = '', $color = 'default') +{ + echo format($write, $color); + flush(); +} diff --git a/tilde/bash_profile.bash b/tilde/bash_profile.bash index 1cc299b..501f890 100644 --- a/tilde/bash_profile.bash +++ b/tilde/bash_profile.bash @@ -42,13 +42,16 @@ function _prepend_path() { # Construct $PATH PATH="/usr/bin:/bin:/usr/sbin:/sbin" -[ -d /usr/texbin ] && _prepend_path "/usr/texbin" [ -d /usr/local/sbin ] && _prepend_path "/usr/local/sbin" [ -d /usr/local/bin ] && _prepend_path "/usr/local/bin" -command -v brew >/dev/null 2>&1 && _prepend_path "$(brew --prefix coreutils)/libexec/gnubin" -[ -d $HOME/bin ] && _prepend_path "$HOME/bin" -[ -d $HOME/dotfiles/bin ] && _prepend_path "$HOME/dotfiles/bin" -[ -d "$COMPOSER_HOME/vendor/bin" ] && _prepend_path "$COMPOSER_HOME/vendor/bin" +[ -f /usr/bin/npm ] && _prepend_path "./node_modules/.bin" # Node.js +[ -d /usr/texbin ] && _prepend_path "/usr/texbin" # LaTex +[ -d $HOME/.cargo/bin ] && _prepend_path "$HOME/.cargo/bin" # Rust +command -v brew >/dev/null 2>&1 && _prepend_path "$(brew --prefix coreutils)/libexec/gnubin" # Homebrew +[ -d $HOME/.local/bin ] && _prepend_path "$HOME/.local/bin" # Local bin +[ -d $HOME/bin ] && _prepend_path "$HOME/bin" # ~/bin +[ -d $HOME/dotfiles/bin ] && _prepend_path "$HOME/dotfiles/bin" # Dotfiles bin +[ -d "$COMPOSER_HOME/vendor/bin" ] && _prepend_path "$COMPOSER_HOME/vendor/bin" # PHP Composer _prepend_path "./vendor/bin" export PATH @@ -86,9 +89,6 @@ fi # Tell ls to be colourful export CLICOLOR=1 -# Tell grep to highlight matches -export GREP_OPTIONS='--color=auto' - # Make less the default pager, and specify some useful defaults. less_options=( # If the entire text fits on one screen, just show it and quit. (Be more @@ -122,3 +122,5 @@ export PAGER='less' # Force a green prompt true + +export PATH="$HOME/.cargo/bin:$PATH" diff --git a/tilde/gitconfig b/tilde/gitconfig index 18f5259..8a8d2cd 100644 --- a/tilde/gitconfig +++ b/tilde/gitconfig @@ -15,7 +15,8 @@ editor = vim -f # http://stackoverflow.com/questions/136178/git-diff-handling-long-lines # If doesn't work, try: pager = less -+$LESS -FRX - pager = less -r + pager = diff-highlight | less -RFX +# pager = less -r autocrlf = false safecrlf = false mergeoptions = --no-edit @@ -70,11 +71,16 @@ # DiffMerge [merge] + ff = no + commit = no tool = diffmerge [mergetool "diffmerge"] cmd = diffmerge --merge --result=$MERGED $LOCAL $BASE $REMOTE trustExitCode = true [diff] + algorithm = minimal + compationHeuristic = true + renames = true tool = diffmerge [difftool "diffmerge"] cmd = diffmerge $LOCAL $REMOTE @@ -91,3 +97,5 @@ [init] templatedir = ~/dotfiles/resources/git-template +[pull] + ff = yes