@roomi-fields/grillhouse 0.0.0-stage → 0.23.0
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/.claude-plugin/plugin.json +9 -0
- package/METACADRE.md +41 -0
- package/agents/developpeur.md +10 -0
- package/agents/explorateur.md +9 -0
- package/agents/questionneur.md +11 -0
- package/agents/referent-technique.md +9 -0
- package/agents/regulateur.md +11 -0
- package/agents/relecteur.md +9 -0
- package/agents/testwriter.md +10 -0
- package/bin/grillhouse.mjs +125 -0
- package/cadre/templates/projet/.claude/settings.json +30 -0
- package/cadre/templates/projet/.editorconfig +47 -0
- package/cadre/templates/projet/.env.example +57 -0
- package/cadre/templates/projet/.eslintrc.cjs +56 -0
- package/cadre/templates/projet/.github/workflows/ci.yml +66 -0
- package/cadre/templates/projet/.mcp.json +13 -0
- package/cadre/templates/projet/.prettierrc +11 -0
- package/cadre/templates/projet/CHANGELOG.md +61 -0
- package/cadre/templates/projet/CLAUDE.md +46 -0
- package/cadre/templates/projet/CONTRIBUTING.md +243 -0
- package/cadre/templates/projet/CREDITS.md +41 -0
- package/cadre/templates/projet/README.md +152 -0
- package/cadre/templates/projet/_gitignore +91 -0
- package/cadre/templates/projet/_npmignore +46 -0
- package/cadre/templates/projet/deployment/README.md +98 -0
- package/cadre/templates/projet/deployment/docs/01-INSTALL.md +145 -0
- package/cadre/templates/projet/deployment/docs/02-CONFIGURATION.md +117 -0
- package/cadre/templates/projet/deployment/docs/03-API.md +264 -0
- package/cadre/templates/projet/deployment/docs/04-TROUBLESHOOTING.md +262 -0
- package/cadre/templates/projet/deployment/scripts/install.ps1 +100 -0
- package/cadre/templates/projet/deployment/scripts/start.ps1 +61 -0
- package/cadre/templates/projet/deployment/scripts/stop.ps1 +37 -0
- package/cadre/templates/projet/deployment/scripts/test.ps1 +118 -0
- package/cadre/templates/projet/docs/agents/issue-tracker.md +44 -0
- package/cadre/templates/projet/ecosystem.config.cjs +73 -0
- package/cadre/templates/projet/package.json +90 -0
- package/cadre/templates/projet/pitmaster/SUIVI.md +22 -0
- package/cadre/templates/projet/src/config.ts +68 -0
- package/cadre/templates/projet/src/errors.ts +102 -0
- package/cadre/templates/projet/src/index.ts +46 -0
- package/cadre/templates/projet/src/services/.gitkeep +8 -0
- package/cadre/templates/projet/src/types/index.ts +24 -0
- package/cadre/templates/projet/src/utils/logger.ts +106 -0
- package/cadre/templates/projet/tests/integration/.gitkeep +7 -0
- package/cadre/templates/projet/tests/unit/config.spec.ts +68 -0
- package/cadre/templates/projet/tests/unit/errors.spec.ts +132 -0
- package/cadre/templates/projet/tests/unit/types.spec.ts +73 -0
- package/cadre/templates/projet/tsconfig.eslint.json +9 -0
- package/cadre/templates/projet/tsconfig.json +41 -0
- package/cadre/templates/projet/tsdoc.json +6 -0
- package/cadre/templates/projet/vitest.config.ts +44 -0
- package/cadre/templates/turbo/paquets.json +29 -0
- package/cadre/templates/turbo/sans-paquets.json +28 -0
- package/charte.md +107 -0
- package/docs/ARCHITECTURE.md +90 -0
- package/hooks/crochet.mjs +33 -0
- package/hooks/hooks.json +58 -0
- package/hooks/register.tsx +558 -0
- package/package.json +75 -4
- package/scripts/avancement.mjs +244 -0
- package/scripts/bilan.mjs +523 -0
- package/scripts/branche-de-nuit.mjs +59 -0
- package/scripts/cadre.mjs +109 -0
- package/scripts/circuit.mjs +4375 -0
- package/scripts/code-mort.mjs +371 -0
- package/scripts/composants-affectes.mjs +598 -0
- package/scripts/consommateurs-arbitres.mjs +192 -0
- package/scripts/consommateurs.mjs +310 -0
- package/scripts/crochet.mjs +24 -0
- package/scripts/crochets.mjs +135 -0
- package/scripts/dernier-vert.mjs +208 -0
- package/scripts/dette.mjs +181 -0
- package/scripts/droits.mjs +354 -0
- package/scripts/enveloppe/codes.mjs +17 -0
- package/scripts/enveloppe/composant.mjs +11 -0
- package/scripts/enveloppe/enveloppe.mjs +628 -0
- package/scripts/enveloppe/lancer.sh +311 -0
- package/scripts/etapes.mjs +323 -0
- package/scripts/etat-du-circuit.mjs +104 -0
- package/scripts/frontieres.mjs +456 -0
- package/scripts/gardes-du-cadre.mjs +72 -0
- package/scripts/greffons.mjs +338 -0
- package/scripts/grillhouse-maj.mjs +514 -0
- package/scripts/index-interfaces.mjs +293 -0
- package/scripts/init.mjs +117 -0
- package/scripts/integration/file-attente.mjs +61 -0
- package/scripts/integration/file.mjs +494 -0
- package/scripts/integration/integrer.mjs +381 -0
- package/scripts/integration/rejeu.mjs +139 -0
- package/scripts/integration/verdict.mjs +13 -0
- package/scripts/interfaces-contre-code.mjs +547 -0
- package/scripts/ligne-etat/defaut.sh +110 -0
- package/scripts/ligne-etat/ligne-etat.mjs +93 -0
- package/scripts/migrations/0.23.0-charte-importee.mjs +47 -0
- package/scripts/migrations/0.23.0-config-vitest.mjs +105 -0
- package/scripts/migrations/0.23.0-crochets-de-seance.mjs +55 -0
- package/scripts/migrations/0.23.0-marche-du-projet.mjs +82 -0
- package/scripts/migrations.mjs +43 -0
- package/scripts/nuit.sh +269 -0
- package/scripts/paquets.mjs +79 -0
- package/scripts/poussee-cles.mjs +46 -0
- package/scripts/preparation.mjs +84 -0
- package/scripts/references-par-les-types.mjs +420 -0
- package/scripts/registre.mjs +336 -0
- package/scripts/resultats.mjs +580 -0
- package/scripts/resumes.mjs +57 -0
- package/scripts/retirer-copie.sh +127 -0
- package/scripts/session-start.sh +203 -0
- package/scripts/sortie.mjs +155 -0
- package/scripts/sous-modules.sh +316 -0
- package/scripts/structure-guard.sh +27 -0
- package/scripts/superviseur.mjs +102 -0
- package/scripts/tableau.mjs +1886 -0
- package/scripts/tests.mjs +236 -0
- package/scripts/ticket.sh +23 -0
- package/scripts/turbo-des-paquets.mjs +899 -0
- package/scripts/un-commit-par-ticket.mjs +212 -0
- package/scripts/verifier.mjs +469 -0
- package/scripts/verrou-de-fichier.mjs +130 -0
- package/scripts/verrou-de-machine.mjs +211 -0
- package/scripts/verrous/commande.mjs +180 -0
- package/scripts/verrous/ticket-du-sous-agent.mjs +39 -0
- package/scripts/verrous/verrou.mjs +165 -0
- package/scripts/vitest-config/avancement.mjs +39 -0
- package/scripts/vitest-config/avancement.reporter.mjs +56 -0
- package/scripts/vitest-config/base-de-passe.mjs +128 -0
- package/scripts/vitest-config/base.d.ts +6 -0
- package/scripts/vitest-config/base.mjs +87 -0
- package/scripts/vitest-config/changements.mjs +173 -0
- package/scripts/vitest-config/cibles.mjs +207 -0
- package/scripts/vitest-config/duree.reporter.mjs +98 -0
- package/scripts/vitest-config/machine.setup.mjs +14 -0
- package/scripts/vitest-config/mesure.d.ts +6 -0
- package/scripts/vitest-config/mesure.mjs +13 -0
- package/scripts/vitest-config/mesure.setup.mjs +12 -0
- package/scripts/vitest-config/pression.mjs +90 -0
- package/scripts/vitest-config/resultats.mjs +23 -0
- package/scripts/vitest-config/resultats.setup.mjs +19 -0
- package/scripts/vitest.nuit.config.mjs +26 -0
- package/skills/developpeur/SKILL.md +175 -0
- package/skills/explorateur/SKILL.md +84 -0
- package/skills/grill/SKILL.md +238 -0
- package/skills/grill/references/releve-structurel.md +38 -0
- package/skills/mesure/SKILL.md +168 -0
- package/skills/pitmaster/SKILL.md +382 -0
- package/skills/pitmaster/references/cadre.md +119 -0
- package/skills/pitmaster/references/consigne-agent.md +308 -0
- package/skills/pitmaster/references/erreurs.md +25 -0
- package/skills/pitmaster/references/tour.md +124 -0
- package/skills/questionneur/SKILL.md +64 -0
- package/skills/redacteur/SKILL.md +84 -0
- package/skills/redacteur/references/documents-d-un-composant.md +105 -0
- package/skills/referent-technique/SKILL.md +145 -0
- package/skills/regulateur/SKILL.md +220 -0
- package/skills/release/SKILL.md +134 -0
- package/skills/release/scripts/update-version.cjs +92 -0
- package/skills/relecteur/SKILL.md +152 -0
- package/skills/relecteur/references/LICENSE-MIT +30 -0
- package/skills/relecteur/references/SOURCE.md +8 -0
- package/skills/relecteur/references/claims-check.md +14 -0
- package/skills/relecteur/references/deletion-check.md +14 -0
- package/skills/relecteur/references/edge-case-hunter.md +80 -0
- package/skills/relecteur/references/verification-gap.md +113 -0
- package/skills/testwriter/SKILL.md +187 -0
- package/types/index.d.ts +56 -0
- package/README.md +0 -3
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// The day's tests, as Turborepo's tasks (`npm test`, `npm run test:forcer`): the build, then the
|
|
3
|
+
// `test:vitest` of each package, an unchanged task replayed from Turborepo's cache.
|
|
4
|
+
//
|
|
5
|
+
// npx grillhouse tests [--force] [<path>…] [--<option>=<value>…]
|
|
6
|
+
//
|
|
7
|
+
// - Without a path, every package plays its tests (`turbo run test:vitest`); `--force` plays each
|
|
8
|
+
// task for real, the builds included (`npm run test:forcer`).
|
|
9
|
+
// - A path is written from the root of the repository: a test file or a directory. In a repository
|
|
10
|
+
// of packages, each path plays in the package that holds it: Turborepo runs the `test:vitest` of
|
|
11
|
+
// those packages only (`--filter=<name>`), and their Vitest receives each path made absolute,
|
|
12
|
+
// which it matches against its own test files (a path of another package matches none of them).
|
|
13
|
+
// Turborepo filters packages, not files, and Vitest resolves a relative path from the directory
|
|
14
|
+
// of the package that runs it, so the frame translates each path into its package; a Vitest at the
|
|
15
|
+
// root (its projects) would run each package's tests under the root's version, not the one the
|
|
16
|
+
// package declares. A path out of every package, in a package out of the frame
|
|
17
|
+
// (`docs/agents/hors-cadre.txt`), or in a package without a `test:vitest` script is refused,
|
|
18
|
+
// named, and nothing plays. In a repository without packages, the paths go to the root's Vitest
|
|
19
|
+
// as they are.
|
|
20
|
+
// - The paths and the options reach Vitest in the variable `GRILLHOUSE_TESTS`
|
|
21
|
+
// (scripts/vitest-config/cibles.mjs), which the `env` of the task `test:vitest` names, never
|
|
22
|
+
// after `--`: Turborepo passes the arguments after `--` to the tasks the command names only, and
|
|
23
|
+
// counts them in the hash of every task of the run (its documentation, « Caching »: « including
|
|
24
|
+
// dependencies of `build` that did not receive `--arg=value` »), where a variable of a task's
|
|
25
|
+
// `env` enters that task's hash alone. So a run with paths is one Turborepo run of the tests with
|
|
26
|
+
// what they depend on (`turbo run test:vitest --filter=<name>`): the builds and the traces they
|
|
27
|
+
// wait for play first, from the cache when nothing moved, whatever paths are named, and the hash
|
|
28
|
+
// of the tests holds theirs, as Bazel's key of a target holds its transitive inputs; a change to
|
|
29
|
+
// a package the tests import, or to what they read, plays them again. Every other run of
|
|
30
|
+
// Turborepo plays with the variable unset.
|
|
31
|
+
// - Each run of Turborepo plays every task whose dependencies succeed
|
|
32
|
+
// (`--continue=dependencies-successful`), as Bazel's `--keep_going` and `npm run verifier` do:
|
|
33
|
+
// each build that fails is named on Turborepo's line « Failed: », a test that waits for a failed
|
|
34
|
+
// build does not play, and the exit code stays red. A build that fails first does not hide another
|
|
35
|
+
// one, which the run would otherwise cancel unreported.
|
|
36
|
+
// - `--force` with paths plays the tests named for real, their builds replayed from the cache:
|
|
37
|
+
// Turborepo's `--force` re-executes every task of the run, so the variable carries the moment of
|
|
38
|
+
// the run instead (`rejouer`), a value no cached run of the tests has. A test suspected unstable
|
|
39
|
+
// is played again, and a build, which the same inputs give again, is not.
|
|
40
|
+
// - In the envelope of an agent (`GRILLHOUSE_ENVELOPPE`, scripts/enveloppe/composant.mjs), the
|
|
41
|
+
// neighbours and their traces arrive built by the launcher and read-only, as in a sandbox of
|
|
42
|
+
// Bazel: the build is the named packages' alone, with the traces of those packages their tests
|
|
43
|
+
// wait for, which live in the package the agent writes (`turbo run build <name>#trace:<t>…
|
|
44
|
+
// --only --filter=<name>`, their task ids read in Turborepo's plan of the tests,
|
|
45
|
+
// `turbo run test:vitest --filter=<name> --dry=json`), never their dependencies nor a
|
|
46
|
+
// neighbour's trace; then the tests alone (`turbo run test:vitest --only --filter=<name>`), the
|
|
47
|
+
// paths in the variable. A named package that the envelope shows read-only (the shared test
|
|
48
|
+
// material, for every role but the testwriter) is not built, nor are its traces: it arrives built,
|
|
49
|
+
// as a read-only input of Bazel, and its tests play as it is; the frame knows it read-only by
|
|
50
|
+
// testing its directory for writing (`inscriptible`), where the envelope mounts it, and the logs
|
|
51
|
+
// of its tasks go to the envelope's directories proper to the session (`sortiesDeTest`,
|
|
52
|
+
// scripts/enveloppe/enveloppe.mjs), never into its source. There the hash of the tests sees
|
|
53
|
+
// neither the code of the neighbours nor their builds: the verdict that counts is the reviewer's
|
|
54
|
+
// and the integration's, out of the envelope.
|
|
55
|
+
// - An argument that begins with « - » is an option of Vitest, written `--<name>=<value>`, carried
|
|
56
|
+
// in the variable beside the paths.
|
|
57
|
+
// - A night test or a time budget bench, which the day leaves out, plays when a path names its own
|
|
58
|
+
// file, under the measure of time of the day's configuration (scripts/vitest-config/cibles.mjs);
|
|
59
|
+
// a directory or a package named leaves them out.
|
|
60
|
+
// - A run that plays no test fails: the frame's base configuration of Vitest keeps Vitest's
|
|
61
|
+
// `passWithNoTests: false` (scripts/vitest-config/base.mjs).
|
|
62
|
+
// - Under the circuit's mark (`GRILLHOUSE_DEPUIS_LE_VERT`, its proof and its checks,
|
|
63
|
+
// scripts/circuit.mjs), a run measures itself against the last green, as `npm run verifier`
|
|
64
|
+
// does (scripts/dernier-vert.mjs): in a package or a directory named, the tests Vitest relates to
|
|
65
|
+
// the files changed since it, every test when a change lies out of Vitest's graph; a file named
|
|
66
|
+
// itself plays, changed or not; `--force` plays them all. Without the mark, every test named
|
|
67
|
+
// plays.
|
|
68
|
+
// - While the environment names a results directory (`GRILLHOUSE_RESULTATS`,
|
|
69
|
+
// scripts/resultats.mjs), each run of Turborepo writes its summary (`--summarize`), moved there,
|
|
70
|
+
// and Vitest its JSON report there: what the circuit reads of a run.
|
|
71
|
+
// - While the environment names the progress directory of a pass (`GRILLHOUSE_AVANCEMENT`,
|
|
72
|
+
// scripts/avancement.mjs: the circuit's proof and checks), each run of the tests plans its
|
|
73
|
+
// tasks first, and Vitest writes there the files done and planned of each.
|
|
74
|
+
// - The run has a base of its own (scripts/vitest-config/base-de-passe.mjs), which it sweeps first
|
|
75
|
+
// of the bases a killed run left: it names it in TMPDIR to every run of Turborepo, which the
|
|
76
|
+
// root's `globalPassThroughEnv` passes on to every task, and removes it at its end.
|
|
77
|
+
// The exit code is Turborepo's; 2 for a path refused.
|
|
78
|
+
import { spawnSync } from 'node:child_process';
|
|
79
|
+
import { accessSync, constants, existsSync, readdirSync, statSync } from 'node:fs';
|
|
80
|
+
import path from 'node:path';
|
|
81
|
+
import { planifier } from './avancement.mjs';
|
|
82
|
+
import { composantDeLEnveloppe } from './enveloppe/composant.mjs';
|
|
83
|
+
import { paquets } from './paquets.mjs';
|
|
84
|
+
import { garderLesResumes, RESULTATS } from './resultats.mjs';
|
|
85
|
+
import { tracesDuPlan } from './turbo-des-paquets.mjs';
|
|
86
|
+
import { AVANCEMENT } from './vitest-config/avancement.mjs';
|
|
87
|
+
import { VARIABLE } from './vitest-config/cibles.mjs';
|
|
88
|
+
import { CHANGEMENTS } from './vitest-config/changements.mjs';
|
|
89
|
+
import { DEPUIS_LE_VERT, mesure } from './dernier-vert.mjs';
|
|
90
|
+
import { ouvrirBase } from './vitest-config/base-de-passe.mjs';
|
|
91
|
+
|
|
92
|
+
const racine = process.cwd();
|
|
93
|
+
// The base of the run (scripts/vitest-config/base-de-passe.mjs): this process and every run of
|
|
94
|
+
// Turborepo write in it (TMPDIR), and it goes at the end of the run.
|
|
95
|
+
const base = ouvrirBase('tests');
|
|
96
|
+
process.env.TMPDIR = base.dossier;
|
|
97
|
+
const enveloppe = composantDeLEnveloppe() !== null;
|
|
98
|
+
const args = process.argv.slice(2);
|
|
99
|
+
const force = args.includes('--force');
|
|
100
|
+
const options = args.filter(a => a.startsWith('-') && a !== '--force');
|
|
101
|
+
const chemins = args.filter(a => !a.startsWith('-'));
|
|
102
|
+
// Under the circuit's mark, the tests measured against the last green; `--force` plays them all.
|
|
103
|
+
const depuis = process.env[DEPUIS_LE_VERT] ? mesure(racine, { tout: force }) : null;
|
|
104
|
+
if (depuis) process.stdout.write(`${depuis.ligne}\n`);
|
|
105
|
+
|
|
106
|
+
// One Turborepo run of <args>, VARIABLE set to <tests> (unset without), each task whose
|
|
107
|
+
// dependencies succeed played to its end; its exit code. While the run names a results directory
|
|
108
|
+
// (RESULTATS), Turborepo writes its summary, which goes there.
|
|
109
|
+
const turbo = (args, tests) => {
|
|
110
|
+
const env = { ...process.env };
|
|
111
|
+
delete env[VARIABLE];
|
|
112
|
+
delete env[CHANGEMENTS];
|
|
113
|
+
Object.assign(env, depuis?.env ?? {});
|
|
114
|
+
if (tests) env[VARIABLE] = JSON.stringify(tests);
|
|
115
|
+
const resume = env[RESULTATS] ? ['--summarize'] : [];
|
|
116
|
+
const runs = path.join(racine, '.turbo', 'runs');
|
|
117
|
+
const avant = new Set(existsSync(runs) ? readdirSync(runs) : []);
|
|
118
|
+
// A run of the tests under a progress directory plans its tasks (scripts/avancement.mjs).
|
|
119
|
+
if (args[0] === 'test:vitest') {
|
|
120
|
+
planifier(env[AVANCEMENT], {
|
|
121
|
+
racine,
|
|
122
|
+
args: [...args, '--continue=dependencies-successful'],
|
|
123
|
+
env,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
const code =
|
|
127
|
+
spawnSync('turbo', ['run', ...args, '--continue=dependencies-successful', ...resume], {
|
|
128
|
+
cwd: racine,
|
|
129
|
+
stdio: 'inherit',
|
|
130
|
+
env,
|
|
131
|
+
}).status ?? 1;
|
|
132
|
+
if (resume.length) garderLesResumes(racine, avant, env);
|
|
133
|
+
return code;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
// The trace tasks of the packages <noms> their tests wait for, read in Turborepo's plan of the
|
|
137
|
+
// tests <filtres> select: `{ ids }`; a plan that fails gives `{ code }`, its output written.
|
|
138
|
+
const traces = (filtres, noms) => {
|
|
139
|
+
const plan = spawnSync('turbo', ['run', 'test:vitest', ...filtres, '--dry=json'], {
|
|
140
|
+
cwd: racine,
|
|
141
|
+
encoding: 'utf8',
|
|
142
|
+
maxBuffer: 256 * 1024 * 1024,
|
|
143
|
+
});
|
|
144
|
+
if (plan.status !== 0) {
|
|
145
|
+
process.stderr.write(`${plan.stdout ?? ''}${plan.stderr ?? ''}`);
|
|
146
|
+
return { code: plan.status ?? 1 };
|
|
147
|
+
}
|
|
148
|
+
return { ids: tracesDuPlan(JSON.parse(plan.stdout), t => noms.has(t.package)) };
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
// The tests <filtres> select, which receive <passes> in VARIABLE: one run with what they depend on;
|
|
152
|
+
// in an envelope, the build of the packages they name with their own traces, then the tests alone.
|
|
153
|
+
// Its exit code: the first that is not 0, else the tests'.
|
|
154
|
+
const cibles = (filtres, passes) => {
|
|
155
|
+
const tests = { arguments: passes, ...(force ? { rejouer: new Date().toISOString() } : {}) };
|
|
156
|
+
if (!enveloppe) return turbo(['test:vitest', ...filtres], tests);
|
|
157
|
+
// A package the envelope shows read-only arrives built: only the packages it shows in writing
|
|
158
|
+
// build, as the envelope mounts them (`inscriptible`).
|
|
159
|
+
const construits = filtres.filter(f => inscriptible(dossiers.get(f.slice('--filter='.length))));
|
|
160
|
+
if (filtres.length === 0 || construits.length > 0) {
|
|
161
|
+
const noms = new Set(construits.map(f => f.slice('--filter='.length)));
|
|
162
|
+
const propres = construits.length ? traces(construits, noms) : { ids: [] };
|
|
163
|
+
if (propres.code !== undefined) return propres.code;
|
|
164
|
+
const construction = turbo(['build', ...propres.ids, '--only', ...construits]);
|
|
165
|
+
if (construction !== 0) return construction;
|
|
166
|
+
}
|
|
167
|
+
return turbo(['test:vitest', '--only', ...filtres], tests);
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
// True when this process may write the directory <dir>: false under a read-only mount.
|
|
171
|
+
const inscriptible = dir => {
|
|
172
|
+
try {
|
|
173
|
+
accessSync(dir, constants.W_OK);
|
|
174
|
+
return true;
|
|
175
|
+
} catch {
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
const liste = paquets(racine);
|
|
181
|
+
// The directory of each package of the frame, by its name.
|
|
182
|
+
const dossiers = new Map(liste.map(p => [p.pkg.name, path.join(racine, p.dossier)]));
|
|
183
|
+
|
|
184
|
+
// The run the command asks for: its exit code.
|
|
185
|
+
const lancer = () => {
|
|
186
|
+
if (chemins.length === 0) {
|
|
187
|
+
return turbo(
|
|
188
|
+
['test:vitest', ...(force ? ['--force'] : [])],
|
|
189
|
+
options.length ? { arguments: options } : undefined
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
if (liste.length === 0) return cibles([], [...chemins, ...options]);
|
|
193
|
+
|
|
194
|
+
// The package of the frame that holds each path, the paths made absolute; the refusals.
|
|
195
|
+
const refus = [];
|
|
196
|
+
const noms = new Set();
|
|
197
|
+
const absolus = [];
|
|
198
|
+
for (const chemin of chemins) {
|
|
199
|
+
const abs = path.resolve(racine, chemin);
|
|
200
|
+
const p = liste.find(({ dossier }) =>
|
|
201
|
+
`${abs}${path.sep}`.startsWith(path.join(racine, dossier, path.sep))
|
|
202
|
+
);
|
|
203
|
+
if (!p) {
|
|
204
|
+
refus.push(
|
|
205
|
+
`⛔ ${chemin} : hors de tout paquet ; un chemin de test s'écrit depuis la racine, dans un paquet.`
|
|
206
|
+
);
|
|
207
|
+
} else if (p.hors) {
|
|
208
|
+
refus.push(
|
|
209
|
+
`⛔ ${chemin} : ${p.dossier} est hors cadre (docs/agents/hors-cadre.txt) ; Turborepo n'en joue aucune tâche.`
|
|
210
|
+
);
|
|
211
|
+
} else if (typeof p.pkg.scripts?.['test:vitest'] !== 'string') {
|
|
212
|
+
refus.push(`⛔ ${chemin} : ${p.dossier} n'a pas de script test:vitest.`);
|
|
213
|
+
} else {
|
|
214
|
+
noms.add(p.pkg.name);
|
|
215
|
+
// A directory ends with « / »: Vitest matches the start of a path, and packages/a is the start
|
|
216
|
+
// of packages/ab.
|
|
217
|
+
const dossier = existsSync(abs) && statSync(abs).isDirectory();
|
|
218
|
+
absolus.push(dossier ? `${abs}${path.sep}` : abs);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
if (refus.length) {
|
|
222
|
+
for (const l of refus) process.stderr.write(`${l}\n`);
|
|
223
|
+
return 2;
|
|
224
|
+
}
|
|
225
|
+
return cibles(
|
|
226
|
+
[...noms].sort().map(n => `--filter=${n}`),
|
|
227
|
+
[...absolus, ...options]
|
|
228
|
+
);
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
try {
|
|
232
|
+
process.exitCode = lancer();
|
|
233
|
+
} finally {
|
|
234
|
+
depuis?.retirer();
|
|
235
|
+
base.fermer();
|
|
236
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Crée un ticket sous sa mère, titré « <numéro> — <sujet> — <composants> », et affiche son id.
|
|
3
|
+
# ticket.sh <mère> <sujet> <composants> <corps> [étiquette]
|
|
4
|
+
# Les composants tiennent en un argument, séparés par des virgules, le fournisseur d'abord :
|
|
5
|
+
# « 020-loader, 050-emitter ».
|
|
6
|
+
# Un corps @<fichier> se lit dans ce fichier. L'étiquette vaut a-valider par défaut ;
|
|
7
|
+
# decouverte crée le ticket fermé (« découverte consignée »).
|
|
8
|
+
# Le numéro est l'id sans le préfixe entier du projet (bd config get issue_prefix).
|
|
9
|
+
set -eu
|
|
10
|
+
if [ $# -lt 4 ]; then
|
|
11
|
+
sed -n '2,9p' "$0" >&2
|
|
12
|
+
exit 2
|
|
13
|
+
fi
|
|
14
|
+
mere=$1 sujet=$2 composants=$3 corps=$4 etiquette=${5:-a-valider}
|
|
15
|
+
|
|
16
|
+
case "$corps" in
|
|
17
|
+
@*) source_corps=(--body-file "${corps#@}") ;;
|
|
18
|
+
*) source_corps=(-d "$corps") ;;
|
|
19
|
+
esac
|
|
20
|
+
n=$(bd create "$sujet" --parent "$mere" --no-inherit-labels -t task -l "$etiquette" "${source_corps[@]}" --silent)
|
|
21
|
+
bd update "$n" --title "${n#"$(bd config get issue_prefix)"-} — $sujet — $composants" >/dev/null
|
|
22
|
+
[ "$etiquette" = decouverte ] && bd close "$n" -r "découverte consignée" >/dev/null
|
|
23
|
+
echo "$n"
|