Compare commits

..

14 Commits

11 changed files with 107 additions and 148 deletions

View File

@@ -54,54 +54,6 @@ var TERMS_META = [
'stable', 'stable',
]; ];
/** @typedef {String} TripletString - {arch}-{vendor}-{os}-{libc} */
/** @typedef {String} VersionString */
/** @typedef {Object.<VersionString, Array<BuildAsset>>} PackagesByRelease */
/**
* @typedef ProjectInfo
* @prop {Array<BuildAsset>} releases
* @prop {Array<BuildAsset>} packages
* @prop {Object.<TripletString, PackagesByRelease>} releasesByTriplet
* @prop {Array<import('./build-classifier/types.js').ArchString>} arches
* @prop {Array<import('./build-classifier/types.js').OsString>} oses
* @prop {Array<import('./build-classifier/types.js').LibcString>} libcs
* @prop {Array<String>} channels
* @prop {Array<String>} formats
* @prop {Array<String>} triplets
* @prop {Array<String>} versions
* @prop {Array<String>} lexvers
* @prop {Object.<String, String>} lexversMap
*/
/**
* @typedef BuildAsset
* @prop {String} name
* @prop {String} version
* @prop {Boolean} lts
* @prop {String} date
* @prop {String} arch
* @prop {String} os
* @prop {String} libc
* @prop {String} ext
* @prop {String} download
*/
/**
* @typedef VersionTarget
* @prop {String} version
* @prop {Boolean} lts
* @prop {String} channel
*/
/** @typedef {TargetTriplet & HostTargetPartial} HostTarget */
/** @typedef {import('./build-classifier/types.js').TargetTriplet} TargetTriplet */
/**
* @typedef HostTargetPartial
* @prop {String} target.triplet - os-vendor-arch-libc
* @prop {Error} target.error
*/
async function getPartialHeader(path) { async function getPartialHeader(path) {
let readme = `${path}/README.md`; let readme = `${path}/README.md`;
let head = await readFirstBytes(readme).catch(function (err) { let head = await readFirstBytes(readme).catch(function (err) {
@@ -120,7 +72,7 @@ async function readFirstBytes(path) {
let start = 0; let start = 0;
let n = 1024; let n = 1024;
let fh = await Fs.open(path, 'r'); let fh = await Fs.open(path, 'r');
let buf = Buffer.alloc(n); let buf = new Buffer.alloc(n);
let result = await fh.read(buf, start, n); let result = await fh.read(buf, start, n);
let str = result.buffer.toString('utf8'); let str = result.buffer.toString('utf8');
await fh.close(); await fh.close();
@@ -782,35 +734,21 @@ BuildsCacher.create = function ({ ALL_TERMS, installers, caches }) {
}; };
/** /**
* @param {ProjectInfo} projInfo * @param {Object} target
* @param {HostTarget} hostTarget * @param {String} target.os - linux, darwin, windows, *bsd
* @param {String} target.arch - arm64, x86_64, ppc64le
* @param {String} target.libc - none, libc, gnu, musl, bionic, msvc
* @param {String} target.triplet - os-vendor-arch-libc
* @param {Error} target.error
*/ */
bc.enumerateLatestVersions = function (projInfo, hostTarget) { bc.findMatchingPackages = function (pkgInfo, hostTarget, verTarget) {
let lexPrefix = ''; let matchInfo = bc._enumerateVersions(pkgInfo, verTarget.version);
let matchInfo = Lexver.matchSorted(projInfo.lexvers, lexPrefix);
let verInfo = {
default: projInfo.lexversMap[matchInfo.default],
previous: projInfo.lexversMap[matchInfo.previous],
stable: projInfo.lexversMap[matchInfo.stable],
latest: projInfo.lexversMap[matchInfo.latest],
};
return verInfo;
};
/**
* @param {ProjectInfo} projInfo
* @param {HostTarget} hostTarget
* @param {VersionTarget} verTarget
*/
bc.findMatchingPackages = function (projInfo, hostTarget, verTarget) {
let matchInfo = bc._enumerateVersions(projInfo, verTarget.version);
let triplets = bc._enumerateTriplets(hostTarget); let triplets = bc._enumerateTriplets(hostTarget);
//console.log('dbg: matchInfo', matchInfo); //console.log('dbg: matchInfo', matchInfo);
if (matchInfo) { if (matchInfo) {
for (let _triplet of triplets) { for (let _triplet of triplets) {
let targetReleases = projInfo.releasesByTriplet[_triplet]; let targetReleases = pkgInfo.releasesByTriplet[_triplet];
if (!targetReleases) { if (!targetReleases) {
continue; continue;
} }
@@ -818,7 +756,7 @@ BuildsCacher.create = function ({ ALL_TERMS, installers, caches }) {
// Make sure that these releases are the expected version // Make sure that these releases are the expected version
// (ex: jq1.7 => darwin-arm64-libc, jq1.6 => darwin-x86_64-libc) // (ex: jq1.7 => darwin-arm64-libc, jq1.6 => darwin-x86_64-libc)
for (let matchver of matchInfo.matches) { for (let matchver of matchInfo.matches) {
let ver = projInfo.lexversMap[matchver] || matchver; let ver = pkgInfo.lexversMap[matchver] || matchver;
let packages = targetReleases[ver]; let packages = targetReleases[ver];
if (!packages) { if (!packages) {
continue; continue;
@@ -827,7 +765,7 @@ BuildsCacher.create = function ({ ALL_TERMS, installers, caches }) {
let match = { let match = {
triplet: _triplet, triplet: _triplet,
packages: packages, packages: packages,
latest: projInfo.versions[0], latest: pkgInfo.versions[0],
version: ver, version: ver,
versions: matchInfo, versions: matchInfo,
}; };
@@ -839,7 +777,7 @@ BuildsCacher.create = function ({ ALL_TERMS, installers, caches }) {
} }
for (let _triplet of triplets) { for (let _triplet of triplets) {
let targetReleases = projInfo.releasesByTriplet[_triplet]; let targetReleases = pkgInfo.releasesByTriplet[_triplet];
if (!targetReleases) { if (!targetReleases) {
continue; continue;
} }
@@ -858,7 +796,7 @@ BuildsCacher.create = function ({ ALL_TERMS, installers, caches }) {
// Make sure that these releases are the expected version // Make sure that these releases are the expected version
// (ex: jq1.7 => darwin-arm64-libc, jq1.6 => darwin-x86_64-libc) // (ex: jq1.7 => darwin-arm64-libc, jq1.6 => darwin-x86_64-libc)
for (let matchver of lexvers) { for (let matchver of lexvers) {
let ver = projInfo.lexversMap[matchver] || matchver; let ver = pkgInfo.lexversMap[matchver] || matchver;
let packages = targetReleases[ver]; let packages = targetReleases[ver];
//console.log('dbg: packages', packages); //console.log('dbg: packages', packages);
if (!packages) { if (!packages) {
@@ -874,7 +812,7 @@ BuildsCacher.create = function ({ ALL_TERMS, installers, caches }) {
let match = { let match = {
triplet: _triplet, triplet: _triplet,
packages: packages, packages: packages,
latest: projInfo.versions[0], latest: pkgInfo.versions[0],
version: ver, version: ver,
versions: matchInfo, versions: matchInfo,
}; };
@@ -893,7 +831,7 @@ BuildsCacher.create = function ({ ALL_TERMS, installers, caches }) {
let match = { let match = {
triplet: _triplet, triplet: _triplet,
packages: packages, packages: packages,
latest: projInfo.versions[0], latest: pkgInfo.versions[0],
version: ver, version: ver,
versions: matchInfo, versions: matchInfo,
}; };
@@ -940,12 +878,12 @@ BuildsCacher.create = function ({ ALL_TERMS, installers, caches }) {
return triplets; return triplets;
}; };
bc._enumerateVersions = function (projInfo, ver) { bc._enumerateVersions = function (pkgInfo, ver) {
if (!ver) { if (!ver) {
return null; return null;
} }
let lexPrefix = Lexver.parsePrefix(ver); let lexPrefix = Lexver.parsePrefix(ver);
let matchInfo = Lexver.matchSorted(projInfo.lexvers, lexPrefix); let matchInfo = Lexver.matchSorted(pkgInfo.lexvers, lexPrefix);
return matchInfo; return matchInfo;
}; };

View File

@@ -34,8 +34,7 @@ Builds.init = async function () {
} }
}; };
Builds.enumerateLatestVersions = bc.enumerateLatestVersions;
Builds.findMatchingPackages = bc.findMatchingPackages;
Builds.getPackage = bc.getPackages;
Builds.getProjectType = bc.getProjectType; Builds.getProjectType = bc.getProjectType;
Builds.getPackage = bc.getPackages;
Builds.findMatchingPackages = bc.findMatchingPackages;
Builds.selectPackage = bc.selectPackage; Builds.selectPackage = bc.selectPackage;

View File

@@ -14,16 +14,11 @@ function padScript(txt) {
var BAD_SH_RE = /[<>'"`$\\]/; var BAD_SH_RE = /[<>'"`$\\]/;
Installers.renderBash = async function ( Installers.renderBash = async function (
pkgdir, baseurl,
rel, posixTemplate,
{ baseurl, pkg, tag, ver, os = '', arch = '', libc = '', formats, latest }, buildRequest,
buildMatch,
) { ) {
if (!Array.isArray(formats)) {
formats = [];
}
if (!tag) {
tag = '';
}
let installTxt = await Fs.readFile(path.join(pkgdir, 'install.sh'), 'utf8'); let installTxt = await Fs.readFile(path.join(pkgdir, 'install.sh'), 'utf8');
installTxt = padScript(installTxt); installTxt = padScript(installTxt);
var vers = rel.version.split('.'); var vers = rel.version.split('.');
@@ -131,17 +126,18 @@ Installers.renderBash = async function (
return tplTxt; return tplTxt;
}; };
/**
* @param {String} pkgdir
* @param {String} baseurl
* @param {BuildRequest} buildRequest
* @param {BuildMatch} buildMatch
*/
Installers.renderPowerShell = async function ( Installers.renderPowerShell = async function (
pkgdir, baseurl,
rel, pwshTemplate,
{ baseurl, pkg, tag, ver, os, arch, libc = '', formats }, buildRequest,
buildMatch,
) { ) {
if (!Array.isArray(formats)) {
formats = [];
}
if (!tag) {
tag = '';
}
let installTxt = await Fs.readFile(path.join(pkgdir, 'install.ps1'), 'utf8'); let installTxt = await Fs.readFile(path.join(pkgdir, 'install.ps1'), 'utf8');
installTxt = padScript(installTxt); installTxt = padScript(installTxt);
/* /*

View File

@@ -125,7 +125,6 @@ let bc = BuildsCacher.create({
}); });
async function main() { async function main() {
/* jshint maxcomplexity: 25 */
// TODO // TODO
// node ./_webi/lint-builds.js caddy@beta 'x86_64/unknown Darwin libc' // node ./_webi/lint-builds.js caddy@beta 'x86_64/unknown Darwin libc'
// //
@@ -185,7 +184,6 @@ async function main() {
// non-build file // non-build file
continue; continue;
} }
if (target.error) { if (target.error) {
let e = target.error; let e = target.error;
if (e.code === 'E_BUILD_NO_PATTERN') { if (e.code === 'E_BUILD_NO_PATTERN') {
@@ -197,12 +195,6 @@ async function main() {
throw e; throw e;
} }
if (target.unknownTerms?.length) {
let msg = `${projInfo.name}: unrecognized term(s) '${target.unknownTerms}' in '${build.download}'`;
let err = new Error(msg);
throw err;
}
triples.push(target.triplet); triples.push(target.triplet);
// if (!build.version) { // if (!build.version) {
// throw new Error(`no version for ${pkg.name} ${build.name}`); // throw new Error(`no version for ${pkg.name} ${build.name}`);

View File

@@ -10,27 +10,53 @@ let Builds = require('./builds.js');
let Installers = require('./installers.js'); let Installers = require('./installers.js');
InstallerServer.INSTALLERS_DIR = Path.join(__dirname, '..'); InstallerServer.INSTALLERS_DIR = Path.join(__dirname, '..');
/**
* @typedef BuildRequest
* @prop {String} unameAgent
* @prop {String} projectName
* @prop {String} tag
* @prop {Array<String>} formats
*/
InstallerServer.serveInstaller = async function ( InstallerServer.serveInstaller = async function (
baseurl, baseurl,
ua, ua, // TODO nix
pkg, unameAgent,
pkg, // TODO nix
projectName,
tag, tag,
ext, ext, // TODO nix
installerType,
formats, formats,
libc,
) { ) {
let unameAgent = ua; if (!unameAgent) {
let projectName = pkg; unameAgent = ua;
let [rel, tmplParams] = await InstallerServer.helper({ }
unameAgent, if (!projectName) {
projectName = pkg;
}
if (!installerType) {
installerType = ext;
}
let buildRequest = {
projectName, projectName,
tag, tag,
unameAgent,
formats, formats,
libc, };
});
Object.assign(tmplParams, { let hostTarget = {};
baseurl, let buildMatch;
}); {
let terms = unameAgent.split(/[\s\/]+/g);
void HostTargets.termsToTarget(hostTarget, terms);
buildMatch = await InstallerServer.getBuild(buildRequest, hostTarget);
}
Object.assign(tmplParams, { baseurl, });
console.log('dbg: buildPkg', rel);
console.log('dbg: tmplParams', tmplParams);
var pkgdir = Path.join(InstallerServer.INSTALLERS_DIR, projectName); var pkgdir = Path.join(InstallerServer.INSTALLERS_DIR, projectName);
if ('ps1' === ext) { if ('ps1' === ext) {
@@ -41,12 +67,15 @@ InstallerServer.serveInstaller = async function (
// TODO put some of this in a middleware? or common function? // TODO put some of this in a middleware? or common function?
// TODO maybe move package/version/lts/channel detection into getReleases // TODO maybe move package/version/lts/channel detection into getReleases
/**
* @param {BuildRequest}
* @returns {BuildMatch}
*/
InstallerServer.helper = async function ({ InstallerServer.helper = async function ({
unameAgent, unameAgent,
projectName, projectName,
tag, tag,
formats, formats,
libc,
}) { }) {
console.log(`dbg: Installer User-Agent: ${unameAgent}`); console.log(`dbg: Installer User-Agent: ${unameAgent}`);
@@ -133,9 +162,6 @@ InstallerServer.helper = async function ({
}; };
let hasOs = projInfo.oses.includes(hostTarget.os); let hasOs = projInfo.oses.includes(hostTarget.os);
if (!hasOs) {
hasOs = projInfo.oses.includes('ANYOS');
}
if (!hasOs) { if (!hasOs) {
let pkg1 = Object.assign(buildTargetInfo, errPackage); let pkg1 = Object.assign(buildTargetInfo, errPackage);
return [pkg1, tmplParams]; return [pkg1, tmplParams];
@@ -165,10 +191,11 @@ InstallerServer.helper = async function ({
if (version.startsWith('v')) { if (version.startsWith('v')) {
version = version.slice(1); version = version.slice(1);
} }
let ver = version;
buildPkg = Object.assign(buildTargetInfo, buildPkg, { ext, version }); buildPkg = Object.assign(buildTargetInfo, buildPkg, { ext, version, tag });
console.log('dbg: buildPkg', buildPkg); Object.assign(tmplParams, { tag, ext, ver, version });
console.log('dbg: tmplParams', tmplParams); //console.log(`VERSION: ${version}`, ext);
return [buildPkg, tmplParams]; return [buildPkg, tmplParams];
}; };

View File

@@ -32,7 +32,7 @@ if (/\b-?-h(elp)?\b/.test(process.argv.join(' '))) {
var os = require('os'); var os = require('os');
var fs = require('fs'); var fs = require('fs');
var path = require('path'); var path = require('path');
var Builds = require('./builds.js'); var Releases = require('./transform-releases.js');
var Installers = require('./installers.js'); var Installers = require('./installers.js');
var ServeInstaller = require('./serve-installer.js'); var ServeInstaller = require('./serve-installer.js');
@@ -65,8 +65,7 @@ console.info('Has the necessary files?');
}); });
console.info(''); console.info('');
let projName = pkgdir.split('/').filter(Boolean).pop(); Releases.get(path.join(process.cwd(), pkgdir)).then(async function (all) {
Builds.getPackage({ name: projName }).then(async function (/*projInfo*/) {
var pkgname = path.basename(pkgdir.replace(/\/$/, '')); var pkgname = path.basename(pkgdir.replace(/\/$/, ''));
var nodeOs = os.platform(); var nodeOs = os.platform();
var nodeOsRelease = os.release(); var nodeOsRelease = os.release();
@@ -82,20 +81,29 @@ Builds.getPackage({ name: projName }).then(async function (/*projInfo*/) {
} }
var formats = ['exe', 'xz', 'tar', 'zip', 'git']; var formats = ['exe', 'xz', 'tar', 'zip', 'git'];
let unameAgent = `${nodeOs}/${nodeOsRelease} ${nodeArch}/unknown ${nodeLibc}`;
console.log(`DEBUG: ${unameAgent}`);
let [rel, opts] = await ServeInstaller.helper({ let [rel, opts] = await ServeInstaller.helper({
unameAgent: `${nodeOs}/${nodeOsRelease} ${nodeArch}/unknown ${nodeLibc}`, unameAgent: unameAgent,
projectName: pkgname, projectName: pkgname,
tag: pkgtag || '', tag: pkgtag || '',
formats: formats, formats: formats,
libc: nodeLibc, libc: nodeLibc,
}); });
console.log('DEBUG opts:');
console.log(opts);
Object.assign( Object.assign(
rel,
{ {
ver: '', version: '{test-version}',
git_tag: '{test-git-tag}',
git_commit_hash: '{test-git-commit-hash}',
lts: null, lts: null,
channel: '', channel: '{test-channel}',
os: '', date: '1970-01-01T00:00:00Z',
arch: '', os: '{test-os}',
arch: '{test-arch}',
ext: '{test-ext}',
limit: 0, limit: 0,
}, },
opts, opts,

View File

@@ -66,10 +66,10 @@ module.exports = async function (request) {
json: true, json: true,
}); });
let osBaseUrl = resp.body.base_url; let body = resp.body;
let osReleases = resp.body.releases; all.download = `${body.base_url}/{{ download }}`;
for (let asset of osReleases) { for (let asset of body.releases) {
if (!channelMap[asset.channel]) { if (!channelMap[asset.channel]) {
channelMap[asset.channel] = true; channelMap[asset.channel] = true;
} }
@@ -81,8 +81,7 @@ module.exports = async function (request) {
channel: asset.channel, channel: asset.channel,
date: asset.release_date.replace(/T.*/, ''), date: asset.release_date.replace(/T.*/, ''),
//sha256: asset.sha256, //sha256: asset.sha256,
download: `${osBaseUrl}/${asset.archive}`, download: asset.archive,
_filename: asset.archive,
}); });
} }
} }

View File

@@ -44,7 +44,7 @@ function getAllReleases(request) {
var goReleases = resp.body; var goReleases = resp.body;
var all = { var all = {
releases: [], releases: [],
download: '', download: 'https://dl.google.com/go/{{ download }}',
}; };
goReleases.forEach((release) => { goReleases.forEach((release) => {
@@ -77,7 +77,7 @@ function getAllReleases(request) {
arch: arch, arch: arch,
ext: '', // let normalize run the split/test/join ext: '', // let normalize run the split/test/join
hash: '-', // not ready to standardize this yet hash: '-', // not ready to standardize this yet
download: `https://dl.google.com/go/${filename}`, download: filename,
}); });
}); });
}); });

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "@webinstall/webi-installers", "name": "@webinstall/webi-installers",
"version": "1.1.0", "version": "1.0.1",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@webinstall/webi-installers", "name": "@webinstall/webi-installers",
"version": "1.1.0", "version": "1.0.1",
"license": "MPL-2.0", "license": "MPL-2.0",
"dependencies": { "dependencies": {
"@root/request": "^1.9.2", "@root/request": "^1.9.2",

View File

@@ -1,7 +1,7 @@
{ {
"name": "@webinstall/webi-installers", "name": "@webinstall/webi-installers",
"private": true, "private": true,
"version": "1.1.0", "version": "1.0.1",
"description": "webinstall script repository", "description": "webinstall script repository",
"main": "_webi/", "main": "_webi/",
"scripts": { "scripts": {