-
-
Save adamnew123456/8358f23f3ac8a3b9bb02 to your computer and use it in GitHub Desktop.
USM Fix
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
set -u | |
USAGE='Usage: usm COMMAND ... | |
usm help | |
usm init | |
usm copy-script | |
usm add SOFTWARE VERSION | |
usm set-current SOFTWARE VERSION | |
usm ls [SOFTWARE] [SOFTWARE] ... | |
usm path SOFTWARE VERSION | |
usm rm SOFTWARE VERSION' | |
HELP='Usage: usm COMMAND ... | |
Commands: | |
help | |
Show this help page. | |
init | |
Initializes a fresh USM repository. The location should be contained | |
in the environment variable USM_PATH - otherwise, $HOME/Apps | |
becomes the location for the new USM repository. | |
Note that this calls create-script automatically, and will thus | |
clobber the file $HOME/.usm-env | |
copy-script | |
Copies the USM startup script to $HOME/.usm-env | |
add SOFTWARE VERSION | |
Configures a directory for a new version of the given software. | |
Also, if there is no version of SOFTWARE already installed, then | |
VERSION becomes the default version. | |
set-current SOFTWARE VERSION | |
Sets VERSION to be the current version of SOFTWARE. This changes | |
which version is added to $PATH, $PKG_CONFIG_PATH, $MANPATH, and | |
whatever other variables are added via ~/.usm-env | |
ls [SOFTWARE...] | |
Lists out the software installed in USM, and all of the versions | |
of each software. If SOFTWARE is given, only versions of SOFTWARE | |
are listed. | |
path SOFTWARE VERSION | |
Gets the absolute path to the directory storing VERSION of | |
SOFTWARE. | |
rm SOFTWARE VERSION | |
Removes VERSION of SOFTWARE - if VERSION is the last remaining | |
version, then the whole directory containing SOFTWARE is removed.' | |
if [ -z "$USM_PATH" ]; then | |
echo '$USM_PATH not set - aborting' | |
exit 1 | |
fi | |
STARTUP_SCRIPT="`sed '1,/^BEGIN ENV SCRIPT/d' < "$0" | sed "s:%USM_PATH%:$USM_PATH:g"`" | |
# Make sure that a particular software-version combo exists - if not, then | |
# exit with an error | |
assert_software_exists() { | |
_SOFTWARE="$1" | |
_VERSION="$2" | |
test -d "$USM_PATH/$_SOFTWARE/$_VERSION" | |
_IS_A_DIRECTORY=$? | |
# Make sure that we include symlinks, otherwise a test for the version | |
# 'current' would always fail | |
test -L "$USM_PATH/$_SOFTWARE/$_VERSION" | |
_IS_A_LINK=$? | |
if [ $_IS_A_DIRECTORY -ne 0 -a $_IS_A_LINK -ne 0 ]; then | |
echo "$_VERSION of $_SOFTWARE does not exist" | |
exit 1 | |
fi | |
} | |
# Initializes the USM repository, by creating the root and running | |
# usm_copy_script | |
usm_init() { | |
echo "Creating $USM_PATH" | |
mkdir "$USM_PATH" | |
usm_copy_script | |
} | |
# Copies the startup script ($STARTUP_SCRIPT) into $HOME/.usm-env | |
usm_copy_script() { | |
echo "Writing startup script to $HOME/.usm-env" | |
echo "$STARTUP_SCRIPT" > "$HOME/.usm-env" | |
} | |
# Adds a directory for a new version of a software | |
usm_add() { | |
_SOFTWARE="$1" | |
_VERSION="$2" | |
if [ "$_VERSION" = "current" ]; then | |
echo "Cannot used the reserved name 'current' as a version" | |
exit 1 | |
fi | |
echo "Installing $_SOFTWARE $_VERSION" | |
# Make the base directory if this is the first version | |
if [ ! -d "$USM_PATH/$_SOFTWARE" ]; then | |
_IS_NEW=1 | |
mkdir "$USM_PATH/$_SOFTWARE" | |
else | |
_IS_NEW=0 | |
fi | |
# Make the directory for the version | |
mkdir "$USM_PATH/$_SOFTWARE/$_VERSION" | |
# If this is the first version, then update the current link to this | |
# version so the user isn't left without a 'current' | |
if [ $_IS_NEW -ne 0 ]; then | |
usm_set_current "$_SOFTWARE" "$_VERSION" | |
fi | |
} | |
# Sets the current version by updating a symbolic link | |
usm_set_current() { | |
assert_software_exists "$1" "$2" | |
_SOFTWARE="$1" | |
_VERSION="$2" | |
if [ "$_VERSION" = "current" ]; then | |
echo "Cannot used the reserved name 'current' as a version" | |
exit 1 | |
fi | |
echo "Making $_VERSION the current for $_SOFTWARE" | |
_CURRENT_SYMLINK="$USM_PATH/$_SOFTWARE/current" | |
rm -f "$_CURRENT_SYMLINK" | |
ln -s "$USM_PATH/$_SOFTWARE/$_VERSION" "$_CURRENT_SYMLINK" | |
} | |
# Lists the versions of a single software | |
list_software() { | |
# This is a little weird, but it is the most reliable way to ensure | |
# that a given software exists in general, since all of them have a | |
# 'current' version | |
assert_software_exists "$1" "current" | |
_SOFTWARE="$1" | |
echo "$_SOFTWARE" | |
_CURRENT_VERSION="$(readlink "$USM_PATH/$_SOFTWARE/current")" | |
for _VERSION in "$USM_PATH/$_SOFTWARE/"*; do | |
if [ "$_VERSION" != "$USM_PATH/$_SOFTWARE/current" ]; then | |
if [ "$_CURRENT_VERSION" = "$_VERSION" ]; then | |
echo "* $(basename "$_VERSION")" | |
else | |
echo "- $(basename "$_VERSION")" | |
fi | |
fi | |
done | |
} | |
# Lists the versions of all software given | |
usm_ls() { | |
if [ $# -eq 0 ]; then | |
# The goal here is to get a list of all the software contained inside | |
# $USM_PATH, in order. Since the shell should sort it for us, the only | |
# odd thing is the 'set -- ...' line, which is necessary to 'append' to | |
# the list of arguments | |
for _SOFTWARE in "$USM_PATH/"*; do | |
set -- "$@" "$_SOFTWARE" | |
done | |
fi | |
while [ $# -gt 0 ]; do | |
list_software "$(basename "$1")" | |
shift | |
done | |
} | |
# Prints out the absolute path to a particular software-version combo | |
usm_path() { | |
_SOFTWARE="$1" | |
_VERSION="$2" | |
echo "$USM_PATH/$_SOFTWARE/$_VERSION" | |
} | |
# Removes a version of a particular software, removing the software itself | |
# if this is the last version | |
usm_rm() { | |
assert_software_exists "$1" "$2" | |
_SOFTWARE="$1" | |
_VERSION="$2" | |
_CURRENT_VERSION="$(readlink "$USM_PATH/$_SOFTWARE/current")" | |
# If there is only one version left, then just remove the whole | |
# software directory - this actually counts all versions, excluding the | |
# 'current' symlink | |
_NUM_VERSIONS=0 | |
for _ITER_VERSION in "$USM_PATH/$_SOFTWARE/"*; do | |
if [ "$_ITER_VERSION" != "$USM_PATH/$_SOFTWARE/current" ]; then | |
_NUM_VERSIONS=$((_NUM_VERSIONS + 1)) | |
fi | |
done | |
if [ $_NUM_VERSIONS -eq 1 ]; then | |
echo "Only one version of $_SOFTWARE - deleting $_SOFTWARE" | |
rm -rf "$USM_PATH/$_SOFTWARE" | |
else | |
# Ensure that we're not deleting the current version, since that | |
# would leave the user's shell in a bad state (since they would have | |
# a dangling symlink) | |
if [ "$_CURRENT_VERSION" = "$USM_PATH/$_SOFTWARE/$_VERSION" ]; then | |
echo "$_VERSION is the current version - please select another" | |
echo "current version using 'usm set-current $_SOFTWARE VERSION'." | |
exit 1 | |
fi | |
echo "Removing $_SOFTWARE $_VERSION" | |
rm -rf "$USM_PATH/$_SOFTWARE/$_VERSION" | |
fi | |
} | |
if [ $# -eq 0 ]; then | |
echo "$USAGE" | |
exit 1 | |
fi | |
COMMAND=$1 | |
# Push all the other arguments forward so we don't have to deal with | |
# the command later. | |
shift | |
case "$COMMAND" in | |
help) | |
echo "$HELP" | |
exit 1;; | |
init) | |
if [ $# -ne 0 ]; then | |
echo "'usm init' takes 0 arguments, got $#" | |
exit 1 | |
fi | |
usm_init | |
;; | |
copy-script) | |
if [ $# -ne 0 ]; then | |
echo "'usm copy-script' takes 0 arguments, got $#" | |
exit 1 | |
fi | |
usm_copy_script ;; | |
add) | |
if [ $# -ne 2 ]; then | |
echo "'usm add SOFTWARE VERSION' takes 2 arguments, got $#" | |
exit 1 | |
fi | |
usm_add "$@" ;; | |
set-current) | |
if [ $# -ne 2 ]; then | |
echo "'usm set-current SOFTWARE VERSION' takes 2 arguments, got $#" | |
exit 1 | |
fi | |
usm_set_current "$@" ;; | |
ls) | |
usm_ls "$@" ;; | |
path) | |
if [ $# -ne 2 ]; then | |
echo "'usm path SOFTWARE VERSION' takes 2 arguments, got $#" | |
exit 1 | |
fi | |
usm_path "$@" ;; | |
rm) | |
if [ $# -ne 2 ]; then | |
echo "'usm rm SOFTWARE VERSION' takes 2 arguments, got $#" | |
exit 1 | |
fi | |
usm_rm "$@" ;; | |
*) | |
echo "$USAGE" | |
exit 1 ;; | |
esac | |
### The following embeds the literal content of the .usm-env script here, | |
### which is accessible via a bit of POSIX sed magic. | |
exit 0 | |
BEGIN ENV SCRIPT | |
#!/bin/sh | |
# This is the USM initialization file - source it from your shell RC file | |
# to load USM in your shell automatically, or source it from a script | |
# which needs USM to run. | |
USM_PATH="%USM_PATH%" | |
export USM_PATH | |
# Updates a : separated variable, if a specific entry is not already | |
# present | |
update_if_not_in_var() { | |
varname=$1 | |
value=$2 | |
varvalue="`eval echo '$'"$varname"`" | |
varupdate="$varname=\"$varvalue:$value\"" | |
echo "$varvalue" | grep -s -q "$value" || eval "$varupdate" | |
} | |
for f in "$USM_PATH"/*; do | |
update_if_not_in_var PATH "$f/current/bin" | |
update_if_not_in_var PKG_CONFIG_PATH "$f/current/lib/pkgconfig" | |
update_if_not_in_var MANPATH "$f/current/man" | |
update_if_not_in_var MANPATH "$f/current/share/man" | |
done | |
export PATH | |
export PKG_CONFIG_PATH | |
export MANPATH |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment