From 6e50eb68ef40fa4523ec3cb2f1edc6d00822c671 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Sun, 14 Jun 2020 03:16:00 -0600 Subject: [PATCH] update _examples and README.md --- README.md | 98 +++++++++++++------------ _example/install.bash | 123 +++++++++++++++++--------------- _example/install_safe_copy.bash | 14 ++++ 3 files changed, 126 insertions(+), 109 deletions(-) create mode 100644 _example/install_safe_copy.bash diff --git a/README.md b/README.md index 27acc3a..9a01abc 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ Just copy the format from any of the existing packages. It's like this: `my-new-package.bash`: -``` +```` # title: Node.js # homepage: https://nodejs.org # tagline: JavaScript V8 runtime @@ -55,13 +55,15 @@ Just copy the format from any of the existing packages. It's like this: # node -e 'console.log("Hello, World!")' # > Hello, World! # ``` -``` +```` ### 1. Fetch Releases -All you're doing in this step is just translating from one form of JSON or CSV or TAB or whatever, to a format understood by `webi`. +All you're doing in this step is just translating from one form of JSON or CSV +or TAB or whatever, to a format understood by `webi`. -- Using Github releases? See `ripgrep/releases.js` (which uses `_common/github.js`) +- Using Github releases? See `ripgrep/releases.js` (which uses + `_common/github.js`) - Have a special format? See `golang/releases.js` or `node/releases.js`. It looks like this: @@ -78,67 +80,61 @@ module.exports = function (request) { }; ``` -### 2. Version Check (semi-optional) +### 2. Bash Installer -If the thing is already installed, we don't need to download and install it again. +1. Variables _you_ can set +2. Functions _you_ must define +3. Convenience / Helper Functions -You create a version check that looks like this: +(optional, if needed) Bash variables that you _may_ define: -``` - # if the output is "foobar 1.3.4", we just need the "1.3.4" - cur_ver=$(foobar --version | cut -d ' ' -f 2) -``` +```bash +# Define this if the package name is different from the command name (i.e. golang => go) +pkg_cmd_name="foobar" -And then you wrap it in some **boilerplate** (copy/paste/replace) that looks like this: +# These are used for symlinks, PATH, and test commands +pkg_common_opt="$HOME/.local/opt/foobar" +pkg_common_bin="$HOME/.local/opt/foobar/bin" +pkg_common_cmd="$HOME/.local/opt/foobar/bin/foobar" +# These are the _real_ locations for the above +pkg_new_opt="$HOME/.local/opt/foobar-v$WEBI_VERSION" +pkg_new_bin="$HOME/.local/opt/foobar-v$WEBI_VERSION/bin" +pkg_new_cmd="$HOME/.local/opt/foobar-v$WEBI_VERSION/bin/foobar" ``` -new_foobar="${HOME}/.local/bin/foobar" - -# Test for existing version -set +e -current_foobar="$(command -v foobar)" -set -e -if [ -n "$current_foobar" ]; then - # if the output is "foobar 1.3.4", we just need the "1.3.4" - cur_ver=$(foobar --version | cut -d ' ' -f 2) - if [ "$cur_ver" == "$WEBI_VERSION" ]; then - echo "foobar v$WEBI_VERSION already installed at $current_foobar" - exit 0 - elif [ "$current_foobar" != "$new_foobar" ]; then - echo "WARN: possible conflict with foobar v$WEBI_VERSION at $current_foobar" - fi -fi -``` - -### 3. Move files to $HOME/.local - -The `webi_download` and `webi_extract` functions will handle download and unpacking. -All you have to do is move your files into the right place. -If you have a single binary that'll look like this: +(required) A version check function that strips all non-version junk -``` - mv ./foobar-*/bin/foobar "$HOME/.local/bin/" +```bash +pkg_get_current_version() { + # foobar-v1.1.7 => 1.1.7 + echo "$(foobar --version | head -n 1 | sed 's:foobar-v::')" +} ``` -If you have something with more parts it'll look like this: +For the rest of the functions you can like copy/paste from the examples: -``` - if [ -n "$(command -v rsync 2>/dev/null | grep rsync)" ]; then - rsync -Krl ./foobar*/ "$new_foobar_home/" 2>/dev/null - else - cp -Hr ./foobar*/* "$new_foobar_home/" 2>/dev/null - cp -Hr ./foobar*/.* "$new_foobar_home/" 2>/dev/null - fi -``` +```bash +pkg_format_cmd_version() {} # Optional, pretty prints version + +pkg_link_new_version() {} # Required, may be empty for $HOME/.local/bin commands -### 4. Update PATH +pkg_pre_install() { # Required, runs any webi_* commands + webi_check # for $HOME/.local/opt tools + webi_download # for things that have a releases.js + webi_extract # for .xz, .tar.*, and .zip files +} -Typically speaking, `$HOME/.local/bin` will be added to the PATH for you. +pkg_install() {} # Required, usually just needs to rename extracted folder to + # "$HOME/.local/opt/$pkg_cmd_name-v$WEBI_VERSION" -However, you should call `webi_path_add` to add any special paths. +pkg_post_install() { # Required + pkg_link_new_version # should probably call pkg_link_new_version() + webi_path_add "$pkg_common_bin" # should probably update PATH +} -Again, just look at the examples. +pkg_post_install_message() {} # Optional, pretty print a success message +``` ## Script API @@ -149,6 +145,7 @@ These variables will be set by the server: ``` WEBI_PKG=example@v1 WEBI_NAME=example +WEBI_TAG=v1 WEBI_HOST=https://webinstall.dev WEBI_RELEASES=https://webinstall.dev/api/releases/example@v1?os=macos&arch=amd64&pretty=true WEBI_CSV=v1.0.2, @@ -168,6 +165,7 @@ WEBI_TMP=${WEBI_TMP:-"$(mktemp -d -t webinstall-foobar.XXXXXXXX)"} ``` ```bash +webi_check # Checks to see if the selected version is already installed (and re-links if so) webi_download # Downloads the selected release to $HOME/Downloads/.tar.gz webi_extract # Extracts the download to /tmp/-/ webi_path_add /new/path # Adds /new/path to PATH for bash, zsh, and fish diff --git a/_example/install.bash b/_example/install.bash index 824bf5d..9513225 100644 --- a/_example/install.bash +++ b/_example/install.bash @@ -5,76 +5,81 @@ set -e set -u -################### -# Install foobar # -################### - -common_opt="${HOME}/.local/opt/foobar-v${WEBI_VERSION}" -new_opt="${HOME}/.local/opt/foobar-v${WEBI_VERSION}" -new_bin="${HOME}/.local/opt/foobar-v${WEBI_VERSION}/bin/foobar" - -update_installed() { - rm -rf "$common_opt" - ln -s "$new_opt" "$common_opt" - - # TODO get better output from pathman / output the path to add as return to webi bootstrap - webi_path_add "$common_opt/bin" - webi_path_add "$HOME/foobar/bin" +## The defaults can be assumed if these are not set + +## The command name may be different from the package name +## (i.e. golang => go, rustlang => cargo, ripgrep => rg) +## Note: $HOME may contain special characters and should alway be quoted + +pkg_cmd_name="xmpl" + +## Some of these directories may be the same, in some cases +#pkg_common_opt="$HOME/.local/opt/xmpl" +#pkg_common_bin="$HOME/.local/opt/xmpl/bin" +#pkg_common_cmd="$HOME/.local/opt/xmpl/bin/xmpl" + +#pkg_new_opt="$HOME/.local/opt/xmpl-v$WEBI_VERSION" +#pkg_new_bin="$HOME/.local/opt/xmpl-v$WEBI_VERSION/bin" +#pkg_new_cmd="$HOME/.local/opt/xmpl-v$WEBI_VERSION/bin/xmpl" + +# Different packages represent the version in different ways +# ex: node v12.8.0 (leading 'v') +# ex: go1.14 (no space, nor trailing '.0's) +# ex: flutter 1.17.2 (plain) +pkg_format_cmd_version() { + my_version=$1 + echo "$pkg_cmd_name v$my_version" } -if [ -x "$new_opt/bin/foobar" ]; then - update_installed - exit 0 -fi +# The version info should be reduced to a sortable version, without any leading characters +# (i.e. v12.8.0 => 12.8.0, go1.14 => 1.14, 1.12.13+hotfix => 1.12.13+hotfix) +pkg_get_current_version() { + echo "$(xmpl --version 2>/dev/null | head -n 1 | cut -d' ' -f2)" +} -# Test for existing version -set +e -cur_go="$(command -v foobar)" -set -e -if [ -n "$cur_go" ]; then - cur_ver=$(foobar version | cut -d' ' -f3 | sed 's:foobar::') - if [ "$cur_ver" == "$(echo $WEBI_VERSION | sed 's:\.0::g')" ]; then - echo "foobar v$WEBI_VERSION already installed at $cur_go" - exit 0 - elif [ "$cur_go" != "$new_bin" ]; then - echo "WARN: possible conflict with foobar v$WEBI_VERSION at $cur_go" - fi -fi +# For (re-)linking to the desired installed version +# (for example: 'go' is special and needs both $HOME/go and $HOME/.local/opt/go) +# (others like 'rg', 'hugo', and 'caddy' are single files that just get replaced) +pkg_link_new_version() { + rm -rf "$pkg_common_opt" + ln -s "$pkg_new_opt" "$pkg_common_opt" +} +pkg_pre_install() { + # web_* are defined in webi/template.bash at https://github.com/webinstall/packages -# Note: this file is `source`d by the true installer and hence will have the webi functions + # if selected version is installed, re-link it and quit + webi_check -# because we created releases.js we can use webi_download() -# downloads foobar to ~/Downloads -webi_download + # will save to ~/Downloads/$WEBI_PKG_FILE by default + webi_download -# because this is tar or zip, we can webi_extract() -# extracts to the WEBI_TMP directory, raw (no --strip-prefix) -webi_extract + # supported formats (.xz, .tar.*, .zip) will be extracted to $WEBI_TMP + webi_extract +} -pushd "$WEBI_TMP" 2>&1 >/dev/null - echo Installing foobar v${WEBI_VERSION} as "$new_bin" +# For installing from the extracted package tmp directory +pkg_install() { + pushd "$WEBI_TMP" 2>&1 >/dev/null - # simpler for single-binary commands - #mv ./example*/bin/example "$HOME/.local/bin" + # remove the versioned folder, just in case it's there with junk + rm -rf "$pkg_new_opt" - # best for packages and toolchains - rm -rf "$new_opt" - if [ -n "$(command -v rsync 2>/dev/null | grep rsync)" ]; then - rsync -Krl ./foobar*/ "$new_opt/" 2>/dev/null - else - cp -Hr ./foobar*/* "$new_opt/" 2>/dev/null - cp -Hr ./foobar*/.* "$new_opt/" 2>/dev/null - fi - rm -rf ./foobar* + # rename the entire extracted folder to the new location + # (this will be "$HOME/.local/opt/xmpl-v$WEBI_VERSION" by default) + mv ./"$pkg_cmd_name"* "$pkg_new_opt" -popd 2>&1 >/dev/null + popd 2>&1 >/dev/null +} -################### -# Update PATH # -################### +# For updating PATHs and installing companion tools +pkg_post_install() { + pkg_link_new_version -update_installed + # web_path_add is defined in webi/template.bash at https://github.com/webinstall/packages + webi_path_add "$pkg_common_bin" +} -echo "Installed 'foobar'" -echo "" +pkg_post_install_message() { + echo "Installed 'example' as 'xmpl'" +} diff --git a/_example/install_safe_copy.bash b/_example/install_safe_copy.bash new file mode 100644 index 0000000..1296ed0 --- /dev/null +++ b/_example/install_safe_copy.bash @@ -0,0 +1,14 @@ +# For installing from the extracted package tmp directory +pkg_install() { + pushd "$WEBI_TMP" 2>&1 >/dev/null + + if [ -n "$(command -v rsync 2>/dev/null | grep rsync)" ]; then + rsync -Krl ./xmpl*/ "$pkg_new_opt/" 2>/dev/null + else + cp -Hr ./xmpl*/* "$pkg_new_opt/" 2>/dev/null + cp -Hr ./xmpl*/.* "$pkg_new_opt/" 2>/dev/null + fi + rm -rf ./xmpl* + + popd 2>&1 >/dev/null +} -- 2.25.1