@mutmutco/cli 4.2.3 → 4.2.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.
Files changed (2) hide show
  1. package/dist/main.cjs +32 -14
  2. package/package.json +1 -1
package/dist/main.cjs CHANGED
@@ -11802,10 +11802,10 @@ var rollout_plan_default = {
11802
11802
  note: "The v4.0.0 stamp happens at cut time (D6e #4463); until then the candidate is the origin/development head artifacts (built cli/dist + npm pack), identity proven by dist content hash (D6a)."
11803
11803
  },
11804
11804
  baseline: {
11805
- version: "4.2.3",
11806
- tag: "v4.2.3",
11807
- commit: "a54078f2ac92",
11808
- npm: "@mutmutco/cli@4.2.3"
11805
+ version: "4.2.5",
11806
+ tag: "v4.2.5",
11807
+ commit: "258de06d0766",
11808
+ npm: "@mutmutco/cli@4.2.5"
11809
11809
  },
11810
11810
  exitCriterion: "fleet-n-of-n",
11811
11811
  hubOnlyShortcut: "forbidden",
@@ -11822,14 +11822,14 @@ var rollout_plan_default = {
11822
11822
  repo: "mutmutco/mmi-hub",
11823
11823
  role: "canary",
11824
11824
  schedule: "train",
11825
- v3Target: "v4.2.3"
11825
+ v3Target: "v4.2.5"
11826
11826
  }
11827
11827
  ],
11828
11828
  rollbackTrigger: "Any red inside the post-contract soak window: `devops train gate` FAIL attributable to the v4 doors, Hub endpoint health probe failure, a pre-v4 client admitted instead of receiving actionable HTTP 426, or npm consumer install/doctor failure on the v4-only dist.",
11829
11829
  rollback: {
11830
11830
  independent: true,
11831
- mechanism: "npm dist-tag latest -> 4.2.3 and redeploy the Hub Lambda from tag v4.2.3 (a54078f2ac92); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
11832
- v3Target: "v4.2.3 (@mutmutco/cli@4.2.3, tag commit a54078f2ac92 \u2014 last known-good release carrying the repo-index v4-only contract)"
11831
+ mechanism: "npm dist-tag latest -> 4.2.5 and redeploy the Hub Lambda from tag v4.2.5 (258de06d0766); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
11832
+ v3Target: "v4.2.5 (@mutmutco/cli@4.2.5, tag commit 258de06d0766 \u2014 last known-good release carrying the repo-index v4-only contract)"
11833
11833
  }
11834
11834
  },
