@opndev/rzilla 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,69 @@
1
+ // SPDX-FileCopyrightText: 2026 Wesley Schwengle <wesleys@opperschaap.net>
2
+ //
3
+ // SPDX-License-Identifier: MIT
4
+
5
+ import fs from "node:fs/promises";
6
+ import path from "node:path";
7
+ import fg from "fast-glob";
8
+
9
+ /**
10
+ * Copy a list of files into buildDir, preserving relative paths.
11
+ */
12
+ async function copyFilesIntoBuildDir(buildDir, files) {
13
+ for (const file of files) {
14
+ const dest = path.join(buildDir, file);
15
+ await fs.mkdir(path.dirname(dest), { recursive: true });
16
+ await fs.copyFile(file, dest);
17
+ }
18
+ }
19
+
20
+ /**
21
+ * Returns files matched by patterns (deduped, sorted), excluding common cruft.
22
+ * Patterns are relative to repo root.
23
+ */
24
+ async function gatherFiles(patterns) {
25
+ const matches = await fg(patterns, {
26
+ dot: true,
27
+ onlyFiles: true,
28
+ unique: true,
29
+ // Avoid publishing cruft by default (dzil PruneCruft vibe)
30
+ ignore: [
31
+ "**/.git/**",
32
+ "**/.build/**",
33
+ "**/.rzil/**",
34
+ "**/node_modules/**",
35
+ "**/.DS_Store",
36
+ ],
37
+ });
38
+
39
+ matches.sort();
40
+ return matches;
41
+ }
42
+
43
+ //
44
+ // Build dir population for "publishable-only" mode.
45
+ //
46
+ // - files: one or more glob patterns (e.g. ["lib/**/*.mjs"])
47
+ // - include: one or more specific files (e.g. ["README.md","LICENSE","Changes"])
48
+ // - binDirs: one or more directories (e.g. ["bin","cli"]) scanned for *.{mjs,cjs,js}
49
+ //
50
+ export async function populateBuildDir({
51
+ buildDir,
52
+ files = [],
53
+ include = [],
54
+ binDirs = [],
55
+ }) {
56
+ // normalize bin dirs -> globs
57
+ const binGlobs = binDirs.map((d) => `${d}/**/*.{mjs,cjs,js}`);
58
+
59
+ const patterns = []
60
+ .concat(files)
61
+ .concat(binGlobs)
62
+ .concat(include);
63
+
64
+ const gathered = await gatherFiles(patterns);
65
+ await copyFilesIntoBuildDir(buildDir, gathered);
66
+
67
+ return gathered;
68
+ }
69
+
package/lib/util.mjs ADDED
@@ -0,0 +1,44 @@
1
+ // SPDX-FileCopyrightText: 2026 Wesley Schwengle <wesleys@opperschaap.net>
2
+ //
3
+ // SPDX-License-Identifier: MIT
4
+
5
+ export function requireString(v, label) {
6
+ if (v == null) return null;
7
+ if (typeof v === "string") return v;
8
+ throw new Error(`${label} must be a single string.`);
9
+ }
10
+
11
+ export function normalizeRange(range) {
12
+ if (typeof range !== "string") return range;
13
+ return range
14
+ .trim()
15
+ .replace(/\s+/g, " ")
16
+ // remove whitespace after comparator operators
17
+ .replace(/([<>]=?)\s+/g, "$1");
18
+ }
19
+
20
+ export function normalizePrereqValue(v) {
21
+ if (v === 0) return "*";
22
+ if (typeof v === "number") return String(v);
23
+ if (typeof v === "string") return normalizeRange(v);
24
+ return v;
25
+ }
26
+
27
+ export function bumpSemver(version, bumpType) {
28
+ const m = String(version).trim().match(/^(\d+)\.(\d+)\.(\d+)(.*)?$/);
29
+ if (!m) throw new Error(`Unsupported version format: ${version}`);
30
+ let maj = Number(m[1]), min = Number(m[2]), pat = Number(m[3]);
31
+ const suffix = m[4] ?? "";
32
+
33
+ if (bumpType === "patch") pat += 1;
34
+ else if (bumpType === "minor") { min += 1; pat = 0; }
35
+ else if (bumpType === "major") { maj += 1; min = 0; pat = 0; }
36
+ else throw new Error(`Unsupported bump type: ${bumpType}`);
37
+
38
+ return `${maj}.${min}.${pat}${suffix}`;
39
+ }
40
+
41
+ export function prefixDotSlash(p) {
42
+ if (!p) return p;
43
+ return p.startsWith("./") ? p : `./${p}`;
44
+ }
@@ -0,0 +1,64 @@
1
+ // SPDX-FileCopyrightText: 2026 Wesley Schwengle <wesleys@opperschaap.net>
2
+ //
3
+ // SPDX-License-Identifier: MIT
4
+
5
+ import fs from "node:fs/promises";
6
+ import path from "node:path";
7
+
8
+ const VERSION_RE =
9
+ /\b(?:export\s+)?const\s+VERSION\s*=\s*(["'])([^"'\\\n]+)\1\s*;?/g;
10
+
11
+ function stripShebang(s) {
12
+ return s.startsWith("#!") ? s.replace(/^#!.*\n/, "") : s;
13
+ }
14
+
15
+ export function resolveVersionSource(cfg) {
16
+ const from = cfg.version?.from;
17
+ if (!from) {
18
+ throw new Error(
19
+ "No [version].from configured in dist.toml. Version must come from a file."
20
+ );
21
+ }
22
+ return path.resolve(from);
23
+ }
24
+
25
+ export async function readVersion(cfg) {
26
+ const file = resolveVersionSource(cfg);
27
+ const raw = await fs.readFile(file, "utf8");
28
+ const src = stripShebang(raw);
29
+
30
+ const matches = [...src.matchAll(VERSION_RE)];
31
+ if (matches.length !== 1) {
32
+ throw new Error(
33
+ `Expected exactly one VERSION constant in ${file}, found ${matches.length}`
34
+ );
35
+ }
36
+
37
+ return matches[0][2];
38
+ }
39
+
40
+ export async function writeVersion(cfg, nextVersion) {
41
+ const file = resolveVersionSource(cfg);
42
+ const original = await fs.readFile(file, "utf8");
43
+ const src = stripShebang(original);
44
+
45
+ const matches = [...src.matchAll(VERSION_RE)];
46
+ if (matches.length !== 1) {
47
+ throw new Error(
48
+ `Expected exactly one VERSION constant in ${file}, found ${matches.length}`
49
+ );
50
+ }
51
+
52
+ const replaced = src.replace(
53
+ VERSION_RE,
54
+ (_, quote) => `const VERSION = ${quote}${nextVersion}${quote};`
55
+ );
56
+
57
+ const out = original.startsWith("#!")
58
+ ? original.match(/^#!.*\n/)[0] + replaced
59
+ : replaced;
60
+
61
+ await fs.writeFile(file, out, "utf8");
62
+
63
+ return file; // so release can auto-commit it
64
+ }
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "author": {
3
+ "email": "wesleys@opperschaap.net",
4
+ "name": "Wesley Schwengle"
5
+ },
6
+ "bin": {
7
+ "rzil": "./bin/rzil.mjs"
8
+ },
9
+ "dependencies": {
10
+ "@iarna/toml": "latest",
11
+ "@opndev/util": ">=0.0.11",
12
+ "fast-glob": "latest"
13
+ },
14
+ "description": "Release zilla for npm packages",
15
+ "devDependencies": {
16
+ "jsdoc": "latest",
17
+ "tap": "latest"
18
+ },
19
+ "engines": {
20
+ "node": ">=18",
21
+ "npm": ">=11"
22
+ },
23
+ "exports": {
24
+ ".": "./lib/index.mjs"
25
+ },
26
+ "homepage": "https://gitlab.com/opndev/javascript/rzilla",
27
+ "keywords": [
28
+ "release",
29
+ "npm",
30
+ "changes",
31
+ "changelog",
32
+ "git",
33
+ "cli"
34
+ ],
35
+ "license": "MIT",
36
+ "name": "@opndev/rzilla",
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "git+https://gitlab.com/opndev/javascript/rzilla.git"
40
+ },
41
+ "scripts": {
42
+ "build": "rzil build",
43
+ "pkg": "rzil pkg",
44
+ "release": "rzil release",
45
+ "test": "tap"
46
+ },
47
+ "sideEffects": false,
48
+ "type": "module",
49
+ "version": "0.0.1"
50
+ }