Skip to content

Add DAG-based hook scheduling with group and after#1704

Draft
drichardson wants to merge 6 commits intoj178:masterfrom
drichardson:dag-scheduling
Draft

Add DAG-based hook scheduling with group and after#1704
drichardson wants to merge 6 commits intoj178:masterfrom
drichardson:dag-scheduling

Conversation

@drichardson
Copy link
Contributor

Summary

  • Adds two new optional config fields — group and after — that let users express a DAG of hook dependencies
  • prek builds the DAG, schedules maximally parallel execution, and only serializes where explicit dependency edges exist
  • priority continues to work unchanged; priority and group/after are mutually exclusive on the same hook
  • Includes cycle detection, unknown reference errors, and 7 new integration tests
  • See docs/proposals/dag-scheduling.md for the full design

Test plan

  • cargo build compiles
  • All 294 existing unit tests pass
  • All 59 existing integration tests pass (1 pre-existing failure in run_in_non_git_repo unrelated to this change)
  • 7 new DAG scheduling integration tests pass
  • Priority-based tests (priority_fail_fast_stops_later_groups, priority_group_modified_files_is_group_failure_and_output_is_indented) pass unchanged
  • JSON schema regenerated with new fields
  • cargo clippy and cargo fmt clean

🤖 Assisted by Claude Code

drichardson and others added 4 commits February 27, 2026 19:59
Introduce two new optional config fields — `group` and `after` — that let
users express a DAG of hook dependencies. prek builds the DAG, schedules
maximally parallel execution, and only serializes where explicit edges exist.

- `group: string` labels a hook so others can depend on the entire group
- `after: [hook-id]` or `after: [group:name]` creates dependency edges
- `priority` and `group`/`after` are mutually exclusive on the same hook
- Cycle detection via Kahn's algorithm with clear error messages
- Backwards compatible: priority-based scheduling unchanged when no hooks
  use `group`/`after`

Assisted by AI

Co-Authored-By: Claude <noreply@anthropic.com>
Assisted by AI

Co-Authored-By: Claude <noreply@anthropic.com>
Assisted by AI

Co-Authored-By: Claude <noreply@anthropic.com>
Assisted by AI

Co-Authored-By: Claude <noreply@anthropic.com>
@drichardson
Copy link
Contributor Author

oops, didn't mean to request a review on this yet

drichardson and others added 2 commits February 27, 2026 20:27
Assisted by AI

Co-Authored-By: Claude <noreply@anthropic.com>
Assisted by AI

Co-Authored-By: Claude <noreply@anthropic.com>
@codecov
Copy link

codecov bot commented Feb 28, 2026

Codecov Report

❌ Patch coverage is 95.94595% with 12 lines in your changes missing coverage. Please review.
✅ Project coverage is 91.62%. Comparing base (e290094) to head (a713507).
⚠️ Report is 3 commits behind head on master.

Files with missing lines Patch % Lines
crates/prek/src/cli/run/run.rs 95.87% 9 Missing ⚠️
crates/prek/src/hook.rs 94.28% 2 Missing ⚠️
crates/prek/src/config.rs 80.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1704      +/-   ##
==========================================
+ Coverage   91.43%   91.62%   +0.18%     
==========================================
  Files          96       96              
  Lines       18892    19235     +343     
==========================================
+ Hits        17274    17624     +350     
+ Misses       1618     1611       -7     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@prek-ci-bot
Copy link

prek-ci-bot bot commented Feb 28, 2026

📦 Cargo Bloat Comparison

Binary size change: +0.00% (23.9 MiB → 23.9 MiB)

Expand for cargo-bloat output

