@patterkit/cli 0.9.2 → 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.
Files changed (2) hide show
  1. package/dist/cli.js +79 -62
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -247165,8 +247165,8 @@ function planEditableImport(loaded, returned, opts) {
247165
247165
  const { text: proposedRaw, notes } = takeNotes(b.rowDeleted ? "" : b.text.proposed, sent.baseline);
247166
247166
  const proposed = tidy(proposedRaw);
247167
247167
  const textChanged = normalise(proposed, !!opts.strictQuotes) !== normalise(sent.baseline, !!opts.strictQuotes);
247168
- const tracked = b.text.changes.length > 0;
247169
- if (tracked && normalise(b.text.original, !!opts.strictQuotes) !== normalise(sent.baseline, !!opts.strictQuotes)) {
247168
+ const tracked2 = b.text.changes.length > 0;
247169
+ if (tracked2 && normalise(b.text.original, !!opts.strictQuotes) !== normalise(sent.baseline, !!opts.strictQuotes)) {
247170
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." });
247171
247171
  }
247172
247172
  const cue = sent.kind === "line" ? readLead(b.lead.proposed) : void 0;
@@ -248613,15 +248613,61 @@ function cmAsync(args) {
248613
248613
  return runCommandAsync("cm", args);
248614
248614
  }
248615
248615
  function isTracked$1(filePath) {
248616
- return trackedFromShortStatus(cm(["status", "--short", filePath]));
248616
+ return tracked(localState(filePath));
248617
248617
  }
248618
248618
  async function isTrackedAsync$1(filePath) {
248619
- return trackedFromShortStatus(await cmAsync(["status", "--short", filePath]));
248619
+ return tracked(await localStateAsync(filePath));
248620
248620
  }
248621
- function trackedFromShortStatus(result) {
248622
- if (result.exitCode !== 0) return false;
248623
- const lines = result.output.split("\n").filter((l2) => l2.trim());
248624
- return lines.length > 0 && !lines[0].startsWith("?");
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}`);
248625
248671
  }
248626
248672
  function undoCheckoutResult(filePath, result) {
248627
248673
  if (result.exitCode === 0) return okResult("Checkout undone in Plastic SCM");
@@ -248641,67 +248687,36 @@ var PlasticProvider = class {
248641
248687
  const u = await plasticWhoamiAsync();
248642
248688
  return u === "" ? void 0 : u;
248643
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
+ */
248644
248696
  prepareToWrite(filePath) {
248645
248697
  if (!existsSync7(filePath)) return okResult();
248646
- if (!isTracked$1(filePath)) {
248647
- return fs$1.prepareToWrite(filePath);
248648
- }
248649
- const result = cm(["co", filePath]);
248650
- if (result.exitCode === 0) return okResult();
248651
- const combined = (result.output + " " + result.error).toLowerCase();
248652
- if (combined.includes("locked") || combined.includes("exclusive")) {
248653
- return errorResult("locked", `'${filePath}' is locked`);
248654
- }
248655
- if (combined.includes("out of date") || combined.includes("not latest")) {
248656
- return errorResult("outOfDate", `'${filePath}' is out of date \u2014 update before editing`);
248657
- }
248658
- 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]));
248659
248700
  }
248701
+ /** Add a new private file to Plastic SCM after it is written. */
248660
248702
  finishedWrite(filePath) {
248661
248703
  if (!existsSync7(filePath))
248662
248704
  return errorResult("error", `'${filePath}' does not exist after write`);
248663
- const statusResult = cm(["status", "--short", filePath]);
248664
- if (statusResult.exitCode !== 0)
248665
- return fs$1.finishedWrite(filePath);
248666
- const lines = statusResult.output.split("\n").filter((l2) => l2.trim());
248667
- const tracked = lines.length > 0 && !lines[0].startsWith("?");
248668
- if (tracked) return okResult();
248669
- const result = cm(["add", filePath]);
248670
- if (result.exitCode === 0) return okResult("File added to Plastic SCM");
248671
- const combined = (result.output + " " + result.error).toLowerCase();
248672
- if (combined.includes("ignored")) return fs$1.finishedWrite(filePath);
248673
- 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]));
248674
248707
  }
248675
248708
  /** Async twin of {@link prepareToWrite}. */
248676
248709
  async prepareToWriteAsync(filePath) {
248677
248710
  if (!existsSync7(filePath)) return okResult();
248678
- if (!await isTrackedAsync$1(filePath)) {
248679
- return fs$1.prepareToWriteAsync(filePath);
248680
- }
248681
- const result = await cmAsync(["co", filePath]);
248682
- if (result.exitCode === 0) return okResult();
248683
- const combined = (result.output + " " + result.error).toLowerCase();
248684
- if (combined.includes("locked") || combined.includes("exclusive")) {
248685
- return errorResult("locked", `'${filePath}' is locked`);
248686
- }
248687
- if (combined.includes("out of date") || combined.includes("not latest")) {
248688
- return errorResult("outOfDate", `'${filePath}' is out of date \u2014 update before editing`);
248689
- }
248690
- 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]));
248691
248713
  }
248692
248714
  /** Async twin of {@link finishedWrite}. */
248693
248715
  async finishedWriteAsync(filePath) {
248694
248716
  if (!existsSync7(filePath))
248695
248717
  return errorResult("error", `'${filePath}' does not exist after write`);
248696
- const statusResult = await cmAsync(["status", "--short", filePath]);
248697
- if (statusResult.exitCode !== 0)
248698
- return fs$1.finishedWriteAsync(filePath);
248699
- if (trackedFromShortStatus(statusResult)) return okResult();
248700
- const result = await cmAsync(["add", filePath]);
248701
- if (result.exitCode === 0) return okResult("File added to Plastic SCM");
248702
- const combined = (result.output + " " + result.error).toLowerCase();
248703
- if (combined.includes("ignored")) return fs$1.finishedWriteAsync(filePath);
248704
- 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]));
248705
248720
  }
248706
248721
  /**
248707
248722
  * Undo what {@link prepareToWrite} did, for an all-or-nothing batch that has to back
@@ -248877,7 +248892,7 @@ function buildPlasticBase(result, filePaths) {
248877
248892
  if (!parsed) continue;
248878
248893
  for (const p of parsed.paths) {
248879
248894
  const abs = resolve8(p);
248880
- byPath.set(abs, parsed.info);
248895
+ byPath.set(pathKey(abs), parsed.info);
248881
248896
  const base = basename7(abs);
248882
248897
  if (!byBase.has(base)) byBase.set(base, []);
248883
248898
  byBase.get(base).push(parsed.info);
@@ -248887,7 +248902,7 @@ function buildPlasticBase(result, filePaths) {
248887
248902
  return filePaths.map((filePath) => {
248888
248903
  const abs = resolve8(filePath);
248889
248904
  const status = { filePath: abs, system: "plastic", writable: writableBit(abs) };
248890
- let info = byPath.get(abs);
248905
+ let info = byPath.get(pathKey(abs));
248891
248906
  if (!info) {
248892
248907
  const sameName = byBase.get(basename7(abs));
248893
248908
  if (sameName && sameName.length === 1) info = sameName[0];
@@ -248961,18 +248976,20 @@ var PLASTIC_DIRTY_CODES = /* @__PURE__ */ new Set([
248961
248976
  "LM"
248962
248977
  ]);
248963
248978
  var PLASTIC_UNTRACKED_CODES = /* @__PURE__ */ new Set(["PR", "IG"]);
248979
+ var PLASTIC_CHECKED_OUT_CODES = /* @__PURE__ */ new Set(["CO", "AD", "CP", "RP", "MV"]);
248964
248980
  function parseCmStatusLine(line2) {
248965
248981
  const trimmed = line2.trim();
248966
248982
  const space = trimmed.indexOf(" ");
248967
248983
  if (space === -1) return null;
248968
- const code = trimmed.slice(0, space);
248969
- const dirty = PLASTIC_DIRTY_CODES.has(code);
248970
- const untracked = PLASTIC_UNTRACKED_CODES.has(code);
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));
248971
248987
  if (!dirty && !untracked) return null;
248972
248988
  const rest = trimmed.slice(space + 1).trim();
248973
248989
  const quoted = [...rest.matchAll(/"([^"]*)"/g)].map((m) => m[1]);
248974
248990
  const paths = quoted.length > 0 ? quoted : [rest];
248975
- return { info: { tracked: !untracked, dirty }, paths };
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 };
248976
248993
  }
248977
248994
  var fs3 = new FilesystemProvider();
248978
248995
  function svn(args) {
@@ -249544,7 +249561,7 @@ function fileStatus(filePaths, options = {}) {
249544
249561
  // package.json
249545
249562
  var package_default = {
249546
249563
  name: "@patterkit/cli",
249547
- version: "0.9.2",
249564
+ version: "0.9.3",
249548
249565
  description: "The `patter` CLI: validate, format, export, play, test coverage, localise, and merge Patter projects.",
249549
249566
  type: "module",
249550
249567
  license: "MIT",
@@ -249575,7 +249592,7 @@ var package_default = {
249575
249592
  dependencies: {
249576
249593
  "@patterkit/core": "0.4.1",
249577
249594
  "@patterkit/ops": "0.14.2",
249578
- "@wildwinter/simple-vc-lib": "^0.5.0"
249595
+ "@wildwinter/simple-vc-lib": "^0.5.1"
249579
249596
  }
249580
249597
  };
249581
249598
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patterkit/cli",
3
- "version": "0.9.2",
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",
@@ -31,6 +31,6 @@
31
31
  "dependencies": {
32
32
  "@patterkit/core": "0.4.1",
33
33
  "@patterkit/ops": "0.14.2",
34
- "@wildwinter/simple-vc-lib": "^0.5.0"
34
+ "@wildwinter/simple-vc-lib": "^0.5.1"
35
35
  }
36
36
  }