@abloh/repository 1.0.0 → 1.0.1-staging.34767970367
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/index.d.ts +85 -3
- package/dist/index.js +81 -16
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RepoReader, PackageManifestReading, MatrixLeg, MatrixLegs, FailFastReading, SetupCandidateTrigger, SetupWorkflowCaller, SetupCandidateGate, NativeVocabulary, SetupFailFast, SetupCandidateExclusion, Refusal, YamlQuote, CoverageProviderChoice, MatrixValue, WorkflowNodePin, SetupScriptStep, ValueOrigin, CommandScriptHop, AngularTestTarget, PreparedTestCommand, InitFailureClass, InitQuestionKey, EnvironmentConfig, TargetSelectionKind, EvidenceOutputId, resolvePreparedTestCommand, MeasurementPlan, PackageExclusion } from '@abloh/core';
|
|
1
|
+
import { RepoReader, PackageManifestReading, ProposedFile, MatrixLeg, MatrixLegs, FailFastReading, SetupCandidateTrigger, SetupWorkflowCaller, SetupCandidateGate, NativeVocabulary, SetupFailFast, SetupCandidateExclusion, Refusal, YamlQuote, CoverageProviderChoice, MatrixValue, WorkflowNodePin, SetupScriptStep, ValueOrigin, CommandScriptHop, AngularTestTarget, PreparedTestCommand, InitFailureClass, InitQuestionKey, EnvironmentConfig, TargetSelectionKind, EvidenceOutputId, resolvePreparedTestCommand, MeasurementPlan, PackageExclusion } from '@abloh/core';
|
|
2
2
|
export { SETUP_STEP_ACTION, SETUP_STEP_IF, SETUP_STEP_JOB_STATUS, SETUP_STEP_NAME, setupStepIf } from '@abloh/core';
|
|
3
3
|
import { JasmineSuite, ProofRunner, StrykerMutationRunner } from '@abloh/measure';
|
|
4
4
|
|
|
@@ -56,6 +56,17 @@ interface RepoAccess {
|
|
|
56
56
|
}
|
|
57
57
|
/** The access `abloh init` and every existing caller get: a checkout on this machine. */
|
|
58
58
|
declare function diskRepoAccess(repoDir: string): RepoAccess;
|
|
59
|
+
/**
|
|
60
|
+
* THE SAME ACCESS, READING {@link ProposedFile} BYTES FOR THE PATHS SOMEBODY HAS AGREED TO.
|
|
61
|
+
*
|
|
62
|
+
* WHAT IT IS FOR (the audit's class 5, 2026-09-12). `abloh init` has to draft as if an answered edit
|
|
63
|
+
* to a file of the maintainer's were already there, and it used to do that by writing the file and
|
|
64
|
+
* reading it back - before the confirmation that says abloh has written nothing yet. The root, the
|
|
65
|
+
* spellings of it and the realpath rule are untouched: only what the reader answers moves.
|
|
66
|
+
*
|
|
67
|
+
* An empty list returns the access itself, so the ordinary road pays nothing.
|
|
68
|
+
*/
|
|
69
|
+
declare function overlayRepoAccess(base: RepoAccess, files: readonly ProposedFile[]): RepoAccess;
|
|
59
70
|
/**
|
|
60
71
|
* The repository-relative path an absolute one names, or null when it names nothing in here.
|
|
61
72
|
*
|
|
@@ -975,6 +986,20 @@ interface CiRecipe {
|
|
|
975
986
|
* sets environment values Abloh has no key for, a build scoped to one workspace package.
|
|
976
987
|
*/
|
|
977
988
|
notices: readonly string[];
|
|
989
|
+
/**
|
|
990
|
+
* THE CHOSEN JOB'S OWN STEPS THAT ABLOH READ AND DID NOT COPY INTO `.abloh/setup.sh`.
|
|
991
|
+
*
|
|
992
|
+
* THE RULING (the captain, 2026-09-12, review finding F4): init copies only the steps the tests
|
|
993
|
+
* need, a lint, format, docs or publish step is not one of them, and the maintainer is told which
|
|
994
|
+
* ones were left out. `honojs/hono` is the repository that earned it - its job runs `format`,
|
|
995
|
+
* `lint` and `editorconfig-checker` before its suite, and the checker downloads a release binary
|
|
996
|
+
* and cannot, so a repository that was never measured stopped on a step about trailing newlines.
|
|
997
|
+
*
|
|
998
|
+
* NOT {@link refusal} AND NOT A REFUSAL'S LIST. Those say abloh could not READ a step; these say
|
|
999
|
+
* abloh read it and the suite does not read what it produces. Only the first is a gap in abloh's
|
|
1000
|
+
* reading, and folding the two would tell a maintainer to go and copy in a linter.
|
|
1001
|
+
*/
|
|
1002
|
+
stepsNotCopied: readonly CiDroppedStep[];
|
|
978
1003
|
}
|
|
979
1004
|
type AptReading = {
|
|
980
1005
|
ok: true;
|
|
@@ -1029,6 +1054,21 @@ interface NodeEnvironment {
|
|
|
1029
1054
|
* cell does Abloh's step actually run on".
|
|
1030
1055
|
*/
|
|
1031
1056
|
declare function readCiNodeDeclaration(raw: string | null, matrix: unknown, reader: RepoReader, leg?: MatrixLeg | null | undefined, env?: NodeEnvironment): CiNodeVersion | null;
|
|
1057
|
+
/** One step of a candidate job abloh read and declined to translate, with its own sentence. */
|
|
1058
|
+
/**
|
|
1059
|
+
* ONE STEP ABLOH READ AND DID NOT COPY: where it sits, what it runs, and why it was left out.
|
|
1060
|
+
*
|
|
1061
|
+
* THE COMMAND IS THE MAINTAINER'S OWN TEXT, so it is local-only wherever it is shown - the same
|
|
1062
|
+
* rule `setup-ci-steps-unread` already carries its step bodies under.
|
|
1063
|
+
*/
|
|
1064
|
+
interface CiDroppedStep {
|
|
1065
|
+
/** 1-based, as a maintainer counts the `steps:` of their own job. Null for Travis and CircleCI. */
|
|
1066
|
+
step: number | null;
|
|
1067
|
+
/** The step's own command line. */
|
|
1068
|
+
command: string;
|
|
1069
|
+
/** Why the suite does not need it, in the reading's own words. */
|
|
1070
|
+
why: string;
|
|
1071
|
+
}
|
|
1032
1072
|
/**
|
|
1033
1073
|
* DO TWO JOB REFERENCES NAME THE SAME JOB, whichever spelling each of them uses?
|
|
1034
1074
|
*
|
|
@@ -2219,8 +2259,27 @@ interface DraftService {
|
|
|
2219
2259
|
*
|
|
2220
2260
|
* A constant because a re-run has to RECOGNIZE it: the block is replaced from its own `environment:`
|
|
2221
2261
|
* line down, and a header left stranded above the replacement appears twice in the customer's file.
|
|
2262
|
+
*
|
|
2263
|
+
* IT NAMES CI RATHER THAN A CONTAINER (the audit of 2026-09-12, 10.4). "the proof container" is a
|
|
2264
|
+
* thing one road builds: a run on the maintainer's own machine measures a copy of their own tree
|
|
2265
|
+
* with their own installed dependencies, and reads none of the keys under this header. The block is
|
|
2266
|
+
* still written on both roads, because it is what their CI needs the day they add abloh's check
|
|
2267
|
+
* there, and the header now says so instead of describing work that is not happening.
|
|
2222
2268
|
*/
|
|
2223
|
-
declare const ENVIRONMENT_BLOCK_HEADER = "#
|
|
2269
|
+
declare const ENVIRONMENT_BLOCK_HEADER = "# How CI rebuilds this project for abloh's check. Comments name the source file.";
|
|
2270
|
+
/**
|
|
2271
|
+
* HEADERS THIS COMMAND USED TO WRITE, so a re-run still recognizes a file it wrote before.
|
|
2272
|
+
*
|
|
2273
|
+
* WHY IT EXISTS. The recognition above is an exact string match. Change the constant with no list
|
|
2274
|
+
* beside it and every `abloh.yml` already carrying the old line gets the new header written above
|
|
2275
|
+
* the old one - the exact duplication that constant's own header warns about, arriving through the
|
|
2276
|
+
* one edit it did not anticipate.
|
|
2277
|
+
*
|
|
2278
|
+
* IT ONLY GROWS. A line here is a line some repository has committed, and nothing rewrites it.
|
|
2279
|
+
*/
|
|
2280
|
+
declare const RETIRED_ENVIRONMENT_BLOCK_HEADERS: readonly string[];
|
|
2281
|
+
/** Is this line an environment-block header this command has ever written? */
|
|
2282
|
+
declare function isEnvironmentBlockHeader(line: string): boolean;
|
|
2224
2283
|
/**
|
|
2225
2284
|
* WHAT ABLOH READ ABOUT THE JOB ITS STEP RIDES, as the contract will state it.
|
|
2226
2285
|
*
|
|
@@ -4427,6 +4486,29 @@ declare function placeSetupStep(input: {
|
|
|
4427
4486
|
before: string;
|
|
4428
4487
|
} | null;
|
|
4429
4488
|
}): SetupStepPlacement | Refusal;
|
|
4489
|
+
/**
|
|
4490
|
+
* Is abloh's step already the last thing this job does?
|
|
4491
|
+
*
|
|
4492
|
+
* MATCHED ON THE ACTION REPOSITORY AND NOT ON THE PIN. A customer who is already running abloh at
|
|
4493
|
+
* an older commit has an abloh step, and appending a second one would run the measurement twice and
|
|
4494
|
+
* put two check runs on every pull request. The pin is ours to bump and theirs to keep.
|
|
4495
|
+
*/
|
|
4496
|
+
/**
|
|
4497
|
+
* DOES THIS WORKFLOW ALREADY RUN ABLOH, in any job of it?
|
|
4498
|
+
*
|
|
4499
|
+
* WHO ASKS (the captain's ruling of 2026-09-12). Re-running `abloh init` adds a lane, so the command
|
|
4500
|
+
* has to be able to tell a repository that is already set up for pull requests from one that is not
|
|
4501
|
+
* - and the step in one of the maintainer's own jobs is the fact that says so.
|
|
4502
|
+
*
|
|
4503
|
+
* IT IS THE SAME MATCHER THE WRITER USES, over every job rather than over one. A second reading of
|
|
4504
|
+
* "is abloh's step here" is how one of them comes to answer differently, and the writer's answer is
|
|
4505
|
+
* what decides whether a second step is appended.
|
|
4506
|
+
*
|
|
4507
|
+
* AN UNREADABLE FILE ANSWERS FALSE. What that costs is an offer to set up a lane that is already
|
|
4508
|
+
* there, which a maintainer can decline. Answering true would hide the offer from somebody who
|
|
4509
|
+
* needs it.
|
|
4510
|
+
*/
|
|
4511
|
+
declare function workflowRunsAbloh(text: string): boolean;
|
|
4430
4512
|
|
|
4431
4513
|
/**
|
|
4432
4514
|
* WHICH OF THE MAINTAINER'S SUITE STEPS ABLOH'S STEP GOES BEHIND, ON THE LEG IT PINNED.
|
|
@@ -4628,4 +4710,4 @@ declare function selectAutoTarget(input: {
|
|
|
4628
4710
|
*/
|
|
4629
4711
|
declare function committedYarnVersion(directory: string, lockfileName: string, ctx?: RepoAccess): string | null;
|
|
4630
4712
|
|
|
4631
|
-
export { ANSWERABLE_SETUP_KEYS, ANSWERED_EVIDENCE, type AggregatorInvocation, type AggregatorTool, type AttestationJob, type AutoTargetSelection, type BrowserLane, type BrowserLaneEvidence, type BrowserLaneKind, CI_RECIPE_REFUSALS, type CiBorrowJob, type CiBrowserLane, type CiEnvironmentValue, type CiInstallStep, type CiJobStep, type CiJobTestStep, type CiManagerVersion, type CiNodeVersion, type CiRecipe, type CiRequiredVariable, type CiService, type CiSetupCommand, type CiSystemPackage, type CiTestCommand, type CiUnreadableJobCall, type CiUnsupportedService, type ConfigInput, type ConfigSystemPackage, type CoverageChildSuite, DENO_CONFIG_FILES, DENO_LOCKFILE, type DeclaredBinding, type DeclaredCommandContext, type DenoProject, type DraftService, ENVIRONMENT_BLOCK_HEADER, InitRefusal, type LockfileChoice, type ManifestClassification, type NodeChoice, type NodeDeclaration, type NodeDeclarationProblem, type NodeDeclarationRejection, type NodeEnvironment, type NodeRelease, type NodeRequirement, type NodeSpecReading, type NxProject, type NxTestTarget, type PackageManager, type PackageManagerContext, type PackageManagerResolution, type PlanDeclaration, type PolicyDeclaration, RUSH_CONFIG_DIRECTORY, RUSH_CONFIG_FILE, RUSH_INSTALL_COMMAND, RUSH_INSTALL_SCRIPT, RUSH_LOCKFILE_NAME, RUSH_REPO_STATE_NAME, RUSH_SUBSPACE_DIRECTORY, RUSH_TEST_SCRIPTS, type ReadTextAt, type RebuildDraftValue, type RepoAccess, type ResolveMeasurementPlanInput, type Runner, type RuntimeNeed, type RushProject, type RushTestTarget, SETUP_QUESTION_DESCRIPTORS, STEP_WHAT, type SetupAnswerChannel, type SetupAnswerShape, type SetupDraftValues, type SetupFailFastDecision, type SetupJobDecision, type SetupJobQuestion, type SetupMatrixLeg, type SetupPin, type SetupPublishPlacement, type SetupQuestionDescriptor, type SetupStepAnchor, type SetupStepPlacement, type SetupStepPrecondition, type SubmoduleRoot, type TargetDetection, TargetDetectionError, TargetNotFoundError, type TargetNotFoundReason, type TargetResolution, type TargetResolutionInput, type WorkflowEnvironmentEntry, type WorkflowEnvironmentLevel, type WorkflowEnvironmentScope, type WorkflowExpressionFacts, type WorkflowExpressionReading, type WorkspaceEnumeration, type WorkspaceRootSuite, __testing, accessExists, accessKind, accessManifest, accessSubdirectories, accessText, admitSubmodules, aggregatorInvocation, aggregatorTaskPhrase, aliasHopFamily, answeredTargetDirectory, applyAnswersToContract, applyDeclaredRunner, argvInvokesNodeTest, assertNoGitlinkChanges, bindDeclaredCommand, bindPreparedTestCommand, chooseNodeVersion, ciInstallSteps, ciInstallersFor, ciManagerVersions, ciRefusalIsActionable, classicPerTestRefusal, classicPerTestRunner, classifyNxTestTarget, classifyPackageDirectory, classifyPackageManifest, classifyRushTestScript, classifyWithAliasHop, commentLines, committedYarnVersion, contractDescriptors, decideSetupJob, declarableSetupJobs, declaredCommandContext, declaredRunner, declaredRunnerInvocation, declaredSetupJob, declaredSetupPin, denoLockfilePath, denoTestInvocation, deriveCiRecipe, detectJasmineSuite, detectPackageManager, detectPackageManagerContext, detectTarget, detectVitestDir, diskRepoAccess, diskRepoReader, doorSetupJobs, emptyCiRecipe, engineRunner, enumerateNxProjects, enumerateRushProjects, enumerateWorkspacePackages, enumerateWorkspacePackagesOnDisk, initFailureClassOf, initRefusal, initStepRole, invokesNodeTest, isBrowserInstallCommand, isInstallStep, jasmineSuiteFromScript, layerEnvironment, materializeSubmodule, nodeDeclarationProblemReason, nodeSpecVersions, placeSetupStep, policyDeclaration, preRunnerStageCommands, readAnswerValue, readBrowserLane, readDenoProject, readNodeSpec, readWorkflowExpressions, referencesExpression, referencesSecret, refusalRemedyOf, renderConfig, renderEnvironmentBlock, renderWorkflow, repoPath, resolveMeasurementPlan, resolveSetupPin, resolveTarget, resolveTargetDetection, rootAggregatorTasks, runnerInvocation, runnerStageCommand, runnerSuiteInvocations, rushIdentityFiles, rushLockfiles, rushNodeVersionRange, sameJobReference, scriptRunsDenoTest, selectAutoTarget, setupAnswerProblem, setupJobCandidates, setupJobReference, setupScriptSteps, setupStepAnchor, setupStepOrigin, splitAnswerList, suiteStages, systemPackagesStep, testCommandReceipt, testStepLabel, testableWorkspacePackages, unreadableConditionLine, vitestDirIn, withoutPackageRunnerPrefix, workDirPrefix };
|
|
4713
|
+
export { ANSWERABLE_SETUP_KEYS, ANSWERED_EVIDENCE, type AggregatorInvocation, type AggregatorTool, type AttestationJob, type AutoTargetSelection, type BrowserLane, type BrowserLaneEvidence, type BrowserLaneKind, CI_RECIPE_REFUSALS, type CiBorrowJob, type CiBrowserLane, type CiDroppedStep, type CiEnvironmentValue, type CiInstallStep, type CiJobStep, type CiJobTestStep, type CiManagerVersion, type CiNodeVersion, type CiRecipe, type CiRequiredVariable, type CiService, type CiSetupCommand, type CiSystemPackage, type CiTestCommand, type CiUnreadableJobCall, type CiUnsupportedService, type ConfigInput, type ConfigSystemPackage, type CoverageChildSuite, DENO_CONFIG_FILES, DENO_LOCKFILE, type DeclaredBinding, type DeclaredCommandContext, type DenoProject, type DraftService, ENVIRONMENT_BLOCK_HEADER, InitRefusal, type LockfileChoice, type ManifestClassification, type NodeChoice, type NodeDeclaration, type NodeDeclarationProblem, type NodeDeclarationRejection, type NodeEnvironment, type NodeRelease, type NodeRequirement, type NodeSpecReading, type NxProject, type NxTestTarget, type PackageManager, type PackageManagerContext, type PackageManagerResolution, type PlanDeclaration, type PolicyDeclaration, RETIRED_ENVIRONMENT_BLOCK_HEADERS, RUSH_CONFIG_DIRECTORY, RUSH_CONFIG_FILE, RUSH_INSTALL_COMMAND, RUSH_INSTALL_SCRIPT, RUSH_LOCKFILE_NAME, RUSH_REPO_STATE_NAME, RUSH_SUBSPACE_DIRECTORY, RUSH_TEST_SCRIPTS, type ReadTextAt, type RebuildDraftValue, type RepoAccess, type ResolveMeasurementPlanInput, type Runner, type RuntimeNeed, type RushProject, type RushTestTarget, SETUP_QUESTION_DESCRIPTORS, STEP_WHAT, type SetupAnswerChannel, type SetupAnswerShape, type SetupDraftValues, type SetupFailFastDecision, type SetupJobDecision, type SetupJobQuestion, type SetupMatrixLeg, type SetupPin, type SetupPublishPlacement, type SetupQuestionDescriptor, type SetupStepAnchor, type SetupStepPlacement, type SetupStepPrecondition, type SubmoduleRoot, type TargetDetection, TargetDetectionError, TargetNotFoundError, type TargetNotFoundReason, type TargetResolution, type TargetResolutionInput, type WorkflowEnvironmentEntry, type WorkflowEnvironmentLevel, type WorkflowEnvironmentScope, type WorkflowExpressionFacts, type WorkflowExpressionReading, type WorkspaceEnumeration, type WorkspaceRootSuite, __testing, accessExists, accessKind, accessManifest, accessSubdirectories, accessText, admitSubmodules, aggregatorInvocation, aggregatorTaskPhrase, aliasHopFamily, answeredTargetDirectory, applyAnswersToContract, applyDeclaredRunner, argvInvokesNodeTest, assertNoGitlinkChanges, bindDeclaredCommand, bindPreparedTestCommand, chooseNodeVersion, ciInstallSteps, ciInstallersFor, ciManagerVersions, ciRefusalIsActionable, classicPerTestRefusal, classicPerTestRunner, classifyNxTestTarget, classifyPackageDirectory, classifyPackageManifest, classifyRushTestScript, classifyWithAliasHop, commentLines, committedYarnVersion, contractDescriptors, decideSetupJob, declarableSetupJobs, declaredCommandContext, declaredRunner, declaredRunnerInvocation, declaredSetupJob, declaredSetupPin, denoLockfilePath, denoTestInvocation, deriveCiRecipe, detectJasmineSuite, detectPackageManager, detectPackageManagerContext, detectTarget, detectVitestDir, diskRepoAccess, diskRepoReader, doorSetupJobs, emptyCiRecipe, engineRunner, enumerateNxProjects, enumerateRushProjects, enumerateWorkspacePackages, enumerateWorkspacePackagesOnDisk, initFailureClassOf, initRefusal, initStepRole, invokesNodeTest, isBrowserInstallCommand, isEnvironmentBlockHeader, isInstallStep, jasmineSuiteFromScript, layerEnvironment, materializeSubmodule, nodeDeclarationProblemReason, nodeSpecVersions, overlayRepoAccess, placeSetupStep, policyDeclaration, preRunnerStageCommands, readAnswerValue, readBrowserLane, readDenoProject, readNodeSpec, readWorkflowExpressions, referencesExpression, referencesSecret, refusalRemedyOf, renderConfig, renderEnvironmentBlock, renderWorkflow, repoPath, resolveMeasurementPlan, resolveSetupPin, resolveTarget, resolveTargetDetection, rootAggregatorTasks, runnerInvocation, runnerStageCommand, runnerSuiteInvocations, rushIdentityFiles, rushLockfiles, rushNodeVersionRange, sameJobReference, scriptRunsDenoTest, selectAutoTarget, setupAnswerProblem, setupJobCandidates, setupJobReference, setupScriptSteps, setupStepAnchor, setupStepOrigin, splitAnswerList, suiteStages, systemPackagesStep, testCommandReceipt, testStepLabel, testableWorkspacePackages, unreadableConditionLine, vitestDirIn, withoutPackageRunnerPrefix, workDirPrefix, workflowRunsAbloh };
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { realpathSync as realpathSync2 } from "fs";
|
|
|
3
3
|
import { relative, resolve as resolve2 } from "path";
|
|
4
4
|
import {
|
|
5
5
|
normalizeRepoPath as normalizeRepoPath2,
|
|
6
|
+
overlayRepoReader,
|
|
6
7
|
readPackageManifest
|
|
7
8
|
} from "@abloh/core";
|
|
8
9
|
|
|
@@ -116,6 +117,10 @@ function diskRepoAccess(repoDir) {
|
|
|
116
117
|
}
|
|
117
118
|
};
|
|
118
119
|
}
|
|
120
|
+
function overlayRepoAccess(base, files) {
|
|
121
|
+
const reader = overlayRepoReader(base.reader, files);
|
|
122
|
+
return reader === base.reader ? base : { ...base, reader };
|
|
123
|
+
}
|
|
119
124
|
function repoPath(ctx, absolute) {
|
|
120
125
|
const target = resolve2(absolute);
|
|
121
126
|
for (const base of ctx.roots) {
|
|
@@ -320,6 +325,7 @@ import {
|
|
|
320
325
|
manifestScripts,
|
|
321
326
|
normalizeRepoPath as normalizeRepoPath3,
|
|
322
327
|
readPackageManifest as readPackageManifest2,
|
|
328
|
+
runIsDroppable,
|
|
323
329
|
scriptRuns
|
|
324
330
|
} from "@abloh/core";
|
|
325
331
|
import {
|
|
@@ -1037,7 +1043,7 @@ function readStep(step, manifest, reader) {
|
|
|
1037
1043
|
const script = workspaceFirst[2];
|
|
1038
1044
|
if (TEST_NAMES.test(script)) return { kind: "test", command };
|
|
1039
1045
|
if (BUILD_NAMES.test(script)) return { kind: "build", command, env };
|
|
1040
|
-
return { kind: "other" };
|
|
1046
|
+
return { kind: "other", command, why: "abloh could not read what it does" };
|
|
1041
1047
|
}
|
|
1042
1048
|
const scoped = /--workspace[= ]([^\s]+)|--filter[= ]([^\s]+)/u.test(tail);
|
|
1043
1049
|
if (manifest.scripts[name] !== void 0 || scoped) {
|
|
@@ -1050,7 +1056,7 @@ function readStep(step, manifest, reader) {
|
|
|
1050
1056
|
if (manifest.scripts[name] !== void 0 && scriptRunsBuild(manifest, name)) {
|
|
1051
1057
|
return { kind: "build", command, env };
|
|
1052
1058
|
}
|
|
1053
|
-
return { kind: "other" };
|
|
1059
|
+
return { kind: "other", command, why: scriptNotABuildBecause(manifest, name) };
|
|
1054
1060
|
}
|
|
1055
1061
|
if (TEST_BINARIES.has(name)) return { kind: "test", command };
|
|
1056
1062
|
if (BUILD_BINARIES.has(name)) {
|
|
@@ -1170,7 +1176,20 @@ function scriptRunsBuild(manifest, name) {
|
|
|
1170
1176
|
lifecycle: false
|
|
1171
1177
|
});
|
|
1172
1178
|
if (runs.length === 0) return false;
|
|
1173
|
-
return runs.every((run) => run.kind === "preparation" &&
|
|
1179
|
+
return runs.every((run) => run.kind === "preparation" && run.role === "build");
|
|
1180
|
+
}
|
|
1181
|
+
function scriptNotABuildBecause(manifest, name) {
|
|
1182
|
+
const runs = scriptRuns({
|
|
1183
|
+
scripts: manifest.scripts,
|
|
1184
|
+
dependencies: manifest.dependencies,
|
|
1185
|
+
script: name,
|
|
1186
|
+
lifecycle: false
|
|
1187
|
+
});
|
|
1188
|
+
if (runs.length > 0 && runs.every((run) => runIsDroppable(run) && run.kind !== "test")) {
|
|
1189
|
+
return "it checks the tree rather than writing into it";
|
|
1190
|
+
}
|
|
1191
|
+
const unknown = runs.find((run) => run.kind === "preparation" && run.role === "tool");
|
|
1192
|
+
return unknown === void 0 ? "abloh could not read what it does" : `abloh has no reading of ${unknown.name}, so it cannot say the suite needs it`;
|
|
1174
1193
|
}
|
|
1175
1194
|
function clip(command) {
|
|
1176
1195
|
return command.length > 70 ? `${command.slice(0, 70)}\u2026` : command;
|
|
@@ -1334,6 +1353,7 @@ function emptyCiRecipe(refusal) {
|
|
|
1334
1353
|
browserLane: null,
|
|
1335
1354
|
unreadableJobCalls: [],
|
|
1336
1355
|
refusal,
|
|
1356
|
+
stepsNotCopied: [],
|
|
1337
1357
|
notices: []
|
|
1338
1358
|
};
|
|
1339
1359
|
}
|
|
@@ -1359,6 +1379,7 @@ function deriveCiRecipe(input) {
|
|
|
1359
1379
|
browserLane: null,
|
|
1360
1380
|
unreadableJobCalls: [],
|
|
1361
1381
|
refusal: `your CI configuration could not be read (${error instanceof Error ? error.message : "unknown error"})`,
|
|
1382
|
+
stepsNotCopied: [],
|
|
1362
1383
|
notices: []
|
|
1363
1384
|
};
|
|
1364
1385
|
}
|
|
@@ -1385,6 +1406,7 @@ function derive(input) {
|
|
|
1385
1406
|
runnerImage: null,
|
|
1386
1407
|
browserLane: null,
|
|
1387
1408
|
unreadableJobCalls: calls,
|
|
1409
|
+
stepsNotCopied: [],
|
|
1388
1410
|
refusal,
|
|
1389
1411
|
notices: [...bounds, ...notices]
|
|
1390
1412
|
});
|
|
@@ -1598,20 +1620,21 @@ function assemble(input) {
|
|
|
1598
1620
|
for (const refused of chosen.refusals) {
|
|
1599
1621
|
if (!unread.some((seen2) => seen2.step === refused.step && seen2.why === refused.why)) unread.push(refused);
|
|
1600
1622
|
}
|
|
1601
|
-
const
|
|
1602
|
-
kind: "setup-ci-steps",
|
|
1603
|
-
unread,
|
|
1623
|
+
const stepsRead = {
|
|
1604
1624
|
workflow: chosen.workflowPath,
|
|
1605
1625
|
job: chosen.jobId,
|
|
1606
1626
|
/* THE MAINTAINER'S OWN FILE SAID IT, and `at` is the receipt spelling every other notice in
|
|
1607
1627
|
this function uses, so a reader meets one name for the job on every line. */
|
|
1608
1628
|
at: `${chosen.file}::${chosen.jobId}`
|
|
1609
|
-
}
|
|
1610
|
-
|
|
1611
|
-
const
|
|
1612
|
-
|
|
1629
|
+
};
|
|
1630
|
+
const sayStepsRead = (facts2) => {
|
|
1631
|
+
const outcome = messageFromFacts({ kind: "setup-ci-steps", ...stepsRead, ...facts2 });
|
|
1632
|
+
if (outcome.kind !== "message") return;
|
|
1633
|
+
const rendered = renderRefusal(outcome.refusal, "terminal");
|
|
1613
1634
|
if (rendered !== null) notices.push(refusalLines(rendered).join("\n"));
|
|
1614
|
-
}
|
|
1635
|
+
};
|
|
1636
|
+
sayStepsRead({ unread, notCopied: [] });
|
|
1637
|
+
sayStepsRead({ unread: [], notCopied: [...chosen.notCopied] });
|
|
1615
1638
|
const drafted = [];
|
|
1616
1639
|
const seen = /* @__PURE__ */ new Set();
|
|
1617
1640
|
const push = (step, source) => {
|
|
@@ -1838,6 +1861,11 @@ function assemble(input) {
|
|
|
1838
1861
|
runnerImage,
|
|
1839
1862
|
browserLane,
|
|
1840
1863
|
unreadableJobCalls: input.unreadableJobCalls,
|
|
1864
|
+
/* THE STEPS THE CHOSEN JOB RUNS THAT THE RECIPE LEFT OUT. See {@link CiRecipe.stepsNotCopied}:
|
|
1865
|
+
this is the chosen candidate's own list and never a pooling of every job's, because the
|
|
1866
|
+
recipe is derived from one job and a sentence about another job's steps would name edits to a
|
|
1867
|
+
file abloh is not reading. */
|
|
1868
|
+
stepsNotCopied: chosen.notCopied,
|
|
1841
1869
|
refusal: null,
|
|
1842
1870
|
notices
|
|
1843
1871
|
};
|
|
@@ -2052,6 +2080,7 @@ function blankCandidate(file, jobId, label) {
|
|
|
2052
2080
|
testSteps: [],
|
|
2053
2081
|
installs: false,
|
|
2054
2082
|
refusals: [],
|
|
2083
|
+
notCopied: [],
|
|
2055
2084
|
refusedTestSteps: [],
|
|
2056
2085
|
/* A `.travis.yml` or a CircleCI job declares no `env:` block and no `services:` this module has
|
|
2057
2086
|
a preset for, so the three keys those produce are empty here by construction. */
|
|
@@ -2489,6 +2518,7 @@ function readJob(reader, manifest, file, jobId, job, workflowEnv, bounds = []) {
|
|
|
2489
2518
|
testSteps: [],
|
|
2490
2519
|
installs: false,
|
|
2491
2520
|
refusals: [],
|
|
2521
|
+
notCopied: [],
|
|
2492
2522
|
refusedTestSteps: [],
|
|
2493
2523
|
node: null,
|
|
2494
2524
|
nodeEnv: NO_NODE_ENVIRONMENT,
|
|
@@ -2595,6 +2625,15 @@ function readJob(reader, manifest, file, jobId, job, workflowEnv, bounds = []) {
|
|
|
2595
2625
|
candidate.refusedTestSteps.push(classified.why);
|
|
2596
2626
|
}
|
|
2597
2627
|
break;
|
|
2628
|
+
case "other":
|
|
2629
|
+
if (!candidate.notCopied.some((seen) => seen.command === classified.command)) {
|
|
2630
|
+
candidate.notCopied.push({
|
|
2631
|
+
step: stepNumber(step),
|
|
2632
|
+
command: classified.command,
|
|
2633
|
+
why: classified.why
|
|
2634
|
+
});
|
|
2635
|
+
}
|
|
2636
|
+
break;
|
|
2598
2637
|
default:
|
|
2599
2638
|
break;
|
|
2600
2639
|
}
|
|
@@ -2790,7 +2829,7 @@ function renderEnvironmentBlock(input) {
|
|
|
2790
2829
|
...input.coverageProvider === void 0 ? [] : [{
|
|
2791
2830
|
key: "coverageProvider",
|
|
2792
2831
|
value: input.coverageProvider,
|
|
2793
|
-
receipt: input.coverageProvider === "install" ? "you agreed abloh may stage @vitest/coverage-v8
|
|
2832
|
+
receipt: input.coverageProvider === "install" ? "you agreed abloh may stage @vitest/coverage-v8 where a run measures, into its own cache outside this repository" : "you asked abloh not to install @vitest/coverage-v8, so the changed-line check reports itself as declined"
|
|
2794
2833
|
}],
|
|
2795
2834
|
...input.sealedTestCommand !== null || input.sealedNote !== null ? [{
|
|
2796
2835
|
key: "sealedTestCommand",
|
|
@@ -2838,7 +2877,7 @@ function renderEnvironmentBlock(input) {
|
|
|
2838
2877
|
}
|
|
2839
2878
|
}
|
|
2840
2879
|
if (input.identityFiles.length > 0) {
|
|
2841
|
-
lines.push(" identityFiles: # a change here
|
|
2880
|
+
lines.push(" identityFiles: # a change here makes CI reinstall instead of reusing its image");
|
|
2842
2881
|
for (const path of input.identityFiles) lines.push(` - ${yamlScalar(path, quote)}`);
|
|
2843
2882
|
}
|
|
2844
2883
|
if (input.requiredVariables.length > 0) {
|
|
@@ -2952,7 +2991,13 @@ function receiptLines(entries, indent, quote) {
|
|
|
2952
2991
|
}
|
|
2953
2992
|
return lines;
|
|
2954
2993
|
}
|
|
2955
|
-
var ENVIRONMENT_BLOCK_HEADER = "#
|
|
2994
|
+
var ENVIRONMENT_BLOCK_HEADER = "# How CI rebuilds this project for abloh's check. Comments name the source file.";
|
|
2995
|
+
var RETIRED_ENVIRONMENT_BLOCK_HEADERS = [
|
|
2996
|
+
"# Rebuild recipe for the proof container. Comments name the source file."
|
|
2997
|
+
];
|
|
2998
|
+
function isEnvironmentBlockHeader(line) {
|
|
2999
|
+
return line === ENVIRONMENT_BLOCK_HEADER || RETIRED_ENVIRONMENT_BLOCK_HEADERS.includes(line);
|
|
3000
|
+
}
|
|
2956
3001
|
var STEP_WHAT = {
|
|
2957
3002
|
systemPackages: "OS packages your suite needs, pinned",
|
|
2958
3003
|
corepack: "put the package manager on PATH, for your own lifecycle scripts",
|
|
@@ -2977,7 +3022,9 @@ function isInstallStep(what) {
|
|
|
2977
3022
|
return what === STEP_WHAT.install || what === STEP_WHAT.installUnlocked;
|
|
2978
3023
|
}
|
|
2979
3024
|
function setupStepOrigin(step) {
|
|
2980
|
-
|
|
3025
|
+
const role = initStepRole(step.what);
|
|
3026
|
+
if (role === null) return CUSTOMER_TYPED;
|
|
3027
|
+
return role === "setupCommands" ? "abloh-composed" : "abloh-derived";
|
|
2981
3028
|
}
|
|
2982
3029
|
function initStepRole(what) {
|
|
2983
3030
|
if (what === STEP_WHAT.systemPackages) return "systemPackages";
|
|
@@ -7278,6 +7325,20 @@ function failFastInsertion(lines, job) {
|
|
|
7278
7325
|
}
|
|
7279
7326
|
return null;
|
|
7280
7327
|
}
|
|
7328
|
+
function workflowRunsAbloh(text) {
|
|
7329
|
+
let document;
|
|
7330
|
+
try {
|
|
7331
|
+
document = parse3(text);
|
|
7332
|
+
} catch {
|
|
7333
|
+
return false;
|
|
7334
|
+
}
|
|
7335
|
+
const jobs = document?.jobs;
|
|
7336
|
+
if (typeof jobs !== "object" || jobs === null) return false;
|
|
7337
|
+
return Object.values(jobs).some((job) => {
|
|
7338
|
+
const steps = job?.steps;
|
|
7339
|
+
return Array.isArray(steps) && alreadyEndsInAblohStep(steps);
|
|
7340
|
+
});
|
|
7341
|
+
}
|
|
7281
7342
|
function alreadyEndsInAblohStep(steps) {
|
|
7282
7343
|
const repository = SETUP_STEP_ACTION.split("@")[0] ?? SETUP_STEP_ACTION;
|
|
7283
7344
|
return steps.some(
|
|
@@ -7593,6 +7654,7 @@ export {
|
|
|
7593
7654
|
DENO_LOCKFILE,
|
|
7594
7655
|
ENVIRONMENT_BLOCK_HEADER,
|
|
7595
7656
|
InitRefusal,
|
|
7657
|
+
RETIRED_ENVIRONMENT_BLOCK_HEADERS,
|
|
7596
7658
|
RUSH_CONFIG_DIRECTORY,
|
|
7597
7659
|
RUSH_CONFIG_FILE,
|
|
7598
7660
|
RUSH_INSTALL_COMMAND,
|
|
@@ -7670,12 +7732,14 @@ export {
|
|
|
7670
7732
|
initStepRole,
|
|
7671
7733
|
invokesNodeTest,
|
|
7672
7734
|
isBrowserInstallCommand,
|
|
7735
|
+
isEnvironmentBlockHeader,
|
|
7673
7736
|
isInstallStep,
|
|
7674
7737
|
jasmineSuiteFromScript,
|
|
7675
7738
|
layerEnvironment,
|
|
7676
7739
|
materializeSubmodule,
|
|
7677
7740
|
nodeDeclarationProblemReason,
|
|
7678
7741
|
nodeSpecVersions,
|
|
7742
|
+
overlayRepoAccess,
|
|
7679
7743
|
placeSetupStep,
|
|
7680
7744
|
policyDeclaration,
|
|
7681
7745
|
preRunnerStageCommands,
|
|
@@ -7721,5 +7785,6 @@ export {
|
|
|
7721
7785
|
unreadableConditionLine,
|
|
7722
7786
|
vitestDirIn,
|
|
7723
7787
|
withoutPackageRunnerPrefix,
|
|
7724
|
-
workDirPrefix
|
|
7788
|
+
workDirPrefix,
|
|
7789
|
+
workflowRunsAbloh
|
|
7725
7790
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abloh/repository",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1-staging.34767970367",
|
|
4
4
|
"description": "Reads a repository and decides what abloh may measure in it: the CI recipe, the target, the package manager, the workspace packages, the job abloh's step rides and the measurement plan. Shared by the CLI, which reads a checkout, and by the control plane, which reads the same repository over GitHub's contents API. \"name\" will publish under the @abloh scope.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"semver": "7.8.5",
|
|
25
25
|
"yaml": "^2.6.1",
|
|
26
|
-
"@abloh/
|
|
27
|
-
"@abloh/
|
|
26
|
+
"@abloh/measure": "1.0.1-staging.34767970367",
|
|
27
|
+
"@abloh/core": "1.0.1-staging.34767970367"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@types/semver": "7.7.1",
|