generalize, a lot
authorAJ ONeal <aj@therootcompany.com>
Tue, 16 Jun 2020 10:45:54 +0000 (10:45 +0000)
committerAJ ONeal <aj@therootcompany.com>
Tue, 16 Jun 2020 10:45:54 +0000 (10:45 +0000)
66 files changed:
.gitignore [new file with mode: 0644]
README.md
_common/normalize.js [deleted file]
_example/install.bash [deleted file]
_example/install.sh [new file with mode: 0644]
_example/install_safe_copy.bash [deleted file]
_example/install_safe_copy.sh [new file with mode: 0644]
_example/releases.js
_webi/bootstrap.bat [new file with mode: 0644]
_webi/bootstrap.sh [new file with mode: 0644]
_webi/normalize.js [new file with mode: 0644]
_webi/packages.js [new file with mode: 0644]
_webi/releases.js [new file with mode: 0644]
_webi/template.sh [new file with mode: 0644]
_webi/test.js [new file with mode: 0755]
_webi/ua-detect.js [new file with mode: 0644]
_webi/webi.bat [new file with mode: 0644]
brew/install.bash [deleted file]
brew/install.sh [new file with mode: 0644]
caddy/install.bash [deleted file]
caddy/install.sh [new file with mode: 0644]
caddy/package.yash [new file with mode: 0644]
caddy/releases.js
flutter/install.bash [deleted file]
flutter/install.sh [new file with mode: 0644]
flutter/package.yash [new file with mode: 0644]
gitea/install.bash [deleted file]
gitea/install.sh [new file with mode: 0644]
gitea/package.yash [new file with mode: 0644]
gitea/releases.js
go/install.bash [deleted file]
go/install.sh [new file with mode: 0644]
golang/install.bash [deleted file]
golang/install.sh [new file with mode: 0644]
golang/package.yash [new file with mode: 0644]
golang/releases.js
hugo/install.bash [deleted file]
hugo/install.sh [new file with mode: 0644]
hugo/package.yash [new file with mode: 0644]
hugo/releases.js
macos/install.bash [deleted file]
macos/install.sh [new file with mode: 0644]
node/install.bash [deleted file]
node/install.sh [new file with mode: 0644]
node/package.yash [new file with mode: 0644]
node/releases.js
pathman/install.bash [deleted file]
pathman/install.sh [new file with mode: 0644]
rg/install.bash [deleted file]
rg/install.sh [new file with mode: 0644]
rg/package.yash [new file with mode: 0644]
ripgrep/install.bash [deleted file]
ripgrep/install.sh [new file with mode: 0644]
rust/install.bash [deleted file]
rust/install.sh [new file with mode: 0644]
rustlang/install.bash [deleted file]
rustlang/install.sh [new file with mode: 0644]
serviceman/install.bash [deleted file]
serviceman/install.sh [new file with mode: 0644]
vim-sensible/install.bash [deleted file]
vim-sensible/install.sh [new file with mode: 0644]
webi/bootstrap.bash [deleted file]
webi/install.bash [deleted file]
webi/install.sh [new file with mode: 0644]
webi/template.bash [deleted file]
webi/webinstall.bat [deleted file]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..e3a0b44
--- /dev/null
@@ -0,0 +1 @@
+install-*.sh
index c082b0f62141597a3fb027898bffb7b21de4bd91..28da84b3901fde0ac7b30b73e8ce32e580cfc105 100644 (file)
--- a/README.md
+++ b/README.md
@@ -14,12 +14,14 @@ Primary and community-submitted packages for
 
 ## Creating an Installer
 
-An install consists of 5 parts in two files:
+An install consists of 5 parts in 4 files:
 
 ```
 my-new-package/
+  - package.yash
   - releases.js
-  - my-new-package.bash
+  - install.sh
+  - install.bat
 ```
 
 1. Create Description
@@ -38,11 +40,20 @@ variables and functions pre-defined.
 
 You just fill in the blanks.
 
+### TL;DR
+
+Just create an empty directory and run the tests until you get a good result.
+
+```bash
+mkdir -p new-package
+node _webi/test.js ./new-package/
+```
+
 ### 1. Create Description
 
 Just copy the format from any of the existing packages. It's like this:
 
-`my-new-package.bash`:
+`package.yash`:
 
 ````
 # title: Node.js
@@ -55,8 +66,15 @@ Just copy the format from any of the existing packages. It's like this:
 #   node -e 'console.log("Hello, World!")'
 #   > Hello, World!
 #   ```
+
+END
 ````
 
+This is a dumb format. We know. Historical accident (originally these were in
+bash comments).
+
+It's in the TODOs to replace this with either YAML or Markdown.
+
 ### 1. Fetch Releases
 
 All you're doing in this step is just translating from one form of JSON or CSV
@@ -115,25 +133,24 @@ pkg_get_current_version() {
 For the rest of the functions you can like copy/paste from the examples:
 
 ```bash
-pkg_format_cmd_version() {}       # Optional, pretty prints version
+pkg_format_cmd_version() {}         # Override, pretty prints version
 
-pkg_link_src_dst() {}             # Required, may be empty for $HOME/.local/bin commands
+pkg_link                            # Override, replaces webi_link()
 
-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
+pkg_pre_install() {                 # Override, 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
 }
 
-pkg_install() {}                  # Required, usually just needs to rename extracted folder to
-                                  # "$HOME/.local/opt/$pkg_cmd_name-v$WEBI_VERSION"
+pkg_install() {}                    # Override, usually just needs to rename extracted folder to
+                                    # "$HOME/.local/opt/$pkg_cmd_name-v$WEBI_VERSION"
 
-pkg_post_install() {              # Required
-    pkg_link_src_dst                  # should probably call pkg_link_src_dst()
-    webi_path_add "$pkg_dst_bin"      # should probably update PATH
+pkg_post_install() {                # Override
+    webi_path_add "$pkg_dst_bin"        # should probably update PATH
 }
 
-pkg_post_install_message() {}     # Optional, pretty print a success message
+pkg_done_message() {}               # Override, pretty print a success message
 ```
 
 ## Script API
@@ -162,6 +179,7 @@ WEBI_PKG_FILE=example-macos-amd64.tar.gz
 
 ```bash
 WEBI_TMP=${WEBI_TMP:-"$(mktemp -d -t webinstall-foobar.XXXXXXXX)"}
+WEBI_SINGLE=""
 ```
 
 ```bash
@@ -169,6 +187,10 @@ webi_check              # Checks to see if the selected version is already insta
 webi_download           # Downloads the selected release to $HOME/Downloads/<package-name>.tar.gz
 webi_extract            # Extracts the download to /tmp/<package-name>-<random>/
 webi_path_add /new/path # Adds /new/path to PATH for bash, zsh, and fish
+webi_pre_install        # Runs webi_check, webi_download, and webi_extract
+webi_install            # Moves extracted files from $WEBI_TMP to $pkg_src
+webi_link               # replaces any existing symlink with the currently selected version
+webi_post_install       # Runs `webi_add_path $pkg_dst_bin`
 ```
 
 # Roadmap
diff --git a/_common/normalize.js b/_common/normalize.js
deleted file mode 100644 (file)
index dac0902..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-'use strict';
-
-// this may need customizations between packages
-const osMap = {
-  macos: /(\b|_)(apple|mac|darwin|iPhone|iOS|iPad)/i,
-  linux: /(\b|_)(linux)/i,
-  freebsd: /(\b|_)(freebsd)/i,
-  windows: /(\b|_)(win|microsoft|msft)/i,
-  sunos: /(\b|_)(sun)/i,
-  aix: /(\b|_)(aix)/i
-};
-
-// evaluation order matters
-// (i.e. otherwise x86 and x64 can cross match)
-var archArr = [
-  'amd64', // first and most likely match
-  'arm64',
-  'x86',
-  'ppc64le',
-  'ppc64',
-  'armv7l',
-  'armv6l',
-  's390x'
-];
-var archMap = {
-  amd64: /(amd.?64|x64|[_\-]64)/i,
-  x86: /(86)(\b|_)/i,
-  ppc64le: /(\b|_)(ppc64le)/i,
-  ppc64: /(\b|_)(ppc64)(\b|_)/i,
-  arm64: /(\b|_)(arm64|arm)/i,
-  armv7l: /(\b|_)(armv?7l)/i,
-  armv6l: /(\b|_)(armv?6l)/i,
-  s390x: /(\b|_)(s390x)/i
-};
-
-function normalize(all) {
-  all.releases.forEach(function (rel) {
-    rel.version = rel.version.replace(/^v/i, '');
-    if (!rel.name) {
-      rel.name = rel.download.replace(/.*\//, '');
-    }
-    if (!rel.os) {
-      rel.os =
-        Object.keys(osMap).find(function (regKey) {
-          /* console.log(
-            'release os:',
-            regKey,
-            osMap[regKey],
-            osMap[regKey].test(rel.name || rel.download),
-            rel.name,
-            rel.download
-          );
-          // */
-          return osMap[regKey].test(rel.name || rel.download);
-        }) || 'unknown';
-    }
-
-    if (!rel.arch) {
-      archArr.some(function (regKey) {
-        //console.log('release arch:', rel.download, regKey, archMap[regKey]);
-        var arch = (rel.name || rel.download).match(archMap[regKey]) && regKey;
-        if (arch) {
-          rel.arch = arch;
-          return true;
-        }
-      })[0];
-    }
-
-    if (!rel.ext) {
-      // pkg-v1.0.tar.gz => ['gz', 'tar', '0', 'pkg-v1']
-      // pkg-v1.0.tar => ['tar', '0' ,'pkg-v1']
-      // pkg-v1.0.zip => ['zip', '0', 'pkg-v1']
-      var exts = (rel.name || rel.download).split('.').reverse().slice(0, 2);
-      var ext;
-      if ('tar' === exts[1]) {
-        rel.ext = exts.reverse().join('.');
-      } else if ('tgz' == exts[0]) {
-        rel.ext = 'tar.gz';
-      } else {
-        rel.ext = exts[0];
-      }
-    }
-
-    if (all.download) {
-      rel.download = all.download.replace(/{{ download }}/, rel.download);
-    }
-  });
-  return all;
-}
-
-module.exports = normalize;
diff --git a/_example/install.bash b/_example/install.bash
deleted file mode 100644 (file)
index 619534d..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/bin/bash
-
-# TODO: migrate from shmatter to frontmarker
-
-set -e
-set -u
-
-## 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_dst="$HOME/.local/opt/xmpl"
-#pkg_dst_bin="$HOME/.local/opt/xmpl/bin"
-#pkg_dst_cmd="$HOME/.local/opt/xmpl/bin/xmpl"
-
-#pkg_src="$HOME/.local/opt/xmpl-v$WEBI_VERSION"
-#pkg_src_bin="$HOME/.local/opt/xmpl-v$WEBI_VERSION/bin"
-#pkg_src_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"
-}
-
-# 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)"
-}
-
-# 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_src_dst() {
-    rm -rf "$pkg_dst"
-    ln -s "$pkg_src" "$pkg_dst"
-}
-
-pkg_pre_install() {
-    # web_* are defined in webi/template.bash at https://github.com/webinstall/packages
-
-    # if selected version is installed, re-link it and quit
-    webi_check
-
-    # will save to ~/Downloads/$WEBI_PKG_FILE by default
-    webi_download
-
-    # supported formats (.xz, .tar.*, .zip) will be extracted to $WEBI_TMP
-    webi_extract
-}
-
-# For installing from the extracted package tmp directory
-pkg_install() {
-    pushd "$WEBI_TMP" 2>&1 >/dev/null
-
-        # remove the versioned folder, just in case it's there with junk
-        rm -rf "$pkg_src"
-
-        # 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_src"
-
-    popd 2>&1 >/dev/null
-}
-
-# For updating PATHs and installing companion tools
-pkg_post_install() {
-    pkg_link_src_dst
-
-    # web_path_add is defined in webi/template.bash at https://github.com/webinstall/packages
-    webi_path_add "$pkg_dst_bin"
-}
-
-pkg_post_install_message() {
-    echo "Installed 'example' as 'xmpl'"
-}
diff --git a/_example/install.sh b/_example/install.sh
new file mode 100644 (file)
index 0000000..2794685
--- /dev/null
@@ -0,0 +1,79 @@
+#!/bin/bash
+
+set -e
+set -u
+
+## 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_dst="$HOME/.local/opt/xmpl"
+#pkg_dst_bin="$HOME/.local/opt/xmpl/bin"
+#pkg_dst_cmd="$HOME/.local/opt/xmpl/bin/xmpl"
+
+#pkg_src="$HOME/.local/opt/xmpl-v$WEBI_VERSION"
+#pkg_src_bin="$HOME/.local/opt/xmpl-v$WEBI_VERSION/bin"
+#pkg_src_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"
+}
+
+# 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)"
+}
+
+# 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() {
+    rm -rf "$pkg_dst"
+    ln -s "$pkg_src" "$pkg_dst"
+}
+
+pkg_pre_install() {
+    # web_* are defined in webi/template.bash at https://github.com/webinstall/packages
+
+    # if selected version is installed, re-link it and quit
+    webi_check
+
+    # will save to ~/Downloads/$WEBI_PKG_FILE by default
+    webi_download
+
+    # supported formats (.xz, .tar.*, .zip) will be extracted to $WEBI_TMP
+    webi_extract
+}
+
+# For installing from the extracted package tmp directory
+pkg_install() {
+    # remove the versioned folder, just in case it's there with junk
+    rm -rf "$pkg_src"
+
+    # 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_src"
+}
+
+# For updating PATHs and installing companion tools
+pkg_post_install() {
+    pkg_link
+
+    # web_path_add is defined in webi/template.bash at https://github.com/webinstall/packages
+    webi_path_add "$pkg_dst_bin"
+}
+
+pkg_done_message() {
+    echo "Installed 'example' as 'xmpl' at $pkg_dst_cmd"
+}
diff --git a/_example/install_safe_copy.bash b/_example/install_safe_copy.bash
deleted file mode 100644 (file)
index c52b018..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-# 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_src/" 2>/dev/null
-        else
-            cp -Hr ./xmpl*/* "$pkg_src/" 2>/dev/null
-            cp -Hr ./xmpl*/.* "$pkg_src/" 2>/dev/null
-        fi
-        rm -rf ./xmpl*
-
-    popd 2>&1 >/dev/null
-}
diff --git a/_example/install_safe_copy.sh b/_example/install_safe_copy.sh
new file mode 100644 (file)
index 0000000..c52b018
--- /dev/null
@@ -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_src/" 2>/dev/null
+        else
+            cp -Hr ./xmpl*/* "$pkg_src/" 2>/dev/null
+            cp -Hr ./xmpl*/.* "$pkg_src/" 2>/dev/null
+        fi
+        rm -rf ./xmpl*
+
+    popd 2>&1 >/dev/null
+}
index 60ef61e51567ce4d7762b931d3101d291d79335c..98125593ed89c9ed46939c64b5c814824e2dcc0a 100644 (file)
@@ -36,7 +36,7 @@ if (module === require.main) {
   module.exports(require('@root/request')).then(function (all) {
     // limit the example output
     all.releases = all.releases.slice(0, 5);
-    all = require('../_common/normalize.js')(all);
+    all = require('../_webi/normalize.js')(all);
     console.info(JSON.stringify(all, null, 2));
   });
 }
