Single-source the version from package.json (closes #5)
check / check (push) Successful in 33s
check / check (push) Successful in 33s
src/index.ts imports package.json for VERSION and bin/quak.ts passes VERSION to commander, so package.json is the only place the version is written. tsc copies package.json to dist/package.json, so the import resolves from the built output; script/build runs the built CLI with --version to prove it. A test checks VERSION and quak --version against package.json. Model: opus-5-5
This commit is contained in:
@@ -18,6 +18,12 @@ Tag v1.0.0.
|
|||||||
|
|
||||||
# Completed Steps
|
# Completed Steps
|
||||||
|
|
||||||
|
- 2026-09-23: Single-sourced the version string (issue 5). `package.json` is the
|
||||||
|
only place it is written: `src/index.ts` imports it for `VERSION` and
|
||||||
|
`bin/quak.ts` passes `VERSION` to commander. tsc copies `package.json` to
|
||||||
|
`dist/package.json`, so the import resolves from the built output too, and
|
||||||
|
`script/build` runs the built CLI with `--version` to prove it. A test checks
|
||||||
|
that `VERSION` and `quak --version` both equal the `package.json` version.
|
||||||
- 2026-09-23: Tested that `Library.close()` waits for the originals precache
|
- 2026-09-23: Tested that `Library.close()` waits for the originals precache
|
||||||
(issue 93). The test that holds a precache fetch open while `close()` runs now
|
(issue 93). The test that holds a precache fetch open while `close()` runs now
|
||||||
runs once with only the thumbnail fill and once with only the originals fill,
|
runs once with only the thumbnail fill and once with only the originals fill,
|
||||||
|
|||||||
+2
-1
@@ -19,6 +19,7 @@ import {
|
|||||||
fixMissingThumbnailsCommand,
|
fixMissingThumbnailsCommand,
|
||||||
} from "../src/cli-commands.js";
|
} from "../src/cli-commands.js";
|
||||||
import { loadSession } from "../src/cli-session.js";
|
import { loadSession } from "../src/cli-session.js";
|
||||||
|
import { VERSION } from "../src/index.js";
|
||||||
|
|
||||||
const paths = envPaths("quak", { suffix: "" });
|
const paths = envPaths("quak", { suffix: "" });
|
||||||
|
|
||||||
@@ -27,7 +28,7 @@ const program = new Command();
|
|||||||
program
|
program
|
||||||
.name("quak")
|
.name("quak")
|
||||||
.description("CLI for the Ente end-to-end encrypted photo service")
|
.description("CLI for the Ente end-to-end encrypted photo service")
|
||||||
.version("0.0.0")
|
.version(VERSION)
|
||||||
.option(
|
.option(
|
||||||
"--cache-dir <path>",
|
"--cache-dir <path>",
|
||||||
"Directory for the local metadata/content cache " +
|
"Directory for the local metadata/content cache " +
|
||||||
|
|||||||
@@ -45,10 +45,24 @@ for (const bin of bins) {
|
|||||||
'
|
'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# src/index.ts imports ../package.json for the version, which tsc copies to
|
||||||
|
# dist/package.json. Running the built CLI proves that import resolves from
|
||||||
|
# dist/ and reports the version package.json declares.
|
||||||
|
verify_version() {
|
||||||
|
built="$(node dist/bin/quak.js --version)"
|
||||||
|
declared="$(node -p 'require("./package.json").version')"
|
||||||
|
if [ "$built" != "$declared" ]; then
|
||||||
|
echo "build: dist/bin/quak.js reports $built, package.json declares $declared" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "build: dist/bin/quak.js reports version $built"
|
||||||
|
}
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
cd "$ROOT"
|
cd "$ROOT"
|
||||||
yarn run tsc
|
yarn run tsc
|
||||||
verify_entrypoints
|
verify_entrypoints
|
||||||
|
verify_version
|
||||||
}
|
}
|
||||||
|
|
||||||
main "$@"
|
main "$@"
|
||||||
|
|||||||
+5
-1
@@ -1,4 +1,8 @@
|
|||||||
export const VERSION = "0.0.0";
|
// package.json is the one place the version is written. tsc copies it to
|
||||||
|
// dist/package.json, so this path resolves from source and from dist/src/.
|
||||||
|
import pkg from "../package.json" with { type: "json" };
|
||||||
|
|
||||||
|
export const VERSION: string = pkg.version;
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Client,
|
Client,
|
||||||
|
|||||||
+39
-5
@@ -1,9 +1,43 @@
|
|||||||
import { describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||||
|
import { readFileSync } from "node:fs";
|
||||||
import { VERSION } from "../src/index.js";
|
import { VERSION } from "../src/index.js";
|
||||||
|
|
||||||
describe("quak", () => {
|
const packageVersion = (
|
||||||
it("exports a version string", () => {
|
JSON.parse(
|
||||||
expect(typeof VERSION).toBe("string");
|
readFileSync(new URL("../package.json", import.meta.url), "utf-8"),
|
||||||
expect(VERSION.length).toBeGreaterThan(0);
|
) as { version: string }
|
||||||
|
).version;
|
||||||
|
|
||||||
|
class ExitCalled extends Error {}
|
||||||
|
|
||||||
|
describe("version", () => {
|
||||||
|
const argv = process.argv;
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
process.argv = argv;
|
||||||
|
vi.restoreAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("exports the version from package.json", () => {
|
||||||
|
expect(VERSION).toBe(packageVersion);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Runs bin/quak.ts with --version. commander prints the version and then
|
||||||
|
// calls process.exit, which is stubbed to throw so the test survives.
|
||||||
|
it("reports the version from package.json in quak --version", async () => {
|
||||||
|
const printed: string[] = [];
|
||||||
|
vi.spyOn(process.stdout, "write").mockImplementation((chunk) => {
|
||||||
|
printed.push(String(chunk));
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
vi.spyOn(process, "exit").mockImplementation(() => {
|
||||||
|
throw new ExitCalled();
|
||||||
|
});
|
||||||
|
process.argv = ["node", "quak", "--version"];
|
||||||
|
|
||||||
|
await expect(import("../bin/quak.js")).rejects.toBeInstanceOf(
|
||||||
|
ExitCalled,
|
||||||
|
);
|
||||||
|
expect(printed.join("").trim()).toBe(packageVersion);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user