New path management system

This commit is contained in:
Ivan Malison 2016-01-05 19:50:42 -08:00
parent b54fd3c8aa
commit 25af0c8be8
3 changed files with 141 additions and 60 deletions

117
dotfiles/lib/python/shell_path.py Executable file
View File

@ -0,0 +1,117 @@
#!/usr/bin/env python
import argparse
import os
class PathList(object):
@classmethod
def from_string(cls, path_string, separator=':'):
non_empty_paths = [path for path in path_string.split(separator) if path]
return cls(non_empty_paths, separator=':')
def __init__(self, paths, separator=':'):
self.paths = paths
self.separator = separator
def __str__(self):
return self.with_separator(self.separator)
def with_separator(self, separator=None):
separator = separator or self.separator
deduped = []
included = set()
for path in self.paths:
normalized = os.path.normpath(path)
if normalized not in included:
included.add(normalized)
deduped.append(path)
return separator.join(
os.path.normpath(path) for path in deduped
)
def add(self, new_paths, after=False, target=None):
if target:
target_index = self.paths.index(target)
else:
target_index = 0
if after:
increment = 1 if target else len(self.paths)
target_index += increment
self.paths = self.paths[:target_index] + new_paths + self.paths[target_index:]
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Manipulate path variables.')
parser.add_argument(
'paths',
metavar='PATH',
type=str,
nargs='*',
help='paths to add',
)
parser.add_argument(
'--path-var',
help='the path var to add to.',
default='PATH',
)
parser.add_argument(
'--separator',
help='the separator of the path variable',
default=':',
)
parser.add_argument(
'--path-string',
help='the path string to edit',
default=None,
)
parser.add_argument(
'--after',
help=('whether to do the action after the target (if target is specified)'
'or the entire path variable'),
action='store_true',
default=True,
)
parser.add_argument(
'--before',
help='inverse of after',
dest='after',
action='store_false',
)
parser.add_argument(
'--target',
help='the target path',
default=None
)
parser.add_argument(
'--include-assignment',
action='store_true',
help='include the assignment command in output',
)
parser.add_argument(
'--print-separator',
help='separator to use for output',
default=None,
)
parser.add_argument(
'--path-lines',
help='use newlines to separate path output',
action='store_true',
default=False,
)
args = parser.parse_args()
path_string = args.path_string or os.environ.get(args.path_var, '')
path_list = PathList.from_string(path_string, separator=args.separator)
path_list.add(args.paths, after=args.after, target=args.target)
output_separator = '\n' if args.path_lines else args.print_separator
output_path = path_list.with_separator(separator=output_separator)
if args.include_assignment:
output = "export {}='{}'".format(args.path_var, output_path)
else:
output = output_path
print(output)

View File