diff --git a/_webi/bootstrap.bat b/_webi/bootstrap.bat
new file mode 100644 (file)
index 0000000..495a624
--- /dev/null
@@ -0,0 +1,28 @@
+setlocal
+@echo off
+pushd "%userprofile%" || goto :error
+  IF NOT EXIST .local (
+    mkdir .local || goto :error
+  )
+  IF NOT EXIST .local\bin (
+    mkdir .local\bin || goto :error
+  )
+
+  rem {{ baseurl }}
+  rem {{ version }}
+  pushd .local\bin || goto :error
+    if NOT EXIST webi.bat (
+      rem without SilentlyContinue this is SLOOOOOOOOOOOOOOOW!
+      powershell $ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest https://webinstall.dev/packages/_webi/webi.bat -OutFile webi.bat || goto :error
+    )
+    call .\webi {{ exename }} || goto :error
+    rem pathman add "%userprofile%\.local\bin" >nul 2>&1 || goto :error
+    pathman add "%userprofile%\.local\bin" || goto :error
+  popd || goto :error
+popd
+
+goto :EOF
+
+:error
+echo Failed with error #%errorlevel%.
+exit /b %errorlevel%
diff --git a/_webi/bootstrap.sh b/_webi/bootstrap.sh
new file mode 100644 (file)
index 0000000..4a65519
--- /dev/null
@@ -0,0 +1,98 @@
+#!/bin/bash
+
+{
+
+#WEBI_PKG=
+#WEBI_HOST=https://webinstall.dev
+export WEBI_HOST
+
+mkdir -p "$HOME/.local/bin"
+
+cat << EOF > "$HOME/.local/bin/webi"
+#!/bin/bash
+
+set -e
+set -u
+
+{
+
+my_package="\${1:-}"
+if [ -z "\$my_package" ]; then
+       echo "Usage: webi <package>@<version>"
+       echo "Example: webi node@latest"
+       exit 1
+fi
+
+##
+## Detect acceptable package formats
+##
+
+my_ext=""
+set +e
+# NOTE: the order here is least favorable to most favorable
+if [ -n "\$(command -v pkgutil)" ]; then
+       my_ext="pkg,\$my_ext"
+fi
+# disable this check for the sake of building the macOS installer on Linux
+#if [ -n "\$(command -v diskutil)" ]; then
+       # note: could also detect via hdiutil
+       my_ext="dmg,\$my_ext"
+#fi
+if [ -n "\$(command -v git)" ]; then
+       my_ext="git,\$my_ext"
+fi
+if [ -n "\$(command -v unxz)" ]; then
+       my_ext="xz,\$my_ext"
+fi
+if [ -n "\$(command -v unzip)" ]; then
+       my_ext="zip,\$my_ext"
+fi
+if [ -n "\$(command -v tar)" ]; then
+       my_ext="tar,\$my_ext"
+fi
+my_ext="\$(echo "\$my_ext" | sed 's/,$//')" # nix trailing comma
+set -e
+
+##
+## Detect http client
+##
+set +e
+export WEBI_CURL="\$(command -v curl)"
+export WEBI_WGET="\$(command -v wget)"
+set -e
+
+export WEBI_BOOT="\$(mktemp -d -t "\$my_package-bootstrap.XXXXXXXX")"
+export WEBI_HOST="\${WEBI_HOST:-https://webinstall.dev}"
+export WEBI_UA="\$(uname -a)"
+
+my_installer_url="\$WEBI_HOST/api/installers/\$my_package.bash?formats=\$my_ext"
+set +e
+if [ -n "\$WEBI_CURL" ]; then
+       curl -fsSL "\$my_installer_url" -H "User-Agent: curl \$WEBI_UA" \\
+               -o "\$WEBI_BOOT/\$my_package-bootstrap.sh"
+else
+       wget -q "\$my_installer_url" --user-agent="wget \$WEBI_UA" \\
+               -O "\$WEBI_BOOT/\$my_package-bootstrap.sh"
+fi
+if ! [ \$? -eq 0 ]; then
+  echo "error fetching '\$my_installer_url'"
+  exit 1
+fi
+set -e
+
+pushd "\$WEBI_BOOT" 2>&1 > /dev/null
+       bash "\$my_package-bootstrap.sh"
+popd 2>&1 > /dev/null
+
+rm -rf "\$WEBI_BOOT"
+
+}
+EOF
+
+chmod a+x "$HOME/.local/bin/webi"
+
+if [ -n "${WEBI_PKG:-}" ]; then
+    "$HOME/.local/bin/webi" "${WEBI_PKG}"
+fi
+
+}
diff --git a/_webi/normalize.js b/_webi/normalize.js
new file mode 100644 (file)
index 0000000..dac0902
--- /dev/null
@@ -0,0 +1,91 @@
+'use strict';
+
+// this may need customizations between packages
+const osMap = {
+  macos: /(\b|_)(apple|mac|darwin|iPhone|iOS|iPad)/i,
+  linux: /(\b|_)(linux)/i,
+  freebsd: /(\b|_)(freebsd)/i,
+  windows: /(\b|_)(win|microsoft|msft)/i,
+  sunos: /(\b|_)(sun)/i,
+  aix: /(\b|_)(aix)/i
+};
+
+// evaluation order matters
+// (i.e. otherwise x86 and x64 can cross match)
+var archArr = [
+  'amd64', // first and most likely match
+  'arm64',
+  'x86',
+  'ppc64le',
+  'ppc64',
+  'armv7l',
+  'armv6l',
+  's390x'
+];
+var archMap = {
+  amd64: /(amd.?64|x64|[_\-]64)/i,
+  x86: /(86)(\b|_)/i,
+  ppc64le: /(\b|_)(ppc64le)/i,
+  ppc64: /(\b|_)(ppc64)(\b|_)/i,
+  arm64: /(\b|_)(arm64|arm)/i,
+  armv7l: /(\b|_)(armv?7l)/i,
+  armv6l: /(\b|_)(armv?6l)/i,
+  s390x: /(\b|_)(s390x)/i
+};
+
+function normalize(all) {
+  all.releases.forEach(function (rel) {
+    rel.version = rel.version.replace(/^v/i, '');
+    if (!rel.name) {
+      rel.name = rel.download.replace(/.*\//, '');
+    }
+    if (!rel.os) {
+      rel.os =
+        Object.keys(osMap).find(function (regKey) {
+          /* console.log(
+            'release os:',
+            regKey,
+            osMap[regKey],
+            osMap[regKey].test(rel.name || rel.download),
+            rel.name,
+            rel.download
+          );
+          // */
+          return osMap[regKey].test(rel.name || rel.download);
+        }) || 'unknown';
+    }
+
+    if (!rel.arch) {
+      archArr.some(function (regKey) {
+        //console.log('release arch:', rel.download, regKey, archMap[regKey]);
+        var arch = (rel.name || rel.download).match(archMap[regKey]) && regKey;
+        if (arch) {
+          rel.arch = arch;
+          return true;
+        }
+      })[0];
+    }
+
+    if (!rel.ext) {
+      // pkg-v1.0.tar.gz => ['gz', 'tar', '0', 'pkg-v1']
+      // pkg-v1.0.tar => ['tar', '0' ,'pkg-v1']
+      // pkg-v1.0.zip => ['zip', '0', 'pkg-v1']
+      var exts = (rel.name || rel.download).split('.').reverse().slice(0, 2);
+      var ext;
+      if ('tar' === exts[1]) {
+        rel.ext = exts.reverse().join('.');
+      } else if ('tgz' == exts[0]) {
+        rel.ext = 'tar.gz';
+      } else {
+        rel.ext = exts[0];
+      }
+    }
+
+    if (all.download) {
+      rel.download = all.download.replace(/{{ download }}/, rel.download);
+    }
+  });
+  return all;
+}
+
+module.exports = normalize;
diff --git a/_webi/packages.js b/_webi/packages.js
new file mode 100644 (file)
index 0000000..603dc14
--- /dev/null
@@ -0,0 +1,108 @@
+'use strict';
+
+var shmatter = require('shmatter');
+var fs = require('fs');
+var path = require('path');
+
+var pkgs = module.exports;
+pkgs.create = function (Pkgs, basepath) {
+  if (!Pkgs) {
+    Pkgs = {};
+  }
+  if (!basepath) {
+    basepath = path.join(__dirname, '../');
+  }
+
+  Pkgs.all = function () {
+    return fs.promises.readdir(basepath).then(function (nodes) {
+      var items = [];
+      return nodes
+        .reduce(function (p, node) {
+          return p.then(function () {
+            return pkgs.get(node).then(function (meta) {
+              if (meta && '_' !== node[0]) {
+                meta.name = node;
+                items.push(meta);
+              }
+            });
+          });
+        }, Promise.resolve())
+        .then(function () {
+          return items;
+        });
+    });
+  };
+
+  Pkgs.get = function (node) {
+    var yash = path.join(basepath, node, 'package.yash');
+    var curlbash = path.join(basepath, node, 'install.sh');
+    var readme = path.join(basepath, node, 'README.md');
+    var winstall = path.join(basepath, node, 'install.bat');
+    return Promise.all([
+      fs.promises
+        .readFile(readme, 'utf-8')
+        .then(function (txt) {
+          // TODO
+          //return frontmarker.parse(txt);
+        })
+        .catch(function (e) {
+          if ('ENOENT' !== e.code && 'ENOTDIR' !== e.code) {
+            console.error("failed to read '" + node + "/README.md'");
+            console.error(e);
+          }
+        }),
+      fs.promises
+        .readFile(yash, 'utf-8')
+        .then(function (txt) {
+          return shmatter.parse(txt);
+        })
+        .catch(function (e) {
+          // no yash package description
+          yash = '';
+          if ('ENOENT' !== e.code && 'ENOTDIR' !== e.code) {
+            console.error("failed to parse '" + node + "/package.yash'");
+            console.error(e);
+          }
+          return fs.promises.readFile(curlbash, 'utf-8').then(function (txt) {
+            return shmatter.parse(txt);
+          });
+        })
+        .catch(function (e) {
+          // no *nix installer
+          curlbash = '';
+          if ('ENOENT' !== e.code && 'ENOTDIR' !== e.code) {
+            console.error("failed to parse '" + node + "/install.sh'");
+            console.error(e);
+          }
+        }),
+      fs.promises.access(winstall).catch(function (e) {
+        // no winstaller
+        winstall = '';
+        if ('ENOENT' !== e.code && 'ENOTDIR' !== e.code) {
+          console.error("failed to read '" + node + "/install.bat'");
+          console.error(e);
+        }
+      })
+    ]).then(function (items) {
+      var meta = items[1];
+      if (!meta) {
+        // doesn't exist
+        return;
+      }
+      meta.windows = !!winstall;
+      meta.bash = !!curlbash;
+
+      return meta;
+    });
+  };
+
+  return Pkgs;
+};
+pkgs.create(pkgs);
+
+if (module === require.main) {
+  pkgs.all().then(function (data) {
+    console.info('package info:');
+    console.info(data);
+  });
+}
diff --git a/_webi/releases.js b/_webi/releases.js
new file mode 100644 (file)
index 0000000..f7f5eff
--- /dev/null
@@ -0,0 +1,101 @@
+'use strict';
+
+var fs = require('fs');
+var path = require('path');
+var request = require('@root/request');
+var _normalize = require('../_webi/normalize.js');
+
+var Releases = module.exports;
+Releases.get = async function (pkgdir) {
+  var get = require(path.join(pkgdir, 'releases.js'));
+  return get(request).then(function (all) {
+    return _normalize(all);
+  });
+};
+
+Releases.renderBash = function (
+  pkgdir,
+  rel,
+  { baseurl, pkg, tag, ver, os, arch, formats }
+) {
+  return fs.promises
+    .readFile(path.join(pkgdir, 'install.sh'), 'utf8')
+    .then(function (installTxt) {
+      var vers = rel.version.split('.');
+      var v = {
+        major: vers.shift() || '',
+        minor: vers.shift() || '',
+        patch: vers.join('.').replace(/[+\-].*/, ''),
+        build: vers
+          .join('.')
+          .replace(/[^+\-]*/, '')
+          .replace(/^-/, '')
+      };
+      return fs.promises
+        .readFile(path.join(__dirname, 'template.sh'), 'utf8')
+        .then(function (tplTxt) {
+          return tplTxt
+            .replace(/^#?WEBI_PKG=.*/m, "WEBI_PKG='" + pkg + '@' + ver + "'")
+            .replace(/^#?WEBI_NAME=.*/m, "WEBI_NAME='" + pkg + "'")
+            .replace(/^#?WEBI_HOST=.*/m, "WEBI_HOST='" + baseurl + "'")
+            .replace(/^#?WEBI_OS=.*/m, "WEBI_OS='" + (os || '') + "'")
+            .replace(/^#?WEBI_ARCH=.*/m, "WEBI_ARCH='" + (arch || '') + "'")
+            .replace(/^#?WEBI_TAG=.*/m, "WEBI_TAG='" + (tag || '') + "'")
+            .replace(
+              /^#?WEBI_RELEASES=.*/m,
+              "WEBI_RELEASES='" +
+                baseurl +
+                '/api/releases/' +
+                pkg +
+                '@' +
+                tag +
+                '.tab?os=' +
+                rel.os +
+                '&arch=' +
+                rel.arch +
+                '&pretty=true' +
+                "'"
+            )
+            .replace(
+              /^#?WEBI_CSV=.*/m,
+              "WEBI_CSV='" +
+                [
+                  rel.version,
+                  rel.lts,
+                  rel.channel,
+                  rel.date,
+                  rel.os,
+                  rel.arch,
+                  rel.ext,
+                  '-',
+                  rel.download,
+                  rel.name,
+                  rel.comment || ''
+                ]
+                  .join(',')
+                  .replace(/'/g, '') +
+                "'"
+            )
+            .replace(
+              /^#?WEBI_VERSION=.*/m,
+              'WEBI_VERSION=' + JSON.stringify(rel.version)
+            )
+            .replace(/^#?WEBI_MAJOR=.*/m, 'WEBI_MAJOR=' + v.major)
+            .replace(/^#?WEBI_MINOR=.*/m, 'WEBI_MINOR=' + v.minor)
+            .replace(/^#?WEBI_PATCH=.*/m, 'WEBI_PATCH=' + v.patch)
+            .replace(/^#?WEBI_BUILD=.*/m, 'WEBI_BUILD=' + v.build)
+            .replace(/^#?WEBI_LTS=.*/m, 'WEBI_LTS=' + rel.lts)
+            .replace(/^#?WEBI_CHANNEL=.*/m, 'WEBI_CHANNEL=' + rel.channel)
+            .replace(
+              /^#?WEBI_EXT=.*/m,
+              'WEBI_EXT=' + rel.ext.replace(/tar.*/, 'tar')
+            )
+            .replace(
+              /^#?WEBI_PKG_URL=.*/m,
+              "WEBI_PKG_URL='" + rel.download + "'"
+            )
+            .replace(/^#?WEBI_PKG_FILE=.*/m, "WEBI_PKG_FILE='" + rel.name + "'")
+            .replace(/{{ installer }}/, installTxt);
+        });
+    });
+};
diff --git a/_webi/template.sh b/_webi/template.sh
new file mode 100644 (file)
index 0000000..191cf10
--- /dev/null
@@ -0,0 +1,296 @@
+#!/bin/bash
+
+{
+
+set -e
+set -u
+#set -x
+
+#WEBI_PKG=
+#WEBI_NAME=
+# TODO should this be BASEURL instead?
+#WEBI_HOST=
+#WEBI_RELEASES=
+#WEBI_CSV=
+#WEBI_TAG=
+#WEBI_VERSION=
+#WEBI_MAJOR=
+#WEBI_MINOR=
+#WEBI_PATCH=
+# TODO not sure if BUILD is the best name for this
+#WEBI_BUILD=
+#WEBI_LTS=
+#WEBI_CHANNEL=
+#WEBI_EXT=
+#WEBI_PKG_URL=
+#WEBI_PKG_FILE=
+WEBI_UA="$(uname -a)"
+export WEBI_HOST
+
+##
+## Set up tmp, download, and install directories
+##
+
+WEBI_TMP=${WEBI_TMP:-"$(mktemp -d -t webinstall-${WEBI_PKG:-}.XXXXXXXX)"}
+
+mkdir -p "$HOME/Downloads"
+mkdir -p "$HOME/.local/bin"
+mkdir -p "$HOME/.local/opt"
+
+##
+## Detect http client
+##
+set +e
+export WEBI_CURL="$(command -v curl)"
+export WEBI_WGET="$(command -v wget)"
+set -e
+
+my_versioned_name=""
+_webi_canonical_name() {
+    if [ -n "$my_versioned_name" ]; then
+        echo "$my_versioned_name"
+        return 0
+    fi
+
+    if [ -n "$(command -v pkg_format_cmd_version)" ]; then
+        my_versioned_name="$(pkg_format_cmd_version "$WEBI_VERSION")"
+    else
+        my_versioned_name="'$pkg_cmd_name' v$WEBI_VERSION"
+    fi
+
+    echo "$my_versioned_name"
+}
+
+webi_link() {
+    if [ -n "$(command -v pkg_link)" ]; then
+        pkg_link
+        return 0
+    fi
+
+    if [ -n "$WEBI_SINGLE" ] || [ "single" == "${1:-}" ]; then
+        if [ -d "$pkg_dst_cmd" ]; then
+            rm -rf -i "$pkg_dst_cmd"
+        else
+            rm -f "$pkg_dst_cmd"
+        fi
+        ln -s "$pkg_src_cmd" "$pkg_dst_cmd"
+    else
+        # 'pkg_dst' will default to $HOME/.local/opt/node
+        # 'pkg_src' will be the installed version, such as to $HOME/.local/opt/node-v12.8.0
+        if [ -d "$pkg_dst" ]; then
+            rm -rf -i "$pkg_dst"
+        else
+            rm -f "$pkg_dst"
+        fi
+        ln -s "$pkg_src" "$pkg_dst"
+    fi
+}
+
+webi_check() {
+    # Test for existing version
+    set +e
+    my_current_cmd="$(command -v "$pkg_cmd_name")"
+    set -e
+    if [ -n "$my_current_cmd" ]; then
+        pkg_current_version="$(pkg_get_current_version 2>/dev/null | head -n 1)"
+        # remove trailing '.0's for golang's sake
+        my_current_version="$(echo $pkg_current_version | sed 's:\.0::g')"
+        my_src_version="$(echo $WEBI_VERSION | sed 's:\.0::g')"
+        my_canonical_name="$(_webi_canonical_name)"
+        if [ "$my_src_version" == "$my_current_version" ]; then
+            echo "$my_canonical_name already installed at $my_current_cmd"
+            exit 0
+        else
+            if [ "$my_current_cmd" != "$pkg_dst_cmd" ]; then
+                echo "WARN: possible conflict between $my_canonical_name and $pkg_current_version at $my_current_cmd"
+            fi
+            if [ -x "$pkg_src_cmd" ]; then
+                webi_link
+                echo "switched to $my_canonical_name at $pkg_src"
+                exit 0
+            fi
+          fi
+    fi
+}
+
+webi_download() {
+    if [ -n "${1:-}" ]; then
+        my_url="$1"
+    else
+        if [ "error" == "$WEBI_CHANNEL" ]; then
+            # TODO pass back requested OS / Arch / Version
+            echo "Error: no '$WEBI_NAME' release found for the given OS and architecture by that tag or version"
+            echo "       (check that the package name and version are correct)"
+            exit 1
+        fi
+        my_url="$WEBI_PKG_URL"
+    fi
+    if [ -n "${2:-}" ]; then
+        my_dl="$2"
+    else
+        my_dl="$HOME/Downloads/$WEBI_PKG_FILE"
+    fi
+
+    if [ -e "$my_dl" ]; then
+        echo "Found $my_dl"
+        return 0
+    fi
+
+    echo "Downloading $WEBI_NAME to $my_dl"
+
+    # It's only 2020, we can't expect to have reliable CLI tools
+    # to tell us the size of a file as part of a base system...
+    if [ -n "$WEBI_WGET" ]; then
+        # wget has resumable downloads
+        # TODO wget -c --content-disposition "$my_url"
+        set +e
+        wget -q --show-progress --user-agent="wget $WEBI_UA" -c "$my_url" -O "$my_dl.part"
+        if ! [ $? -eq 0 ]; then
+          echo "failed to download from $WEBI_PKG_URL"
+          exit 1
+        fi
+        set -e
+    else
+        # Neither GNU nor BSD curl have sane resume download options, hence we don't bother
+        # TODO curl -fsSL --remote-name --remote-header-name --write-out "$my_url"
+        curl -fSL -H "User-Agent: curl $WEBI_UA" "$my_url" -o "$my_dl.part"
+    fi
+
+    mv "$my_dl.part" "$my_dl"
+}
+
+webi_extract() {
+    pushd "$WEBI_TMP" 2>&1 >/dev/null
+        if [ "tar" == "$WEBI_EXT" ]; then
+            echo "Extracting $HOME/Downloads/$WEBI_PKG_FILE"
+            tar xf "$HOME/Downloads/$WEBI_PKG_FILE"
+        elif [ "zip" == "$WEBI_EXT" ]; then
+            echo "Extracting $HOME/Downloads/$WEBI_PKG_FILE"
+            unzip "$HOME/Downloads/$WEBI_PKG_FILE"
+        elif [ "exe" == "$WEBI_EXT" ]; then
+            # do nothing (but don't leave an empty if block either)
+            echo -n ""
+        elif [ "xz" == "$WEBI_EXT" ]; then
+            echo "Inflating $HOME/Downloads/$WEBI_PKG_FILE"
+            unxz -c "$HOME/Downloads/$WEBI_PKG_FILE" > $(basename "$WEBI_PKG_FILE")
+        else
+            # do nothing
+            echo "Failed to extract $HOME/Downloads/$WEBI_PKG_FILE"
+            exit 1
+        fi
+    popd 2>&1 >/dev/null
+}
+
+webi_path_add() {
+    # make sure that we don't recursively install pathman with webi
+    my_path="$PATH"
+    export PATH="$HOME/.local/bin:$PATH"
+    set +e
+    my_pathman=$(command -v pathman)
+    set -e
+    export PATH="$my_path"
+
+    # install pathman if not already installed
+    if [ -z "$my_pathman" ]; then
+        "$HOME/.local/bin/webi" pathman
+        export PATH="$HOME/.local/bin:$PATH"
+    fi
+
+    # in case pathman was recently installed and the PATH not updated
+    "$HOME/.local/bin/pathman" add "$1"
+}
+
+webi_pre_install() {
+    webi_check
+    webi_download
+    webi_extract
+}
+
+webi_install() {
+    if [ -n "$WEBI_SINGLE" ] || [ "single" == "${1:-}" ]; then
+        mkdir -p "$(dirname $pkg_src_cmd)"
+        mv ./"$pkg_cmd_name"* "$pkg_src_cmd"
+        chmod a+x "$pkg_src_cmd"
+    else
+        mkdir -p "$(dirname $pkg_src)"
+        if [ -d "$pkg_src" ]; then
+            rm -rf -i "$pkg_src"
+        else
+            rm -f "$pkg_src"
+        fi
+        mv ./"$pkg_cmd_name"* "$pkg_src"
+    fi
+}
+
+webi_post_install() {
+    webi_path_add "$pkg_dst_bin"
+}
+
+_webi_done_message() {
+    echo "Installed $(_webi_canonical_name) as $pkg_dst_cmd"
+}
+
+##
+##
+## BEGIN user-submited script
+##
+##
+
+WEBI_SINGLE=
+
+{
+
+{{ installer }}
+
+}
+
+##
+##
+## END user-submitted script
+##
+##
+
+if [ -n "$(command -v pkg_get_current_version)" ]; then
+    pkg_cmd_name="${pkg_cmd_name:-$WEBI_NAME}"
+
+    if [ -n "$WEBI_SINGLE" ]; then
+        pkg_dst_cmd="${pkg_dst_cmd:-$HOME/.local/bin/$pkg_cmd_name}"
+        pkg_dst_bin="$(dirname $pkg_dst_cmd)"
+        pkg_dst="$(dirname $pkg_dst_bin)"
+
+        pkg_src_cmd="${pkg_src_cmd:-$HOME/.local/xbin/$pkg_cmd_name-$WEBI_VERSION}"
+        pkg_src_bin="$(dirname $pkg_src_cmd)"
+        pkg_src="$(dirname $pkg_src_bin)"
+    else
+        pkg_dst="${pkg_dst:-$HOME/.local/opt/$pkg_cmd_name}"
+        pkg_dst_bin="${pkg_dst_bin:-$pkg_dst/bin}"
+        pkg_dst_cmd="${pkg_dst_cmd:-$pkg_dst_bin/$pkg_cmd_name}"
+
+        pkg_src="${pkg_src:-$HOME/.local/opt/$pkg_cmd_name-v$WEBI_VERSION}"
+        pkg_src_bin="${pkg_src_bin:-$pkg_src/bin}"
+        pkg_src_cmd="${pkg_src_cmd:-$pkg_src_bin/$pkg_cmd_name}"
+    fi
+
+    [ -n "$(command -v pkg_pre_install)" ] && pkg_pre_install || webi_pre_install
+
+    pushd "$WEBI_TMP" 2>&1 >/dev/null
+        echo "Installing to $pkg_src_cmd"
+        [ -n "$(command -v pkg_install)" ] && pkg_install || webi_install
+    popd 2>&1 >/dev/null
+
+    webi_link
+
+    pushd "$WEBI_TMP" 2>&1 >/dev/null
+        [ -n "$(command -v pkg_post_install)" ] && pkg_post_install || webi_post_install
+    popd 2>&1 >/dev/null
+
+    pushd "$WEBI_TMP" 2>&1 >/dev/null
+        [ -n "$(command -v pkg_done_message)" ] && pkg_done_message || _webi_done_message
+    popd 2>&1 >/dev/null
+
+    echo ""
+fi
+
+rm -rf "$WEBI_TMP"
+
+}
diff --git a/_webi/test.js b/_webi/test.js
new file mode 100755 (executable)
index 0000000..552a5fa
--- /dev/null
@@ -0,0 +1,107 @@
+'use strict';
+
+//
+// Print help if there's no pkgdir argument
+//
+var usage = [
+  'Usage: node _webi/test.js <path-to-package>',
+  'Example: node _webi/test.js ./node/'
+].join('\n');
+
+if (3 !== process.argv.length) {
+  console.error(usage);
+  process.exit(1);
+}
+
+if (/\b-?-h(elp)?\b/.test(process.argv.join(' '))) {
+  console.info(usage);
+  process.exit(0);
+}
+
+//
+// Check for stuff
+//
+var os = require('os');
+var fs = require('fs');
+var path = require('path');
+var Releases = require('./releases.js');
+var uaDetect = require('./ua-detect.js');
+var pkg = process.argv[2].split('@');
+var pkgdir = pkg[0];
+var pkgtag = pkg[1] || '';
+var nodesMap = {};
+var nodes = fs.readdirSync(pkgdir);
+nodes.forEach(function (node) {
+  nodesMap[node] = true;
+});
+
+var maxLen = 0;
+console.info('');
+console.info('Has the necessary files?');
+['package.yash', 'releases.js', 'install.sh', 'install.bat']
+  .map(function (node) {
+    maxLen = Math.max(maxLen, node.length);
+    return node;
+  })
+  .forEach(function (node) {
+    var label = node.padStart(maxLen, ' ');
+    var found = nodesMap[node];
+    if (found) {
+      console.info('\t' + label + ': ✅ found');
+    } else {
+      console.info('\t' + label + ': ❌ not found');
+    }
+  });
+
+console.info('');
+Releases.get(path.join(process.cwd(), pkgdir)).then(function (all) {
+  var pkgname = path.basename(pkgdir.replace(/\/$/, ''));
+  var osrel = os.platform() + '-' + os.release();
+  var arch = os.arch();
+  var formats = ['xz', 'tar', 'zip'];
+
+  var rel = all.releases.filter(function (rel) {
+    return (
+      formats.filter(function (ext) {
+        return rel.ext.match(ext);
+      })[0] &&
+      'stable' === rel.channel &&
+      rel.os === uaDetect.os(osrel) &&
+      rel.arch === uaDetect.arch(arch) &&
+      (!pkgtag ||
+        rel.tag === pkgtag ||
+        new RegExp('^' + pkgtag).test(rel.version))
+    );
+  })[0];
+
+  if (!rel) {
+    console.error('Error: ❌ no release found for current os, arch, and tag');
+    process.exit(1);
+    return;
+  }
+
+  console.info('');
+  console.info('Found release matching current os, arch, and tag:');
+  console.info(rel);
+  console.info('');
+
+  return Releases.renderBash(pkgdir, rel, {
+    baseurl: 'https://webinstall.dev',
+    pkg: pkgname,
+    tag: pkgtag || '',
+    ver: '',
+    os: osrel,
+    arch,
+    formats: formats
+  }).then(function (bashTxt) {
+    var bashFile = 'install-' + pkgname + '.sh';
+    var batFile = 'install-' + pkgname + '.bat';
+
+    bashTxt = bashTxt.replace(/#set -x/g, 'set -x');
+    fs.writeFileSync(bashFile, bashTxt, 'utf-8');
+    console.info('Has the necessary files?');
+    console.info('\tNEEDS MANUAL TEST: %s', bashFile);
+    console.info('\t(todo: ' + batFile + ')');
+    console.info('');
+  });
+});
diff --git a/_webi/ua-detect.js b/_webi/ua-detect.js
new file mode 100644 (file)
index 0000000..fb0a316
--- /dev/null
@@ -0,0 +1,53 @@
+'use strict';
+
+function getOs(ua) {
+  if ('-' === ua) {
+    return '-';
+  }
+
+  if (/Android/i.test(ua)) {
+    // android must be tested before linux
+    return 'android';
+  } else if (/iOS|iPhone|Macintosh|Darwin|OS\s*X|macOS|mac/i.test(ua)) {
+    return 'macos';
+  } else if (/Microsoft|Windows|win32|win|PowerShell/.test(ua)) {
+    // 'win' must be tested after 'darwin'
+    return 'windows';
+  } else if (/Linux|curl|wget/i.test(ua)) {
+    return 'linux';
+  } else {
+    return 'error';
+  }
+}
+
+function getArch(ua) {
+  if ('-' === ua) {
+    return '-';
+  }
+
+  if (/arm64|arm8|armv8/i.test(ua)) {
+    return 'arm64';
+  } else if (/arm7|armv7/i.test(ua)) {
+    return 'armv7l';
+  } else if (/arm6|armv6/i.test(ua)) {
+    return 'armv6l';
+  } else if (/ppc64/i.test(ua)) {
+    return 'ppc64';
+  } else if (/mips64/i.test(ua)) {
+    return 'mips64';
+  } else if (/mips/i.test(ua)) {
+    return 'mips';
+  } else if (/(amd64|x64|_64)\b/i.test(ua)) {
+    // must come after ppc64/mips64
+    return 'amd64';
+  } else if (/(3|6|x|_)86\b/i.test(ua)) {
+    // must come after x86_64
+    return 'x86';
+  } else {
+    // TODO handle explicit invalid different
+    return 'error';
+  }
+}
+
+module.exports.os = getOs;
+module.exports.arch = getArch;
diff --git a/_webi/webi.bat b/_webi/webi.bat
new file mode 100644 (file)
index 0000000..065ba29
--- /dev/null
@@ -0,0 +1,38 @@
+@echo off
+pushd "%userprofile%" || goto :error
+  IF NOT EXIST .local (
+    mkdir .local || goto :error
+  )
+  IF NOT EXIST .local\bin (
+    mkdir .local\bin || goto :error
+  )
+  IF NOT EXIST .local\opt (
+    mkdir .local\opt || goto :error
+  )
+
+  pushd .local\bin || goto :error
+    if NOT EXIST pathman.exe (
+      echo updating PATH management
+      powershell $ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest https://webinstall.dev/packages/pathman/pathman.bat -OutFile pathman-setup.bat || goto :error
+      call .\pathman-setup.bat || goto :error
+      del pathman-setup.bat  || goto :error
+      rem TODO there's rumor of a windows tool called 'pathman' that does the same thing?
+    )
+  popd || goto :error
+  .\.local\bin\pathman add ".local\bin" || goto :error
+
+  echo downloading and installing %1
+  powershell $ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest https://webinstall.dev/packages/%1/install.bat -OutFile %1-webinstall.bat || goto :error
+
+  rem TODO only add if it's not in there already
+  PATH .local\bin;%PATH%
+
+  call %1-webinstall.bat || goto :error
+  del %1-webinstall.bat || goto :error
+popd
+
+goto :EOF
+
+:error
+echo Failed with error #%errorlevel%.
+exit /b %errorlevel%
diff --git a/brew/install.bash b/brew/install.bash
deleted file mode 100644 (file)
index e95a572..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/bash
-
-# title: Homebrew
-# homepage: https://brew.sh
-# tagline: The Missing Package Manager for macOS (or Linux)
-# description: |
-#   Homebrew installs the stuff you need that Apple (or your Linux system) didn’t.
-# examples: |
-#   ```bash
-#   brew install node
-#   ```
-
-# Straight from https://brew.sh
-/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
diff --git a/brew/install.sh b/brew/install.sh
new file mode 100644 (file)
index 0000000..e95a572
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+# title: Homebrew
+# homepage: https://brew.sh
+# tagline: The Missing Package Manager for macOS (or Linux)
+# description: |
+#   Homebrew installs the stuff you need that Apple (or your Linux system) didn’t.
+# examples: |
+#   ```bash
+#   brew install node
+#   ```
+
+# Straight from https://brew.sh
+/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
diff --git a/caddy/install.bash b/caddy/install.bash
deleted file mode 100644 (file)
index 5f6a98f..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-# title: Caddy
-# homepage: https://github.com/caddyserver/caddy
-# tagline: Fast, multi-platform web server with automatic HTTPS
-# description: |
-#   Caddy is an extensible server platform that uses TLS by default.
-# examples: |
-#   ```bash
-#   caddy start
-#   ```
-
-set -e
-set -u
-
-pkg_cmd_name="caddy"
-pkg_dst="$HOME/.local"
-
-# the "source" here isn't used, nor very meaningful,
-# but we'll use the download location as a junk value
-pkg_src="$HOME/Downloads/$WEBI_PKG_FILE"
-
-pkg_get_current_version() {
-    # 'caddy version' has output in this format:
-    #       v2.1.0 h1:pQSaIJGFluFvu8KDGDODV8u4/QRED/OPyIR+MWYYse8=
-    # This trims it down to just the version number:
-    #       2.0.0
-    echo "$(caddy version 2>/dev/null | head -n 1 | cut -d' ' -f1 | sed 's:^v::')"
-}
-
-pkg_format_cmd_version() {
-    # 'caddy v2.1.0' is the canonical version format for caddy
-    my_version="$1"
-    echo "$pkg_cmd_name v$my_version"
-}
-
-pkg_link_src_dst() {
-    # caddy is just a single file, no directory linking to do
-    true
-}
-
-pkg_pre_install() {
-    # if selected version is installed, quit
-    webi_check
-    # will save to ~/Downloads/$WEBI_PKG_FILE by default
-    webi_download
-    # supported formats (.xz, .tar.*, .zip) will be extracted to $WEBI_TMP
-    webi_extract
-}
-
-pkg_install() {
-    pushd "$WEBI_TMP" 2>&1 >/dev/null
-
-        # ensure the bin dir exists
-        mkdir -p "$pkg_dst_bin"
-
-        # rename the entire extracted folder to the new location
-        # (this will be "$HOME/.local/bin/caddy", as set above)
-
-        # ex (full directory): ./node-v13-linux-amd64/bin/node.exe
-        #mv ./"$pkg_cmd_name"* "$pkg_src"
-
-        # ex (single file): ./caddy-v2.0.0-linux-amd64.exe
-        mv ./"$pkg_cmd_name"* "$pkg_dst_cmd"
-        chmod a+x "$pkg_dst_cmd"
-
-        # ex (single file, nested in directory): ./rg/rg-v13-linux-amd64
-        #mv ./"$pkg_cmd_name"*/"$pkg_cmd_name"* "$pkg_commend_cmd"
-        #chmod a+x "$pkg_dst_cmd"
-
-    popd 2>&1 >/dev/null
-}
-
-pkg_post_install() {
-    # just in case we add something in the future
-    pkg_link_src_dst
-
-    # web_path_add is defined in webi/template.bash at https://github.com/webinstall/packages
-    # Adds "$HOME/.local/bin" to PATH
-    webi_path_add "$pkg_dst_bin"
-}
-
-pkg_post_install_message() {
-    echo "Installed 'caddy' v$WEBI_VERSION as $pkg_dst_cmd"
-}
diff --git a/caddy/install.sh b/caddy/install.sh
new file mode 100644 (file)
index 0000000..0148194
--- /dev/null
@@ -0,0 +1,39 @@
+#!/bin/bash
+
+# This file only defines custom functions which may be unique to installing Caddy.
+# For the generic functions (version comparison, downloading, symlinking) which
+# are used by almost all installers, see `template.bash`:
+#   - https://github.com/webinstall/packages/branches/master/webi/template.bash
+
+set -e
+set -u
+
+pkg_cmd_name="caddy"
+WEBI_SINGLE=true
+
+pkg_get_current_version() {
+    # 'caddy version' has output in this format:
+    #       v2.1.0 h1:pQSaIJGFluFvu8KDGDODV8u4/QRED/OPyIR+MWYYse8=
+    # This trims it down to just the version number:
+    #       2.0.0
+    echo "$(caddy version 2>/dev/null | head -n 1 | cut -d' ' -f1 | sed 's:^v::')"
+}
+
+pkg_install() {
+    # $HOME/.local/xbin
+    mkdir -p "$pkg_src_bin"
+
+    # mv ./caddy* "$HOME/.local/xbin/caddy-v2.0.0"
+    mv ./"$pkg_cmd_name"* "$pkg_src_cmd"
+
+    # chmod a+x "$HOME/.local/xbin/caddy-v2.0.0"
+    chmod a+x "$pkg_src_cmd"
+}
+
+pkg_link() {
+    # rm -f "$HOME/.local/bin/caddy"
+    rm -f "$pkg_dst_cmd"
+
+    # ln -s "$HOME/.local/xbin/caddy-v2.0.0" "$HOME/.local/bin/caddy"
+    ln -s "$pkg_src_cmd" "$pkg_dst_cmd"
+}
diff --git a/caddy/package.yash b/caddy/package.yash
new file mode 100644 (file)
index 0000000..6ac8fcd
--- /dev/null
@@ -0,0 +1,13 @@
+# title: Caddy
+# homepage: https://github.com/caddyserver/caddy
+# tagline: Fast, multi-platform web server with automatic HTTPS
+# description: |
+#   Caddy is an extensible server platform that uses TLS by default.
+# examples: |
+#   ```bash
+#   caddy start
+#   ```
+
+This is a comment... because... poor choices I made.
+
+Don't worry, this will be yaml or markdown in the... sometime... future
index bc026d13e430e7a20ff7667a0548e51d63ce175b..30776c3abb89a78bf80ff7d6b49eb5be53a8edd6 100644 (file)
@@ -16,7 +16,7 @@ module.exports = function (request) {
 
 if (module === require.main) {
   module.exports(require('@root/request')).then(function (all) {
-    all = require('../_common/normalize.js')(all);
+    all = require('../_webi/normalize.js')(all);
     console.info(JSON.stringify(all));
   });
 }
diff --git a/flutter/install.bash b/flutter/install.bash
deleted file mode 100644 (file)
index 0ad1f29..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/bin/bash
-
-# title: Flutter
-# homepage: https://flutter.dev
-# tagline: UI Toolkit for mobile, web, and desktop
-# description: |
-#   Flutter is Google’s UI toolkit for building beautiful, natively compiled applications for mobile, web, and desktop from a single codebase.
-# examples: |
-#
-#   ```bash
-#   flutter create my_app
-#   ```
-
-set -e
-set -u
-
-# NOTE: pkg_* variables can be defined here
-#       pkg_cmd_name
-#       pkg_src, pkg_src_bin, pkg_src_cmd
-#       pkg_dst, pkg_dst_bin, pkg_dst_cmd
-#
-# Their defaults are defined in webi/template.bash at https://github.com/webinstall/packages
-
-pkg_cmd_name="flutter"
-
-pkg_get_current_version() {
-    # 'flutter --version' outputs a lot of information:
-    #       Flutter 1.19.0-4.1.pre • channel beta • https://github.com/flutter/flutter.git
-    #       Framework • revision f994b76974 (4 days ago) • 2020-06-09 15:53:13 -0700
-    #       Engine • revision 9a28c3bcf4
-    #       Tools • Dart 2.9.0 (build 2.9.0-14.1.beta)
-    # This trims it down to just the version number:
-    #       1.19.0-4.1.pre
-    echo "$(flutter --version 2>/dev/null | head -n 1 | cut -d' ' -f2)"
-}
-
-pkg_link_src_dst() {
-    # 'pkg_dst' will default to $HOME/.local/opt/flutter
-    # 'pkg_src' will be the installed version, such as to $HOME/.local/opt/flutter-v1.17.3
-    rm -rf "$pkg_dst"
-    ln -s "$pkg_src" "$pkg_dst"
-}
-
-pkg_pre_install() {
-    # web_* are defined in webi/template.bash at https://github.com/webinstall/packages
-
-    # multiple versions may be installed
-    # if one already matches, it will simply be re-linked
-    webi_check
-
-    # the download is quite large - hopefully you have wget installed
-    # will go to ~/Downloads by default
-    webi_download
-
-    # Multiple formats are supported: .xz, .tar.*, and .zip
-    # will be extracted to $WEBI_TMP
-    webi_extract
-}
-
-pkg_install() {
-    pushd "$WEBI_TMP" 2>&1 >/dev/null
-
-        # remove the versioned folder, just in case it's there with junk
-        rm -rf "$pkg_src"
-
-        # rename the entire extracted folder to the new location
-        # (this will be "$HOME/.local/opt/flutter-v$WEBI_VERSION" by default)
-        mv ./flutter* "$pkg_src"
-
-    popd 2>&1 >/dev/null
-}
-
-pkg_post_install() {
-    pkg_link_src_dst
-
-    # web_path_add is defined in webi/template.bash at https://github.com/webinstall/packages
-    # Adds "$HOME/.local/opt/flutter" to PATH
-    webi_path_add "$pkg_dst_bin"
-}
diff --git a/flutter/install.sh b/flutter/install.sh
new file mode 100644 (file)
index 0000000..4feb311
--- /dev/null
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+set -e
+set -u
+
+# NOTE: pkg_* variables can be defined here
+#       pkg_cmd_name
+#       pkg_src, pkg_src_bin, pkg_src_cmd
+#       pkg_dst, pkg_dst_bin, pkg_dst_cmd
+#
+# Their defaults are defined in webi/template.bash at https://github.com/webinstall/packages
+
+pkg_cmd_name="flutter"
+
+pkg_get_current_version() {
+    # 'flutter --version' outputs a lot of information:
+    #       Flutter 1.19.0-4.1.pre • channel beta • https://github.com/flutter/flutter.git
+    #       Framework • revision f994b76974 (4 days ago) • 2020-06-09 15:53:13 -0700
+    #       Engine • revision 9a28c3bcf4
+    #       Tools • Dart 2.9.0 (build 2.9.0-14.1.beta)
+    # This trims it down to just the version number:
+    #       1.19.0-4.1.pre
+    echo "$(flutter --version 2>/dev/null | head -n 1 | cut -d' ' -f2)"
+}
+
+pkg_format_cmd_version() {
+    # 'flutter 1.19.0' is the canonical version format for flutter
+    my_version="$1"
+    echo "$pkg_cmd_name $my_version"
+}
diff --git a/flutter/package.yash b/flutter/package.yash
new file mode 100644 (file)
index 0000000..e9413ff
--- /dev/null
@@ -0,0 +1,12 @@
+# title: Flutter
+# homepage: https://flutter.dev
+# tagline: UI Toolkit for mobile, web, and desktop
+# description: |
+#   Flutter is Google’s UI toolkit for building beautiful, natively compiled applications for mobile, web, and desktop from a single codebase.
+# examples: |
+#
+#   ```bash
+#   flutter create my_app
+#   ```
+
+END
diff --git a/gitea/install.bash b/gitea/install.bash
deleted file mode 100644 (file)
index 43af834..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-# title: Gitea
-# homepage: https://github.com/go-gitea/gitea
-# tagline: Git with a cup of tea, painless self-hosted git service 
-# description: |
-#   `gitea` is a clean, lightweight self-hosted Github alternative, forked from Gogs. Lighter and more user-friendly than Gitlab.
-# examples: |
-#   ```bash
-#   gitea --version
-#   ```
-
-set -e
-set -u
-
-pkg_cmd_name="gitea"
-pkg_dst="$HOME/.local"
-
-# pkg_src isn't used in this script,
-# just setting a junk value for completeness (and possibly debug output)
-pkg_src="$HOME/Downloads/$WEBI_PKG_FILE"
-
-pkg_get_current_version() {
-    # 'gitea version' has output in this format:
-    #       v2.1.0 h1:pQSaIJGFluFvu8KDGDODV8u4/QRED/OPyIR+MWYYse8=
-    # This trims it down to just the version number:
-    #       2.0.0
-    echo "$(gitea --version 2>/dev/null | head -n 1 | cut -d' ' -f3)"
-}
-
-pkg_format_cmd_version() {
-    # 'gitea v2.1.0' is the canonical version format for gitea
-    my_version="$1"
-    echo "$pkg_cmd_name v$my_version"
-}
-
-pkg_link_src_dst() {
-    # gitea is just a single file, no directory linking to do
-    true
-}
-
-pkg_pre_install() {
-    # if selected version is installed, quit
-    webi_check
-    # will save to ~/Downloads/$WEBI_PKG_FILE by default
-    webi_download
-    # supported formats (.xz, .tar.*, .zip) will be extracted to $WEBI_TMP
-    webi_extract
-}
-
-pkg_install() {
-    pushd "$WEBI_TMP" 2>&1 >/dev/null
-
-        # rename the entire extracted folder to the new location
-        # (this will be "$HOME/.local/bin/gitea" by default)
-        mkdir -p "$pkg_dst_bin"
-        mv ./"$pkg_cmd_name"* "$pkg_dst_cmd"
-        chmod a+x "$pkg_dst_cmd"
-
-    popd 2>&1 >/dev/null
-}
-
-pkg_post_install() {
-    # just in case we add something in the future
-    pkg_link_src_dst
-
-    # web_path_add is defined in webi/template.bash at https://github.com/webinstall/packages
-    # Adds "$HOME/.local/bin" to PATH
-    webi_path_add "$pkg_dst_bin"
-}
-
-pkg_post_install_message() {
-    echo "Installed 'gitea' v$WEBI_VERSION as $pkg_dst_cmd"
-}
diff --git a/gitea/install.sh b/gitea/install.sh
new file mode 100644 (file)
index 0000000..31d575c
--- /dev/null
@@ -0,0 +1,18 @@
+set -e
+set -u
+
+pkg_cmd_name="gitea"
+
+pkg_get_current_version() {
+    # 'gitea version' has output in this format:
+    #       v2.1.0 h1:pQSaIJGFluFvu8KDGDODV8u4/QRED/OPyIR+MWYYse8=
+    # This trims it down to just the version number:
+    #       2.0.0
+    echo "$(gitea --version 2>/dev/null | head -n 1 | cut -d' ' -f3)"
+}
+
+pkg_format_cmd_version() {
+    # 'gitea v2.1.0' is the canonical version format for gitea
+    my_version="$1"
+    echo "$pkg_cmd_name v$my_version"
+}
diff --git a/gitea/package.yash b/gitea/package.yash
new file mode 100644 (file)
index 0000000..1eacd29
--- /dev/null
@@ -0,0 +1,11 @@
+# title: Gitea
+# homepage: https://github.com/go-gitea/gitea
+# tagline: Git with a cup of tea, painless self-hosted git service
+# description: |
+#   `gitea` is a clean, lightweight self-hosted Github alternative, forked from Gogs. Lighter and more user-friendly than Gitlab.
+# examples: |
+#   ```bash
+#   gitea --version
+#   ```
+
+END
index 41e1ee527782e9c44173b89e04b82d860c165ce1..e24c7562ca86e74302229fe2b8565b702a01c32c 100644 (file)
@@ -16,7 +16,7 @@ module.exports = function (request) {
 
 if (module === require.main) {
   module.exports(require('@root/request')).then(function (all) {
-    all = require('../_common/normalize.js')(all);
+    all = require('../_webi/normalize.js')(all);
     console.info(JSON.stringify(all));
   });
 }
diff --git a/go/install.bash b/go/install.bash
deleted file mode 100644 (file)
index a88c0e7..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-# title: Go (golang alias)
-# homepage: https://webinstall.dev/golang
-# tagline: Alias for https://webinstall.dev/golang
-# alias: golang
-# description: |
-#   See https://webinstall.dev/golang
-
-echo "'go@${WEBI_TAG:-}' is an alias for 'golang@${WEBI_VERSION:-}'"
-curl -fsSL https://webinstall.dev/golang@${WEBI_VERSION:-} | bash
diff --git a/go/install.sh b/go/install.sh
new file mode 100644 (file)
index 0000000..a88c0e7
--- /dev/null
@@ -0,0 +1,9 @@
+# title: Go (golang alias)
+# homepage: https://webinstall.dev/golang
+# tagline: Alias for https://webinstall.dev/golang
+# alias: golang
+# description: |
+#   See https://webinstall.dev/golang
+
+echo "'go@${WEBI_TAG:-}' is an alias for 'golang@${WEBI_VERSION:-}'"
+curl -fsSL https://webinstall.dev/golang@${WEBI_VERSION:-} | bash
diff --git a/golang/install.bash b/golang/install.bash
deleted file mode 100644 (file)
index fa97d20..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-#!/bin/bash
-
-# title: Go
-# homepage: https://golang.org
-# tagline: The Go Programming Language tools
-# description: |
-#   Go is an open source programming language that makes it easy to build simple, reliable, and efficient software.
-# examples: |
-#   ```bash
-#   mkdir -p hello/
-#   pushd hello/
-#   ```
-#
-#   ```bash
-#   cat << EOF >> main.go
-#   package main
-#
-#   import (
-#     "fmt"
-#   )
-#
-#   func main () {
-#     fmt.Println("Hello, World!")
-#   }
-#   EOF
-#   ```
-#
-#   ```bash
-#   go fmt ./...
-#   go build .
-#   ./hello
-#   > Hello, World!
-#   ```
-
-set -e
-set -u
-
-GOBIN="${HOME}/go"
-GOBIN_REAL="${HOME}/.local/opt/go-bin-v${WEBI_VERSION}"
-
-# The package is 'golang', but the command is 'go'
-pkg_cmd_name="go"
-
-# NOTE: pkg_* variables can be defined here
-#       pkg_cmd_name
-#       pkg_src, pkg_src_bin, pkg_src_cmd
-#       pkg_dst, pkg_dst_bin, pkg_dst_cmd
-#
-# Their defaults are defined in webi/template.bash at https://github.com/webinstall/packages
-
-pkg_get_current_version() {
-    # 'go version' has output in this format:
-    #       go version go1.14.2 darwin/amd64
-    # This trims it down to just the version number:
-    #       1.14.2
-    echo "$(go version 2>/dev/null | head -n 1 | cut -d' ' -f3 | sed 's:go::')"
-}
-
-pkg_format_cmd_version() {
-    # 'go v1.14.0' will be 'go1.14'
-    my_version=$(echo "$1" | sed 's:\.0::g')
-    echo "${pkg_cmd_name}${my_version}"
-}
-
-pkg_link_src_dst() {
-    # 'pkg_dst' will default to $HOME/.local/opt/go
-    # 'pkg_src' will be the installed version, such as to $HOME/.local/opt/go-v1.14.2
-    rm -rf "$pkg_dst"
-    ln -s "$pkg_src" "$pkg_dst"
-
-    # Go has a special $GOBIN
-
-    # 'GOBIN' is set above to "${HOME}/go"
-    # 'GOBIN_REAL' will be "${HOME}/.local/opt/go-bin-v${WEBI_VERSION}"
-    rm -rf "$GOBIN"
-    mkdir -p "$GOBIN_REAL/bin"
-    ln -s "$GOBIN_REAL" "$GOBIN"
-}
-
-pkg_pre_install() {
-    # web_* are defined in webi/template.bash at https://github.com/webinstall/packages
-
-    # multiple versions may be installed
-    # if one already matches, it will simply be re-linked
-    webi_check
-
-    # the download is quite large - hopefully you have wget installed
-    # will go to ~/Downloads by default
-    webi_download
-
-    # Multiple formats are supported: .xz, .tar.*, and .zip
-    # will be extracted to $WEBI_TMP
-    webi_extract
-}
-
-pkg_install() {
-    pushd "$WEBI_TMP" 2>&1 >/dev/null
-
-        # remove the versioned folder, just in case it's there with junk
-        rm -rf "$pkg_src"
-
-        # rename the entire extracted folder to the new location
-        # (this will be "$HOME/.local/opt/go-v$WEBI_VERSION" by default)
-        mv ./"$pkg_cmd_name"* "$pkg_src"
-
-    popd 2>&1 >/dev/null
-}
-
-pkg_post_install() {
-    pkg_link_src_dst
-
-    # web_path_add is defined in webi/template.bash at https://github.com/webinstall/packages
-    # Updates PATH with
-    #       "$HOME/.local/opt/go"
-    webi_path_add "$pkg_dst_bin"
-    webi_path_add "$GOBIN/bin"
-
-    # Install x go
-    echo "Installing go extended tools (goimports, gorename, etc)"
-    "$pkg_dst_cmd" get golang.org/x/tools/cmd/goimports > /dev/null 2>/dev/null
-    "$pkg_dst_cmd" get golang.org/x/tools/cmd/gorename > /dev/null 2>/dev/null
-    "$pkg_dst_cmd" get golang.org/x/tools/cmd/gotype > /dev/null 2>/dev/null
-    "$pkg_dst_cmd" get golang.org/x/tools/cmd/stringer > /dev/null 2>/dev/null
-}
-
-pkg_post_install_message() {
-    echo "Installed 'go' (and go tools)"
-}
diff --git a/golang/install.sh b/golang/install.sh
new file mode 100644 (file)
index 0000000..30edb69
--- /dev/null
@@ -0,0 +1,66 @@
+set -e
+set -u
+
+GOBIN="${HOME}/go"
+GOBIN_REAL="${HOME}/.local/opt/go-bin-v${WEBI_VERSION}"
+
+# The package is 'golang', but the command is 'go'
+pkg_cmd_name="go"
+
+# NOTE: pkg_* variables can be defined here
+#       pkg_cmd_name
+#       pkg_src, pkg_src_bin, pkg_src_cmd
+#       pkg_dst, pkg_dst_bin, pkg_dst_cmd
+#
+# Their defaults are defined in webi/template.bash at https://github.com/webinstall/packages
+
+pkg_get_current_version() {
+    # 'go version' has output in this format:
+    #       go version go1.14.2 darwin/amd64
+    # This trims it down to just the version number:
+    #       1.14.2
+    echo "$(go version 2>/dev/null | head -n 1 | cut -d' ' -f3 | sed 's:go::')"
+}
+
+pkg_format_cmd_version() {
+    # 'go v1.14.0' will be 'go1.14'
+    my_version=$(echo "$1" | sed 's:\.0::g')
+    echo "${pkg_cmd_name}${my_version}"
+}
+
+pkg_link() {
+    # 'pkg_dst' will default to $HOME/.local/opt/go
+    # 'pkg_src' will be the installed version, such as to $HOME/.local/opt/go-v1.14.2
+    rm -rf "$pkg_dst"
+    ln -s "$pkg_src" "$pkg_dst"
+
+    # Go has a special $GOBIN
+
+    # 'GOBIN' is set above to "${HOME}/go"
+    # 'GOBIN_REAL' will be "${HOME}/.local/opt/go-bin-v${WEBI_VERSION}"
+    rm -rf "$GOBIN"
+    mkdir -p "$GOBIN_REAL/bin"
+    ln -s "$GOBIN_REAL" "$GOBIN"
+}
+
+pkg_post_install() {
+    webi_link
+
+    # web_path_add is defined in webi/template.bash at https://github.com/webinstall/packages
+    # Updates PATH with
+    #       "$HOME/.local/opt/go"
+    webi_path_add "$pkg_dst_bin"
+    webi_path_add "$GOBIN/bin"
+
+    # Install x go
+    echo "Building go extended tools (goimports, gorename, gotype, and stringer)"
+    "$pkg_dst_cmd" get golang.org/x/tools/cmd/goimports > /dev/null 2>/dev/null
+    "$pkg_dst_cmd" get golang.org/x/tools/cmd/gorename > /dev/null 2>/dev/null
+    "$pkg_dst_cmd" get golang.org/x/tools/cmd/gotype > /dev/null 2>/dev/null
+    "$pkg_dst_cmd" get golang.org/x/tools/cmd/stringer > /dev/null 2>/dev/null
+}
+
+pkg_done_message() {
+    echo "Installed 'go' v$WEBI_VERSION to ~/.local/opt/go"
+    echo "Installed go 'x' tools to GOBIN=\$HOME/go/bin"
+}
diff --git a/golang/package.yash b/golang/package.yash
new file mode 100644 (file)
index 0000000..447e3d8
--- /dev/null
@@ -0,0 +1,33 @@
+# title: Go
+# homepage: https://golang.org
+# tagline: The Go Programming Language tools
+# description: |
+#   Go is an open source programming language that makes it easy to build simple, reliable, and efficient software.
+# examples: |
+#   ```bash
+#   mkdir -p hello/
+#   pushd hello/
+#   ```
+#
+#   ```bash
+#   cat << EOF >> main.go
+#   package main
+#
+#   import (
+#     "fmt"
+#   )
+#
+#   func main () {
+#     fmt.Println("Hello, World!")
+#   }
+#   EOF
+#   ```
+#
+#   ```bash
+#   go fmt ./...
+#   go build .
+#   ./hello
+#   > Hello, World!
+#   ```
+
+END
index 133d8fd44b65e1b774bf219ce669753c0542a804..a9ad7de79c3b32272e216e9c3a0dc9ce6766db21 100644 (file)
@@ -71,7 +71,7 @@ module.exports = getAllReleases;
 
 if (module === require.main) {
   getAllReleases(require('@root/request')).then(function (all) {
-    all = require('../_common/normalize.js')(all);
+    all = require('../_webi/normalize.js')(all);
     all.releases = all.releases.slice(0, 10);
     console.info(JSON.stringify(all, null, 2));
   });
diff --git a/hugo/install.bash b/hugo/install.bash
deleted file mode 100644 (file)
index 1fe55ef..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-# title: Hugo
-# homepage: https://github.com/gohugoio/hugo
-# tagline: The world’s fastest framework for building websites
-# description: |
-#   Hugo is one of the most popular open-source static site generators. With its amazing speed and flexibility, Hugo makes building websites fun again.
-# examples: |
-#   ```bash
-#   hugo
-#   ```
-#
-#   ```bash
-#   hugo server -D
-#   ```
-
-set -e
-set -u
-
-pkg_cmd_name="hugo"
-pkg_dst="$HOME/.local"
-
-# pkg_src isn't used in this script,
-# just setting a junk value for completeness (and possibly debug output)
-pkg_src="$HOME/Downloads/$WEBI_PKG_FILE"
-
-pkg_get_current_version() {
-    # 'hugo version' has output in this format:
-    #       Hugo Static Site Generator v0.72.0-8A7EF3CF darwin/amd64 BuildDate: 2020-05-31T12:07:44Z
-    # This trims it down to just the version number:
-    #       0.72.0
-    echo "$(hugo version 2>/dev/null | head -n 1 | cut -d' ' -f5 | cut -d '-' -f1 | sed 's:^v::')"
-}
-
-pkg_format_cmd_version() {
-    # 'node v12.8.0' is the canonical version format for node
-    my_version="$1"
-    echo "$pkg_cmd_name v$my_version"
-}
-
-pkg_link_src_dst() {
-    # hugo is just a single file, no directory linking to do
-    true
-}
-
-pkg_pre_install() {
-    # if selected version is installed, quit
-    webi_check
-    # will save to ~/Downloads/$WEBI_PKG_FILE by default
-    webi_download
-    # supported formats (.xz, .tar.*, .zip) will be extracted to $WEBI_TMP
-    webi_extract
-}
-
-pkg_install() {
-    pushd "$WEBI_TMP" 2>&1 >/dev/null
-
-        # rename the entire extracted folder to the new location
-        # (this will be "$HOME/.local/opt/node-v$WEBI_VERSION" by default)
-        mkdir -p "$pkg_dst_bin"
-        mv ./"$pkg_cmd_name"* "$pkg_dst_cmd"
-        chmod a+x "$pkg_dst_cmd"
-
-    popd 2>&1 >/dev/null
-}
-
-pkg_post_install() {
-    # just in case we add something in the future
-    pkg_link_src_dst
-
-    # web_path_add is defined in webi/template.bash at https://github.com/webinstall/packages
-    # Adds "$HOME/.local/opt/node" to PATH
-    webi_path_add "$pkg_dst_bin"
-}
diff --git a/hugo/install.sh b/hugo/install.sh
new file mode 100644 (file)
index 0000000..7326ccf
--- /dev/null
@@ -0,0 +1,58 @@
+set -e
+set -u
+
+pkg_cmd_name="hugo"
+pkg_dst="$HOME/.local"
+
+# pkg_src isn't used in this script,
+# just setting a junk value for completeness (and possibly debug output)
+pkg_src="$HOME/Downloads/$WEBI_PKG_FILE"
+
+pkg_get_current_version() {
+    # 'hugo version' has output in this format:
+    #       Hugo Static Site Generator v0.72.0-8A7EF3CF darwin/amd64 BuildDate: 2020-05-31T12:07:44Z
+    # This trims it down to just the version number:
+    #       0.72.0
+    echo "$(hugo version 2>/dev/null | head -n 1 | cut -d' ' -f5 | cut -d '-' -f1 | sed 's:^v::')"
+}
+
+pkg_format_cmd_version() {
+    # 'node v12.8.0' is the canonical version format for node
+    my_version="$1"
+    echo "$pkg_cmd_name v$my_version"
+}
+
+pkg_link() {
+    # hugo is just a single file, no directory linking to do
+    true
+}
+
+pkg_pre_install() {
+    # if selected version is installed, quit
+    webi_check
+    # will save to ~/Downloads/$WEBI_PKG_FILE by default
+    webi_download
+    # supported formats (.xz, .tar.*, .zip) will be extracted to $WEBI_TMP
+    webi_extract
+}
+
+pkg_install() {
+    pushd "$WEBI_TMP" 2>&1 >/dev/null
+
+        # rename the entire extracted folder to the new location
+        # (this will be "$HOME/.local/opt/node-v$WEBI_VERSION" by default)
+        mkdir -p "$pkg_dst_bin"
+        mv ./"$pkg_cmd_name"* "$pkg_dst_cmd"
+        chmod a+x "$pkg_dst_cmd"
+
+    popd 2>&1 >/dev/null
+}
+
+pkg_post_install() {
+    # just in case we add something in the future
+    pkg_link
+
+    # web_path_add is defined in webi/template.bash at https://github.com/webinstall/packages
+    # Adds "$HOME/.local/opt/node" to PATH
+    webi_path_add "$pkg_dst_bin"
+}
diff --git a/hugo/package.yash b/hugo/package.yash
new file mode 100644 (file)
index 0000000..4cf4941
--- /dev/null
@@ -0,0 +1,15 @@
+# title: Hugo
+# homepage: https://github.com/gohugoio/hugo
+# tagline: The world’s fastest framework for building websites
+# description: |
+#   Hugo is one of the most popular open-source static site generators. With its amazing speed and flexibility, Hugo makes building websites fun again.
+# examples: |
+#   ```bash
+#   hugo
+#   ```
+#
+#   ```bash
+#   hugo server -D
+#   ```
+
+END
index e143123a18f4d2799c966ce5013245c964f24736..610129b16dfa2e34c2651d2ebbb0226ccf0e36fa 100644 (file)
@@ -16,7 +16,7 @@ module.exports = function (request) {
 
 if (module === require.main) {
   module.exports(require('@root/request')).then(function (all) {
-    all = require('../_common/normalize.js')(all);
+    all = require('../_webi/normalize.js')(all);
     console.info(JSON.stringify(all));
   });
 }
diff --git a/macos/install.bash b/macos/install.bash
deleted file mode 100644 (file)
index dd5566b..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-# title: macOS
-# homepage: https://bootableinstaller.com/macos/
-# tagline: Bootable macOS Installer
-# description: |
-#   Downloads the official OS X / macOS dmg from Apple to create bootable installers - works from macOS, Linux, or even Windows (through VirtualBox).
-# examples: |
-#
-#   Use with Balena Etcher to burn ISO to USB, or boot with VirtualBox.
-#
-#   ```txt
-#   Created ~/Downloads/el-capitan.iso
-#   ```
-
-set -e
-set -u
-
-webi_download
-
-pushd ~/Downloads 2>&1 >/dev/null
-
-if [ "Darwin" == "$(uname -s)" ]; then
-  curl -fsSL 'https://gist.githubusercontent.com/solderjs/8c36d132250163011c83bad8284975ee/raw/5a291955813743c20c12ca2d35c7b1bb34f8aecc/create-bootable-installer-for-os-x-el-capitan.sh' -o create-bootable-installer-for-os-x-el-capitan.sh
-  bash create-bootable-installer-for-os-x-el-capitan.sh
-else
-  curl -fsSL 'https://gist.githubusercontent.com/solderjs/9834a45a6c21a41e8882698a00b55787/raw/c43061cd0c53ec675996f5cb66c7077e666aabd4/install-mac-tools.sh' -o install-mac-tools.sh
-  # TODO add xar to webinstall.dev
-  sudo apt install libz-dev # needed for xar
-  bash install-mac-tools.sh
-  echo "WARN: may need a restart for hfsplus to be recognized by the kernel"
-
-  curl -fsSL 'https://gist.github.com/solderjs/04fd06560a8465a695337eb502f5b0e9/raw/0a06fb4dce91399d374d9a12958dabb48a9bd42a/empty.7400m.img.bz2' -o empty.7400m.img.bz2
-
-  curl -fsSL 'https://gist.githubusercontent.com/solderjs/9834a45a6c21a41e8882698a00b55787/raw/c43061cd0c53ec675996f5cb66c7077e666aabd4/linux-create-bootable-macos-recovery-image.sh' -o linux-create-bootable-macos-recovery-image.sh
-  bash linux-create-bootable-macos-recovery-image.sh
-fi
-
-echo ""
-echo "Created $HOME/Downloads/el-capitan.iso"
-echo ""
-
-popd 2>&1 >/dev/null
diff --git a/macos/install.sh b/macos/install.sh
new file mode 100644 (file)
index 0000000..dd5566b
--- /dev/null
@@ -0,0 +1,41 @@
+# title: macOS
+# homepage: https://bootableinstaller.com/macos/
+# tagline: Bootable macOS Installer
+# description: |
+#   Downloads the official OS X / macOS dmg from Apple to create bootable installers - works from macOS, Linux, or even Windows (through VirtualBox).
+# examples: |
+#
+#   Use with Balena Etcher to burn ISO to USB, or boot with VirtualBox.
+#
+#   ```txt
+#   Created ~/Downloads/el-capitan.iso
+#   ```
+
+set -e
+set -u
+
+webi_download
+
+pushd ~/Downloads 2>&1 >/dev/null
+
+if [ "Darwin" == "$(uname -s)" ]; then
+  curl -fsSL 'https://gist.githubusercontent.com/solderjs/8c36d132250163011c83bad8284975ee/raw/5a291955813743c20c12ca2d35c7b1bb34f8aecc/create-bootable-installer-for-os-x-el-capitan.sh' -o create-bootable-installer-for-os-x-el-capitan.sh
+  bash create-bootable-installer-for-os-x-el-capitan.sh
+else
+  curl -fsSL 'https://gist.githubusercontent.com/solderjs/9834a45a6c21a41e8882698a00b55787/raw/c43061cd0c53ec675996f5cb66c7077e666aabd4/install-mac-tools.sh' -o install-mac-tools.sh
+  # TODO add xar to webinstall.dev
+  sudo apt install libz-dev # needed for xar
+  bash install-mac-tools.sh
+  echo "WARN: may need a restart for hfsplus to be recognized by the kernel"
+
+  curl -fsSL 'https://gist.github.com/solderjs/04fd06560a8465a695337eb502f5b0e9/raw/0a06fb4dce91399d374d9a12958dabb48a9bd42a/empty.7400m.img.bz2' -o empty.7400m.img.bz2
+
+  curl -fsSL 'https://gist.githubusercontent.com/solderjs/9834a45a6c21a41e8882698a00b55787/raw/c43061cd0c53ec675996f5cb66c7077e666aabd4/linux-create-bootable-macos-recovery-image.sh' -o linux-create-bootable-macos-recovery-image.sh
+  bash linux-create-bootable-macos-recovery-image.sh
+fi
+
+echo ""
+echo "Created $HOME/Downloads/el-capitan.iso"
+echo ""
+
+popd 2>&1 >/dev/null
diff --git a/node/install.bash b/node/install.bash
deleted file mode 100644 (file)
index e65662b..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-#!/bin/bash
-
-# title: Node.js
-# homepage: https://nodejs.org
-# tagline: JavaScript V8 runtime
-# description: |
-#   Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine
-# examples: |
-#
-#   ### Hello World
-#
-#   ```bash
-#   node -e 'console.log("Hello, World!")'
-#   > Hello, World!
-#   ```
-#
-#   ### A Simple Web Server
-#
-#   `server.js`:
-#
-#   ```bash
-#   var http = require('http');
-#   var app = function (req, res) {
-#     res.end('Hello, World!');
-#   };
-#   http.createServer(app).listen(8080, function () {
-#     console.info('Listening on', this.address());
-#   });
-#   ```
-#
-#   ```bash
-#   node server.js
-#   ```
-#
-#   ### An Express App
-#
-#   ```bash
-#   mkdir my-server
-#   pushd my-server
-#   npm init
-#   npm install --save express
-#   ```
-#
-#   `app.js`:
-#
-#   ```js
-#   'use strict';
-#
-#   var express = require('express');
-#   var app = express();
-#
-#   app.use('/', function (req, res, next) {
-#     res.end("Hello, World!");
-#   });
-#
-#   module.exports = app;</code></pre>
-#   ```
-#
-#   `server.js`:
-#
-#   ```js
-#   'use strict';
-#
-#   var http = require('http');
-#   var app = require('./app.js');
-#
-#   http.createServer(app).listen(8080, function () {
-#     console.info('Listening on', this.address());
-#   });
-#   ```
-#
-#   ```bash
-#   npm start
-#   ```
-#
-
-set -e
-set -u
-
-pkg_cmd_name="node"
-
-pkg_get_current_version() {
-    # 'node --version' has output in this format:
-    #       v12.8.0
-    # This trims it down to just the version number:
-    #       12.8.0
-    echo "$(node --version 2>/dev/null | head -n 1 | cut -d' ' -f1 | sed 's:^v::')"
-}
-
-pkg_format_cmd_version() {
-    # 'node v12.8.0' is the canonical version format for node
-    my_version="$1"
-    echo "$pkg_cmd_name v$my_version"
-}
-
-pkg_link_src_dst() {
-    # 'pkg_dst' will default to $HOME/.local/opt/node
-    # 'pkg_src' will be the installed version, such as to $HOME/.local/opt/node-v12.8.0
-    rm -rf "$pkg_dst"
-    ln -s "$pkg_src" "$pkg_dst"
-}
-
-pkg_pre_install() {
-    # web_* are defined in webi/template.bash at https://github.com/webinstall/packages
-
-    # if selected version is installed, re-link it and quit
-    webi_check
-
-    # will save to ~/Downloads/$WEBI_PKG_FILE by default
-    webi_download
-
-    # supported formats (.xz, .tar.*, .zip) will be extracted to $WEBI_TMP
-    webi_extract
-}
-
-pkg_install() {
-    pushd "$WEBI_TMP" 2>&1 >/dev/null
-
-        # remove the versioned folder, just in case it's there with junk
-        rm -rf "$pkg_src"
-
-        # rename the entire extracted folder to the new location
-        # (this will be "$HOME/.local/opt/node-v$WEBI_VERSION" by default)
-
-        # ex (full directory): ./node-v13-linux-amd64/bin/node.exe
-        mv ./"$pkg_cmd_name"* "$pkg_src"
-
-        # ex (single file): ./caddy-v13-linux-amd64.exe
-        #mv ./"$pkg_cmd_name"* "$pkg_dst_cmd"
-        #chmod a+x "$pkg_dst_cmd"
-
-        # ex (single file, nested in directory): ./rg/rg-v13-linux-amd64
-        #mv ./"$pkg_cmd_name"*/"$pkg_cmd_name"* "$pkg_commend_cmd"
-        #chmod a+x "$pkg_dst_cmd"
-
-    popd 2>&1 >/dev/null
-}
-
-pkg_post_install() {
-    pkg_link_src_dst
-
-    # web_path_add is defined in webi/template.bash at https://github.com/webinstall/packages
-    # Adds "$HOME/.local/opt/node/bin" to PATH
-    webi_path_add "$pkg_dst_bin"
-}
-
-pkg_post_install_message() {
-    echo "Installed 'node' and 'npm'"
-}
diff --git a/node/install.sh b/node/install.sh
new file mode 100644 (file)
index 0000000..f2c259c
--- /dev/null
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+set -e
+set -u
+
+pkg_cmd_name="node"
+
+pkg_get_current_version() {
+    # 'node --version' has output in this format:
+    #       v12.8.0
+    # This trims it down to just the version number:
+    #       12.8.0
+    echo "$(node --version 2>/dev/null | head -n 1 | cut -d' ' -f1 | sed 's:^v::')"
+}
+
+pkg_install() {
+    # mkdir -p $HOME/.local/opt
+    mkdir -p "$(dirname $pkg_src)"
+
+    # mv ./node* "$HOME/.local/opt/node-v14.4.0"
+    mv ./"$pkg_cmd_name"* "$pkg_src"
+}
+
+pkg_link() {
+    # rm -f "$HOME/.local/opt/node"
+    rm -f "$pkg_dst"
+
+    # ln -s "$HOME/.local/opt/node-v14.4.0" "$HOME/.local/opt/node"
+    ln -s "$pkg_src" "$pkg_dst"
+}
+
+pkg_done_message() {
+    echo "Installed 'node' and 'npm' at $pkg_dst"
+}
diff --git a/node/package.yash b/node/package.yash
new file mode 100644 (file)
index 0000000..a10af04
--- /dev/null
@@ -0,0 +1,78 @@
+#
+# title: Node.js
+# homepage: https://nodejs.org
+# tagline: JavaScript V8 runtime
+# description: |
+#   Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine
+# examples: |
+#
+#   ### Hello World
+#
+#   ```bash
+#   node -e 'console.log("Hello, World!")'
+#   > Hello, World!
+#   ```
+#
+#   ### A Simple Web Server
+#
+#   `server.js`:
+#
+#   ```bash
+#   var http = require('http');
+#   var app = function (req, res) {
+#     res.end('Hello, World!');
+#   };
+#   http.createServer(app).listen(8080, function () {
+#     console.info('Listening on', this.address());
+#   });
+#   ```
+#
+#   ```bash
+#   node server.js
+#   ```
+#
+#   ### An Express App
+#
+#   ```bash
+#   mkdir my-server
+#   pushd my-server
+#   npm init
+#   npm install --save express
+#   ```
+#
+#   `app.js`:
+#
+#   ```js
+#   'use strict';
+#
+#   var express = require('express');
+#   var app = express();
+#
+#   app.use('/', function (req, res, next) {
+#     res.end("Hello, World!");
+#   });
+#
+#   module.exports = app;</code></pre>
+#   ```
+#
+#   `server.js`:
+#
+#   ```js
+#   'use strict';
+#
+#   var http = require('http');
+#   var app = require('./app.js');
+#
+#   http.createServer(app).listen(8080, function () {
+#     console.info('Listening on', this.address());
+#   });
+#   ```
+#
+#   ```bash
+#   npm start
+#   ```
+#
+
+This is a comment... because... poor choices I made.
+
+Don't worry, this will be yaml or markdown in the... sometime... future
index 9f0077b6515c16d2584746fcc8e52d4f0771b883..44f4cad0f99269b9971a991e06db1765706af312 100644 (file)
@@ -140,7 +140,7 @@ module.exports = getAllReleases;
 
 if (module === require.main) {
   getAllReleases(require('@root/request')).then(function (all) {
-    all = require('../_common/normalize.js')(all);
+    all = require('../_webi/normalize.js')(all);
     console.info(JSON.stringify(all));
     //console.info(JSON.stringify(all, null, 2));
   });
diff --git a/pathman/install.bash b/pathman/install.bash
deleted file mode 100644 (file)
index 4b9e538..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/bin/bash
-
-# title: Pathman
-# homepage: https://git.rootprojects.org/root/pathman
-# tagline: cross-platform PATH management for bash, zsh, fish, cmd.exe, and PowerShell
-# description: |
-#   Manages PATH on various OSes and shells
-#     - Mac, Windows, Linux
-#     - Bash, Zsh, Fish
-#     - Command, Powershell
-# examples: |
-#   ```bash
-#   pathman add ~/.local/bin
-#   ```
-#   <br/>
-#
-#   ```bash
-#   pathman remove ~/.local/bin
-#   ```
-#   <br/>
-#
-#   ```bash
-#   pathman list
-#   ```
-
-
-set -e
-set -u
-
-# Test if in PATH
-set +e
-my_pathman=$(command -v pathman)
-set -e
-if [ -n "$my_pathman" ]; then
-    # TODO test pathman version
-    # if [ "$WEBI_VERSION" == "$(pathman version | cut -d ' ' -f2)" ]; then
-       if [ "$my_pathman" != "$HOME/.local/bin/pathman" ]; then
-               echo "a pathman installation (which make take precedence) exists at:"
-               echo "    $my_pathman"
-               echo ""
-       fi
-    echo "pathman already installed"
-    exit 0
-fi
-
-# TODO use webi_download via releases.js
-webi_download "https://rootprojects.org/pathman/dist/$(uname -s)/$(uname -m)/pathman" "$HOME/.local/bin/pathman"
-
-# TODO use webi_extract
-chmod +x "$HOME/.local/bin/pathman"
-
-# add to ~/.local/bin to PATH even if pathman is elsewhere
-# TODO pathman needs silent option and debug output (quiet "already exists" output)
-"$HOME/.local/bin/pathman" add ~/.local/bin # > /dev/null 2> /dev/null
-# TODO inform user to add to path, apart from pathman?
diff --git a/pathman/install.sh b/pathman/install.sh
new file mode 100644 (file)
index 0000000..309befc
--- /dev/null
@@ -0,0 +1,79 @@
+#!/bin/bash
+
+# title: Pathman
+# homepage: https://git.rootprojects.org/root/pathman
+# tagline: cross-platform PATH management for bash, zsh, fish, cmd.exe, and PowerShell
+# description: |
+#   Manages PATH on various OSes and shells
+#     - Mac, Windows, Linux
+#     - Bash, Zsh, Fish
+#     - Command, Powershell
+# examples: |
+#   ```bash
+#   pathman add ~/.local/bin
+#   ```
+#   <br/>
+#
+#   ```bash
+#   pathman remove ~/.local/bin
+#   ```
+#   <br/>
+#
+#   ```bash
+#   pathman list
+#   ```
+
+
+set -e
+set -u
+
+pkg_cmd_name="pathman"
+WEBI_SINGLE=true
+
+pkg_get_current_version() {
+    echo $(pathman version 2>/dev/null | head -n 1 | cut -d ' ' -f2 | sed 's:^v::')
+}
+
+x_pkg_pre_install() {
+    # Test if in PATH
+    set +e
+    my_pathman=$(command -v pathman)
+    set -e
+    if [ -n "$my_pathman" ]; then
+        # TODO test pathman version
+        # if [ "$WEBI_VERSION" == "$(pathman version | cut -d ' ' -f2)" ]; then
+        if [ "$my_pathman" != "$HOME/.local/bin/pathman" ]; then
+            echo "a pathman installation (which make take precedence) exists at:"
+            echo "    $my_pathman"
+            echo ""
+        fi
+        echo "pathman already installed"
+        exit 0
+    fi
+}
+
+x_pkg_install() {
+    # TODO use webi_download via releases.js
+    mkdir -p "$HOME/.local/bin/"
+    webi_check
+    webi_download
+    webi_download
+    # webi_download "https://rootprojects.org/pathman/dist/$(uname -s)/$(uname -m)/pathman"
+    mv "$HOME/Downloads/pathman-v0.5.2" "$HOME/.local/bin/pathman"
+    chmod +x "$HOME/.local/bin/pathman"
+}
+
+x_pkg_link() {
+    true
+}
+
+pkg_post_install() {
+    # add to ~/.local/bin to PATH even if pathman is elsewhere
+    # TODO pathman needs silent option and debug output (quiet "already exists" output)
+    # TODO inform user to add to path, apart from pathman?
+    "$HOME/.local/bin/pathman" add "$HOME/.local/bin"
+}
+
+pkg_done_message() {
+    true
+}
diff --git a/rg/install.bash b/rg/install.bash
deleted file mode 100644 (file)
index afc1c19..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-# title: Ripgrep
-# homepage: https://github.com/BurntSushi/ripgrep
-# tagline: a modern drop-in grep replacement
-# alias: rg
-# description: |
-#   `rg` is a drop-in replacement for `grep`, that respects `.gitignore` and `.ignore`, has all of the sensible default options you want (colors, numbers, etc) turned on by default, is written in Rust, and simply outperforms grep in every imaginable way. R.I.P. grep.
-# examples: |
-#
-#   ```bash
-#   rg <search-term> # searches recursively, ignoing .git, node_modules, etc
-#   ```
-#
-#   ```bash
-#   rg 'function doStuff'
-#   ```
-#
-#   ```bash
-#   rg 'doStuff\(.*\)'
-#   ```
-
-set -e
-set -u
-
-###################
-# Install ripgrep #
-###################
-
-new_rg="${HOME}/.local/bin/rg"
-
-# Test for existing version
-set +e
-cur_rg="$(command -v rg)"
-set -e
-if [ -n "$cur_rg" ]; then
-  cur_ver=$(rg --version | head -n 1 | cut -d ' ' -f 2)
-  if [ "$cur_ver" == "$WEBI_VERSION" ]; then
-    echo "ripgrep v$WEBI_VERSION already installed at $cur_rg"
-    exit 0
-  elif [ "$cur_rg" != "$new_rg" ]; then
-    echo "WARN: possible conflict with ripgrep v$WEBI_VERSION at $cur_rg"
-  fi
-fi
-
-# Note: this file is `source`d by the true installer and hence will have the webi functions
-
-# because we created releases.js we can use webi_download()
-# downloads ripgrep to ~/Downloads
-webi_download
-
-# because this is tar or zip, we can webi_extract()
-# extracts to the WEBI_TMP directory, raw (no --strip-prefix)
-webi_extract
-
-pushd "$WEBI_TMP" 2>&1 >/dev/null
-        echo Installing ripgrep v${WEBI_VERSION} as "$new_rg"
-        mv ./ripgrep-*/rg "$HOME/.local/bin/"
-popd 2>&1 >/dev/null
-
-###################
-#   Update PATH   #
-###################
-
-# TODO get better output from pathman / output the path to add as return to webi bootstrap
-webi_path_add "$HOME/.local/bin"
-
-echo "Installed 'rg'"
-echo ""
diff --git a/rg/install.sh b/rg/install.sh
new file mode 100644 (file)
index 0000000..eb3cc3b
--- /dev/null
@@ -0,0 +1,24 @@
+set -e
+set -u
+
+###################
+# Install ripgrep #
+###################
+
+new_rg="${HOME}/.local/bin/rg"
+WEBI_SINGLE=true
+
+pkg_get_current_version() {
+  echo $(rg --version 2>/dev/null | head -n 1 | cut -d ' ' -f 2)
+}
+
+pkg_install() {
+    # $HOME/.local/xbin
+    mkdir -p "$pkg_src_bin"
+
+    # mv ./ripgrep-*/rg "$HOME/.local/xbin/rg-v11.1.0"
+    mv ./ripgrep-*/rg "$pkg_src_cmd"
+
+    # chmod a+x "$HOME/.local/xbin/rg-v11.1.0"
+    chmod a+x "$pkg_src_cmd"
+}
diff --git a/rg/package.yash b/rg/package.yash
new file mode 100644 (file)
index 0000000..7c11c6f
--- /dev/null
@@ -0,0 +1,21 @@
+# title: Ripgrep
+# homepage: https://github.com/BurntSushi/ripgrep
+# tagline: a modern drop-in grep replacement
+# alias: rg
+# description: |
+#   `rg` is a drop-in replacement for `grep`, that respects `.gitignore` and `.ignore`, has all of the sensible default options you want (colors, numbers, etc) turned on by default, is written in Rust, and simply outperforms grep in every imaginable way. R.I.P. grep.
+# examples: |
+#
+#   ```bash
+#   rg <search-term> # searches recursively, ignoing .git, node_modules, etc
+#   ```
+#
+#   ```bash
+#   rg 'function doStuff'
+#   ```
+#
+#   ```bash
+#   rg 'doStuff\(.*\)'
+#   ```
+
+END
diff --git a/ripgrep/install.bash b/ripgrep/install.bash
deleted file mode 100644 (file)
index 1805ebb..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-# title: Ripgrep (alias)
-# homepage: https://webinstall.dev/rg
-# tagline: `ripgrep` (project) is an alias for `rg` (command)
-# alias: rg
-# description: |
-#   See https://webinstall.dev/rg
-
-echo "'ripgrep@${WEBI_TAG:-}' (project) is an alias for 'rg@${WEBI_VERSION:-}' (command)"
-curl -fsSL https://webinstall.dev/rg@${WEBI_VERSION:-} | bash
diff --git a/ripgrep/install.sh b/ripgrep/install.sh
new file mode 100644 (file)
index 0000000..1805ebb
--- /dev/null
@@ -0,0 +1,9 @@
+# title: Ripgrep (alias)
+# homepage: https://webinstall.dev/rg
+# tagline: `ripgrep` (project) is an alias for `rg` (command)
+# alias: rg
+# description: |
+#   See https://webinstall.dev/rg
+
+echo "'ripgrep@${WEBI_TAG:-}' (project) is an alias for 'rg@${WEBI_VERSION:-}' (command)"
+curl -fsSL https://webinstall.dev/rg@${WEBI_VERSION:-} | bash
diff --git a/rust/install.bash b/rust/install.bash
deleted file mode 100644 (file)
index ae4a4ac..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-# title: Rust (rustlang alias)
-# homepage: https://webinstall.dev/rustlang
-# tagline: Alias for https://webinstall.dev/rustlang
-# alias: rustlang
-# description: |
-#   See https://webinstall.dev/rustlang
-
-echo "'rust' is an alias for 'rustlang'"
-curl -fsSL https://webinstall.dev/rustlang@${WEBI_VERSION:-} | bash
diff --git a/rust/install.sh b/rust/install.sh
new file mode 100644 (file)
index 0000000..ae4a4ac
--- /dev/null
@@ -0,0 +1,9 @@
+# title: Rust (rustlang alias)
+# homepage: https://webinstall.dev/rustlang
+# tagline: Alias for https://webinstall.dev/rustlang
+# alias: rustlang
+# description: |
+#   See https://webinstall.dev/rustlang
+
+echo "'rust' is an alias for 'rustlang'"
+curl -fsSL https://webinstall.dev/rustlang@${WEBI_VERSION:-} | bash
diff --git a/rustlang/install.bash b/rustlang/install.bash
deleted file mode 100644 (file)
index e95f172..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/bash
-
-# title: Rust
-# homepage: https://rust-lang.org
-# tagline: The Rust Toolchain
-# description: |
-#   A language empowering everyone to build reliable and efficient software.
-#
-#   Rust is the modern language used to build all of your favorite CLI tools, such as
-#     - rg (ripgrep, modern grep)
-#     - fd (modern find)
-#     - sd (modern sed)
-#     - lsd (modern ls)
-#     - bat (modern cat)
-# examples: |
-#   ```bash
-#   cargo install ripgrep
-#   ```
-#   <br/>
-#
-#   ```bash
-#   cargo new hello --bin
-#   cargo build --release
-#   ./hello
-#   > "Hello, world!"
-#   ```
-
-
-# Straight from https://rustup.rs/
-curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
diff --git a/rustlang/install.sh b/rustlang/install.sh
new file mode 100644 (file)
index 0000000..e95f172
--- /dev/null
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+# title: Rust
+# homepage: https://rust-lang.org
+# tagline: The Rust Toolchain
+# description: |
+#   A language empowering everyone to build reliable and efficient software.
+#
+#   Rust is the modern language used to build all of your favorite CLI tools, such as
+#     - rg (ripgrep, modern grep)
+#     - fd (modern find)
+#     - sd (modern sed)
+#     - lsd (modern ls)
+#     - bat (modern cat)
+# examples: |
+#   ```bash
+#   cargo install ripgrep
+#   ```
+#   <br/>
+#
+#   ```bash
+#   cargo new hello --bin
+#   cargo build --release
+#   ./hello
+#   > "Hello, world!"
+#   ```
+
+
+# Straight from https://rustup.rs/
+curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
diff --git a/serviceman/install.bash b/serviceman/install.bash
deleted file mode 100644 (file)
index df80877..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/bin/bash
-
-# title: Serviceman
-# homepage: https://git.rootprojects.org/root/serviceman
-# tagline: cross-platform service management for Linux, Mac, and Windows
-# description: |
-#   A system laucher that wraps `launchctl` (macOS), `systemctl` (Linux),
-#   and the Windows Registry to work cross-platform.
-# examples: |
-#
-#   Works with anything, including
-#
-#   ### Node.js
-#
-#   ```bash
-#   serviceman add --name my-service node ./serve.js --port 3000
-#   ```
-#
-#   ### Golang
-#
-#   ```bash
-#   go build -mod vendor cmd/my-service
-#   serviceman add ./my-service --port 3000
-#   ```
-#
-#   ### And even bash!
-#
-#   ```bash
-#   serviceman add --name backuper bash ./backup.sh /mnt/data
-#   ```
-
-set -e
-set -u
-
-# Test if in PATH
-set +e
-my_serviceman=$(command -v serviceman)
-set -e
-if [ -n "$my_serviceman" ]; then
-       if [ "$my_serviceman" != "$HOME/.local/bin/serviceman" ]; then
-               echo "a serviceman installation (which make take precedence) exists at:"
-               echo "    $my_serviceman"
-               echo ""
-       fi
-fi
-
-# Get arch envs, etc
-webi_download "https://rootprojects.org/serviceman/dist/$(uname -s)/$(uname -m)/serviceman" "$HOME/Downloads/serviceman"
-chmod +x "$HOME/Downloads/serviceman"
-mv "$HOME/Downloads/serviceman" "$HOME/.local/bin/"
-
-# add to ~/.local/bin to PATH, just in case
-webi_path_add $HOME/.local/bin # > /dev/null 2> /dev/null
-# TODO inform user to add to path, apart from pathman?
diff --git a/serviceman/install.sh b/serviceman/install.sh
new file mode 100644 (file)
index 0000000..df80877
--- /dev/null
@@ -0,0 +1,54 @@
+#!/bin/bash
+
+# title: Serviceman
+# homepage: https://git.rootprojects.org/root/serviceman
+# tagline: cross-platform service management for Linux, Mac, and Windows
+# description: |
+#   A system laucher that wraps `launchctl` (macOS), `systemctl` (Linux),
+#   and the Windows Registry to work cross-platform.
+# examples: |
+#
+#   Works with anything, including
+#
+#   ### Node.js
+#
+#   ```bash
+#   serviceman add --name my-service node ./serve.js --port 3000
+#   ```
+#
+#   ### Golang
+#
+#   ```bash
+#   go build -mod vendor cmd/my-service
+#   serviceman add ./my-service --port 3000
+#   ```
+#
+#   ### And even bash!
+#
+#   ```bash
+#   serviceman add --name backuper bash ./backup.sh /mnt/data
+#   ```
+
+set -e
+set -u
+
+# Test if in PATH
+set +e
+my_serviceman=$(command -v serviceman)
+set -e
+if [ -n "$my_serviceman" ]; then
+       if [ "$my_serviceman" != "$HOME/.local/bin/serviceman" ]; then
+               echo "a serviceman installation (which make take precedence) exists at:"
+               echo "    $my_serviceman"
+               echo ""
+       fi
+fi
+
+# Get arch envs, etc
+webi_download "https://rootprojects.org/serviceman/dist/$(uname -s)/$(uname -m)/serviceman" "$HOME/Downloads/serviceman"
+chmod +x "$HOME/Downloads/serviceman"
+mv "$HOME/Downloads/serviceman" "$HOME/.local/bin/"
+
+# add to ~/.local/bin to PATH, just in case
+webi_path_add $HOME/.local/bin # > /dev/null 2> /dev/null
+# TODO inform user to add to path, apart from pathman?
diff --git a/vim-sensible/install.bash b/vim-sensible/install.bash
deleted file mode 100644 (file)
index e19a75b..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/bash
-
-# title: vim-sensible
-# homepage: https://github.com/tpope/vim-sensible
-# tagline: sensible defaults for vim
-# description: |
-#   Think of sensible.vim as one step above 'nocompatible' mode: a universal set of defaults that (hopefully) everyone can agree on.
-# examples: |
-#   N/A
-
-mkdir -p $HOME/.vim/pack/plugins/start
-rm -rf $HOME/.vim/pack/plugins/start/sensible
-git clone --depth=1 https://tpope.io/vim/sensible.git $HOME/.vim/pack/plugins/start/sensible
diff --git a/vim-sensible/install.sh b/vim-sensible/install.sh
new file mode 100644 (file)
index 0000000..e19a75b
--- /dev/null
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+# title: vim-sensible
+# homepage: https://github.com/tpope/vim-sensible
+# tagline: sensible defaults for vim
+# description: |
+#   Think of sensible.vim as one step above 'nocompatible' mode: a universal set of defaults that (hopefully) everyone can agree on.
+# examples: |
+#   N/A
+
+mkdir -p $HOME/.vim/pack/plugins/start
+rm -rf $HOME/.vim/pack/plugins/start/sensible
+git clone --depth=1 https://tpope.io/vim/sensible.git $HOME/.vim/pack/plugins/start/sensible
diff --git a/webi/bootstrap.bash b/webi/bootstrap.bash
deleted file mode 100644 (file)
index 13d34d9..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/bin/bash
-
-{
-
-#WEBI_PKG=
-#WEBI_HOST=https://webinstall.dev
-export WEBI_HOST
-
-mkdir -p "$HOME/.local/bin"
-
-cat << EOF > "$HOME/.local/bin/webi"
-#!/bin/bash
-
-set -e
-set -u
-
-my_package="\${1:-}"
-if [ -z "\$my_package" ]; then
-       echo "Usage: webi <package>@<version>"
-       echo "Example: webi node@latest"
-       exit 1
-fi
-
-##
-## Detect acceptable package formats
-##
-
-my_ext=""
-set +e
-# NOTE: the order here is least favorable to most favorable
-if [ -n "\$(command -v pkgutil)" ]; then
-       my_ext="pkg,\$my_ext"
-fi
-# disable this check for the sake of building the macOS installer on Linux
-#if [ -n "\$(command -v diskutil)" ]; then
-       # note: could also detect via hdiutil
-       my_ext="dmg,\$my_ext"
-#fi
-if [ -n "\$(command -v git)" ]; then
-       my_ext="git,\$my_ext"
-fi
-if [ -n "\$(command -v unxz)" ]; then
-       my_ext="xz,\$my_ext"
-fi
-if [ -n "\$(command -v unzip)" ]; then
-       my_ext="zip,\$my_ext"
-fi
-if [ -n "\$(command -v tar)" ]; then
-       my_ext="tar,\$my_ext"
-fi
-my_ext="\$(echo "\$my_ext" | sed 's/,$//')" # nix trailing comma
-set -e
-
-##
-## Detect http client
-##
-set +e
-export WEBI_CURL="\$(command -v curl)"
-export WEBI_WGET="\$(command -v wget)"
-set -e
-
-export WEBI_BOOT="\$(mktemp -d -t "\$my_package-bootstrap.XXXXXXXX")"
-export WEBI_HOST="\${WEBI_HOST:-https://webinstall.dev}"
-export WEBI_UA="\$(uname -a)"
-
-my_installer_url="\$WEBI_HOST/api/installers/\$my_package.bash?formats=\$my_ext"
-set +e
-if [ -n "\$WEBI_CURL" ]; then
-       curl -fsSL "\$my_installer_url" -H "User-Agent: curl \$WEBI_UA" \\
-               -o "\$WEBI_BOOT/\$my_package-bootstrap.sh"
-else
-       wget -q "\$my_installer_url" --user-agent="wget \$WEBI_UA" \\
-               -O "\$WEBI_BOOT/\$my_package-bootstrap.sh"
-fi
-if ! [ \$? -eq 0 ]; then
-  echo "error fetching '\$my_installer_url'"
-  exit 1
-fi
-set -e
-
-pushd "\$WEBI_BOOT" 2>&1 > /dev/null
-       bash "\$my_package-bootstrap.sh"
-popd 2>&1 > /dev/null
-
-rm -rf "\$WEBI_BOOT"
-EOF
-
-chmod a+x "$HOME/.local/bin/webi"
-
-if [ -n "${WEBI_PKG:-}" ]; then
-    "$HOME/.local/bin/webi" "${WEBI_PKG}"
-fi
-
-}
diff --git a/webi/install.bash b/webi/install.bash
deleted file mode 100644 (file)
index 25c49a1..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/bash
-
-# title: Webi
-# homepage: https://webinstall.dev
-# tagline: webinstall.dev for the CLI
-# description: |
-#   for the people like us that are too lazy even to run <kbd>curl&nbsp;https://webinstall.dev/PACKAGE_NAME&nbsp;|&nbsp;bash</kbd>
-# examples: |
-#   ```bash
-#   webi node@latest
-#   ```
-#   <br/>
-#
-#   ```bash
-#   webi golang@v1.14
-#   ```
-#   <br/>
-#
-#   ```bash
-#   webi rustlang
-#   ```
-
-if [ -f "$HOME/.local/bin/webi" ]; then
-  set +e
-  cur_webi="$(command -v webi)"
-  set -e
-  if [ -z "$cur_webi" ]; then
-    webi_path_add "$HOME/.local/bin"
-  fi
-  echo "Installed 'webi'"
-else
-  # for when this file is run on its own, not from webinstall.dev
-  echo "Install any other package via https://webinstall.dev and webi will be installed as part of the bootstrap process"
-fi
diff --git a/webi/install.sh b/webi/install.sh
new file mode 100644 (file)
index 0000000..c5730b2
--- /dev/null
@@ -0,0 +1,38 @@
+#!/bin/bash
+
+# title: Webi
+# homepage: https://webinstall.dev
+# tagline: webinstall.dev for the CLI
+# description: |
+#   for the people like us that are too lazy even to run <kbd>curl&nbsp;https://webinstall.dev/PACKAGE_NAME&nbsp;|&nbsp;bash</kbd>
+# examples: |
+#   ```bash
+#   webi node@latest
+#   ```
+#   <br/>
+#
+#   ```bash
+#   webi golang@v1.14
+#   ```
+#   <br/>
+#
+#   ```bash
+#   webi rustlang
+#   ```
+
+{
+
+if [ -f "$HOME/.local/bin/webi" ]; then
+  set +e
+  cur_webi="$(command -v webi)"
+  set -e
+  if [ -z "$cur_webi" ]; then
+    webi_path_add "$HOME/.local/bin"
+  fi
+  echo "Installed 'webi'"
+else
+  # for when this file is run on its own, not from webinstall.dev
+  echo "Install any other package via https://webinstall.dev and webi will be installed as part of the bootstrap process"
+fi
+
+}
diff --git a/webi/template.bash b/webi/template.bash
deleted file mode 100644 (file)
index f5147ea..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-#!/bin/bash
-
-{
-
-set -e
-set -u
-
-#WEBI_PKG=
-#WEBI_NAME=
-# TODO should this be BASEURL instead?
-#WEBI_HOST=
-#WEBI_RELEASES=
-#WEBI_CSV=
-#WEBI_TAG=
-#WEBI_VERSION=
-#WEBI_MAJOR=
-#WEBI_MINOR=
-#WEBI_PATCH=
-# TODO not sure if BUILD is the best name for this
-#WEBI_BUILD=
-#WEBI_LTS=
-#WEBI_CHANNEL=
-#WEBI_EXT=
-#WEBI_PKG_URL=
-#WEBI_PKG_FILE=
-export WEBI_HOST
-
-##
-## Set up tmp, download, and install directories
-##
-
-WEBI_TMP=${WEBI_TMP:-"$(mktemp -d -t webinstall-${WEBI_PKG:-}.XXXXXXXX)"}
-
-mkdir -p "$HOME/Downloads"
-mkdir -p "$HOME/.local/bin"
-mkdir -p "$HOME/.local/opt"
-
-##
-## Detect http client
-##
-set +e
-export WEBI_CURL="$(command -v curl)"
-export WEBI_WGET="$(command -v wget)"
-set -e
-
-webi_check() {
-    # Test for existing version
-    set +e
-    my_current_cmd="$(command -v "$pkg_cmd_name")"
-    set -e
-    if [ -n "$my_current_cmd" ]; then
-        pkg_current_version="$(pkg_get_current_version)"
-        # remove trailing '.0's for golang's sake
-        my_current_version="$(echo $pkg_current_version | sed 's:\.0::g')"
-        my_src_version="$(echo $WEBI_VERSION | sed 's:\.0::g')"
-        if [ -n "$(command -v pkg_format_cmd_version)" ]; then
-            my_canonical_name="$(pkg_format_cmd_version "$WEBI_VERSION")"
-        else
-            #my_canonical_name="$WEBI_NAME $WEBI_VERSION"
-            my_canonical_name="$pkg_cmd_name v$WEBI_VERSION"
-        fi
-        if [ "$my_src_version" == "$my_current_version" ]; then
-            echo "$my_canonical_name already installed at $my_current_cmd"
-            exit 0
-        else
-            if [ "$my_current_cmd" != "$pkg_dst_cmd" ]; then
-                echo "WARN: possible conflict between $my_canonical_name and $pkg_current_version at $my_current_cmd"
-            fi
-            if [ -x "$pkg_src_cmd" ]; then
-                pkg_link_src_dst
-                echo "switched to $my_canonical_name at $pkg_src"
-                exit 0
-            fi
-          fi
-    fi
-}
-
-webi_download() {
-    if [ -n "${1:-}" ]; then
-        my_url="$1"
-    else
-        if [ "error" == "$WEBI_CHANNEL" ]; then
-            echo "Could not find $WEBI_NAME v$WEBI_VERSION"
-            exit 1
-        fi
-        my_url="$WEBI_PKG_URL"
-        echo "Downloading $WEBI_NAME v$WEBI_VERSION"
-    fi
-    if [ -n "${2:-}" ]; then
-        my_dl="$2"
-    else
-        my_dl="$HOME/Downloads/$WEBI_PKG_FILE"
-    fi
-
-    if [ -n "$WEBI_WGET" ]; then
-        # wget has resumable downloads
-        # TODO wget -c --content-disposition "$my_url"
-        set +e
-        wget -q --show-progress -c "$my_url" --user-agent="wget $WEBI_UA" -O "$my_dl"
-        if ! [ $? -eq 0 ]; then
-          echo "failed to download from $WEBI_PKG_URL"
-          exit 1
-        fi
-        set -e
-    else
-        # BSD curl is non-resumable, hence we don't bother
-        # TODO curl -fsSL --remote-name --remote-header-name --write-out "$my_url"
-        curl -fSL "$my_url" -H "User-Agent: curl $WEBI_UA" -o "$my_dl"
-    fi
-}
-
-webi_extract() {
-    pushd "$WEBI_TMP" 2>&1 >/dev/null
-        if [ "tar" == "$WEBI_EXT" ]; then
-            echo "Extracting $HOME/Downloads/$WEBI_PKG_FILE"
-            tar xf "$HOME/Downloads/$WEBI_PKG_FILE"
-        elif [ "zip" == "$WEBI_EXT" ]; then
-            echo "Extracting $HOME/Downloads/$WEBI_PKG_FILE"
-            unzip "$HOME/Downloads/$WEBI_PKG_FILE"
-        elif [ "exe" == "$WEBI_EXT" ]; then
-            # do nothing (but don't leave an empty if block either)
-            echo -n ""
-        elif [ "xz" == "$WEBI_EXT" ]; then
-            echo "Inflating $HOME/Downloads/$WEBI_PKG_FILE"
-            unxz -c "$HOME/Downloads/$WEBI_PKG_FILE" > $(basename "$WEBI_PKG_FILE")
-        else
-            # do nothing
-            echo "Failed to extract $HOME/Downloads/$WEBI_PKG_FILE"
-            exit 1
-        fi
-    popd 2>&1 >/dev/null
-}
-
-webi_path_add() {
-    # make sure that we don't recursively install pathman with webi
-    my_path="$PATH"
-    export PATH="$HOME/.local/bin:$PATH"
-    set +e
-    my_pathman=$(command -v pathman)
-    set -e
-    export PATH="$my_path"
-
-    # install pathman if not already installed
-    if [ -z "$my_pathman" ]; then
-        "$HOME/.local/bin/webi" pathman
-        "$HOME/.local/bin/pathman" add "$HOME/.local/bin"
-        export PATH="$HOME/.local/bin:$PATH"
-    fi
-
-    # in case pathman was recently installed and the PATH not updated
-    "$HOME/.local/bin/pathman" add "$1"
-}
-
-##
-##
-## BEGIN user-submited script
-##
-##
-
-{{ installer }}
-
-##
-##
-## END user-submitted script
-##
-##
-
-if [ -n "$(command -v pkg_install)" ]; then
-    pkg_cmd_name="${pkg_cmd_name:-$WEBI_NAME}"
-
-    pkg_dst="${pkg_dst:-$HOME/.local/opt/$pkg_cmd_name}"
-    pkg_dst_bin="${pkg_dst_bin:-$pkg_dst/bin}"
-    pkg_dst_cmd="${pkg_dst_cmd:-$pkg_dst_bin/$pkg_cmd_name}"
-
-    pkg_src="${pkg_src:-$HOME/.local/opt/$pkg_cmd_name-v$WEBI_VERSION}"
-    pkg_src_bin="${pkg_src_bin:-$pkg_src/bin}"
-    pkg_src_cmd="${pkg_src_cmd:-$pkg_src_bin/$pkg_cmd_name}"
-
-    [ -n "$(command -v pkg_pre_install)" ] && pkg_pre_install
-
-    echo "Installing '$pkg_cmd_name' v$WEBI_VERSION as $pkg_src_cmd"
-    pkg_install
-
-    [ -n "$(command -v pkg_post_install)" ] && pkg_post_install
-
-    if [ -n "$(command -v pkg_post_install_message)" ]; then
-        pkg_post_install_message
-    else
-        echo "Installed '$pkg_cmd_name' v$WEBI_VERSION as $pkg_src_cmd"
-    fi
-    echo ""
-fi
-
-rm -rf "$WEBI_TMP"
-
-}
diff --git a/webi/webinstall.bat b/webi/webinstall.bat
deleted file mode 100644 (file)
index 065ba29..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-@echo off
-pushd "%userprofile%" || goto :error
-  IF NOT EXIST .local (
-    mkdir .local || goto :error
-  )
-  IF NOT EXIST .local\bin (
-    mkdir .local\bin || goto :error
-  )
-  IF NOT EXIST .local\opt (
-    mkdir .local\opt || goto :error
-  )
-
-  pushd .local\bin || goto :error
-    if NOT EXIST pathman.exe (
-      echo updating PATH management
-      powershell $ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest https://webinstall.dev/packages/pathman/pathman.bat -OutFile pathman-setup.bat || goto :error
-      call .\pathman-setup.bat || goto :error
-      del pathman-setup.bat  || goto :error
-      rem TODO there's rumor of a windows tool called 'pathman' that does the same thing?
-    )
-  popd || goto :error
-  .\.local\bin\pathman add ".local\bin" || goto :error
-
-  echo downloading and installing %1
-  powershell $ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest https://webinstall.dev/packages/%1/install.bat -OutFile %1-webinstall.bat || goto :error
-
-  rem TODO only add if it's not in there already
-  PATH .local\bin;%PATH%
-
-  call %1-webinstall.bat || goto :error
-  del %1-webinstall.bat || goto :error
-popd
-
-goto :EOF
-
-:error
-echo Failed with error #%errorlevel%.
-exit /b %errorlevel%