@doki-land/nifty 0.0.3 → 0.0.5
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.
- package/cli/nifty.mjs +11 -11
- package/locales/en-US/cli.json +68 -68
- package/locales/locales.json +4 -4
- package/package.json +16 -20
- package/src/cli/authArgs.ts +52 -52
- package/src/cli/bump-cmd.ts +55 -55
- package/src/cli/bump.ts +237 -237
- package/src/cli/change-logs-cmd.ts +97 -97
- package/src/cli/cli.ts +47 -47
- package/src/cli/context.ts +36 -36
- package/src/cli/format-cmd.ts +23 -23
- package/src/cli/format.ts +28 -28
- package/src/cli/index.ts +9 -9
- package/src/cli/install-native-cmd.ts +22 -22
- package/src/cli/install-native.ts +80 -80
- package/src/cli/lint-cmd.ts +35 -35
- package/src/cli/lint.ts +102 -102
- package/src/cli/main.ts +1 -1
- package/src/cli/options.ts +40 -40
- package/src/cli/publish-cmd.ts +38 -38
- package/src/cli/publish.ts +95 -95
- package/src/cli/resolveNpm.ts +16 -16
- package/src/cli/retime-cmd.ts +62 -62
- package/src/cli/reword-cmd.ts +87 -87
- package/src/cli/trust-cmd.ts +38 -38
- package/src/cli/trust.ts +83 -83
- package/src/cli/update-cmd.ts +20 -20
- package/src/cli/update.ts +32 -32
- package/src/cli/upload-cmd.ts +44 -44
- package/src/cli/upload.ts +313 -313
- package/src/cli/workspace.ts +124 -124
- package/src/config/defineConfig.ts +12 -12
- package/src/config/detectProject.ts +189 -189
- package/src/config/index.ts +25 -25
- package/src/config/loadConfig.ts +129 -129
- package/src/config/types.ts +57 -57
- package/src/git.ts +61 -61
- package/src/github.ts +184 -184
- package/src/gitmoji.ts +77 -77
- package/src/index.ts +36 -36
- package/src/native.ts +665 -665
- package/src/nifty.ts +95 -95
- package/src/types.ts +40 -40
- package/README.md +0 -29
package/src/cli/cli.ts
CHANGED
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
import { dirname, join } from "node:path";
|
|
2
|
-
import { fileURLToPath } from "node:url";
|
|
3
|
-
|
|
4
|
-
import { createCli } from "@vmz/commander";
|
|
5
|
-
|
|
6
|
-
import { registerBumpCommand } from "./bump-cmd.js";
|
|
7
|
-
import { registerFormatCommand } from "./format-cmd.js";
|
|
8
|
-
import { registerChangeLogsCommand } from "./change-logs-cmd.js";
|
|
9
|
-
import { registerInstallNativeCommand } from "./install-native-cmd.js";
|
|
10
|
-
import { registerLintCommands } from "./lint-cmd.js";
|
|
11
|
-
import { registerPublishCommand } from "./publish-cmd.js";
|
|
12
|
-
import { registerRetimeCommand } from "./retime-cmd.js";
|
|
13
|
-
import { registerRewordCommand } from "./reword-cmd.js";
|
|
14
|
-
import { registerTrustCommand } from "./trust-cmd.js";
|
|
15
|
-
import { registerUpdateCommand } from "./update-cmd.js";
|
|
16
|
-
import { registerUploadCommand } from "./upload-cmd.js";
|
|
17
|
-
|
|
18
|
-
function buildNiftyCli() {
|
|
19
|
-
const localesRoot = join(dirname(fileURLToPath(import.meta.url)), "../../locales");
|
|
20
|
-
const cli = createCli("nifty")
|
|
21
|
-
.locales(localesRoot)
|
|
22
|
-
.intro("cli.intro")
|
|
23
|
-
.option("-C, --cwd <dir>", "cli.opt.cwd");
|
|
24
|
-
|
|
25
|
-
registerUpdateCommand(cli);
|
|
26
|
-
registerFormatCommand(cli);
|
|
27
|
-
registerLintCommands(cli);
|
|
28
|
-
registerUploadCommand(cli);
|
|
29
|
-
registerInstallNativeCommand(cli);
|
|
30
|
-
registerBumpCommand(cli);
|
|
31
|
-
registerPublishCommand(cli);
|
|
32
|
-
registerTrustCommand(cli);
|
|
33
|
-
registerRewordCommand(cli);
|
|
34
|
-
registerRetimeCommand(cli);
|
|
35
|
-
registerChangeLogsCommand(cli);
|
|
36
|
-
|
|
37
|
-
return cli;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export async function runCli(argv: string[]): Promise<number> {
|
|
41
|
-
try {
|
|
42
|
-
return await buildNiftyCli().parse(argv);
|
|
43
|
-
} catch (error) {
|
|
44
|
-
console.error(`error: ${error instanceof Error ? error.message : String(error)}`);
|
|
45
|
-
return 1;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
1
|
+
import { dirname, join } from "node:path";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
|
|
4
|
+
import { createCli } from "@vmz/commander";
|
|
5
|
+
|
|
6
|
+
import { registerBumpCommand } from "./bump-cmd.js";
|
|
7
|
+
import { registerFormatCommand } from "./format-cmd.js";
|
|
8
|
+
import { registerChangeLogsCommand } from "./change-logs-cmd.js";
|
|
9
|
+
import { registerInstallNativeCommand } from "./install-native-cmd.js";
|
|
10
|
+
import { registerLintCommands } from "./lint-cmd.js";
|
|
11
|
+
import { registerPublishCommand } from "./publish-cmd.js";
|
|
12
|
+
import { registerRetimeCommand } from "./retime-cmd.js";
|
|
13
|
+
import { registerRewordCommand } from "./reword-cmd.js";
|
|
14
|
+
import { registerTrustCommand } from "./trust-cmd.js";
|
|
15
|
+
import { registerUpdateCommand } from "./update-cmd.js";
|
|
16
|
+
import { registerUploadCommand } from "./upload-cmd.js";
|
|
17
|
+
|
|
18
|
+
function buildNiftyCli() {
|
|
19
|
+
const localesRoot = join(dirname(fileURLToPath(import.meta.url)), "../../locales");
|
|
20
|
+
const cli = createCli("nifty")
|
|
21
|
+
.locales(localesRoot)
|
|
22
|
+
.intro("cli.intro")
|
|
23
|
+
.option("-C, --cwd <dir>", "cli.opt.cwd");
|
|
24
|
+
|
|
25
|
+
registerUpdateCommand(cli);
|
|
26
|
+
registerFormatCommand(cli);
|
|
27
|
+
registerLintCommands(cli);
|
|
28
|
+
registerUploadCommand(cli);
|
|
29
|
+
registerInstallNativeCommand(cli);
|
|
30
|
+
registerBumpCommand(cli);
|
|
31
|
+
registerPublishCommand(cli);
|
|
32
|
+
registerTrustCommand(cli);
|
|
33
|
+
registerRewordCommand(cli);
|
|
34
|
+
registerRetimeCommand(cli);
|
|
35
|
+
registerChangeLogsCommand(cli);
|
|
36
|
+
|
|
37
|
+
return cli;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export async function runCli(argv: string[]): Promise<number> {
|
|
41
|
+
try {
|
|
42
|
+
return await buildNiftyCli().parse(argv);
|
|
43
|
+
} catch (error) {
|
|
44
|
+
console.error(`error: ${error instanceof Error ? error.message : String(error)}`);
|
|
45
|
+
return 1;
|
|
46
|
+
}
|
|
47
|
+
}
|
package/src/cli/context.ts
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
import { resolve } from "node:path";
|
|
2
|
-
|
|
3
|
-
import type { ParsedOptions } from "@vmz/commander";
|
|
4
|
-
|
|
5
|
-
import { loadConfig } from "../config/loadConfig.js";
|
|
6
|
-
import { cwdFrom } from "./options.js";
|
|
7
|
-
|
|
8
|
-
/** Parse shared CLI flags used across nifty commands. */
|
|
9
|
-
export function parseCliContext(argv: string[]): { cwd: string; dryRun: boolean } {
|
|
10
|
-
let cwd = process.cwd();
|
|
11
|
-
let dryRun = false;
|
|
12
|
-
|
|
13
|
-
for (let i = 0; i < argv.length; i += 1) {
|
|
14
|
-
const arg = argv[i];
|
|
15
|
-
if (arg === "--dry-run") {
|
|
16
|
-
dryRun = true;
|
|
17
|
-
} else if (arg === "-C" || arg === "--cwd") {
|
|
18
|
-
cwd = resolve(argv[++i] ?? cwd);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return { cwd, dryRun };
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/** Ensure `nifty.config.*` exists before running a command (skip create on `--dry-run`). */
|
|
26
|
-
export async function bootstrapNiftyConfig(argv: string[]): Promise<void> {
|
|
27
|
-
const { cwd, dryRun } = parseCliContext(argv);
|
|
28
|
-
await loadConfig({ cwd, createIfMissing: !dryRun });
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/** Commander action hook: load config from parsed global/command flags. */
|
|
32
|
-
export async function bootstrapFromOptions(options: ParsedOptions): Promise<void> {
|
|
33
|
-
const cwd = cwdFrom(options) ?? process.cwd();
|
|
34
|
-
const dryRun = options["dry-run"] === true;
|
|
35
|
-
await loadConfig({ cwd, createIfMissing: !dryRun });
|
|
36
|
-
}
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
|
|
3
|
+
import type { ParsedOptions } from "@vmz/commander";
|
|
4
|
+
|
|
5
|
+
import { loadConfig } from "../config/loadConfig.js";
|
|
6
|
+
import { cwdFrom } from "./options.js";
|
|
7
|
+
|
|
8
|
+
/** Parse shared CLI flags used across nifty commands. */
|
|
9
|
+
export function parseCliContext(argv: string[]): { cwd: string; dryRun: boolean } {
|
|
10
|
+
let cwd = process.cwd();
|
|
11
|
+
let dryRun = false;
|
|
12
|
+
|
|
13
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
14
|
+
const arg = argv[i];
|
|
15
|
+
if (arg === "--dry-run") {
|
|
16
|
+
dryRun = true;
|
|
17
|
+
} else if (arg === "-C" || arg === "--cwd") {
|
|
18
|
+
cwd = resolve(argv[++i] ?? cwd);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return { cwd, dryRun };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Ensure `nifty.config.*` exists before running a command (skip create on `--dry-run`). */
|
|
26
|
+
export async function bootstrapNiftyConfig(argv: string[]): Promise<void> {
|
|
27
|
+
const { cwd, dryRun } = parseCliContext(argv);
|
|
28
|
+
await loadConfig({ cwd, createIfMissing: !dryRun });
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Commander action hook: load config from parsed global/command flags. */
|
|
32
|
+
export async function bootstrapFromOptions(options: ParsedOptions): Promise<void> {
|
|
33
|
+
const cwd = cwdFrom(options) ?? process.cwd();
|
|
34
|
+
const dryRun = options["dry-run"] === true;
|
|
35
|
+
await loadConfig({ cwd, createIfMissing: !dryRun });
|
|
36
|
+
}
|
package/src/cli/format-cmd.ts
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import type { Cli, ParsedOptions } from "@vmz/commander";
|
|
2
|
-
|
|
3
|
-
import { bootstrapFromOptions } from "./context.js";
|
|
4
|
-
import { formatWorkspace } from "./format.js";
|
|
5
|
-
import { cwdFrom, flag } from "./options.js";
|
|
6
|
-
|
|
7
|
-
export function registerFormatCommand(cli: Cli): void {
|
|
8
|
-
cli.command("format", "cli.cmd.format")
|
|
9
|
-
.option("--check", "cli.opt.check")
|
|
10
|
-
.action(async (options) => cmdFormat(options));
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export async function cmdFormat(options: ParsedOptions): Promise<number> {
|
|
14
|
-
await bootstrapFromOptions(options);
|
|
15
|
-
const exitCode = await formatWorkspace({
|
|
16
|
-
check: flag(options, "check"),
|
|
17
|
-
cwd: cwdFrom(options),
|
|
18
|
-
});
|
|
19
|
-
if (exitCode !== 0) {
|
|
20
|
-
throw new Error("format check failed");
|
|
21
|
-
}
|
|
22
|
-
return 0;
|
|
23
|
-
}
|
|
1
|
+
import type { Cli, ParsedOptions } from "@vmz/commander";
|
|
2
|
+
|
|
3
|
+
import { bootstrapFromOptions } from "./context.js";
|
|
4
|
+
import { formatWorkspace } from "./format.js";
|
|
5
|
+
import { cwdFrom, flag } from "./options.js";
|
|
6
|
+
|
|
7
|
+
export function registerFormatCommand(cli: Cli): void {
|
|
8
|
+
cli.command("format", "cli.cmd.format")
|
|
9
|
+
.option("--check", "cli.opt.check")
|
|
10
|
+
.action(async (options) => cmdFormat(options));
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export async function cmdFormat(options: ParsedOptions): Promise<number> {
|
|
14
|
+
await bootstrapFromOptions(options);
|
|
15
|
+
const exitCode = await formatWorkspace({
|
|
16
|
+
check: flag(options, "check"),
|
|
17
|
+
cwd: cwdFrom(options),
|
|
18
|
+
});
|
|
19
|
+
if (exitCode !== 0) {
|
|
20
|
+
throw new Error("format check failed");
|
|
21
|
+
}
|
|
22
|
+
return 0;
|
|
23
|
+
}
|
package/src/cli/format.ts
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
import { loadNiftyNative } from "../native.js";
|
|
2
|
-
|
|
3
|
-
export type FormatOptions = {
|
|
4
|
-
check?: boolean;
|
|
5
|
-
cwd?: string;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
export async function formatWorkspace(options: FormatOptions): Promise<number> {
|
|
9
|
-
const native = loadNiftyNative();
|
|
10
|
-
const report = native.formatter.run({
|
|
11
|
-
cwd: options.cwd,
|
|
12
|
-
check: options.check,
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
if (report.errors.length > 0) {
|
|
16
|
-
for (const message of report.errors) {
|
|
17
|
-
console.error(`error: ${message}`);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
if (report.formatted === 0 && report.unchanged > 0 && report.errors.length === 0) {
|
|
22
|
-
console.log("format: no changes needed");
|
|
23
|
-
} else if (report.errors.length === 0) {
|
|
24
|
-
console.log(`format: ${report.formatted} file(s) updated, ${report.unchanged} unchanged`);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return report.errors.length > 0 ? 1 : 0;
|
|
28
|
-
}
|
|
1
|
+
import { loadNiftyNative } from "../native.js";
|
|
2
|
+
|
|
3
|
+
export type FormatOptions = {
|
|
4
|
+
check?: boolean;
|
|
5
|
+
cwd?: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export async function formatWorkspace(options: FormatOptions): Promise<number> {
|
|
9
|
+
const native = loadNiftyNative();
|
|
10
|
+
const report = native.formatter.run({
|
|
11
|
+
cwd: options.cwd,
|
|
12
|
+
check: options.check,
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
if (report.errors.length > 0) {
|
|
16
|
+
for (const message of report.errors) {
|
|
17
|
+
console.error(`error: ${message}`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (report.formatted === 0 && report.unchanged > 0 && report.errors.length === 0) {
|
|
22
|
+
console.log("format: no changes needed");
|
|
23
|
+
} else if (report.errors.length === 0) {
|
|
24
|
+
console.log(`format: ${report.formatted} file(s) updated, ${report.unchanged} unchanged`);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return report.errors.length > 0 ? 1 : 0;
|
|
28
|
+
}
|
package/src/cli/index.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export { runCli } from "./main.js";
|
|
2
|
-
export { bumpSemver, bumpWorkspace, runBump, type BumpKind, type BumpOptions, type BumpReport } from "./bump.js";
|
|
3
|
-
export { runPublish, type PublishOptions, type PublishReport } from "./publish.js";
|
|
4
|
-
export { runTrust, type TrustReport } from "./trust.js";
|
|
5
|
-
export { runUpdate } from "./update.js";
|
|
6
|
-
export { runLint } from "./lint.js";
|
|
7
|
-
export { runUpload } from "./upload.js";
|
|
8
|
-
export { installNativeFromOptions, type InstallNativeOptions } from "./install-native.js";
|
|
9
|
-
export { findWorkspaceRoot, listWorkspacePackages, type WorkspacePackage } from "./workspace.js";
|
|
1
|
+
export { runCli } from "./main.js";
|
|
2
|
+
export { bumpSemver, bumpWorkspace, runBump, type BumpKind, type BumpOptions, type BumpReport } from "./bump.js";
|
|
3
|
+
export { runPublish, type PublishOptions, type PublishReport } from "./publish.js";
|
|
4
|
+
export { runTrust, type TrustReport } from "./trust.js";
|
|
5
|
+
export { runUpdate } from "./update.js";
|
|
6
|
+
export { runLint } from "./lint.js";
|
|
7
|
+
export { runUpload } from "./upload.js";
|
|
8
|
+
export { installNativeFromOptions, type InstallNativeOptions } from "./install-native.js";
|
|
9
|
+
export { findWorkspaceRoot, listWorkspacePackages, type WorkspacePackage } from "./workspace.js";
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import type { Cli, ParsedOptions } from "@vmz/commander";
|
|
2
|
-
|
|
3
|
-
import { installNativeFromOptions } from "./install-native.js";
|
|
4
|
-
import { cwdFrom, str } from "./options.js";
|
|
5
|
-
|
|
6
|
-
export function registerInstallNativeCommand(cli: Cli): void {
|
|
7
|
-
cli.command("install-native", "cli.cmd.install-native")
|
|
8
|
-
.option("--from <dir>", "cli.opt.from-artifacts")
|
|
9
|
-
.action(async (options) => cmdInstallNative(options));
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export async function cmdInstallNative(options: ParsedOptions): Promise<number> {
|
|
13
|
-
const from =
|
|
14
|
-
str(options, "from") ??
|
|
15
|
-
process.env.NATIVE_ARTIFACT_ROOT ??
|
|
16
|
-
"native-artifacts";
|
|
17
|
-
installNativeFromOptions({
|
|
18
|
-
from,
|
|
19
|
-
cwd: cwdFrom(options),
|
|
20
|
-
});
|
|
21
|
-
return 0;
|
|
22
|
-
}
|
|
1
|
+
import type { Cli, ParsedOptions } from "@vmz/commander";
|
|
2
|
+
|
|
3
|
+
import { installNativeFromOptions } from "./install-native.js";
|
|
4
|
+
import { cwdFrom, str } from "./options.js";
|
|
5
|
+
|
|
6
|
+
export function registerInstallNativeCommand(cli: Cli): void {
|
|
7
|
+
cli.command("install-native", "cli.cmd.install-native")
|
|
8
|
+
.option("--from <dir>", "cli.opt.from-artifacts")
|
|
9
|
+
.action(async (options) => cmdInstallNative(options));
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export async function cmdInstallNative(options: ParsedOptions): Promise<number> {
|
|
13
|
+
const from =
|
|
14
|
+
str(options, "from") ??
|
|
15
|
+
process.env.NATIVE_ARTIFACT_ROOT ??
|
|
16
|
+
"native-artifacts";
|
|
17
|
+
installNativeFromOptions({
|
|
18
|
+
from,
|
|
19
|
+
cwd: cwdFrom(options),
|
|
20
|
+
});
|
|
21
|
+
return 0;
|
|
22
|
+
}
|
|
@@ -1,80 +1,80 @@
|
|
|
1
|
-
import { copyFileSync, existsSync, mkdirSync, readdirSync } from "node:fs";
|
|
2
|
-
import { basename, dirname, join, relative, resolve } from "node:path";
|
|
3
|
-
|
|
4
|
-
import { detectProjectLayout } from "../config/detectProject.js";
|
|
5
|
-
|
|
6
|
-
/** Basename of a built .node file → platform package directory under projects/packages/. */
|
|
7
|
-
const PACKAGE_BY_ASSET: Record<string, string> = {
|
|
8
|
-
"nifty-win32-x64-msvc.node": "nifty-win32-x64",
|
|
9
|
-
"nifty-linux-x64-gnu.node": "nifty-linux-x64",
|
|
10
|
-
"nifty-linux-arm64-gnu.node": "nifty-linux-arm64",
|
|
11
|
-
"nifty-darwin-x64.node": "nifty-darwin-x64",
|
|
12
|
-
"nifty-darwin-arm64.node": "nifty-darwin-arm64",
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
/** Matrix platforms that must be present after install (matches publish-npm.yml). */
|
|
16
|
-
const REQUIRED_PACKAGES = ["nifty-win32-x64", "nifty-linux-x64", "nifty-darwin-arm64"];
|
|
17
|
-
|
|
18
|
-
export type InstallNativeOptions = {
|
|
19
|
-
/** Downloaded CI artifact tree (walked recursively for .node files). */
|
|
20
|
-
from: string;
|
|
21
|
-
cwd?: string;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
function walkNodes(dir: string): string[] {
|
|
25
|
-
const out: string[] = [];
|
|
26
|
-
if (!existsSync(dir)) {
|
|
27
|
-
return out;
|
|
28
|
-
}
|
|
29
|
-
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
30
|
-
const full = join(dir, entry.name);
|
|
31
|
-
if (entry.isDirectory()) {
|
|
32
|
-
out.push(...walkNodes(full));
|
|
33
|
-
} else if (entry.isFile() && entry.name.endsWith(".node")) {
|
|
34
|
-
out.push(full);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
return out;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function libHasNode(libDir: string): boolean {
|
|
41
|
-
return existsSync(libDir) && readdirSync(libDir).some((name) => name.endsWith(".node"));
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/** Copy matrix .node artifacts into platform package lib dirs for npm publish. */
|
|
45
|
-
export function installNativeFromOptions(options: InstallNativeOptions): void {
|
|
46
|
-
const layout = detectProjectLayout(options.cwd ?? process.cwd());
|
|
47
|
-
const artifactRoot = resolve(layout.root, options.from);
|
|
48
|
-
const nodes = walkNodes(artifactRoot);
|
|
49
|
-
if (nodes.length === 0) {
|
|
50
|
-
throw new Error(`install-native: no .node files under ${artifactRoot}`);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
let installed = 0;
|
|
54
|
-
for (const file of nodes) {
|
|
55
|
-
const base = basename(file);
|
|
56
|
-
const packageDir = PACKAGE_BY_ASSET[base];
|
|
57
|
-
if (!packageDir) {
|
|
58
|
-
console.log(`skip unmapped artifact ${relative(artifactRoot, file)}`);
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
const dest = join(layout.root, "projects/packages", packageDir, "lib", base);
|
|
62
|
-
mkdirSync(dirname(dest), { recursive: true });
|
|
63
|
-
copyFileSync(file, dest);
|
|
64
|
-
console.log(`installed ${relative(layout.root, dest)}`);
|
|
65
|
-
installed += 1;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (installed === 0) {
|
|
69
|
-
throw new Error("install-native: no mapped platform .node files installed");
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
for (const packageDir of REQUIRED_PACKAGES) {
|
|
73
|
-
const libDir = join(layout.root, "projects/packages", packageDir, "lib");
|
|
74
|
-
if (!libHasNode(libDir)) {
|
|
75
|
-
throw new Error(`install-native: missing .node under ${packageDir}/lib`);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
console.log(`install-native: ${installed} native binary(ies) ready for npm publish`);
|
|
80
|
-
}
|
|
1
|
+
import { copyFileSync, existsSync, mkdirSync, readdirSync } from "node:fs";
|
|
2
|
+
import { basename, dirname, join, relative, resolve } from "node:path";
|
|
3
|
+
|
|
4
|
+
import { detectProjectLayout } from "../config/detectProject.js";
|
|
5
|
+
|
|
6
|
+
/** Basename of a built .node file → platform package directory under projects/packages/. */
|
|
7
|
+
const PACKAGE_BY_ASSET: Record<string, string> = {
|
|
8
|
+
"nifty-win32-x64-msvc.node": "nifty-win32-x64",
|
|
9
|
+
"nifty-linux-x64-gnu.node": "nifty-linux-x64",
|
|
10
|
+
"nifty-linux-arm64-gnu.node": "nifty-linux-arm64",
|
|
11
|
+
"nifty-darwin-x64.node": "nifty-darwin-x64",
|
|
12
|
+
"nifty-darwin-arm64.node": "nifty-darwin-arm64",
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/** Matrix platforms that must be present after install (matches publish-npm.yml). */
|
|
16
|
+
const REQUIRED_PACKAGES = ["nifty-win32-x64", "nifty-linux-x64", "nifty-darwin-arm64"];
|
|
17
|
+
|
|
18
|
+
export type InstallNativeOptions = {
|
|
19
|
+
/** Downloaded CI artifact tree (walked recursively for .node files). */
|
|
20
|
+
from: string;
|
|
21
|
+
cwd?: string;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
function walkNodes(dir: string): string[] {
|
|
25
|
+
const out: string[] = [];
|
|
26
|
+
if (!existsSync(dir)) {
|
|
27
|
+
return out;
|
|
28
|
+
}
|
|
29
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
30
|
+
const full = join(dir, entry.name);
|
|
31
|
+
if (entry.isDirectory()) {
|
|
32
|
+
out.push(...walkNodes(full));
|
|
33
|
+
} else if (entry.isFile() && entry.name.endsWith(".node")) {
|
|
34
|
+
out.push(full);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return out;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function libHasNode(libDir: string): boolean {
|
|
41
|
+
return existsSync(libDir) && readdirSync(libDir).some((name) => name.endsWith(".node"));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Copy matrix .node artifacts into platform package lib dirs for npm publish. */
|
|
45
|
+
export function installNativeFromOptions(options: InstallNativeOptions): void {
|
|
46
|
+
const layout = detectProjectLayout(options.cwd ?? process.cwd());
|
|
47
|
+
const artifactRoot = resolve(layout.root, options.from);
|
|
48
|
+
const nodes = walkNodes(artifactRoot);
|
|
49
|
+
if (nodes.length === 0) {
|
|
50
|
+
throw new Error(`install-native: no .node files under ${artifactRoot}`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
let installed = 0;
|
|
54
|
+
for (const file of nodes) {
|
|
55
|
+
const base = basename(file);
|
|
56
|
+
const packageDir = PACKAGE_BY_ASSET[base];
|
|
57
|
+
if (!packageDir) {
|
|
58
|
+
console.log(`skip unmapped artifact ${relative(artifactRoot, file)}`);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
const dest = join(layout.root, "projects/packages", packageDir, "lib", base);
|
|
62
|
+
mkdirSync(dirname(dest), { recursive: true });
|
|
63
|
+
copyFileSync(file, dest);
|
|
64
|
+
console.log(`installed ${relative(layout.root, dest)}`);
|
|
65
|
+
installed += 1;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (installed === 0) {
|
|
69
|
+
throw new Error("install-native: no mapped platform .node files installed");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
for (const packageDir of REQUIRED_PACKAGES) {
|
|
73
|
+
const libDir = join(layout.root, "projects/packages", packageDir, "lib");
|
|
74
|
+
if (!libHasNode(libDir)) {
|
|
75
|
+
throw new Error(`install-native: missing .node under ${packageDir}/lib`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
console.log(`install-native: ${installed} native binary(ies) ready for npm publish`);
|
|
80
|
+
}
|
package/src/cli/lint-cmd.ts
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
import type { Cli, ParsedOptions } from "@vmz/commander";
|
|
2
|
-
|
|
3
|
-
import { bootstrapFromOptions } from "./context.js";
|
|
4
|
-
import { lintCommits, type LintOptions } from "./lint.js";
|
|
5
|
-
import { cwdFrom, flag, str, strList } from "./options.js";
|
|
6
|
-
|
|
7
|
-
export function registerLintCommands(cli: Cli): void {
|
|
8
|
-
registerLintLike(cli, "lint", "cli.cmd.lint", false);
|
|
9
|
-
registerLintLike(cli, "check", "cli.cmd.check", true);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
function registerLintLike(cli: Cli, name: string, helpId: string, check: boolean): void {
|
|
13
|
-
cli.command(name, helpId)
|
|
14
|
-
.option("--from <ref>", "cli.opt.from")
|
|
15
|
-
.option("--to <ref>", "cli.opt.to")
|
|
16
|
-
.option("-s, --subject <text>...", "cli.opt.subject")
|
|
17
|
-
.option("--no-cargo", "cli.opt.no-cargo")
|
|
18
|
-
.action(async (options) => cmdLint(options, check));
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export async function cmdLint(options: ParsedOptions, check: boolean): Promise<number> {
|
|
22
|
-
await bootstrapFromOptions(options);
|
|
23
|
-
const lintOptions: LintOptions = {
|
|
24
|
-
subjects: strList(options, "subject"),
|
|
25
|
-
from: str(options, "from"),
|
|
26
|
-
to: str(options, "to"),
|
|
27
|
-
cwd: cwdFrom(options),
|
|
28
|
-
scanCargo: flag(options, "no-cargo") ? false : undefined,
|
|
29
|
-
};
|
|
30
|
-
const errorCount = await lintCommits(lintOptions, check);
|
|
31
|
-
if (check && errorCount > 0) {
|
|
32
|
-
throw new Error(`found ${errorCount} lint error(s)`);
|
|
33
|
-
}
|
|
34
|
-
return 0;
|
|
35
|
-
}
|
|
1
|
+
import type { Cli, ParsedOptions } from "@vmz/commander";
|
|
2
|
+
|
|
3
|
+
import { bootstrapFromOptions } from "./context.js";
|
|
4
|
+
import { lintCommits, type LintOptions } from "./lint.js";
|
|
5
|
+
import { cwdFrom, flag, str, strList } from "./options.js";
|
|
6
|
+
|
|
7
|
+
export function registerLintCommands(cli: Cli): void {
|
|
8
|
+
registerLintLike(cli, "lint", "cli.cmd.lint", false);
|
|
9
|
+
registerLintLike(cli, "check", "cli.cmd.check", true);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function registerLintLike(cli: Cli, name: string, helpId: string, check: boolean): void {
|
|
13
|
+
cli.command(name, helpId)
|
|
14
|
+
.option("--from <ref>", "cli.opt.from")
|
|
15
|
+
.option("--to <ref>", "cli.opt.to")
|
|
16
|
+
.option("-s, --subject <text>...", "cli.opt.subject")
|
|
17
|
+
.option("--no-cargo", "cli.opt.no-cargo")
|
|
18
|
+
.action(async (options) => cmdLint(options, check));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export async function cmdLint(options: ParsedOptions, check: boolean): Promise<number> {
|
|
22
|
+
await bootstrapFromOptions(options);
|
|
23
|
+
const lintOptions: LintOptions = {
|
|
24
|
+
subjects: strList(options, "subject"),
|
|
25
|
+
from: str(options, "from"),
|
|
26
|
+
to: str(options, "to"),
|
|
27
|
+
cwd: cwdFrom(options),
|
|
28
|
+
scanCargo: flag(options, "no-cargo") ? false : undefined,
|
|
29
|
+
};
|
|
30
|
+
const errorCount = await lintCommits(lintOptions, check);
|
|
31
|
+
if (check && errorCount > 0) {
|
|
32
|
+
throw new Error(`found ${errorCount} lint error(s)`);
|
|
33
|
+
}
|
|
34
|
+
return 0;
|
|
35
|
+
}
|