From: AJ ONeal Date: Tue, 16 Jun 2020 10:45:54 +0000 (+0000) Subject: generalize, a lot X-Git-Url: https://git.josue.xyz/?a=commitdiff_plain;h=5e0debf4c54c1e55476c1bc533c26db2b54d2f77;p=webi-installers%2F.git generalize, a lot --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e3a0b44 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +install-*.sh diff --git a/README.md b/README.md index c082b0f..28da84b 100644 --- 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/.tar.gz webi_extract # Extracts the download to /tmp/-/ 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 index dac0902..0000000 --- a/_common/normalize.js +++ /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 index 619534d..0000000 --- a/_example/install.bash +++ /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 index 0000000..2794685 --- /dev/null +++ b/_example/install.sh @@ -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 index c52b018..0000000 --- a/_example/install_safe_copy.bash +++ /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 index 0000000..c52b018 --- /dev/null +++ b/_example/install_safe_copy.sh @@ -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 +} diff --git a/_example/releases.js b/_example/releases.js index 60ef61e..9812559 100644 --- a/_example/releases.js +++ b/_example/releases.js @@ -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 index 0000000..495a624 --- /dev/null +++ b/_webi/bootstrap.bat @@ -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 index 0000000..4a65519 --- /dev/null +++ b/_webi/bootstrap.sh @@ -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 @" + 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 index 0000000..dac0902 --- /dev/null +++ b/_webi/normalize.js @@ -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 index 0000000..603dc14 --- /dev/null +++ b/_webi/packages.js @@ -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 index 0000000..f7f5eff --- /dev/null +++ b/_webi/releases.js @@ -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 index 0000000..191cf10 --- /dev/null +++ b/_webi/template.sh @@ -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 index 0000000..552a5fa --- /dev/null +++ b/_webi/test.js @@ -0,0 +1,107 @@ +'use strict'; + +// +// Print help if there's no pkgdir argument +// +var usage = [ + 'Usage: node _webi/test.js ', + '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 index 0000000..fb0a316 --- /dev/null +++ b/_webi/ua-detect.js @@ -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 index 0000000..065ba29 --- /dev/null +++ b/_webi/webi.bat @@ -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 index e95a572..0000000 --- a/brew/install.bash +++ /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 index 0000000..e95a572 --- /dev/null +++ b/brew/install.sh @@ -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 index 5f6a98f..0000000 --- a/caddy/install.bash +++ /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 index 0000000..0148194 --- /dev/null +++ b/caddy/install.sh @@ -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 index 0000000..6ac8fcd --- /dev/null +++ b/caddy/package.yash @@ -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 diff --git a/caddy/releases.js b/caddy/releases.js index bc026d1..30776c3 100644 --- a/caddy/releases.js +++ b/caddy/releases.js @@ -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 index 0ad1f29..0000000 --- a/flutter/install.bash +++ /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 index 0000000..4feb311 --- /dev/null +++ b/flutter/install.sh @@ -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 index 0000000..e9413ff --- /dev/null +++ b/flutter/package.yash @@ -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 index 43af834..0000000 --- a/gitea/install.bash +++ /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 index 0000000..31d575c --- /dev/null +++ b/gitea/install.sh @@ -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 index 0000000..1eacd29 --- /dev/null +++ b/gitea/package.yash @@ -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 diff --git a/gitea/releases.js b/gitea/releases.js index 41e1ee5..e24c756 100644 --- a/gitea/releases.js +++ b/gitea/releases.js @@ -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 index a88c0e7..0000000 --- a/go/install.bash +++ /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 index 0000000..a88c0e7 --- /dev/null +++ b/go/install.sh @@ -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 index fa97d20..0000000 --- a/golang/install.bash +++ /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 index 0000000..30edb69 --- /dev/null +++ b/golang/install.sh @@ -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 index 0000000..447e3d8 --- /dev/null +++ b/golang/package.yash @@ -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 diff --git a/golang/releases.js b/golang/releases.js index 133d8fd..a9ad7de 100644 --- a/golang/releases.js +++ b/golang/releases.js @@ -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 index 1fe55ef..0000000 --- a/hugo/install.bash +++ /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 index 0000000..7326ccf --- /dev/null +++ b/hugo/install.sh @@ -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 index 0000000..4cf4941 --- /dev/null +++ b/hugo/package.yash @@ -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 diff --git a/hugo/releases.js b/hugo/releases.js index e143123..610129b 100644 --- a/hugo/releases.js +++ b/hugo/releases.js @@ -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 index dd5566b..0000000 --- a/macos/install.bash +++ /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 index 0000000..dd5566b --- /dev/null +++ b/macos/install.sh @@ -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 index e65662b..0000000 --- a/node/install.bash +++ /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; -# ``` -# -# `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 index 0000000..f2c259c --- /dev/null +++ b/node/install.sh @@ -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 index 0000000..a10af04 --- /dev/null +++ b/node/package.yash @@ -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; +# ``` +# +# `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 diff --git a/node/releases.js b/node/releases.js index 9f0077b..44f4cad 100644 --- a/node/releases.js +++ b/node/releases.js @@ -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 index 4b9e538..0000000 --- a/pathman/install.bash +++ /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 -# ``` -#
-# -# ```bash -# pathman remove ~/.local/bin -# ``` -#
-# -# ```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 index 0000000..309befc --- /dev/null +++ b/pathman/install.sh @@ -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 +# ``` +#
+# +# ```bash +# pathman remove ~/.local/bin +# ``` +#
+# +# ```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 index afc1c19..0000000 --- a/rg/install.bash +++ /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 # 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 index 0000000..eb3cc3b --- /dev/null +++ b/rg/install.sh @@ -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 index 0000000..7c11c6f --- /dev/null +++ b/rg/package.yash @@ -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 # 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 index 1805ebb..0000000 --- a/ripgrep/install.bash +++ /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 index 0000000..1805ebb --- /dev/null +++ b/ripgrep/install.sh @@ -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 index ae4a4ac..0000000 --- a/rust/install.bash +++ /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 index 0000000..ae4a4ac --- /dev/null +++ b/rust/install.sh @@ -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 index e95f172..0000000 --- a/rustlang/install.bash +++ /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 -# ``` -#
-# -# ```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 index 0000000..e95f172 --- /dev/null +++ b/rustlang/install.sh @@ -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 +# ``` +#
+# +# ```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 index df80877..0000000 --- a/serviceman/install.bash +++ /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 index 0000000..df80877 --- /dev/null +++ b/serviceman/install.sh @@ -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 index e19a75b..0000000 --- a/vim-sensible/install.bash +++ /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 index 0000000..e19a75b --- /dev/null +++ b/vim-sensible/install.sh @@ -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 index 13d34d9..0000000 --- a/webi/bootstrap.bash +++ /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 @" - 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 index 25c49a1..0000000 --- a/webi/install.bash +++ /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 curl https://webinstall.dev/PACKAGE_NAME | bash -# examples: | -# ```bash -# webi node@latest -# ``` -#
-# -# ```bash -# webi golang@v1.14 -# ``` -#
-# -# ```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 index 0000000..c5730b2 --- /dev/null +++ b/webi/install.sh @@ -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 curl https://webinstall.dev/PACKAGE_NAME | bash +# examples: | +# ```bash +# webi node@latest +# ``` +#
+# +# ```bash +# webi golang@v1.14 +# ``` +#
+# +# ```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 index f5147ea..0000000 --- a/webi/template.bash +++ /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 index 065ba29..0000000 --- a/webi/webinstall.bat +++ /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%