pr-checkmate 3.0.4 → 3.2.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/{core → cjs/core}/checks/languages/go-format.js +21 -21
- 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/cjs/core/checks/quality/markdown-lint.js +147 -0
- 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/profiles.js +1 -1
- 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/{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/esm/core/checks/languages/go-format.js +163 -0
- 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 +141 -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/esm/utils/execa.js +10 -0
- 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/duplicate/package-lock.json +0 -12
- package/install-manifests/js/package-lock.json +17 -41
- package/install-manifests/js/package.json +1 -1
- package/install-manifests/markdown/package-lock.json +1 -492
- package/install-manifests/markdown/package.json +1 -1
- package/package.json +17 -15
- package/dist/core/checks/languages/lint.d.ts +0 -2
- package/dist/core/checks/quality/markdown-lint.js +0 -110
- 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}/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}/execa.js +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,81 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { execa } from '../../../utils/execa.js';
|
|
4
|
+
import { logger } from '../../../utils/index.js';
|
|
5
|
+
import { excludeClientPaths } from '../../targets.js';
|
|
6
|
+
import { pass, skip, warn } from '../../types.js';
|
|
7
|
+
/** Source extensions a license header is expected on. */
|
|
8
|
+
const SOURCE_EXT = /\.(ts|tsx|js|jsx|mjs|cjs|py|kt|java|go|rs|cs|rb|php|swift|c|cc|cpp|h|hpp)$/i;
|
|
9
|
+
const DEFAULT_HEADER_LINES = 10;
|
|
10
|
+
/**
|
|
11
|
+
* Requires a license/copyright header (a configured regex) in the first N lines
|
|
12
|
+
* of newly ADDED source files. Opt-in — needs `licenseHeader.pattern`; does
|
|
13
|
+
* nothing until a repo configures one. Advisory (warn).
|
|
14
|
+
*/
|
|
15
|
+
export const licenseHeaderCheck = {
|
|
16
|
+
name: 'License Header',
|
|
17
|
+
phase: 'informational',
|
|
18
|
+
// No `requiresDiff`: with no range the question becomes "which source files
|
|
19
|
+
// lack the header", which is what a repo adopting the policy actually needs —
|
|
20
|
+
// the delta form only ever covers files added since the policy was turned on
|
|
21
|
+
// (ticket 067).
|
|
22
|
+
applies(ctx) {
|
|
23
|
+
return ctx.config.licenseHeader?.enabled === true;
|
|
24
|
+
},
|
|
25
|
+
async run(ctx) {
|
|
26
|
+
const patternSrc = ctx.config.licenseHeader?.pattern;
|
|
27
|
+
if (!patternSrc)
|
|
28
|
+
return skip('no licenseHeader.pattern configured');
|
|
29
|
+
let header;
|
|
30
|
+
try {
|
|
31
|
+
header = new RegExp(patternSrc);
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
logger.warn(`[License Header]: ⚠️ invalid pattern\n${err}`);
|
|
35
|
+
return skip('invalid licenseHeader.pattern');
|
|
36
|
+
}
|
|
37
|
+
const maxLines = ctx.config.licenseHeader?.lines ?? DEFAULT_HEADER_LINES;
|
|
38
|
+
let added;
|
|
39
|
+
try {
|
|
40
|
+
if (!ctx.baseSha && ctx.config.run?.fullScanBehaviour === 'skip')
|
|
41
|
+
return pass();
|
|
42
|
+
// Added files in delta mode; every tracked source file in full mode.
|
|
43
|
+
const args = ctx.baseSha
|
|
44
|
+
? ['diff', '--name-only', '--diff-filter=A', ctx.baseSha, ctx.headSha ?? 'HEAD']
|
|
45
|
+
: ['ls-files'];
|
|
46
|
+
const { stdout } = await execa('git', args, { cwd: ctx.cwd });
|
|
47
|
+
// Its own git call rather than `resolveTargets`, and for one reason:
|
|
48
|
+
// `--diff-filter=A`. This check is about files a PR ADDS, and the shared
|
|
49
|
+
// resolver asks for ACMR — routing through it would start demanding a
|
|
50
|
+
// header on every modified file too, which is a different check. So the
|
|
51
|
+
// client's `excludePaths` is applied here explicitly instead (ticket 080).
|
|
52
|
+
added = excludeClientPaths(stdout.split('\n').filter(Boolean), ctx.cwd).filter(f => SOURCE_EXT.test(f));
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
logger.warn(`[License Header]: ⚠️ Could not analyze diff\n${err}`);
|
|
56
|
+
return skip('diff unavailable');
|
|
57
|
+
}
|
|
58
|
+
const missing = [];
|
|
59
|
+
for (const file of added) {
|
|
60
|
+
let head;
|
|
61
|
+
try {
|
|
62
|
+
head = fs
|
|
63
|
+
.readFileSync(path.join(ctx.cwd, file), 'utf-8')
|
|
64
|
+
.split('\n')
|
|
65
|
+
.slice(0, maxLines)
|
|
66
|
+
.join('\n');
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
continue; // removed/renamed between diff and read
|
|
70
|
+
}
|
|
71
|
+
if (!header.test(head))
|
|
72
|
+
missing.push(file);
|
|
73
|
+
}
|
|
74
|
+
if (missing.length === 0)
|
|
75
|
+
return pass();
|
|
76
|
+
missing.slice(0, 10).forEach(f => logger.warn(`[License Header]: ⚠️ missing header: ${f}`));
|
|
77
|
+
if (missing.length > 10)
|
|
78
|
+
logger.warn(`[License Header]: ⚠️ ... and ${missing.length - 10} more`);
|
|
79
|
+
return warn(`${missing.length} new source file(s) missing the license header`);
|
|
80
|
+
},
|
|
81
|
+
};
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { pathToFileURL } from 'node:url';
|
|
4
|
+
import { GENERATED_DOC_FILES, getPackageConfigPath, hasLocalConfig, } from '../../../config/index.js';
|
|
5
|
+
import { logger, resolvePackageBin } from '../../../utils/index.js';
|
|
6
|
+
import { resolveTargetFiles } from '../../targets.js';
|
|
7
|
+
import { pass, warn, skip } from '../../types.js';
|
|
8
|
+
function loadUserMarkdownConfig(cwd) {
|
|
9
|
+
const configPath = path.join(cwd, 'pr-checkmate.json');
|
|
10
|
+
if (!fs.existsSync(configPath))
|
|
11
|
+
return {};
|
|
12
|
+
try {
|
|
13
|
+
return JSON.parse(fs.readFileSync(configPath, 'utf-8')).markdownlint || {};
|
|
14
|
+
}
|
|
15
|
+
catch (err) {
|
|
16
|
+
logger.warn(`[Markdown]: ⚠️ Failed to read markdownlint config: ${err}`);
|
|
17
|
+
return {};
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Load the markdownlint library, or `null` when it cannot be found.
|
|
22
|
+
*
|
|
23
|
+
* The library rather than `markdownlint-cli2`: the CLI drags in globby →
|
|
24
|
+
* micromatch → braces, which carries an unpatched advisory every client's
|
|
25
|
+
* `npm audit` then reports against pr-checkmate. We already have the file list
|
|
26
|
+
* from git, so the CLI's globbing bought nothing.
|
|
27
|
+
*
|
|
28
|
+
* Resolved through `resolvePackageBin` and loaded by a dynamic `import()` for the
|
|
29
|
+
* same two reasons as the bundled gofmt: the package may live in a fetched
|
|
30
|
+
* profile directory, and it is ESM while we emit CommonJS.
|
|
31
|
+
*/
|
|
32
|
+
async function loadMarkdownlint() {
|
|
33
|
+
try {
|
|
34
|
+
const promiseEntry = resolvePackageBin('markdownlint', 'lib/exports-promise.mjs');
|
|
35
|
+
const mainEntry = path.join(path.dirname(promiseEntry), 'exports.mjs');
|
|
36
|
+
const promise = (await import(pathToFileURL(promiseEntry).href));
|
|
37
|
+
const main = (await import(pathToFileURL(mainEntry).href));
|
|
38
|
+
return { lint: promise.lint, readConfig: promise.readConfig, applyFixes: main.applyFixes };
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
logger.warn(`[Markdown]: ⚠️ markdownlint could not be loaded\n${err}`);
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The rules to lint with: the repository's own config when it has one, ours
|
|
47
|
+
* (plus the client's `markdownlint.rules`) when it does not. Someone with a
|
|
48
|
+
* `.markdownlint.json` has an opinion; merging ours into it would silently
|
|
49
|
+
* override the rules they wrote.
|
|
50
|
+
*/
|
|
51
|
+
async function readLintConfig(lib, cwd, userRules) {
|
|
52
|
+
const local = ['.markdownlint.json', '.markdownlint.jsonc'].find(name => hasLocalConfig([name], cwd));
|
|
53
|
+
if (local)
|
|
54
|
+
return lib.readConfig(path.join(cwd, local));
|
|
55
|
+
if (hasLocalConfig(['.markdownlint.yaml', '.markdownlint.yml'], cwd)) {
|
|
56
|
+
logger.warn('[Markdown]: ⚠️ YAML markdownlint configs are not supported, using bundled rules');
|
|
57
|
+
}
|
|
58
|
+
const bundled = await lib.readConfig(getPackageConfigPath('.markdownlint.json'));
|
|
59
|
+
return { ...bundled, ...userRules };
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* An ignore pattern as a regular expression over a repo-relative path.
|
|
63
|
+
*
|
|
64
|
+
* A bare directory name excludes its contents; a file name matches exactly; `*`
|
|
65
|
+
* stays within a segment and `**` crosses them. `path.extname` is what tells a
|
|
66
|
+
* directory from a file, and it reads a leading dot as part of the name, so
|
|
67
|
+
* `.claude` is still the directory it is.
|
|
68
|
+
*/
|
|
69
|
+
function toIgnoreRegExp(pattern) {
|
|
70
|
+
const clean = pattern.replace(/\/+$/, '');
|
|
71
|
+
const escaped = clean
|
|
72
|
+
.replace(/[.+^${}()|[\]\\]/g, '\\$&')
|
|
73
|
+
.replace(/\*\*\//g, '\u0001')
|
|
74
|
+
.replace(/\*\*/g, '\u0000')
|
|
75
|
+
.replace(/\*/g, '[^/]*')
|
|
76
|
+
.replace(/\u0001/g, '(?:.*/)?')
|
|
77
|
+
.replace(/\u0000/g, '.*');
|
|
78
|
+
const isDir = !clean.includes('*') && !path.extname(clean);
|
|
79
|
+
return new RegExp(`^${escaped}${isDir ? '(/.*)?' : ''}$`);
|
|
80
|
+
}
|
|
81
|
+
export const markdownLintCheck = {
|
|
82
|
+
name: 'Markdown',
|
|
83
|
+
phase: 'informational',
|
|
84
|
+
applies() {
|
|
85
|
+
return true;
|
|
86
|
+
},
|
|
87
|
+
async run(ctx) {
|
|
88
|
+
const targets = await resolveTargetFiles(ctx, ['*.md', '*.mdx']);
|
|
89
|
+
if (targets === null)
|
|
90
|
+
return skip('git unavailable');
|
|
91
|
+
if (targets.length === 0)
|
|
92
|
+
return skip('no markdown files');
|
|
93
|
+
const userConfig = loadUserMarkdownConfig(ctx.cwd);
|
|
94
|
+
const userRules = userConfig.rules ?? {};
|
|
95
|
+
const lib = await loadMarkdownlint();
|
|
96
|
+
if (!lib)
|
|
97
|
+
return warn('markdownlint failed to run (exit 2) — check the markdownlint config');
|
|
98
|
+
const ignores = [
|
|
99
|
+
'node_modules/**',
|
|
100
|
+
'dist/**',
|
|
101
|
+
'coverage/**',
|
|
102
|
+
'graphify-out/**',
|
|
103
|
+
'.claude/**',
|
|
104
|
+
// Release-tool output, not prose anyone edits — see GENERATED_DOC_FILES.
|
|
105
|
+
...GENERATED_DOC_FILES,
|
|
106
|
+
...(userConfig.ignores ?? []),
|
|
107
|
+
].map(toIgnoreRegExp);
|
|
108
|
+
const files = targets.filter(file => !ignores.some(re => re.test(file)));
|
|
109
|
+
if (files.length === 0)
|
|
110
|
+
return skip('no markdown files');
|
|
111
|
+
try {
|
|
112
|
+
const config = await readLintConfig(lib, ctx.cwd, userRules);
|
|
113
|
+
const results = await lib.lint({ files: files.map(f => path.resolve(ctx.cwd, f)), config });
|
|
114
|
+
let findings = 0;
|
|
115
|
+
for (const [file, errors] of Object.entries(results)) {
|
|
116
|
+
if (errors.length === 0)
|
|
117
|
+
continue;
|
|
118
|
+
const rel = path.relative(ctx.cwd, file);
|
|
119
|
+
let remaining = errors;
|
|
120
|
+
if (ctx.write && errors.some(e => e.fixInfo)) {
|
|
121
|
+
const fixed = lib.applyFixes(fs.readFileSync(file, 'utf-8'), errors);
|
|
122
|
+
fs.writeFileSync(file, fixed);
|
|
123
|
+
remaining = errors.filter(e => !e.fixInfo);
|
|
124
|
+
}
|
|
125
|
+
for (const e of remaining) {
|
|
126
|
+
findings++;
|
|
127
|
+
const col = e.errorRange?.[0] ? `:${e.errorRange[0]}` : '';
|
|
128
|
+
logger.warn(`${rel}:${e.lineNumber}${col} ${e.ruleNames.join('/')} ${e.ruleDescription}` +
|
|
129
|
+
(e.errorDetail ? ` [${e.errorDetail}]` : ''));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return findings === 0 ? pass() : warn('markdown lint issues found');
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
// An unreadable config or a file that vanished: the tool could not run,
|
|
136
|
+
// which is not the same claim as "the prose has problems".
|
|
137
|
+
logger.warn(`[Markdown]: ⚠️ ${err}`);
|
|
138
|
+
return warn('markdownlint failed to run (exit 2) — check the markdownlint config');
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Check } from '../../types.js';
|
|
2
|
+
/** Why we could not read a published version. */
|
|
3
|
+
export type QueryFailure = 'absent' | 'unauthenticated' | 'unreadable';
|
|
4
|
+
/**
|
|
5
|
+
* Tell "never published" apart from "we were not let in".
|
|
6
|
+
*
|
|
7
|
+
* Lumped into one sentence they read the same and they are not: one is a fact
|
|
8
|
+
* about the package, the other is about this run's credentials. A skip whose
|
|
9
|
+
* reason is a guess between two causes is the defect of ticket 057, one layer up.
|
|
10
|
+
*
|
|
11
|
+
* A 401 is also evidence in itself, and it points one way: a name nobody ever
|
|
12
|
+
* published answers 404 on the public registry, while 401 comes from a host that
|
|
13
|
+
* has the package and will not show it to a stranger. So the message leads with
|
|
14
|
+
* the token, which is what that situation actually needs.
|
|
15
|
+
*
|
|
16
|
+
* It deliberately does NOT suggest `"private": true` as the way out. That field
|
|
17
|
+
* means "never publish this", and a package behind a private registry is
|
|
18
|
+
* published — advising it would break the publish step of the very repository
|
|
19
|
+
* asking. `packageSize.enabled: false` silences the row and touches nothing
|
|
20
|
+
* else, so that is the opt-out worth naming.
|
|
21
|
+
*/
|
|
22
|
+
export declare function classifyQueryFailure(stderr: string): QueryFailure;
|
|
23
|
+
/**
|
|
24
|
+
* Reports how much the published package grew since the last release.
|
|
25
|
+
*
|
|
26
|
+
* The question this answers is "is it growing without anyone noticing", not "has
|
|
27
|
+
* it crossed a line" — so the comparison is against the previously published
|
|
28
|
+
* version rather than a threshold somebody had to invent. A number a client never
|
|
29
|
+
* configured is a number they will not trust, and a check that fires on every
|
|
30
|
+
* release teaches people to skim the whole report.
|
|
31
|
+
*
|
|
32
|
+
* Advisory by design. Growth is usually earned — a language profile was added, a
|
|
33
|
+
* WASM binary landed — and a red build for it would be wrong. `severity:
|
|
34
|
+
* { "Package Size": "error" }` makes it a gate for a repository that wants one.
|
|
35
|
+
*/
|
|
36
|
+
export declare const packageSizeCheck: Check;
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { execa } from '../../../utils/execa.js';
|
|
4
|
+
import { logger } from '../../../utils/index.js';
|
|
5
|
+
import { pass, skip, warn } from '../../types.js';
|
|
6
|
+
import { logSample } from '../findings.js';
|
|
7
|
+
/** Growth that is worth a row in the report, unless the client says otherwise. */
|
|
8
|
+
const DEFAULT_MAX_GROWTH = 20;
|
|
9
|
+
/** How many of the files behind the growth are named. */
|
|
10
|
+
const NAMED_FILES = 5;
|
|
11
|
+
/**
|
|
12
|
+
* Ask npm what a tarball would contain, without producing one.
|
|
13
|
+
*
|
|
14
|
+
* `--dry-run` writes nothing to the working tree — which matters, because a check
|
|
15
|
+
* whose side effect is a `.tgz` beside the source shows up in the client's next
|
|
16
|
+
* commit. Given a package spec instead of nothing, npm answers for the PUBLISHED
|
|
17
|
+
* version, with the same shape and the same per-file detail; that is what makes a
|
|
18
|
+
* real comparison possible rather than a bare number.
|
|
19
|
+
*
|
|
20
|
+
* `--ignore-scripts` is not negotiable. `npm pack` runs `prepare` and `prepack`,
|
|
21
|
+
* and in a client's repository those are arbitrary commands — frequently a full
|
|
22
|
+
* build. A quality check that executes them has stopped being a check and started
|
|
23
|
+
* being a build step with side effects nobody asked for. We are a supply-chain
|
|
24
|
+
* tool; the same rule already governs the install path and the Docker build.
|
|
25
|
+
*
|
|
26
|
+
* @param cwd Repository to run in.
|
|
27
|
+
* @param spec `undefined` for the working tree, or `name@tag` for a release.
|
|
28
|
+
* @param registry Where to look for a published version; the manifest's own
|
|
29
|
+
* `publishConfig.registry` when it names one.
|
|
30
|
+
*/
|
|
31
|
+
async function packManifest(cwd, spec, registry) {
|
|
32
|
+
const args = [
|
|
33
|
+
'pack',
|
|
34
|
+
...(spec ? [spec] : []),
|
|
35
|
+
'--dry-run',
|
|
36
|
+
'--json',
|
|
37
|
+
'--ignore-scripts',
|
|
38
|
+
...(registry ? ['--registry', registry] : []),
|
|
39
|
+
];
|
|
40
|
+
const result = await execa('npm', args, { cwd, reject: false });
|
|
41
|
+
if (result.exitCode !== 0)
|
|
42
|
+
return { failure: classifyQueryFailure(result.stderr ?? '') };
|
|
43
|
+
try {
|
|
44
|
+
const parsed = JSON.parse(result.stdout);
|
|
45
|
+
if (Array.isArray(parsed) && parsed.length > 0) {
|
|
46
|
+
return { manifest: parsed[0] };
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// Fall through: npm answered with something that is not a manifest.
|
|
51
|
+
}
|
|
52
|
+
return { failure: 'unreadable' };
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Tell "never published" apart from "we were not let in".
|
|
56
|
+
*
|
|
57
|
+
* Lumped into one sentence they read the same and they are not: one is a fact
|
|
58
|
+
* about the package, the other is about this run's credentials. A skip whose
|
|
59
|
+
* reason is a guess between two causes is the defect of ticket 057, one layer up.
|
|
60
|
+
*
|
|
61
|
+
* A 401 is also evidence in itself, and it points one way: a name nobody ever
|
|
62
|
+
* published answers 404 on the public registry, while 401 comes from a host that
|
|
63
|
+
* has the package and will not show it to a stranger. So the message leads with
|
|
64
|
+
* the token, which is what that situation actually needs.
|
|
65
|
+
*
|
|
66
|
+
* It deliberately does NOT suggest `"private": true` as the way out. That field
|
|
67
|
+
* means "never publish this", and a package behind a private registry is
|
|
68
|
+
* published — advising it would break the publish step of the very repository
|
|
69
|
+
* asking. `packageSize.enabled: false` silences the row and touches nothing
|
|
70
|
+
* else, so that is the opt-out worth naming.
|
|
71
|
+
*/
|
|
72
|
+
export function classifyQueryFailure(stderr) {
|
|
73
|
+
if (/\bE?40[13]\b|Unauthorized|Forbidden|authentication token/i.test(stderr)) {
|
|
74
|
+
return 'unauthenticated';
|
|
75
|
+
}
|
|
76
|
+
if (/\bE?404\b|Not found/i.test(stderr))
|
|
77
|
+
return 'absent';
|
|
78
|
+
return 'unreadable';
|
|
79
|
+
}
|
|
80
|
+
/** `1.15 MB`, at the precision a human compares two of these at. */
|
|
81
|
+
function mb(bytes) {
|
|
82
|
+
return `${(bytes / 1024 / 1024).toFixed(2)} MB`;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Which files account for the growth, biggest first.
|
|
86
|
+
*
|
|
87
|
+
* A percentage alone is a finding nobody can act on — the same defect as a
|
|
88
|
+
* duplicate-code report with no file names (ticket 078). The published manifest
|
|
89
|
+
* carries per-file sizes, so the answer is a plain diff of the two lists: files
|
|
90
|
+
* that appeared, and files that grew.
|
|
91
|
+
*/
|
|
92
|
+
function growthByFile(before, after) {
|
|
93
|
+
const old = new Map(before.map(f => [f.path, f.size]));
|
|
94
|
+
return after
|
|
95
|
+
.map(f => ({ path: f.path, delta: f.size - (old.get(f.path) ?? 0), isNew: !old.has(f.path) }))
|
|
96
|
+
.filter(f => f.delta > 0)
|
|
97
|
+
.sort((a, b) => b.delta - a.delta)
|
|
98
|
+
.slice(0, NAMED_FILES)
|
|
99
|
+
.map(f => `${f.path} +${mb(f.delta)}${f.isNew ? ' (new)' : ''}`);
|
|
100
|
+
}
|
|
101
|
+
/** What this repository publishes, and where — or `null` if it publishes nothing. */
|
|
102
|
+
function published(cwd) {
|
|
103
|
+
try {
|
|
104
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(cwd, 'package.json'), 'utf-8'));
|
|
105
|
+
if (pkg.private || !pkg.name)
|
|
106
|
+
return null;
|
|
107
|
+
// `publishConfig.registry` is the manifest's own statement of where this
|
|
108
|
+
// package lives, and npm uses it for `publish` but not for a fetch. Asking
|
|
109
|
+
// the default registry instead reports "no published version" for every
|
|
110
|
+
// package on GitHub Packages or a company mirror — which is not a fact about
|
|
111
|
+
// the package, it is us having asked the wrong host. Measured on a real
|
|
112
|
+
// client: the default registry answered 404 for a package published at
|
|
113
|
+
// version 1.2.15.
|
|
114
|
+
const registry = pkg.publishConfig?.registry;
|
|
115
|
+
return registry ? { name: pkg.name, registry } : { name: pkg.name };
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Reports how much the published package grew since the last release.
|
|
123
|
+
*
|
|
124
|
+
* The question this answers is "is it growing without anyone noticing", not "has
|
|
125
|
+
* it crossed a line" — so the comparison is against the previously published
|
|
126
|
+
* version rather than a threshold somebody had to invent. A number a client never
|
|
127
|
+
* configured is a number they will not trust, and a check that fires on every
|
|
128
|
+
* release teaches people to skim the whole report.
|
|
129
|
+
*
|
|
130
|
+
* Advisory by design. Growth is usually earned — a language profile was added, a
|
|
131
|
+
* WASM binary landed — and a red build for it would be wrong. `severity:
|
|
132
|
+
* { "Package Size": "error" }` makes it a gate for a repository that wants one.
|
|
133
|
+
*/
|
|
134
|
+
export const packageSizeCheck = {
|
|
135
|
+
name: 'Package Size',
|
|
136
|
+
phase: 'informational',
|
|
137
|
+
weight: 'heavy',
|
|
138
|
+
applies(ctx) {
|
|
139
|
+
if (ctx.config.packageSize?.enabled === false)
|
|
140
|
+
return false;
|
|
141
|
+
// A private package is never published, so there is nothing to compare with
|
|
142
|
+
// and no consumer to pay for the growth.
|
|
143
|
+
return published(ctx.cwd) !== null;
|
|
144
|
+
},
|
|
145
|
+
async run(ctx) {
|
|
146
|
+
const target = published(ctx.cwd);
|
|
147
|
+
if (!target)
|
|
148
|
+
return skip('no publishable package.json');
|
|
149
|
+
const tag = ctx.config.packageSize?.compareWith ?? 'latest';
|
|
150
|
+
const maxGrowth = ctx.config.packageSize?.maxGrowthPercent ?? DEFAULT_MAX_GROWTH;
|
|
151
|
+
const spec = `${target.name}@${tag}`;
|
|
152
|
+
const local = await packManifest(ctx.cwd);
|
|
153
|
+
if (!('manifest' in local))
|
|
154
|
+
return skip('npm could not describe this package');
|
|
155
|
+
const current = local.manifest;
|
|
156
|
+
// Never a pass: a green row over a comparison that did not happen is the
|
|
157
|
+
// mistake of ticket 072. And never one reason standing in for three — the
|
|
158
|
+
// three are different situations for the reader, and only one of them is a
|
|
159
|
+
// fact about the package rather than about the run.
|
|
160
|
+
const remote = await packManifest(ctx.cwd, spec, target.registry);
|
|
161
|
+
if (!('manifest' in remote)) {
|
|
162
|
+
// The fact, and nothing past it. The remedy for a private registry is three
|
|
163
|
+
// lines in a workflow — `setup-node` with `registry-url`, a scope, and
|
|
164
|
+
// `NODE_AUTH_TOKEN`, because npm reads the token through a reference in
|
|
165
|
+
// `.npmrc` — and instructions that do not fit cannot be followed. They
|
|
166
|
+
// belong on the check's page, which the report already links to.
|
|
167
|
+
//
|
|
168
|
+
// The package name is left out on purpose: the reader owns it. The host is
|
|
169
|
+
// not, because it is the one part they cannot infer — and the difference
|
|
170
|
+
// between "we asked the wrong registry" and "we were refused" is exactly
|
|
171
|
+
// what this row got wrong before.
|
|
172
|
+
// Named only when we know it. Without `publishConfig.registry` npm used
|
|
173
|
+
// whatever the client's own config points at, and we do not know what that
|
|
174
|
+
// was — "at the registry" would be filler dressed up as information.
|
|
175
|
+
const host = target.registry ? new URL(target.registry).host : null;
|
|
176
|
+
const at = host ? ` at ${host}` : '';
|
|
177
|
+
const reason = {
|
|
178
|
+
absent: `nothing published under this name${at} yet`,
|
|
179
|
+
unauthenticated: `no credentials for ${host ?? 'the registry'}`,
|
|
180
|
+
unreadable: `could not read the published version${at}`,
|
|
181
|
+
}[remote.failure];
|
|
182
|
+
return skip(reason);
|
|
183
|
+
}
|
|
184
|
+
const previous = remote.manifest;
|
|
185
|
+
const delta = current.unpackedSize - previous.unpackedSize;
|
|
186
|
+
const growth = previous.unpackedSize > 0 ? (delta / previous.unpackedSize) * 100 : 0;
|
|
187
|
+
const summary = `${mb(previous.unpackedSize)} → ${mb(current.unpackedSize)} ` +
|
|
188
|
+
`(${growth >= 0 ? '+' : ''}${growth.toFixed(1)}%) vs ${previous.version}`;
|
|
189
|
+
if (growth <= maxGrowth) {
|
|
190
|
+
logger.info(`[Package Size]: ✅ ${summary}`);
|
|
191
|
+
return pass(summary);
|
|
192
|
+
}
|
|
193
|
+
logSample('Package Size', `${summary}:`, growthByFile(previous.files, current.files));
|
|
194
|
+
return warn(summary);
|
|
195
|
+
},
|
|
196
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { CspellConfig } from '../../../interfaces/index.js';
|
|
2
|
+
import { Check } from '../../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Anchors an ignore glob to the repository root.
|
|
5
|
+
*
|
|
6
|
+
* cspell matches `ignorePaths` against each file's ABSOLUTE path, so an unanchored
|
|
7
|
+
* `**\/build/**` also matches every ancestor directory of the workspace. On Bitbucket
|
|
8
|
+
* Pipelines the clone lives in `/opt/atlassian/pipelines/agent/build`, so that one
|
|
9
|
+
* pattern excluded the entire repository and the check silently spellchecked nothing.
|
|
10
|
+
* A leading `/` anchors the pattern to the config's directory (the repo root) while
|
|
11
|
+
* `/**\/dir/**` still matches at any depth INSIDE the repo — verified against cspell 10.
|
|
12
|
+
*
|
|
13
|
+
* Patterns that are already anchored (`/…`) or plainly relative (`dir/**`,
|
|
14
|
+
* `CHANGELOG.md`) are left untouched: they cannot match an ancestor.
|
|
15
|
+
*/
|
|
16
|
+
export declare function anchorIgnoreGlob(pattern: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Folds the client's `cspell` block from pr-checkmate.json into the bundled
|
|
19
|
+
* defaults. `enabled` is deliberately not carried over — it gates the check
|
|
20
|
+
* itself (see `applies`) and is not a cspell setting.
|
|
21
|
+
*
|
|
22
|
+
* Lists are appended so a client extends the curated vocabulary instead of
|
|
23
|
+
* replacing it; `language` is the one exception and replaces the default, because
|
|
24
|
+
* a client writing `"en"` means exactly that and appending would be meaningless.
|
|
25
|
+
*/
|
|
26
|
+
export declare function mergeCspellConfig(defaultConfig: CspellConfig, userConfig: Partial<CspellConfig>): CspellConfig;
|
|
27
|
+
/**
|
|
28
|
+
* The optional dictionaries this installation actually has — and what to do
|
|
29
|
+
* about the ones it does not.
|
|
30
|
+
*
|
|
31
|
+
* Dropping a dictionary must not turn into a flood of warnings: a repository
|
|
32
|
+
* with Russian comments would report every Russian word as a misspelling, which
|
|
33
|
+
* is worse than the ~9 MB the dictionaries cost. So for the languages written in
|
|
34
|
+
* a script of their own, absence suppresses that script instead: cspell cannot
|
|
35
|
+
* judge those words, and reporting words it cannot judge is noise, not coverage.
|
|
36
|
+
*
|
|
37
|
+
* Latin-script languages (French, Spanish) have no such escape — their words are
|
|
38
|
+
* indistinguishable from misspelled English — so their absence is only logged,
|
|
39
|
+
* with the command that restores them.
|
|
40
|
+
*
|
|
41
|
+
* @returns imports and language codes to enable, ignore patterns for scripts left
|
|
42
|
+
* without a dictionary, and the packages a client may want to install.
|
|
43
|
+
*/
|
|
44
|
+
export declare function availableDictionaries(resolve?: (id: string) => string): {
|
|
45
|
+
imports: string[];
|
|
46
|
+
languages: string[];
|
|
47
|
+
ignoreRegExpList: string[];
|
|
48
|
+
absent: string[];
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Turn config imports into absolute paths, dropping the ones that are not installed.
|
|
52
|
+
*
|
|
53
|
+
* An unresolvable `import` is not a soft failure in cspell: it aborts config
|
|
54
|
+
* loading, checks **zero files**, and exits 1 — which this check would then have
|
|
55
|
+
* reported as "spelling issues found", a warning about problems that do not exist
|
|
56
|
+
* on a run that examined nothing. Passing the raw string through and hoping cspell
|
|
57
|
+
* copes is therefore the one thing that must not happen.
|
|
58
|
+
*
|
|
59
|
+
* @returns the imports that resolved, plus the language codes left without a
|
|
60
|
+
* dictionary so the caller can drop them from `language`.
|
|
61
|
+
*/
|
|
62
|
+
export declare function resolveImports(imports: string[], baseDir: string, resolve?: (id: string) => string): {
|
|
63
|
+
resolved: string[];
|
|
64
|
+
missing: Array<{
|
|
65
|
+
pkg: string;
|
|
66
|
+
lang?: string;
|
|
67
|
+
}>;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Drop language codes whose dictionary is absent.
|
|
71
|
+
*
|
|
72
|
+
* Leaving `ru` in `language` with no Russian dictionary does not spellcheck
|
|
73
|
+
* Russian — it reports every Russian word as a misspelling. Having no opinion is
|
|
74
|
+
* the honest outcome when the dictionary that would form one is not installed.
|
|
75
|
+
*/
|
|
76
|
+
export declare function dropMissingLanguages(language: string, missing: string[]): string;
|
|
77
|
+
export declare const spellcheckCheck: Check;
|