repopo 0.12.0 → 0.14.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/CHANGELOG.md +70 -0
- package/README.md +57 -90
- package/THIRD-PARTY-LICENSES.txt +169 -11
- package/bin/dev.js +0 -0
- package/esm/adapters/fluidFramework.d.ts +13 -9
- package/esm/adapters/fluidFramework.d.ts.map +1 -1
- package/esm/adapters/fluidFramework.js +20 -43
- package/esm/adapters/fluidFramework.js.map +1 -1
- package/esm/api.d.ts +66 -1
- package/esm/api.d.ts.map +1 -1
- package/esm/api.js +18 -1
- package/esm/api.js.map +1 -1
- package/esm/baseCommand.d.ts.map +1 -1
- package/esm/baseCommand.js +2 -2
- package/esm/baseCommand.js.map +1 -1
- package/esm/commands/check-native.d.ts +5 -3
- package/esm/commands/check-native.d.ts.map +1 -1
- package/esm/commands/check-native.js +35 -7
- package/esm/commands/check-native.js.map +1 -1
- package/esm/commands/check.d.ts +8 -21
- package/esm/commands/check.d.ts.map +1 -1
- package/esm/commands/check.js +98 -154
- package/esm/commands/check.js.map +1 -1
- package/esm/commands/list.d.ts.map +1 -1
- package/esm/commands/list.js +1 -0
- package/esm/commands/list.js.map +1 -1
- package/esm/concurrency.d.ts +3 -0
- package/esm/concurrency.d.ts.map +1 -0
- package/esm/concurrency.js +8 -0
- package/esm/concurrency.js.map +1 -0
- package/esm/config.d.ts +10 -39
- package/esm/config.d.ts.map +1 -1
- package/esm/config.js +3 -7
- package/esm/config.js.map +1 -1
- package/esm/context.d.ts +10 -1
- package/esm/context.d.ts.map +1 -1
- package/esm/context.js +19 -1
- package/esm/context.js.map +1 -1
- package/esm/executionContractError.d.ts +4 -0
- package/esm/executionContractError.d.ts.map +1 -0
- package/esm/executionContractError.js +4 -0
- package/esm/executionContractError.js.map +1 -0
- package/esm/fileCache.d.ts +12 -0
- package/esm/fileCache.d.ts.map +1 -0
- package/esm/fileCache.js +37 -0
- package/esm/fileCache.js.map +1 -0
- package/esm/filePaths.d.ts +2 -0
- package/esm/filePaths.d.ts.map +1 -0
- package/esm/filePaths.js +9 -0
- package/esm/filePaths.js.map +1 -0
- package/esm/generators.d.ts +0 -20
- package/esm/generators.d.ts.map +1 -1
- package/esm/generators.js.map +1 -1
- package/esm/index.d.ts +3 -16
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +3 -17
- package/esm/index.js.map +1 -1
- package/esm/makePolicy.d.ts +20 -100
- package/esm/makePolicy.d.ts.map +1 -1
- package/esm/makePolicy.js +46 -132
- package/esm/makePolicy.js.map +1 -1
- package/esm/perf.d.ts +5 -2
- package/esm/perf.d.ts.map +1 -1
- package/esm/perf.js +10 -9
- package/esm/perf.js.map +1 -1
- package/esm/policies/CargoLicenceValidated.d.ts +4 -4
- package/esm/policies/CargoLicenceValidated.d.ts.map +1 -1
- package/esm/policies/CargoLicenceValidated.js +9 -7
- package/esm/policies/CargoLicenceValidated.js.map +1 -1
- package/esm/policies/CargoLintsConfigured.d.ts +4 -4
- package/esm/policies/CargoLintsConfigured.d.ts.map +1 -1
- package/esm/policies/CargoLintsConfigured.js +19 -15
- package/esm/policies/CargoLintsConfigured.js.map +1 -1
- package/esm/policies/CargoLockPolicy.d.ts +4 -4
- package/esm/policies/CargoLockPolicy.d.ts.map +1 -1
- package/esm/policies/CargoLockPolicy.js +15 -11
- package/esm/policies/CargoLockPolicy.js.map +1 -1
- package/esm/policies/CargoTomlRequired.d.ts +5 -5
- package/esm/policies/CargoTomlRequired.d.ts.map +1 -1
- package/esm/policies/CargoTomlRequired.js +7 -7
- package/esm/policies/CargoTomlRequired.js.map +1 -1
- package/esm/policies/CargoTomlSorted.d.ts +4 -4
- package/esm/policies/CargoTomlSorted.d.ts.map +1 -1
- package/esm/policies/CargoTomlSorted.js +21 -17
- package/esm/policies/CargoTomlSorted.js.map +1 -1
- package/esm/policies/ConditionalScripts.d.ts +10 -8
- package/esm/policies/ConditionalScripts.d.ts.map +1 -1
- package/esm/policies/ConditionalScripts.js +24 -22
- package/esm/policies/ConditionalScripts.js.map +1 -1
- package/esm/policies/ExactScripts.d.ts +8 -6
- package/esm/policies/ExactScripts.d.ts.map +1 -1
- package/esm/policies/ExactScripts.js +15 -18
- package/esm/policies/ExactScripts.js.map +1 -1
- package/esm/policies/GleamDepVersions.d.ts +5 -5
- package/esm/policies/GleamDepVersions.d.ts.map +1 -1
- package/esm/policies/GleamDepVersions.js +5 -5
- package/esm/policies/GleamDepVersions.js.map +1 -1
- package/esm/policies/GleamDocExists.d.ts +4 -4
- package/esm/policies/GleamDocExists.d.ts.map +1 -1
- package/esm/policies/GleamDocExists.js +6 -6
- package/esm/policies/GleamDocExists.js.map +1 -1
- package/esm/policies/GleamInternalModulesConfigured.d.ts +4 -4
- package/esm/policies/GleamInternalModulesConfigured.d.ts.map +1 -1
- package/esm/policies/GleamInternalModulesConfigured.js +8 -6
- package/esm/policies/GleamInternalModulesConfigured.js.map +1 -1
- package/esm/policies/GleamLicenceConfigured.d.ts +4 -4
- package/esm/policies/GleamLicenceConfigured.d.ts.map +1 -1
- package/esm/policies/GleamLicenceConfigured.js +8 -6
- package/esm/policies/GleamLicenceConfigured.js.map +1 -1
- package/esm/policies/GleamManifestCommitted.d.ts +10 -3
- package/esm/policies/GleamManifestCommitted.d.ts.map +1 -1
- package/esm/policies/GleamManifestCommitted.js +10 -9
- package/esm/policies/GleamManifestCommitted.js.map +1 -1
- package/esm/policies/GleamMonorepoConsistency.d.ts +13 -5
- package/esm/policies/GleamMonorepoConsistency.d.ts.map +1 -1
- package/esm/policies/GleamMonorepoConsistency.js +10 -10
- package/esm/policies/GleamMonorepoConsistency.js.map +1 -1
- package/esm/policies/GleamNameRestrictions.d.ts +4 -4
- package/esm/policies/GleamNameRestrictions.d.ts.map +1 -1
- package/esm/policies/GleamNameRestrictions.js +6 -6
- package/esm/policies/GleamNameRestrictions.js.map +1 -1
- package/esm/policies/GleamNoPathDepsInPublished.d.ts +4 -4
- package/esm/policies/GleamNoPathDepsInPublished.d.ts.map +1 -1
- package/esm/policies/GleamNoPathDepsInPublished.js +6 -6
- package/esm/policies/GleamNoPathDepsInPublished.js.map +1 -1
- package/esm/policies/GleamPathDepsValid.d.ts +3 -3
- package/esm/policies/GleamPathDepsValid.d.ts.map +1 -1
- package/esm/policies/GleamPathDepsValid.js +5 -5
- package/esm/policies/GleamPathDepsValid.js.map +1 -1
- package/esm/policies/GleamProjectStructure.d.ts +11 -4
- package/esm/policies/GleamProjectStructure.d.ts.map +1 -1
- package/esm/policies/GleamProjectStructure.js +7 -8
- package/esm/policies/GleamProjectStructure.js.map +1 -1
- package/esm/policies/GleamSharedDependencyVersions.d.ts +12 -4
- package/esm/policies/GleamSharedDependencyVersions.d.ts.map +1 -1
- package/esm/policies/GleamSharedDependencyVersions.js +10 -10
- package/esm/policies/GleamSharedDependencyVersions.js.map +1 -1
- package/esm/policies/GleamTomlRequired.d.ts +4 -4
- package/esm/policies/GleamTomlRequired.d.ts.map +1 -1
- package/esm/policies/GleamTomlRequired.js +5 -5
- package/esm/policies/GleamTomlRequired.js.map +1 -1
- package/esm/policies/GleamTomlSorted.d.ts +4 -4
- package/esm/policies/GleamTomlSorted.d.ts.map +1 -1
- package/esm/policies/GleamTomlSorted.js +21 -17
- package/esm/policies/GleamTomlSorted.js.map +1 -1
- package/esm/policies/GleamVersionConstraint.d.ts +4 -4
- package/esm/policies/GleamVersionConstraint.d.ts.map +1 -1
- package/esm/policies/GleamVersionConstraint.js +14 -10
- package/esm/policies/GleamVersionConstraint.js.map +1 -1
- package/esm/policies/HtmlFileHeaders.d.ts +4 -2
- package/esm/policies/HtmlFileHeaders.d.ts.map +1 -1
- package/esm/policies/HtmlFileHeaders.js +1 -1
- package/esm/policies/HtmlFileHeaders.js.map +1 -1
- package/esm/policies/JsTsFileHeaders.d.ts +4 -2
- package/esm/policies/JsTsFileHeaders.d.ts.map +1 -1
- package/esm/policies/JsTsFileHeaders.js +1 -1
- package/esm/policies/JsTsFileHeaders.js.map +1 -1
- package/esm/policies/LicenseFileExists.d.ts +10 -4
- package/esm/policies/LicenseFileExists.d.ts.map +1 -1
- package/esm/policies/LicenseFileExists.js +27 -20
- package/esm/policies/LicenseFileExists.js.map +1 -1
- package/esm/policies/MaxChangedFiles.d.ts +17 -0
- package/esm/policies/MaxChangedFiles.d.ts.map +1 -0
- package/esm/policies/MaxChangedFiles.js +22 -0
- package/esm/policies/MaxChangedFiles.js.map +1 -0
- package/esm/policies/MutuallyExclusiveScripts.d.ts +8 -6
- package/esm/policies/MutuallyExclusiveScripts.d.ts.map +1 -1
- package/esm/policies/MutuallyExclusiveScripts.js +9 -13
- package/esm/policies/MutuallyExclusiveScripts.js.map +1 -1
- package/esm/policies/NoBuildDirectory.d.ts +9 -3
- package/esm/policies/NoBuildDirectory.d.ts.map +1 -1
- package/esm/policies/NoBuildDirectory.js +8 -13
- package/esm/policies/NoBuildDirectory.js.map +1 -1
- package/esm/policies/NoJsFileExtensions.d.ts +9 -3
- package/esm/policies/NoJsFileExtensions.d.ts.map +1 -1
- package/esm/policies/NoJsFileExtensions.js +9 -14
- package/esm/policies/NoJsFileExtensions.js.map +1 -1
- package/esm/policies/NoLargeBinaryFiles.d.ts +9 -4
- package/esm/policies/NoLargeBinaryFiles.d.ts.map +1 -1
- package/esm/policies/NoLargeBinaryFiles.js +10 -16
- package/esm/policies/NoLargeBinaryFiles.js.map +1 -1
- package/esm/policies/NoPrivateWorkspaceDependencies.d.ts +10 -6
- package/esm/policies/NoPrivateWorkspaceDependencies.d.ts.map +1 -1
- package/esm/policies/NoPrivateWorkspaceDependencies.js +12 -14
- package/esm/policies/NoPrivateWorkspaceDependencies.js.map +1 -1
- package/esm/policies/NoTargetArtifacts.d.ts +9 -3
- package/esm/policies/NoTargetArtifacts.d.ts.map +1 -1
- package/esm/policies/NoTargetArtifacts.js +9 -14
- package/esm/policies/NoTargetArtifacts.js.map +1 -1
- package/esm/policies/NoUnsafeWithoutJustification.d.ts +11 -4
- package/esm/policies/NoUnsafeWithoutJustification.d.ts.map +1 -1
- package/esm/policies/NoUnsafeWithoutJustification.js +8 -9
- package/esm/policies/NoUnsafeWithoutJustification.js.map +1 -1
- package/esm/policies/NoWildcardDependencies.d.ts +5 -5
- package/esm/policies/NoWildcardDependencies.d.ts.map +1 -1
- package/esm/policies/NoWildcardDependencies.js +6 -6
- package/esm/policies/NoWildcardDependencies.js.map +1 -1
- package/esm/policies/PackageAllowedScopes.d.ts +9 -5
- package/esm/policies/PackageAllowedScopes.d.ts.map +1 -1
- package/esm/policies/PackageAllowedScopes.js +15 -16
- package/esm/policies/PackageAllowedScopes.js.map +1 -1
- package/esm/policies/PackageEsmType.d.ts +7 -5
- package/esm/policies/PackageEsmType.d.ts.map +1 -1
- package/esm/policies/PackageEsmType.js +31 -31
- package/esm/policies/PackageEsmType.js.map +1 -1
- package/esm/policies/PackageFolderName.d.ts +8 -6
- package/esm/policies/PackageFolderName.d.ts.map +1 -1
- package/esm/policies/PackageFolderName.js +13 -16
- package/esm/policies/PackageFolderName.js.map +1 -1
- package/esm/policies/PackageJsonProperties.d.ts +5 -3
- package/esm/policies/PackageJsonProperties.d.ts.map +1 -1
- package/esm/policies/PackageJsonProperties.js +6 -17
- package/esm/policies/PackageJsonProperties.js.map +1 -1
- package/esm/policies/PackageJsonRepoDirectoryProperty.d.ts +2 -7
- package/esm/policies/PackageJsonRepoDirectoryProperty.d.ts.map +1 -1
- package/esm/policies/PackageJsonRepoDirectoryProperty.js +28 -42
- package/esm/policies/PackageJsonRepoDirectoryProperty.js.map +1 -1
- package/esm/policies/PackageJsonSorted.d.ts +2 -2
- package/esm/policies/PackageJsonSorted.d.ts.map +1 -1
- package/esm/policies/PackageJsonSorted.js +15 -30
- package/esm/policies/PackageJsonSorted.js.map +1 -1
- package/esm/policies/PackageLicense.d.ts +4 -4
- package/esm/policies/PackageLicense.d.ts.map +1 -1
- package/esm/policies/PackageLicense.js +31 -52
- package/esm/policies/PackageLicense.js.map +1 -1
- package/esm/policies/PackagePrivateField.d.ts +12 -8
- package/esm/policies/PackagePrivateField.d.ts.map +1 -1
- package/esm/policies/PackagePrivateField.js +31 -23
- package/esm/policies/PackagePrivateField.js.map +1 -1
- package/esm/policies/PackageReadme.d.ts +6 -5
- package/esm/policies/PackageReadme.d.ts.map +1 -1
- package/esm/policies/PackageReadme.js +22 -59
- package/esm/policies/PackageReadme.js.map +1 -1
- package/esm/policies/PackageScripts.d.ts +26 -22
- package/esm/policies/PackageScripts.d.ts.map +1 -1
- package/esm/policies/PackageScripts.js +39 -36
- package/esm/policies/PackageScripts.js.map +1 -1
- package/esm/policies/PackageTestScripts.d.ts +10 -6
- package/esm/policies/PackageTestScripts.d.ts.map +1 -1
- package/esm/policies/PackageTestScripts.js +14 -16
- package/esm/policies/PackageTestScripts.js.map +1 -1
- package/esm/policies/PublicApiDocumented.d.ts +4 -4
- package/esm/policies/PublicApiDocumented.d.ts.map +1 -1
- package/esm/policies/PublicApiDocumented.js +10 -8
- package/esm/policies/PublicApiDocumented.js.map +1 -1
- package/esm/policies/RequireCompanionChanges.d.ts +16 -0
- package/esm/policies/RequireCompanionChanges.d.ts.map +1 -0
- package/esm/policies/RequireCompanionChanges.js +42 -0
- package/esm/policies/RequireCompanionChanges.js.map +1 -0
- package/esm/policies/RequiredGitignorePatterns.d.ts +11 -4
- package/esm/policies/RequiredGitignorePatterns.d.ts.map +1 -1
- package/esm/policies/RequiredGitignorePatterns.js +29 -36
- package/esm/policies/RequiredGitignorePatterns.js.map +1 -1
- package/esm/policies/RequiredScripts.d.ts +9 -7
- package/esm/policies/RequiredScripts.d.ts.map +1 -1
- package/esm/policies/RequiredScripts.js +24 -24
- package/esm/policies/RequiredScripts.js.map +1 -1
- package/esm/policies/RustDocExists.d.ts +4 -4
- package/esm/policies/RustDocExists.d.ts.map +1 -1
- package/esm/policies/RustDocExists.js +6 -6
- package/esm/policies/RustDocExists.js.map +1 -1
- package/esm/policies/RustToolchainExists.d.ts +11 -4
- package/esm/policies/RustToolchainExists.d.ts.map +1 -1
- package/esm/policies/RustToolchainExists.js +10 -9
- package/esm/policies/RustToolchainExists.js.map +1 -1
- package/esm/policies/RustfmtConfigExists.d.ts +11 -4
- package/esm/policies/RustfmtConfigExists.d.ts.map +1 -1
- package/esm/policies/RustfmtConfigExists.js +10 -9
- package/esm/policies/RustfmtConfigExists.js.map +1 -1
- package/esm/policies/ScriptContains.d.ts +9 -7
- package/esm/policies/ScriptContains.d.ts.map +1 -1
- package/esm/policies/ScriptContains.js +9 -13
- package/esm/policies/ScriptContains.js.map +1 -1
- package/esm/policies/SharedDependencyVersions.d.ts +9 -4
- package/esm/policies/SharedDependencyVersions.d.ts.map +1 -1
- package/esm/policies/SharedDependencyVersions.js +28 -20
- package/esm/policies/SharedDependencyVersions.js.map +1 -1
- package/esm/policies/WorkspaceInheritance.d.ts +11 -4
- package/esm/policies/WorkspaceInheritance.d.ts.map +1 -1
- package/esm/policies/WorkspaceInheritance.js +10 -11
- package/esm/policies/WorkspaceInheritance.js.map +1 -1
- package/esm/policies/WorkspaceMembersValid.d.ts +11 -4
- package/esm/policies/WorkspaceMembersValid.d.ts.map +1 -1
- package/esm/policies/WorkspaceMembersValid.js +10 -11
- package/esm/policies/WorkspaceMembersValid.js.map +1 -1
- package/esm/policies/constants.d.ts.map +1 -1
- package/esm/policies/constants.js +1 -1
- package/esm/policies/constants.js.map +1 -1
- package/esm/policies.d.ts +15 -5
- package/esm/policies.d.ts.map +1 -1
- package/esm/policies.js +14 -5
- package/esm/policies.js.map +1 -1
- package/esm/policy.d.ts +67 -289
- package/esm/policy.d.ts.map +1 -1
- package/esm/policy.js +1 -122
- package/esm/policy.js.map +1 -1
- package/esm/policyDefiners/defineCargoPolicy.d.ts +25 -9
- package/esm/policyDefiners/defineCargoPolicy.d.ts.map +1 -1
- package/esm/policyDefiners/defineCargoPolicy.js +10 -28
- package/esm/policyDefiners/defineCargoPolicy.js.map +1 -1
- package/esm/policyDefiners/defineFileHeaderPolicy.d.ts +27 -14
- package/esm/policyDefiners/defineFileHeaderPolicy.d.ts.map +1 -1
- package/esm/policyDefiners/defineFileHeaderPolicy.js +16 -35
- package/esm/policyDefiners/defineFileHeaderPolicy.js.map +1 -1
- package/esm/policyDefiners/defineGleamPolicy.d.ts +25 -9
- package/esm/policyDefiners/defineGleamPolicy.d.ts.map +1 -1
- package/esm/policyDefiners/defineGleamPolicy.js +10 -27
- package/esm/policyDefiners/defineGleamPolicy.js.map +1 -1
- package/esm/policyDefiners/definePackagePolicy.d.ts +24 -13
- package/esm/policyDefiners/definePackagePolicy.d.ts.map +1 -1
- package/esm/policyDefiners/definePackagePolicy.js +9 -32
- package/esm/policyDefiners/definePackagePolicy.js.map +1 -1
- package/esm/policyDefiners/spdxValidator.d.ts +4 -12
- package/esm/policyDefiners/spdxValidator.d.ts.map +1 -1
- package/esm/policyDefiners/spdxValidator.js +26 -14
- package/esm/policyDefiners/spdxValidator.js.map +1 -1
- package/esm/policyExecution.d.ts +20 -0
- package/esm/policyExecution.d.ts.map +1 -0
- package/esm/policyExecution.js +234 -0
- package/esm/policyExecution.js.map +1 -0
- package/esm/repositoryChanges.d.ts +26 -0
- package/esm/repositoryChanges.d.ts.map +1 -0
- package/esm/repositoryChanges.js +172 -0
- package/esm/repositoryChanges.js.map +1 -0
- package/esm/repositoryFiles.d.ts +6 -0
- package/esm/repositoryFiles.d.ts.map +1 -0
- package/esm/repositoryFiles.js +11 -0
- package/esm/repositoryFiles.js.map +1 -0
- package/esm/runner.d.ts +73 -47
- package/esm/runner.d.ts.map +1 -1
- package/esm/runner.js +158 -144
- package/esm/runner.js.map +1 -1
- package/esm/settlePolicyPromise.d.ts +4 -0
- package/esm/settlePolicyPromise.d.ts.map +1 -0
- package/esm/settlePolicyPromise.js +10 -0
- package/esm/settlePolicyPromise.js.map +1 -0
- package/esm/tsdoc-metadata.json +1 -1
- package/esm/utils/safePaths.d.ts +9 -0
- package/esm/utils/safePaths.d.ts.map +1 -0
- package/esm/utils/safePaths.js +40 -0
- package/esm/utils/safePaths.js.map +1 -0
- package/oclif.manifest.json +57 -2
- package/package.json +42 -27
- package/scripts/benchmark.mjs +341 -0
- package/sidecar/sidecar.mjs +388 -417
package/esm/runner.js
CHANGED
|
@@ -1,174 +1,188 @@
|
|
|
1
|
-
import { all, call } from "effection";
|
|
2
|
-
import {
|
|
1
|
+
import { all, call, run, spawn } from "effection";
|
|
2
|
+
import { DEFAULT_CONCURRENCY, validateConcurrency } from "./concurrency.js";
|
|
3
|
+
import { createExcludedPolicyFileMap, exclusionRegex, matchesPath, } from "./context.js";
|
|
4
|
+
import { ParsedFileCache } from "./fileCache.js";
|
|
3
5
|
import { identifyPolicyInstances } from "./makePolicy.js";
|
|
4
|
-
import { newPerfStats
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
value !== null &&
|
|
9
|
-
"next" in value &&
|
|
10
|
-
typeof value.next === "function");
|
|
11
|
-
}
|
|
12
|
-
function matches(regex, value) {
|
|
13
|
-
if (!(regex.global || regex.sticky)) {
|
|
14
|
-
return regex.test(value);
|
|
15
|
-
}
|
|
16
|
-
const savedLastIndex = regex.lastIndex;
|
|
17
|
-
try {
|
|
18
|
-
regex.lastIndex = 0;
|
|
19
|
-
return regex.test(value);
|
|
20
|
-
}
|
|
21
|
-
finally {
|
|
22
|
-
regex.lastIndex = savedLastIndex;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Runs configured policies against files and collects results.
|
|
27
|
-
* @alpha
|
|
28
|
-
*/
|
|
6
|
+
import { newPerfStats } from "./perf.js";
|
|
7
|
+
import { PolicyExecutor } from "./policyExecution.js";
|
|
8
|
+
import { annotateInventory, inventoryPaths, snapshotInventory, } from "./repositoryChanges.js";
|
|
9
|
+
/** Effection runner; cancellation unwinds active generator handlers and resolvers. @public */
|
|
29
10
|
export class PolicyRunner {
|
|
11
|
+
options;
|
|
30
12
|
policies;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
resolve;
|
|
35
|
-
logger;
|
|
13
|
+
exclusions;
|
|
14
|
+
policyExclusions;
|
|
15
|
+
concurrency;
|
|
36
16
|
constructor(options) {
|
|
37
|
-
this.
|
|
38
|
-
this.
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
17
|
+
this.options = options;
|
|
18
|
+
this.policies = identifyPolicyInstances(options.policies.map((policy) => ({
|
|
19
|
+
...policy,
|
|
20
|
+
config: policy.config === undefined ? policy.defaultConfig : policy.config,
|
|
21
|
+
})));
|
|
22
|
+
this.exclusions = (options.exclude ?? []).map(exclusionRegex);
|
|
23
|
+
this.policyExclusions = createExcludedPolicyFileMap(this.policies);
|
|
24
|
+
this.concurrency = validateConcurrency(options.concurrency ?? DEFAULT_CONCURRENCY);
|
|
25
|
+
if (this.policies.some((policy) => policy.scope === "repository" || policy.scope === "changes") &&
|
|
26
|
+
options.inventory === undefined) {
|
|
27
|
+
throw new TypeError("Repository policies require an explicit inventory array or loader; files is only a selection.");
|
|
28
|
+
}
|
|
29
|
+
for (const policy of this.policies) {
|
|
30
|
+
if ((policy.scope === "repository" || policy.scope === "changes") &&
|
|
31
|
+
policy.resolver !== undefined) {
|
|
32
|
+
throw new TypeError("Repository policies support inline fixes only; remove resolver.");
|
|
33
|
+
}
|
|
34
|
+
if (policy.requiresConfig &&
|
|
35
|
+
policy.config === undefined &&
|
|
36
|
+
policy.defaultConfig === undefined) {
|
|
37
|
+
throw new TypeError(`Policy '${policy.name}' requires config.`);
|
|
38
|
+
}
|
|
42
39
|
}
|
|
43
|
-
this.gitRoot = options.gitRoot;
|
|
44
|
-
this.resolve = options.resolve;
|
|
45
|
-
this.logger = options.logger;
|
|
46
40
|
}
|
|
47
|
-
*run(
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
};
|
|
52
|
-
for (const filePath of filePaths) {
|
|
53
|
-
yield* this.checkOrExcludeFile(filePath, state);
|
|
41
|
+
*run() {
|
|
42
|
+
const signal = this.options.signal;
|
|
43
|
+
if (signal?.aborted) {
|
|
44
|
+
throw signal.reason;
|
|
54
45
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
46
|
+
const task = yield* spawn(() => this.runInternal());
|
|
47
|
+
// halt() is lazy; consuming it initiates teardown. The task retains any teardown error.
|
|
48
|
+
const abort = () => {
|
|
49
|
+
task.halt().catch(() => undefined);
|
|
58
50
|
};
|
|
59
|
-
|
|
60
|
-
*checkOrExcludeFile(relPath, state) {
|
|
61
|
-
state.perfStats.count++;
|
|
51
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
62
52
|
try {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
catch (error) {
|
|
66
|
-
throw new Error(`Error routing ${relPath} to handler: ${error}\nStack:\n${error.stack}`);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
*routeToPolicies(relPath, state) {
|
|
70
|
-
if (this.excludeFromAll.some((regex) => matches(regex, relPath))) {
|
|
71
|
-
this.logger?.verbose(`Excluded all handlers: ${relPath}`);
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
const matchingPolicies = this.policies.filter((policy) => matches(policy.match, relPath));
|
|
75
|
-
if (this.resolve) {
|
|
76
|
-
// Fixers can read and rewrite the same file.
|
|
77
|
-
for (const policy of matchingPolicies) {
|
|
78
|
-
yield* this.runPolicyOnFile(relPath, policy, state);
|
|
53
|
+
if (signal?.aborted) {
|
|
54
|
+
abort();
|
|
79
55
|
}
|
|
80
|
-
return;
|
|
56
|
+
return yield* task;
|
|
57
|
+
}
|
|
58
|
+
finally {
|
|
59
|
+
signal?.removeEventListener("abort", abort);
|
|
81
60
|
}
|
|
82
|
-
yield* all(matchingPolicies.map((policy) => {
|
|
83
|
-
return this.runPolicyOnFile(relPath, policy, state);
|
|
84
|
-
}));
|
|
85
61
|
}
|
|
86
|
-
*
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
62
|
+
*runInternal() {
|
|
63
|
+
const result = {
|
|
64
|
+
findings: [],
|
|
65
|
+
errors: [],
|
|
66
|
+
skipped: [],
|
|
67
|
+
perfStats: newPerfStats(),
|
|
68
|
+
};
|
|
69
|
+
const fix = this.options.fix ?? false;
|
|
70
|
+
const cache = fix ? undefined : new ParsedFileCache();
|
|
71
|
+
const rawInventory = yield* this.loadInventory();
|
|
72
|
+
if (rawInventory.some((entry) => typeof entry === "string") &&
|
|
73
|
+
this.policies.some((policy) => policy.scope === "changes")) {
|
|
74
|
+
throw new TypeError("Change-aware policies require inventory entries with Git statuses, not string paths.");
|
|
90
75
|
}
|
|
76
|
+
const inventory = snapshotInventory(rawInventory);
|
|
77
|
+
const files = this.options.files ?? inventoryPaths(inventory);
|
|
78
|
+
let fileFixError = false;
|
|
91
79
|
try {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
80
|
+
if (fix) {
|
|
81
|
+
for (const file of files) {
|
|
82
|
+
if (yield* this.runFile(file, result, cache)) {
|
|
83
|
+
fileFixError = true;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
96
86
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
policy: policy.name,
|
|
100
|
-
policyId: policy.instanceId,
|
|
101
|
-
outcome: result,
|
|
102
|
-
};
|
|
103
|
-
// Check if resolution should be attempted: result is a failure that
|
|
104
|
-
// wasn't already fixed, resolve mode is on, and a standalone resolver exists.
|
|
105
|
-
const alreadyFixed = isPolicyFixResult(result) ||
|
|
106
|
-
(isPolicyError(result) && result.fixed !== undefined);
|
|
107
|
-
if (!alreadyFixed && this.resolve && policy.resolver) {
|
|
108
|
-
const resolution = yield* this.attemptResolution(relPath, policy, policy.resolver, state);
|
|
109
|
-
fileResult.resolution = resolution;
|
|
87
|
+
else {
|
|
88
|
+
yield* this.runReadOnlyFiles(files, result, cache);
|
|
110
89
|
}
|
|
111
|
-
state.results.push(fileResult);
|
|
112
90
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
state.results.push({
|
|
116
|
-
file: relPath,
|
|
117
|
-
policy: policy.name,
|
|
118
|
-
policyId: policy.instanceId,
|
|
119
|
-
outcome: {
|
|
120
|
-
error: `System Error: Error executing policy '${policy.instanceId}' for file '${relPath}': ${message}`,
|
|
121
|
-
},
|
|
122
|
-
});
|
|
91
|
+
finally {
|
|
92
|
+
cache?.clear();
|
|
123
93
|
}
|
|
94
|
+
yield* this.runRepositories(result, inventory, fileFixError);
|
|
95
|
+
return result;
|
|
124
96
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
97
|
+
*runReadOnlyFiles(files, result, cache) {
|
|
98
|
+
const entries = files.entries();
|
|
99
|
+
const outputs = [];
|
|
100
|
+
const runner = this;
|
|
101
|
+
yield* all(Array.from({ length: Math.min(this.concurrency, files.length) }, function* () {
|
|
102
|
+
for (let entry = entries.next(); !entry.done; entry = entries.next()) {
|
|
103
|
+
const [index, file] = entry.value;
|
|
104
|
+
const local = {
|
|
105
|
+
findings: [],
|
|
106
|
+
errors: [],
|
|
107
|
+
skipped: [],
|
|
108
|
+
perfStats: result.perfStats,
|
|
109
|
+
};
|
|
110
|
+
yield* runner.runFile(file, local, cache);
|
|
111
|
+
outputs[index] = local;
|
|
112
|
+
}
|
|
113
|
+
}));
|
|
114
|
+
for (const output of outputs) {
|
|
115
|
+
result.findings.push(...output.findings);
|
|
116
|
+
result.errors.push(...output.errors);
|
|
117
|
+
result.skipped.push(...output.skipped);
|
|
118
|
+
}
|
|
129
119
|
}
|
|
130
|
-
*
|
|
131
|
-
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
config: policy.config,
|
|
138
|
-
};
|
|
139
|
-
if (policy._internalHandler) {
|
|
140
|
-
return yield* policy._internalHandler(args);
|
|
120
|
+
*runRepositories(result, initialInventory, fileFixError) {
|
|
121
|
+
let inventory = initialInventory;
|
|
122
|
+
const fix = this.options.fix ?? false;
|
|
123
|
+
let repositoryFixError = false;
|
|
124
|
+
for (const policy of this.policies) {
|
|
125
|
+
if (policy.scope !== "repository" && policy.scope !== "changes") {
|
|
126
|
+
continue;
|
|
141
127
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
128
|
+
if (fileFixError || repositoryFixError) {
|
|
129
|
+
result.skipped.push({
|
|
130
|
+
scope: policy.scope,
|
|
131
|
+
policy: policy.name,
|
|
132
|
+
policyId: policy.instanceId,
|
|
133
|
+
reason: fileFixError ? "file-fix-error" : "repository-fix-error",
|
|
134
|
+
});
|
|
135
|
+
continue;
|
|
145
136
|
}
|
|
146
|
-
if (
|
|
147
|
-
|
|
137
|
+
if (fix) {
|
|
138
|
+
const refreshed = yield* this.loadInventory();
|
|
139
|
+
inventory = annotateInventory(inventoryPaths(snapshotInventory(refreshed)), initialInventory);
|
|
148
140
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
if (result === undefined) {
|
|
152
|
-
throw new Error("Policy result was undefined.");
|
|
141
|
+
const eligible = inventory.filter((entry) => !this.excluded(entry.path, policy));
|
|
142
|
+
repositoryFixError = yield* new PolicyExecutor(this.options.root, fix).repository(policy, eligible, result);
|
|
153
143
|
}
|
|
154
|
-
return result;
|
|
155
144
|
}
|
|
156
|
-
*
|
|
157
|
-
const
|
|
158
|
-
return
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
145
|
+
*loadInventory() {
|
|
146
|
+
const inventory = this.options.inventory;
|
|
147
|
+
return ((typeof inventory === "function" ? yield* call(inventory) : inventory) ??
|
|
148
|
+
[]);
|
|
149
|
+
}
|
|
150
|
+
excluded(file, policy) {
|
|
151
|
+
return (this.exclusions.some((regex) => matchesPath(regex, file)) ||
|
|
152
|
+
(this.policyExclusions.get(policy.instanceId) ?? []).some((regex) => matchesPath(regex, file)));
|
|
153
|
+
}
|
|
154
|
+
*runFile(file, output, cache) {
|
|
155
|
+
output.perfStats.count++;
|
|
156
|
+
const globallyExcluded = this.exclusions.some((regex) => matchesPath(regex, file));
|
|
157
|
+
if (!globallyExcluded) {
|
|
158
|
+
output.perfStats.processed++;
|
|
159
|
+
}
|
|
160
|
+
let stopped = false;
|
|
161
|
+
for (const policy of this.policies) {
|
|
162
|
+
if (policy.scope !== undefined && policy.scope !== "file") {
|
|
163
|
+
continue;
|
|
166
164
|
}
|
|
167
|
-
if (
|
|
168
|
-
|
|
165
|
+
if (!matchesPath(policy.match, file)) {
|
|
166
|
+
continue;
|
|
169
167
|
}
|
|
170
|
-
|
|
171
|
-
|
|
168
|
+
if (stopped || this.excluded(file, policy)) {
|
|
169
|
+
output.skipped.push({
|
|
170
|
+
scope: "file",
|
|
171
|
+
file,
|
|
172
|
+
policy: policy.name,
|
|
173
|
+
policyId: policy.instanceId,
|
|
174
|
+
reason: stopped ? "file-fix-error" : "excluded",
|
|
175
|
+
});
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
stopped = yield* new PolicyExecutor(this.options.root, this.options.fix ?? false).file(file, policy, output, cache);
|
|
179
|
+
}
|
|
180
|
+
return stopped;
|
|
172
181
|
}
|
|
173
182
|
}
|
|
183
|
+
/** Promise entry point sharing the Effection runner's contracts and cancellation. @public */
|
|
184
|
+
export async function runPolicies(options) {
|
|
185
|
+
const runner = new PolicyRunner(options);
|
|
186
|
+
return await run(() => runner.run());
|
|
187
|
+
}
|
|
174
188
|
//# sourceMappingURL=runner.js.map
|
package/esm/runner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Logger } from \"@tylerbu/cli-api\";\nimport { all, call, type Operation } from \"effection\";\n\nimport {\n\tcreateExcludedPolicyFileMap,\n\ttype ExcludedPolicyFileMap,\n} from \"./context.js\";\nimport { identifyPolicyInstances } from \"./makePolicy.js\";\nimport {\n\tnewPerfStats,\n\ttype PolicyHandlerPerfStats,\n\trunWithPerf,\n} from \"./perf.js\";\nimport type {\n\tIdentifiedPolicy,\n\tPolicyFixResult,\n\tPolicyHandlerResult,\n\tPolicyInstance,\n\tPolicyInstanceId,\n\tPolicyName,\n\tPolicyStandaloneResolver,\n} from \"./policy.js\";\nimport { isPolicyError, isPolicyFixResult } from \"./policy.js\";\n\nfunction isOperation<T>(value: unknown): value is Operation<T> {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"next\" in value &&\n\t\ttypeof (value as { next: unknown }).next === \"function\"\n\t);\n}\n\nfunction matches(regex: RegExp, value: string): boolean {\n\tif (!(regex.global || regex.sticky)) {\n\t\treturn regex.test(value);\n\t}\n\n\tconst savedLastIndex = regex.lastIndex;\n\ttry {\n\t\tregex.lastIndex = 0;\n\t\treturn regex.test(value);\n\t} finally {\n\t\tregex.lastIndex = savedLastIndex;\n\t}\n}\n\n/**\n * Result of running a single policy on a single file.\n * @alpha\n */\nexport interface PolicyFileResult {\n\tfile: string;\n\tpolicy: PolicyName;\n\t/** Stable identity of the configured policy instance */\n\tpolicyId: PolicyInstanceId;\n\t/** The raw result from the policy handler */\n\toutcome: PolicyHandlerResult;\n\t/** Set when a standalone resolver was attempted (legacy resolver path) */\n\tresolution?: PolicyFixResult;\n}\n\n/**\n * Aggregated results from a full policy run.\n * @alpha\n */\nexport interface PolicyRunResults {\n\tresults: PolicyFileResult[];\n\tperfStats: PolicyHandlerPerfStats;\n}\n\ninterface PolicyRunState {\n\tresults: PolicyFileResult[];\n\tperfStats: PolicyHandlerPerfStats;\n}\n\n/**\n * Options for configuring a {@link PolicyRunner}.\n * @alpha\n */\nexport interface PolicyRunnerOptions {\n\tpolicies: PolicyInstance[];\n\texcludeFromAll: RegExp[];\n\texcludePoliciesForFiles: ExcludedPolicyFileMap;\n\tgitRoot: string;\n\tresolve: boolean;\n\tlogger?: Pick<Logger, \"verbose\">;\n}\n\n/**\n * Runs configured policies against files and collects results.\n * @alpha\n */\nexport class PolicyRunner {\n\tprivate readonly policies: IdentifiedPolicy[];\n\tprivate readonly excludeFromAll: RegExp[];\n\tprivate readonly excludePoliciesForFiles: ExcludedPolicyFileMap;\n\tprivate readonly gitRoot: string;\n\tprivate readonly resolve: boolean;\n\tprivate readonly logger: Pick<Logger, \"verbose\"> | undefined;\n\n\tpublic constructor(options: PolicyRunnerOptions) {\n\t\tthis.policies = identifyPolicyInstances(options.policies);\n\t\tthis.excludeFromAll = options.excludeFromAll;\n\t\tthis.excludePoliciesForFiles = createExcludedPolicyFileMap(this.policies);\n\t\tfor (const [instanceId, exclusions] of options.excludePoliciesForFiles) {\n\t\t\tthis.excludePoliciesForFiles.set(instanceId, exclusions);\n\t\t}\n\t\tthis.gitRoot = options.gitRoot;\n\t\tthis.resolve = options.resolve;\n\t\tthis.logger = options.logger;\n\t}\n\n\tpublic *run(filePaths: string[]): Operation<PolicyRunResults> {\n\t\tconst state: PolicyRunState = {\n\t\t\tresults: [],\n\t\t\tperfStats: newPerfStats(),\n\t\t};\n\n\t\tfor (const filePath of filePaths) {\n\t\t\tyield* this.checkOrExcludeFile(filePath, state);\n\t\t}\n\n\t\treturn {\n\t\t\tresults: state.results,\n\t\t\tperfStats: state.perfStats,\n\t\t};\n\t}\n\n\tprivate *checkOrExcludeFile(\n\t\trelPath: string,\n\t\tstate: PolicyRunState,\n\t): Operation<void> {\n\t\tstate.perfStats.count++;\n\t\ttry {\n\t\t\tyield* this.routeToPolicies(relPath, state);\n\t\t} catch (error: unknown) {\n\t\t\tthrow new Error(\n\t\t\t\t`Error routing ${relPath} to handler: ${error}\\nStack:\\n${(error as Error).stack}`,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate *routeToPolicies(\n\t\trelPath: string,\n\t\tstate: PolicyRunState,\n\t): Operation<void> {\n\t\tif (this.excludeFromAll.some((regex) => matches(regex, relPath))) {\n\t\t\tthis.logger?.verbose(`Excluded all handlers: ${relPath}`);\n\t\t\treturn;\n\t\t}\n\n\t\tconst matchingPolicies = this.policies.filter((policy) =>\n\t\t\tmatches(policy.match, relPath),\n\t\t);\n\t\tif (this.resolve) {\n\t\t\t// Fixers can read and rewrite the same file.\n\t\t\tfor (const policy of matchingPolicies) {\n\t\t\t\tyield* this.runPolicyOnFile(relPath, policy, state);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tyield* all(\n\t\t\tmatchingPolicies.map((policy) => {\n\t\t\t\treturn this.runPolicyOnFile(relPath, policy, state);\n\t\t\t}),\n\t\t);\n\t}\n\n\tprivate *runPolicyOnFile(\n\t\trelPath: string,\n\t\tpolicy: IdentifiedPolicy,\n\t\tstate: PolicyRunState,\n\t): Operation<void> {\n\t\tif (this.isPolicyExcluded(relPath, policy)) {\n\t\t\tthis.logger?.verbose(\n\t\t\t\t`Excluded from '${policy.instanceId}' policy: ${relPath}`,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = yield* this.executePolicyHandler(relPath, policy, state);\n\n\t\t\t// Success — nothing to report\n\t\t\tif (result === true) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst fileResult: PolicyFileResult = {\n\t\t\t\tfile: relPath,\n\t\t\t\tpolicy: policy.name,\n\t\t\t\tpolicyId: policy.instanceId,\n\t\t\t\toutcome: result,\n\t\t\t};\n\n\t\t\t// Check if resolution should be attempted: result is a failure that\n\t\t\t// wasn't already fixed, resolve mode is on, and a standalone resolver exists.\n\t\t\tconst alreadyFixed =\n\t\t\t\tisPolicyFixResult(result) ||\n\t\t\t\t(isPolicyError(result) && result.fixed !== undefined);\n\n\t\t\tif (!alreadyFixed && this.resolve && policy.resolver) {\n\t\t\t\tconst resolution = yield* this.attemptResolution(\n\t\t\t\t\trelPath,\n\t\t\t\t\tpolicy,\n\t\t\t\t\tpolicy.resolver,\n\t\t\t\t\tstate,\n\t\t\t\t);\n\t\t\t\tfileResult.resolution = resolution;\n\t\t\t}\n\n\t\t\tstate.results.push(fileResult);\n\t\t} catch (error: unknown) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tstate.results.push({\n\t\t\t\tfile: relPath,\n\t\t\t\tpolicy: policy.name,\n\t\t\t\tpolicyId: policy.instanceId,\n\t\t\t\toutcome: {\n\t\t\t\t\terror: `System Error: Error executing policy '${policy.instanceId}' for file '${relPath}': ${message}`,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate isPolicyExcluded(relPath: string, policy: IdentifiedPolicy): boolean {\n\t\treturn (\n\t\t\tthis.excludePoliciesForFiles\n\t\t\t\t.get(policy.instanceId)\n\t\t\t\t?.some((regex) => matches(regex, relPath)) ?? false\n\t\t);\n\t}\n\n\tprivate *executePolicyHandler(\n\t\trelPath: string,\n\t\tpolicy: IdentifiedPolicy,\n\t\tstate: PolicyRunState,\n\t): Operation<PolicyHandlerResult> {\n\t\tconst { resolve, gitRoot } = this;\n\n\t\tconst result = yield* runWithPerf(\n\t\t\tpolicy.instanceId,\n\t\t\t\"handle\",\n\t\t\tstate.perfStats,\n\t\t\tfunction* () {\n\t\t\t\tconst args = {\n\t\t\t\t\tfile: relPath,\n\t\t\t\t\troot: gitRoot,\n\t\t\t\t\tresolve,\n\t\t\t\t\tconfig: policy.config,\n\t\t\t\t};\n\n\t\t\t\tif (policy._internalHandler) {\n\t\t\t\t\treturn yield* policy._internalHandler(args);\n\t\t\t\t}\n\n\t\t\t\tconst handlerResult = policy.handler(args);\n\t\t\t\tif (handlerResult instanceof Promise) {\n\t\t\t\t\treturn yield* call(() => handlerResult);\n\t\t\t\t}\n\t\t\t\tif (isOperation<PolicyHandlerResult>(handlerResult)) {\n\t\t\t\t\treturn yield* handlerResult;\n\t\t\t\t}\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Unexpected handler result type: ${typeof handlerResult}`,\n\t\t\t\t);\n\t\t\t},\n\t\t);\n\n\t\tif (result === undefined) {\n\t\t\tthrow new Error(\"Policy result was undefined.\");\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tprivate *attemptResolution(\n\t\trelPath: string,\n\t\tpolicy: IdentifiedPolicy,\n\t\tresolver: PolicyStandaloneResolver,\n\t\tstate: PolicyRunState,\n\t): Operation<PolicyFixResult> {\n\t\tconst { gitRoot } = this;\n\n\t\treturn yield* runWithPerf(\n\t\t\tpolicy.instanceId,\n\t\t\t\"resolve\",\n\t\t\tstate.perfStats,\n\t\t\tfunction* () {\n\t\t\t\tconst result = resolver({\n\t\t\t\t\tfile: relPath,\n\t\t\t\t\troot: gitRoot,\n\t\t\t\t\tconfig: policy.config,\n\t\t\t\t});\n\t\t\t\tif (result instanceof Promise) {\n\t\t\t\t\treturn yield* call(() => result);\n\t\t\t\t}\n\t\t\t\tif (isOperation<PolicyFixResult>(result)) {\n\t\t\t\t\treturn yield* result;\n\t\t\t\t}\n\t\t\t\tthrow new Error(`Unexpected resolver result type: ${typeof result}`);\n\t\t\t},\n\t\t);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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","sourcesContent":["import { all, call, type Operation, run, spawn } from \"effection\";\nimport { DEFAULT_CONCURRENCY, validateConcurrency } from \"./concurrency.js\";\nimport {\n\tcreateExcludedPolicyFileMap,\n\ttype ExcludedPolicyFileMap,\n\texclusionRegex,\n\tmatchesPath,\n} from \"./context.js\";\nimport { ParsedFileCache } from \"./fileCache.js\";\nimport { identifyPolicyInstances } from \"./makePolicy.js\";\nimport { newPerfStats, type PolicyHandlerPerfStats } from \"./perf.js\";\nimport type {\n\tConfiguredPolicy,\n\tIdentifiedPolicy,\n\tPolicyFinding,\n} from \"./policy.js\";\nimport { PolicyExecutor } from \"./policyExecution.js\";\nimport {\n\tannotateInventory,\n\tinventoryPaths,\n\ttype RepositoryFile,\n\tsnapshotInventory,\n} from \"./repositoryChanges.js\";\n\n/** A finding with runner-owned identity and scope-safe location. @public */\nexport type PolicyRunFinding =\n\t| (Omit<PolicyFinding, \"files\"> & {\n\t\t\tscope: \"file\";\n\t\t\tfile: string;\n\t\t\tfiles?: never;\n\t\t\tpolicy: string;\n\t\t\tpolicyId: string;\n\t })\n\t| (PolicyFinding & {\n\t\t\tscope: \"repository\" | \"changes\";\n\t\t\tfile?: never;\n\t\t\tpolicy: string;\n\t\t\tpolicyId: string;\n\t });\n\n/** An execution failure, separate from ordinary policy findings. @public */\nexport type PolicyExecutionError = {\n\tpolicy: string;\n\tpolicyId: string;\n\tphase: \"handle\" | \"resolve\";\n\tkind: \"contract\" | \"exception\";\n\tmessage: string;\n\tcause: unknown;\n} & (\n\t| { scope: \"file\"; file: string; files?: never }\n\t| { scope: \"repository\" | \"changes\"; files: readonly string[]; file?: never }\n);\n\n/** A unit that was not executed. @public */\nexport type PolicySkippedWork = {\n\tpolicy: string;\n\tpolicyId: string;\n\treason: \"excluded\" | \"file-fix-error\" | \"repository-fix-error\";\n} & (\n\t| { scope: \"file\"; file: string }\n\t| { scope: \"repository\" | \"changes\"; file?: never }\n);\n\n/** Findings, failures, skipped units, and file/per-instance timing statistics. @public */\nexport interface PolicyRunResults {\n\tfindings: PolicyRunFinding[];\n\terrors: PolicyExecutionError[];\n\tskipped: PolicySkippedWork[];\n\tperfStats: PolicyHandlerPerfStats;\n}\n\n/** Full repository inventory, never inferred from a file selection. @public */\nexport type RepositoryInventory =\n\t| readonly (string | RepositoryFile)[]\n\t| (() => Promise<readonly (string | RepositoryFile)[]>);\n\n/** Shared Promise and Effection runner options. @public */\nexport interface PolicyRunnerOptions {\n\tpolicies: readonly ConfiguredPolicy[];\n\troot: string;\n\tinventory?: RepositoryInventory | undefined;\n\t/** Selection limits only file policies. Defaults to inventory when supplied. */\n\tfiles?: readonly string[] | undefined;\n\texclude?: readonly (string | RegExp)[] | undefined;\n\tfix?: boolean | undefined;\n\tconcurrency?: number | undefined;\n\tsignal?: AbortSignal | undefined;\n}\n\n/** Effection runner; cancellation unwinds active generator handlers and resolvers. @public */\nexport class PolicyRunner {\n\tprivate readonly policies: IdentifiedPolicy[];\n\tprivate readonly exclusions: RegExp[];\n\tprivate readonly policyExclusions: ExcludedPolicyFileMap;\n\tprivate readonly concurrency: number;\n\n\tpublic constructor(private readonly options: PolicyRunnerOptions) {\n\t\tthis.policies = identifyPolicyInstances(\n\t\t\toptions.policies.map((policy) => ({\n\t\t\t\t...policy,\n\t\t\t\tconfig:\n\t\t\t\t\tpolicy.config === undefined ? policy.defaultConfig : policy.config,\n\t\t\t})),\n\t\t);\n\t\tthis.exclusions = (options.exclude ?? []).map(exclusionRegex);\n\t\tthis.policyExclusions = createExcludedPolicyFileMap(this.policies);\n\t\tthis.concurrency = validateConcurrency(\n\t\t\toptions.concurrency ?? DEFAULT_CONCURRENCY,\n\t\t);\n\t\tif (\n\t\t\tthis.policies.some(\n\t\t\t\t(policy) => policy.scope === \"repository\" || policy.scope === \"changes\",\n\t\t\t) &&\n\t\t\toptions.inventory === undefined\n\t\t) {\n\t\t\tthrow new TypeError(\n\t\t\t\t\"Repository policies require an explicit inventory array or loader; files is only a selection.\",\n\t\t\t);\n\t\t}\n\t\tfor (const policy of this.policies) {\n\t\t\tif (\n\t\t\t\t(policy.scope === \"repository\" || policy.scope === \"changes\") &&\n\t\t\t\tpolicy.resolver !== undefined\n\t\t\t) {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\"Repository policies support inline fixes only; remove resolver.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (\n\t\t\t\tpolicy.requiresConfig &&\n\t\t\t\tpolicy.config === undefined &&\n\t\t\t\tpolicy.defaultConfig === undefined\n\t\t\t) {\n\t\t\t\tthrow new TypeError(`Policy '${policy.name}' requires config.`);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic *run(): Operation<PolicyRunResults> {\n\t\tconst signal = this.options.signal;\n\t\tif (signal?.aborted) {\n\t\t\tthrow signal.reason;\n\t\t}\n\t\tconst task = yield* spawn(() => this.runInternal());\n\t\t// halt() is lazy; consuming it initiates teardown. The task retains any teardown error.\n\t\tconst abort = () => {\n\t\t\ttask.halt().catch(() => undefined);\n\t\t};\n\t\tsignal?.addEventListener(\"abort\", abort, { once: true });\n\t\ttry {\n\t\t\tif (signal?.aborted) {\n\t\t\t\tabort();\n\t\t\t}\n\t\t\treturn yield* task;\n\t\t} finally {\n\t\t\tsignal?.removeEventListener(\"abort\", abort);\n\t\t}\n\t}\n\n\tprivate *runInternal(): Operation<PolicyRunResults> {\n\t\tconst result: PolicyRunResults = {\n\t\t\tfindings: [],\n\t\t\terrors: [],\n\t\t\tskipped: [],\n\t\t\tperfStats: newPerfStats(),\n\t\t};\n\t\tconst fix = this.options.fix ?? false;\n\t\tconst cache = fix ? undefined : new ParsedFileCache();\n\t\tconst rawInventory = yield* this.loadInventory();\n\t\tif (\n\t\t\trawInventory.some((entry) => typeof entry === \"string\") &&\n\t\t\tthis.policies.some((policy) => policy.scope === \"changes\")\n\t\t) {\n\t\t\tthrow new TypeError(\n\t\t\t\t\"Change-aware policies require inventory entries with Git statuses, not string paths.\",\n\t\t\t);\n\t\t}\n\t\tconst inventory = snapshotInventory(rawInventory);\n\t\tconst files = this.options.files ?? inventoryPaths(inventory);\n\t\tlet fileFixError = false;\n\t\ttry {\n\t\t\tif (fix) {\n\t\t\t\tfor (const file of files) {\n\t\t\t\t\tif (yield* this.runFile(file, result, cache)) {\n\t\t\t\t\t\tfileFixError = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tyield* this.runReadOnlyFiles(files, result, cache);\n\t\t\t}\n\t\t} finally {\n\t\t\tcache?.clear();\n\t\t}\n\t\tyield* this.runRepositories(result, inventory, fileFixError);\n\t\treturn result;\n\t}\n\n\tprivate *runReadOnlyFiles(\n\t\tfiles: readonly string[],\n\t\tresult: PolicyRunResults,\n\t\tcache: ParsedFileCache | undefined,\n\t): Operation<void> {\n\t\tconst entries = files.entries();\n\t\tconst outputs: PolicyRunResults[] = [];\n\t\tconst runner = this;\n\t\tyield* all(\n\t\t\tArray.from(\n\t\t\t\t{ length: Math.min(this.concurrency, files.length) },\n\t\t\t\tfunction* () {\n\t\t\t\t\tfor (\n\t\t\t\t\t\tlet entry = entries.next();\n\t\t\t\t\t\t!entry.done;\n\t\t\t\t\t\tentry = entries.next()\n\t\t\t\t\t) {\n\t\t\t\t\t\tconst [index, file] = entry.value;\n\t\t\t\t\t\tconst local: PolicyRunResults = {\n\t\t\t\t\t\t\tfindings: [],\n\t\t\t\t\t\t\terrors: [],\n\t\t\t\t\t\t\tskipped: [],\n\t\t\t\t\t\t\tperfStats: result.perfStats,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tyield* runner.runFile(file, local, cache);\n\t\t\t\t\t\toutputs[index] = local;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t\t);\n\t\tfor (const output of outputs) {\n\t\t\tresult.findings.push(...output.findings);\n\t\t\tresult.errors.push(...output.errors);\n\t\t\tresult.skipped.push(...output.skipped);\n\t\t}\n\t}\n\n\tprivate *runRepositories(\n\t\tresult: PolicyRunResults,\n\t\tinitialInventory: readonly RepositoryFile[],\n\t\tfileFixError: boolean,\n\t): Operation<void> {\n\t\tlet inventory = initialInventory;\n\t\tconst fix = this.options.fix ?? false;\n\t\tlet repositoryFixError = false;\n\t\tfor (const policy of this.policies) {\n\t\t\tif (policy.scope !== \"repository\" && policy.scope !== \"changes\") {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (fileFixError || repositoryFixError) {\n\t\t\t\tresult.skipped.push({\n\t\t\t\t\tscope: policy.scope,\n\t\t\t\t\tpolicy: policy.name,\n\t\t\t\t\tpolicyId: policy.instanceId,\n\t\t\t\t\treason: fileFixError ? \"file-fix-error\" : \"repository-fix-error\",\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (fix) {\n\t\t\t\tconst refreshed = yield* this.loadInventory();\n\t\t\t\tinventory = annotateInventory(\n\t\t\t\t\tinventoryPaths(snapshotInventory(refreshed)),\n\t\t\t\t\tinitialInventory,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst eligible = inventory.filter(\n\t\t\t\t(entry) => !this.excluded(entry.path, policy),\n\t\t\t);\n\t\t\trepositoryFixError = yield* new PolicyExecutor(\n\t\t\t\tthis.options.root,\n\t\t\t\tfix,\n\t\t\t).repository(policy, eligible, result);\n\t\t}\n\t}\n\n\tprivate *loadInventory(): Operation<readonly (string | RepositoryFile)[]> {\n\t\tconst inventory = this.options.inventory;\n\t\treturn (\n\t\t\t(typeof inventory === \"function\" ? yield* call(inventory) : inventory) ??\n\t\t\t[]\n\t\t);\n\t}\n\n\tprivate excluded(file: string, policy: IdentifiedPolicy): boolean {\n\t\treturn (\n\t\t\tthis.exclusions.some((regex) => matchesPath(regex, file)) ||\n\t\t\t(this.policyExclusions.get(policy.instanceId) ?? []).some((regex) =>\n\t\t\t\tmatchesPath(regex, file),\n\t\t\t)\n\t\t);\n\t}\n\n\tprivate *runFile(\n\t\tfile: string,\n\t\toutput: PolicyRunResults,\n\t\tcache: ParsedFileCache | undefined,\n\t): Operation<boolean> {\n\t\toutput.perfStats.count++;\n\t\tconst globallyExcluded = this.exclusions.some((regex) =>\n\t\t\tmatchesPath(regex, file),\n\t\t);\n\t\tif (!globallyExcluded) {\n\t\t\toutput.perfStats.processed++;\n\t\t}\n\t\tlet stopped = false;\n\t\tfor (const policy of this.policies) {\n\t\t\tif (policy.scope !== undefined && policy.scope !== \"file\") {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!matchesPath(policy.match, file)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (stopped || this.excluded(file, policy)) {\n\t\t\t\toutput.skipped.push({\n\t\t\t\t\tscope: \"file\",\n\t\t\t\t\tfile,\n\t\t\t\t\tpolicy: policy.name,\n\t\t\t\t\tpolicyId: policy.instanceId,\n\t\t\t\t\treason: stopped ? \"file-fix-error\" : \"excluded\",\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tstopped = yield* new PolicyExecutor(\n\t\t\t\tthis.options.root,\n\t\t\t\tthis.options.fix ?? false,\n\t\t\t).file(file, policy, output, cache);\n\t\t}\n\t\treturn stopped;\n\t}\n}\n\n/** Promise entry point sharing the Effection runner's contracts and cancellation. @public */\nexport async function runPolicies(\n\toptions: PolicyRunnerOptions,\n): Promise<PolicyRunResults> {\n\tconst runner = new PolicyRunner(options);\n\treturn await run(() => runner.run());\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settlePolicyPromise.d.ts","sourceRoot":"","sources":["../src/settlePolicyPromise.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAEjD,6EAA6E;AAC7E,wBAAiB,mBAAmB,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAWzE"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { call } from "effection";
|
|
2
|
+
/** Keep arbitrary rejected values out of Effection's error normalization. */
|
|
3
|
+
export function* settlePolicyPromise(promise) {
|
|
4
|
+
const settled = yield* call(() => promise.then((value) => ({ ok: true, value }), (cause) => ({ ok: false, cause })));
|
|
5
|
+
if (!settled.ok) {
|
|
6
|
+
throw settled.cause;
|
|
7
|
+
}
|
|
8
|
+
return settled.value;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=settlePolicyPromise.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settlePolicyPromise.js","sourceRoot":"","sources":["../src/settlePolicyPromise.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAkB,MAAM,WAAW,CAAC;AAEjD,6EAA6E;AAC7E,MAAM,SAAS,CAAC,CAAC,mBAAmB,CAAI,OAAmB;IAC1D,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAChC,OAAO,CAAC,IAAI,CACX,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAU,EACzC,CAAC,KAAc,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAU,CACnD,CACD,CAAC;IACF,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,OAAO,CAAC,KAAK,CAAC;IACrB,CAAC;IACD,OAAO,OAAO,CAAC,KAAK,CAAC;AACtB,CAAC","sourcesContent":["import { call, type Operation } from \"effection\";\n\n/** Keep arbitrary rejected values out of Effection's error normalization. */\nexport function* settlePolicyPromise<T>(promise: Promise<T>): Operation<T> {\n\tconst settled = yield* call(() =>\n\t\tpromise.then(\n\t\t\t(value) => ({ ok: true, value }) as const,\n\t\t\t(cause: unknown) => ({ ok: false, cause }) as const,\n\t\t),\n\t);\n\tif (!settled.ok) {\n\t\tthrow settled.cause;\n\t}\n\treturn settled.value;\n}\n"]}
|
package/esm/tsdoc-metadata.json
CHANGED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves a candidate file path against the repository root and verifies it does not escape that root.
|
|
3
|
+
*/
|
|
4
|
+
export declare function resolveRepoFilePath(root: string, filePath: string): string;
|
|
5
|
+
/**
|
|
6
|
+
* Converts an input path into a normalized repository-relative path after validating root containment.
|
|
7
|
+
*/
|
|
8
|
+
export declare function normalizeRepoRelativeFilePath(root: string, filePath: string): string;
|
|
9
|
+
//# sourceMappingURL=safePaths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safePaths.d.ts","sourceRoot":"","sources":["../../src/utils/safePaths.ts"],"names":[],"mappings":"AAkBA;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAe1E;AAED;;GAEG;AACH,wBAAgB,6BAA6B,CAC5C,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GACd,MAAM,CAaR"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { isAbsolute, normalize, relative, resolve } from "pathe";
|
|
2
|
+
function normalizeRoot(root) {
|
|
3
|
+
return normalize(resolve(root));
|
|
4
|
+
}
|
|
5
|
+
function isPathWithinRoot(rootPath, candidatePath) {
|
|
6
|
+
const relativePath = normalize(relative(rootPath, candidatePath));
|
|
7
|
+
if (relativePath === "" || relativePath === ".") {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
return (!isAbsolute(relativePath) &&
|
|
11
|
+
relativePath !== ".." &&
|
|
12
|
+
!relativePath.startsWith("../"));
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Resolves a candidate file path against the repository root and verifies it does not escape that root.
|
|
16
|
+
*/
|
|
17
|
+
export function resolveRepoFilePath(root, filePath) {
|
|
18
|
+
if (filePath.trim().length === 0) {
|
|
19
|
+
throw new Error("File path cannot be empty.");
|
|
20
|
+
}
|
|
21
|
+
const rootPath = normalizeRoot(root);
|
|
22
|
+
const candidatePath = normalize(resolve(rootPath, filePath));
|
|
23
|
+
if (!isPathWithinRoot(rootPath, candidatePath)) {
|
|
24
|
+
throw new Error(`File path must be within repository root. Received: ${filePath}`);
|
|
25
|
+
}
|
|
26
|
+
return candidatePath;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Converts an input path into a normalized repository-relative path after validating root containment.
|
|
30
|
+
*/
|
|
31
|
+
export function normalizeRepoRelativeFilePath(root, filePath) {
|
|
32
|
+
const rootPath = normalizeRoot(root);
|
|
33
|
+
const absolutePath = resolveRepoFilePath(rootPath, filePath);
|
|
34
|
+
const relativePath = normalize(relative(rootPath, absolutePath)).replace(/\\/g, "/");
|
|
35
|
+
if (relativePath === "" || relativePath === ".") {
|
|
36
|
+
throw new Error("File path resolves to repository root instead of a file.");
|
|
37
|
+
}
|
|
38
|
+
return relativePath;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=safePaths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safePaths.js","sourceRoot":"","sources":["../../src/utils/safePaths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAEjE,SAAS,aAAa,CAAC,IAAY;IAClC,OAAO,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;AACjC,CAAC;AAED,SAAS,gBAAgB,CAAC,QAAgB,EAAE,aAAqB;IAChE,MAAM,YAAY,GAAG,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC;IAClE,IAAI,YAAY,KAAK,EAAE,IAAI,YAAY,KAAK,GAAG,EAAE,CAAC;QACjD,OAAO,IAAI,CAAC;IACb,CAAC;IACD,OAAO,CACN,CAAC,UAAU,CAAC,YAAY,CAAC;QACzB,YAAY,KAAK,IAAI;QACrB,CAAC,YAAY,CAAC,UAAU,CAAC,KAAK,CAAC,CAC/B,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY,EAAE,QAAgB;IACjE,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAC/C,CAAC;IAED,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,aAAa,GAAG,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;IAE7D,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,aAAa,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CACd,uDAAuD,QAAQ,EAAE,CACjE,CAAC;IACH,CAAC;IAED,OAAO,aAAa,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,6BAA6B,CAC5C,IAAY,EACZ,QAAgB;IAEhB,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,YAAY,GAAG,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC7D,MAAM,YAAY,GAAG,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,OAAO,CACvE,KAAK,EACL,GAAG,CACH,CAAC;IAEF,IAAI,YAAY,KAAK,EAAE,IAAI,YAAY,KAAK,GAAG,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC7E,CAAC;IAED,OAAO,YAAY,CAAC;AACrB,CAAC","sourcesContent":["import { isAbsolute, normalize, relative, resolve } from \"pathe\";\n\nfunction normalizeRoot(root: string): string {\n\treturn normalize(resolve(root));\n}\n\nfunction isPathWithinRoot(rootPath: string, candidatePath: string): boolean {\n\tconst relativePath = normalize(relative(rootPath, candidatePath));\n\tif (relativePath === \"\" || relativePath === \".\") {\n\t\treturn true;\n\t}\n\treturn (\n\t\t!isAbsolute(relativePath) &&\n\t\trelativePath !== \"..\" &&\n\t\t!relativePath.startsWith(\"../\")\n\t);\n}\n\n/**\n * Resolves a candidate file path against the repository root and verifies it does not escape that root.\n */\nexport function resolveRepoFilePath(root: string, filePath: string): string {\n\tif (filePath.trim().length === 0) {\n\t\tthrow new Error(\"File path cannot be empty.\");\n\t}\n\n\tconst rootPath = normalizeRoot(root);\n\tconst candidatePath = normalize(resolve(rootPath, filePath));\n\n\tif (!isPathWithinRoot(rootPath, candidatePath)) {\n\t\tthrow new Error(\n\t\t\t`File path must be within repository root. Received: ${filePath}`,\n\t\t);\n\t}\n\n\treturn candidatePath;\n}\n\n/**\n * Converts an input path into a normalized repository-relative path after validating root containment.\n */\nexport function normalizeRepoRelativeFilePath(\n\troot: string,\n\tfilePath: string,\n): string {\n\tconst rootPath = normalizeRoot(root);\n\tconst absolutePath = resolveRepoFilePath(rootPath, filePath);\n\tconst relativePath = normalize(relative(rootPath, absolutePath)).replace(\n\t\t/\\\\/g,\n\t\t\"/\",\n\t);\n\n\tif (relativePath === \"\" || relativePath === \".\") {\n\t\tthrow new Error(\"File path resolves to repository root instead of a file.\");\n\t}\n\n\treturn relativePath;\n}\n"]}
|
package/oclif.manifest.json
CHANGED
|
@@ -3,8 +3,35 @@
|
|
|
3
3
|
"check-native": {
|
|
4
4
|
"aliases": [],
|
|
5
5
|
"args": {},
|
|
6
|
-
"description": "Runs the Rust-based repopo-core engine with the Node.js sidecar.
|
|
6
|
+
"description": "Runs the Rust-based repopo-core engine with the Node.js sidecar. Rust handles file matching, scheduling and reporting; the sidecar shares per-policy contracts with 'check'. Repository policies always run with the full repository inventory, including with --stdin. With --fix, repository policies can modify files outside the stdin selection.",
|
|
7
7
|
"flags": {
|
|
8
|
+
"change-mode": {
|
|
9
|
+
"description": "Change context: pr (default), local, or staged. Does not select file-policy paths.",
|
|
10
|
+
"name": "change-mode",
|
|
11
|
+
"hasDynamicHelp": false,
|
|
12
|
+
"multiple": false,
|
|
13
|
+
"options": [
|
|
14
|
+
"pr",
|
|
15
|
+
"local",
|
|
16
|
+
"staged"
|
|
17
|
+
],
|
|
18
|
+
"type": "option"
|
|
19
|
+
},
|
|
20
|
+
"change-base": {
|
|
21
|
+
"description": "Override the PR change context base ref.",
|
|
22
|
+
"name": "change-base",
|
|
23
|
+
"hasDynamicHelp": false,
|
|
24
|
+
"multiple": false,
|
|
25
|
+
"type": "option"
|
|
26
|
+
},
|
|
27
|
+
"concurrency": {
|
|
28
|
+
"description": "Maximum concurrent files in read-only checks. Fixes remain sequential.",
|
|
29
|
+
"name": "concurrency",
|
|
30
|
+
"default": 8,
|
|
31
|
+
"hasDynamicHelp": false,
|
|
32
|
+
"multiple": false,
|
|
33
|
+
"type": "option"
|
|
34
|
+
},
|
|
8
35
|
"fix": {
|
|
9
36
|
"aliases": [
|
|
10
37
|
"resolve"
|
|
@@ -100,6 +127,7 @@
|
|
|
100
127
|
"check": {
|
|
101
128
|
"aliases": [],
|
|
102
129
|
"args": {},
|
|
130
|
+
"description": "File policies check selected files. Repository policies always run with the full repository file inventory, including with --stdin. With --fix, repository policies can modify files outside the stdin selection.",
|
|
103
131
|
"flags": {
|
|
104
132
|
"verbose": {
|
|
105
133
|
"char": "v",
|
|
@@ -124,6 +152,33 @@
|
|
|
124
152
|
"allowNo": false,
|
|
125
153
|
"type": "boolean"
|
|
126
154
|
},
|
|
155
|
+
"change-mode": {
|
|
156
|
+
"description": "Change context: pr (default), local, or staged. Does not select file-policy paths.",
|
|
157
|
+
"name": "change-mode",
|
|
158
|
+
"hasDynamicHelp": false,
|
|
159
|
+
"multiple": false,
|
|
160
|
+
"options": [
|
|
161
|
+
"pr",
|
|
162
|
+
"local",
|
|
163
|
+
"staged"
|
|
164
|
+
],
|
|
165
|
+
"type": "option"
|
|
166
|
+
},
|
|
167
|
+
"change-base": {
|
|
168
|
+
"description": "Override the PR change context base ref.",
|
|
169
|
+
"name": "change-base",
|
|
170
|
+
"hasDynamicHelp": false,
|
|
171
|
+
"multiple": false,
|
|
172
|
+
"type": "option"
|
|
173
|
+
},
|
|
174
|
+
"concurrency": {
|
|
175
|
+
"description": "Maximum concurrent files in read-only checks. Fixes remain sequential.",
|
|
176
|
+
"name": "concurrency",
|
|
177
|
+
"default": 8,
|
|
178
|
+
"hasDynamicHelp": false,
|
|
179
|
+
"multiple": false,
|
|
180
|
+
"type": "option"
|
|
181
|
+
},
|
|
127
182
|
"fix": {
|
|
128
183
|
"aliases": [
|
|
129
184
|
"resolve"
|
|
@@ -222,5 +277,5 @@
|
|
|
222
277
|
]
|
|
223
278
|
}
|
|
224
279
|
},
|
|
225
|
-
"version": "0.
|
|
280
|
+
"version": "0.14.0"
|
|
226
281
|
}
|