diff --git a/Makefile b/Makefile index e03ceab..87ea309 100644 --- a/Makefile +++ b/Makefile @@ -43,7 +43,7 @@ script: .PHONY: scripts scripts: - node tools/make-foreach.js script + node tools/make-foreach.js --pkgs script .PHONY: pkg pkg: @@ -91,6 +91,11 @@ install: if [[ -z "$$(ls -A /var/lib/apt/lists)" ]]; then sudo apt update; fi sudo apt reinstall -y ./$(BUILD)/$(DEB) +.PHONY: installs +installs: + @: $${L} + node tools/make-foreach.js --types install L=$(L) + ### Build and run application code .PHONY: frontend diff --git a/tools/make-foreach.js b/tools/make-foreach.js index 88ca7c7..3b7ff98 100644 --- a/tools/make-foreach.js +++ b/tools/make-foreach.js @@ -6,13 +6,26 @@ import { runCommand } from "./util.js"; // Parse command-line arguments, run main functionality, and exit. async function main() { - const targets = process.argv.slice(2); - if (targets.length === 0) { - console.error("usage: make-foreach.js TARGET..."); + const args = process.argv.slice(2); + if (args.length < 2) { + console.error("usage: make-foreach.js (--pkgs | --types) TARGET..."); process.exit(1); } - for (const { lang, type } of await getPackages()) { - await runCommand(`make ${targets} L=${lang} T=${type}`); + const [selector, ...targets] = args; + switch (selector) { + case "--pkgs": + for (const { lang, type } of await getPackages()) { + await runCommand(`make ${targets.join(" ")} L=${lang} T=${type}`); + } + break; + case "--types": + for (const type of ["lang", "config"]) { + await runCommand(`make ${targets.join(" ")} T=${type}`); + } + break; + default: + console.error(`make-foreach.js: unknown selector: ${selector}`); + process.exit(1); } process.exit(0); } diff --git a/tools/plan-publish.js b/tools/plan-publish.js index 53103f7..a3b02de 100644 --- a/tools/plan-publish.js +++ b/tools/plan-publish.js @@ -50,6 +50,9 @@ async function planDockerImage(name, dependentHashes, opts) { await runCommand(`make image I=${name}`); }, upload: async () => { + if (name === "composite") { + await runCommand(`make shell I=composite CMD="make test"`); + } await runCommand(`make push I=${name}`); }, }; @@ -70,51 +73,63 @@ async function planDebianPackages(opts) { return [remoteName, remoteHash]; }) ); + const packages = await getPackages(); + const langUUIDs = Object.fromEntries( + packages + .filter(({ type }) => type === "lang") + .map(({ lang }) => ["lang", getUUID()]) + ); return await Promise.all( - (await getPackages()).map( - async ({ lang, type, name, buildScriptPath, debPath }) => { - const desired = crypto - .createHash("sha1") - .update(await fs.readFile(buildScriptPath, "utf-8")) - .digest("hex"); - let debExists = true; - try { - await fs.access(debPath); - } catch (err) { - debExists = false; - } - let local = null; - if (debExists) { - local = - ( - await runCommand(`dpkg-deb -f ${debPath} Riju-Script-Hash`, { - getStdout: true, - }) - ).stdout.trim() || null; - } - const remote = remoteHashes[name] || null; - return { - id: getUUID(), - deps: deps || [], - artifact: "Debian package", - name, - desired, - local, - remote, - download: async () => { - await runCommand(`make download L=${lang} T=${type}`); - }, - build: async () => { - await runCommand( - `make shell I=packaging CMD="make pkg L=${lang} T=${type}"` - ); - }, - upload: async () => { - await runCommand(`make upload L=${lang} T=${type}`); - }, - }; + packages.map(async ({ lang, type, name, buildScriptPath, debPath }) => { + const desired = crypto + .createHash("sha1") + .update(await fs.readFile(buildScriptPath, "utf-8")) + .digest("hex"); + let debExists = true; + try { + await fs.access(debPath); + } catch (err) { + debExists = false; } - ) + let local = null; + if (debExists) { + local = + ( + await runCommand(`dpkg-deb -f ${debPath} Riju-Script-Hash`, { + getStdout: true, + }) + ).stdout.trim() || null; + } + const remote = remoteHashes[name] || null; + return { + id: getUUID(), + deps: [ + ...(deps || []), + type === "config" ? langUUIDs[lang] : getUUID(), + ], + artifact: "Debian package", + name, + desired, + local, + remote, + download: async () => { + await runCommand(`make download L=${lang} T=${type}`); + }, + build: async () => { + await runCommand( + `make shell I=packaging CMD="make pkg L=${lang} T=${type}"` + ); + }, + upload: async () => { + if (type === "config") { + await runCommand( + `make shell I=runtime CMD="make installs test L=${lang}"` + ); + } + await runCommand(`make upload L=${lang} T=${type}`); + }, + }; + }) ); } @@ -124,7 +139,9 @@ async function computePlan() { }; const packaging = await planDockerImage("packaging", dependentHashes); const runtime = await planDockerImage("runtime", dependentHashes); - const packages = await planDebianPackages({ deps: [packaging.id] }); + const packages = await planDebianPackages({ + deps: [packaging.id, runtime.id], + }); const composite = await planDockerImage("composite", dependentHashes, { deps: [runtime.id, ...packages.map(({ id }) => id)], hashOpts: {