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
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=""
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"
my_package="\${1:-}"
if [ -z "\$my_package" ]; then
- echo "Usage: webi <package>@<version> ..."
- echo "Example: webi node@lts rg"
+ >&2 echo "Usage: webi <package>@<version> ..."
+ >&2 echo "Example: webi node@lts rg"
exit 1
fi
-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
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',
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(/.*\//, '');
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;
}
})[0];
}
+ supported.arches[rel.arch] = true;
if (!rel.ext) {
// pkg-v1.0.tar.gz => ['gz', 'tar', '0', 'pkg-v1']
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;
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;
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)
+ );
});
});
};
#set -x
#WEBI_PKG=
-#WEBI_NAME=
+#PKG_NAME=
# TODO should this be BASEURL instead?
+#WEBI_OS=
+#WEBI_ARCH=
#WEBI_HOST=
#WEBI_RELEASES=
#WEBI_CSV=
#WEBI_FORMATS=
#WEBI_PKG_URL=
#WEBI_PKG_FILE=
+#PKG_OSES=
+#PKG_ARCHES=
+#PKG_FORMATS=
WEBI_UA="$(uname -a)"
export WEBI_HOST
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
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"
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...
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
# 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}"
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"
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');