Head Branch Results

 File  .text    Size             Crate Name
 0.3%   0.8% 79.5KiB             prek? <prek::cli::Command as clap_builder::derive::Subcommand>::augment_subcommands
 0.3%   0.7% 73.8KiB              prek prek::languages::<impl prek::config::Language>::run::{{closure}}::{{closure}}
 0.3%   0.7% 71.1KiB              prek prek::languages::<impl prek::config::Language>::run::{{closure}}::{{closure}}
 0.2%   0.5% 51.2KiB annotate_snippets annotate_snippets::renderer::render::render
 0.2%   0.5% 50.5KiB              prek prek::languages::<impl prek::config::Language>::install::{{closure}}
 0.2%   0.4% 40.0KiB              prek prek::cli::run::run::run::{{closure}}
 0.2%   0.4% 39.1KiB              prek prek::run::{{closure}}
 0.1%   0.3% 31.3KiB             prek? <prek::cli::RunArgs as clap_builder::derive::Args>::augment_args
 0.1%   0.3% 28.5KiB      serde_saphyr saphyr_parser_bw::scanner::Scanner<T>::fetch_more_tokens
 0.1%   0.2% 24.7KiB             prek? <prek::config::_::<impl serde_core::de::Deserialize for prek::config::Config>::deserialize::__Visitor as serde_core::de::Visitor>::visit_map
 0.1%   0.2% 22.8KiB      serde_saphyr saphyr_parser_bw::scanner::Scanner<T>::fetch_more_tokens
 0.1%   0.2% 22.7KiB              prek <prek::languages::ruby::ruby::Ruby as prek::languages::LanguageImpl>::install::{{closure}}
 0.1%   0.2% 21.5KiB              prek prek::hooks::meta_hooks::MetaHooks::run::{{closure}}
 0.1%   0.2% 21.1KiB      clap_builder clap_builder::parser::parser::Parser::get_matches_with
 0.1%   0.2% 20.3KiB     serde_saphyr? <serde_saphyr::de::YamlDeserializer as serde_core::de::Deserializer>::deserialize_map
 0.1%   0.2% 20.2KiB               std core::ptr::drop_in_place<prek::languages::<impl prek::config::Language>::install::{{closure}}>
 0.1%   0.2% 20.0KiB   cargo_metadata? <cargo_metadata::_::<impl serde_core::de::Deserialize for cargo_metadata::Package>::deserialize::__Visitor as serde_core::de::Visitor>::visit_map
 0.1%   0.2% 19.6KiB              prek prek::archive::unzip::{{closure}}
 0.1%   0.2% 18.6KiB              ring ring_core_0_17_14__x25519_ge_frombytes_vartime
 0.1%   0.2% 18.5KiB              prek prek::cli::run::filter::collect_files_from_args::{{closure}}
38.4%  91.7%  9.2MiB                   And 21151 smaller methods. Use -n N to show more.
41.8% 100.0% 10.0MiB                   .text section size, the file size is 23.9MiB

Base Branch Results

 File  .text    Size             Crate Name
 0.3%   0.7% 71.4KiB              prek prek::languages::<impl prek::config::Language>::run::{{closure}}::{{closure}}
 0.3%   0.7% 70.6KiB             prek? <prek::cli::Command as clap_builder::derive::Subcommand>::augment_subcommands
 0.3%   0.6% 65.6KiB              prek prek::languages::<impl prek::config::Language>::run::{{closure}}::{{closure}}
 0.2%   0.5% 51.2KiB annotate_snippets annotate_snippets::renderer::render::render
 0.2%   0.5% 50.5KiB              prek prek::languages::<impl prek::config::Language>::install::{{closure}}
 0.2%   0.4% 41.5KiB              prek prek::cli::run::run::run::{{closure}}
 0.2%   0.4% 38.8KiB              prek prek::run::{{closure}}
 0.1%   0.3% 32.0KiB             prek? <prek::cli::RunArgs as clap_builder::derive::Args>::augment_args
 0.1%   0.3% 28.5KiB      serde_saphyr saphyr_parser_bw::scanner::Scanner<T>::fetch_more_tokens
 0.1%   0.2% 24.7KiB             prek? <prek::config::_::<impl serde_core::de::Deserialize for prek::config::Config>::deserialize::__Visitor as serde_core::de::Visitor>::visit_map
 0.1%   0.2% 22.8KiB      serde_saphyr saphyr_parser_bw::scanner::Scanner<T>::fetch_more_tokens
 0.1%   0.2% 22.7KiB              prek <prek::languages::ruby::ruby::Ruby as prek::languages::LanguageImpl>::install::{{closure}}
 0.1%   0.2% 22.5KiB              prek prek::hooks::meta_hooks::MetaHooks::run::{{closure}}
 0.1%   0.2% 21.1KiB      clap_builder clap_builder::parser::parser::Parser::get_matches_with
 0.1%   0.2% 20.8KiB              prek prek::hooks::meta_hooks::MetaHooks::run::{{closure}}
 0.1%   0.2% 20.2KiB               std core::ptr::drop_in_place<prek::languages::<impl prek::config::Language>::install::{{closure}}>
 0.1%   0.2% 19.4KiB   cargo_metadata? <cargo_metadata::_::<impl serde_core::de::Deserialize for cargo_metadata::Package>::deserialize::__Visitor as serde_core::de::Visitor>::visit_map
 0.1%   0.2% 19.2KiB              prek prek::archive::unzip::{{closure}}
 0.1%   0.2% 18.7KiB     serde_saphyr? <serde_saphyr::de::YamlDeserializer as serde_core::de::Deserializer>::deserialize_map
 0.1%   0.2% 18.6KiB     serde_saphyr? <serde_saphyr::de::YamlDeserializer as serde_core::de::Deserializer>::deserialize_map
38.3%  91.8%  9.2MiB                   And 21074 smaller methods. Use -n N to show more.
41.8% 100.0% 10.0MiB                   .text section size, the file size is 23.9MiB

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant