Skip to content

Replace serde-yaml with serde-saphyr (again)#1520

Merged
j178 merged 1 commit intomasterfrom
serde-saphyr
Feb 2, 2026
Merged

Replace serde-yaml with serde-saphyr (again)#1520
j178 merged 1 commit intomasterfrom
serde-saphyr

Conversation

@j178
Copy link
Owner

@j178 j178 commented Feb 1, 2026

serde-saphyr has way better error message, and it is written in safe Rust.

Previous try: #1087
Previous revert: #1106 and #1112

TODO:
Replace serialize_yaml_scalar with serde-saphyr as well:

/// Serialize a YAML scalar while preserving the caller's quote style.
pub(crate) fn serialize_yaml_scalar(value: &str, quote: &str) -> Result<String> {

@j178 j178 added the enhancement New feature or request label Feb 1, 2026
@codecov
Copy link

codecov bot commented Feb 1, 2026

Codecov Report

❌ Patch coverage is 98.59155% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 91.93%. Comparing base (0a4be22) to head (6b2b8bc).
⚠️ Report is 6 commits behind head on master.

Files with missing lines Patch % Lines
...ates/prek/src/hooks/pre_commit_hooks/check_yaml.rs 86.66% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1520      +/-   ##
==========================================
- Coverage   92.02%   91.93%   -0.09%     
==========================================
  Files          89       89              
  Lines       18500    18288     -212     
==========================================
- Hits        17024    16813     -211     
+ Misses       1476     1475       -1     

☔ 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.

serde-saphyr has way better error message, and it is written in safe Rust.
@prek-ci-bot
Copy link

prek-ci-bot bot commented Feb 1, 2026

📦 Cargo Bloat Comparison

Binary size change: +3.10% (22.6 MiB → 23.3 MiB)

Expand for cargo-bloat output

Head Branch Results

 File  .text    Size             Crate Name
 0.3%   0.8% 75.6KiB             prek? <prek::cli::Command as clap_builder::derive::Subcommand>::augment_subcommands
 0.3%   0.7% 70.3KiB              prek prek::languages::<impl prek::config::Language>::run::{{closure}}::{{closure}}
 0.3%   0.7% 65.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.8KiB              prek prek::languages::<impl prek::config::Language>::install::{{closure}}
 0.2%   0.4% 43.4KiB              prek prek::identify::by_extension::{{closure}}
 0.2%   0.4% 43.3KiB              prek prek::run::{{closure}}
 0.2%   0.4% 41.7KiB              prek prek::cli::run::run::run::{{closure}}
 0.1%   0.3% 31.7KiB             prek? <prek::cli::RunArgs as clap_builder::derive::Args>::augment_args
 0.1%   0.3% 28.4KiB      serde_saphyr saphyr_parser_bw::scanner::Scanner<T>::fetch_more_tokens
 0.1%   0.3% 24.8KiB             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.6KiB      serde_saphyr saphyr_parser_bw::scanner::Scanner<T>::fetch_more_tokens
 0.1%   0.2% 22.1KiB              prek prek::hooks::meta_hooks::MetaHooks::run::{{closure}}
 0.1%   0.2% 21.2KiB      clap_builder clap_builder::parser::parser::Parser::get_matches_with
 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.8KiB              prek prek::archive::unzip::{{closure}}
 0.1%   0.2% 19.7KiB              prek prek::hooks::meta_hooks::MetaHooks::run::{{closure}}
 0.1%   0.2% 19.5KiB              prek prek::cli::run::filter::collect_files_from_args::{{closure}}
 0.1%   0.2% 19.3KiB               std core::ptr::drop_in_place<prek::languages::<impl prek::config::Language>::install::{{closure}}>
 0.1%   0.2% 19.3KiB              prek <prek::languages::ruby::ruby::Ruby as prek::languages::LanguageImpl>::install::{{closure}}
37.9%  91.3%  8.8MiB                   And 20592 smaller methods. Use -n N to show more.
41.5% 100.0%  9.7MiB                   .text section size, the file size is 23.3MiB

Base Branch Results

 File  .text    Size           Crate Name
 0.3%   0.8% 77.0KiB           prek? <prek::cli::Command as clap_builder::derive::Subcommand>::augment_subcommands
 0.3%   0.8% 70.3KiB            prek prek::languages::<impl prek::config::Language>::run::{{closure}}::{{closure}}
 0.3%   0.7% 65.1KiB            prek prek::languages::<impl prek::config::Language>::run::{{closure}}::{{closure}}
 0.2%   0.5% 50.8KiB            prek prek::languages::<impl prek::config::Language>::install::{{closure}}
 0.2%   0.5% 43.9KiB            prek prek::run::{{closure}}
 0.2%   0.5% 43.4KiB            prek prek::identify::by_extension::{{closure}}
 0.2%   0.4% 41.5KiB            prek prek::cli::run::run::run::{{closure}}
 0.1%   0.3% 32.0KiB           prek? <prek::cli::RunArgs as clap_builder::derive::Args>::augment_args
 0.1%   0.2% 22.1KiB            prek prek::hooks::meta_hooks::MetaHooks::run::{{closure}}
 0.1%   0.2% 22.1KiB            prek prek::hooks::meta_hooks::MetaHooks::run::{{closure}}
 0.1%   0.2% 21.2KiB    clap_builder clap_builder::parser::parser::Parser::get_matches_with
 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% 19.5KiB            prek prek::cli::run::filter::collect_files_from_args::{{closure}}
 0.1%   0.2% 19.3KiB             std core::ptr::drop_in_place<prek::languages::<impl prek::config::Language>::install::{{closure}}>
 0.1%   0.2% 19.3KiB            prek <prek::languages::ruby::ruby::Ruby as prek::languages::LanguageImpl>::install::{{closure}}
 0.1%   0.2% 19.1KiB            prek prek::cli::run::filter::collect_files_from_args::{{closure}}
 0.1%   0.2% 18.6KiB            ring ring_core_0_17_14__x25519_ge_frombytes_vartime
 0.1%   0.2% 18.1KiB       [Unknown] fe_loose_invert
 0.1%   0.2% 18.1KiB      hyper_util hyper_util::client::legacy::client::Client<C,B>::send_request::{{closure}}
36.8%  91.3%  8.3MiB                 And 20083 smaller methods. Use -n N to show more.
40.3% 100.0%  9.1MiB                 .text section size, the file size is 22.6MiB

@j178 j178 marked this pull request as ready for review February 2, 2026 12:19
Copilot AI review requested due to automatic review settings February 2, 2026 12:19
@j178 j178 merged commit b070282 into master Feb 2, 2026
52 checks passed
@j178 j178 deleted the serde-saphyr branch February 2, 2026 12:19
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR switches prek’s YAML parsing from serde_yaml to serde-saphyr to improve user-facing YAML error messages (including richer spans/snippets), and updates tests/schema accordingly.

Changes:

  • Replace serde_yaml with serde-saphyr for config/manifest parsing and the check-yaml builtin hook.
  • Update integration/unit test snapshots to match the new error formatting.
  • Regenerate/update prek.schema.json and dependency manifests/lockfile for the new YAML stack.

Reviewed changes

Copilot reviewed 14 out of 15 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
prek.schema.json Regenerated schema reflecting updated config model/serialization details.
crates/prek/src/config.rs Switch config/manifest parsing to serde-saphyr and update related unit tests/snapshots.
crates/prek/src/hooks/pre_commit_hooks/check_yaml.rs Use serde-saphyr to validate YAML files (single/multi-doc) and adjust error output.
crates/prek/src/yaml.rs Remove prior merge-key processing code, leaving scalar serialization logic.
crates/prek/src/cli/run/filter.rs Update tests to construct glob patterns without serde_yaml.
crates/prek/tests/workspace.rs Snapshot updates for new YAML parse errors.
crates/prek/tests/validate.rs Snapshot updates + new test coverage for invalid-config errors with new formatting.
crates/prek/tests/run.rs Snapshot updates for new YAML parse errors.
crates/prek/tests/meta_hooks.rs Snapshot updates for new YAML parse errors.
crates/prek/tests/install.rs Snapshot updates for new YAML parse errors in warnings.
crates/prek/tests/builtin_hooks.rs Snapshot updates for check-yaml output + naming tweaks in test display strings.
crates/prek/tests/auto_update.rs Snapshot updates for new YAML parse errors.
crates/prek/Cargo.toml Swap dependency from serde_yaml to serde-saphyr.
Cargo.toml Add workspace dependency for serde-saphyr and adjust clippy lint settings.
Cargo.lock Lockfile updates for serde-saphyr and its transitive dependencies.

Comment on lines +45 to 60
let options = serde_saphyr::Options {
ignore_binary_tag_for_string: true,
..Default::default()
};
if allow_multi_docs {
for doc in deserializer {
if let Err(e) = serde_yaml::Value::deserialize(doc) {
let error_message =
format!("{}: Failed to yaml decode ({e})\n", filename.display());
return Ok((1, error_message.into_bytes()));
}
if let Err(e) = serde_saphyr::from_slice_multiple_with_options::<serde_json::Value>(
&content,
options.clone(),
) {
let error_message = format!("{}: Failed to yaml decode ({e})\n", filename.display());
return Ok((1, error_message.into_bytes()));
}
Ok((0, Vec::new()))
} else {
match serde_yaml::from_slice::<serde_yaml::Value>(&content) {
match serde_saphyr::from_slice_with_options::<serde_json::Value>(&content, options) {
Ok(_) => Ok((0, Vec::new())),
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check-yaml now deserializes YAML into serde_json::Value, which only supports JSON-compatible YAML (e.g., mapping keys must be strings). This can cause valid YAML files (such as those with non-string keys or other YAML-only constructs) to be reported as invalid. Consider parsing/deserializing into a YAML value type (or using a parser-only API) so this hook validates YAML syntax rather than JSON compatibility.

Copilot uses AI. Check for mistakes.
Comment on lines +1134 to +1135
let config = serde_saphyr::from_str(&content)
.map_err(|e| Error::Yaml(path.user_display().to_string(), Box::new(e)))?;
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The serde_saphyr error string already includes a leading "error:"; wrapping it as the source for Failed to parse ... results in user output like "caused by: error: ..." / "Failed to parse ...: error: ...". Consider normalizing the source message (e.g., stripping the leading prefix) before boxing/storing it so the final output isn’t redundant.

Copilot uses AI. Check for mistakes.
Comment on lines +197 to +198
},
"writeOnly": true
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

writeOnly: true on RemoteRepo.hooks is likely incorrect for a configuration-file JSON schema (it may hide the property in editors/UI tooling even though it’s required for configs). Consider removing writeOnly here unless there’s a specific schema-consumer reason for it.

Suggested change
},
"writeOnly": true
}

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants