CI / verify (pull_request) Successful in 58s
CI / infrastructure-smoke (pull_request) Successful in 35s
CI / migration-smoke (pull_request) Successful in 1m53s
CI / image-build (pull_request) Successful in 30s
CI / deploy-smoke (same-origin) (pull_request) Successful in 50s
CI / deploy-smoke (split) (pull_request) Successful in 1m32s
Every Module Package v1 now declares the module's license and carries its text. packageFormat stays 1; pre-ADR-0051 metadata fails closed. - Contracts: ekklesia.package.json requires an SPDX `license` expression, validated with spdx-expression-parse, with UNLICENSED and non-expressions refused. The `files` list must hold exactly one non-empty root LICENSE. The package contracts move to the @ekklesia/contracts/module-package subpath, so the SPDX parser and its data (spdx-exceptions and spdx-license-ids ship no licence files) never reach a module bundle through the SDK's re-export of the contracts root. - Packager: reads the source package.json's string SPDX declaration and never invents one. It requires an explicit --license-file (a non-empty regular file, no symlink, no parent search, no download) and copies its bytes unchanged to LICENSE, listed with size and SHA-256 and covered by the archive digest. THIRD_PARTY_NOTICES stays third-party only, and bundled Ekklesia code stays in `incorporates`. - Verifier: rejects missing or invalid license metadata, and a missing, unlisted, duplicated, or corrupted LICENSE, through the schema and the existing strict inventory. - Template: packaged as AGPL-3.0-or-later with the repository's canonical LICENSE, passed explicitly (Dockerfile, smoke, docs). Packing it twice gives byte-identical archives. Started by Codex; reviewed and completed in Claude Code (empty license-text refusal, schema non-empty LICENSE, symlink and empty-file tests). ADR 0051 is Accepted. Co-Authored-By: Claude Opus 5.5 <[email protected]>
84 lines
2.1 KiB
TypeScript
84 lines
2.1 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { parsePackModuleArguments } from "../src/cli.js";
|
|
|
|
const revision = "86ae907f59458508e3277666cdd214f5bd7c1078";
|
|
|
|
describe("ekklesia-pack-module arguments", () => {
|
|
it("takes the module, the target, the output directory, and the source revision", () => {
|
|
expect(
|
|
parsePackModuleArguments([
|
|
"--module",
|
|
"templates/module",
|
|
"--target",
|
|
"any",
|
|
"--out",
|
|
"dist/packages",
|
|
"--license-file",
|
|
"LICENSE",
|
|
"--source-revision",
|
|
revision,
|
|
]),
|
|
).toEqual({
|
|
moduleDirectory: "templates/module",
|
|
licenseFile: "LICENSE",
|
|
outDirectory: "dist/packages",
|
|
sourceRevision: revision,
|
|
target: "any",
|
|
});
|
|
});
|
|
|
|
it("records a repository only when one is given", () => {
|
|
expect(
|
|
parsePackModuleArguments([
|
|
"--module",
|
|
".",
|
|
"--target",
|
|
"any",
|
|
"--out",
|
|
"out",
|
|
"--license-file",
|
|
"LICENSE",
|
|
"--source-revision",
|
|
revision,
|
|
"--repository",
|
|
"https://example.org/acme/example.git",
|
|
]).repository,
|
|
).toBe("https://example.org/acme/example.git");
|
|
});
|
|
|
|
it.each([
|
|
["no arguments", []],
|
|
["a missing target", ["--module", ".", "--out", "o", "--source-revision", revision]],
|
|
[
|
|
"a missing license file",
|
|
["--module", ".", "--target", "any", "--out", "o", "--source-revision", revision],
|
|
],
|
|
["a missing revision", ["--module", ".", "--target", "any", "--out", "o"]],
|
|
[
|
|
"an unknown option",
|
|
["--module", ".", "--target", "any", "--out", "o", "--source-revision", revision, "--legacy"],
|
|
],
|
|
[
|
|
"a repeated option",
|
|
[
|
|
"--module",
|
|
".",
|
|
"--module",
|
|
"..",
|
|
"--target",
|
|
"any",
|
|
"--out",
|
|
"o",
|
|
"--source-revision",
|
|
revision,
|
|
],
|
|
],
|
|
[
|
|
"a stray positional argument",
|
|
["module", "--target", "any", "--out", "o", "--source-revision", revision],
|
|
],
|
|
])("refuses %s", (_label, argv) => {
|
|
expect(() => parsePackModuleArguments(argv)).toThrow();
|
|
});
|
|
});
|