pr-checkmate 3.0.3 → 3.1.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/dist/{cli.js → cjs/cli.js} +30 -30
- package/dist/{config → cjs/config}/index.d.ts +2 -2
- package/dist/{config → cjs/config}/index.js +8 -7
- package/dist/{config → cjs/config}/loader.d.ts +1 -1
- package/dist/{config → cjs/config}/loader.js +8 -8
- package/dist/{core → cjs/core}/checks/dependencies/banned-imports.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/dependencies/banned-imports.js +10 -10
- package/dist/{core → cjs/core}/checks/dependencies/circular-deps.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/dependencies/circular-deps.js +27 -27
- package/dist/{core → cjs/core}/checks/dependencies/dependency-check.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/dependencies/dependency-check.js +17 -17
- package/dist/{core → cjs/core}/checks/dependencies/grype-scan.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/dependencies/grype-scan.js +18 -18
- package/dist/{core → cjs/core}/checks/dependencies/license-check.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/dependencies/license-check.js +12 -12
- package/dist/{core → cjs/core}/checks/dependencies/npm-audit.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/dependencies/npm-audit.js +14 -14
- package/dist/{core → cjs/core}/checks/dependencies/outdated-deps.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/dependencies/outdated-deps.js +14 -14
- package/dist/{core → cjs/core}/checks/dependencies/vuln-scan.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/dependencies/vuln-scan.js +14 -14
- package/dist/{core → cjs/core}/checks/findings.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/findings.js +16 -16
- package/dist/{core → cjs/core}/checks/git/custom-rules.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/git/custom-rules.js +19 -19
- package/dist/{core → cjs/core}/checks/git/diff-smell.d.ts +2 -2
- package/dist/{core → cjs/core}/checks/git/diff-smell.js +13 -13
- package/dist/{core → cjs/core}/checks/git/large-files.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/git/large-files.js +15 -15
- package/dist/{core → cjs/core}/checks/git/leftover-debug.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/git/leftover-debug.js +13 -13
- package/dist/{core → cjs/core}/checks/git/lockfile-drift.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/git/lockfile-drift.js +12 -12
- package/dist/{core → cjs/core}/checks/git/merge-conflict.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/git/merge-conflict.js +15 -15
- package/dist/{core → cjs/core}/checks/git/missing-tests.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/git/missing-tests.js +15 -15
- package/dist/{core → cjs/core}/checks/git/todo-fixme.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/git/todo-fixme.js +11 -11
- package/dist/{core → cjs/core}/checks/languages/cpp-format.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/languages/cpp-format.js +18 -18
- package/dist/{core → cjs/core}/checks/languages/external-checks.d.ts +9 -9
- package/dist/{core → cjs/core}/checks/languages/external-checks.js +10 -10
- package/dist/{core → cjs/core}/checks/languages/external-runner.d.ts +2 -2
- package/dist/{core → cjs/core}/checks/languages/external-runner.js +21 -21
- package/dist/{core → cjs/core}/checks/languages/go-format.d.ts +1 -1
- package/dist/cjs/core/checks/languages/go-format.js +202 -0
- package/dist/cjs/core/checks/languages/lint.d.ts +2 -0
- package/dist/{core → cjs/core}/checks/languages/lint.js +21 -21
- package/dist/{core → cjs/core}/checks/languages/prettier.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/languages/prettier.js +18 -18
- package/dist/{core → cjs/core}/checks/languages/python-format.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/languages/python-format.js +14 -14
- package/dist/{core → cjs/core}/checks/languages/python-lint.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/languages/python-lint.js +13 -13
- package/dist/{core → cjs/core}/checks/languages/python-typecheck.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/languages/python-typecheck.js +29 -29
- package/dist/{core → cjs/core}/checks/languages/typecheck.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/languages/typecheck.js +13 -13
- package/dist/{core → cjs/core}/checks/pr/commitlint.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/pr/commitlint.js +12 -12
- package/dist/{core → cjs/core}/checks/pr/pr-body.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/pr/pr-body.js +8 -8
- package/dist/{core → cjs/core}/checks/pr/pr-size-check.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/pr/pr-size-check.js +10 -10
- package/dist/{core → cjs/core}/checks/pr/pr-title-lint.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/pr/pr-title-lint.js +8 -8
- package/dist/{core → cjs/core}/checks/quality/case-collision.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/quality/case-collision.js +7 -7
- package/dist/{core → cjs/core}/checks/quality/config-validation.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/quality/config-validation.js +9 -9
- package/dist/{core → cjs/core}/checks/quality/coverage.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/quality/coverage.js +4 -4
- package/dist/{core → cjs/core}/checks/quality/dead-code.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/quality/dead-code.js +23 -23
- package/dist/{core → cjs/core}/checks/quality/duplicate-check.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/quality/duplicate-check.js +22 -22
- package/dist/{core → cjs/core}/checks/quality/license-header.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/quality/license-header.js +16 -16
- package/dist/{core → cjs/core}/checks/quality/markdown-lint.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/quality/markdown-lint.js +17 -17
- package/dist/{core → cjs/core}/checks/quality/package-size.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/quality/package-size.js +12 -12
- package/dist/{core → cjs/core}/checks/quality/spellcheck.d.ts +2 -2
- package/dist/{core → cjs/core}/checks/quality/spellcheck.js +18 -18
- package/dist/{core → cjs/core}/checks/quality/symlinks.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/quality/symlinks.js +8 -8
- package/dist/{core → cjs/core}/checks/quality/yaml-lint.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/quality/yaml-lint.js +12 -12
- package/dist/{core → cjs/core}/checks/security/diff-security.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/security/diff-security.js +15 -15
- package/dist/{core → cjs/core}/checks/security/dockerfile-security.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/security/dockerfile-security.js +16 -16
- package/dist/{core → cjs/core}/checks/security/migration-safety.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/security/migration-safety.js +17 -17
- package/dist/{core → cjs/core}/checks/security/security.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/security/security.js +21 -21
- package/dist/{core → cjs/core}/checks/security/sensitive-file-guard.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/security/sensitive-file-guard.js +14 -14
- package/dist/{core → cjs/core}/checks/security/workflow-security.d.ts +2 -2
- package/dist/{core → cjs/core}/checks/security/workflow-security.js +14 -14
- package/dist/{core → cjs/core}/checks/tool-install.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/tool-install.js +2 -2
- package/dist/{core → cjs/core}/context.d.ts +1 -1
- package/dist/{core → cjs/core}/context.js +16 -16
- package/dist/cjs/core/index.d.ts +4 -0
- package/dist/{core → cjs/core}/index.js +7 -7
- package/dist/{core → cjs/core}/install/cache.js +2 -2
- package/dist/{core → cjs/core}/install/doctor.d.ts +4 -4
- package/dist/{core → cjs/core}/install/doctor.js +34 -34
- package/dist/{core → cjs/core}/install/ensure.d.ts +2 -2
- package/dist/{core → cjs/core}/install/ensure.js +15 -14
- package/dist/{core → cjs/core}/install/lock.js +4 -4
- package/dist/{core → cjs/core}/install/prepare.d.ts +4 -4
- package/dist/{core → cjs/core}/install/prepare.js +13 -13
- package/dist/{core → cjs/core}/install/profiles.d.ts +2 -2
- package/dist/{core → cjs/core}/install/reuse.d.ts +1 -1
- package/dist/{core → cjs/core}/install/reuse.js +4 -4
- package/dist/{core → cjs/core}/registry.d.ts +1 -1
- package/dist/cjs/core/registry.js +112 -0
- package/dist/{core → cjs/core}/reporters.d.ts +1 -1
- package/dist/{core → cjs/core}/reporters.js +28 -28
- package/dist/{core → cjs/core}/run-checks.d.ts +2 -2
- package/dist/{core → cjs/core}/run-checks.js +31 -31
- package/dist/{core → cjs/core}/targets.d.ts +1 -1
- package/dist/{core → cjs/core}/targets.js +20 -20
- package/dist/{core → cjs/core}/types.d.ts +3 -3
- package/dist/cjs/index.d.ts +12 -0
- package/dist/{index.js → cjs/index.js} +18 -18
- package/dist/{init.js → cjs/init.js} +68 -56
- package/dist/{interfaces → cjs/interfaces}/index.d.ts +3 -3
- package/dist/cjs/package.json +1 -0
- package/dist/{scripts → cjs/scripts}/copy-configs.js +22 -7
- package/dist/{scripts → cjs/scripts}/generate-install-manifests.js +2 -2
- package/dist/{scripts → cjs/scripts}/publish-github.js +4 -4
- package/dist/{utils → cjs/utils}/detect-language.js +12 -12
- package/dist/cjs/utils/execa.js +46 -0
- package/dist/{utils → cjs/utils}/git.js +2 -2
- package/dist/{utils → cjs/utils}/http.js +2 -2
- package/dist/cjs/utils/index.d.ts +15 -0
- package/dist/{utils → cjs/utils}/index.js +13 -13
- package/dist/{utils → cjs/utils}/own-deps.d.ts +2 -0
- package/dist/{utils → cjs/utils}/own-deps.js +1 -0
- package/dist/{utils → cjs/utils}/package-version.js +2 -1
- package/dist/{utils → cjs/utils}/resolve-bin.js +2 -1
- package/dist/{utils → cjs/utils}/update-notifier.js +4 -4
- package/dist/esm/cli.d.ts +2 -0
- package/dist/esm/cli.js +137 -0
- package/dist/esm/config/constants.d.ts +153 -0
- package/dist/esm/config/constants.js +360 -0
- package/dist/esm/config/index.d.ts +40 -0
- package/dist/esm/config/index.js +60 -0
- package/dist/esm/config/loader.d.ts +6 -0
- package/dist/esm/config/loader.js +191 -0
- package/dist/esm/config/pr-checkmate-workflow-docker.yml +79 -0
- package/dist/esm/config/pr-checkmate-workflow.yml +92 -0
- package/dist/esm/core/checks/dependencies/banned-imports.d.ts +2 -0
- package/dist/esm/core/checks/dependencies/banned-imports.js +70 -0
- package/dist/esm/core/checks/dependencies/circular-deps.d.ts +2 -0
- package/dist/esm/core/checks/dependencies/circular-deps.js +155 -0
- package/dist/esm/core/checks/dependencies/dependency-check.d.ts +43 -0
- package/dist/esm/core/checks/dependencies/dependency-check.js +174 -0
- package/dist/esm/core/checks/dependencies/grype-scan.d.ts +22 -0
- package/dist/esm/core/checks/dependencies/grype-scan.js +112 -0
- package/dist/esm/core/checks/dependencies/license-check.d.ts +2 -0
- package/dist/esm/core/checks/dependencies/license-check.js +61 -0
- package/dist/esm/core/checks/dependencies/npm-audit.d.ts +6 -0
- package/dist/esm/core/checks/dependencies/npm-audit.js +80 -0
- package/dist/esm/core/checks/dependencies/outdated-deps.d.ts +2 -0
- package/dist/esm/core/checks/dependencies/outdated-deps.js +66 -0
- package/dist/esm/core/checks/dependencies/vuln-scan.d.ts +2 -0
- package/dist/esm/core/checks/dependencies/vuln-scan.js +54 -0
- package/dist/esm/core/checks/findings.d.ts +299 -0
- package/dist/esm/core/checks/findings.js +701 -0
- package/dist/esm/core/checks/git/custom-rules.d.ts +2 -0
- package/dist/esm/core/checks/git/custom-rules.js +106 -0
- package/dist/esm/core/checks/git/diff-smell.d.ts +19 -0
- package/dist/esm/core/checks/git/diff-smell.js +69 -0
- package/dist/esm/core/checks/git/large-files.d.ts +2 -0
- package/dist/esm/core/checks/git/large-files.js +112 -0
- package/dist/esm/core/checks/git/leftover-debug.d.ts +2 -0
- package/dist/esm/core/checks/git/leftover-debug.js +89 -0
- package/dist/esm/core/checks/git/lockfile-drift.d.ts +2 -0
- package/dist/esm/core/checks/git/lockfile-drift.js +114 -0
- package/dist/esm/core/checks/git/merge-conflict.d.ts +2 -0
- package/dist/esm/core/checks/git/merge-conflict.js +117 -0
- package/dist/esm/core/checks/git/missing-tests.d.ts +2 -0
- package/dist/esm/core/checks/git/missing-tests.js +105 -0
- package/dist/esm/core/checks/git/todo-fixme.d.ts +7 -0
- package/dist/esm/core/checks/git/todo-fixme.js +80 -0
- package/dist/esm/core/checks/languages/cpp-format.d.ts +7 -0
- package/dist/esm/core/checks/languages/cpp-format.js +91 -0
- package/dist/esm/core/checks/languages/external-checks.d.ts +77 -0
- package/dist/esm/core/checks/languages/external-checks.js +197 -0
- package/dist/esm/core/checks/languages/external-runner.d.ts +119 -0
- package/dist/esm/core/checks/languages/external-runner.js +138 -0
- package/dist/esm/core/checks/languages/go-format.d.ts +8 -0
- package/dist/{core → esm/core}/checks/languages/go-format.js +29 -35
- package/dist/esm/core/checks/languages/lint.d.ts +2 -0
- package/dist/esm/core/checks/languages/lint.js +92 -0
- package/dist/esm/core/checks/languages/prettier.d.ts +2 -0
- package/dist/esm/core/checks/languages/prettier.js +85 -0
- package/dist/esm/core/checks/languages/python-format.d.ts +7 -0
- package/dist/esm/core/checks/languages/python-format.js +61 -0
- package/dist/esm/core/checks/languages/python-lint.d.ts +9 -0
- package/dist/esm/core/checks/languages/python-lint.js +55 -0
- package/dist/esm/core/checks/languages/python-typecheck.d.ts +14 -0
- package/dist/esm/core/checks/languages/python-typecheck.js +184 -0
- package/dist/esm/core/checks/languages/ruff-shared.d.ts +10 -0
- package/dist/esm/core/checks/languages/ruff-shared.js +35 -0
- package/dist/esm/core/checks/languages/typecheck.d.ts +2 -0
- package/dist/esm/core/checks/languages/typecheck.js +61 -0
- package/dist/esm/core/checks/pr/commitlint.d.ts +2 -0
- package/dist/esm/core/checks/pr/commitlint.js +102 -0
- package/dist/esm/core/checks/pr/pr-body.d.ts +2 -0
- package/dist/esm/core/checks/pr/pr-body.js +43 -0
- package/dist/esm/core/checks/pr/pr-size-check.d.ts +2 -0
- package/dist/esm/core/checks/pr/pr-size-check.js +42 -0
- package/dist/esm/core/checks/pr/pr-title-lint.d.ts +2 -0
- package/dist/esm/core/checks/pr/pr-title-lint.js +31 -0
- package/dist/esm/core/checks/quality/case-collision.d.ts +8 -0
- package/dist/esm/core/checks/quality/case-collision.js +39 -0
- package/dist/esm/core/checks/quality/config-validation.d.ts +11 -0
- package/dist/esm/core/checks/quality/config-validation.js +188 -0
- package/dist/esm/core/checks/quality/coverage.d.ts +2 -0
- package/dist/esm/core/checks/quality/coverage.js +62 -0
- package/dist/esm/core/checks/quality/dead-code.d.ts +2 -0
- package/dist/esm/core/checks/quality/dead-code.js +124 -0
- package/dist/esm/core/checks/quality/duplicate-check.d.ts +2 -0
- package/dist/esm/core/checks/quality/duplicate-check.js +141 -0
- package/dist/esm/core/checks/quality/license-header.d.ts +7 -0
- package/dist/esm/core/checks/quality/license-header.js +81 -0
- package/dist/esm/core/checks/quality/markdown-lint.d.ts +2 -0
- package/dist/esm/core/checks/quality/markdown-lint.js +104 -0
- package/dist/esm/core/checks/quality/package-size.d.ts +36 -0
- package/dist/esm/core/checks/quality/package-size.js +196 -0
- package/dist/esm/core/checks/quality/spellcheck.d.ts +77 -0
- package/dist/esm/core/checks/quality/spellcheck.js +296 -0
- package/dist/esm/core/checks/quality/symlinks.d.ts +16 -0
- package/dist/esm/core/checks/quality/symlinks.js +57 -0
- package/dist/esm/core/checks/quality/yaml-lint.d.ts +20 -0
- package/dist/esm/core/checks/quality/yaml-lint.js +116 -0
- package/dist/esm/core/checks/security/diff-security.d.ts +2 -0
- package/dist/esm/core/checks/security/diff-security.js +354 -0
- package/dist/esm/core/checks/security/dockerfile-security.d.ts +2 -0
- package/dist/esm/core/checks/security/dockerfile-security.js +98 -0
- package/dist/esm/core/checks/security/migration-safety.d.ts +2 -0
- package/dist/esm/core/checks/security/migration-safety.js +137 -0
- package/dist/esm/core/checks/security/security.d.ts +63 -0
- package/dist/esm/core/checks/security/security.js +201 -0
- package/dist/esm/core/checks/security/sensitive-file-guard.d.ts +2 -0
- package/dist/esm/core/checks/security/sensitive-file-guard.js +160 -0
- package/dist/esm/core/checks/security/workflow-security.d.ts +12 -0
- package/dist/esm/core/checks/security/workflow-security.js +100 -0
- package/dist/esm/core/checks/tool-install.d.ts +102 -0
- package/dist/esm/core/checks/tool-install.js +66 -0
- package/dist/esm/core/commands.d.ts +27 -0
- package/dist/esm/core/commands.js +89 -0
- package/dist/esm/core/context.d.ts +62 -0
- package/dist/esm/core/context.js +241 -0
- package/dist/esm/core/index.d.ts +4 -0
- package/dist/esm/core/index.js +4 -0
- package/dist/esm/core/install/cache.d.ts +58 -0
- package/dist/esm/core/install/cache.js +142 -0
- package/dist/esm/core/install/doctor.d.ts +35 -0
- package/dist/esm/core/install/doctor.js +164 -0
- package/dist/esm/core/install/ensure.d.ts +77 -0
- package/dist/esm/core/install/ensure.js +269 -0
- package/dist/esm/core/install/lock.d.ts +34 -0
- package/dist/esm/core/install/lock.js +92 -0
- package/dist/esm/core/install/merge.d.ts +47 -0
- package/dist/esm/core/install/merge.js +85 -0
- package/dist/esm/core/install/prepare.d.ts +76 -0
- package/dist/esm/core/install/prepare.js +142 -0
- package/dist/esm/core/install/profiles.d.ts +78 -0
- package/dist/esm/core/install/profiles.js +192 -0
- package/dist/esm/core/install/reuse.d.ts +41 -0
- package/dist/esm/core/install/reuse.js +100 -0
- package/dist/esm/core/registry.d.ts +6 -0
- package/dist/esm/core/registry.js +109 -0
- package/dist/esm/core/reporters.d.ts +18 -0
- package/dist/esm/core/reporters.js +266 -0
- package/dist/esm/core/run-checks.d.ts +33 -0
- package/dist/esm/core/run-checks.js +293 -0
- package/dist/esm/core/targets.d.ts +140 -0
- package/dist/esm/core/targets.js +213 -0
- package/dist/esm/core/types.d.ts +195 -0
- package/dist/esm/core/types.js +38 -0
- package/dist/esm/index.d.ts +12 -0
- package/dist/esm/index.js +15 -0
- package/dist/esm/init.d.ts +38 -0
- package/dist/esm/init.js +421 -0
- package/dist/esm/interfaces/index.d.ts +432 -0
- package/dist/esm/interfaces/index.js +2 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/scripts/copy-configs.d.ts +1 -0
- package/dist/esm/scripts/copy-configs.js +64 -0
- package/dist/esm/scripts/generate-install-manifests.d.ts +39 -0
- package/dist/esm/scripts/generate-install-manifests.js +115 -0
- package/dist/esm/scripts/publish-github.d.ts +1 -0
- package/dist/esm/scripts/publish-github.js +45 -0
- package/dist/esm/utils/ci.d.ts +11 -0
- package/dist/esm/utils/ci.js +40 -0
- package/dist/esm/utils/detect-language.d.ts +48 -0
- package/dist/esm/utils/detect-language.js +234 -0
- package/dist/esm/utils/direct-deps.d.ts +21 -0
- package/dist/esm/utils/direct-deps.js +220 -0
- package/dist/esm/utils/execa.d.ts +22 -0
- package/dist/{utils → esm/utils}/execa.js +1 -4
- package/dist/esm/utils/git.d.ts +14 -0
- package/dist/esm/utils/git.js +21 -0
- package/dist/esm/utils/glob.d.ts +24 -0
- package/dist/esm/utils/glob.js +40 -0
- package/dist/esm/utils/http.d.ts +59 -0
- package/dist/esm/utils/http.js +115 -0
- package/dist/esm/utils/index.d.ts +15 -0
- package/dist/esm/utils/index.js +26 -0
- package/dist/esm/utils/logger.d.ts +65 -0
- package/dist/esm/utils/logger.js +157 -0
- package/dist/esm/utils/own-deps.d.ts +16 -0
- package/dist/esm/utils/own-deps.js +107 -0
- package/dist/esm/utils/package-version.d.ts +4 -0
- package/dist/esm/utils/package-version.js +38 -0
- package/dist/esm/utils/pool.d.ts +49 -0
- package/dist/esm/utils/pool.js +113 -0
- package/dist/esm/utils/resolve-bin.d.ts +67 -0
- package/dist/esm/utils/resolve-bin.js +156 -0
- package/dist/esm/utils/result-collector.d.ts +33 -0
- package/dist/esm/utils/result-collector.js +44 -0
- package/dist/esm/utils/update-notifier.d.ts +19 -0
- package/dist/esm/utils/update-notifier.js +108 -0
- package/install-manifests/core/package-lock.json +4 -4
- package/install-manifests/core/package.json +1 -1
- package/install-manifests/cpp/package-lock.json +4 -4
- package/install-manifests/cpp/package.json +1 -1
- package/package.json +16 -14
- package/dist/core/checks/languages/lint.d.ts +0 -2
- package/dist/core/index.d.ts +0 -4
- package/dist/core/registry.js +0 -112
- package/dist/index.d.ts +0 -12
- package/dist/utils/index.d.ts +0 -15
- /package/dist/{cli.d.ts → cjs/cli.d.ts} +0 -0
- /package/dist/{config → cjs/config}/constants.d.ts +0 -0
- /package/dist/{config → cjs/config}/constants.js +0 -0
- /package/dist/{config → cjs/config}/pr-checkmate-workflow-docker.yml +0 -0
- /package/dist/{config → cjs/config}/pr-checkmate-workflow.yml +0 -0
- /package/dist/{core → cjs/core}/checks/languages/ruff-shared.d.ts +0 -0
- /package/dist/{core → cjs/core}/checks/languages/ruff-shared.js +0 -0
- /package/dist/{core → cjs/core}/commands.d.ts +0 -0
- /package/dist/{core → cjs/core}/commands.js +0 -0
- /package/dist/{core → cjs/core}/install/cache.d.ts +0 -0
- /package/dist/{core → cjs/core}/install/lock.d.ts +0 -0
- /package/dist/{core → cjs/core}/install/merge.d.ts +0 -0
- /package/dist/{core → cjs/core}/install/merge.js +0 -0
- /package/dist/{core → cjs/core}/install/profiles.js +0 -0
- /package/dist/{core → cjs/core}/types.js +0 -0
- /package/dist/{init.d.ts → cjs/init.d.ts} +0 -0
- /package/dist/{interfaces → cjs/interfaces}/index.js +0 -0
- /package/dist/{scripts → cjs/scripts}/copy-configs.d.ts +0 -0
- /package/dist/{scripts → cjs/scripts}/generate-install-manifests.d.ts +0 -0
- /package/dist/{scripts → cjs/scripts}/publish-github.d.ts +0 -0
- /package/dist/{utils → cjs/utils}/ci.d.ts +0 -0
- /package/dist/{utils → cjs/utils}/ci.js +0 -0
- /package/dist/{utils → cjs/utils}/detect-language.d.ts +0 -0
- /package/dist/{utils → cjs/utils}/direct-deps.d.ts +0 -0
- /package/dist/{utils → cjs/utils}/direct-deps.js +0 -0
- /package/dist/{utils → cjs/utils}/execa.d.ts +0 -0
- /package/dist/{utils → cjs/utils}/git.d.ts +0 -0
- /package/dist/{utils → cjs/utils}/glob.d.ts +0 -0
- /package/dist/{utils → cjs/utils}/glob.js +0 -0
- /package/dist/{utils → cjs/utils}/http.d.ts +0 -0
- /package/dist/{utils → cjs/utils}/logger.d.ts +0 -0
- /package/dist/{utils → cjs/utils}/logger.js +0 -0
- /package/dist/{utils → cjs/utils}/package-version.d.ts +0 -0
- /package/dist/{utils → cjs/utils}/pool.d.ts +0 -0
- /package/dist/{utils → cjs/utils}/pool.js +0 -0
- /package/dist/{utils → cjs/utils}/resolve-bin.d.ts +0 -0
- /package/dist/{utils → cjs/utils}/result-collector.d.ts +0 -0
- /package/dist/{utils → cjs/utils}/result-collector.js +0 -0
- /package/dist/{utils → cjs/utils}/update-notifier.d.ts +0 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { fileURLToPath as __fileURLToPath } from 'node:url';
|
|
2
|
+
import { dirname as __dirnameFn } from 'node:path';
|
|
3
|
+
const __dirname = __dirnameFn(__fileURLToPath(import.meta.url));
|
|
4
|
+
import fs from 'node:fs';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { findOwnPackageRoot } from './own-deps.js';
|
|
7
|
+
/**
|
|
8
|
+
* Our own name and version, read from the manifest that ships inside the package.
|
|
9
|
+
*
|
|
10
|
+
* Read from disk rather than baked in at build time so it is the *running* copy
|
|
11
|
+
* that answers. That distinction is the whole point: a stale global install
|
|
12
|
+
* (`npm i -g pr-checkmate`) shadows the project's own copy on `PATH`, and a repo
|
|
13
|
+
* pinned to the latest version can still be checked by a year-old binary without
|
|
14
|
+
* anything in the log saying so. One client spent a while reading an upgrade
|
|
15
|
+
* notice for a version they had already installed, because nothing printed which
|
|
16
|
+
* version was speaking.
|
|
17
|
+
*
|
|
18
|
+
* Falls back to placeholders rather than throwing: no caller here is important
|
|
19
|
+
* enough to fail a run over a manifest it could not read.
|
|
20
|
+
*/
|
|
21
|
+
function readManifest() {
|
|
22
|
+
try {
|
|
23
|
+
const manifest = path.join(findOwnPackageRoot() ?? path.resolve(__dirname, '../../..'), 'package.json');
|
|
24
|
+
const parsed = JSON.parse(fs.readFileSync(manifest, 'utf-8'));
|
|
25
|
+
return { name: parsed.name ?? 'pr-checkmate', version: parsed.version ?? '0.0.0' };
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return { name: 'pr-checkmate', version: '0.0.0' };
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/** The version of pr-checkmate that is executing right now. */
|
|
32
|
+
export function packageVersion() {
|
|
33
|
+
return readManifest().version;
|
|
34
|
+
}
|
|
35
|
+
/** The package name that is executing right now — the one to query npm for. */
|
|
36
|
+
export function packageName() {
|
|
37
|
+
return readManifest().name;
|
|
38
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run tasks with a bounded number in flight.
|
|
3
|
+
*
|
|
4
|
+
* `Promise.all` over a whole phase started every check at once — thirty-seven of
|
|
5
|
+
* them in the informational phase, many spawning heavy processes (cspell, jscpd,
|
|
6
|
+
* knip, dpdm, grype, tsc). On a two-core runner that is context-switch thrashing:
|
|
7
|
+
* the wall clock gets worse, not better, and a large monorepo can run the machine
|
|
8
|
+
* out of memory.
|
|
9
|
+
*
|
|
10
|
+
* Results come back in the order the tasks were given, so callers can pair them
|
|
11
|
+
* with their inputs.
|
|
12
|
+
*/
|
|
13
|
+
export declare function runPool<T>(tasks: Array<() => Promise<T>>, limit: number): Promise<Array<T | undefined>>;
|
|
14
|
+
/**
|
|
15
|
+
* Default concurrency for this machine.
|
|
16
|
+
*
|
|
17
|
+
* One core is left for the orchestrator and whatever else the runner is doing,
|
|
18
|
+
* and the ceiling of four keeps a 32-core developer laptop from starting thirty
|
|
19
|
+
* subprocesses that then fight over disk. On the standard two-core CI runner this
|
|
20
|
+
* resolves to 1, which is the case the old code handled worst.
|
|
21
|
+
*/
|
|
22
|
+
export declare function defaultConcurrency(): number;
|
|
23
|
+
/** Resolve the client's `run.concurrency` setting into a number. */
|
|
24
|
+
export declare function resolveConcurrency(setting: number | 'auto' | 'unlimited' | undefined): number;
|
|
25
|
+
/**
|
|
26
|
+
* A counting semaphore, used to admit only a few expensive checks at a time.
|
|
27
|
+
*
|
|
28
|
+
* The overall limit is not enough on its own: four concurrent checks are fine
|
|
29
|
+
* when they are regex scans and ruinous when they are knip, jscpd, dpdm and tsc,
|
|
30
|
+
* each of which wants a core and a few hundred megabytes to itself.
|
|
31
|
+
*/
|
|
32
|
+
export declare class Semaphore {
|
|
33
|
+
private available;
|
|
34
|
+
private readonly waiting;
|
|
35
|
+
constructor(limit: number);
|
|
36
|
+
/** Run `fn` once a slot is free, releasing it even if `fn` throws. */
|
|
37
|
+
run<T>(fn: () => Promise<T>): Promise<T>;
|
|
38
|
+
private acquire;
|
|
39
|
+
private release;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Race a promise against a timeout, resolving to `onTimeout` if it wins.
|
|
43
|
+
*
|
|
44
|
+
* A check that never returns used to hold the whole phase — and with it the run —
|
|
45
|
+
* open indefinitely. Note the underlying work is not killed: there is no portable
|
|
46
|
+
* way to do that here, so it is left to finish in the background while the run
|
|
47
|
+
* moves on and reports the timeout.
|
|
48
|
+
*/
|
|
49
|
+
export declare function withTimeout<T>(work: Promise<T>, timeoutMs: number, onTimeout: () => T): Promise<T>;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
/**
|
|
3
|
+
* Run tasks with a bounded number in flight.
|
|
4
|
+
*
|
|
5
|
+
* `Promise.all` over a whole phase started every check at once — thirty-seven of
|
|
6
|
+
* them in the informational phase, many spawning heavy processes (cspell, jscpd,
|
|
7
|
+
* knip, dpdm, grype, tsc). On a two-core runner that is context-switch thrashing:
|
|
8
|
+
* the wall clock gets worse, not better, and a large monorepo can run the machine
|
|
9
|
+
* out of memory.
|
|
10
|
+
*
|
|
11
|
+
* Results come back in the order the tasks were given, so callers can pair them
|
|
12
|
+
* with their inputs.
|
|
13
|
+
*/
|
|
14
|
+
export async function runPool(tasks, limit) {
|
|
15
|
+
const bound = Math.max(1, Math.floor(limit));
|
|
16
|
+
const results = new Array(tasks.length);
|
|
17
|
+
let next = 0;
|
|
18
|
+
const worker = async () => {
|
|
19
|
+
while (next < tasks.length) {
|
|
20
|
+
const index = next++;
|
|
21
|
+
results[index] = await tasks[index]();
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
await Promise.all(Array.from({ length: Math.min(bound, tasks.length) }, worker));
|
|
25
|
+
return results;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Default concurrency for this machine.
|
|
29
|
+
*
|
|
30
|
+
* One core is left for the orchestrator and whatever else the runner is doing,
|
|
31
|
+
* and the ceiling of four keeps a 32-core developer laptop from starting thirty
|
|
32
|
+
* subprocesses that then fight over disk. On the standard two-core CI runner this
|
|
33
|
+
* resolves to 1, which is the case the old code handled worst.
|
|
34
|
+
*/
|
|
35
|
+
export function defaultConcurrency() {
|
|
36
|
+
const cores = os.cpus()?.length ?? 2;
|
|
37
|
+
return Math.max(1, Math.min(4, cores - 1));
|
|
38
|
+
}
|
|
39
|
+
/** Resolve the client's `run.concurrency` setting into a number. */
|
|
40
|
+
export function resolveConcurrency(setting) {
|
|
41
|
+
const fromEnv = process.env.PR_CHECKMATE_CONCURRENCY;
|
|
42
|
+
const value = fromEnv ?? setting ?? 'auto';
|
|
43
|
+
if (value === 'unlimited')
|
|
44
|
+
return Number.MAX_SAFE_INTEGER;
|
|
45
|
+
if (value === 'auto')
|
|
46
|
+
return defaultConcurrency();
|
|
47
|
+
const parsed = typeof value === 'number' ? value : parseInt(value, 10);
|
|
48
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : defaultConcurrency();
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* A counting semaphore, used to admit only a few expensive checks at a time.
|
|
52
|
+
*
|
|
53
|
+
* The overall limit is not enough on its own: four concurrent checks are fine
|
|
54
|
+
* when they are regex scans and ruinous when they are knip, jscpd, dpdm and tsc,
|
|
55
|
+
* each of which wants a core and a few hundred megabytes to itself.
|
|
56
|
+
*/
|
|
57
|
+
export class Semaphore {
|
|
58
|
+
constructor(limit) {
|
|
59
|
+
this.waiting = [];
|
|
60
|
+
this.available = Math.max(1, limit);
|
|
61
|
+
}
|
|
62
|
+
/** Run `fn` once a slot is free, releasing it even if `fn` throws. */
|
|
63
|
+
async run(fn) {
|
|
64
|
+
await this.acquire();
|
|
65
|
+
try {
|
|
66
|
+
return await fn();
|
|
67
|
+
}
|
|
68
|
+
finally {
|
|
69
|
+
this.release();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async acquire() {
|
|
73
|
+
if (this.available > 0) {
|
|
74
|
+
this.available--;
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
return new Promise(resolve => this.waiting.push(resolve));
|
|
78
|
+
}
|
|
79
|
+
release() {
|
|
80
|
+
const next = this.waiting.shift();
|
|
81
|
+
if (next)
|
|
82
|
+
next();
|
|
83
|
+
else
|
|
84
|
+
this.available++;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Race a promise against a timeout, resolving to `onTimeout` if it wins.
|
|
89
|
+
*
|
|
90
|
+
* A check that never returns used to hold the whole phase — and with it the run —
|
|
91
|
+
* open indefinitely. Note the underlying work is not killed: there is no portable
|
|
92
|
+
* way to do that here, so it is left to finish in the background while the run
|
|
93
|
+
* moves on and reports the timeout.
|
|
94
|
+
*/
|
|
95
|
+
export async function withTimeout(work, timeoutMs, onTimeout) {
|
|
96
|
+
if (timeoutMs <= 0)
|
|
97
|
+
return work;
|
|
98
|
+
let timer;
|
|
99
|
+
try {
|
|
100
|
+
return await Promise.race([
|
|
101
|
+
work,
|
|
102
|
+
new Promise(resolve => {
|
|
103
|
+
timer = setTimeout(() => resolve(onTimeout()), timeoutMs);
|
|
104
|
+
// Do not keep the event loop alive purely for this timer.
|
|
105
|
+
timer.unref?.();
|
|
106
|
+
}),
|
|
107
|
+
]);
|
|
108
|
+
}
|
|
109
|
+
finally {
|
|
110
|
+
if (timer)
|
|
111
|
+
clearTimeout(timer);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/** Where a tool was found, in the order the candidates are tried. */
|
|
2
|
+
export type ToolSource = 'client' | 'profile' | 'bundled';
|
|
3
|
+
/** A resolved tool binary, and which copy of it answered. */
|
|
4
|
+
export interface ResolvedTool {
|
|
5
|
+
bin: string;
|
|
6
|
+
source: ToolSource;
|
|
7
|
+
/** The search root that produced it; `undefined` for module-relative resolution. */
|
|
8
|
+
root?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Point tool resolution at the profile directories fetched for this run.
|
|
12
|
+
*
|
|
13
|
+
* Called by the install layer once the cache is known. Passing an empty list —
|
|
14
|
+
* or never calling it at all — leaves resolution exactly as it was before
|
|
15
|
+
* profiles existed, which is what keeps a run that needs no fetching identical
|
|
16
|
+
* to a run from before there was anything to fetch.
|
|
17
|
+
*/
|
|
18
|
+
export declare function registerToolPaths(dirs: string[]): void;
|
|
19
|
+
/** Drop every registered profile root. For tests, and for a second run in-process. */
|
|
20
|
+
export declare function clearToolPaths(): void;
|
|
21
|
+
/** The root of the installed pr-checkmate package — where our own tooling lives. */
|
|
22
|
+
export declare function ownPackageRoot(): string;
|
|
23
|
+
/**
|
|
24
|
+
* Whether a package is physically present in our own dependency tree.
|
|
25
|
+
*
|
|
26
|
+
* Checked by walking `node_modules` upwards rather than by `require.resolve`,
|
|
27
|
+
* because a package that restricts its `exports` map resolves for neither its
|
|
28
|
+
* main entry nor its `package.json` while being perfectly well installed —
|
|
29
|
+
* `cspell` is one. The question here is only "is it there", and the directory
|
|
30
|
+
* answers that without an opinion about what it chooses to export.
|
|
31
|
+
*
|
|
32
|
+
* Walking up matters as much as the check itself: installed as a dependency, our
|
|
33
|
+
* own packages are hoisted to the client's `node_modules`, one level above ours.
|
|
34
|
+
*/
|
|
35
|
+
export declare function packagePresent(pkgName: string, from?: string): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Resolve a tool's binary and say which copy answered.
|
|
38
|
+
*
|
|
39
|
+
* Use this over {@link resolvePackageBin} when the answer is worth logging — the
|
|
40
|
+
* source is the difference between "the client's ESLint 8 ran" and "ours did",
|
|
41
|
+
* and that is the first thing anyone asks when a lint result looks wrong.
|
|
42
|
+
*
|
|
43
|
+
* @param pkgName Package whose binary to resolve (e.g. `eslint`).
|
|
44
|
+
* @param binRelPath Bin path relative to the package root (e.g. `bin/eslint.js`).
|
|
45
|
+
* @param options Resolution options.
|
|
46
|
+
* @param options.paths Roots to prefer ahead of everything else. Use
|
|
47
|
+
* `[process.cwd()]` to prefer the consumer project's copy.
|
|
48
|
+
*/
|
|
49
|
+
export declare function resolveTool(pkgName: string, binRelPath: string, options?: {
|
|
50
|
+
paths?: string[];
|
|
51
|
+
}): ResolvedTool | null;
|
|
52
|
+
/**
|
|
53
|
+
* Resolves a binary path for a bundled package, bypassing exports map restrictions.
|
|
54
|
+
*
|
|
55
|
+
* Throws when no copy can be found anywhere, which is the honest outcome: a check
|
|
56
|
+
* that cannot find its tool has nothing to report, and the install layer turns
|
|
57
|
+
* that into a skip with a reason rather than letting it surface as a stack trace.
|
|
58
|
+
*
|
|
59
|
+
* @param pkgName - The package whose binary to resolve (e.g. `eslint`).
|
|
60
|
+
* @param binRelPath - The bin path relative to the package root (e.g. `bin/eslint.js`).
|
|
61
|
+
* @param options - Resolution options.
|
|
62
|
+
* @param options.paths - Directories to resolve from, preferred over everything
|
|
63
|
+
* else. Use `[process.cwd()]` to prefer the consumer project's copy.
|
|
64
|
+
*/
|
|
65
|
+
export declare function resolvePackageBin(pkgName: string, binRelPath: string, options?: {
|
|
66
|
+
paths?: string[];
|
|
67
|
+
}): string;
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { fileURLToPath as __fileURLToPath } from 'node:url';
|
|
2
|
+
import { dirname as __dirnameFn } from 'node:path';
|
|
3
|
+
const __dirname = __dirnameFn(__fileURLToPath(import.meta.url));
|
|
4
|
+
import fs from 'node:fs';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { findOwnPackageRoot } from './own-deps.js';
|
|
7
|
+
/**
|
|
8
|
+
* Extra roots to search, registered once per run by the install layer.
|
|
9
|
+
*
|
|
10
|
+
* Module state rather than a parameter threaded through fifteen call sites: a
|
|
11
|
+
* profile directory is a property of the *run*, not of any one check, and every
|
|
12
|
+
* check that resolves a binary would otherwise have to be handed a value it has
|
|
13
|
+
* no opinion about. `registerToolPaths` is called before the first check starts
|
|
14
|
+
* and never during one, so nothing observes it changing underneath.
|
|
15
|
+
*/
|
|
16
|
+
let profileRoots = [];
|
|
17
|
+
/**
|
|
18
|
+
* Point tool resolution at the profile directories fetched for this run.
|
|
19
|
+
*
|
|
20
|
+
* Called by the install layer once the cache is known. Passing an empty list —
|
|
21
|
+
* or never calling it at all — leaves resolution exactly as it was before
|
|
22
|
+
* profiles existed, which is what keeps a run that needs no fetching identical
|
|
23
|
+
* to a run from before there was anything to fetch.
|
|
24
|
+
*/
|
|
25
|
+
export function registerToolPaths(dirs) {
|
|
26
|
+
profileRoots = [...dirs];
|
|
27
|
+
}
|
|
28
|
+
/** Drop every registered profile root. For tests, and for a second run in-process. */
|
|
29
|
+
export function clearToolPaths() {
|
|
30
|
+
profileRoots = [];
|
|
31
|
+
}
|
|
32
|
+
/** The root of the installed pr-checkmate package — where our own tooling lives. */
|
|
33
|
+
export function ownPackageRoot() {
|
|
34
|
+
return findOwnPackageRoot() ?? path.resolve(__dirname, '../../..');
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Whether a package is physically present in our own dependency tree.
|
|
38
|
+
*
|
|
39
|
+
* Checked by walking `node_modules` upwards rather than by `require.resolve`,
|
|
40
|
+
* because a package that restricts its `exports` map resolves for neither its
|
|
41
|
+
* main entry nor its `package.json` while being perfectly well installed —
|
|
42
|
+
* `cspell` is one. The question here is only "is it there", and the directory
|
|
43
|
+
* answers that without an opinion about what it chooses to export.
|
|
44
|
+
*
|
|
45
|
+
* Walking up matters as much as the check itself: installed as a dependency, our
|
|
46
|
+
* own packages are hoisted to the client's `node_modules`, one level above ours.
|
|
47
|
+
*/
|
|
48
|
+
export function packagePresent(pkgName, from = ownPackageRoot()) {
|
|
49
|
+
let dir = from;
|
|
50
|
+
while (dir !== path.dirname(dir)) {
|
|
51
|
+
if (fs.existsSync(path.join(dir, 'node_modules', pkgName, 'package.json')))
|
|
52
|
+
return true;
|
|
53
|
+
dir = path.dirname(dir);
|
|
54
|
+
}
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
/** One resolution attempt against a single set of search paths. */
|
|
58
|
+
function tryResolve(pkgName, binRelPath, paths) {
|
|
59
|
+
const resolveOpts = paths ? { paths } : undefined;
|
|
60
|
+
// 1. Direct subpath — the fast path for packages that export their bin.
|
|
61
|
+
try {
|
|
62
|
+
return require.resolve(`${pkgName}/${binRelPath}`, resolveOpts);
|
|
63
|
+
}
|
|
64
|
+
catch { }
|
|
65
|
+
// 2. Via package.json — for packages that export `./package.json` but not the
|
|
66
|
+
// bin subpath (eslint).
|
|
67
|
+
try {
|
|
68
|
+
const pkgJsonPath = require.resolve(`${pkgName}/package.json`, resolveOpts);
|
|
69
|
+
return path.join(path.dirname(pkgJsonPath), binRelPath);
|
|
70
|
+
}
|
|
71
|
+
catch { }
|
|
72
|
+
// 3. Walk up from the main entry, matching the package name — for packages
|
|
73
|
+
// that export neither (cspell).
|
|
74
|
+
try {
|
|
75
|
+
let dir = path.dirname(require.resolve(pkgName, resolveOpts));
|
|
76
|
+
while (dir !== path.dirname(dir)) {
|
|
77
|
+
const pkgJsonPath = path.join(dir, 'package.json');
|
|
78
|
+
if (fs.existsSync(pkgJsonPath)) {
|
|
79
|
+
try {
|
|
80
|
+
const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));
|
|
81
|
+
if (pkg.name === pkgName)
|
|
82
|
+
return path.join(dir, binRelPath);
|
|
83
|
+
}
|
|
84
|
+
catch { }
|
|
85
|
+
}
|
|
86
|
+
dir = path.dirname(dir);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch { }
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* The roots to try, in order, and what finding a tool in each one means.
|
|
94
|
+
*
|
|
95
|
+
* The order is the policy, and it is deliberate:
|
|
96
|
+
*
|
|
97
|
+
* 1. **The client's own copy**, when a caller asked for it. A repository pinned
|
|
98
|
+
* to ESLint 8 with a legacy `.eslintrc` must keep working, and only its copy
|
|
99
|
+
* can do that.
|
|
100
|
+
* 2. **A fetched profile**, for tooling that does not ship inside the package.
|
|
101
|
+
* 3. **Our bundle** — module-relative, exactly as resolution worked before
|
|
102
|
+
* profiles existed.
|
|
103
|
+
*
|
|
104
|
+
* Branch 3 is passed `undefined` rather than our package root on purpose: that is
|
|
105
|
+
* literally the previous behaviour, so a run with nothing registered resolves
|
|
106
|
+
* every tool along the identical path it always did.
|
|
107
|
+
*/
|
|
108
|
+
function candidates(optPaths) {
|
|
109
|
+
const list = [];
|
|
110
|
+
if (optPaths && optPaths.length > 0)
|
|
111
|
+
list.push({ paths: optPaths, source: 'client' });
|
|
112
|
+
for (const root of profileRoots)
|
|
113
|
+
list.push({ paths: [root], source: 'profile' });
|
|
114
|
+
list.push({ source: 'bundled' });
|
|
115
|
+
return list;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Resolve a tool's binary and say which copy answered.
|
|
119
|
+
*
|
|
120
|
+
* Use this over {@link resolvePackageBin} when the answer is worth logging — the
|
|
121
|
+
* source is the difference between "the client's ESLint 8 ran" and "ours did",
|
|
122
|
+
* and that is the first thing anyone asks when a lint result looks wrong.
|
|
123
|
+
*
|
|
124
|
+
* @param pkgName Package whose binary to resolve (e.g. `eslint`).
|
|
125
|
+
* @param binRelPath Bin path relative to the package root (e.g. `bin/eslint.js`).
|
|
126
|
+
* @param options Resolution options.
|
|
127
|
+
* @param options.paths Roots to prefer ahead of everything else. Use
|
|
128
|
+
* `[process.cwd()]` to prefer the consumer project's copy.
|
|
129
|
+
*/
|
|
130
|
+
export function resolveTool(pkgName, binRelPath, options) {
|
|
131
|
+
for (const candidate of candidates(options?.paths)) {
|
|
132
|
+
const bin = tryResolve(pkgName, binRelPath, candidate.paths);
|
|
133
|
+
if (bin)
|
|
134
|
+
return { bin, source: candidate.source, root: candidate.paths?.[0] };
|
|
135
|
+
}
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Resolves a binary path for a bundled package, bypassing exports map restrictions.
|
|
140
|
+
*
|
|
141
|
+
* Throws when no copy can be found anywhere, which is the honest outcome: a check
|
|
142
|
+
* that cannot find its tool has nothing to report, and the install layer turns
|
|
143
|
+
* that into a skip with a reason rather than letting it surface as a stack trace.
|
|
144
|
+
*
|
|
145
|
+
* @param pkgName - The package whose binary to resolve (e.g. `eslint`).
|
|
146
|
+
* @param binRelPath - The bin path relative to the package root (e.g. `bin/eslint.js`).
|
|
147
|
+
* @param options - Resolution options.
|
|
148
|
+
* @param options.paths - Directories to resolve from, preferred over everything
|
|
149
|
+
* else. Use `[process.cwd()]` to prefer the consumer project's copy.
|
|
150
|
+
*/
|
|
151
|
+
export function resolvePackageBin(pkgName, binRelPath, options) {
|
|
152
|
+
const resolved = resolveTool(pkgName, binRelPath, options);
|
|
153
|
+
if (resolved)
|
|
154
|
+
return resolved.bin;
|
|
155
|
+
throw new Error(`Cannot resolve binary "${binRelPath}" for package "${pkgName}"`);
|
|
156
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export type CheckStatus = 'pass' | 'warn' | 'fail' | 'skip';
|
|
2
|
+
export interface CheckResult {
|
|
3
|
+
name: string;
|
|
4
|
+
status: CheckStatus;
|
|
5
|
+
details?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
*/
|
|
10
|
+
export declare class ResultCollector {
|
|
11
|
+
private results;
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
*/
|
|
15
|
+
register(name: string, status: CheckStatus, details?: string): void;
|
|
16
|
+
/**
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
getResults(): CheckResult[];
|
|
20
|
+
/**
|
|
21
|
+
*
|
|
22
|
+
*/
|
|
23
|
+
clear(): void;
|
|
24
|
+
/**
|
|
25
|
+
*
|
|
26
|
+
*/
|
|
27
|
+
getSummary(): {
|
|
28
|
+
passed: number;
|
|
29
|
+
warned: number;
|
|
30
|
+
failed: number;
|
|
31
|
+
skipped: number;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
*/
|
|
4
|
+
export class ResultCollector {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.results = [];
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
*
|
|
10
|
+
*/
|
|
11
|
+
register(name, status, details) {
|
|
12
|
+
const idx = this.results.findIndex(r => r.name === name);
|
|
13
|
+
const entry = { name, status, ...(details && { details }) };
|
|
14
|
+
if (idx >= 0) {
|
|
15
|
+
this.results[idx] = entry;
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
this.results.push(entry);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
*
|
|
23
|
+
*/
|
|
24
|
+
getResults() {
|
|
25
|
+
return [...this.results];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
*
|
|
29
|
+
*/
|
|
30
|
+
clear() {
|
|
31
|
+
this.results = [];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
*
|
|
35
|
+
*/
|
|
36
|
+
getSummary() {
|
|
37
|
+
return {
|
|
38
|
+
passed: this.results.filter(r => r.status === 'pass').length,
|
|
39
|
+
warned: this.results.filter(r => r.status === 'warn').length,
|
|
40
|
+
failed: this.results.filter(r => r.status === 'fail').length,
|
|
41
|
+
skipped: this.results.filter(r => r.status === 'skip').length,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** True when the upgrade crosses a major version, i.e. behaviour may change. */
|
|
2
|
+
export declare function isMajorUpgrade(latest: string, current: string): boolean;
|
|
3
|
+
/**
|
|
4
|
+
* Best-effort check for a newer published version. Returns the notice lines when
|
|
5
|
+
* an update exists, or `null` (up-to-date, offline, timed out, or opted out).
|
|
6
|
+
* Non-blocking and fully silent on any failure: short timeout, swallowed errors,
|
|
7
|
+
* opt-out via `PR_CHECKMATE_NO_UPDATE_CHECK`. Returns lines instead of logging so
|
|
8
|
+
* the caller can print them at the very end — after the summary — where they're
|
|
9
|
+
* noticeable. Deliberately called ONLY from the CLI (not `runChecks`) so
|
|
10
|
+
* programmatic consumers (e.g. a wrapping SDK) never trigger a network call.
|
|
11
|
+
*
|
|
12
|
+
* The notice is framed like the run summary so it is noticed, but it is now a
|
|
13
|
+
* one-liner: upgrading is just installing. It used to demand `npx pr-checkmate
|
|
14
|
+
* init` afterwards, because `init` copied the release's new defaults into the
|
|
15
|
+
* client's config — a step nobody could safely skip, for a file that should
|
|
16
|
+
* never have held those defaults in the first place. They are merged in when the
|
|
17
|
+
* config loads, so the second step no longer exists.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getUpdateNotice(timeoutMs?: number): Promise<string[] | null>;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// Imported from the module rather than the `../config` barrel on purpose:
|
|
2
|
+
// `config/index.ts` imports `../utils`, so going through the barrel would make
|
|
3
|
+
// utils ⇄ config circular. `constants.ts` itself pulls in nothing from utils.
|
|
4
|
+
import { DOCS_URL } from '../config/constants.js';
|
|
5
|
+
import { packageName, packageVersion } from './package-version.js';
|
|
6
|
+
// Same widths as the run summary in `reporters.ts`, so the two boxes line up
|
|
7
|
+
// when both are printed at the end of a run.
|
|
8
|
+
const NOTICE_BORDER = '═'.repeat(63);
|
|
9
|
+
const NOTICE_RULE = '─'.repeat(63);
|
|
10
|
+
/** Compare dotted versions; true when `latest` is strictly greater than `current`. */
|
|
11
|
+
function isNewer(latest, current) {
|
|
12
|
+
const a = latest.split('.').map(n => parseInt(n, 10) || 0);
|
|
13
|
+
const b = current.split('.').map(n => parseInt(n, 10) || 0);
|
|
14
|
+
for (let i = 0; i < 3; i++) {
|
|
15
|
+
if ((a[i] ?? 0) !== (b[i] ?? 0))
|
|
16
|
+
return (a[i] ?? 0) > (b[i] ?? 0);
|
|
17
|
+
}
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
/** True when the upgrade crosses a major version, i.e. behaviour may change. */
|
|
21
|
+
export function isMajorUpgrade(latest, current) {
|
|
22
|
+
return (parseInt(latest.split('.')[0], 10) || 0) > (parseInt(current.split('.')[0], 10) || 0);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Extra lines for a major upgrade. A patch bump is a routine "install it"; a
|
|
26
|
+
* major one can change what fails a build, and finding that out from a red PR is
|
|
27
|
+
* the wrong way to learn it. Says what to read and how to stage the rollout,
|
|
28
|
+
* because the answer to "everything went red" should arrive before it happens.
|
|
29
|
+
*/
|
|
30
|
+
function majorNotice(pkgName) {
|
|
31
|
+
return [
|
|
32
|
+
NOTICE_RULE,
|
|
33
|
+
' ⚠️ MAJOR VERSION — behaviour changes, read before upgrading',
|
|
34
|
+
'',
|
|
35
|
+
' Findings a check rates "error" now BLOCK the run. Previously they were',
|
|
36
|
+
' reported and the run still passed, so a repo with existing findings will',
|
|
37
|
+
' start failing its PRs.',
|
|
38
|
+
'',
|
|
39
|
+
' To stage it, make everything advisory first and promote checks back one',
|
|
40
|
+
' at a time — in pr-checkmate.json:',
|
|
41
|
+
' "severityDefaults": { "failOn": "warn" }',
|
|
42
|
+
' "severity": { "Security Scan": "error" }',
|
|
43
|
+
'',
|
|
44
|
+
` Full notes: https://www.npmjs.com/package/${pkgName}?activeTab=versions`,
|
|
45
|
+
];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Best-effort check for a newer published version. Returns the notice lines when
|
|
49
|
+
* an update exists, or `null` (up-to-date, offline, timed out, or opted out).
|
|
50
|
+
* Non-blocking and fully silent on any failure: short timeout, swallowed errors,
|
|
51
|
+
* opt-out via `PR_CHECKMATE_NO_UPDATE_CHECK`. Returns lines instead of logging so
|
|
52
|
+
* the caller can print them at the very end — after the summary — where they're
|
|
53
|
+
* noticeable. Deliberately called ONLY from the CLI (not `runChecks`) so
|
|
54
|
+
* programmatic consumers (e.g. a wrapping SDK) never trigger a network call.
|
|
55
|
+
*
|
|
56
|
+
* The notice is framed like the run summary so it is noticed, but it is now a
|
|
57
|
+
* one-liner: upgrading is just installing. It used to demand `npx pr-checkmate
|
|
58
|
+
* init` afterwards, because `init` copied the release's new defaults into the
|
|
59
|
+
* client's config — a step nobody could safely skip, for a file that should
|
|
60
|
+
* never have held those defaults in the first place. They are merged in when the
|
|
61
|
+
* config loads, so the second step no longer exists.
|
|
62
|
+
*/
|
|
63
|
+
export async function getUpdateNotice(timeoutMs = 2500) {
|
|
64
|
+
if (process.env.PR_CHECKMATE_NO_UPDATE_CHECK)
|
|
65
|
+
return null;
|
|
66
|
+
try {
|
|
67
|
+
// The *running* copy's identity, not the project's declared dependency. A
|
|
68
|
+
// stale global install shadows the local one on `PATH`, and it is the stale
|
|
69
|
+
// copy that must own the notice it prints.
|
|
70
|
+
const pkg = { name: packageName(), version: packageVersion() };
|
|
71
|
+
const controller = new AbortController();
|
|
72
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
73
|
+
let latest;
|
|
74
|
+
try {
|
|
75
|
+
const res = await fetch(`https://registry.npmjs.org/${encodeURIComponent(pkg.name)}/latest`, {
|
|
76
|
+
signal: controller.signal,
|
|
77
|
+
});
|
|
78
|
+
if (res.ok)
|
|
79
|
+
latest = (await res.json()).version;
|
|
80
|
+
}
|
|
81
|
+
finally {
|
|
82
|
+
clearTimeout(timer);
|
|
83
|
+
}
|
|
84
|
+
if (latest && isNewer(latest, pkg.version)) {
|
|
85
|
+
const major = isMajorUpgrade(latest, pkg.version);
|
|
86
|
+
return [
|
|
87
|
+
NOTICE_BORDER,
|
|
88
|
+
` ⬆️ UPDATE AVAILABLE — ${pkg.name} ${pkg.version} → ${latest}`,
|
|
89
|
+
...(major ? majorNotice(pkg.name) : []),
|
|
90
|
+
NOTICE_RULE,
|
|
91
|
+
` Install: npm install ${pkg.name}@latest`,
|
|
92
|
+
'',
|
|
93
|
+
' That is the whole upgrade. New checks and new defaults apply on their',
|
|
94
|
+
' own — your pr-checkmate.json holds only what you changed, and nothing',
|
|
95
|
+
' in it needs topping up.',
|
|
96
|
+
NOTICE_RULE,
|
|
97
|
+
` 📚 Docs: ${DOCS_URL}`,
|
|
98
|
+
` 📦 Release: https://www.npmjs.com/package/${pkg.name}`,
|
|
99
|
+
NOTICE_BORDER,
|
|
100
|
+
];
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
// Best-effort only — never let an update check slow or break a run.
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"execa": "9.6.1",
|
|
12
12
|
"yaml": "2.9.1",
|
|
13
13
|
"inquirer": "14.2.2",
|
|
14
|
-
"gitleaks-secret-scanner-fixed": "3.0.
|
|
14
|
+
"gitleaks-secret-scanner-fixed": "3.0.4"
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
17
|
"node_modules/@inquirer/ansi": {
|
|
@@ -572,9 +572,9 @@
|
|
|
572
572
|
}
|
|
573
573
|
},
|
|
574
574
|
"node_modules/gitleaks-secret-scanner-fixed": {
|
|
575
|
-
"version": "3.0.
|
|
576
|
-
"resolved": "https://registry.npmjs.org/gitleaks-secret-scanner-fixed/-/gitleaks-secret-scanner-fixed-3.0.
|
|
577
|
-
"integrity": "sha512-
|
|
575
|
+
"version": "3.0.4",
|
|
576
|
+
"resolved": "https://registry.npmjs.org/gitleaks-secret-scanner-fixed/-/gitleaks-secret-scanner-fixed-3.0.4.tgz",
|
|
577
|
+
"integrity": "sha512-UxNQSWIcSIux7M6Ue/pcEDz+E/UQVicvpoa/a5TCq6PD32B3sSNe3WY7wIpiyddpJIUImF2gFkQbWM+wZQrKFQ==",
|
|
578
578
|
"hasInstallScript": true,
|
|
579
579
|
"license": "MIT",
|
|
580
580
|
"dependencies": {
|