@patterkit/cli 0.9.1 → 0.9.3
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/dist/cli.js +84 -66
- package/package.json +4 -4
package/dist/cli.js
CHANGED
|
@@ -198054,6 +198054,7 @@ function validateProject(input) {
|
|
|
198054
198054
|
}
|
|
198055
198055
|
}
|
|
198056
198056
|
};
|
|
198057
|
+
const addressOf = (node) => effectiveGameId({ gameId: node.gameId, name: typeof node.name === "string" ? node.name : "" });
|
|
198057
198058
|
const seeId = (id, kind, where) => {
|
|
198058
198059
|
if (typeof id !== "string" || id.length === 0) {
|
|
198059
198060
|
issues.push({ code: "missing-id", message: `${kind} in ${where} has no id` });
|
|
@@ -198078,7 +198079,7 @@ function validateProject(input) {
|
|
|
198078
198079
|
if (scene.gameId && !isValidGameId(scene.gameId)) {
|
|
198079
198080
|
issues.push({ code: "invalid-gameid", message: `${where} address '${scene.gameId}' is invalid (lowercase letters, digits, hyphens; no leading/trailing hyphen)`, id: scene.id });
|
|
198080
198081
|
}
|
|
198081
|
-
const sgid =
|
|
198082
|
+
const sgid = addressOf(scene);
|
|
198082
198083
|
if (sgid) {
|
|
198083
198084
|
const prev = sceneGameIds.get(sgid);
|
|
198084
198085
|
if (prev && prev !== scene.id) issues.push({ code: "duplicate-gameid", message: `${where} address '${sgid}' is already used by scene '${prev}'`, id: scene.id });
|
|
@@ -198113,7 +198114,7 @@ function validateProject(input) {
|
|
|
198113
198114
|
if (block.gameId && !isValidGameId(block.gameId)) {
|
|
198114
198115
|
issues.push({ code: "invalid-gameid", message: `block '${block.id}' address '${block.gameId}' is invalid (lowercase letters, digits, hyphens; no leading/trailing hyphen)`, id: block.id });
|
|
198115
198116
|
}
|
|
198116
|
-
const bgid =
|
|
198117
|
+
const bgid = addressOf(block);
|
|
198117
198118
|
if (bgid) {
|
|
198118
198119
|
const prev = blockGameIds.get(bgid);
|
|
198119
198120
|
if (prev && prev !== block.id) issues.push({ code: "duplicate-gameid", message: `block '${block.id}' address '${bgid}' is already used by block '${prev}' in ${where}`, id: block.id });
|
|
@@ -247164,8 +247165,8 @@ function planEditableImport(loaded, returned, opts) {
|
|
|
247164
247165
|
const { text: proposedRaw, notes } = takeNotes(b.rowDeleted ? "" : b.text.proposed, sent.baseline);
|
|
247165
247166
|
const proposed = tidy(proposedRaw);
|
|
247166
247167
|
const textChanged = normalise(proposed, !!opts.strictQuotes) !== normalise(sent.baseline, !!opts.strictQuotes);
|
|
247167
|
-
const
|
|
247168
|
-
if (
|
|
247168
|
+
const tracked2 = b.text.changes.length > 0;
|
|
247169
|
+
if (tracked2 && normalise(b.text.original, !!opts.strictQuotes) !== normalise(sent.baseline, !!opts.strictQuotes)) {
|
|
247169
247170
|
problems.push({ severity: "info", kind: "untracked-edits", marker: code, anchor: sent.id, message: "This line has tracked changes and some untracked ones too, so the credit may be incomplete." });
|
|
247170
247171
|
}
|
|
247171
247172
|
const cue = sent.kind === "line" ? readLead(b.lead.proposed) : void 0;
|
|
@@ -248612,15 +248613,61 @@ function cmAsync(args) {
|
|
|
248612
248613
|
return runCommandAsync("cm", args);
|
|
248613
248614
|
}
|
|
248614
248615
|
function isTracked$1(filePath) {
|
|
248615
|
-
return
|
|
248616
|
+
return tracked(localState(filePath));
|
|
248616
248617
|
}
|
|
248617
248618
|
async function isTrackedAsync$1(filePath) {
|
|
248618
|
-
return
|
|
248619
|
+
return tracked(await localStateAsync(filePath));
|
|
248619
248620
|
}
|
|
248620
|
-
function
|
|
248621
|
-
|
|
248622
|
-
|
|
248623
|
-
|
|
248621
|
+
function tracked(state) {
|
|
248622
|
+
return state === "controlled" || state === "checkedOut";
|
|
248623
|
+
}
|
|
248624
|
+
function localStateArgs(filePath) {
|
|
248625
|
+
return plasticStatusArgs([filePath]);
|
|
248626
|
+
}
|
|
248627
|
+
function localState(filePath) {
|
|
248628
|
+
return localStateFrom(cm(localStateArgs(filePath)), filePath);
|
|
248629
|
+
}
|
|
248630
|
+
async function localStateAsync(filePath) {
|
|
248631
|
+
return localStateFrom(await cmAsync(localStateArgs(filePath)), filePath);
|
|
248632
|
+
}
|
|
248633
|
+
function localStateFrom(result, filePath) {
|
|
248634
|
+
if (result.exitCode !== 0) return "outside";
|
|
248635
|
+
const info = findStatusInfo(result.output, filePath);
|
|
248636
|
+
if (!info) return "controlled";
|
|
248637
|
+
if (!info.tracked) return info.ignored ? "ignored" : "private";
|
|
248638
|
+
return info.checkedOut ? "checkedOut" : "controlled";
|
|
248639
|
+
}
|
|
248640
|
+
function findStatusInfo(output, filePath) {
|
|
248641
|
+
const key2 = pathKey(filePath);
|
|
248642
|
+
const sameName = [];
|
|
248643
|
+
for (const line2 of output.split("\n")) {
|
|
248644
|
+
const parsed = parseCmStatusLine(line2);
|
|
248645
|
+
if (!parsed) continue;
|
|
248646
|
+
for (const p of parsed.paths) {
|
|
248647
|
+
if (pathKey(p) === key2) return parsed.info;
|
|
248648
|
+
if (basename7(resolve8(p)) === basename7(resolve8(filePath))) sameName.push(parsed.info);
|
|
248649
|
+
}
|
|
248650
|
+
}
|
|
248651
|
+
return sameName.length === 1 ? sameName[0] : void 0;
|
|
248652
|
+
}
|
|
248653
|
+
function pathKey(p) {
|
|
248654
|
+
const abs = resolve8(p);
|
|
248655
|
+
return process.platform === "win32" ? abs.toLowerCase() : abs;
|
|
248656
|
+
}
|
|
248657
|
+
function checkoutResult(filePath, result) {
|
|
248658
|
+
if (result.exitCode === 0) return okResult();
|
|
248659
|
+
const combined = (result.output + " " + result.error).toLowerCase();
|
|
248660
|
+
if (combined.includes("locked") || combined.includes("exclusive")) {
|
|
248661
|
+
return errorResult("locked", `'${filePath}' is locked`);
|
|
248662
|
+
}
|
|
248663
|
+
if (combined.includes("out of date") || combined.includes("not latest")) {
|
|
248664
|
+
return errorResult("outOfDate", `'${filePath}' is out of date \u2014 update before editing`);
|
|
248665
|
+
}
|
|
248666
|
+
return errorResult("error", `Cannot check out '${filePath}': ${result.error || result.output}`);
|
|
248667
|
+
}
|
|
248668
|
+
function addResult(filePath, result) {
|
|
248669
|
+
if (result.exitCode === 0) return okResult("File added to Plastic SCM");
|
|
248670
|
+
return errorResult("error", `Cannot add '${filePath}' to Plastic SCM: ${result.error || result.output}`);
|
|
248624
248671
|
}
|
|
248625
248672
|
function undoCheckoutResult(filePath, result) {
|
|
248626
248673
|
if (result.exitCode === 0) return okResult("Checkout undone in Plastic SCM");
|
|
@@ -248640,67 +248687,36 @@ var PlasticProvider = class {
|
|
|
248640
248687
|
const u = await plasticWhoamiAsync();
|
|
248641
248688
|
return u === "" ? void 0 : u;
|
|
248642
248689
|
}
|
|
248690
|
+
/**
|
|
248691
|
+
* Check a controlled file out before it is written. A file already checked out (or
|
|
248692
|
+
* otherwise pending) in this workspace is not checked out again: a second `cm co` on
|
|
248693
|
+
* it fails, and under lock rules it fails as "locked" by our own checkout. Private,
|
|
248694
|
+
* ignored, and out-of-workspace files only need to be writable.
|
|
248695
|
+
*/
|
|
248643
248696
|
prepareToWrite(filePath) {
|
|
248644
248697
|
if (!existsSync7(filePath)) return okResult();
|
|
248645
|
-
if (
|
|
248646
|
-
|
|
248647
|
-
}
|
|
248648
|
-
const result = cm(["co", filePath]);
|
|
248649
|
-
if (result.exitCode === 0) return okResult();
|
|
248650
|
-
const combined = (result.output + " " + result.error).toLowerCase();
|
|
248651
|
-
if (combined.includes("locked") || combined.includes("exclusive")) {
|
|
248652
|
-
return errorResult("locked", `'${filePath}' is locked`);
|
|
248653
|
-
}
|
|
248654
|
-
if (combined.includes("out of date") || combined.includes("not latest")) {
|
|
248655
|
-
return errorResult("outOfDate", `'${filePath}' is out of date \u2014 update before editing`);
|
|
248656
|
-
}
|
|
248657
|
-
return errorResult("error", `Cannot check out '${filePath}': ${result.error || result.output}`);
|
|
248698
|
+
if (localState(filePath) !== "controlled") return fs$1.prepareToWrite(filePath);
|
|
248699
|
+
return checkoutResult(filePath, cm(["co", filePath]));
|
|
248658
248700
|
}
|
|
248701
|
+
/** Add a new private file to Plastic SCM after it is written. */
|
|
248659
248702
|
finishedWrite(filePath) {
|
|
248660
248703
|
if (!existsSync7(filePath))
|
|
248661
248704
|
return errorResult("error", `'${filePath}' does not exist after write`);
|
|
248662
|
-
|
|
248663
|
-
|
|
248664
|
-
return fs$1.finishedWrite(filePath);
|
|
248665
|
-
const lines = statusResult.output.split("\n").filter((l2) => l2.trim());
|
|
248666
|
-
const tracked = lines.length > 0 && !lines[0].startsWith("?");
|
|
248667
|
-
if (tracked) return okResult();
|
|
248668
|
-
const result = cm(["add", filePath]);
|
|
248669
|
-
if (result.exitCode === 0) return okResult("File added to Plastic SCM");
|
|
248670
|
-
const combined = (result.output + " " + result.error).toLowerCase();
|
|
248671
|
-
if (combined.includes("ignored")) return fs$1.finishedWrite(filePath);
|
|
248672
|
-
return errorResult("error", `Cannot add '${filePath}' to Plastic SCM: ${result.error || result.output}`);
|
|
248705
|
+
if (localState(filePath) !== "private") return fs$1.finishedWrite(filePath);
|
|
248706
|
+
return addResult(filePath, cm(["add", filePath]));
|
|
248673
248707
|
}
|
|
248674
248708
|
/** Async twin of {@link prepareToWrite}. */
|
|
248675
248709
|
async prepareToWriteAsync(filePath) {
|
|
248676
248710
|
if (!existsSync7(filePath)) return okResult();
|
|
248677
|
-
if (
|
|
248678
|
-
|
|
248679
|
-
}
|
|
248680
|
-
const result = await cmAsync(["co", filePath]);
|
|
248681
|
-
if (result.exitCode === 0) return okResult();
|
|
248682
|
-
const combined = (result.output + " " + result.error).toLowerCase();
|
|
248683
|
-
if (combined.includes("locked") || combined.includes("exclusive")) {
|
|
248684
|
-
return errorResult("locked", `'${filePath}' is locked`);
|
|
248685
|
-
}
|
|
248686
|
-
if (combined.includes("out of date") || combined.includes("not latest")) {
|
|
248687
|
-
return errorResult("outOfDate", `'${filePath}' is out of date \u2014 update before editing`);
|
|
248688
|
-
}
|
|
248689
|
-
return errorResult("error", `Cannot check out '${filePath}': ${result.error || result.output}`);
|
|
248711
|
+
if (await localStateAsync(filePath) !== "controlled") return fs$1.prepareToWriteAsync(filePath);
|
|
248712
|
+
return checkoutResult(filePath, await cmAsync(["co", filePath]));
|
|
248690
248713
|
}
|
|
248691
248714
|
/** Async twin of {@link finishedWrite}. */
|
|
248692
248715
|
async finishedWriteAsync(filePath) {
|
|
248693
248716
|
if (!existsSync7(filePath))
|
|
248694
248717
|
return errorResult("error", `'${filePath}' does not exist after write`);
|
|
248695
|
-
|
|
248696
|
-
|
|
248697
|
-
return fs$1.finishedWriteAsync(filePath);
|
|
248698
|
-
if (trackedFromShortStatus(statusResult)) return okResult();
|
|
248699
|
-
const result = await cmAsync(["add", filePath]);
|
|
248700
|
-
if (result.exitCode === 0) return okResult("File added to Plastic SCM");
|
|
248701
|
-
const combined = (result.output + " " + result.error).toLowerCase();
|
|
248702
|
-
if (combined.includes("ignored")) return fs$1.finishedWriteAsync(filePath);
|
|
248703
|
-
return errorResult("error", `Cannot add '${filePath}' to Plastic SCM: ${result.error || result.output}`);
|
|
248718
|
+
if (await localStateAsync(filePath) !== "private") return fs$1.finishedWriteAsync(filePath);
|
|
248719
|
+
return addResult(filePath, await cmAsync(["add", filePath]));
|
|
248704
248720
|
}
|
|
248705
248721
|
/**
|
|
248706
248722
|
* Undo what {@link prepareToWrite} did, for an all-or-nothing batch that has to back
|
|
@@ -248876,7 +248892,7 @@ function buildPlasticBase(result, filePaths) {
|
|
|
248876
248892
|
if (!parsed) continue;
|
|
248877
248893
|
for (const p of parsed.paths) {
|
|
248878
248894
|
const abs = resolve8(p);
|
|
248879
|
-
byPath.set(abs, parsed.info);
|
|
248895
|
+
byPath.set(pathKey(abs), parsed.info);
|
|
248880
248896
|
const base = basename7(abs);
|
|
248881
248897
|
if (!byBase.has(base)) byBase.set(base, []);
|
|
248882
248898
|
byBase.get(base).push(parsed.info);
|
|
@@ -248886,7 +248902,7 @@ function buildPlasticBase(result, filePaths) {
|
|
|
248886
248902
|
return filePaths.map((filePath) => {
|
|
248887
248903
|
const abs = resolve8(filePath);
|
|
248888
248904
|
const status = { filePath: abs, system: "plastic", writable: writableBit(abs) };
|
|
248889
|
-
let info = byPath.get(abs);
|
|
248905
|
+
let info = byPath.get(pathKey(abs));
|
|
248890
248906
|
if (!info) {
|
|
248891
248907
|
const sameName = byBase.get(basename7(abs));
|
|
248892
248908
|
if (sameName && sameName.length === 1) info = sameName[0];
|
|
@@ -248960,18 +248976,20 @@ var PLASTIC_DIRTY_CODES = /* @__PURE__ */ new Set([
|
|
|
248960
248976
|
"LM"
|
|
248961
248977
|
]);
|
|
248962
248978
|
var PLASTIC_UNTRACKED_CODES = /* @__PURE__ */ new Set(["PR", "IG"]);
|
|
248979
|
+
var PLASTIC_CHECKED_OUT_CODES = /* @__PURE__ */ new Set(["CO", "AD", "CP", "RP", "MV"]);
|
|
248963
248980
|
function parseCmStatusLine(line2) {
|
|
248964
248981
|
const trimmed = line2.trim();
|
|
248965
248982
|
const space = trimmed.indexOf(" ");
|
|
248966
248983
|
if (space === -1) return null;
|
|
248967
|
-
const
|
|
248968
|
-
const dirty = PLASTIC_DIRTY_CODES.has(
|
|
248969
|
-
const untracked = PLASTIC_UNTRACKED_CODES.has(
|
|
248984
|
+
const codes = trimmed.slice(0, space).split("+");
|
|
248985
|
+
const dirty = codes.some((c2) => PLASTIC_DIRTY_CODES.has(c2));
|
|
248986
|
+
const untracked = codes.some((c2) => PLASTIC_UNTRACKED_CODES.has(c2));
|
|
248970
248987
|
if (!dirty && !untracked) return null;
|
|
248971
248988
|
const rest = trimmed.slice(space + 1).trim();
|
|
248972
248989
|
const quoted = [...rest.matchAll(/"([^"]*)"/g)].map((m) => m[1]);
|
|
248973
248990
|
const paths = quoted.length > 0 ? quoted : [rest];
|
|
248974
|
-
|
|
248991
|
+
const checkedOut = !untracked && codes.some((c2) => PLASTIC_CHECKED_OUT_CODES.has(c2));
|
|
248992
|
+
return { info: { tracked: !untracked, dirty, checkedOut, ignored: codes.includes("IG") }, paths };
|
|
248975
248993
|
}
|
|
248976
248994
|
var fs3 = new FilesystemProvider();
|
|
248977
248995
|
function svn(args) {
|
|
@@ -249543,7 +249561,7 @@ function fileStatus(filePaths, options = {}) {
|
|
|
249543
249561
|
// package.json
|
|
249544
249562
|
var package_default = {
|
|
249545
249563
|
name: "@patterkit/cli",
|
|
249546
|
-
version: "0.9.
|
|
249564
|
+
version: "0.9.3",
|
|
249547
249565
|
description: "The `patter` CLI: validate, format, export, play, test coverage, localise, and merge Patter projects.",
|
|
249548
249566
|
type: "module",
|
|
249549
249567
|
license: "MIT",
|
|
@@ -249572,9 +249590,9 @@ var package_default = {
|
|
|
249572
249590
|
"build:standalone:others": "node scripts/build-standalone.mjs --targets=linux-x64,linux-arm64,windows-x64"
|
|
249573
249591
|
},
|
|
249574
249592
|
dependencies: {
|
|
249575
|
-
"@patterkit/core": "0.4.
|
|
249576
|
-
"@patterkit/ops": "0.14.
|
|
249577
|
-
"@wildwinter/simple-vc-lib": "^0.5.
|
|
249593
|
+
"@patterkit/core": "0.4.1",
|
|
249594
|
+
"@patterkit/ops": "0.14.2",
|
|
249595
|
+
"@wildwinter/simple-vc-lib": "^0.5.1"
|
|
249578
249596
|
}
|
|
249579
249597
|
};
|
|
249580
249598
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patterkit/cli",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.3",
|
|
4
4
|
"description": "The `patter` CLI: validate, format, export, play, test coverage, localise, and merge Patter projects.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"build:standalone:others": "node scripts/build-standalone.mjs --targets=linux-x64,linux-arm64,windows-x64"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@patterkit/core": "0.4.
|
|
33
|
-
"@patterkit/ops": "0.14.
|
|
34
|
-
"@wildwinter/simple-vc-lib": "^0.5.
|
|
32
|
+
"@patterkit/core": "0.4.1",
|
|
33
|
+
"@patterkit/ops": "0.14.2",
|
|
34
|
+
"@wildwinter/simple-vc-lib": "^0.5.1"
|
|
35
35
|
}
|
|
36
36
|
}
|