Repository navigation
feat: add a JavaScript/TypeScript ecosystem profile - #124
Merged
Merged
Conversation
npm-compatible (package.json) and Deno (deno.json) projects are judged by prettier, biome, deno fmt or dprint; branch coverage from c8, nyc, jest, vitest, deno test or node's test runner; *.test.*, *.spec.* and __tests__/ files run by any common runner; eslint, biome or deno lint as the linter, failing on warnings with --max-warnings 0; npm, pnpm, yarn or bun audits; eslint-plugin-security or semgrep; eslint's max-lines-per-function; tsc (strict in tsconfig.json) or deno check; committed lockfiles; package.json's license; an ignored node_modules/; and the Node.js, Deno and Bun versions CI runs. A package.json alone is the tooling of many projects in other languages, so it makes a JavaScript project only when it names entry points (main, module, exports, bin); JavaScript and TypeScript sources do too. JavaScript tooling mostly runs through package scripts, so the scripts and Deno tasks that CI or a pre-commit hook runs (npm run lint, pnpm lint, deno task fmt, with their pre/post scripts and the scripts they run) count as CI configuration. For that, the Formatter rule gets an optional texts, CI configuration by default, which code-formatting reads; no other check changes. The JSON-with-comments reader moves from data-wellformed to text.py, so profiles can read tsconfig.json and deno.jsonc with evidence.json_value. Closes cpp-best-practices#65 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ByTXNqDWdM7HzezrFtEvQt
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #124 +/- ##
==========================================
+ Coverage 98.51% 98.83% +0.31%
==========================================
Files 58 64 +6
Lines 2297 2928 +631
Branches 231 281 +50
==========================================
+ Hits 2263 2894 +631
Misses 28 28
Partials 6 6 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…adle) Maven and Gradle projects are judged by Spotless (or fmt-maven-plugin, google-java-format, ktfmt, ktlint); JaCoCo or Kover branch coverage; @test methods and Kotest specs under src/test run by mvn or gradle; javac's -Xlint:all (Kotlin warns by default); -Werror or Kotlin's allWarningsAsErrors; OWASP dependency-check; Find Security Bugs or PMD's security rules; Checkstyle MethodLength or detekt LongMethod; Error Prone, SpotBugs, PMD, Checkstyle or detekt; Gradle dependency verification, a gradle.lockfile or Maven's --strict-checksums; ignored target/ (Maven) or build/ (Gradle); and the JDK versions CI runs. JVM builds wire their tools in: a Maven plugin binds a goal to a phase, a Gradle plugin adds its task to check. So the build files count as CI configuration when CI runs the build far enough: any compiling phase or task for compiler flags, mvn verify or gradle check/build for the verification plugins. A Maven plugin counts only when an execution binds the goal. Two language-agnostic changes support it: DependencyAudit gets the optional texts that Formatter got (dependency-check bound in pom.xml), and vcs-ignore judges the BuildOutputs of the build system a project uses, as committed-artifacts already did (judge_each_ecosystem). Tests look up checks by name (checks_named) and layouts by name (run_in_layout). Closes cpp-best-practices#66 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ByTXNqDWdM7HzezrFtEvQt
This was referenced Nov 6, 2026
Composer projects are judged by PHP-CS-Fixer, PHP_CodeSniffer or Pint; PHPUnit --path-coverage, which reports branch and path coverage together (so it earns the path bonus, and line coverage alone counts no branches); *Test.php files with PHPUnit test cases or Pest tests; error_reporting E_ALL while testing; PHPUnit failing on warnings, notices and deprecations; composer audit or roave/security-advisories; Psalm taint analysis or phpcs-security-audit; PHPMD's ExcessiveMethodLength; PHPStan, Psalm, PHPMD or Phan; PHPStan or Psalm as type checkers, strict at PHPStan level 8+ or Psalm errorLevel 1-2; composer.lock for anything not declared a library; composer.json's license; an ignored vendor/; and the PHP versions CI runs. PHP tooling runs through Composer scripts, so the scripts CI runs (composer test, composer run-script x, @x and @composer x inside a script) count as CI configuration. Following scripts moves to evidence.scripts_run, shared with the JavaScript profile. TestSuite gets the optional texts that Formatter and DependencyAudit have, which tests-run reads, so tests run through a script count; the JavaScript profile uses it too. jscpd ignores parenthesised import blocks, which every full profile shares with the others. Closes cpp-best-practices#69 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ByTXNqDWdM7HzezrFtEvQt
Bundler projects (Gemfile, *.gemspec) are judged by RuboCop, Standard or syntax_tree; SimpleCov with enable_coverage :branch; RSpec specs and Minitest tests run by rspec, rake or rails test; Ruby's own warnings while testing plus a linter; bundler-audit; brakeman or RuboCop's Security cops (on by default); RuboCop's Metrics/MethodLength (on by default, off in Standard); RuboCop, Standard or Reek; Sorbet or Steep, strict with # typed: strict or D::Ruby.strict; Gemfile.lock for applications (a gem need not lock); the gemspec's licenses; ignored .bundle/ and vendor/bundle/; and the Ruby versions and implementations CI runs. Ruby projects run their tools through Rake, so the Rakefile and rakelib/*.rake count as CI configuration when CI runs rake: its RSpec::Core::RakeTask and RuboCop::RakeTask then run the specs and the linter. Closes cpp-best-practices#68 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ByTXNqDWdM7HzezrFtEvQt
MSBuild projects (*.csproj, *.fsproj, *.sln, *.slnx, Directory.Build.props, global.json) are judged by dotnet format, CSharpier or Fantomas; coverlet, dotnet-coverage or Microsoft.Testing.Platform coverage; test projects referencing Microsoft.NET.Test.Sdk (or MSTest.Sdk) run by dotnet test; AnalysisMode Recommended or All, EnforceCodeStyleInBuild and Nullable for C# (<WarnOn> for F#-only projects); TreatWarningsAsErrors; NuGet audit of every package or dotnet list package --vulnerable; the analyzers' Security category or Security Code Scan; lizard for C# (F#-only projects are skipped); analyzer packages such as Roslynator or FSharpLint; committed packages.lock.json files; PackageLicenseExpression; ignored bin/ and obj/; and the SDK versions CI runs. MSBuild reads its settings from the project files and Directory.Build.props, so those count as CI configuration when CI builds, restores or tests. bin/ and obj/ beside a project file are build output and are never inspected. Binary hardening (native AOT, CetCompat) is left for a decision, as cpp-best-practices#67 asks, and ci-build-types stays C/C++ and Rust: its requirement includes sanitizer builds, which .NET does not have. Closes cpp-best-practices#67 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ByTXNqDWdM7HzezrFtEvQt
SwiftPM (Package.swift) and Xcode (*.xcodeproj/, *.xcworkspace/) projects are judged by swift-format or SwiftFormat in lint mode; region coverage from swift test --enable-code-coverage or Xcode's coverage (Swift's instrumentation counts regions, not branches); XCTest cases or Swift Testing @test functions run by swift test or xcodebuild test; SwiftLint plus complete concurrency checking; -warnings-as-errors, treatAllWarnings(as: .error) or SWIFT_TREAT_WARNINGS_AS_ERRORS; releases that keep Swift's runtime safety checks (no -Ounchecked or unchecked exclusivity); SwiftLint's function_body_length; SwiftLint as the static analyzer; osv-scanner as the audit; Package.resolved for applications; ignored .build/ (SwiftPM) or xcuserdata/ and DerivedData/ (Xcode); and the Swift and Xcode versions CI runs, each built debug and release, with and without sanitizers. Build configurations now include SwiftPM's (debug unless -c release) and xcodebuild's -configuration, beside CMake build types and Cargo profiles. The README's "Applies to" cells lose a doubled space. Closes cpp-best-practices#70 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ByTXNqDWdM7HzezrFtEvQt
feat: add a Swift ecosystem profile (SwiftPM and Xcode)
feat: add a .NET ecosystem profile (C# and F#)
feat: add a Ruby ecosystem profile
feat: add a PHP ecosystem profile
feat: add a JVM ecosystem profile (Java and Kotlin, with Maven and Gradle)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #65. First step of Phase 4 in #107.
project_validator/ecosystems/javascript.pyjudges npm-compatible projects (package.json: npm, pnpm, yarn, bun) and Deno projects (deno.json/deno.jsonc). The ecosystem's label isJavaScript/TypeScript, and it covers two languages:.js .mjs .cjs .jsxcount as JavaScript, and.ts .mts .cts .tsxas TypeScript.tests-run*.test.*,*.spec.*,*_test.*(Deno) or__tests__/files exist, and jest, vitest, mocha, ava,node --test,deno test,bun test, playwright ornpm testruns themcoveragejest --coverage/collectCoverage: true,vitest --coverage/ coverageenabled: true,deno test --coverageornode --experimental-test-coverageis used (all of them report branches)code-formattingprettier --check,biome format/check/ci,deno fmt --checkordprint check. All of them have a default stylecompiler-warningsdeno lintwarnings-as-errorseslint --max-warnings 0,biome ci/--error-on-warnings, ordeno lintdependency-auditnpm audit(notnpm audit signatures),pnpm audit,yarn (npm) auditorbun auditrunssecurity-scanningeslint-plugin-security(or@microsoft/eslint-plugin-sdl) is used, or semgrep runs with a JavaScript rulesetfunction-limitsmax-lines-per-functionenabled. It warns when the rule is enabled but eslint never runsstatic-analysistype-checkingtsc/vue-tsc,deno checkordeno testruns. Bonus:"strict": trueor@tsconfig/strictestintsconfig.json/jsconfig.json, or a Deno project, which is strict unless"strict": falsedependency-managementpackage.json(orimportsindeno.json) are locked by a committedpackage-lock.json,npm-shrinkwrap.json,pnpm-lock.yaml,yarn.lock,bun.lock(b)ordeno.locklicenselicenseinpackage.jsonvcs-ignore/committed-artifactsnode_modules/is ignored.node_modules/, a top-levelcoverage/and*.tsbuildinfomust not be committedplatform-matrixnode-version,deno-version,bun-version,node:/denoland/deno:/oven/bun:images)hardeningandci-build-typesdo not apply, because JavaScript builds no native binary.How a project is recognised. Many projects in other languages have a
package.jsonjust for their tooling, so that file alone does not make a JavaScript project. It counts only when it names entry points (main,module,exportsorbin), or when JavaScript or TypeScript sources exist outsidenode_modules.deno.jsonalways counts.Package scripts count as CI. JavaScript tools mostly run through package scripts (
npm run lint), not straight from CI. So when CI or a pre-commit hook runs a script, its text counts as evidence too. This coversnpm run lint,npm test,pnpm lint,yarn run x,bun run xanddeno task x, plus theirpre/postscripts and any scripts they call in turn. A script that CI never runs counts for nothing.Changes outside the profile (please review)
#107 says nothing in
project_validator/checks/should change for a new ecosystem. Two small, language-agnostic changes were needed:Formattergets an optionaltexts. Before,code-formattingsearched only CI configuration, sonpm run format:checkwould always fail. The default is still CI configuration, so every existing profile behaves exactly as before. The check now readsformatter.texts(context), a one-line change.checks/data_wellformed.pytotext.strip_json_comments. Profiles can now readtsconfig.jsonanddeno.jsoncwith the newevidence.json_value, which mirrorstoml_value.data-wellformedbehaves the same.Deviations from #65 (please confirm)
branchesthreshold (Add a JavaScript/TypeScript ecosystem profile (Node, Deno, Bun) #65) is not path coverage, so it earns no bonus. Neither Istanbul nor V8 reports path coverage, so this profile has no path patterns and no path hint.npm ci,--frozen-lockfile,--immutable). That is not judged:DependencyManagementhas no place for it.dependency-managementcheck: dependencies come from a package manager #24's open question is whether libraries are exempt. A package's lockfile is never published, so npm's own guidance is to commit it in libraries as well. Rust exempts library crates; this profile does not.dist/may be committed. It is suggested as an ignore entry, but it is not acommitted-artifactsfailure, because a JavaScript GitHub Action has to commit its bundle.type-checkinganddependency-managementrows of Add a JavaScript/TypeScript ecosystem profile (Node, Deno, Bun) #65, marked later, are included now that those checks exist, as Action plan: order of execution for the ecosystem roadmap and strict self-validation #107's Phase 3 intended. So arestatic-analysisandlicense.Tests
tests/fixtures/well_configured_javascriptpasses every check that applies to it.tests/fixtures/bare_javascriptfails or warns on every JavaScript practice (tests/test_ecosystem_contract.py).tests/test_javascript.pycovers recognition, script following, and each rule.tests/support.py: npm JavaScript and Deno TypeScript.SKIPmessages change. No CI job is attributed differently.npxalone is not treated as JavaScript usage, because other ecosystems' CI runs jscpd with it.Local gates all pass:
python -W error -m unittest(624 tests)lizard --length 30project-validator --strict --exclude tests/fixtures .🤖 Generated with Claude Code
https://claude.ai/code/session_01ByTXNqDWdM7HzezrFtEvQt