repopo 0.12.0 → 0.13.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.
Files changed (333) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README.md +50 -90
  3. package/THIRD-PARTY-LICENSES.txt +169 -11
  4. package/bin/dev.js +0 -0
  5. package/esm/adapters/fluidFramework.d.ts +13 -9
  6. package/esm/adapters/fluidFramework.d.ts.map +1 -1
  7. package/esm/adapters/fluidFramework.js +20 -43
  8. package/esm/adapters/fluidFramework.js.map +1 -1
  9. package/esm/api.d.ts +64 -1
  10. package/esm/api.d.ts.map +1 -1
  11. package/esm/api.js +17 -1
  12. package/esm/api.js.map +1 -1
  13. package/esm/baseCommand.d.ts.map +1 -1
  14. package/esm/baseCommand.js +2 -2
  15. package/esm/baseCommand.js.map +1 -1
  16. package/esm/commands/check-native.d.ts +3 -3
  17. package/esm/commands/check-native.d.ts.map +1 -1
  18. package/esm/commands/check-native.js +26 -7
  19. package/esm/commands/check-native.js.map +1 -1
  20. package/esm/commands/check.d.ts +6 -21
  21. package/esm/commands/check.d.ts.map +1 -1
  22. package/esm/commands/check.js +73 -153
  23. package/esm/commands/check.js.map +1 -1
  24. package/esm/commands/list.d.ts.map +1 -1
  25. package/esm/commands/list.js +2 -1
  26. package/esm/commands/list.js.map +1 -1
  27. package/esm/concurrency.d.ts +3 -0
  28. package/esm/concurrency.d.ts.map +1 -0
  29. package/esm/concurrency.js +8 -0
  30. package/esm/concurrency.js.map +1 -0
  31. package/esm/config.d.ts +5 -39
  32. package/esm/config.d.ts.map +1 -1
  33. package/esm/config.js +3 -7
  34. package/esm/config.js.map +1 -1
  35. package/esm/context.d.ts +8 -1
  36. package/esm/context.d.ts.map +1 -1
  37. package/esm/context.js +8 -1
  38. package/esm/context.js.map +1 -1
  39. package/esm/executionContractError.d.ts +4 -0
  40. package/esm/executionContractError.d.ts.map +1 -0
  41. package/esm/executionContractError.js +4 -0
  42. package/esm/executionContractError.js.map +1 -0
  43. package/esm/fileCache.d.ts +12 -0
  44. package/esm/fileCache.d.ts.map +1 -0
  45. package/esm/fileCache.js +37 -0
  46. package/esm/fileCache.js.map +1 -0
  47. package/esm/filePaths.d.ts +2 -0
  48. package/esm/filePaths.d.ts.map +1 -0
  49. package/esm/filePaths.js +9 -0
  50. package/esm/filePaths.js.map +1 -0
  51. package/esm/generators.d.ts +0 -20
  52. package/esm/generators.d.ts.map +1 -1
  53. package/esm/generators.js.map +1 -1
  54. package/esm/index.d.ts +3 -16
  55. package/esm/index.d.ts.map +1 -1
  56. package/esm/index.js +3 -17
  57. package/esm/index.js.map +1 -1
  58. package/esm/makePolicy.d.ts +20 -100
  59. package/esm/makePolicy.d.ts.map +1 -1
  60. package/esm/makePolicy.js +44 -132
  61. package/esm/makePolicy.js.map +1 -1
  62. package/esm/perf.d.ts +5 -2
  63. package/esm/perf.d.ts.map +1 -1
  64. package/esm/perf.js +10 -9
  65. package/esm/perf.js.map +1 -1
  66. package/esm/policies/CargoLicenceValidated.d.ts +4 -4
  67. package/esm/policies/CargoLicenceValidated.d.ts.map +1 -1
  68. package/esm/policies/CargoLicenceValidated.js +9 -7
  69. package/esm/policies/CargoLicenceValidated.js.map +1 -1
  70. package/esm/policies/CargoLintsConfigured.d.ts +4 -4
  71. package/esm/policies/CargoLintsConfigured.d.ts.map +1 -1
  72. package/esm/policies/CargoLintsConfigured.js +19 -15
  73. package/esm/policies/CargoLintsConfigured.js.map +1 -1
  74. package/esm/policies/CargoLockPolicy.d.ts +4 -4
  75. package/esm/policies/CargoLockPolicy.d.ts.map +1 -1
  76. package/esm/policies/CargoLockPolicy.js +15 -11
  77. package/esm/policies/CargoLockPolicy.js.map +1 -1
  78. package/esm/policies/CargoTomlRequired.d.ts +5 -5
  79. package/esm/policies/CargoTomlRequired.d.ts.map +1 -1
  80. package/esm/policies/CargoTomlRequired.js +7 -7
  81. package/esm/policies/CargoTomlRequired.js.map +1 -1
  82. package/esm/policies/CargoTomlSorted.d.ts +4 -4
  83. package/esm/policies/CargoTomlSorted.d.ts.map +1 -1
  84. package/esm/policies/CargoTomlSorted.js +21 -17
  85. package/esm/policies/CargoTomlSorted.js.map +1 -1
  86. package/esm/policies/ConditionalScripts.d.ts +10 -8
  87. package/esm/policies/ConditionalScripts.d.ts.map +1 -1
  88. package/esm/policies/ConditionalScripts.js +24 -22
  89. package/esm/policies/ConditionalScripts.js.map +1 -1
  90. package/esm/policies/ExactScripts.d.ts +8 -6
  91. package/esm/policies/ExactScripts.d.ts.map +1 -1
  92. package/esm/policies/ExactScripts.js +15 -18
  93. package/esm/policies/ExactScripts.js.map +1 -1
  94. package/esm/policies/GleamDepVersions.d.ts +5 -5
  95. package/esm/policies/GleamDepVersions.d.ts.map +1 -1
  96. package/esm/policies/GleamDepVersions.js +5 -5
  97. package/esm/policies/GleamDepVersions.js.map +1 -1
  98. package/esm/policies/GleamDocExists.d.ts +4 -4
  99. package/esm/policies/GleamDocExists.d.ts.map +1 -1
  100. package/esm/policies/GleamDocExists.js +6 -6
  101. package/esm/policies/GleamDocExists.js.map +1 -1
  102. package/esm/policies/GleamInternalModulesConfigured.d.ts +4 -4
  103. package/esm/policies/GleamInternalModulesConfigured.d.ts.map +1 -1
  104. package/esm/policies/GleamInternalModulesConfigured.js +8 -6
  105. package/esm/policies/GleamInternalModulesConfigured.js.map +1 -1
  106. package/esm/policies/GleamLicenceConfigured.d.ts +4 -4
  107. package/esm/policies/GleamLicenceConfigured.d.ts.map +1 -1
  108. package/esm/policies/GleamLicenceConfigured.js +8 -6
  109. package/esm/policies/GleamLicenceConfigured.js.map +1 -1
  110. package/esm/policies/GleamManifestCommitted.d.ts +10 -3
  111. package/esm/policies/GleamManifestCommitted.d.ts.map +1 -1
  112. package/esm/policies/GleamManifestCommitted.js +10 -9
  113. package/esm/policies/GleamManifestCommitted.js.map +1 -1
  114. package/esm/policies/GleamMonorepoConsistency.d.ts +13 -5
  115. package/esm/policies/GleamMonorepoConsistency.d.ts.map +1 -1
  116. package/esm/policies/GleamMonorepoConsistency.js +10 -10
  117. package/esm/policies/GleamMonorepoConsistency.js.map +1 -1
  118. package/esm/policies/GleamNameRestrictions.d.ts +4 -4
  119. package/esm/policies/GleamNameRestrictions.d.ts.map +1 -1
  120. package/esm/policies/GleamNameRestrictions.js +6 -6
  121. package/esm/policies/GleamNameRestrictions.js.map +1 -1
  122. package/esm/policies/GleamNoPathDepsInPublished.d.ts +4 -4
  123. package/esm/policies/GleamNoPathDepsInPublished.d.ts.map +1 -1
  124. package/esm/policies/GleamNoPathDepsInPublished.js +6 -6
  125. package/esm/policies/GleamNoPathDepsInPublished.js.map +1 -1
  126. package/esm/policies/GleamPathDepsValid.d.ts +3 -3
  127. package/esm/policies/GleamPathDepsValid.d.ts.map +1 -1
  128. package/esm/policies/GleamPathDepsValid.js +5 -5
  129. package/esm/policies/GleamPathDepsValid.js.map +1 -1
  130. package/esm/policies/GleamProjectStructure.d.ts +11 -4
  131. package/esm/policies/GleamProjectStructure.d.ts.map +1 -1
  132. package/esm/policies/GleamProjectStructure.js +7 -8
  133. package/esm/policies/GleamProjectStructure.js.map +1 -1
  134. package/esm/policies/GleamSharedDependencyVersions.d.ts +12 -4
  135. package/esm/policies/GleamSharedDependencyVersions.d.ts.map +1 -1
  136. package/esm/policies/GleamSharedDependencyVersions.js +10 -10
  137. package/esm/policies/GleamSharedDependencyVersions.js.map +1 -1
  138. package/esm/policies/GleamTomlRequired.d.ts +4 -4
  139. package/esm/policies/GleamTomlRequired.d.ts.map +1 -1
  140. package/esm/policies/GleamTomlRequired.js +5 -5
  141. package/esm/policies/GleamTomlRequired.js.map +1 -1
  142. package/esm/policies/GleamTomlSorted.d.ts +4 -4
  143. package/esm/policies/GleamTomlSorted.d.ts.map +1 -1
  144. package/esm/policies/GleamTomlSorted.js +21 -17
  145. package/esm/policies/GleamTomlSorted.js.map +1 -1
  146. package/esm/policies/GleamVersionConstraint.d.ts +4 -4
  147. package/esm/policies/GleamVersionConstraint.d.ts.map +1 -1
  148. package/esm/policies/GleamVersionConstraint.js +14 -10
  149. package/esm/policies/GleamVersionConstraint.js.map +1 -1
  150. package/esm/policies/HtmlFileHeaders.d.ts +4 -2
  151. package/esm/policies/HtmlFileHeaders.d.ts.map +1 -1
  152. package/esm/policies/HtmlFileHeaders.js +1 -1
  153. package/esm/policies/HtmlFileHeaders.js.map +1 -1
  154. package/esm/policies/JsTsFileHeaders.d.ts +4 -2
  155. package/esm/policies/JsTsFileHeaders.d.ts.map +1 -1
  156. package/esm/policies/JsTsFileHeaders.js +1 -1
  157. package/esm/policies/JsTsFileHeaders.js.map +1 -1
  158. package/esm/policies/LicenseFileExists.d.ts +10 -4
  159. package/esm/policies/LicenseFileExists.d.ts.map +1 -1
  160. package/esm/policies/LicenseFileExists.js +27 -20
  161. package/esm/policies/LicenseFileExists.js.map +1 -1
  162. package/esm/policies/MutuallyExclusiveScripts.d.ts +8 -6
  163. package/esm/policies/MutuallyExclusiveScripts.d.ts.map +1 -1
  164. package/esm/policies/MutuallyExclusiveScripts.js +9 -13
  165. package/esm/policies/MutuallyExclusiveScripts.js.map +1 -1
  166. package/esm/policies/NoBuildDirectory.d.ts +9 -3
  167. package/esm/policies/NoBuildDirectory.d.ts.map +1 -1
  168. package/esm/policies/NoBuildDirectory.js +8 -13
  169. package/esm/policies/NoBuildDirectory.js.map +1 -1
  170. package/esm/policies/NoJsFileExtensions.d.ts +9 -3
  171. package/esm/policies/NoJsFileExtensions.d.ts.map +1 -1
  172. package/esm/policies/NoJsFileExtensions.js +9 -14
  173. package/esm/policies/NoJsFileExtensions.js.map +1 -1
  174. package/esm/policies/NoLargeBinaryFiles.d.ts +9 -4
  175. package/esm/policies/NoLargeBinaryFiles.d.ts.map +1 -1
  176. package/esm/policies/NoLargeBinaryFiles.js +10 -16
  177. package/esm/policies/NoLargeBinaryFiles.js.map +1 -1
  178. package/esm/policies/NoPrivateWorkspaceDependencies.d.ts +10 -6
  179. package/esm/policies/NoPrivateWorkspaceDependencies.d.ts.map +1 -1
  180. package/esm/policies/NoPrivateWorkspaceDependencies.js +12 -14
  181. package/esm/policies/NoPrivateWorkspaceDependencies.js.map +1 -1
  182. package/esm/policies/NoTargetArtifacts.d.ts +9 -3
  183. package/esm/policies/NoTargetArtifacts.d.ts.map +1 -1
  184. package/esm/policies/NoTargetArtifacts.js +9 -14
  185. package/esm/policies/NoTargetArtifacts.js.map +1 -1
  186. package/esm/policies/NoUnsafeWithoutJustification.d.ts +11 -4
  187. package/esm/policies/NoUnsafeWithoutJustification.d.ts.map +1 -1
  188. package/esm/policies/NoUnsafeWithoutJustification.js +8 -9
  189. package/esm/policies/NoUnsafeWithoutJustification.js.map +1 -1
  190. package/esm/policies/NoWildcardDependencies.d.ts +5 -5
  191. package/esm/policies/NoWildcardDependencies.d.ts.map +1 -1
  192. package/esm/policies/NoWildcardDependencies.js +6 -6
  193. package/esm/policies/NoWildcardDependencies.js.map +1 -1
  194. package/esm/policies/PackageAllowedScopes.d.ts +9 -5
  195. package/esm/policies/PackageAllowedScopes.d.ts.map +1 -1
  196. package/esm/policies/PackageAllowedScopes.js +15 -16
  197. package/esm/policies/PackageAllowedScopes.js.map +1 -1
  198. package/esm/policies/PackageEsmType.d.ts +7 -5
  199. package/esm/policies/PackageEsmType.d.ts.map +1 -1
  200. package/esm/policies/PackageEsmType.js +31 -31
  201. package/esm/policies/PackageEsmType.js.map +1 -1
  202. package/esm/policies/PackageFolderName.d.ts +8 -6
  203. package/esm/policies/PackageFolderName.d.ts.map +1 -1
  204. package/esm/policies/PackageFolderName.js +13 -16
  205. package/esm/policies/PackageFolderName.js.map +1 -1
  206. package/esm/policies/PackageJsonProperties.d.ts +5 -3
  207. package/esm/policies/PackageJsonProperties.d.ts.map +1 -1
  208. package/esm/policies/PackageJsonProperties.js +6 -17
  209. package/esm/policies/PackageJsonProperties.js.map +1 -1
  210. package/esm/policies/PackageJsonRepoDirectoryProperty.d.ts +2 -7
  211. package/esm/policies/PackageJsonRepoDirectoryProperty.d.ts.map +1 -1
  212. package/esm/policies/PackageJsonRepoDirectoryProperty.js +28 -42
  213. package/esm/policies/PackageJsonRepoDirectoryProperty.js.map +1 -1
  214. package/esm/policies/PackageJsonSorted.d.ts +2 -2
  215. package/esm/policies/PackageJsonSorted.d.ts.map +1 -1
  216. package/esm/policies/PackageJsonSorted.js +15 -30
  217. package/esm/policies/PackageJsonSorted.js.map +1 -1
  218. package/esm/policies/PackageLicense.d.ts +4 -4
  219. package/esm/policies/PackageLicense.d.ts.map +1 -1
  220. package/esm/policies/PackageLicense.js +31 -52
  221. package/esm/policies/PackageLicense.js.map +1 -1
  222. package/esm/policies/PackagePrivateField.d.ts +12 -8
  223. package/esm/policies/PackagePrivateField.d.ts.map +1 -1
  224. package/esm/policies/PackagePrivateField.js +31 -23
  225. package/esm/policies/PackagePrivateField.js.map +1 -1
  226. package/esm/policies/PackageReadme.d.ts +6 -5
  227. package/esm/policies/PackageReadme.d.ts.map +1 -1
  228. package/esm/policies/PackageReadme.js +22 -59
  229. package/esm/policies/PackageReadme.js.map +1 -1
  230. package/esm/policies/PackageScripts.d.ts +26 -22
  231. package/esm/policies/PackageScripts.d.ts.map +1 -1
  232. package/esm/policies/PackageScripts.js +39 -36
  233. package/esm/policies/PackageScripts.js.map +1 -1
  234. package/esm/policies/PackageTestScripts.d.ts +10 -6
  235. package/esm/policies/PackageTestScripts.d.ts.map +1 -1
  236. package/esm/policies/PackageTestScripts.js +14 -16
  237. package/esm/policies/PackageTestScripts.js.map +1 -1
  238. package/esm/policies/PublicApiDocumented.d.ts +4 -4
  239. package/esm/policies/PublicApiDocumented.d.ts.map +1 -1
  240. package/esm/policies/PublicApiDocumented.js +10 -8
  241. package/esm/policies/PublicApiDocumented.js.map +1 -1
  242. package/esm/policies/RequiredGitignorePatterns.d.ts +11 -4
  243. package/esm/policies/RequiredGitignorePatterns.d.ts.map +1 -1
  244. package/esm/policies/RequiredGitignorePatterns.js +29 -36
  245. package/esm/policies/RequiredGitignorePatterns.js.map +1 -1
  246. package/esm/policies/RequiredScripts.d.ts +9 -7
  247. package/esm/policies/RequiredScripts.d.ts.map +1 -1
  248. package/esm/policies/RequiredScripts.js +24 -24
  249. package/esm/policies/RequiredScripts.js.map +1 -1
  250. package/esm/policies/RustDocExists.d.ts +4 -4
  251. package/esm/policies/RustDocExists.d.ts.map +1 -1
  252. package/esm/policies/RustDocExists.js +6 -6
  253. package/esm/policies/RustDocExists.js.map +1 -1
  254. package/esm/policies/RustToolchainExists.d.ts +11 -4
  255. package/esm/policies/RustToolchainExists.d.ts.map +1 -1
  256. package/esm/policies/RustToolchainExists.js +10 -9
  257. package/esm/policies/RustToolchainExists.js.map +1 -1
  258. package/esm/policies/RustfmtConfigExists.d.ts +11 -4
  259. package/esm/policies/RustfmtConfigExists.d.ts.map +1 -1
  260. package/esm/policies/RustfmtConfigExists.js +10 -9
  261. package/esm/policies/RustfmtConfigExists.js.map +1 -1
  262. package/esm/policies/ScriptContains.d.ts +9 -7
  263. package/esm/policies/ScriptContains.d.ts.map +1 -1
  264. package/esm/policies/ScriptContains.js +9 -13
  265. package/esm/policies/ScriptContains.js.map +1 -1
  266. package/esm/policies/SharedDependencyVersions.d.ts +9 -4
  267. package/esm/policies/SharedDependencyVersions.d.ts.map +1 -1
  268. package/esm/policies/SharedDependencyVersions.js +28 -20
  269. package/esm/policies/SharedDependencyVersions.js.map +1 -1
  270. package/esm/policies/WorkspaceInheritance.d.ts +11 -4
  271. package/esm/policies/WorkspaceInheritance.d.ts.map +1 -1
  272. package/esm/policies/WorkspaceInheritance.js +10 -11
  273. package/esm/policies/WorkspaceInheritance.js.map +1 -1
  274. package/esm/policies/WorkspaceMembersValid.d.ts +11 -4
  275. package/esm/policies/WorkspaceMembersValid.d.ts.map +1 -1
  276. package/esm/policies/WorkspaceMembersValid.js +10 -11
  277. package/esm/policies/WorkspaceMembersValid.js.map +1 -1
  278. package/esm/policies/constants.d.ts.map +1 -1
  279. package/esm/policies/constants.js +1 -1
  280. package/esm/policies/constants.js.map +1 -1
  281. package/esm/policies.d.ts +13 -5
  282. package/esm/policies.d.ts.map +1 -1
  283. package/esm/policies.js +12 -5
  284. package/esm/policies.js.map +1 -1
  285. package/esm/policy.d.ts +61 -289
  286. package/esm/policy.d.ts.map +1 -1
  287. package/esm/policy.js +1 -122
  288. package/esm/policy.js.map +1 -1
  289. package/esm/policyDefiners/defineCargoPolicy.d.ts +25 -9
  290. package/esm/policyDefiners/defineCargoPolicy.d.ts.map +1 -1
  291. package/esm/policyDefiners/defineCargoPolicy.js +10 -28
  292. package/esm/policyDefiners/defineCargoPolicy.js.map +1 -1
  293. package/esm/policyDefiners/defineFileHeaderPolicy.d.ts +27 -14
  294. package/esm/policyDefiners/defineFileHeaderPolicy.d.ts.map +1 -1
  295. package/esm/policyDefiners/defineFileHeaderPolicy.js +16 -35
  296. package/esm/policyDefiners/defineFileHeaderPolicy.js.map +1 -1
  297. package/esm/policyDefiners/defineGleamPolicy.d.ts +25 -9
  298. package/esm/policyDefiners/defineGleamPolicy.d.ts.map +1 -1
  299. package/esm/policyDefiners/defineGleamPolicy.js +10 -27
  300. package/esm/policyDefiners/defineGleamPolicy.js.map +1 -1
  301. package/esm/policyDefiners/definePackagePolicy.d.ts +24 -13
  302. package/esm/policyDefiners/definePackagePolicy.d.ts.map +1 -1
  303. package/esm/policyDefiners/definePackagePolicy.js +9 -32
  304. package/esm/policyDefiners/definePackagePolicy.js.map +1 -1
  305. package/esm/policyDefiners/spdxValidator.d.ts +4 -12
  306. package/esm/policyDefiners/spdxValidator.d.ts.map +1 -1
  307. package/esm/policyDefiners/spdxValidator.js +26 -14
  308. package/esm/policyDefiners/spdxValidator.js.map +1 -1
  309. package/esm/policyExecution.d.ts +19 -0
  310. package/esm/policyExecution.d.ts.map +1 -0
  311. package/esm/policyExecution.js +224 -0
  312. package/esm/policyExecution.js.map +1 -0
  313. package/esm/repositoryFiles.d.ts +4 -0
  314. package/esm/repositoryFiles.d.ts.map +1 -0
  315. package/esm/repositoryFiles.js +8 -0
  316. package/esm/repositoryFiles.js.map +1 -0
  317. package/esm/runner.d.ts +72 -47
  318. package/esm/runner.d.ts.map +1 -1
  319. package/esm/runner.js +153 -138
  320. package/esm/runner.js.map +1 -1
  321. package/esm/settlePolicyPromise.d.ts +4 -0
  322. package/esm/settlePolicyPromise.d.ts.map +1 -0
  323. package/esm/settlePolicyPromise.js +10 -0
  324. package/esm/settlePolicyPromise.js.map +1 -0
  325. package/esm/tsdoc-metadata.json +1 -1
  326. package/esm/utils/safePaths.d.ts +9 -0
  327. package/esm/utils/safePaths.d.ts.map +1 -0
  328. package/esm/utils/safePaths.js +40 -0
  329. package/esm/utils/safePaths.js.map +1 -0
  330. package/oclif.manifest.json +19 -2
  331. package/package.json +42 -27
  332. package/scripts/benchmark.mjs +341 -0
  333. package/sidecar/sidecar.mjs +348 -417