@ -7,26 +7,31 @@ function _source_shellenv_files {
done
}
function add_to_path {
local result=$($HOME/.lib/python/shell_path.py --include-assignment "$@")
eval "$result"
}
function _setup_env {
_path_helper
idem_add_to_back_of_path "$HOME/.local/lib/python2.6/site-packages"
idem_add_to_back_of_path "$HOME/.rvm/bin"
idem_add_to_front_of_path "$HOME/bin"
hash brew 2>/dev/null && idem_add_to_front_of_path "$(brew --prefix coreutils)/libexec/gnubin"
idem_add_to_front_of_path "/usr/local/bin"
add_to_path "$HOME/.local/lib/python2.6/site-packages" --after
add_to_path "$HOME/.rvm/bin" --after
add_to_path "$HOME/bin"
hash brew 2>/dev/null && add_to_path "$(brew --prefix coreutils)/libexec/gnubin"
add_to_path "/usr/local/bin"
idem_add_to_back_of_path `python -c 'import sysconfig; print sysconfig.get_path("scripts")'`
add_to_path $(python -c 'import sysconfig; print sysconfig.get_path("scripts")') --before
if is_osx; then
export CFLAGS=-Qunused-arguments
export CPPFLAGS=-Qunused-arguments
idem_add_to_back_of_path "/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources"
add_to_path "/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources" --after
local JDK_LOCATION="$(find /Library/Java/JavaVirtualMachines -depth 1 | head -n 1)"
export JAVA_HOME="$JDK_LOCATION/Contents/Home"
export STUDIO_JDK=$JDK_LOCATION
export GRADLE_HOME="$(brew --prefix gradle)"
export ANDROID_HOME="$(brew --prefix android-sdk)"
idem_add_to_back_of_path "$ANDROID_HOME"
add_to_path "$ANDROID_HOME" --after
# Access gnu man pages.
hash brew 2> /dev/null && export MANPATH="$(brew --prefix)/opt/coreutils/libexec/gnuman:$MANPATH"
@ -35,10 +40,10 @@ function _setup_env {
is_osx && export VISUAL="which emacsclient -c -n"
fi
idem_add_to_front_of_path "$JAVA_HOME/bin"
add_to_path "$JAVA_HOME/bin"
idem_add_to_back_of_path "$HOME/.lib/python"
idem_add_to_back_of_path "/usr/local/sbin"
add_to_path "$HOME/.lib/python" --after
add_to_path "/usr/local/sbin" --after
# Load RVM into a shell session *as a function*
[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm"
@ -54,18 +59,18 @@ function _setup_env {
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm
export NODE_PATH="/usr/local/lib/node_modules/"
idem_add_to_front_of_path "$HOME/.local/bin"
idem_add_to_front_of_path "$HOME/.lib/python" 'PYTHONPATH'
add_to_path "$HOME/.local/bin"
add_to_path "$HOME/.lib/python" --path-var 'PYTHONPATH'
idem_add_to_front_of_path "$HOME/go" 'GOPATH'
idem_add_to_front_of_path "${GOPATH//://bin:}/bin"
add_to_path "$HOME/go" --path-var 'GOPATH'
add_to_path "${GOPATH//://bin:}/bin"
export RBENV_ROOT=/usr/local/var/rbenv
idem_add_to_front_of_path "$HOME/.rbenv/bin"
add_to_path "$HOME/.rbenv/bin"
hash rbenv 2> /dev/null && eval "$(rbenv init -)"
hash brew 2>/dev/null && idem_add_to_front_of_path "$(brew --prefix coreutils)/libexec/gnubin"
hash brew 2>/dev/null && add_to_path "$(brew --prefix coreutils)/libexec/gnubin"
idem_add_to_front_of_path "$HOME/.lib/bin"
add_to_path "$HOME/.lib/bin"
export ENVIRONMENT_SETUP_DONE="$(date)"
}

View File

@ -1,46 +1,5 @@
function path_lines {
target=${1-PATH}
if is_zsh; then
echo ${(P)target} | tr ':' '\n'
else
echo ${!target} | tr ':' '\n'
fi
}
function _add_to_front_of_path_lines {
target=${2-PATH}
echo $1
path_lines $target | grep -Ev "^$1$"
}
function _add_to_back_of_path_lines {
target=${2-PATH}
path_lines $target | grep -Ev "^$1$"
echo $1
}
function remove_trailing_colon {
sed 's|:*$||'
}
function add_to_front_of_path {
target=${2-PATH}
export $target="$(_add_to_front_of_path_lines $1 $target | tr '\n' ':' | remove_trailing_colon)"
}
function add_to_back_of_path {
target=${2-PATH}
export $target="$(_add_to_back_of_path_lines $1 $target | tr '\n' ':' | remove_trailing_colon)"
}
function idem_add_to_front_of_path {
target=${2-PATH}
exists_in_path_var $1 $target || add_to_front_of_path $1 $target
}
function idem_add_to_back_of_path {
target=${2-PATH}
exists_in_path_var $1 $target || add_to_back_of_path $1 $target
shell_path.py --path-lines "$@"
}
function indirect_expand {