From fd44aab1f85e89d6d0dd859e4e1a9d6247f92324 Mon Sep 17 00:00:00 2001 From: Jo <10510431+j178@users.noreply.github.com> Date: Wed, 26 Aug 2026 20:21:51 +0800 Subject: [PATCH 1/3] Remove legacy update aliases --- crates/prek/src/cli/mod.rs | 2 +- crates/prek/src/config/mod.rs | 16 ---------------- crates/prek/src/schema.rs | 29 +---------------------------- crates/prek/src/settings.rs | 17 ----------------- crates/prek/tests/global_config.rs | 4 ++-- docs/compatibility.md | 9 --------- docs/reference/configuration.md | 8 -------- prek.schema.json | 4 ---- skills/prek/SKILL.md | 2 +- 9 files changed, 5 insertions(+), 86 deletions(-) diff --git a/crates/prek/src/cli/mod.rs b/crates/prek/src/cli/mod.rs index 2bf699cd0..1628f06a6 100644 --- a/crates/prek/src/cli/mod.rs +++ b/crates/prek/src/cli/mod.rs @@ -268,7 +268,7 @@ pub(crate) enum Command { /// Generate a sample prek configuration file. SampleConfig(SampleConfigArgs), /// Update configured repositories. - #[command(aliases = ["auto-update", "autoupdate"])] + #[command(alias = "autoupdate")] Update(UpdateArgs), /// Manage the prek cache. Cache(CacheNamespace), diff --git a/crates/prek/src/config/mod.rs b/crates/prek/src/config/mod.rs index 21515f70d..65e1cd013 100644 --- a/crates/prek/src/config/mod.rs +++ b/crates/prek/src/config/mod.rs @@ -45,7 +45,6 @@ use crate::warn_user_once; )] pub(crate) struct Config { /// Default settings for `prek update` in this project. - #[serde(alias = "auto_update")] pub update: Option, /// Configuration-local aliases for numeric hook priorities. #[serde(default)] @@ -873,21 +872,6 @@ mod tests { "#); } - #[test] - fn parse_legacy_update_key_alias() { - let yaml = indoc::indoc! {r" - auto_update: - cooldown_days: 7 - repos: [] - "}; - let result = serde_saphyr::from_str::(yaml).unwrap(); - - assert_eq!( - result.update.and_then(|options| options.cooldown_days), - Some(7) - ); - } - #[test] fn test_read_yaml_config() -> Result<()> { let config = read_config(Path::new("tests/fixtures/uv-pre-commit-config.yaml"))?; diff --git a/crates/prek/src/schema.rs b/crates/prek/src/schema.rs index a55cfbe82..aa135721d 100644 --- a/crates/prek/src/schema.rs +++ b/crates/prek/src/schema.rs @@ -120,32 +120,6 @@ fn strip_null_acceptance(schema: &mut schemars::Schema) { } } -fn add_compatibility_aliases(schema: &mut schemars::Schema) { - use serde_json::Value; - - let Some(properties) = schema - .as_object_mut() - .and_then(|schema| schema.get_mut("properties")) - .and_then(Value::as_object_mut) - else { - return; - }; - - let Some(update_schema) = properties.get("update").cloned() else { - return; - }; - let mut auto_update_schema = update_schema; - if let Some(obj) = auto_update_schema.as_object_mut() { - obj.insert( - "description".to_string(), - Value::String( - "Compatibility alias for `update`. Prefer `update` in new configs.".to_string(), - ), - ); - } - properties.insert("auto_update".to_string(), auto_update_schema); -} - impl schemars::JsonSchema for Stages { fn inline_schema() -> bool { true @@ -471,8 +445,7 @@ mod _gen { .with_transform(schemars::transform::RestrictFormats::default()) .with_transform(super::RemoveNullTypes); let generator = schemars::SchemaGenerator::new(settings); - let mut schema = generator.into_root_schema_for::(); - super::add_compatibility_aliases(&mut schema); + let schema = generator.into_root_schema_for::(); serde_json::to_string_pretty(&schema).unwrap() + "\n" } diff --git a/crates/prek/src/settings.rs b/crates/prek/src/settings.rs index 49db73fe0..7dd7caf0f 100644 --- a/crates/prek/src/settings.rs +++ b/crates/prek/src/settings.rs @@ -82,7 +82,6 @@ impl Deref for FilesystemOptions { #[derive(Debug, Clone, Default, Deserialize)] #[serde(default, rename_all = "snake_case")] pub(crate) struct Options { - #[serde(alias = "auto_update")] update: Option, } @@ -260,22 +259,6 @@ mod tests { "#); } - #[test] - fn options_deserializes_legacy_update_key_alias() { - let options: Options = toml::from_str( - r" - [auto_update] - cooldown_days = 7 - ", - ) - .unwrap(); - - assert_eq!( - options.update.and_then(|options| options.cooldown_days), - Some(7) - ); - } - #[test] fn update_settings_uses_global_freeze() { let filesystem = FilesystemOptions( diff --git a/crates/prek/tests/global_config.rs b/crates/prek/tests/global_config.rs index 6a7690935..e82339bb5 100644 --- a/crates/prek/tests/global_config.rs +++ b/crates/prek/tests/global_config.rs @@ -36,10 +36,10 @@ fn global_config_ignores_unknown_options() { } #[test] -fn update_command_accepts_legacy_command_alias() { +fn update_command_accepts_upstream_alias() { let context = TestEnv::new().with_config("repos: []"); - cmd_snapshot!(context, context.command().arg("auto-update"), @" + cmd_snapshot!(context, context.command().arg("autoupdate"), @" success: true exit_code: 0 ----- stdout ----- diff --git a/docs/compatibility.md b/docs/compatibility.md index 61de3a6f6..8e3984f33 100644 --- a/docs/compatibility.md +++ b/docs/compatibility.md @@ -16,7 +16,6 @@ | -- | -- | | `prek install-hooks` | `prek prepare-hooks` | | `prek install --install-hooks` | `prek install --prepare-hooks` | -| `prek auto-update` | `prek update` | | `prek autoupdate` | `prek update` | | `prek gc` | `prek cache gc` | | `prek clean` | `prek cache clean` | @@ -24,14 +23,6 @@ | `prek init-template-dir` | `prek util init-template-dir` | | `pre-commit migrate-config` | Not provided directly; use `prek util yaml-to-toml` to migrate YAML to `prek.toml` | -## Preferred config key spellings - -`prek` still accepts legacy config keys below as aliases. - -| Compatibility spelling | Preferred `prek` spelling | -| -- | -- | -| `auto_update` | `update` | - ## Why the CLI is reorganized `pre-commit` keeps many maintenance commands as separate top-level entries. `prek` reorganizes some of them so the command tree is easier to navigate: diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index a6abfe36d..3ce063966 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -43,10 +43,6 @@ The cooldown age is computed from the tag creation timestamp for annotated tags, If the current `rev` is newer than the latest cooldown-eligible tag, [`prek update`](cli.md#prek-update) keeps the current `rev` instead of downgrading it. -!!! note "Compatibility alias" - - The legacy `auto_update` key is still accepted as an alias for `update`. - ## Extension keys (`x-`) Any key starting with `x-` (a lowercase `x` followed by a hyphen) is silently ignored by `prek` at any level of the configuration. This supports custom metadata without triggering unexpected key warnings. @@ -411,10 +407,6 @@ CLI filters have the highest precedence. `--include-tag` and `--exclude-tag` rep In workspace mode, `update` is scoped to the project config file that defines it and is not inherited by nested projects. Sub-projects use their own `update`, then the user-level global config, then built-in defaults. Repositories shared by multiple projects are fetched once but evaluated with each project's cooldown, freeze, and tag-filter settings. -!!! note "Compatibility alias" - - The legacy `auto_update` key is still accepted as an alias for `update`. - ### `minimum_prek_version` diff --git a/prek.schema.json b/prek.schema.json index 96fbca7f5..64e539ced 100644 --- a/prek.schema.json +++ b/prek.schema.json @@ -149,10 +149,6 @@ "orphan": { "description": "Set to true to isolate this project from parent configurations in workspace mode.\nWhen true, files in this project are \"consumed\" by this project and will not be processed\nby parent projects.\nWhen false (default), files in subprojects are processed by both the subproject and\nany parent projects that contain them.", "type": "boolean" - }, - "auto_update": { - "description": "Compatibility alias for `update`. Prefer `update` in new configs.", - "$ref": "#/definitions/UpdateOptions" } }, "required": [ diff --git a/skills/prek/SKILL.md b/skills/prek/SKILL.md index 9275a24ea..e53dde59c 100644 --- a/skills/prek/SKILL.md +++ b/skills/prek/SKILL.md @@ -154,7 +154,7 @@ Common install methods: - `prek run `: run only one hook - `prek list`: list discovered hooks and projects - `prek validate-config`: validate `prek.toml` or `.pre-commit-config.yaml` -- `prek auto-update`: update pinned hook revisions +- `prek update`: update pinned hook revisions - `prek util yaml-to-toml`: convert an existing YAML config to `prek.toml` - `prek util identify `: inspect file tags when `types`, `types_or`, or `exclude_types` do not match as expected From eedda1b48a6549d96c5fa0a32e00678a3e5dd646 Mon Sep 17 00:00:00 2001 From: Jo <10510431+j178@users.noreply.github.com> Date: Wed, 26 Aug 2026 20:24:37 +0800 Subject: [PATCH 2/3] Remove PREK_MAX_CONCURRENCY --- crates/prek-consts/src/env_vars.rs | 1 - crates/prek/src/run.rs | 49 +++++------------------------- 2 files changed, 8 insertions(+), 42 deletions(-) diff --git a/crates/prek-consts/src/env_vars.rs b/crates/prek-consts/src/env_vars.rs index a2e725dd2..a5a005926 100644 --- a/crates/prek-consts/src/env_vars.rs +++ b/crates/prek-consts/src/env_vars.rs @@ -89,7 +89,6 @@ impl EnvVars { pub const PREK_NO_CONCURRENCY: &'static str = "PREK_NO_CONCURRENCY"; pub const PREK_CONCURRENT_HOOKS: &'static str = "PREK_CONCURRENT_HOOKS"; pub const PREK_CONCURRENT_BATCHES: &'static str = "PREK_CONCURRENT_BATCHES"; - pub const PREK_MAX_CONCURRENCY: &'static str = "PREK_MAX_CONCURRENCY"; pub const PREK_NO_FAST_PATH: &'static str = "PREK_NO_FAST_PATH"; pub const PREK_UV_SOURCE: &'static str = "PREK_UV_SOURCE"; pub const PREK_NATIVE_TLS: &'static str = "PREK_NATIVE_TLS"; diff --git a/crates/prek/src/run.rs b/crates/prek/src/run.rs index 9ada7c624..82ab73a5b 100644 --- a/crates/prek/src/run.rs +++ b/crates/prek/src/run.rs @@ -23,23 +23,16 @@ fn resolve_concurrency(env_vars: &impl EnvVarsRead, primary_env_var: &str) -> us return 1; } - let primary = env_vars.var(primary_env_var).ok(); - let legacy_max = env_vars.var(EnvVars::PREK_MAX_CONCURRENCY).ok(); - let (name, value) = if let Some(primary) = primary.as_deref() { - (primary_env_var, Some(primary)) - } else { - (EnvVars::PREK_MAX_CONCURRENCY, legacy_max.as_deref()) - }; - let cpu = cpu_count(); - if let Some(value) = value { - if let Ok(cap) = value.parse::() { - return cap.max(1); - } - warn_user!( - "Invalid value for {name}: {value:?}. Expected a positive integer; using default ({cpu})" - ); + let Ok(value) = env_vars.var(primary_env_var) else { + return cpu; + }; + if let Ok(cap) = value.parse::() { + return cap.max(1); } + warn_user!( + "Invalid value for {primary_env_var}: {value:?}. Expected a positive integer; using default ({cpu})" + ); cpu } @@ -474,7 +467,6 @@ mod tests { &[ (EnvVars::PREK_NO_CONCURRENCY, "1"), (EnvVars::PREK_CONCURRENT_HOOKS, "8"), - (EnvVars::PREK_MAX_CONCURRENCY, "4"), ], EnvVars::PREK_CONCURRENT_HOOKS, ), @@ -482,31 +474,6 @@ mod tests { ); } - #[test] - fn test_resolve_concurrency_uses_legacy_max() { - assert_eq!( - resolve_concurrency_from_map( - &[(EnvVars::PREK_MAX_CONCURRENCY, "4")], - EnvVars::PREK_CONCURRENT_HOOKS, - ), - 4 - ); - } - - #[test] - fn test_resolve_concurrency_prefers_new_env_over_legacy_max() { - assert_eq!( - resolve_concurrency_from_map( - &[ - (EnvVars::PREK_CONCURRENT_BATCHES, "2"), - (EnvVars::PREK_MAX_CONCURRENCY, "4"), - ], - EnvVars::PREK_CONCURRENT_BATCHES, - ), - 2 - ); - } - #[test] fn test_partitions_respects_cli_length_limit() { // Create files that will exceed CLI length limit From e804c974fc78587dae234c89dfe0a2593230a3bc Mon Sep 17 00:00:00 2001 From: Jo <10510431+j178@users.noreply.github.com> Date: Wed, 26 Aug 2026 20:27:01 +0800 Subject: [PATCH 3/3] Remove config-tracking cache bootstrap --- crates/prek/src/store.rs | 22 +++--------- crates/prek/src/workspace.rs | 60 -------------------------------- crates/prek/tests/cache.rs | 66 ------------------------------------ 3 files changed, 4 insertions(+), 144 deletions(-) diff --git a/crates/prek/src/store.rs b/crates/prek/src/store.rs index 76ae69053..94a19ac58 100644 --- a/crates/prek/src/store.rs +++ b/crates/prek/src/store.rs @@ -16,7 +16,7 @@ use crate::fs::{LockedFile, expand_tilde}; use crate::git::{self, TerminalPrompt}; use crate::run::INTERNAL_CONCURRENCY; use crate::warn_user; -use crate::workspace::{HookInitReporter, WorkspaceCache}; +use crate::workspace::HookInitReporter; struct PendingClone<'a> { repo: &'a RemoteRepo, @@ -347,33 +347,19 @@ impl Store { } /// Get all tracked config files. - /// - /// Seed `config-tracking.json` from the workspace discovery cache if it doesn't exist. - /// This is a one-time upgrade helper: it only does work when the tracking file is absent. pub(crate) fn tracked_configs(&self) -> Result, Error> { let tracking_file = self.config_tracking_file(); match fs_err::read_to_string(&tracking_file) { - Err(e) if e.kind() == std::io::ErrorKind::NotFound => {} - Err(e) => return Err(e.into()), + Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(FxHashSet::default()), + Err(e) => Err(e.into()), Ok(content) => { let tracked = serde_json::from_str(&content).unwrap_or_else(|e| { warn!("Failed to parse config tracking file: {e}, resetting"); FxHashSet::default() }); - return Ok(tracked); + Ok(tracked) } } - - let tracked = WorkspaceCache::cached_config_paths(self); - if !tracked.is_empty() { - debug!( - count = tracked.len(), - "Bootstrapping config tracking from workspace cache" - ); - self.update_tracked_configs(&tracked)?; - } - - Ok(tracked) } /// Track new config files for GC. diff --git a/crates/prek/src/workspace.rs b/crates/prek/src/workspace.rs index be6b6d0eb..3afef237f 100644 --- a/crates/prek/src/workspace.rs +++ b/crates/prek/src/workspace.rs @@ -600,66 +600,6 @@ impl WorkspaceCache { fs_err::write(&cache_path, content)?; Ok(()) } - - /// Best-effort source of config paths for bootstrapping config tracking. - /// - /// This is used on upgrades from older versions that didn't track configs yet. - /// It reads all cached workspace discovery entries under `cache/prek/workspace/*` - /// and collects any config file paths they mention. - pub(crate) fn cached_config_paths(store: &Store) -> FxHashSet { - let mut paths: FxHashSet = FxHashSet::default(); - - let workspace_cache_root = store.cache_path(CacheBucket::Prek).join("workspace"); - let entries = match fs_err::read_dir(&workspace_cache_root) { - Ok(entries) => entries, - Err(err) if err.kind() == std::io::ErrorKind::NotFound => return paths, - Err(err) => { - debug!(path = %workspace_cache_root.display(), %err, "Failed to read workspace cache directory for tracking bootstrap"); - return paths; - } - }; - - for entry in entries { - let entry = match entry { - Ok(entry) => entry, - Err(err) => { - debug!(%err, "Failed to read workspace cache entry for tracking bootstrap"); - continue; - } - }; - - let path = entry.path(); - if !path.is_file() { - continue; - } - - let content = match fs_err::read_to_string(&path) { - Ok(content) => content, - Err(err) => { - debug!(path = %path.display(), %err, "Failed to read workspace cache file for tracking bootstrap"); - continue; - } - }; - - let cache: WorkspaceCache = match serde_json::from_str(&content) { - Ok(cache) => cache, - Err(err) => { - debug!(path = %path.display(), %err, "Failed to parse workspace cache file for tracking bootstrap"); - continue; - } - }; - - if cache.version != WorkspaceCache::CURRENT_VERSION { - continue; - } - - for file in cache.config_files { - paths.insert(file.path); - } - } - - paths - } } pub(crate) struct Workspace { diff --git a/crates/prek/tests/cache.rs b/crates/prek/tests/cache.rs index 56e7be623..1c19ceaf2 100644 --- a/crates/prek/tests/cache.rs +++ b/crates/prek/tests/cache.rs @@ -809,72 +809,6 @@ fn write_patch_file(path: &ChildPath, content: &str, modified: SystemTime) -> an Ok(()) } -fn write_workspace_cache_file( - home: &ChildPath, - workspace_root: &std::path::Path, -) -> anyhow::Result<()> { - use std::hash::{Hash as _, Hasher as _}; - use std::time::SystemTime; - - let config_path = workspace_root.join(PRE_COMMIT_CONFIG_YAML); - let metadata = fs_err::metadata(&config_path)?; - let modified = metadata.modified().unwrap_or(SystemTime::UNIX_EPOCH); - let size = metadata.len(); - - let mut hasher = std::collections::hash_map::DefaultHasher::new(); - workspace_root.hash(&mut hasher); - let digest = hex::encode(hasher.finish().to_le_bytes()); - - let cache_path = home.child("cache/prek/workspace").child(digest); - let parent = cache_path.parent().expect("cache path has parent"); - fs_err::create_dir_all(parent)?; - - let content = json!({ - "version": 1u32, - "workspace_root": workspace_root, - "created_at": serde_json::to_value(SystemTime::now())?, - "config_files": [ - { - "path": config_path, - "modified": serde_json::to_value(modified)?, - "size": size, - } - ], - }); - - cache_path.write_str(&serde_json::to_string_pretty(&content)?)?; - Ok(()) -} - -#[test] -fn cache_gc_bootstraps_tracking_from_workspace_cache() -> anyhow::Result<()> { - let context = TestEnv::new().with_config("repos: []\n"); - context.git_add_all(); - - let home = context.home_dir(); - write_workspace_cache_file(home, context.work_dir().path())?; - - // Seed store entries that should be swept, even if `config-tracking.json` is missing. - home.child("repos/deadbeef").create_dir_all()?; - home.child("hooks/hook-env-dead").create_dir_all()?; - - cmd_snapshot!(context, context.command().arg("cache").arg("gc"), @r#" - success: true - exit_code: 0 - ----- stdout ----- - Removed 1 repo, 1 hook env ([SIZE]) - - ----- stderr ----- - "#); - - home.child("repos/deadbeef") - .assert(predicates::path::missing()); - home.child("hooks/hook-env-dead") - .assert(predicates::path::missing()); - - Ok(()) -} - #[test] fn cache_gc_drops_missing_tracked_config() -> anyhow::Result<()> { let context = TestEnv::new().with_config("repos: []\n");