@@ -1,41 +1,34 @@
1
- import { EOL as newline } from "node:os";
2
1
  import process from "node:process";
3
2
  import { Flags } from "@oclif/core";
4
- import { StringBuilder } from "@rushstack/node-core-library";
5
- import { call, run } from "effection";
6
- import chalk from "picocolors";
7
3
  import { BaseRepopoCommand } from "../baseCommand.js";
4
+ import { DEFAULT_CONCURRENCY, validateConcurrency } from "../concurrency.js";
5
+ import { parseFilePaths } from "../filePaths.js";
8
6
  import { logStats } from "../perf.js";
9
- import { isPolicyError, isPolicyFixResult, } from "../policy.js";
10
- import { PolicyRunner } from "../runner.js";
7
+ import { readRepositoryFiles } from "../repositoryFiles.js";
8
+ import { runPolicies, } from "../runner.js";
9
+ import { normalizeRepoRelativeFilePath } from "../utils/safePaths.js";
11
10
  async function readStdin() {
12
- return new Promise((resolve) => {
13
- const stdin = process.stdin;
14
- stdin.setEncoding("utf8");
15
- let data = "";
16
- stdin.on("data", (chunk) => {
17
- data += chunk;
18
- });
19
- stdin.on("end", () => {
20
- resolve(data);
21
- });
22
- if (stdin.isTTY) {
23
- resolve("");
24
- }
25
- });
11
+ if (process.stdin.isTTY) {
12
+ return "";
13
+ }
14
+ process.stdin.setEncoding("utf8");
15
+ let data = "";
16
+ for await (const chunk of process.stdin) {
17
+ data += chunk;
18
+ }
19
+ return data;
26
20
  }
