mirror of
https://github.com/smogon/sprites.git
synced 2026-08-25 03:07:29 -05:00
Adopt the house import style
Node builtins come in as node:-prefixed namespace imports; multi-symbol internal imports use short namespace aliases (artifact, cas, subst, db, api, executor). Single-symbol pulls, types, and the buildfile DSL names stay braced, matching the sanctioned exceptions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import * as path from 'node:path';
|
||||
import * as fs from 'node:fs';
|
||||
import root from '@smogon/sprite-root/index.ts';
|
||||
|
||||
let libdir = path.join(root, 'data');
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
import path from 'path';
|
||||
import * as path from 'node:path';
|
||||
|
||||
export default path.resolve(import.meta.dirname, '../../');
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
|
||||
import pathlib from 'path';
|
||||
import {createHash} from 'crypto';
|
||||
import * as pathlib from 'node:path';
|
||||
import {createHash} from 'node:crypto';
|
||||
|
||||
import {astable, glob} from './helpers.ts';
|
||||
import {type Cmd, basenameNoExt, flattenCmds, substitute, substituteNames} from './subst.ts';
|
||||
import * as subst from './subst.ts';
|
||||
|
||||
// A rule's output: content-addressed bytes with a nominal name. The nominal
|
||||
// name exists for provenance, inspection, and deploy-time naming; it is NOT
|
||||
@@ -61,7 +61,7 @@ export interface CmdSpec {
|
||||
// the spritesheet builders). Identity is normally content-only, so
|
||||
// without this flag a same-bytes rename would leave the output stale.
|
||||
nameSensitive?: boolean;
|
||||
cmds: Cmd[];
|
||||
cmds: subst.Cmd[];
|
||||
}
|
||||
|
||||
export interface RuleDecl {
|
||||
@@ -128,7 +128,7 @@ export function computeKey(decl: RuleDecl, digestOf: (i: Input) => string): stri
|
||||
return h.digest('hex');
|
||||
}
|
||||
|
||||
function normalizeSpec(spec: CmdSpec | Cmd[]): CmdSpec {
|
||||
function normalizeSpec(spec: CmdSpec | subst.Cmd[]): CmdSpec {
|
||||
return Array.isArray(spec) ? {cmds: spec} : spec;
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ function makeDecl(inputs: Input[], deps: Input[], spec: CmdSpec, outputs: string
|
||||
// %b/%B expand to nominal input names, never CAS paths, so they are
|
||||
// resolved at declaration. This also lands them in the identity key: a
|
||||
// command embedding input names is name-dependent by construction.
|
||||
let cmds = flattenCmds(spec.cmds).map(c => substituteNames(c, nominalInputs));
|
||||
let cmds = subst.flattenCmds(spec.cmds).map(c => subst.substituteNames(c, nominalInputs));
|
||||
if (cmds.length === 0) {
|
||||
throw new Error(`Rule with no commands (outputs: ${outputs.join(' ')})`);
|
||||
}
|
||||
@@ -197,16 +197,16 @@ function makeDecl(inputs: Input[], deps: Input[], spec: CmdSpec, outputs: string
|
||||
if (ext === '' || ext === '.') {
|
||||
throw new Error(`Rule output needs an extension: ${out}`);
|
||||
}
|
||||
decl.outputs.push(new Artifact(basenameNoExt(out), ext.slice(1), decl, index));
|
||||
decl.outputs.push(new Artifact(subst.basenameNoExt(out), ext.slice(1), decl, index));
|
||||
});
|
||||
// Validate substitutions now (unknown escapes, out-of-range %oN) rather
|
||||
// than at execution; the results are discarded.
|
||||
let nominalOutputs = decl.outputs.map(o => o.filename);
|
||||
for (let cmd of cmds) {
|
||||
substitute(cmd, nominalInputs, nominalOutputs);
|
||||
subst.substitute(cmd, nominalInputs, nominalOutputs);
|
||||
}
|
||||
if (spec.display !== undefined) {
|
||||
decl.display = substitute(spec.display, nominalInputs, nominalOutputs);
|
||||
decl.display = subst.substitute(spec.display, nominalInputs, nominalOutputs);
|
||||
}
|
||||
decls.push(decl);
|
||||
declIndex.set(identity, decl);
|
||||
@@ -216,19 +216,19 @@ function makeDecl(inputs: Input[], deps: Input[], spec: CmdSpec, outputs: string
|
||||
// One Artifact per declared output, as a tuple when the output list is a
|
||||
// literal, so `let [png, css] = rule(...)` needs no undefined checks. A
|
||||
// single string output returns its Artifact directly.
|
||||
export function rule(input: Input | Input[], spec: CmdSpec | Cmd[],
|
||||
export function rule(input: Input | Input[], spec: CmdSpec | subst.Cmd[],
|
||||
output: string): Artifact;
|
||||
export function rule<const T extends readonly string[]>(
|
||||
input: Input | Input[], spec: CmdSpec | Cmd[],
|
||||
input: Input | Input[], spec: CmdSpec | subst.Cmd[],
|
||||
output: T): {[K in keyof T]: Artifact};
|
||||
export function rule(input: Input | Input[], spec: CmdSpec | Cmd[],
|
||||
export function rule(input: Input | Input[], spec: CmdSpec | subst.Cmd[],
|
||||
output: string | readonly string[]): Artifact | Artifact[] {
|
||||
let s = normalizeSpec(spec);
|
||||
let decl = makeDecl(resolveInputs(input), resolveInputs(s.deps), s, astable(output));
|
||||
return typeof output === 'string' ? decl.outputs[0]! : decl.outputs;
|
||||
}
|
||||
|
||||
export function forEachRule(input: Input | Input[], spec: CmdSpec | Cmd[],
|
||||
export function forEachRule(input: Input | Input[], spec: CmdSpec | subst.Cmd[],
|
||||
output: string): Artifact[] {
|
||||
let s = normalizeSpec(spec);
|
||||
if (/%[fo]/.test(output)) {
|
||||
@@ -237,7 +237,7 @@ export function forEachRule(input: Input | Input[], spec: CmdSpec | Cmd[],
|
||||
let deps = resolveInputs(s.deps);
|
||||
let outputs = [];
|
||||
for (let file of resolveInputs(input)) {
|
||||
let decl = makeDecl([file], deps, s, [substitute(output, [nominal(file)], [])]);
|
||||
let decl = makeDecl([file], deps, s, [subst.substitute(output, [nominal(file)], [])]);
|
||||
outputs.push(...decl.outputs);
|
||||
}
|
||||
return outputs;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
import fs from 'fs';
|
||||
import pathlib from 'path';
|
||||
import * as fs from 'node:fs';
|
||||
import * as pathlib from 'node:path';
|
||||
|
||||
import {hashFileSync} from './hash.ts';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
import fs from 'fs';
|
||||
import * as fs from 'node:fs';
|
||||
|
||||
export function parseConfig(text: string): Map<string, string> {
|
||||
let result = new Map<string, string>();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import {type RuleDecl} from './artifact.ts';
|
||||
import {casSweep} from './cas.ts';
|
||||
import {BuildError} from './errors.ts';
|
||||
import {type BuildResult, Executor, label} from './executor.ts';
|
||||
import * as executor from './executor.ts';
|
||||
import {reconcileHashes} from './hash.ts';
|
||||
import {type Store} from './store.ts';
|
||||
|
||||
@@ -25,7 +25,7 @@ export interface BuildOpts {
|
||||
logError?: (line: string) => void;
|
||||
}
|
||||
|
||||
export interface DriveResult extends BuildResult {
|
||||
export interface DriveResult extends executor.BuildResult {
|
||||
interrupted: boolean;
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ export async function build(decls: readonly RuleDecl[], opts: BuildOpts): Promis
|
||||
store.saveFileCache(updated);
|
||||
}
|
||||
|
||||
let executor = new Executor({
|
||||
let exe = new executor.Executor({
|
||||
root: opts.root,
|
||||
store,
|
||||
casDir: opts.casDir,
|
||||
@@ -75,7 +75,7 @@ export async function build(decls: readonly RuleDecl[], opts: BuildOpts): Promis
|
||||
log,
|
||||
logError,
|
||||
});
|
||||
let result = await executor.build(decls);
|
||||
let result = await exe.build(decls);
|
||||
let interrupted = opts.signal.aborted;
|
||||
|
||||
let counts = {clean: 0, ran: 0, 'would-run': 0, failed: 0, blocked: 0};
|
||||
@@ -103,7 +103,7 @@ export async function build(decls: readonly RuleDecl[], opts: BuildOpts): Promis
|
||||
logError('Failed rules:');
|
||||
for (let decl of decls) {
|
||||
if (result.outcomes.get(decl)?.status === 'failed') {
|
||||
logError(` ${label(decl)}`);
|
||||
logError(` ${executor.label(decl)}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
import {spawn} from 'child_process';
|
||||
import {spawn} from 'node:child_process';
|
||||
|
||||
export interface ExecResult {
|
||||
code: number | null;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
|
||||
import fs from 'fs';
|
||||
import pathlib from 'path';
|
||||
import * as fs from 'node:fs';
|
||||
import * as pathlib from 'node:path';
|
||||
|
||||
import {type Input, type RuleDecl, computeKey} from './artifact.ts';
|
||||
import {casInsert, casPath, casStat} from './cas.ts';
|
||||
import * as artifact from './artifact.ts';
|
||||
import * as cas from './cas.ts';
|
||||
import {BuildError} from './errors.ts';
|
||||
import {runShell} from './exec.ts';
|
||||
import {type Store} from './store.ts';
|
||||
@@ -19,8 +19,8 @@ export type RuleOutcome =
|
||||
| {status: 'blocked'}; // a producer failed
|
||||
|
||||
export interface BuildResult {
|
||||
outcomes: Map<RuleDecl, RuleOutcome>; // no entry = not attempted (aborted)
|
||||
keys: Map<RuleDecl, string>; // only decls whose key resolved
|
||||
outcomes: Map<artifact.RuleDecl, RuleOutcome>; // no entry = not attempted (aborted)
|
||||
keys: Map<artifact.RuleDecl, string>; // only decls whose key resolved
|
||||
ok: boolean; // every decl clean or ran
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ export interface ExecutorOpts {
|
||||
logError?: (line: string) => void;
|
||||
}
|
||||
|
||||
export function label(decl: RuleDecl): string {
|
||||
export function label(decl: artifact.RuleDecl): string {
|
||||
return decl.display ?? decl.cmds[0]!;
|
||||
}
|
||||
|
||||
@@ -86,10 +86,10 @@ class Semaphore {
|
||||
// artifacts that already exist as values), so there is no cycle check.
|
||||
export class Executor {
|
||||
private opts: ExecutorOpts;
|
||||
private memo = new Map<RuleDecl, Promise<string[]>>();
|
||||
private memo = new Map<artifact.RuleDecl, Promise<string[]>>();
|
||||
private inflightByKey = new Map<string, Promise<string[]>>();
|
||||
private outcomes = new Map<RuleDecl, RuleOutcome>();
|
||||
private keys = new Map<RuleDecl, string>();
|
||||
private outcomes = new Map<artifact.RuleDecl, RuleOutcome>();
|
||||
private keys = new Map<artifact.RuleDecl, string>();
|
||||
private semaphore: Semaphore;
|
||||
private failAc = new AbortController();
|
||||
private runSignal: AbortSignal;
|
||||
@@ -106,7 +106,7 @@ export class Executor {
|
||||
this.logError = opts.logError ?? console.error;
|
||||
}
|
||||
|
||||
async build(decls: readonly RuleDecl[]): Promise<BuildResult> {
|
||||
async build(decls: readonly artifact.RuleDecl[]): Promise<BuildResult> {
|
||||
await Promise.allSettled(decls.map(d => this.demand(d)));
|
||||
let ok = decls.every(d => {
|
||||
let status = this.outcomes.get(d)?.status;
|
||||
@@ -115,7 +115,7 @@ export class Executor {
|
||||
return {outcomes: this.outcomes, keys: this.keys, ok};
|
||||
}
|
||||
|
||||
private demand(decl: RuleDecl): Promise<string[]> {
|
||||
private demand(decl: artifact.RuleDecl): Promise<string[]> {
|
||||
let p = this.memo.get(decl);
|
||||
if (p === undefined) {
|
||||
// Any non-sentinel escape (a store error, a resolve conflict, a
|
||||
@@ -136,7 +136,7 @@ export class Executor {
|
||||
return p;
|
||||
}
|
||||
|
||||
private async digestOf(i: Input): Promise<string> {
|
||||
private async digestOf(i: artifact.Input): Promise<string> {
|
||||
if (typeof i !== 'string') {
|
||||
await this.demand(i.decl);
|
||||
return i.hash;
|
||||
@@ -148,8 +148,8 @@ export class Executor {
|
||||
return hash.toString('hex');
|
||||
}
|
||||
|
||||
private async demandInner(decl: RuleDecl): Promise<string[]> {
|
||||
let digests: Map<Input, string>;
|
||||
private async demandInner(decl: artifact.RuleDecl): Promise<string[]> {
|
||||
let digests: Map<artifact.Input, string>;
|
||||
try {
|
||||
let inputs = [...decl.inputs, ...decl.deps];
|
||||
let resolved = await Promise.all(inputs.map(i => this.digestOf(i)));
|
||||
@@ -164,7 +164,7 @@ export class Executor {
|
||||
throw err;
|
||||
}
|
||||
|
||||
let key = computeKey(decl, i => digests.get(i)!);
|
||||
let key = artifact.computeKey(decl, i => digests.get(i)!);
|
||||
this.keys.set(decl, key);
|
||||
|
||||
// Byte-identical duplicate declarations share one execution.
|
||||
@@ -191,13 +191,13 @@ export class Executor {
|
||||
return result;
|
||||
}
|
||||
|
||||
private async perform(decl: RuleDecl, key: string): Promise<string[]> {
|
||||
private async perform(decl: artifact.RuleDecl, key: string): Promise<string[]> {
|
||||
let {store, casDir} = this.opts;
|
||||
let stored = store.lookupRule(key);
|
||||
if (stored !== null
|
||||
&& stored.length === decl.outputs.length
|
||||
&& stored.every((o, n) => o.ext === decl.outputs[n]!.ext)
|
||||
&& stored.every(o => casStat(casDir, o.digest, o.ext) === o.size)) {
|
||||
&& stored.every(o => cas.casStat(casDir, o.digest, o.ext) === o.size)) {
|
||||
this.outcomes.set(decl, {status: 'clean'});
|
||||
return stored.map(o => o.digest);
|
||||
}
|
||||
@@ -220,13 +220,13 @@ export class Executor {
|
||||
}
|
||||
}
|
||||
|
||||
private async execute(decl: RuleDecl, key: string, reason: DirtyReason): Promise<string[]> {
|
||||
private async execute(decl: artifact.RuleDecl, key: string, reason: DirtyReason): Promise<string[]> {
|
||||
let {store, casDir, tmpDir, root} = this.opts;
|
||||
let ruleTmp = pathlib.join(tmpDir, String(this.tmpSeq++));
|
||||
fs.mkdirSync(ruleTmp, {recursive: true});
|
||||
let tempOutputs = decl.outputs.map(o => pathlib.join(ruleTmp, o.filename));
|
||||
let concreteInputs = decl.inputs.map(
|
||||
i => typeof i === 'string' ? i : casPath(casDir, i.hash, i.ext));
|
||||
i => typeof i === 'string' ? i : cas.casPath(casDir, i.hash, i.ext));
|
||||
let command = decl.cmds.map(c => substitute(c, concreteInputs, tempOutputs)).join(' && ');
|
||||
|
||||
try {
|
||||
@@ -238,7 +238,7 @@ export class Executor {
|
||||
let missing = tempOutputs.filter(p => !fs.existsSync(p));
|
||||
if (missing.length === 0) {
|
||||
let outputs = decl.outputs.map((o, n) => {
|
||||
let object = casInsert(casDir, tempOutputs[n]!, o.ext);
|
||||
let object = cas.casInsert(casDir, tempOutputs[n]!, o.ext);
|
||||
return {digest: object.digest, ext: o.ext, size: object.size};
|
||||
});
|
||||
store.recordRule(key, decl.cmds, outputs);
|
||||
@@ -261,7 +261,7 @@ export class Executor {
|
||||
|
||||
// Nothing is recorded for a failure: failed and never-ran are the same
|
||||
// state, so the rule stays dirty.
|
||||
private fail(decl: RuleDecl, command: string, output: string, message: string): never {
|
||||
private fail(decl: artifact.RuleDecl, command: string, output: string, message: string): never {
|
||||
this.outcomes.set(decl, {status: 'failed', message});
|
||||
this.logError(`FAILED: ${label(decl)} (${message})`);
|
||||
this.logError(` command: ${command}`);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
import fs from 'fs';
|
||||
import {createHash} from 'crypto';
|
||||
import * as fs from 'node:fs';
|
||||
import {createHash} from 'node:crypto';
|
||||
|
||||
export interface FileStat {
|
||||
size: bigint;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
import fs from 'fs';
|
||||
import pathlib from 'path';
|
||||
import * as fs from 'node:fs';
|
||||
import * as pathlib from 'node:path';
|
||||
|
||||
import type {Artifact} from './artifact.ts';
|
||||
import {type Cmd, basenameNoExt} from './subst.ts';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
import fs from 'fs';
|
||||
import pathlib from 'path';
|
||||
import * as fs from 'node:fs';
|
||||
import * as pathlib from 'node:path';
|
||||
import {DatabaseSync} from 'node:sqlite';
|
||||
|
||||
import {BuildError} from './errors.ts';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
import pathlib from 'path';
|
||||
import * as pathlib from 'node:path';
|
||||
|
||||
// A command spec entry: a shell command string, or an arbitrarily nested list
|
||||
// of them (flattened, like the Lua flatten()).
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
|
||||
import assert from 'node:assert/strict';
|
||||
import {createHash} from 'node:crypto';
|
||||
import fs from 'node:fs';
|
||||
import os from 'node:os';
|
||||
import pathlib from 'node:path';
|
||||
import * as fs from 'node:fs';
|
||||
import * as os from 'node:os';
|
||||
import * as pathlib from 'node:path';
|
||||
import {test} from 'node:test';
|
||||
|
||||
import {casExists, casInsert, casPath, casStat, casSweep} from '../cas.ts';
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
import assert from 'node:assert/strict';
|
||||
import fs from 'node:fs';
|
||||
import os from 'node:os';
|
||||
import pathlib from 'node:path';
|
||||
import * as fs from 'node:fs';
|
||||
import * as os from 'node:os';
|
||||
import * as pathlib from 'node:path';
|
||||
import {beforeEach, test} from 'node:test';
|
||||
|
||||
import {type Artifact, type CmdSpec, getDecls, resetDecls, rule} from '../artifact.ts';
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
import assert from 'node:assert/strict';
|
||||
import fs from 'node:fs';
|
||||
import os from 'node:os';
|
||||
import pathlib from 'node:path';
|
||||
import * as fs from 'node:fs';
|
||||
import * as os from 'node:os';
|
||||
import * as pathlib from 'node:path';
|
||||
import {test} from 'node:test';
|
||||
|
||||
import {base, spritedata, spriteglob} from '../helpers.ts';
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
import assert from 'node:assert/strict';
|
||||
import fs from 'node:fs';
|
||||
import os from 'node:os';
|
||||
import pathlib from 'node:path';
|
||||
import * as fs from 'node:fs';
|
||||
import * as os from 'node:os';
|
||||
import * as pathlib from 'node:path';
|
||||
import {test} from 'node:test';
|
||||
|
||||
import {DatabaseSync} from 'node:sqlite';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
import crypto from 'crypto';
|
||||
import fs from 'fs';
|
||||
import * as crypto from 'node:crypto';
|
||||
import * as fs from 'node:fs';
|
||||
|
||||
import b32encode from 'base32-encode';
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
import fs from 'fs';
|
||||
import nodePath from 'path';
|
||||
import * as fs from 'node:fs';
|
||||
import * as nodePath from 'node:path';
|
||||
|
||||
import JSON5 from 'json5';
|
||||
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
|
||||
import {spawn, type ChildProcess} from 'child_process';
|
||||
import fs from 'fs';
|
||||
import os from 'os';
|
||||
import nodePath from 'path';
|
||||
import {fileURLToPath, pathToFileURL} from 'url';
|
||||
import {parseArgs} from 'util';
|
||||
import {spawn, type ChildProcess} from 'node:child_process';
|
||||
import * as fs from 'node:fs';
|
||||
import * as os from 'node:os';
|
||||
import * as nodePath from 'node:path';
|
||||
import {fileURLToPath, pathToFileURL} from 'node:url';
|
||||
import {parseArgs} from 'node:util';
|
||||
|
||||
import {type RuleDecl, getDecls} from '../build/artifact.ts';
|
||||
import * as artifact from '../build/artifact.ts';
|
||||
import {casPath} from '../build/cas.ts';
|
||||
import {loadConfig} from '../build/config.ts';
|
||||
import {build} from '../build/driver.ts';
|
||||
import {BuildError} from '../build/errors.ts';
|
||||
import {killAllProcessGroups} from '../build/exec.ts';
|
||||
import {setConfig} from '../build/helpers.ts';
|
||||
import {Store, acquireLock, dbVersion} from '../build/store.ts';
|
||||
import {type DeployFn, getDeploys, makeCtx} from './api.ts';
|
||||
import * as db from '../build/store.ts';
|
||||
import * as api from './api.ts';
|
||||
import {loadDeployConfig, matchSubsets} from './config.ts';
|
||||
import {ActionQueue} from './queue.ts';
|
||||
|
||||
@@ -106,12 +106,12 @@ function discoverDeployFiles(): string[] {
|
||||
// Importing a deploy module declares its rules and registers its deploy
|
||||
// blocks; the registry delta over each sequential import is that file's
|
||||
// blocks.
|
||||
async function importDeploys(files: string[]): Promise<Map<string, readonly DeployFn[]>> {
|
||||
let specs = new Map<string, readonly DeployFn[]>();
|
||||
async function importDeploys(files: string[]): Promise<Map<string, readonly api.DeployFn[]>> {
|
||||
let specs = new Map<string, readonly api.DeployFn[]>();
|
||||
for (let file of files) {
|
||||
let before = getDeploys().length;
|
||||
let before = api.getDeploys().length;
|
||||
await import(pathToFileURL(nodePath.resolve(file)).href);
|
||||
specs.set(file, getDeploys().slice(before));
|
||||
specs.set(file, api.getDeploys().slice(before));
|
||||
}
|
||||
return specs;
|
||||
}
|
||||
@@ -119,19 +119,19 @@ async function importDeploys(files: string[]): Promise<Map<string, readonly Depl
|
||||
// Build `decls` and, on success, run `then` while still holding the lock (a
|
||||
// concurrent GC must not sweep CAS objects out from under a finish). Returns
|
||||
// the process exit code.
|
||||
async function buildThen(decls: readonly RuleDecl[], opts: CommonOpts, gc: boolean,
|
||||
async function buildThen(decls: readonly artifact.RuleDecl[], opts: CommonOpts, gc: boolean,
|
||||
then?: () => Promise<number>): Promise<number> {
|
||||
let jobs = Number(opts.jobs);
|
||||
if (!Number.isInteger(jobs) || jobs < 1) {
|
||||
throw new BuildError(`Invalid --jobs value: ${opts.jobs}`);
|
||||
}
|
||||
let dryRun = Boolean(opts.dryRun);
|
||||
let release = dryRun ? null : acquireLock(LOCK_PATH);
|
||||
let release = dryRun ? null : db.acquireLock(LOCK_PATH);
|
||||
try {
|
||||
// A dry run must not create state (opening a db migrates it);
|
||||
// without a current-version db it reads from an empty in-memory one.
|
||||
let dbPath = dryRun && dbVersion(DB_PATH) !== 2 ? ':memory:' : DB_PATH;
|
||||
let store = new Store(dbPath);
|
||||
let dbPath = dryRun && db.dbVersion(DB_PATH) !== 2 ? ':memory:' : DB_PATH;
|
||||
let store = new db.Store(dbPath);
|
||||
if (!dryRun) {
|
||||
fs.rmSync(TMP_DIR, {recursive: true, force: true});
|
||||
}
|
||||
@@ -184,7 +184,7 @@ async function buildThen(decls: readonly RuleDecl[], opts: CommonOpts, gc: boole
|
||||
}
|
||||
}
|
||||
|
||||
function finishOf(specs: Map<string, readonly DeployFn[]>, file: string): readonly DeployFn[] {
|
||||
function finishOf(specs: Map<string, readonly api.DeployFn[]>, file: string): readonly api.DeployFn[] {
|
||||
let fns = specs.get(file);
|
||||
if (fns === undefined || fns.length === 0) {
|
||||
throw new BuildError(`${file} registers no deploy blocks (use deploy())`);
|
||||
@@ -192,9 +192,9 @@ function finishOf(specs: Map<string, readonly DeployFn[]>, file: string): readon
|
||||
return fns;
|
||||
}
|
||||
|
||||
async function runFinish(fns: readonly DeployFn[], verbose: boolean): Promise<ActionQueue | null> {
|
||||
async function runFinish(fns: readonly api.DeployFn[], verbose: boolean): Promise<ActionQueue | null> {
|
||||
let aq = new ActionQueue();
|
||||
let ctx = makeCtx(CAS_DIR, aq);
|
||||
let ctx = api.makeCtx(CAS_DIR, aq);
|
||||
for (let fn of fns) {
|
||||
await fn(ctx);
|
||||
}
|
||||
@@ -218,7 +218,7 @@ async function cmdBuild(files: string[], opts: CommonOpts): Promise<void> {
|
||||
// can know which keys are no longer declared anywhere.
|
||||
let gc = files.length === 0 && !Boolean(opts.dryRun);
|
||||
await importDeploys(files.length > 0 ? files : discoverDeployFiles());
|
||||
process.exitCode = await buildThen(getDecls(), opts, gc);
|
||||
process.exitCode = await buildThen(artifact.getDecls(), opts, gc);
|
||||
}
|
||||
|
||||
async function cmdDeploy(names: string[], opts: VerbOpts): Promise<void> {
|
||||
@@ -240,7 +240,7 @@ async function cmdDeploy(names: string[], opts: VerbOpts): Promise<void> {
|
||||
setConfig(loadConfig(opts.config));
|
||||
let files = [...new Set(names.map(n => config.get(n)!.buildFile))];
|
||||
let specs = await importDeploys(files);
|
||||
process.exitCode = await buildThen(getDecls(), opts, false, async () => {
|
||||
process.exitCode = await buildThen(artifact.getDecls(), opts, false, async () => {
|
||||
for (let name of names) {
|
||||
let target = config.get(name)!;
|
||||
let aq = await runFinish(finishOf(specs, target.buildFile), Boolean(opts.verbose));
|
||||
@@ -296,7 +296,7 @@ async function cmdRun(file: string, opts: VerbOpts): Promise<void> {
|
||||
let output = requireOutput(opts);
|
||||
setConfig(loadConfig(opts.config));
|
||||
let specs = await importDeploys([file]);
|
||||
process.exitCode = await buildThen(getDecls(), opts, false, async () => {
|
||||
process.exitCode = await buildThen(artifact.getDecls(), opts, false, async () => {
|
||||
let aq = await runFinish(finishOf(specs, file), Boolean(opts.verbose));
|
||||
if (aq === null) {
|
||||
return 1;
|
||||
@@ -306,7 +306,7 @@ async function cmdRun(file: string, opts: VerbOpts): Promise<void> {
|
||||
});
|
||||
}
|
||||
|
||||
function slugOf(decl: RuleDecl): string {
|
||||
function slugOf(decl: artifact.RuleDecl): string {
|
||||
let template = decl.displayTemplate ?? decl.cmds[0]!;
|
||||
let slug = template.replace(/%[a-zA-Z0-9]+/g, ' ')
|
||||
.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
|
||||
@@ -327,8 +327,8 @@ async function cmdInspect(paths: string[], opts: VerbOpts): Promise<void> {
|
||||
return target;
|
||||
});
|
||||
|
||||
let closure = new Set<RuleDecl>();
|
||||
for (let decl of getDecls()) {
|
||||
let closure = new Set<artifact.RuleDecl>();
|
||||
for (let decl of artifact.getDecls()) {
|
||||
let hit = [...decl.inputs, ...decl.deps].some(i => typeof i === 'string'
|
||||
&& targets.some(t => i === t || i.startsWith(t + '/')));
|
||||
if (hit) {
|
||||
@@ -342,7 +342,7 @@ async function cmdInspect(paths: string[], opts: VerbOpts): Promise<void> {
|
||||
// executor pulls in any producers the closure needs on its own.
|
||||
for (let grew = true; grew;) {
|
||||
grew = false;
|
||||
for (let decl of getDecls()) {
|
||||
for (let decl of artifact.getDecls()) {
|
||||
if (closure.has(decl)) {
|
||||
continue;
|
||||
}
|
||||
@@ -353,7 +353,7 @@ async function cmdInspect(paths: string[], opts: VerbOpts): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
let decls = getDecls().filter(d => closure.has(d));
|
||||
let decls = artifact.getDecls().filter(d => closure.has(d));
|
||||
console.log(`inspect: ${decls.length} rules`);
|
||||
process.exitCode = await buildThen(decls, opts, false, async () => {
|
||||
for (let decl of decls) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
import pathlib from 'path';
|
||||
import * as pathlib from 'node:path';
|
||||
|
||||
// Slight variation of pathlib parse, less fields, different ext handling
|
||||
export type Path = {dir: string, name: string, ext: string | null};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
import fs from 'fs';
|
||||
import nodePath from 'path';
|
||||
import * as fs from 'node:fs';
|
||||
import * as nodePath from 'node:path';
|
||||
import tar from 'tar-stream';
|
||||
|
||||
type Op = {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
|
||||
import assert from 'node:assert/strict';
|
||||
import {createHash} from 'node:crypto';
|
||||
import fs from 'node:fs';
|
||||
import os from 'node:os';
|
||||
import pathlib from 'node:path';
|
||||
import * as fs from 'node:fs';
|
||||
import * as os from 'node:os';
|
||||
import * as pathlib from 'node:path';
|
||||
import {beforeEach, test} from 'node:test';
|
||||
|
||||
import b32encode from 'base32-encode';
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
import assert from 'node:assert/strict';
|
||||
import fs from 'node:fs';
|
||||
import os from 'node:os';
|
||||
import pathlib from 'node:path';
|
||||
import * as fs from 'node:fs';
|
||||
import * as os from 'node:os';
|
||||
import * as pathlib from 'node:path';
|
||||
import {test} from 'node:test';
|
||||
|
||||
import {loadDeployConfig, matchSubsets} from '../config.ts';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
import cp from 'child_process';
|
||||
import path from 'path';
|
||||
import * as cp from 'node:child_process';
|
||||
import * as path from 'node:path';
|
||||
|
||||
let sheetjs = process.argv[2];
|
||||
let dest = process.argv[3];
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
import spritesmith from 'spritesmith'
|
||||
import path from 'path'
|
||||
import fs from 'fs'
|
||||
import util from 'util';
|
||||
import * as path from 'node:path';
|
||||
import * as fs from 'node:fs';
|
||||
import * as util from 'node:util';
|
||||
import * as spritedata from '@smogon/sprite-data/index.ts';
|
||||
|
||||
let {values: opts, positionals: srcs} = util.parseArgs({
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
import cp from 'child_process';
|
||||
import * as cp from 'node:child_process';
|
||||
|
||||
export function getDims(input: string) {
|
||||
let info = cp.execFileSync('magick', ['convert', input, '-format', '%w+%h+%@', 'info:'],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
import {parseArgs} from 'util';
|
||||
import {parseArgs} from 'node:util';
|
||||
|
||||
import * as image from './image.ts';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user