@spardutti/claude-skills 2.25.1 → 2.25.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/bin/cli.mjs +7 -3
- package/lib/scaffold-stryker.mjs +16 -4
- package/lib/setup-hook.mjs +10 -1
- package/package.json +1 -1
package/bin/cli.mjs
CHANGED
|
@@ -273,6 +273,7 @@ async function main() {
|
|
|
273
273
|
});
|
|
274
274
|
if (doScaffold) {
|
|
275
275
|
const installs = [];
|
|
276
|
+
const apiInstalls = [];
|
|
276
277
|
const vitest = [];
|
|
277
278
|
for (const n of stryker) {
|
|
278
279
|
const r = await scaffoldStryker(CWD, n.rel);
|
|
@@ -284,7 +285,9 @@ async function main() {
|
|
|
284
285
|
}
|
|
285
286
|
// A project that already runs Stryker needs neither the install nor
|
|
286
287
|
// the vitest exclude repeated at it; it only lacked the ignorer.
|
|
287
|
-
if (
|
|
288
|
+
if (n.ignorerOnly) {
|
|
289
|
+
apiInstalls.push(r.apiInstall);
|
|
290
|
+
} else {
|
|
288
291
|
installs.push(r.install);
|
|
289
292
|
vitest.push(r.vitest);
|
|
290
293
|
}
|
|
@@ -300,9 +303,10 @@ async function main() {
|
|
|
300
303
|
// The ignorer imports @stryker-mutator/api, which npm hoists by
|
|
301
304
|
// accident and pnpm does not. Missing, it prints one WARN PluginLoader
|
|
302
305
|
// line, loads nothing, and every className mutant comes back survived.
|
|
303
|
-
if (
|
|
306
|
+
if (apiInstalls.length > 0) {
|
|
304
307
|
console.log(`\n ${chalk.yellow("!")} ${chalk.bold("The ignorer needs its own dependency:")}`);
|
|
305
|
-
console.log(` ${chalk.cyan(
|
|
308
|
+
for (const c of apiInstalls) console.log(` ${chalk.cyan(c)}`);
|
|
309
|
+
console.log(` ${chalk.dim("without it the ignorer silently does not load")}`);
|
|
306
310
|
}
|
|
307
311
|
}
|
|
308
312
|
}
|
package/lib/scaffold-stryker.mjs
CHANGED
|
@@ -78,9 +78,11 @@ async function exists(p) {
|
|
|
78
78
|
// npm's flat node_modules hoists it so the import resolves by accident, and
|
|
79
79
|
// pnpm's isolated store does not. The failure is one WARN PluginLoader line and
|
|
80
80
|
// an ignorer that never loads, so every class-name mutant comes back survived.
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
// A workspace keeps its lockfile at the root, not in apps/web, so asking only
|
|
82
|
+
// the sub-project hands a pnpm monorepo an npm command.
|
|
83
|
+
async function installCommand(projectDir, dir, rel, pkgs) {
|
|
84
|
+
const pnpm =
|
|
85
|
+
(await exists(join(projectDir, "pnpm-lock.yaml"))) || (await exists(join(dir, "pnpm-lock.yaml")));
|
|
84
86
|
return pnpm
|
|
85
87
|
? `pnpm --dir ${rel || "."} add -D ${pkgs}`
|
|
86
88
|
: `npm --prefix ${rel || "."} i -D ${pkgs}`;
|
|
@@ -185,7 +187,17 @@ export async function scaffoldStryker(projectDir, rel) {
|
|
|
185
187
|
kept,
|
|
186
188
|
patched,
|
|
187
189
|
unreadable,
|
|
188
|
-
install: await installCommand(
|
|
190
|
+
install: await installCommand(
|
|
191
|
+
projectDir,
|
|
192
|
+
dir,
|
|
193
|
+
rel,
|
|
194
|
+
"@stryker-mutator/core @stryker-mutator/vitest-runner @stryker-mutator/api",
|
|
195
|
+
),
|
|
196
|
+
// A project that already runs Stryker has the other two packages and needs
|
|
197
|
+
// only this one, which nothing depends on directly. Printed as a command
|
|
198
|
+
// rather than a sentence: the sentence made every reader guess their own
|
|
199
|
+
// package manager and path.
|
|
200
|
+
apiInstall: await installCommand(projectDir, dir, rel, "@stryker-mutator/api"),
|
|
189
201
|
// Stryker copies the whole project into .stryker-tmp/sandbox-*/, so every
|
|
190
202
|
// test file briefly exists twice and the runner collects both. They pass,
|
|
191
203
|
// so a doubled test count is the only symptom. Spread configDefaults.exclude
|
package/lib/setup-hook.mjs
CHANGED
|
@@ -685,6 +685,15 @@ CHANGED=$( { git diff "$BASE"...HEAD --name-only 2>/dev/null
|
|
|
685
685
|
git diff HEAD --name-only 2>/dev/null
|
|
686
686
|
git ls-files --others --exclude-standard 2>/dev/null; } | sort -u )
|
|
687
687
|
|
|
688
|
+
# Only the files this gate can actually read go into the key. It used to be every
|
|
689
|
+
# changed file, so a version bump in package.json or a line in a changelog threw
|
|
690
|
+
# away a receipt the gate would have re-earned unchanged — fifteen minutes of
|
|
691
|
+
# mutation testing to prove nothing about the file that moved, at the one moment
|
|
692
|
+
# a release is trying to ship. An ignored extension is one no check here opens,
|
|
693
|
+
# so it cannot change a verdict. Unknown extensions stay in, because UNPROVEN is
|
|
694
|
+
# a verdict about exactly those.
|
|
695
|
+
KEYED=$(printf '%s\\n' "$CHANGED" | grep -viE "\\.($GAUNTLET_IGNORE_EXT)$")
|
|
696
|
+
|
|
688
697
|
# The repo path plus the names and contents of the changed files, in a fixed
|
|
689
698
|
# order. The path is in there because the key is otherwise pure content: two
|
|
690
699
|
# repos holding the same file would share a receipt, and one would be waved
|
|
@@ -693,7 +702,7 @@ CHANGED=$( { git diff "$BASE"...HEAD --name-only 2>/dev/null
|
|
|
693
702
|
# the moment it was committed. This is identical either side of a commit, and
|
|
694
703
|
# changes the instant any of those files is edited.
|
|
695
704
|
RECEIPT_KEY=$( { printf '%s\\n' "$PROJECT_DIR"
|
|
696
|
-
printf '%s\\n' "$
|
|
705
|
+
printf '%s\\n' "$KEYED" | while IFS= read -r f; do
|
|
697
706
|
[ -n "$f" ] || continue
|
|
698
707
|
printf '%s\\n' "$f"
|
|
699
708
|
[ -f "$f" ] && cat "$f"
|