27
- /**
28
- * This tool enforces policies across the code base via a series of handler functions. The handler functions are
29
- * associated with a regular expression, and all files matching that expression are passed to the handler function.
30
- *
31
- * By default, the list of files to check comes from `git ls-files. You can also pipe in file names from stdin. For
32
- * example:
33
- *
34
- * `git ls-files -co --exclude-standard --full-name | repopo check --stdin --verbose`
35
- */
21
+ /** Check selected files and the complete repository inventory. */
36
22
  export class CheckPolicy extends BaseRepopoCommand {
37
23
  static summary = "Checks and applies policies to the files in the repository.";
24
+ static description = "File policies check selected files. Repository policies always run with the full repository file inventory, " +
25
+ "including with --stdin. With --fix, repository policies can modify files outside the stdin selection.";
38
26
  static flags = {
27
+ concurrency: Flags.integer({
28
+ description: "Maximum concurrent files in read-only checks. Fixes remain sequential.",
29
+ default: DEFAULT_CONCURRENCY,
30
+ parse: async (value) => validateConcurrency(Number(value)),
31
+ }),
39
32
  fix: Flags.boolean({
40
33
  aliases: ["resolve"],
41
34
  description: "Fix errors if possible.",
@@ -52,147 +45,74 @@ export class CheckPolicy extends BaseRepopoCommand {
52
45
  if (this.flags.fix) {
53
46
  this.info("Resolving errors if possible.");
54
47
  }
55
- const filePathsToCheck = await this.collectFilePaths();
56
48
  const context = await this.getContext();
49
+ const files = await this.collectFilePaths(context.gitRoot);
57
50
  this.verbose(`${context.policies.length} policies loaded.`);
58
- for (const configuredPolicy of context.policies) {
59
- this.verbose(configuredPolicy.instanceId);
51
+ for (const policy of context.policies) {
52
+ this.verbose(policy.instanceId);
60
53
  }
61
- const runner = new PolicyRunner({
54
+ const results = await runPolicies({
62
55
  policies: context.policies,
63
- excludeFromAll: context.excludeFromAll,
64
- excludePoliciesForFiles: context.excludePoliciesForFiles,
65
- gitRoot: context.gitRoot,
66
- resolve: this.flags.fix,
67
- logger: this.logger,
56
+ root: context.gitRoot,
57
+ files,
58
+ inventory: () => this.collectRepositoryFiles(),
59
+ exclude: context.excludeFromAll,
60
+ fix: this.flags.fix,
61
+ concurrency: this.flags.concurrency,
68
62
  });
69
- const runResults = await run(() => runner.run(filePathsToCheck));
70
- // Format and log results
71
- for (const result of runResults.results) {
72
- this.formatResult(result);
73
- }
74
- if (!this.flags.quiet) {
75
- logStats(runResults.perfStats, this.logger);
63
+ for (const finding of results.findings) {
64
+ this.reportFinding(finding);
76
65
  }
77
- }
78
- /**
79
- * Collects file paths to check from either stdin or git ls-files.
80
- */
81
- async collectFilePaths() {
82
- if (this.flags.stdin) {
83
- const stdInput = await run(function* () {
84
- return yield* call(() => readStdin());
85
- });
86
- if (stdInput !== undefined && stdInput !== null) {
87
- return stdInput
88
- .replace(
89
- // normalize slashes in case they're windows paths
90
- /\\/g, "/")
91
- .split("\n");
92
- }
93
- return [];
66
+ for (const error of results.errors) {
67
+ this.reportError(error);
94
68
  }
95
- const gitFiles = (await this.git.raw("ls-files",
96
- // include staged files and untracked files
97
- "-co",
98
- // NUL-delimited paths are not quoted or escaped by Git.
99
- "-z",
100
- // exclude gitignored files and other standard ignore rules
101
- "--exclude-standard",
102
- // Outputs paths relative to the root of the repository, regardless of the current working directory.
103
- "--full-name")) ?? "";
104
- return gitFiles.split("\0").filter((file) => file.length > 0);
105
- }
106
- /**
107
- * Formats a single policy file result, logging messages and setting exit codes.
108
- */
109
- formatResult(result) {
110
- const { outcome, resolution } = result;
111
- // Handle fix results (legacy format with resolved property)
112
- if (isPolicyFixResult(outcome)) {
113
- this.formatFixResult(outcome.resolved, outcome.file, result.policyId);
114
- return;
69
+ for (const skipped of results.skipped) {
70
+ this.verbose(`Skipped ${skipped.policyId}: ${skipped.scope === "file" ? skipped.file : "repository"} (${skipped.reason})`);
115
71
  }
116
- // Handle new PolicyError with fixed property (fix was attempted inline)
117
- if (isPolicyError(outcome) && outcome.fixed !== undefined) {
118
- this.formatPolicyErrorFixResult(outcome, result.file, result.policyId);
119
- return;
72
+ if (!this.flags.quiet) {
73
+ logStats(results.perfStats, this.logger);
120
74
  }
121
- // Handle failure with standalone resolver result
122
- if (resolution !== undefined) {
123
- this.formatResolutionResult(resolution, result.file, result.policyId);
75
+ }
76
+ reportFinding(finding) {
77
+ const location = finding.scope === "file"
78
+ ? finding.file
79
+ : finding.files?.join(", ") || "repository";
80
+ const message = `${finding.policyId}: ${location}: ${finding.message}`;
81
+ if (finding.fixStatus === "fixed") {
82
+ this.info(`Resolved ${message}`);
124
83
  return;
125
84
  }
126
- // Handle plain failure (no fix attempted)
127
- // The runner only collects non-true results, but TypeScript needs explicit narrowing
128
- if (outcome === true) {
129
- return;
85
+ process.exitCode = 1;
86
+ this.warning(message);
87
+ if (finding.manualFix) {
88
+ this.warning(`Manual fix: ${finding.manualFix}`);
130
89
  }
131
- this.formatPolicyFailure(outcome, result.file, result.policyId);
132
90
  }
133
- formatFixResult(resolved, file, policyName) {
134
- const messages = new StringBuilder();
135
- if (resolved) {
136
- messages.append(`Resolved ${policyName} policy failure for file: ${file}`);
137
- }
138
- else {
139
- messages.append(`Error fixing ${policyName} policy failure in ${file}`);
140
- process.exitCode = 1;
141
- }
142
- this.logMessages(messages);
91
+ reportError(error) {
92
+ process.exitCode = 1;
93
+ const location = error.scope === "file"
94
+ ? error.file
95
+ : error.files.join(", ") || "repository";
96
+ this.warning(`Execution error (${error.kind}, ${error.phase}) ${error.policyId}: ${location}: ${error.message}`);
143
97
  }
144
- formatPolicyErrorFixResult(result, file, policyName) {
145
- const messages = new StringBuilder();
146
- if (result.fixed) {
147
- messages.append(`Resolved ${policyName} policy failure for file: ${file}`);
148
- }
149
- else {
150
- messages.append(`Error fixing ${policyName} policy failure in ${file}`);
151
- if (result.error) {
152
- messages.append(`${newline}\t${result.error}`);
98
+ async collectFilePaths(gitRoot) {
99
+ const paths = this.flags.stdin
100
+ ? parseFilePaths(await readStdin())
101
+ : await this.collectRepositoryFiles();
102
+ return paths.map((filePath) => {
103
+ try {
104
+ return normalizeRepoRelativeFilePath(gitRoot, filePath);
153
105
  }
154
- process.exitCode = 1;
155
- }
156
- this.logMessages(messages);
157
- }
158
- formatResolutionResult(resolution, file, policyName) {
159
- const messages = new StringBuilder();
160
- messages.append(`${newline}Attempting to resolve '${policyName}' policy failure for file: ${file}`);
161
- if (!resolution.resolved) {
162
- process.exitCode = 1;
163
- }
164
- if (resolution.errorMessages && resolution.errorMessages.length > 0) {
165
- messages.append(newline + resolution.errorMessages.join(newline));
166
- }
167
- this.logMessages(messages);
168
- }
169
- formatPolicyFailure(result, file, policyName) {
170
- const messages = new StringBuilder();
171
- // Handle both legacy PolicyFailure and new PolicyError formats
172
- if (isPolicyError(result)) {
173
- const autoFixable = result.fixable ? chalk.green(" (autofixable)") : "";
174
- messages.append(`'${chalk.bold(policyName)}' policy failure${autoFixable}: ${file}`);
175
- messages.append(`${newline}\t${result.error}`);
176
- }
177
- else {
178
- const autoFixable = result.autoFixable
179
- ? chalk.green(" (autofixable)")
180
- : "";
181
- messages.append(`'${chalk.bold(policyName)}' policy failure${autoFixable}: ${result.file}`);
182
- if (result.errorMessages?.length > 0) {
183
- messages.append(`${newline}\t${result.errorMessages.join(`${newline}\t`)}`);
106
+ catch (error) {
107
+ const message = error instanceof Error ? error.message : String(error);
108
+ throw new Error(`Invalid file path '${filePath}': ${message}`, {
109
+ cause: error,
110
+ });
184
111
  }
185
- }
186
- process.exitCode = 1;
187
- this.logMessages(messages);
112
+ });
188
113
  }
189
- logMessages(messages) {
190
- if ((process.exitCode ?? 0) === 0) {
191
- this.info(messages.toString());
192
- }
193
- else {
194
- this.warning(messages.toString());
195
- }
114
+ async collectRepositoryFiles() {
115
+ return readRepositoryFiles(this.git);
196
116
  }
197
117
  }
198
118
  //# sourceMappingURL=check.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"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","sourcesContent":["import { EOL as newline } from \"node:os\";\nimport process from \"node:process\";\nimport { Flags } from \"@oclif/core\";\nimport { StringBuilder } from \"@rushstack/node-core-library\";\nimport { call, run } from \"effection\";\nimport chalk from \"picocolors\";\n\nimport { BaseRepopoCommand } from \"../baseCommand.js\";\nimport type { RepopoCommandContext } from \"../context.js\";\nimport { logStats } from \"../perf.js\";\nimport {\n\tisPolicyError,\n\tisPolicyFixResult,\n\ttype PolicyError,\n\ttype PolicyFailure,\n} from \"../policy.js\";\nimport { type PolicyFileResult, PolicyRunner } from \"../runner.js\";\n\nasync function readStdin(): Promise<string> {\n\treturn new Promise((resolve) => {\n\t\tconst stdin = process.stdin;\n\t\tstdin.setEncoding(\"utf8\");\n\n\t\tlet data = \"\";\n\t\tstdin.on(\"data\", (chunk) => {\n\t\t\tdata += chunk;\n\t\t});\n\n\t\tstdin.on(\"end\", () => {\n\t\t\tresolve(data);\n\t\t});\n\n\t\tif (stdin.isTTY) {\n\t\t\tresolve(\"\");\n\t\t}\n\t});\n}\n\n/**\n * This tool enforces policies across the code base via a series of handler functions. The handler functions are\n * associated with a regular expression, and all files matching that expression are passed to the handler function.\n *\n * By default, the list of files to check comes from `git ls-files. You can also pipe in file names from stdin. For\n * example:\n *\n * `git ls-files -co --exclude-standard --full-name | repopo check --stdin --verbose`\n */\nexport class CheckPolicy<\n\tT extends typeof BaseRepopoCommand & {\n\t\targs: typeof CheckPolicy.args;\n\t\tflags: typeof CheckPolicy.flags;\n\t},\n> extends BaseRepopoCommand<T> {\n\tpublic static override readonly summary =\n\t\t\"Checks and applies policies to the files in the repository.\";\n\n\tpublic static override readonly flags = {\n\t\tfix: Flags.boolean({\n\t\t\taliases: [\"resolve\"],\n\t\t\tdescription: \"Fix errors if possible.\",\n\t\t\trequired: false,\n\t\t\tchar: \"f\",\n\t\t}),\n\t\tstdin: Flags.boolean({\n\t\t\tdescription: \"Read list of files from stdin.\",\n\t\t\trequired: false,\n\t\t}),\n\t\t...BaseRepopoCommand.flags,\n\t} as const;\n\n\tpublic override async run(): Promise<void> {\n\t\tif (this.flags.fix) {\n\t\t\tthis.info(\"Resolving errors if possible.\");\n\t\t}\n\n\t\tconst filePathsToCheck = await this.collectFilePaths();\n\t\tconst context: RepopoCommandContext = await this.getContext();\n\t\tthis.verbose(`${context.policies.length} policies loaded.`);\n\t\tfor (const configuredPolicy of context.policies) {\n\t\t\tthis.verbose(configuredPolicy.instanceId);\n\t\t}\n\n\t\tconst runner = new PolicyRunner({\n\t\t\tpolicies: context.policies,\n\t\t\texcludeFromAll: context.excludeFromAll,\n\t\t\texcludePoliciesForFiles: context.excludePoliciesForFiles,\n\t\t\tgitRoot: context.gitRoot,\n\t\t\tresolve: this.flags.fix,\n\t\t\tlogger: this.logger,\n\t\t});\n\n\t\tconst runResults = await run(() => runner.run(filePathsToCheck));\n\n\t\t// Format and log results\n\t\tfor (const result of runResults.results) {\n\t\t\tthis.formatResult(result);\n\t\t}\n\n\t\tif (!this.flags.quiet) {\n\t\t\tlogStats(runResults.perfStats, this.logger);\n\t\t}\n\t}\n\n\t/**\n\t * Collects file paths to check from either stdin or git ls-files.\n\t */\n\tprivate async collectFilePaths(): Promise<string[]> {\n\t\tif (this.flags.stdin) {\n\t\t\tconst stdInput = await run(function* () {\n\t\t\t\treturn yield* call(() => readStdin());\n\t\t\t});\n\n\t\t\tif (stdInput !== undefined && stdInput !== null) {\n\t\t\t\treturn stdInput\n\t\t\t\t\t.replace(\n\t\t\t\t\t\t// normalize slashes in case they're windows paths\n\t\t\t\t\t\t/\\\\/g,\n\t\t\t\t\t\t\"/\",\n\t\t\t\t\t)\n\t\t\t\t\t.split(\"\\n\");\n\t\t\t}\n\n\t\t\treturn [];\n\t\t}\n\n\t\tconst gitFiles =\n\t\t\t(await this.git.raw(\n\t\t\t\t\"ls-files\",\n\t\t\t\t// include staged files and untracked files\n\t\t\t\t\"-co\",\n\t\t\t\t// NUL-delimited paths are not quoted or escaped by Git.\n\t\t\t\t\"-z\",\n\t\t\t\t// exclude gitignored files and other standard ignore rules\n\t\t\t\t\"--exclude-standard\",\n\t\t\t\t// Outputs paths relative to the root of the repository, regardless of the current working directory.\n\t\t\t\t\"--full-name\",\n\t\t\t)) ?? \"\";\n\n\t\treturn gitFiles.split(\"\\0\").filter((file) => file.length > 0);\n\t}\n\n\t/**\n\t * Formats a single policy file result, logging messages and setting exit codes.\n\t */\n\tprivate formatResult(result: PolicyFileResult): void {\n\t\tconst { outcome, resolution } = result;\n\n\t\t// Handle fix results (legacy format with resolved property)\n\t\tif (isPolicyFixResult(outcome)) {\n\t\t\tthis.formatFixResult(outcome.resolved, outcome.file, result.policyId);\n\t\t\treturn;\n\t\t}\n\n\t\t// Handle new PolicyError with fixed property (fix was attempted inline)\n\t\tif (isPolicyError(outcome) && outcome.fixed !== undefined) {\n\t\t\tthis.formatPolicyErrorFixResult(outcome, result.file, result.policyId);\n\t\t\treturn;\n\t\t}\n\n\t\t// Handle failure with standalone resolver result\n\t\tif (resolution !== undefined) {\n\t\t\tthis.formatResolutionResult(resolution, result.file, result.policyId);\n\t\t\treturn;\n\t\t}\n\n\t\t// Handle plain failure (no fix attempted)\n\t\t// The runner only collects non-true results, but TypeScript needs explicit narrowing\n\t\tif (outcome === true) {\n\t\t\treturn;\n\t\t}\n\t\tthis.formatPolicyFailure(outcome, result.file, result.policyId);\n\t}\n\n\tprivate formatFixResult(\n\t\tresolved: boolean,\n\t\tfile: string,\n\t\tpolicyName: string,\n\t): void {\n\t\tconst messages = new StringBuilder();\n\n\t\tif (resolved) {\n\t\t\tmessages.append(\n\t\t\t\t`Resolved ${policyName} policy failure for file: ${file}`,\n\t\t\t);\n\t\t} else {\n\t\t\tmessages.append(`Error fixing ${policyName} policy failure in ${file}`);\n\t\t\tprocess.exitCode = 1;\n\t\t}\n\n\t\tthis.logMessages(messages);\n\t}\n\n\tprivate formatPolicyErrorFixResult(\n\t\tresult: PolicyError,\n\t\tfile: string,\n\t\tpolicyName: string,\n\t): void {\n\t\tconst messages = new StringBuilder();\n\n\t\tif (result.fixed) {\n\t\t\tmessages.append(\n\t\t\t\t`Resolved ${policyName} policy failure for file: ${file}`,\n\t\t\t);\n\t\t} else {\n\t\t\tmessages.append(`Error fixing ${policyName} policy failure in ${file}`);\n\t\t\tif (result.error) {\n\t\t\t\tmessages.append(`${newline}\\t${result.error}`);\n\t\t\t}\n\t\t\tprocess.exitCode = 1;\n\t\t}\n\n\t\tthis.logMessages(messages);\n\t}\n\n\tprivate formatResolutionResult(\n\t\tresolution: { resolved: boolean; errorMessages?: string[] },\n\t\tfile: string,\n\t\tpolicyName: string,\n\t): void {\n\t\tconst messages = new StringBuilder();\n\t\tmessages.append(\n\t\t\t`${newline}Attempting to resolve '${policyName}' policy failure for file: ${file}`,\n\t\t);\n\n\t\tif (!resolution.resolved) {\n\t\t\tprocess.exitCode = 1;\n\t\t}\n\n\t\tif (resolution.errorMessages && resolution.errorMessages.length > 0) {\n\t\t\tmessages.append(newline + resolution.errorMessages.join(newline));\n\t\t}\n\n\t\tthis.logMessages(messages);\n\t}\n\n\tprivate formatPolicyFailure(\n\t\tresult: PolicyFailure | PolicyError,\n\t\tfile: string,\n\t\tpolicyName: string,\n\t): void {\n\t\tconst messages = new StringBuilder();\n\n\t\t// Handle both legacy PolicyFailure and new PolicyError formats\n\t\tif (isPolicyError(result)) {\n\t\t\tconst autoFixable = result.fixable ? chalk.green(\" (autofixable)\") : \"\";\n\t\t\tmessages.append(\n\t\t\t\t`'${chalk.bold(policyName)}' policy failure${autoFixable}: ${file}`,\n\t\t\t);\n\t\t\tmessages.append(`${newline}\\t${result.error}`);\n\t\t} else {\n\t\t\tconst autoFixable = result.autoFixable\n\t\t\t\t? chalk.green(\" (autofixable)\")\n\t\t\t\t: \"\";\n\t\t\tmessages.append(\n\t\t\t\t`'${chalk.bold(policyName)}' policy failure${autoFixable}: ${result.file}`,\n\t\t\t);\n\t\t\tif (result.errorMessages?.length > 0) {\n\t\t\t\tmessages.append(\n\t\t\t\t\t`${newline}\\t${result.errorMessages.join(`${newline}\\t`)}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tprocess.exitCode = 1;\n\n\t\tthis.logMessages(messages);\n\t}\n\n\tprivate logMessages(messages: StringBuilder): void {\n\t\tif ((process.exitCode ?? 0) === 0) {\n\t\t\tthis.info(messages.toString());\n\t\t} else {\n\t\t\tthis.warning(messages.toString());\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"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","sourcesContent":["import process from \"node:process\";\nimport { Flags } from \"@oclif/core\";\nimport { BaseRepopoCommand } from \"../baseCommand.js\";\nimport { DEFAULT_CONCURRENCY, validateConcurrency } from \"../concurrency.js\";\nimport { parseFilePaths } from \"../filePaths.js\";\nimport { logStats } from \"../perf.js\";\nimport { readRepositoryFiles } from \"../repositoryFiles.js\";\nimport {\n\ttype PolicyExecutionError,\n\ttype PolicyRunFinding,\n\trunPolicies,\n} from \"../runner.js\";\nimport { normalizeRepoRelativeFilePath } from \"../utils/safePaths.js\";\n\nasync function readStdin(): Promise<string> {\n\tif (process.stdin.isTTY) {\n\t\treturn \"\";\n\t}\n\tprocess.stdin.setEncoding(\"utf8\");\n\tlet data = \"\";\n\tfor await (const chunk of process.stdin) {\n\t\tdata += chunk;\n\t}\n\treturn data;\n}\n\n/** Check selected files and the complete repository inventory. */\nexport class CheckPolicy<\n\tT extends typeof BaseRepopoCommand & {\n\t\targs: typeof CheckPolicy.args;\n\t\tflags: typeof CheckPolicy.flags;\n\t},\n> extends BaseRepopoCommand<T> {\n\tpublic static override readonly summary =\n\t\t\"Checks and applies policies to the files in the repository.\";\n\n\tpublic static override readonly description =\n\t\t\"File policies check selected files. Repository policies always run with the full repository file inventory, \" +\n\t\t\"including with --stdin. With --fix, repository policies can modify files outside the stdin selection.\";\n\n\tpublic static override readonly flags = {\n\t\tconcurrency: Flags.integer({\n\t\t\tdescription:\n\t\t\t\t\"Maximum concurrent files in read-only checks. Fixes remain sequential.\",\n\t\t\tdefault: DEFAULT_CONCURRENCY,\n\t\t\tparse: async (value) => validateConcurrency(Number(value)),\n\t\t}),\n\t\tfix: Flags.boolean({\n\t\t\taliases: [\"resolve\"],\n\t\t\tdescription: \"Fix errors if possible.\",\n\t\t\trequired: false,\n\t\t\tchar: \"f\",\n\t\t}),\n\t\tstdin: Flags.boolean({\n\t\t\tdescription: \"Read list of files from stdin.\",\n\t\t\trequired: false,\n\t\t}),\n\t\t...BaseRepopoCommand.flags,\n\t} as const;\n\n\tpublic override async run(): Promise<void> {\n\t\tif (this.flags.fix) {\n\t\t\tthis.info(\"Resolving errors if possible.\");\n\t\t}\n\t\tconst context = await this.getContext();\n\t\tconst files = await this.collectFilePaths(context.gitRoot);\n\t\tthis.verbose(`${context.policies.length} policies loaded.`);\n\t\tfor (const policy of context.policies) {\n\t\t\tthis.verbose(policy.instanceId);\n\t\t}\n\t\tconst results = await runPolicies({\n\t\t\tpolicies: context.policies,\n\t\t\troot: context.gitRoot,\n\t\t\tfiles,\n\t\t\tinventory: () => this.collectRepositoryFiles(),\n\t\t\texclude: context.excludeFromAll,\n\t\t\tfix: this.flags.fix,\n\t\t\tconcurrency: this.flags.concurrency,\n\t\t});\n\t\tfor (const finding of results.findings) {\n\t\t\tthis.reportFinding(finding);\n\t\t}\n\t\tfor (const error of results.errors) {\n\t\t\tthis.reportError(error);\n\t\t}\n\n\t\tfor (const skipped of results.skipped) {\n\t\t\tthis.verbose(\n\t\t\t\t`Skipped ${skipped.policyId}: ${skipped.scope === \"file\" ? skipped.file : \"repository\"} (${skipped.reason})`,\n\t\t\t);\n\t\t}\n\n\t\tif (!this.flags.quiet) {\n\t\t\tlogStats(results.perfStats, this.logger);\n\t\t}\n\t}\n\n\tprivate reportFinding(finding: PolicyRunFinding): void {\n\t\tconst location =\n\t\t\tfinding.scope === \"file\"\n\t\t\t\t? finding.file\n\t\t\t\t: finding.files?.join(\", \") || \"repository\";\n\t\tconst message = `${finding.policyId}: ${location}: ${finding.message}`;\n\t\tif (finding.fixStatus === \"fixed\") {\n\t\t\tthis.info(`Resolved ${message}`);\n\t\t\treturn;\n\t\t}\n\t\tprocess.exitCode = 1;\n\t\tthis.warning(message);\n\t\tif (finding.manualFix) {\n\t\t\tthis.warning(`Manual fix: ${finding.manualFix}`);\n\t\t}\n\t}\n\n\tprivate reportError(error: PolicyExecutionError): void {\n\t\tprocess.exitCode = 1;\n\t\tconst location =\n\t\t\terror.scope === \"file\"\n\t\t\t\t? error.file\n\t\t\t\t: error.files.join(\", \") || \"repository\";\n\t\tthis.warning(\n\t\t\t`Execution error (${error.kind}, ${error.phase}) ${error.policyId}: ${location}: ${error.message}`,\n\t\t);\n\t}\n\n\tprivate async collectFilePaths(gitRoot: string): Promise<string[]> {\n\t\tconst paths = this.flags.stdin\n\t\t\t? parseFilePaths(await readStdin())\n\t\t\t: await this.collectRepositoryFiles();\n\t\treturn paths.map((filePath) => {\n\t\t\ttry {\n\t\t\t\treturn normalizeRepoRelativeFilePath(gitRoot, filePath);\n\t\t\t} catch (error: unknown) {\n\t\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\t\tthrow new Error(`Invalid file path '${filePath}': ${message}`, {\n\t\t\t\t\tcause: error,\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate async collectRepositoryFiles(): Promise<string[]> {\n\t\treturn readRepositoryFiles(this.git);\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;GAEG;AACH,qBAAa,WAAW,CACvB,CAAC,SAAS,OAAO,iBAAiB,GAAG;IACpC,IAAI,EAAE,OAAO,WAAW,CAAC,IAAI,CAAC;IAC9B,KAAK,EAAE,OAAO,WAAW,CAAC,KAAK,CAAC;CAChC,CACA,SAAQ,iBAAiB,CAAC,CAAC,CAAC;IAC7B,gBAAgC,OAAO,2CACE;IAEnB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAU1C"}
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;GAEG;AACH,qBAAa,WAAW,CACvB,CAAC,SAAS,OAAO,iBAAiB,GAAG;IACpC,IAAI,EAAE,OAAO,WAAW,CAAC,IAAI,CAAC;IAC9B,KAAK,EAAE,OAAO,WAAW,CAAC,KAAK,CAAC;CAChC,CACA,SAAQ,iBAAiB,CAAC,CAAC,CAAC;IAC7B,gBAAgC,OAAO,2CACE;IAEnB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAa1C"}
@@ -10,7 +10,8 @@ export class ListCommand extends BaseRepopoCommand {
10
10
  for (const configuredPolicy of policies) {
11
11
  this.log(configuredPolicy.instanceId);
12
12
  this.log(` ${configuredPolicy.description}`);
13
- this.log(` resolver: ${configuredPolicy.resolver !== undefined}\n`);
13
+ this.log(` scope: ${configuredPolicy.scope ?? "file"}`);
14
+ this.log(` resolver: ${configuredPolicy.scope !== "repository" && configuredPolicy.resolver !== undefined}\n`);
14
15
  }
15
16
  this.log(`${policies.length} TOTAL POLICY HANDLERS`);
16
17
  }
@@ -1 +1 @@
1
- {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;GAEG;AACH,MAAM,OAAO,WAKX,SAAQ,iBAAoB;IACtB,MAAM,CAAmB,OAAO,GACtC,uCAAuC,CAAC;IAEzB,KAAK,CAAC,GAAG;QACxB,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QAC7C,8BAA8B;QAC9B,KAAK,MAAM,gBAAgB,IAAI,QAAQ,EAAE,CAAC;YACzC,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;YACtC,IAAI,CAAC,GAAG,CAAC,KAAK,gBAAgB,CAAC,WAAW,EAAE,CAAC,CAAC;YAC9C,IAAI,CAAC,GAAG,CAAC,eAAe,gBAAgB,CAAC,QAAQ,KAAK,SAAS,IAAI,CAAC,CAAC;QACtE,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,MAAM,wBAAwB,CAAC,CAAC;IACtD,CAAC","sourcesContent":["import { BaseRepopoCommand } from \"../baseCommand.js\";\n\n/**\n * This command lists all the policies configured to run.\n */\nexport class ListCommand<\n\tT extends typeof BaseRepopoCommand & {\n\t\targs: typeof ListCommand.args;\n\t\tflags: typeof ListCommand.flags;\n\t},\n> extends BaseRepopoCommand<T> {\n\tpublic static override readonly summary =\n\t\t\"Lists the policies configured to run.\";\n\n\tpublic override async run(): Promise<void> {\n\t\tconst { policies } = await this.getContext();\n\t\t// list the handlers then exit\n\t\tfor (const configuredPolicy of policies) {\n\t\t\tthis.log(configuredPolicy.instanceId);\n\t\t\tthis.log(` ${configuredPolicy.description}`);\n\t\t\tthis.log(` resolver: ${configuredPolicy.resolver !== undefined}\\n`);\n\t\t}\n\t\tthis.log(`${policies.length} TOTAL POLICY HANDLERS`);\n\t}\n}\n"]}
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;GAEG;AACH,MAAM,OAAO,WAKX,SAAQ,iBAAoB;IACtB,MAAM,CAAmB,OAAO,GACtC,uCAAuC,CAAC;IAEzB,KAAK,CAAC,GAAG;QACxB,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QAC7C,8BAA8B;QAC9B,KAAK,MAAM,gBAAgB,IAAI,QAAQ,EAAE,CAAC;YACzC,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;YACtC,IAAI,CAAC,GAAG,CAAC,KAAK,gBAAgB,CAAC,WAAW,EAAE,CAAC,CAAC;YAC9C,IAAI,CAAC,GAAG,CAAC,YAAY,gBAAgB,CAAC,KAAK,IAAI,MAAM,EAAE,CAAC,CAAC;YACzD,IAAI,CAAC,GAAG,CACP,eAAe,gBAAgB,CAAC,KAAK,KAAK,YAAY,IAAI,gBAAgB,CAAC,QAAQ,KAAK,SAAS,IAAI,CACrG,CAAC;QACH,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,MAAM,wBAAwB,CAAC,CAAC;IACtD,CAAC","sourcesContent":["import { BaseRepopoCommand } from \"../baseCommand.js\";\n\n/**\n * This command lists all the policies configured to run.\n */\nexport class ListCommand<\n\tT extends typeof BaseRepopoCommand & {\n\t\targs: typeof ListCommand.args;\n\t\tflags: typeof ListCommand.flags;\n\t},\n> extends BaseRepopoCommand<T> {\n\tpublic static override readonly summary =\n\t\t\"Lists the policies configured to run.\";\n\n\tpublic override async run(): Promise<void> {\n\t\tconst { policies } = await this.getContext();\n\t\t// list the handlers then exit\n\t\tfor (const configuredPolicy of policies) {\n\t\t\tthis.log(configuredPolicy.instanceId);\n\t\t\tthis.log(` ${configuredPolicy.description}`);\n\t\t\tthis.log(` scope: ${configuredPolicy.scope ?? \"file\"}`);\n\t\t\tthis.log(\n\t\t\t\t` resolver: ${configuredPolicy.scope !== \"repository\" && configuredPolicy.resolver !== undefined}\\n`,\n\t\t\t);\n\t\t}\n\t\tthis.log(`${policies.length} TOTAL POLICY HANDLERS`);\n\t}\n}\n"]}
@@ -0,0 +1,3 @@
1
+ export declare const DEFAULT_CONCURRENCY = 8;
2
+ export declare function validateConcurrency(concurrency: number): number;
3
+ //# sourceMappingURL=concurrency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concurrency.d.ts","sourceRoot":"","sources":["../src/concurrency.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAK/D"}
@@ -0,0 +1,8 @@
1
+ export const DEFAULT_CONCURRENCY = 8;
2
+ export function validateConcurrency(concurrency) {
3
+ if (!Number.isSafeInteger(concurrency) || concurrency < 1) {
4
+ throw new Error("Concurrency must be a positive safe integer.");
5
+ }
6
+ return concurrency;
7
+ }
8
+ //# sourceMappingURL=concurrency.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concurrency.js","sourceRoot":"","sources":["../src/concurrency.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAErC,MAAM,UAAU,mBAAmB,CAAC,WAAmB;IACtD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,WAAW,CAAC,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IACjE,CAAC;IACD,OAAO,WAAW,CAAC;AACpB,CAAC","sourcesContent":["export const DEFAULT_CONCURRENCY = 8;\n\nexport function validateConcurrency(concurrency: number): number {\n\tif (!Number.isSafeInteger(concurrency) || concurrency < 1) {\n\t\tthrow new Error(\"Concurrency must be a positive safe integer.\");\n\t}\n\treturn concurrency;\n}\n"]}
package/esm/config.d.ts CHANGED
@@ -1,44 +1,10 @@
1
- import type { PolicyCreator } from "./generators.js";
2
- import type { ConfiguredPolicy, PolicyInstance } from "./policy.js";
3
- /**
4
- * @alpha
5
- */
6
- export type PolicyList = PolicyCreator[];
7
- /**
8
- * @alpha
9
- */
1
+ import { type ConfiguredPolicy } from "./policy.js";
2
+ /** Repository-wide policy configuration. @public */
10
3
  export interface RepopoConfig {
11
- /**
12
- * An array of configured policies that are enabled.
13
- *
14
- * Use the `policy()` function to configure policies before adding them to this array.
15
- *
16
- * @example
17
- * ```typescript
18
- * import { policy, type RepopoConfig } from "repopo";
19
- * import { NoJsFileExtensions, PackageJsonProperties } from "repopo/policies";
20
- *
21
- * const config: RepopoConfig = {
22
- * policies: [
23
- * policy(NoJsFileExtensions, { exclude: ["bin/*"] }),
24
- * policy(PackageJsonProperties, { verbatim: { license: "MIT" } }),
25
- * ],
26
- * };
27
- * ```
28
- *
29
- * See `DefaultPolicies` for the policies that will be enabled by default if this is `undefined`.
30
- */
31
- policies?: (ConfiguredPolicy<any> | PolicyInstance<any>)[];
32
- /**
33
- * An array of strings/regular expressions. File paths that match any of these expressions will be completely excluded
34
- * from all policies.
35
- */
4
+ policies?: ConfiguredPolicy[];
5
+ /** Repo-relative regex exclusions. Strings are case-insensitive. */
36
6
  excludeFiles?: (string | RegExp)[];
37
7
  }
38
- /**
39
- * The default config applied when no config is found.
40
- *
41
- * @alpha
42
- */
8
+ /** The default configuration when no config file is found. @alpha */
43
9
  export declare const DefaultPolicyConfig: RepopoConfig;
44
10
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGpE;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;AAEzC;;GAEG;AACH,MAAM,WAAW,YAAY;IAC5B;;;;;;;;;;;;;;;;;;;OAmBG;IAEH,QAAQ,CAAC,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;IAE3D;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;CACnC;AAED;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,YAGjC,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,gBAAgB,EAAmB,MAAM,aAAa,CAAC;AAErE,oDAAoD;AACpD,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC9B,oEAAoE;IACpE,YAAY,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;CACnC;AAED,qEAAqE;AACrE,eAAO,MAAM,mBAAmB,EAAE,YAGjC,CAAC"}
package/esm/config.js CHANGED
@@ -1,12 +1,8 @@
1
- import { policy } from "./makePolicy.js";
1
+ import { makePolicy } from "./makePolicy.js";
2
2
  import { DefaultPolicies } from "./policy.js";
3
- /**
4
- * The default config applied when no config is found.
5
- *
6
- * @alpha
7
- */
3
+ /** The default configuration when no config file is found. @alpha */
8
4
  export const DefaultPolicyConfig = {
9
- policies: DefaultPolicies.map((p) => policy(p)),
5
+ policies: DefaultPolicies.map((definition) => makePolicy(definition)),
10
6
  excludeFiles: [],
11
7
  };
12
8
  //# sourceMappingURL=config.js.map
package/esm/config.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAyC9C;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAiB;IAChD,QAAQ,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC/C,YAAY,EAAE,EAAE;CAChB,CAAC","sourcesContent":["import type { PolicyCreator } from \"./generators.js\";\nimport { policy } from \"./makePolicy.js\";\nimport type { ConfiguredPolicy, PolicyInstance } from \"./policy.js\";\nimport { DefaultPolicies } from \"./policy.js\";\n\n/**\n * @alpha\n */\nexport type PolicyList = PolicyCreator[];\n\n/**\n * @alpha\n */\nexport interface RepopoConfig {\n\t/**\n\t * An array of configured policies that are enabled.\n\t *\n\t * Use the `policy()` function to configure policies before adding them to this array.\n\t *\n\t * @example\n\t * ```typescript\n\t * import { policy, type RepopoConfig } from \"repopo\";\n\t * import { NoJsFileExtensions, PackageJsonProperties } from \"repopo/policies\";\n\t *\n\t * const config: RepopoConfig = {\n\t * policies: [\n\t * policy(NoJsFileExtensions, { exclude: [\"bin/*\"] }),\n\t * policy(PackageJsonProperties, { verbatim: { license: \"MIT\" } }),\n\t * ],\n\t * };\n\t * ```\n\t *\n\t * See `DefaultPolicies` for the policies that will be enabled by default if this is `undefined`.\n\t */\n\t// biome-ignore lint/suspicious/noExplicitAny: FIXME\n\tpolicies?: (ConfiguredPolicy<any> | PolicyInstance<any>)[];\n\n\t/**\n\t * An array of strings/regular expressions. File paths that match any of these expressions will be completely excluded\n\t * from all policies.\n\t */\n\texcludeFiles?: (string | RegExp)[];\n}\n\n/**\n * The default config applied when no config is found.\n *\n * @alpha\n */\nexport const DefaultPolicyConfig: RepopoConfig = {\n\tpolicies: DefaultPolicies.map((p) => policy(p)),\n\texcludeFiles: [],\n};\n"]}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAyB,eAAe,EAAE,MAAM,aAAa,CAAC;AASrE,qEAAqE;AACrE,MAAM,CAAC,MAAM,mBAAmB,GAAiB;IAChD,QAAQ,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IACrE,YAAY,EAAE,EAAE;CAChB,CAAC","sourcesContent":["import { makePolicy } from \"./makePolicy.js\";\nimport { type ConfiguredPolicy, DefaultPolicies } from \"./policy.js\";\n\n/** Repository-wide policy configuration. @public */\nexport interface RepopoConfig {\n\tpolicies?: ConfiguredPolicy[];\n\t/** Repo-relative regex exclusions. Strings are case-insensitive. */\n\texcludeFiles?: (string | RegExp)[];\n}\n\n/** The default configuration when no config file is found. @alpha */\nexport const DefaultPolicyConfig: RepopoConfig = {\n\tpolicies: DefaultPolicies.map((definition) => makePolicy(definition)),\n\texcludeFiles: [],\n};\n"]}
package/esm/context.d.ts CHANGED
@@ -2,9 +2,16 @@ import type { PolicyHandlerPerfStats } from "./perf.js";
2
2
  import type { IdentifiedPolicy, PolicyInstanceId } from "./policy.js";
3
3
  /**
4
4
  * A map of policy instance IDs to file-path regexes that should be excluded from those policies.
5
- * @alpha
5
+ * Paths are relative to the repository root.
6
+ *
7
+ * @public
6
8
  */
7
9
  export type ExcludedPolicyFileMap = Map<PolicyInstanceId, RegExp[]>;
10
+ /**
11
+ * Preserve explicit regex flags; string exclusions remain case-insensitive.
12
+ * @internal
13
+ */
14
+ export declare function exclusionRegex(pattern: string | RegExp): RegExp;
8
15
  /**
9
16
  * Creates the per-instance exclusion map used by policy runners.
10
17
  *
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEtE;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG,GAAG,CAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC,CAAC;AAEpE;;;;GAIG;AACH,wBAAgB,2BAA2B,CAC1C,QAAQ,EAAE,gBAAgB,EAAE,GAC1B,qBAAqB,CASvB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC;;OAEG;IACH,cAAc,EAAE,MAAM,EAAE,CAAC;IAEzB;;OAEG;IACH,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAE7B;;OAEG;IACH,uBAAuB,EAAE,qBAAqB,CAAC;IAE/C;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,SAAS,EAAE,sBAAsB,CAAC;CAClC"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEtE;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,GAAG,GAAG,CAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC,CAAC;AAEpE;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAE/D;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAC1C,QAAQ,EAAE,gBAAgB,EAAE,GAC1B,qBAAqB,CAOvB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC;;OAEG;IACH,cAAc,EAAE,MAAM,EAAE,CAAC;IAEzB;;OAEG;IACH,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAE7B;;OAEG;IACH,uBAAuB,EAAE,qBAAqB,CAAC;IAE/C;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,SAAS,EAAE,sBAAsB,CAAC;CAClC"}
package/esm/context.js CHANGED
@@ -1,3 +1,10 @@
1
+ /**
2
+ * Preserve explicit regex flags; string exclusions remain case-insensitive.
3
+ * @internal
4
+ */
5
+ export function exclusionRegex(pattern) {
6
+ return typeof pattern === "string" ? new RegExp(pattern, "i") : pattern;
7
+ }
1
8
  /**
2
9
  * Creates the per-instance exclusion map used by policy runners.
3
10
  *
@@ -6,7 +13,7 @@
6
13
  export function createExcludedPolicyFileMap(policies) {
7
14
  return new Map(policies.map((configuredPolicy) => [
8
15
  configuredPolicy.instanceId,
9
- configuredPolicy.excludeFiles?.map((pattern) => new RegExp(pattern, "i")) ?? [],
16
+ configuredPolicy.exclude?.map(exclusionRegex) ?? [],
10
17
  ]));
11
18
  }
12
19
  //# sourceMappingURL=context.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AASA;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CAC1C,QAA4B;IAE5B,OAAO,IAAI,GAAG,CACb,QAAQ,CAAC,GAAG,CAAC,CAAC,gBAAgB,EAAE,EAAE,CAAC;QAClC,gBAAgB,CAAC,UAAU;QAC3B,gBAAgB,CAAC,YAAY,EAAE,GAAG,CACjC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CACrC,IAAI,EAAE;KACP,CAAC,CACF,CAAC;AACH,CAAC","sourcesContent":["import type { PolicyHandlerPerfStats } from \"./perf.js\";\nimport type { IdentifiedPolicy, PolicyInstanceId } from \"./policy.js\";\n\n/**\n * A map of policy instance IDs to file-path regexes that should be excluded from those policies.\n * @alpha\n */\nexport type ExcludedPolicyFileMap = Map<PolicyInstanceId, RegExp[]>;\n\n/**\n * Creates the per-instance exclusion map used by policy runners.\n *\n * @internal\n */\nexport function createExcludedPolicyFileMap(\n\tpolicies: IdentifiedPolicy[],\n): ExcludedPolicyFileMap {\n\treturn new Map(\n\t\tpolicies.map((configuredPolicy) => [\n\t\t\tconfiguredPolicy.instanceId,\n\t\t\tconfiguredPolicy.excludeFiles?.map(\n\t\t\t\t(pattern) => new RegExp(pattern, \"i\"),\n\t\t\t) ?? [],\n\t\t]),\n\t);\n}\n\n/**\n * Contextual data available to all Repopo commands.\n */\nexport interface RepopoCommandContext {\n\t/**\n\t * A list of regular expressions used to exclude files from all handlers.\n\t */\n\texcludeFromAll: RegExp[];\n\n\t/**\n\t * A list of handlers to apply to selected files.\n\t */\n\tpolicies: IdentifiedPolicy[];\n\n\t/**\n\t * A per-handler list of regular expressions used to exclude files from specific handlers.\n\t */\n\texcludePoliciesForFiles: ExcludedPolicyFileMap;\n\n\t/**\n\t * Path to the root of the git repo.\n\t */\n\tgitRoot: string;\n\n\t/**\n\t * Stores performance data for each handler. Used to collect and display performance stats.\n\t */\n\tperfStats: PolicyHandlerPerfStats;\n}\n"]}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAWA;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,OAAwB;IACtD,OAAO,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;AACzE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CAC1C,QAA4B;IAE5B,OAAO,IAAI,GAAG,CACb,QAAQ,CAAC,GAAG,CAAC,CAAC,gBAAgB,EAAE,EAAE,CAAC;QAClC,gBAAgB,CAAC,UAAU;QAC3B,gBAAgB,CAAC,OAAO,EAAE,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE;KACnD,CAAC,CACF,CAAC;AACH,CAAC","sourcesContent":["import type { PolicyHandlerPerfStats } from \"./perf.js\";\nimport type { IdentifiedPolicy, PolicyInstanceId } from \"./policy.js\";\n\n/**\n * A map of policy instance IDs to file-path regexes that should be excluded from those policies.\n * Paths are relative to the repository root.\n *\n * @public\n */\nexport type ExcludedPolicyFileMap = Map<PolicyInstanceId, RegExp[]>;\n\n/**\n * Preserve explicit regex flags; string exclusions remain case-insensitive.\n * @internal\n */\nexport function exclusionRegex(pattern: string | RegExp): RegExp {\n\treturn typeof pattern === \"string\" ? new RegExp(pattern, \"i\") : pattern;\n}\n\n/**\n * Creates the per-instance exclusion map used by policy runners.\n *\n * @internal\n */\nexport function createExcludedPolicyFileMap(\n\tpolicies: IdentifiedPolicy[],\n): ExcludedPolicyFileMap {\n\treturn new Map(\n\t\tpolicies.map((configuredPolicy) => [\n\t\t\tconfiguredPolicy.instanceId,\n\t\t\tconfiguredPolicy.exclude?.map(exclusionRegex) ?? [],\n\t\t]),\n\t);\n}\n\n/**\n * Contextual data available to all Repopo commands.\n */\nexport interface RepopoCommandContext {\n\t/**\n\t * A list of regular expressions used to exclude files from all handlers.\n\t */\n\texcludeFromAll: RegExp[];\n\n\t/**\n\t * A list of handlers to apply to selected files.\n\t */\n\tpolicies: IdentifiedPolicy[];\n\n\t/**\n\t * A per-handler list of regular expressions used to exclude files from specific handlers.\n\t */\n\texcludePoliciesForFiles: ExcludedPolicyFileMap;\n\n\t/**\n\t * Path to the root of the git repo.\n\t */\n\tgitRoot: string;\n\n\t/**\n\t * Stores performance data for each handler. Used to collect and display performance stats.\n\t */\n\tperfStats: PolicyHandlerPerfStats;\n}\n"]}
@@ -0,0 +1,4 @@
1
+ /** An invalid handler invocation or result at a runtime boundary. @internal */
2
+ export declare class ExecutionContractError extends TypeError {
3
+ }
4
+ //# sourceMappingURL=executionContractError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executionContractError.d.ts","sourceRoot":"","sources":["../src/executionContractError.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,qBAAa,sBAAuB,SAAQ,SAAS;CAAG"}
@@ -0,0 +1,4 @@
1
+ /** An invalid handler invocation or result at a runtime boundary. @internal */
2
+ export class ExecutionContractError extends TypeError {
3
+ }
4
+ //# sourceMappingURL=executionContractError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executionContractError.js","sourceRoot":"","sources":["../src/executionContractError.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,MAAM,OAAO,sBAAuB,SAAQ,SAAS;CAAG","sourcesContent":["/** An invalid handler invocation or result at a runtime boundary. @internal */\nexport class ExecutionContractError extends TypeError {}\n"]}
@@ -0,0 +1,12 @@
1
+ import type { PolicyArgs } from "./policy.js";
2
+ /** Internal context shared with policies loaded through different module loaders. */
3
+ export declare const fileCache: unique symbol;
4
+ export declare class ParsedFileCache {
5
+ private readonly entries;
6
+ read<T>(key: string, load: () => Promise<T>, clone?: (value: unknown) => unknown): Promise<T>;
7
+ clear(): void;
8
+ }
9
+ export declare function readParsedFile<T>(args: PolicyArgs<unknown> & {
10
+ [fileCache]?: ParsedFileCache | undefined;
11
+ }, format: "json" | "toml", load: () => Promise<T>): Promise<T>;
12
+ //# sourceMappingURL=fileCache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileCache.d.ts","sourceRoot":"","sources":["../src/fileCache.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,qFAAqF;AACrF,eAAO,MAAM,SAAS,eAAiC,CAAC;AAkBxD,qBAAa,eAAe;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuC;IAElD,IAAI,CAAC,CAAC,EAClB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACtB,KAAK,GAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAyB,GAClD,OAAO,CAAC,CAAC,CAAC;IASN,KAAK,IAAI,IAAI;CAGpB;AAED,wBAAgB,cAAc,CAAC,CAAC,EAC/B,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG;IAAE,CAAC,SAAS,CAAC,CAAC,EAAE,eAAe,GAAG,SAAS,CAAA;CAAE,EACzE,MAAM,EAAE,MAAM,GAAG,MAAM,EACvB,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACpB,OAAO,CAAC,CAAC,CAAC,CASZ"}
@@ -0,0 +1,37 @@
1
+ import { resolve } from "pathe";
2
+ /** Internal context shared with policies loaded through different module loaders. */
3
+ export const fileCache = Symbol.for("repopo.fileCache");
4
+ function cloneToml(value) {
5
+ if (value instanceof Date) {
6
+ // TomlDate stores date/time kind and offset in private fields.
7
+ return Reflect.construct(value.constructor, [value.toISOString()]);
8
+ }
9
+ if (Array.isArray(value)) {
10
+ return value.map(cloneToml);
11
+ }
12
+ if (value !== null && typeof value === "object") {
13
+ return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, cloneToml(entry)]));
14
+ }
15
+ return value;
16
+ }
17
+ export class ParsedFileCache {
18
+ entries = new Map();
19
+ async read(key, load, clone = structuredClone) {
20
+ let pending = this.entries.get(key);
21
+ if (pending === undefined) {
22
+ pending = load();
23
+ this.entries.set(key, pending);
24
+ }
25
+ return clone(await pending);
26
+ }
27
+ clear() {
28
+ this.entries.clear();
29
+ }
30
+ }
31
+ export function readParsedFile(args, format, load) {
32
+ const cache = args.resolve ? undefined : args[fileCache];
33
+ return cache
34
+ ? cache.read(JSON.stringify([format, resolve(args.root, args.file)]), load, format === "toml" ? cloneToml : structuredClone)
35
+ : load();
36
+ }
37
+ //# sourceMappingURL=fileCache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileCache.js","sourceRoot":"","sources":["../src/fileCache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAGhC,qFAAqF;AACrF,MAAM,CAAC,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;AAExD,SAAS,SAAS,CAAC,KAAc;IAChC,IAAI,KAAK,YAAY,IAAI,EAAE,CAAC;QAC3B,+DAA+D;QAC/D,OAAO,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IACpE,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC7B,CAAC;IACD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACjD,OAAO,MAAM,CAAC,WAAW,CACxB,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CACpE,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,MAAM,OAAO,eAAe;IACV,OAAO,GAAG,IAAI,GAAG,EAA4B,CAAC;IAExD,KAAK,CAAC,IAAI,CAChB,GAAW,EACX,IAAsB,EACtB,QAAqC,eAAe;QAEpD,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC3B,OAAO,GAAG,IAAI,EAAE,CAAC;YACjB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAChC,CAAC;QACD,OAAO,KAAK,CAAC,MAAM,OAAO,CAAM,CAAC;IAClC,CAAC;IAEM,KAAK;QACX,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC;CACD;AAED,MAAM,UAAU,cAAc,CAC7B,IAAyE,EACzE,MAAuB,EACvB,IAAsB;IAEtB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACzD,OAAO,KAAK;QACX,CAAC,CAAC,KAAK,CAAC,IAAI,CACV,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EACvD,IAAI,EACJ,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAC/C;QACF,CAAC,CAAC,IAAI,EAAE,CAAC;AACX,CAAC","sourcesContent":["import { resolve } from \"pathe\";\nimport type { PolicyArgs } from \"./policy.js\";\n\n/** Internal context shared with policies loaded through different module loaders. */\nexport const fileCache = Symbol.for(\"repopo.fileCache\");\n\nfunction cloneToml(value: unknown): unknown {\n\tif (value instanceof Date) {\n\t\t// TomlDate stores date/time kind and offset in private fields.\n\t\treturn Reflect.construct(value.constructor, [value.toISOString()]);\n\t}\n\tif (Array.isArray(value)) {\n\t\treturn value.map(cloneToml);\n\t}\n\tif (value !== null && typeof value === \"object\") {\n\t\treturn Object.fromEntries(\n\t\t\tObject.entries(value).map(([key, entry]) => [key, cloneToml(entry)]),\n\t\t);\n\t}\n\treturn value;\n}\n\nexport class ParsedFileCache {\n\tprivate readonly entries = new Map<string, Promise<unknown>>();\n\n\tpublic async read<T>(\n\t\tkey: string,\n\t\tload: () => Promise<T>,\n\t\tclone: (value: unknown) => unknown = structuredClone,\n\t): Promise<T> {\n\t\tlet pending = this.entries.get(key);\n\t\tif (pending === undefined) {\n\t\t\tpending = load();\n\t\t\tthis.entries.set(key, pending);\n\t\t}\n\t\treturn clone(await pending) as T;\n\t}\n\n\tpublic clear(): void {\n\t\tthis.entries.clear();\n\t}\n}\n\nexport function readParsedFile<T>(\n\targs: PolicyArgs<unknown> & { [fileCache]?: ParsedFileCache | undefined },\n\tformat: \"json\" | \"toml\",\n\tload: () => Promise<T>,\n): Promise<T> {\n\tconst cache = args.resolve ? undefined : args[fileCache];\n\treturn cache\n\t\t? cache.read(\n\t\t\t\tJSON.stringify([format, resolve(args.root, args.file)]),\n\t\t\t\tload,\n\t\t\t\tformat === \"toml\" ? cloneToml : structuredClone,\n\t\t\t)\n\t\t: load();\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export declare function parseFilePaths(input: string): string[];
2
+ //# sourceMappingURL=filePaths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filePaths.d.ts","sourceRoot":"","sources":["../src/filePaths.ts"],"names":[],"mappings":"AAGA,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAKtD"}
@@ -0,0 +1,9 @@
1
+ const WINDOWS_SEPARATOR = /\\/g;
2
+ const LINE_BREAK = /\r?\n/;
3
+ export function parseFilePaths(input) {
4
+ return input
5
+ .replace(WINDOWS_SEPARATOR, "/")
6
+ .split(input.includes("\0") ? "\0" : LINE_BREAK)
7
+ .filter((filePath) => filePath.length > 0);
8
+ }
9
+ //# sourceMappingURL=filePaths.js.map