From f9f280f724f8bad9eb00440c9dbb81d62a78ee01 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Fri, 19 Jun 2020 05:36:13 +0000 Subject: [PATCH] use stderr for errors, and expose os,arch,format release info upstream --- README.md | 10 ++- _webi/bootstrap.sh | 8 +-- _webi/normalize.js | 56 ++++++++++------- _webi/releases.js | 154 +++++++++++++++++++++++++-------------------- _webi/template.sh | 31 ++++----- _webi/test.js | 3 + 6 files changed, 153 insertions(+), 109 deletions(-) diff --git a/README.md b/README.md index eea409b..f83b776 100644 --- a/README.md +++ b/README.md @@ -206,9 +206,8 @@ See `webi/template.sh` These variables will be set by the server: -``` +```bash WEBI_PKG=example@v1 -WEBI_NAME=example WEBI_TAG=v1 WEBI_HOST=https://webinstall.dev WEBI_RELEASES=https://webinstall.dev/api/releases/example@v1?os=macos&arch=amd64&pretty=true @@ -224,6 +223,13 @@ WEBI_PKG_URL=https://cdn.example.com/example-macos-amd64.tar.gz WEBI_PKG_FILE=example-macos-amd64.tar.gz ``` +```bash +PKG_NAME=example +PKG_OSES=macos,linux,windows +PKG_ARCHES=amd64,arm64,x86 +PKG_FORMATS=zip,xz +``` + ```bash WEBI_TMP=${WEBI_TMP:-"$(mktemp -d -t webinstall-foobar.XXXXXXXX)"} WEBI_SINGLE="" diff --git a/_webi/bootstrap.sh b/_webi/bootstrap.sh index 7bf24e7..6562087 100644 --- a/_webi/bootstrap.sh +++ b/_webi/bootstrap.sh @@ -53,7 +53,7 @@ fi if [ -n "\$(command -v unzip)" ]; then my_ext="zip,\$my_ext" else - echo "WARN: 'unzip' not found" + >&2 echo "WARN: 'unzip' not found" fi if [ -n "\$(command -v tar)" ]; then my_ext="tar,\$my_ext" @@ -79,8 +79,8 @@ webinstall() { my_package="\${1:-}" if [ -z "\$my_package" ]; then - echo "Usage: webi @ ..." - echo "Example: webi node@lts rg" + >&2 echo "Usage: webi @ ..." + >&2 echo "Example: webi node@lts rg" exit 1 fi @@ -96,7 +96,7 @@ webinstall() { -O "\$WEBI_BOOT/\$my_package-bootstrap.sh" fi if ! [ \$? -eq 0 ]; then - echo "error fetching '\$my_installer_url'" + >&2 echo "error fetching '\$my_installer_url'" exit 1 fi set -e diff --git a/_webi/normalize.js b/_webi/normalize.js index 16c60b8..cd9c624 100644 --- a/_webi/normalize.js +++ b/_webi/normalize.js @@ -10,15 +10,24 @@ var osMap = { aix: /(\b|_)(aix)/i }; +var maps = { + oses: {}, + arches: {}, + formats: {} +}; + +Object.keys(osMap).forEach(function (name) { + maps.oses[name] = true; +}); + var formats = ['zip', 'xz', 'tar', 'pkg', 'msi', 'git', 'exe', 'dmg']; -var formatsMap = {}; -formats.forEach(function (ext) { - formatsMap[ext] = true; +formats.forEach(function (name) { + maps.formats[name] = true; }); // evaluation order matters // (i.e. otherwise x86 and x64 can cross match) -var archArr = [ +var arches = [ 'amd64', // first and most likely match 'arm64', 'x86', @@ -38,12 +47,18 @@ var archMap = { armv6l: /(\b|_)(armv?6l)/i, s390x: /(\b|_)(s390x)/i }; +arches.forEach(function (name) { + maps.arches[name] = true; +}); function normalize(all) { - var supportedFormats = {}; + var supported = { + oses: {}, + arches: {}, + formats: {} + }; all.releases.forEach(function (rel) { - supportedFormats[rel.ext] = true; rel.version = rel.version.replace(/^v/i, ''); if (!rel.name) { rel.name = rel.download.replace(/.*\//, ''); @@ -51,22 +66,13 @@ function normalize(all) { 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'; } + supported.oses[rel.os] = true; if (!rel.arch) { - archArr.some(function (regKey) { - //console.log('release arch:', rel.download, regKey, archMap[regKey]); + arches.some(function (regKey) { var arch = (rel.name || rel.download).match(archMap[regKey]) && regKey; if (arch) { rel.arch = arch; @@ -74,6 +80,7 @@ function normalize(all) { } })[0]; } + supported.arches[rel.arch] = true; if (!rel.ext) { // pkg-v1.0.tar.gz => ['gz', 'tar', '0', 'pkg-v1'] @@ -89,14 +96,21 @@ function normalize(all) { rel.ext = exts[0]; } } + supported.formats[rel.ext] = true; if (all.download) { rel.download = all.download.replace(/{{ download }}/, rel.download); } }); - all.formats = Object.keys(supportedFormats).filter(function (ext) { - return formatsMap[ext]; + all.oses = Object.keys(supported.oses).filter(function (name) { + return maps.oses[name]; + }); + all.arches = Object.keys(supported.arches).filter(function (name) { + return maps.arches[name]; + }); + all.formats = Object.keys(supported.formats).filter(function (name) { + return maps.formats[name]; }); return all; @@ -105,5 +119,5 @@ function normalize(all) { module.exports = normalize; // NOT in order of priority (which would be tar, xz, zip, ...) module.exports.formats = formats; -module.exports.arches = archArr; -module.exports.formatsMap = formatsMap; +module.exports.arches = arches; +module.exports.formatsMap = maps.formats; diff --git a/_webi/releases.js b/_webi/releases.js index d85b9c5..dc30ce1 100644 --- a/_webi/releases.js +++ b/_webi/releases.js @@ -40,74 +40,92 @@ Releases.renderBash = function ( 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 + - '&formats=' + - formats.join(',') + - '&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_FORMATS=.*/m, - "WEBI_FORMATS='" + formats.join(',') + "'" - ) - .replace( - /^#?WEBI_PKG_URL=.*/m, - "WEBI_PKG_URL='" + rel.download + "'" - ) - .replace(/^#?WEBI_PKG_FILE=.*/m, "WEBI_PKG_FILE='" + rel.name + "'") - .replace(/{{ installer }}/, installTxt); + return ( + tplTxt + .replace(/^#?WEBI_PKG=.*/m, "WEBI_PKG='" + pkg + '@' + ver + "'") + .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 + + '&formats=' + + formats.join(',') + + '&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_FORMATS=.*/m, + "WEBI_FORMATS='" + formats.join(',') + "'" + ) + .replace( + /^#?WEBI_PKG_URL=.*/m, + "WEBI_PKG_URL='" + rel.download + "'" + ) + .replace( + /^#?WEBI_PKG_FILE=.*/m, + "WEBI_PKG_FILE='" + rel.name + "'" + ) + // PKG details + .replace(/^#?PKG_NAME=.*/m, "PKG_NAME='" + pkg + "'") + .replace( + /^#?PKG_OSES=.*/m, + "PKG_OSES='" + ((rel && rel.oses) || []).join(',') + "'" + ) + .replace( + /^#?PKG_ARCHES=.*/m, + "PKG_ARCHES='" + ((rel && rel.arches) || []).join(',') + "'" + ) + .replace( + /^#?PKG_FORMATS=.*/m, + "PKG_FORMATS='" + ((rel && rel.formats) || []).join(',') + "'" + ) + .replace(/{{ installer }}/, installTxt) + ); }); }); }; diff --git a/_webi/template.sh b/_webi/template.sh index 6c16654..ed590c1 100644 --- a/_webi/template.sh +++ b/_webi/template.sh @@ -7,8 +7,10 @@ set -u #set -x #WEBI_PKG= -#WEBI_NAME= +#PKG_NAME= # TODO should this be BASEURL instead? +#WEBI_OS= +#WEBI_ARCH= #WEBI_HOST= #WEBI_RELEASES= #WEBI_CSV= @@ -25,6 +27,9 @@ set -u #WEBI_FORMATS= #WEBI_PKG_URL= #WEBI_PKG_FILE= +#PKG_OSES= +#PKG_ARCHES= +#PKG_FORMATS= WEBI_UA="$(uname -a)" export WEBI_HOST @@ -102,7 +107,7 @@ webi_check() { 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" + >&2 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 @@ -121,14 +126,12 @@ webi_download() { 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)" - echo "See $WEBI_RELEASES" - echo " WEBI_PKG=$WEBI_PKG" - echo " WEBI_NAME=$WEBI_NAME" - echo " WEBI_VERSION=$WEBI_VERSION" - echo " WEBI_EXT=$WEBI_EXT" - echo " WEBI_FORMATS=$WEBI_FORMATS" + >&2 echo "Error: no '$PKG_NAME' release for '$WEBI_OS' on '$WEBI_ARCH' as one of '$WEBI_FORMATS' by the tag '$WEBI_TAG'" + >&2 echo " '$PKG_NAME' is available for '$PKG_OSES' on '$PKG_ARCHES' as one of '$PKG_FORMATS'" + >&2 echo " (check that the package name and version are correct)" + >&2 echo "" + >&2 echo " Double check at $(echo "$WEBI_RELEASES" | sed 's:\?.*::')" + >&2 echo "" exit 1 fi my_url="$WEBI_PKG_URL" @@ -144,7 +147,7 @@ webi_download() { return 0 fi - echo "Downloading $WEBI_NAME to $my_dl" + echo "Downloading $PKG_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... @@ -154,7 +157,7 @@ webi_download() { 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" + >&2 echo "failed to download from $WEBI_PKG_URL" exit 1 fi set -e @@ -259,7 +262,7 @@ WEBI_SINGLE= # run everything with defaults or overrides as needed if [ -n "$(command -v pkg_get_current_version)" ]; then - pkg_cmd_name="${pkg_cmd_name:-$WEBI_NAME}" + pkg_cmd_name="${pkg_cmd_name:-$PKG_NAME}" if [ -n "$WEBI_SINGLE" ]; then pkg_dst_cmd="${pkg_dst_cmd:-$HOME/.local/bin/$pkg_cmd_name}" @@ -299,7 +302,7 @@ fi webi_path_add "$HOME/.local/bin" if [ -z "${_WEBI_CHILD:-}" ] && [ -f "\$_webi_tmp/.PATH.env" ]; then - echo "You need to update your PATH to use $WEBI_NAME:" + echo "You need to update your PATH to use $PKG_NAME:" echo "" cat "$_webi_tmp/.PATH.env" | sort -u rm -f "$_webi_tmp/.PATH.env" diff --git a/_webi/test.js b/_webi/test.js index 0240d1a..947fbb1 100755 --- a/_webi/test.js +++ b/_webi/test.js @@ -81,6 +81,9 @@ Releases.get(path.join(process.cwd(), pkgdir)).then(function (all) { new RegExp('^' + pkgtag).test(rel.version)) ); })[0]; + rel.oses = all.oses; + rel.arches = all.arches; + rel.formats = all.formats; if (!rel) { console.error('Error: ❌ no release found for current os, arch, and tag'); -- 2.25.1