Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1146 +/- ##
==========================================
+ Coverage 92.13% 92.18% +0.04%
==========================================
Files 112 113 +1
Lines 23235 23555 +320
==========================================
+ Hits 21408 21714 +306
- Misses 1827 1841 +14 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
📦 Cargo Bloat ComparisonBinary size change: +0.00% (25.7 MiB → 25.7 MiB) Expand for cargo-bloat outputHead Branch ResultsBase Branch Results |
|
Still early WIP-haven't checked the parts around the missing test yet. I'd like to try this out with my Flutter repo so that's why I start this PR. Also, I'm using Claude code on web (which is providing credits until tomorrow) for much of the implementation. Plan to do a deeper cleanup and address more details tomorrow. Let me know if you have any early feedback or suggestions! |
|
I came across this repo thanks to the PR to Scoop. It's a great project, and I hope to contribute some features or fixes as I get more familiar with it! |
|
Thank you! The code looks good to me. However, since I'm not very familiar with the Dart ecosystem, I'll need a bit more time to review the details and make sure everything works as expected. |
0264c93 to
9d1e1ec
Compare
⚡️ Hyperfine BenchmarksSummary: 0 regressions, 0 improvements above the 10% threshold. Environment
CLI CommandsBenchmarking basic commands in the main repo:
|
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base --version |
2.2 ± 0.1 | 2.0 | 2.8 | 1.01 ± 0.06 |
prek-head --version |
2.2 ± 0.1 | 2.0 | 2.6 | 1.00 |
prek list
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base list |
8.6 ± 0.2 | 8.4 | 10.1 | 1.00 |
prek-head list |
8.7 ± 0.2 | 8.4 | 9.7 | 1.01 ± 0.04 |
prek validate-config .pre-commit-config.yaml
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base validate-config .pre-commit-config.yaml |
2.9 ± 0.0 | 2.8 | 3.0 | 1.00 |
prek-head validate-config .pre-commit-config.yaml |
2.9 ± 0.1 | 2.8 | 3.5 | 1.01 ± 0.04 |
prek sample-config
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base sample-config |
2.4 ± 0.0 | 2.3 | 2.5 | 1.00 |
prek-head sample-config |
2.4 ± 0.0 | 2.3 | 2.5 | 1.01 ± 0.02 |
Cold vs Warm Runs
Comparing first run (cold) vs subsequent runs (warm cache):
prek run --all-files (cold - no cache)
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run --all-files |
142.4 ± 2.4 | 138.4 | 145.3 | 1.00 |
prek-head run --all-files |
144.9 ± 3.5 | 138.2 | 149.8 | 1.02 ± 0.03 |
prek run --all-files (warm - with cache)
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run --all-files |
140.8 ± 2.9 | 135.5 | 146.7 | 1.00 |
prek-head run --all-files |
140.9 ± 3.1 | 135.5 | 146.8 | 1.00 ± 0.03 |
Full Hook Suite
Running the builtin hook suite on the benchmark workspace:
prek run --all-files (full builtin hook suite)
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run --all-files |
141.8 ± 3.7 | 134.7 | 151.7 | 1.00 |
prek-head run --all-files |
142.2 ± 3.7 | 135.7 | 150.0 | 1.00 ± 0.04 |
Individual Hook Performance
Benchmarking each hook individually on the test repo:
prek run trailing-whitespace --all-files
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run trailing-whitespace --all-files |
19.9 ± 0.4 | 19.2 | 20.7 | 1.00 |
prek-head run trailing-whitespace --all-files |
25.5 ± 19.5 | 19.5 | 125.5 | 1.28 ± 0.98 |
prek run end-of-file-fixer --all-files
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run end-of-file-fixer --all-files |
26.9 ± 2.3 | 23.2 | 30.6 | 1.02 ± 0.12 |
prek-head run end-of-file-fixer --all-files |
26.3 ± 2.2 | 23.1 | 30.5 | 1.00 |
prek run check-json --all-files
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run check-json --all-files |
11.0 ± 0.2 | 10.6 | 11.6 | 1.01 ± 0.03 |
prek-head run check-json --all-files |
10.9 ± 0.2 | 10.5 | 11.4 | 1.00 |
prek run check-yaml --all-files
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run check-yaml --all-files |
10.8 ± 0.2 | 10.5 | 11.5 | 1.00 ± 0.03 |
prek-head run check-yaml --all-files |
10.8 ± 0.2 | 10.5 | 11.3 | 1.00 |
prek run check-toml --all-files
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run check-toml --all-files |
10.9 ± 0.3 | 10.5 | 11.9 | 1.00 ± 0.04 |
prek-head run check-toml --all-files |
10.9 ± 0.2 | 10.6 | 11.6 | 1.00 |
prek run check-xml --all-files
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run check-xml --all-files |
11.3 ± 0.2 | 10.9 | 11.7 | 1.01 ± 0.03 |
prek-head run check-xml --all-files |
11.2 ± 0.3 | 10.7 | 11.8 | 1.00 |
prek run detect-private-key --all-files
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run detect-private-key --all-files |
17.4 ± 1.4 | 15.4 | 20.3 | 1.04 ± 0.11 |
prek-head run detect-private-key --all-files |
16.8 ± 1.1 | 14.6 | 20.0 | 1.00 |
prek run fix-byte-order-marker --all-files
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run fix-byte-order-marker --all-files |
21.8 ± 1.5 | 19.2 | 24.2 | 1.00 ± 0.11 |
prek-head run fix-byte-order-marker --all-files |
21.7 ± 1.9 | 18.9 | 26.5 | 1.00 |
Installation Performance
Benchmarking hook installation (fast path hooks skip Python setup):
prek install-hooks (cold - no cache)
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base install-hooks |
4.6 ± 0.1 | 4.5 | 4.8 | 1.06 ± 0.03 |
prek-head install-hooks |
4.4 ± 0.1 | 4.3 | 4.4 | 1.00 |
prek install-hooks (warm - with cache)
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base install-hooks |
4.3 ± 0.0 | 4.3 | 4.4 | 1.00 |
prek-head install-hooks |
4.4 ± 0.0 | 4.3 | 4.4 | 1.01 ± 0.01 |
File Filtering/Scoping Performance
Testing different file selection modes:
prek run (staged files only)
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run |
48.2 ± 0.8 | 47.0 | 49.5 | 1.00 |
prek-head run |
48.9 ± 1.1 | 47.2 | 51.0 | 1.01 ± 0.03 |
prek run --files '*.json' (specific file type)
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run --files '*.json' |
8.3 ± 0.2 | 8.0 | 8.6 | 1.03 ± 0.02 |
prek-head run --files '*.json' |
8.1 ± 0.1 | 7.9 | 8.2 | 1.00 |
Workspace Discovery & Initialization
Benchmarking hook discovery and initialization overhead:
prek run --dry-run --all-files (measures init overhead)
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run --dry-run --all-files |
12.5 ± 0.4 | 12.2 | 14.1 | 1.01 ± 0.03 |
prek-head run --dry-run --all-files |
12.4 ± 0.1 | 12.2 | 12.6 | 1.00 |
Meta Hooks Performance
Benchmarking meta hooks separately:
prek run check-hooks-apply --all-files
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run check-hooks-apply --all-files |
12.6 ± 0.1 | 12.5 | 12.7 | 1.00 |
prek-head run check-hooks-apply --all-files |
12.7 ± 0.1 | 12.5 | 13.0 | 1.00 ± 0.01 |
prek run check-useless-excludes --all-files
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run check-useless-excludes --all-files |
12.5 ± 0.1 | 12.3 | 12.7 | 1.11 ± 0.03 |
prek-head run check-useless-excludes --all-files |
11.2 ± 0.3 | 11.0 | 12.4 | 1.00 |
prek run identity --all-files
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run identity --all-files |
9.7 ± 0.1 | 9.6 | 9.9 | 1.00 |
prek-head run identity --all-files |
9.8 ± 0.1 | 9.5 | 9.9 | 1.00 ± 0.01 |
There was a problem hiding this comment.
Pull request overview
Adds initial support for language: dart to prek by introducing a Dart language implementation and an accompanying integration test suite, plus CI wiring to exercise those tests.
Changes:
- Added a new Dart language handler (
crates/prek/src/languages/dart.rs) and wired it into the language dispatcher. - Added comprehensive Dart language integration tests and nextest profile support.
- Updated CI to install Dart and run Dart language tests; added snapshot filtering for Dart version output.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| crates/prek/tests/languages/main.rs | Registers the new dart test module. |
| crates/prek/tests/languages/dart.rs | Adds Dart language integration tests (health, deps, pubspec behavior, env vars, remote hook). |
| crates/prek/tests/common/mod.rs | Adds an insta filter to normalize Dart SDK version output in snapshots. |
| crates/prek/src/languages/mod.rs | Wires Language::Dart into install/health/run dispatch and marks it supported. |
| crates/prek/src/languages/dart.rs | Implements Dart install/health/run logic (system dart, pubspec/env pubspec, dart pub get, executable compilation). |
| crates/prek-consts/src/env_vars.rs | Adds PUB_CACHE env var constant. |
| .github/workflows/ci.yml | Installs Dart in the language test matrix and adds dart to the matrix. |
| .config/nextest.toml | Adds a lang-dart nextest profile to run only Dart language tests. |
| let stdout = Cmd::new(&executable, "get dart version") | ||
| .arg("--version") | ||
| .check(true) | ||
| .output() | ||
| .await? | ||
| .stdout; | ||
|
|
||
| let version = str::from_utf8(&stdout) | ||
| .context("Failed to parse `dart --version` output as UTF-8")? | ||
| .lines() | ||
| .find(|line| line.contains("Dart SDK version:")) | ||
| .and_then(|line| line.split_whitespace().nth(3)) | ||
| .context("Failed to extract Dart version from output")? | ||
| .trim(); | ||
| let version = Version::parse(version).context("Failed to parse Dart version")?; | ||
|
|
There was a problem hiding this comment.
query_dart_info() only parses stdout from dart --version, but many Dart installations print the version string to stderr (similar to java -version). This can make Dart support fail at install/health-check time even though dart is present. Consider parsing from both streams (e.g., combine stdout + stderr, or fall back to stderr when stdout is empty).
| let pubspec_content = Self::build_env_pubspec(source_path, package_name, dependencies)?; | ||
| let pubspec_path = env_path.join("pubspec.yaml"); | ||
| fs_err::tokio::write(&pubspec_path, pubspec_content).await?; | ||
|
|
||
| Cmd::new(dart, "dart pub get") | ||
| .current_dir(env_path) | ||
| .env(EnvVars::PUB_CACHE, env_path) | ||
| .arg("pub") | ||
| .arg("get") | ||
| .check(true) | ||
| .output() | ||
| .await | ||
| .context("Failed to run dart pub get")?; | ||
|
|
||
| Ok(()) |
There was a problem hiding this comment.
PR description mentions installing additional_dependencies via dart pub cache add, but the implementation installs them by generating a pubspec and running dart pub get. Either update the PR description to match the implementation, or switch the code to the intended dart pub cache add flow if that’s required for compatibility with pre-commit’s Dart language behavior.
| #[test] | ||
| // Temporarily hosted under Lutra-Fs until upstream fixture repo access is available. | ||
| fn remote_hook() { | ||
| let context = TestContext::new(); | ||
| context.init_project(); | ||
|
|
||
| context.write_pre_commit_config(indoc::indoc! {r" | ||
| repos: | ||
| - repo: https://github.com/Lutra-Fs/dart-hooks | ||
| rev: v1.1.0 | ||
| hooks: | ||
| - id: dart-hooks | ||
| always_run: true | ||
| verbose: true | ||
| "}); |
There was a problem hiding this comment.
The remote_hook test depends on a third-party repo (Lutra-Fs/dart-hooks) rather than the existing prek-test-repos/* fixtures used by other language tests. This increases CI flakiness/risk (repo rename/deletion, rate limits, etc.). Consider moving the fixture under the project’s standard test-fixture org or vendoring a minimal test repo, or gating/ignoring this test when the fixture isn’t guaranteed available.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e6eeb4fe47
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| Self::install_package_config(dart, env_path, None, None, dependencies) | ||
| .await | ||
| .context("Failed to run dart pub get for additional dependencies") |
There was a problem hiding this comment.
Build binaries for additional Dart deps
This path installs additional_dependencies only via dart pub get and then returns, so no executable is produced in env/bin. In run(), hook entries are resolved from PATH with env/bin prepended, so configurations like entry: some_cli + additional_dependencies: ['some_cli:1.2.3'] will still fail with command-not-found even though dependency installation succeeded. This breaks the common Dart-hook expectation that dependency-provided executables can be invoked as the hook entry.
Useful? React with 👍 / 👎.
Implements full Dart language support following TDD approach:
dart pub getdart pub cache addLanguage features:
Closes #51