11835
11835
  {
@@ -25163,6 +25163,16 @@ var WAIVABLE_KINDS = [
25163
25163
  "stale-satisfied-by"
25164
25164
  ];
25165
25165
  var TEST_WORK_KIND = "unrequested-test-file";
25166
+ var TEST_FILE_RE = /\.(?:test|spec)\.[cm]?[jt]sx?$/;
25167
+ var PY_TEST_FILE_RE = /(?:^|\/)test_[^/]*\.py$|_test\.py$/;
25168
+ function isTestPath(path2) {
25169
+ return typeof path2 === "string" && (TEST_FILE_RE.test(path2) || PY_TEST_FILE_RE.test(path2));
25170
+ }
25171
+ function editsExistingTest(paths, addedPaths = []) {
25172
+ const added = new Set(Array.isArray(addedPaths) ? addedPaths : []);
25173
+ const list = Array.isArray(paths) ? paths : [];
25174
+ return list.some((path2) => isTestPath(path2) && !added.has(path2));
25175
+ }
25166
25176
  function translateGlob(glob) {
25167
25177
  let out = "";
25168
25178
  for (let i = 0; i < glob.length; i += 1) {
@@ -25205,7 +25215,7 @@ function matchedMandatoryGlobs(paths, mandatory) {
25205
25215
  return list.some((path2) => re.test(path2));
25206
25216
  });
25207
25217
  }
25208
- function evaluateTestCommandPolicy({ paths, mandatory, regulated = true, override = null } = {}) {
25218
+ function evaluateTestCommandPolicy({ paths, mandatory, regulated = true, override = null, addedPaths = [] } = {}) {
25209
25219
  const configuredMandatoryCount = mandatoryGlobList(mandatory).length;
25210
25220
  if (!regulated) {
25211
25221
  return {
@@ -25213,18 +25223,23 @@ function evaluateTestCommandPolicy({ paths, mandatory, regulated = true, overrid
25213
25223
  matchedMandatoryGlobs: [],
25214
25224
  matchedMandatoryCount: 0,
25215
25225
  testCommandsAllowed: true,
25226
+ editsExistingTest: false,
25216
25227
  reasonId: null,
25217
25228
  commandClasses: { allowed: [TEST_COMMAND_CLASS], refused: [] }
25218
25229
  };
25219
25230
  }
25220
25231
  const matched = matchedMandatoryGlobs(paths, mandatory);
25221
25232
  const overrideAuthorizes = Array.isArray(override?.kinds) && override.kinds.includes(TEST_WORK_KIND);
25222
- const testCommandsAllowed = matched.length > 0 || overrideAuthorizes;
25233
+ const existingTestEdited = editsExistingTest(paths, addedPaths);
25234
+ const testCommandsAllowed = matched.length > 0 || overrideAuthorizes || existingTestEdited;
25223
25235
  return {
25224
25236
  configuredMandatoryCount,
25225
25237
  matchedMandatoryGlobs: matched,
25226
25238
  matchedMandatoryCount: matched.length,
25227
25239
  testCommandsAllowed,
25240
+ /** #5842: true when the diff edits a test file that already existed — one of the facts that can
25241
+ * authorize the class, named so a refusal can say what was missing. */
25242
+ editsExistingTest: existingTestEdited,
25228
25243
  reasonId: testCommandsAllowed ? null : "test-command-outside-mandatory-zone",
25229
25244
  commandClasses: {
25230
25245
  allowed: testCommandsAllowed ? [TEST_COMMAND_CLASS] : [],
@@ -25302,8 +25317,8 @@ function readOverride(base, cwd) {
25302
25317
 
25303
25318
  // src/test-policy-core.ts
25304
25319
  var POLICY_FILE = "test-policy.json";
25305
- var TEST_RE = /\.(?:test|spec)\.[cm]?[jt]sx?$/;
25306
- var PY_TEST_RE = /(?:^|\/)test_[^/]*\.py$|_test\.py$/;
25320
+ var TEST_RE = TEST_FILE_RE;
25321
+ var PY_TEST_RE = PY_TEST_FILE_RE;
25307
25322
  function translate(glob) {
25308
25323
  let out = "";
25309
25324
  for (let i = 0; i < glob.length; i++) {
@@ -25338,7 +25353,7 @@ function translate(glob) {
25338
25353
  function globToRegExp2(glob) {
25339
25354
  return new RegExp(`^${translate(glob)}$`);
25340
25355
  }
25341
- function isTestPath(path2) {
25356
+ function isTestPath2(path2) {
25342
25357
  return TEST_RE.test(path2) || PY_TEST_RE.test(path2);
25343
25358
  }
25344
25359
  var SUPPORTED_SOURCE = /\.[cm]?[jt]s$/;
@@ -25572,7 +25587,7 @@ function annotateChangeMeaning(changed, policy, read) {
25572
25587
  const matchers = (policy.mandatory ?? []).map((m) => globToRegExp2(m.glob));
25573
25588
  return changed.map((file) => {
25574
25589
  if (file.status !== "M" || !SUPPORTED_SOURCE.test(file.path)) return file;
25575
- if (!matchers.some((re) => re.test(file.path)) && !isTestPath(file.path)) return file;
25590
+ if (!matchers.some((re) => re.test(file.path)) && !isTestPath2(file.path)) return file;
25576
25591
  let pair;
25577
25592
  try {
25578
25593
  pair = read(file.path);
@@ -25609,7 +25624,7 @@ function removedPaths(changed) {
25609
25624
  function classify(changed, policy, present = () => false) {
25610
25625
  const matchers = (policy.mandatory ?? []).map((m) => ({ ...m, re: globToRegExp2(m.glob) }));
25611
25626
  const mandatoryHits = changed.filter((f) => matchers.some((m) => m.re.test(f.path)));
25612
- const testChanges = changed.filter((f) => isTestPath(f.path));
25627
+ const testChanges = changed.filter((f) => isTestPath2(f.path));
25613
25628
  const addedTests = testChanges.filter((f) => f.status === "A");
25614
25629
  const removed = removedPaths(changed);
25615
25630
  const discharged = (m) => (m.satisfiedBy?.length ?? 0) > 0 && m.satisfiedBy.every((p) => present(p) && !removed.has(p));
@@ -25798,6 +25813,9 @@ function runTestPolicy(root, deps = {}) {
25798
25813
  const findings = blocking.length > 0 ? blocking : sift(evaluate(changed, policy, present));
25799
25814
  const commandPolicy = evaluateTestCommandPolicy({
25800
25815
  paths: changed.map((f) => f.path),
25816
+ // #5842: `A` is added, `R` is a rename whose new name did not exist at the base either. Both are
25817
+ // test work this diff CREATED, which only a waiver may authorize (#5804).
25818
+ addedPaths: changed.filter((f) => f.status === "A" || f.status === "R").map((f) => f.path),
25801
25819
  mandatory: policy.mandatory,
25802
25820
  regulated: policy.declared !== false,
25803
25821
  override: override && lookup.refusals.length === 0 ? { kinds: override.kinds } : null
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mutmutco/cli",
3
- "version": "4.2.3",
3
+ "version": "4.2.5",
4
4
  "description": "MMI Future CLI — the org dev toolbox and shared cross-IDE engine for every registry-declared MMI coding surface.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",