From c52a388f409246da5d0f9d3cf8eed918f567f38b Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 16 Sep 2026 05:45:02 +0000 Subject: [PATCH 1/2] feat(config): Add entryPoints globs that root whole files as entry points MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A new top-level entryPoints config field takes glob patterns (resolved against the config file's own directory, with the same rules as ignore globs) naming files to treat as entry points. Every declaration in a matching file becomes a root, so the file and everything it references count as used — the file-level counterpart to roots, and unlike an ignore glob it keeps the file's references alive instead of only hiding the file's own findings. A pattern that matches no file at all surfaces as a note, the same way an unmatched --root does, so a stale path can't silently drop the protection it promised. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01GktmvEmkYosc2hG9XEebjP --- README.md | 7 +- docs/commands/dead-code.mdx | 8 +- docs/concepts/entry-points.mdx | 17 +++ docs/configuration.mdx | 33 ++++- skills/roe/SKILL.md | 18 ++- src/commands/dead_code.rs | 33 ++++- src/config.rs | 135 +++++++++++++++--- src/entry_points.rs | 41 ++++++ tests/cli.rs | 30 ++++ tests/dead_code.rs | 52 ++++++- .../config_entry_points_json/PluginHelper.cs | 8 ++ .../Plugins/CustomPlugin.cs | 10 ++ .../config_entry_points_json/Program.cs | 8 ++ .../config_entry_points_json/StillDead.cs | 8 ++ .../config_entry_points_json/roe.json | 3 + .../config_entry_points_yaml/PluginHelper.cs | 8 ++ .../Plugins/CustomPlugin.cs | 10 ++ .../config_entry_points_yaml/Program.cs | 8 ++ .../config_entry_points_yaml/StillDead.cs | 8 ++ .../config_entry_points_yaml/roe.yaml | 2 + 20 files changed, 417 insertions(+), 30 deletions(-) create mode 100644 tests/fixtures/config_entry_points_json/PluginHelper.cs create mode 100644 tests/fixtures/config_entry_points_json/Plugins/CustomPlugin.cs create mode 100644 tests/fixtures/config_entry_points_json/Program.cs create mode 100644 tests/fixtures/config_entry_points_json/StillDead.cs create mode 100644 tests/fixtures/config_entry_points_json/roe.json create mode 100644 tests/fixtures/config_entry_points_yaml/PluginHelper.cs create mode 100644 tests/fixtures/config_entry_points_yaml/Plugins/CustomPlugin.cs create mode 100644 tests/fixtures/config_entry_points_yaml/Program.cs create mode 100644 tests/fixtures/config_entry_points_yaml/StillDead.cs create mode 100644 tests/fixtures/config_entry_points_yaml/roe.yaml diff --git a/README.md b/README.md index cb28e23..a2379b5 100644 --- a/README.md +++ b/README.md @@ -440,6 +440,7 @@ walking up from the analysis root to the nearest directory containing one { "aggressive": true, "roots": ["MyApp.Program.Main"], + "entryPoints": ["Jobs/", "Api/Handlers/**/*.cs"], "libraryProjects": ["MyLib"], "ignore": ["Migrations/**", "Generated/", "**/*.designer.cs"], "deadCode": { @@ -471,7 +472,11 @@ matches the whole directory, so `"Generated/"` needs no `**`). `aggressive`, `roots`, and `libraryProjects` set defaults for the matching CLI flags: an explicit `--aggressive`, `--root`, or `--library` always wins, otherwise the config's value applies, otherwise the built-in default (`false` / no extra -roots / no extra library projects). The same `ignore` list also applies to +roots / no extra library projects). `entryPoints` globs are the file-level +counterpart to `roots`: every declaration in a matching file is treated as +an entry point, so the file and everything it references count as used — +unlike an `ignore` glob, which only drops the findings in the matching file +itself. The same `ignore` list also applies to `roe dupes`, since a duplicate spans multiple files and doesn't map cleanly onto a single-line inline suppression comment. Each command's section takes an `ignore` list of its own with the same rules, unioned with the top-level diff --git a/docs/commands/dead-code.mdx b/docs/commands/dead-code.mdx index 5d95648..39b2dc4 100644 --- a/docs/commands/dead-code.mdx +++ b/docs/commands/dead-code.mdx @@ -51,8 +51,12 @@ roe dead-code --library MyLib ``` Both can also be set persistently in a [config file](/configuration). A -config's `deadCode.ignore` glob list drops every dead-code finding in -matching files without affecting the other commands — see +config's `entryPoints` glob list roots whole files rather than single +symbols — every declaration in a matching file counts as used, along with +everything it references — see +[Entry-point files](/configuration#entry-point-files). And a config's +`deadCode.ignore` glob list drops every dead-code finding in matching files +without affecting the other commands — see [Suppressing findings](/suppressing-findings). ## What counts as an entry point diff --git a/docs/concepts/entry-points.mdx b/docs/concepts/entry-points.mdx index 6d0079e..f2f57d4 100644 --- a/docs/concepts/entry-points.mdx +++ b/docs/concepts/entry-points.mdx @@ -46,6 +46,23 @@ roe dead-code --root App.Jobs.NightlyCleanupJob } ``` +When a whole file is consumed in ways roe can't see — a plugin host loading +it by path, an external tool reading it directly — name the file with the +`entryPoints` config field instead of listing every symbol in it. Patterns +are globs resolved relative to the config file's directory (a trailing `/` +matches the whole directory); every declaration in a matching file becomes +a root, so the file and everything it references count as used: + +```json roe.json +{ + "entryPoints": ["Plugins/", "Jobs/**/*.cs"] +} +``` + +A pattern that matches no file at all is reported as a note, so a stale +path can't silently drop the protection it promised. See +[Configuration](/configuration#entry-point-files) for the full rules. + ## How detection works Under the hood, `roe dead-code` runs a five-step pipeline: diff --git a/docs/configuration.mdx b/docs/configuration.mdx index cd6817e..9192325 100644 --- a/docs/configuration.mdx +++ b/docs/configuration.mdx @@ -25,6 +25,7 @@ error. { "aggressive": true, "roots": ["MyApp.Program.Main"], + "entryPoints": ["Jobs/", "Api/Handlers/**/*.cs"], "libraryProjects": ["MyLib"], "ignore": ["Migrations/**", "Generated/", "**/*.designer.cs"], "deadCode": { @@ -55,6 +56,7 @@ error. | --- | --- | --- | | `aggressive` | boolean | Also flag enum members and public settable auto-properties. Default for the `--aggressive` flag. | | `roots` | string[] | Fully-qualified symbol names to treat as extra entry-point roots. Default for `--root`. | +| `entryPoints` | string[] | Glob patterns naming files to treat as entry points: every declaration in a matching file is a root, so the file and everything it references count as used. | | `libraryProjects` | string[] | Project names to always treat in library mode (public API counts as used). Default for `--library`. | | `ignore` | string[] | Glob patterns; every finding in a matching file is dropped. Applies to all three commands; each command's section can add its own. | | `deadCode` | object | Extra `ignore` globs applied only to [`roe dead-code`](/commands/dead-code). | @@ -110,6 +112,31 @@ passing `--baseline` is also what makes a bare `roe` and its own. A path that doesn't exist is a hard error, not a silent full-backlog run. +## Entry-point files + +`entryPoints` is the file-level counterpart to `roots`: where `roots` names +one symbol by its fully-qualified name, an entry-point glob keeps a whole +file's contents alive. Every declaration in a matching file becomes a root, +so the file is never flagged and everything it references counts as used — +unlike an `ignore` glob, which only drops the findings in the matching file +itself. + +Use it for files that are consumed in ways roe can't see: a plugin host +loading them by path, string-based reflection, or an external tool reading +the file directly. + +```json roe.json +{ + "entryPoints": ["Jobs/", "Api/Handlers/**/*.cs"] +} +``` + +Patterns resolve relative to the config file's own directory with the same +rules as `ignore` globs — a trailing `/` matches the whole directory, and +`..` is unsupported. A pattern that matches no file at all is reported as a +note in the output, so a stale path can't silently drop the protection it +promised. + ## Ignore globs `ignore` patterns are resolved relative to the config file's own directory. @@ -168,9 +195,9 @@ Dupes settings follow the same per-field order: `--min-tokens 100` overrides carries a value, so unlike `--aggressive` and `--exclude-tests` it has no on-only nuance — `--mode exact` overrides a config's `"semantic"` cleanly. -Ignore lists sit outside this order entirely: they have no CLI flag, and a -command's own `ignore` list is unioned with the top-level one rather than -replacing it. +Ignore lists and `entryPoints` sit outside this order entirely: neither has +a CLI flag, and a command's own `ignore` list is unioned with the top-level +one rather than replacing it. To confirm a config-only `excludeTests` or `ignore` actually applied, read the `roe health` footer: the scanned counts narrow by whatever was excluded, and diff --git a/skills/roe/SKILL.md b/skills/roe/SKILL.md index 6713e27..821c1d6 100644 --- a/skills/roe/SKILL.md +++ b/skills/roe/SKILL.md @@ -154,8 +154,9 @@ The `kind` values (identical to the inline-suppression rule names): Prefer fixing real findings over suppressing. When a finding genuinely is a false positive (e.g. code invoked via string-based reflection), first -consider whether `--root`/`roots` describes the situation better — a root -documents *why* the code is alive, a suppression just silences the report. +consider whether `--root`/`roots` (or `entryPoints` for a whole file) +describes the situation better — a root documents *why* the code is alive, +a suppression just silences the report. Inline comments work eslint-style, checked after the first `//` (so `///` doc-comments work too): @@ -188,6 +189,7 @@ fields are a hard error, so typos fail loudly. { "aggressive": false, "roots": ["App.Jobs.NightlyCleanupJob"], + "entryPoints": ["Plugins/", "Jobs/**/*.cs"], "libraryProjects": ["App.Sdk"], "ignore": ["Migrations/**", "Generated/"], "deadCode": { @@ -228,8 +230,16 @@ Precedence is CLI flag → config → built-in default, with gotchas: - `--root` and `--library` **replace** the config's `roots`/`libraryProjects` lists entirely rather than merging with them. - The `dupes` settings are plain per-field overrides (`--mode exact` beats a - config `"semantic"`), and ignore lists have no CLI flag at all — scoped - lists only ever add to the top-level one. + config `"semantic"`), and ignore lists and `entryPoints` have no CLI flag + at all — scoped ignore lists only ever add to the top-level one. + +`entryPoints` is the file-level counterpart to `roots`: globs (resolved +relative to the config file's directory, trailing `/` means the whole +subtree) whose matching files are treated as entry points — every +declaration in them is a root, so the file and everything it references +count as used. Prefer it over `deadCode.ignore` for plugin/reflection-loaded +files: an ignore only hides the file's own findings, an entry point also +keeps alive what the file uses. ## Adopting roe on a legacy codebase diff --git a/src/commands/dead_code.rs b/src/commands/dead_code.rs index 49076a7..6e44c8a 100644 --- a/src/commands/dead_code.rs +++ b/src/commands/dead_code.rs @@ -15,14 +15,18 @@ pub struct Analysis { /// The full dead-code pipeline: discover → extract → symbol table → kill /// list → entry points → graph → reachability → detectors → inline -/// suppressions. +/// suppressions. `entry_points` globs resolve against the workspace root; +/// the config-aware path through [`execute`] resolves them against the +/// config file's own directory instead. pub fn analyze( root: &Path, aggressive: bool, manual_roots: &[String], library_projects: &[String], + entry_points: &[String], ) -> anyhow::Result { let extracted = commands::Extracted::build(root)?; + let entry_point_dir = extracted.workspace.root.clone(); analyze_extracted( &extracted, @@ -30,6 +34,8 @@ pub fn analyze( aggressive, manual_roots, library_projects, + entry_points, + &entry_point_dir, ) } @@ -42,6 +48,8 @@ pub(crate) fn analyze_extracted( aggressive: bool, manual_roots: &[String], library_projects: &[String], + entry_points: &[String], + entry_point_dir: &Path, ) -> anyhow::Result { let mut workspace = extracted.workspace.clone(); let rodeo = &extracted.rodeo; @@ -51,7 +59,7 @@ pub(crate) fn analyze_extracted( rules::apply_kill_list(&mut resolution, &workspace, rodeo, aggressive); - let notes = entry_points::mark_roots( + let mut notes = entry_points::mark_roots( &mut resolution, &workspace, facts, @@ -60,6 +68,14 @@ pub(crate) fn analyze_extracted( rodeo, ); + let entry_point_globs = + config::build_entry_point_globs(entry_point_dir, entry_points, &mut workspace.warnings); + notes.extend(entry_points::mark_entry_point_files( + &mut resolution, + &workspace, + &entry_point_globs, + )); + let symbol_graph = graph::build_graph(&mut resolution, &workspace, facts, rodeo); let roots: Vec = resolution .symbols @@ -109,12 +125,25 @@ pub(crate) fn execute_extracted( &args.library_projects, ); + // `entryPoints` has no CLI flag (like `ignore`), so it comes straight + // from the config, and its globs resolve against the config file's own + // directory the way `ignore` globs do. + let (entry_points, entry_point_dir) = match context.config.as_ref() { + Some(resolved) => ( + resolved.config.entry_points.clone().unwrap_or_default(), + resolved.dir.clone(), + ), + None => (Vec::new(), context.root.clone()), + }; + let mut analysis = analyze_extracted( extracted, extracted.started, effective.aggressive, &effective.roots, &effective.library_projects, + &entry_points, + &entry_point_dir, )?; analysis .workspace diff --git a/src/config.rs b/src/config.rs index 843de6a..a962dce 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,7 +1,7 @@ use std::path::{Path, PathBuf}; use anyhow::{Context, bail}; -use globset::{Glob, GlobSet, GlobSetBuilder}; +use globset::{Glob, GlobMatcher, GlobSet, GlobSetBuilder}; use serde::Deserialize; use crate::cli::DupeMode; @@ -13,6 +13,14 @@ use crate::cli::DupeMode; pub struct RoeConfig { pub aggressive: Option, pub roots: Option>, + /// Glob patterns (relative to this config file's directory, resolved + /// with the same rules as `ignore`) naming files to treat as entry + /// points: every declaration in a matching file is a root, so the file + /// and everything it references count as used. For files consumed in + /// ways roe can't see — plugin hosts, reflection loaders, source + /// generators reading the file by path. + #[serde(rename = "entryPoints")] + pub entry_points: Option>, /// Project names to always treat in library mode (public API is used), /// regardless of executables elsewhere in the workspace. #[serde(rename = "libraryProjects")] @@ -403,21 +411,9 @@ pub(crate) fn build_ignore_globset( let mut builder = GlobSetBuilder::new(); let mut any = false; for pattern in patterns { - if pattern.contains("..") { - warnings.push(format!("unsupported ignore glob with '..': {pattern}")); - continue; - } - let expanded = match pattern.strip_suffix('/') { - Some(dir) => format!("{dir}/**"), - None => pattern.clone(), - }; - let absolute = format!("{}/{}", config_dir.display(), expanded); - match Glob::new(&absolute) { - Ok(glob) => { - builder.add(glob); - any = true; - } - Err(error) => warnings.push(format!("invalid ignore glob {pattern}: {error}")), + if let Some(glob) = build_config_glob(config_dir, pattern, "ignore", warnings) { + builder.add(glob); + any = true; } } if !any { @@ -426,6 +422,69 @@ pub(crate) fn build_ignore_globset( builder.build().ok() } +/// A single compiled `entryPoints` pattern. Kept per-pattern rather than +/// merged into one `GlobSet` so a pattern that matches no file at all can be +/// reported on its own. +pub struct EntryPointGlob { + pub matcher: GlobMatcher, + pub pattern: String, +} + +/// Compiles `entryPoints` glob patterns against `config_dir` (the config +/// file's own directory) with the same resolution rules `ignore` globs use. +/// A pattern that doesn't compile is skipped with a warning. +pub fn build_entry_point_globs( + config_dir: &Path, + patterns: &[String], + warnings: &mut Vec, +) -> Vec { + patterns + .iter() + .filter_map(|pattern| { + build_config_glob(config_dir, pattern, "entryPoints", warnings).map(|glob| { + EntryPointGlob { + matcher: glob.compile_matcher(), + pattern: pattern.clone(), + } + }) + }) + .collect() +} + +/// Expands one config-relative glob pattern into an absolute `Glob` with the +/// rules every config glob list shares: patterns resolve against the config +/// file's own directory, a trailing slash on a pattern reads as "this whole +/// directory" without the user having to spell out `**` themselves, and `..` +/// is unsupported. `label` names the config field so a warning points at the +/// list that holds the bad pattern. +fn build_config_glob( + config_dir: &Path, + pattern: &str, + label: &str, + warnings: &mut Vec, +) -> Option { + if pattern.contains("..") { + warnings.push(format!("unsupported {label} glob with '..': {pattern}")); + + return None; + } + + let expanded = match pattern.strip_suffix('/') { + Some(directory) => format!("{directory}/**"), + None => pattern.to_string(), + }; + let absolute = format!("{}/{}", config_dir.display(), expanded); + + match Glob::new(&absolute) { + Ok(glob) => Some(glob), + Err(error) => { + warnings.push(format!("invalid {label} glob {pattern}: {error}")); + + None + } + } +} + #[cfg(test)] mod tests { use super::*; @@ -890,6 +949,50 @@ mod tests { assert!(result.expect("discover should succeed").is_none()); } + #[test] + fn parses_entry_points() { + let config: RoeConfig = + serde_json::from_str(r#"{"entryPoints": ["Plugins/"]}"#).expect("valid json"); + assert_eq!(config.entry_points, Some(vec!["Plugins/".to_string()])); + + let config: RoeConfig = + serde_yaml_ng::from_str("entryPoints:\n - \"Jobs/**/*.cs\"\n").expect("valid yaml"); + assert_eq!(config.entry_points, Some(vec!["Jobs/**/*.cs".to_string()])); + } + + #[test] + fn entry_point_glob_trailing_slash_matches_whole_directory() { + let mut warnings = Vec::new(); + let globs = + build_entry_point_globs(Path::new("/repo"), &["Plugins/".to_string()], &mut warnings); + + assert_eq!(globs.len(), 1); + assert_eq!(globs[0].pattern, "Plugins/"); + assert!( + globs[0] + .matcher + .is_match(Path::new("/repo/Plugins/Nested/File.cs")) + ); + assert!(!globs[0].matcher.is_match(Path::new("/repo/Other/File.cs"))); + assert!(warnings.is_empty()); + } + + #[test] + fn entry_point_glob_with_dot_dot_is_skipped_with_a_warning() { + let mut warnings = Vec::new(); + let globs = build_entry_point_globs( + Path::new("/repo"), + &["../outside/**".to_string()], + &mut warnings, + ); + + assert!(globs.is_empty()); + assert_eq!( + warnings, + vec!["unsupported entryPoints glob with '..': ../outside/**".to_string()] + ); + } + #[test] fn ignore_glob_trailing_slash_matches_whole_directory() { let mut warnings = Vec::new(); diff --git a/src/entry_points.rs b/src/entry_points.rs index f80ab92..ee08efd 100644 --- a/src/entry_points.rs +++ b/src/entry_points.rs @@ -1,3 +1,4 @@ +use crate::config::EntryPointGlob; use crate::extract::Interner; use crate::extract::FileFacts; @@ -194,6 +195,46 @@ pub fn mark_roots( notes } +/// Root every declaration in the files the config's `entryPoints` globs +/// match, so each matching file and everything it references count as used. +/// This is the file-level counterpart to `roots`: `roots` names one symbol, +/// an entry-point file keeps its whole contents alive. Returns notes to +/// surface in the report (a pattern that matches no file at all). +pub fn mark_entry_point_files( + resolution: &mut Resolution, + workspace: &Workspace, + entry_point_globs: &[EntryPointGlob], +) -> Vec { + let mut notes = Vec::new(); + let mut matched_files = vec![false; workspace.files.len()]; + + for glob in entry_point_globs { + let mut matched = false; + + for file in &workspace.files { + if glob.matcher.is_match(&file.path) { + matched_files[file.id.index()] = true; + matched = true; + } + } + + if !matched { + notes.push(format!( + "entryPoints {}: no matching file found", + glob.pattern + )); + } + } + + for symbol in &mut resolution.symbols { + if matched_files[symbol.file.index()] { + symbol.flags |= SymbolFlags::ROOT; + } + } + + notes +} + fn is_controller(symbol: &crate::resolve::Symbol, rodeo: &Interner) -> bool { if !symbol.kind.is_type() { return false; diff --git a/tests/cli.rs b/tests/cli.rs index 75cc18e..c182f93 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -108,6 +108,36 @@ fn config_ignore_yaml_filters_out_ignored_folder() { assert!(!stdout.contains("Ignored")); } +#[test] +fn config_entry_points_json_roots_matching_files_and_what_they_reference() { + // Plugins/CustomPlugin.cs is only alive through the config's + // `entryPoints` glob, and PluginHelper is only alive through the plugin + // — proving an entry-point file keeps its references alive, which a + // plain `ignore` glob would not. + let output = roe() + .args(["dead-code", &fixture("config_entry_points_json")]) + .output() + .expect("command runs"); + assert_eq!(output.status.code(), Some(1)); + let stdout = String::from_utf8_lossy(&output.stdout); + assert!(stdout.contains("StillDead.cs")); + assert!(!stdout.contains("Plugins")); + assert!(!stdout.contains("PluginHelper")); +} + +#[test] +fn config_entry_points_yaml_roots_matching_files_and_what_they_reference() { + let output = roe() + .args(["dead-code", &fixture("config_entry_points_yaml")]) + .output() + .expect("command runs"); + assert_eq!(output.status.code(), Some(1)); + let stdout = String::from_utf8_lossy(&output.stdout); + assert!(stdout.contains("StillDead.cs")); + assert!(!stdout.contains("Plugins")); + assert!(!stdout.contains("PluginHelper")); +} + #[test] fn dead_code_scoped_ignore_json_drops_findings_in_matching_files() { let output = roe() diff --git a/tests/dead_code.rs b/tests/dead_code.rs index 740afc0..78dc4e7 100644 --- a/tests/dead_code.rs +++ b/tests/dead_code.rs @@ -11,7 +11,8 @@ fn fixture(name: &str) -> PathBuf { /// Sorted (kind, name) pairs for stable assertions. fn findings(name: &str, aggressive: bool) -> Vec<(FindingKind, String)> { - let analysis = analyze(&fixture(name), aggressive, &[], &[]).expect("analysis should succeed"); + let analysis = + analyze(&fixture(name), aggressive, &[], &[], &[]).expect("analysis should succeed"); let mut pairs: Vec<(FindingKind, String)> = analysis .result .findings @@ -131,6 +132,7 @@ fn library_projects_flag_protects_a_named_project_despite_a_sibling_executable() false, &[], &["Lib".to_string()], + &[], ) .expect("analysis should succeed"); assert!(analysis.result.findings.is_empty()); @@ -211,6 +213,7 @@ fn manual_roots_rescue_symbols() { false, &["ConsoleApp.ConsoleGreeter.UnusedHelper".to_string()], &[], + &[], ) .expect("analysis should succeed"); let names: Vec<&str> = analysis @@ -222,9 +225,54 @@ fn manual_roots_rescue_symbols() { assert!(!names.contains(&"ConsoleApp.ConsoleGreeter.UnusedHelper")); } +#[test] +fn entry_point_files_root_every_declaration_they_contain() { + let analysis = analyze( + &fixture("console_app"), + false, + &[], + &[], + &["ConsoleApp/DeadClass.cs".to_string()], + ) + .expect("analysis should succeed"); + let mut pairs: Vec<(FindingKind, String)> = analysis + .result + .findings + .iter() + .map(|f| (f.kind, f.name.clone())) + .collect(); + pairs.sort_by(|a, b| a.1.cmp(&b.1)); + + assert_findings( + pairs, + vec![member("ConsoleApp.ConsoleGreeter.UnusedHelper")], + ); +} + +#[test] +fn an_entry_point_glob_matching_no_file_surfaces_a_note() { + let analysis = analyze( + &fixture("console_app"), + false, + &[], + &[], + &["Plugins/**".to_string()], + ) + .expect("analysis should succeed"); + + assert!( + analysis + .result + .notes + .contains(&"entryPoints Plugins/**: no matching file found".to_string()), + "got notes {:?}", + analysis.result.notes + ); +} + #[test] fn nonexistent_path_errors() { - assert!(analyze(&fixture("does_not_exist"), false, &[], &[]).is_err()); + assert!(analyze(&fixture("does_not_exist"), false, &[], &[], &[]).is_err()); } #[test] diff --git a/tests/fixtures/config_entry_points_json/PluginHelper.cs b/tests/fixtures/config_entry_points_json/PluginHelper.cs new file mode 100644 index 0000000..fd5904c --- /dev/null +++ b/tests/fixtures/config_entry_points_json/PluginHelper.cs @@ -0,0 +1,8 @@ +namespace ConfigEntryPoints; + +internal class PluginHelper +{ + public void Help() + { + } +} diff --git a/tests/fixtures/config_entry_points_json/Plugins/CustomPlugin.cs b/tests/fixtures/config_entry_points_json/Plugins/CustomPlugin.cs new file mode 100644 index 0000000..0089c8c --- /dev/null +++ b/tests/fixtures/config_entry_points_json/Plugins/CustomPlugin.cs @@ -0,0 +1,10 @@ +namespace ConfigEntryPoints; + +internal class CustomPlugin +{ + public void Run() + { + var helper = new PluginHelper(); + helper.Help(); + } +} diff --git a/tests/fixtures/config_entry_points_json/Program.cs b/tests/fixtures/config_entry_points_json/Program.cs new file mode 100644 index 0000000..596b0a0 --- /dev/null +++ b/tests/fixtures/config_entry_points_json/Program.cs @@ -0,0 +1,8 @@ +namespace ConfigEntryPoints; + +public static class Program +{ + public static void Main() + { + } +} diff --git a/tests/fixtures/config_entry_points_json/StillDead.cs b/tests/fixtures/config_entry_points_json/StillDead.cs new file mode 100644 index 0000000..70df89d --- /dev/null +++ b/tests/fixtures/config_entry_points_json/StillDead.cs @@ -0,0 +1,8 @@ +namespace ConfigEntryPoints; + +internal class StillDead +{ + public void DoNothing() + { + } +} diff --git a/tests/fixtures/config_entry_points_json/roe.json b/tests/fixtures/config_entry_points_json/roe.json new file mode 100644 index 0000000..0a7483a --- /dev/null +++ b/tests/fixtures/config_entry_points_json/roe.json @@ -0,0 +1,3 @@ +{ + "entryPoints": ["Plugins/"] +} diff --git a/tests/fixtures/config_entry_points_yaml/PluginHelper.cs b/tests/fixtures/config_entry_points_yaml/PluginHelper.cs new file mode 100644 index 0000000..fd5904c --- /dev/null +++ b/tests/fixtures/config_entry_points_yaml/PluginHelper.cs @@ -0,0 +1,8 @@ +namespace ConfigEntryPoints; + +internal class PluginHelper +{ + public void Help() + { + } +} diff --git a/tests/fixtures/config_entry_points_yaml/Plugins/CustomPlugin.cs b/tests/fixtures/config_entry_points_yaml/Plugins/CustomPlugin.cs new file mode 100644 index 0000000..0089c8c --- /dev/null +++ b/tests/fixtures/config_entry_points_yaml/Plugins/CustomPlugin.cs @@ -0,0 +1,10 @@ +namespace ConfigEntryPoints; + +internal class CustomPlugin +{ + public void Run() + { + var helper = new PluginHelper(); + helper.Help(); + } +} diff --git a/tests/fixtures/config_entry_points_yaml/Program.cs b/tests/fixtures/config_entry_points_yaml/Program.cs new file mode 100644 index 0000000..596b0a0 --- /dev/null +++ b/tests/fixtures/config_entry_points_yaml/Program.cs @@ -0,0 +1,8 @@ +namespace ConfigEntryPoints; + +public static class Program +{ + public static void Main() + { + } +} diff --git a/tests/fixtures/config_entry_points_yaml/StillDead.cs b/tests/fixtures/config_entry_points_yaml/StillDead.cs new file mode 100644 index 0000000..70df89d --- /dev/null +++ b/tests/fixtures/config_entry_points_yaml/StillDead.cs @@ -0,0 +1,8 @@ +namespace ConfigEntryPoints; + +internal class StillDead +{ + public void DoNothing() + { + } +} diff --git a/tests/fixtures/config_entry_points_yaml/roe.yaml b/tests/fixtures/config_entry_points_yaml/roe.yaml new file mode 100644 index 0000000..1c9076d --- /dev/null +++ b/tests/fixtures/config_entry_points_yaml/roe.yaml @@ -0,0 +1,2 @@ +entryPoints: + - "Plugins/" From 6e2c2c296f4fec1f1790c71958a710288d0bad04 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 16 Sep 2026 06:03:11 +0000 Subject: [PATCH 2/2] fix(deps): Update gix to 0.87.1 to drop the yanked bisync crate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CI's cargo-deny advisories check fails because bisync — a transitive dependency of gix-protocol 0.64 — has had every version yanked from crates.io. No 0.64.x release exists without it, so the fix is the gix 0.87.1 line, where gix-protocol 0.65.1 dropped the dependency. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01GktmvEmkYosc2hG9XEebjP --- Cargo.lock | 221 +++++++++++++++++++++++++++-------------------------- Cargo.toml | 2 +- 2 files changed, 113 insertions(+), 110 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3e8990d..ef47de6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -121,21 +121,6 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" -[[package]] -name = "bisync" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5020822f6d6f23196ccaf55e228db36f9de1cf788052b37992e17cbc96ec41a7" -dependencies = [ - "bisync_macros", -] - -[[package]] -name = "bisync_macros" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d21f40d350a700f6aa107e45fb26448cf489d34794b2ba4522181dc9f1173af6" - [[package]] name = "bitflags" version = "1.3.2" @@ -519,9 +504,9 @@ dependencies = [ [[package]] name = "gix" -version = "0.86.0" +version = "0.87.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb3790fd8981cba7949f1ba924ef865d902df731627bc5998d14164063892fce" +checksum = "fdefc1465d8631807deaf504dacdeff628b978de515653b47976ca7c28ab2a7a" dependencies = [ "gix-actor", "gix-attributes", @@ -541,12 +526,14 @@ dependencies = [ "gix-ignore", "gix-index", "gix-lock", + "gix-note", "gix-object", "gix-odb", "gix-pack", "gix-path", "gix-pathspec", "gix-protocol", + "gix-quote", "gix-ref", "gix-refspec", "gix-revision", @@ -570,9 +557,9 @@ dependencies = [ [[package]] name = "gix-actor" -version = "0.41.2" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33f9308ad6fd35b2a865cbe4117ac61b2be59e4a9ef1621c7a9794f7c8e52c5b" +checksum = "e37efa99929ac62f980fb1a7dcd09dea85b3aa6ead6ba0498362add3f4e698de" dependencies = [ "bstr", "gix-date", @@ -581,9 +568,9 @@ dependencies = [ [[package]] name = "gix-attributes" -version = "0.34.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31c593692ebdc1e38858d9a2b56f6a594c501e24a38971fe6685571f5a07be0" +checksum = "76b83782ac69ae28921a6e8fbcf2e24069613f1518030b97ae622b079abffa54" dependencies = [ "bstr", "gix-features", @@ -598,40 +585,39 @@ dependencies = [ [[package]] name = "gix-bitmap" -version = "0.3.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd1d118d0f5d88b96e6f6e13b566475fef4797ead4a02c26fed36c1375066f7" +checksum = "f17013c7ef5cb95ebb4bf4978201e6a8a42ffea9d666fd5388f1b7e742307d80" dependencies = [ "gix-error", ] [[package]] name = "gix-chunk" -version = "0.7.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a871e5cab12ba568845714473505deefffb3c04eb47f4708ce344cd459c1cc" +checksum = "00e32f938b3745ac93d73bc7490b6a15a661b2fc81973bfe90e275cc53c908e1" dependencies = [ "gix-error", ] [[package]] name = "gix-command" -version = "0.9.1" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00706d4fef135ef4b01680d5218c6ee40cda8baf697b864296cbc887d19118f6" +checksum = "aa00adbd2c77f584cfe41f348772d2f131af1fa519a7f6b98638f1144ead96a4" dependencies = [ "bstr", "gix-path", "gix-quote", "gix-trace", - "shell-words", ] [[package]] name = "gix-commitgraph" -version = "0.38.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2cd7f054ae2727223fe46dd39c012f066b12f532962d336d29ee193261787da" +checksum = "6b93c9fb1f5be01bba54a7a3b7455d359efc68555539c75ef74b8021bb6db497" dependencies = [ "bstr", "gix-chunk", @@ -643,9 +629,9 @@ dependencies = [ [[package]] name = "gix-config" -version = "0.59.0" +version = "0.60.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "103d11bef95c467577ecfa8b7b86a22e65af3507b2c9bfa3809a4afbae7df301" +checksum = "f973c28c0a4871a7926fc90c8377d4458fd6cbb19692f56582b4d2022313ae90" dependencies = [ "bstr", "gix-config-value", @@ -662,9 +648,9 @@ dependencies = [ [[package]] name = "gix-config-value" -version = "0.19.0" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f813e312a3f7f327187823cd4c754a3e4d948c98907d11e8f37554a2b6b8059" +checksum = "6f6af5321bfd3711a279d6b244d58532ba1cfabf9eb6374791f19929d8970082" dependencies = [ "bitflags 2.13.1", "bstr", @@ -675,9 +661,9 @@ dependencies = [ [[package]] name = "gix-date" -version = "0.15.6" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e47b9e8cdc688296609b706428de570f88b1e0eed7156dde7b4a89d26fa4567" +checksum = "e63d9aa18f29facd571c8953e66224ee0075b9e16622024794555ed4acceea85" dependencies = [ "bstr", "gix-error", @@ -687,9 +673,9 @@ dependencies = [ [[package]] name = "gix-diff" -version = "0.66.0" +version = "0.67.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fee7d89a3c507491cdfc57a1d1e0e300214720b4f7709ebc253e422f99822bfc" +checksum = "1b1689ff5ddeee4acfb2a43e875a1072a76d208624b15a9065c938b39cb0da2a" dependencies = [ "bstr", "gix-command", @@ -708,9 +694,9 @@ dependencies = [ [[package]] name = "gix-discover" -version = "0.54.0" +version = "0.55.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f517766fa1101dfe2606c1a19a8ffa699099030995a9194445446dfe261bdf" +checksum = "ec32a30ec2934735599c2545f30067e80bd255fd3454b52a5d59bc02b52874a3" dependencies = [ "bstr", "dunce", @@ -723,18 +709,18 @@ dependencies = [ [[package]] name = "gix-error" -version = "0.2.5" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a9292309fd944e71b2a3c96d3c03a6feb8852db646febdde7cbb9f79cb5f329" +checksum = "4a1ba536602db507119eb5f3cdf80bef3ca5a5ec0dfc6e9c7f46dc70ade7c112" dependencies = [ "bstr", ] [[package]] name = "gix-features" -version = "0.49.0" +version = "0.49.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20aa09e83a48dc02c5f5f08578aa79d3ab1bab4618b8c362f88684645a02bdcc" +checksum = "39c0e59d9d253dcccc38c3a46b91bfb9b46bd63eed54fe1a719e12194884d52a" dependencies = [ "bytes", "crc32fast", @@ -751,9 +737,9 @@ dependencies = [ [[package]] name = "gix-filter" -version = "0.33.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e7b5dbf524d97e839f642930c76d7f011c0791e7d11d8148989ac5af7c76aa8" +checksum = "9c30b28d957e2e6f1e1bbfbfd26b8e0bb0aab68d8a5e730fb4fd3049943575e3" dependencies = [ "bstr", "encoding_rs", @@ -772,9 +758,9 @@ dependencies = [ [[package]] name = "gix-fs" -version = "0.22.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "865cf13fcaf5455220546cb9607c416bd1be9a6caafd143655a362fdeab64e80" +checksum = "ebcfa9fd253f25350a3b21b3dd74034a446098e373c6123d4cee3519894f12ef" dependencies = [ "bstr", "gix-features", @@ -785,9 +771,9 @@ dependencies = [ [[package]] name = "gix-glob" -version = "0.27.0" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "421e92a711554fa5827d1b0599d3389acdd0f6729e97a8c5a57d79af1e50bf36" +checksum = "b417cf515fd8c91468b578071f76d6cba716f8a1eccd853906bff4908b2c1413" dependencies = [ "bitflags 2.13.1", "bstr", @@ -797,9 +783,9 @@ dependencies = [ [[package]] name = "gix-hash" -version = "0.26.0" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13adaa73415fd6c902310923f68d0b98e8cecf14b33ea58c02cc387cee56f54e" +checksum = "380b9c423a54f0821064b954b5a5ab25c660812f6a91da03c3f1cb4b10762aa5" dependencies = [ "faster-hex", "gix-features", @@ -820,9 +806,9 @@ dependencies = [ [[package]] name = "gix-ignore" -version = "0.22.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12cff8e8aa125e39377456073e63df3334d9e5741372ddcc226198015076dda2" +checksum = "65859a2f7de5e159d4344a5486ebf53b6bac22d5ec6afa836e47c10ae88a7f0f" dependencies = [ "bstr", "gix-glob", @@ -833,19 +819,19 @@ dependencies = [ [[package]] name = "gix-imara-diff" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a791e6620676a875f362f3156ed213e73ca099a09bf992c18812abe65cc37b1" +checksum = "1c91d8cffac8849493a82233811bd02b2b183b8cf39bf704de0fa0841b737595" dependencies = [ "bstr", - "hashbrown 0.16.1", + "hashbrown 0.17.1", ] [[package]] name = "gix-index" -version = "0.54.0" +version = "0.55.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5009c4e7e9f9b4cfaaab1153e49133eb04d79c015b5702d6c3d2ab94271a89c6" +checksum = "632e16cb48b0e88a747e106924cb2765194105d8070a7a961b0d080ed806c632" dependencies = [ "bitflags 2.13.1", "bstr", @@ -880,18 +866,43 @@ dependencies = [ "thiserror", ] +[[package]] +name = "gix-macros" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3836b4b051393464a753c5a08fe19c7ce0d8b77574a92bd558972941d4553cb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "gix-note" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9af6bbdb3f3c62b4920407c479af1cc0beb27fd75a762782d48baed53d330958" +dependencies = [ + "gix-error", + "gix-hash", + "gix-hashtable", + "gix-object", +] + [[package]] name = "gix-object" -version = "0.63.0" +version = "0.64.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e48c235e7f886eb819fc878af75be889333dd3c38bee02ed7af48ae2cf596c4" +checksum = "56fef799ca40cdeab4de5a3e74a696d8fa9b9c6264592646bf022e026f13ce2c" dependencies = [ "bstr", "gix-actor", + "gix-command", "gix-date", "gix-features", "gix-hash", "gix-hashtable", + "gix-tempfile", "gix-utils", "gix-validate", "itoa", @@ -901,9 +912,9 @@ dependencies = [ [[package]] name = "gix-odb" -version = "0.83.0" +version = "0.84.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dd494ffb5037e62b8220109e894d2861ff2150a2cacbfccdba57ae1ebab2b96" +checksum = "cf45d195b71cb6363886e7b466821bf4dffd7aba1b6b814ff75488e0061d72a7" dependencies = [ "arc-swap", "gix-features", @@ -923,11 +934,12 @@ dependencies = [ [[package]] name = "gix-pack" -version = "0.73.0" +version = "0.74.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d5446127b269706e85998065267ddd2ccc3550179da6780b22fe496175ccb20" +checksum = "3d199d515cbdcf05f531f3859be9771fc12acac7b7fe0f5b581b2c1ab1c3a61e" dependencies = [ "clru", + "crossbeam-deque", "gix-chunk", "gix-error", "gix-features", @@ -944,9 +956,9 @@ dependencies = [ [[package]] name = "gix-packetline" -version = "0.22.0" +version = "0.22.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3766025c72319c4accdd854a18e6f0dd176c8eb0f3bc8a60a7765be2b50cabf2" +checksum = "792bd92bea390087e6223b18d4d023decc36467de31e6b066b69b94beea1b9e2" dependencies = [ "bstr", "faster-hex", @@ -956,9 +968,9 @@ dependencies = [ [[package]] name = "gix-path" -version = "0.12.3" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ed3e8d7a82e886e17a72e03d4ba0c13db6f2219b6cd4e2900b4cae426ec20c9" +checksum = "38fc6f029ea67de83cbcbd33fd98c05a48360d2932b39d9fdacbc6eae802d475" dependencies = [ "bstr", "gix-trace", @@ -968,9 +980,9 @@ dependencies = [ [[package]] name = "gix-pathspec" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f6fa5f8007f008187c3f60b4373209ca83d1cc947f35ede03e16cd15a4d137" +checksum = "c92e44c63ba53bb55aa88ee48847664beae9446417621582fb14dfc69b2f8c72" dependencies = [ "bitflags 2.13.1", "bstr", @@ -983,15 +995,15 @@ dependencies = [ [[package]] name = "gix-protocol" -version = "0.64.0" +version = "0.65.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dede40e89c1e90f548415f50636bb051f6d9c60f68b8b710bc07825722d19588" +checksum = "68878c37ae168b474c762d70adc8a8e0f9323ed0d80444a672e2eb561fa16691" dependencies = [ - "bisync", "bstr", "gix-date", "gix-features", "gix-hash", + "gix-macros", "gix-ref", "gix-shallow", "gix-transport", @@ -1002,9 +1014,9 @@ dependencies = [ [[package]] name = "gix-quote" -version = "0.7.2" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6e541fc33cc2b783b7979040d445a0c86a2eca747c8faea4ca84230d06ae6ef" +checksum = "f74795eb76eab8313063849f9cbd2bbcdc6e4692f71c1d7d0244ab11cd777329" dependencies = [ "bstr", "gix-error", @@ -1013,9 +1025,9 @@ dependencies = [ [[package]] name = "gix-ref" -version = "0.66.0" +version = "0.67.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeb0c90a8f6202ceaaa22996cbf837c943ccb2d8af9ff3490f0758305e6b7883" +checksum = "8328387e7ab354e1dc3afb63e6b4d1866f82d7ce035222bc9d5baaf36bc88020" dependencies = [ "gix-actor", "gix-features", @@ -1033,15 +1045,12 @@ dependencies = [ [[package]] name = "gix-refspec" -version = "0.44.0" +version = "0.45.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7406282cc0259b51f6aee299ca3d31279a020530363152a2e6c96e8a7f7bbc83" +checksum = "7de280d46e8fd9e4d3e7e2ab4276b965e377ba68b2b9a8fce56371015e8bb059" dependencies = [ "bstr", - "gix-error", - "gix-glob", "gix-hash", - "gix-revision", "gix-validate", "smallvec", "thiserror", @@ -1049,9 +1058,9 @@ dependencies = [ [[package]] name = "gix-revision" -version = "0.48.0" +version = "0.49.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e55e09d4a1ecf2beecc8c09cafcad37979e805b31f588b0e957e191df5783681" +checksum = "4577b864c3e134697e91564553e43230c2e401bb1bcc51cfa998edca21c95078" dependencies = [ "bitflags 2.13.1", "bstr", @@ -1068,9 +1077,9 @@ dependencies = [ [[package]] name = "gix-revwalk" -version = "0.34.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c113c0a53294dc6280ffc06cbcc4f50f820397e97d6a00b429a44b8db26e29" +checksum = "248823eefe405e2c0754b74f6f43ab6faab68670cdbf2d6e114cb0471f766450" dependencies = [ "gix-commitgraph", "gix-date", @@ -1109,9 +1118,9 @@ dependencies = [ [[package]] name = "gix-submodule" -version = "0.33.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd98077a56d08886112e6b08dc94076d03539f4bc0b9d7880e4be2b8a640d8c" +checksum = "da85564d6725c483b8d95d7b31d1db0b78c29e462a2b481949e2f18e1ed55a6a" dependencies = [ "bstr", "gix-config", @@ -1143,9 +1152,9 @@ checksum = "be3eb81d9dc914335923e50d52829c551feefd6a72d176c4130c546b67a60814" [[package]] name = "gix-transport" -version = "0.58.0" +version = "0.59.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c1bcf30081eb8ab04540a5795c67a2fcb22cb2e976e8b1a4ea657b1ed61469" +checksum = "b3f41a64939953ff49117df4eb91334d299abc59ff57a90fb2193d8ffa5886f1" dependencies = [ "bstr", "gix-command", @@ -1160,9 +1169,9 @@ dependencies = [ [[package]] name = "gix-traverse" -version = "0.60.0" +version = "0.61.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "008c5cd879e46e86b5c2469e633611978b18775d53d05668d691bc13088bd409" +checksum = "9af3503668739f4de5dba57fe15cfd9adc443b08bcbbf195e5de16b648872245" dependencies = [ "bitflags 2.13.1", "gix-commitgraph", @@ -1177,9 +1186,9 @@ dependencies = [ [[package]] name = "gix-url" -version = "0.37.0" +version = "0.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d10e53b8eae21ee601687f47bbbd6cb2ed7162cb4c1cafdd422fb7ec64cbee" +checksum = "5bda80ccb4bc81fb9fb07a975916eb0c7a889bcbcb0c8a239c3f82a9cc2abdda" dependencies = [ "bstr", "gix-path", @@ -1190,9 +1199,9 @@ dependencies = [ [[package]] name = "gix-utils" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1795bd2a970ca8b2185318c2abb97d955c71992f1cf28de73ad3b593a9f3ce8" +checksum = "0da1c46491b49458a446cc76f0085860f8164c2290742e0aa8c653ce67240a97" dependencies = [ "bstr", "fastrand", @@ -1202,18 +1211,18 @@ dependencies = [ [[package]] name = "gix-validate" -version = "0.11.3" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a034e84d1e04e1b1f20f51f12491da230b6ac8b925d0c8e1b89bcd87a7c5ccc" +checksum = "4dae8780f63ed8a803b8bdabbd7aa5f5c5d74592c8b50eed875c1bb4f6545a6a" dependencies = [ "bstr", ] [[package]] name = "gix-worktree" -version = "0.55.0" +version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31eb8e675122e83585e461fe28f68ff8c5ed55b49017b697e7e76423ff973424" +checksum = "3ed36b627476e2072c129900a17c977a38052b5497e27308159bc881fbf4eecf" dependencies = [ "bstr", "gix-attributes", @@ -1230,9 +1239,9 @@ dependencies = [ [[package]] name = "gix-worktree-stream" -version = "0.35.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b088c8724e7be120c4798dd86925cf05332c9d356a463542578600c50c7a549" +checksum = "de5ec0ccbab39c9994656ea031ded8ffd90b370a3cc8e360fbe3c4ebe7c64964" dependencies = [ "gix-attributes", "gix-error", @@ -1842,12 +1851,6 @@ dependencies = [ "sha1", ] -[[package]] -name = "shell-words" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77" - [[package]] name = "shlex" version = "2.0.1" diff --git a/Cargo.toml b/Cargo.toml index b106b78..8e8b78e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ clap = { version = "4.6.3", features = ["derive"] } colored = "3.1.1" dunce = "1.0.5" fixedbitset = "0.5.7" -gix = { version = "0.86.0", default-features = false, features = ["blob-diff", "max-performance-safe", "revision", "sha1"] } +gix = { version = "0.87.1", default-features = false, features = ["blob-diff", "max-performance-safe", "revision", "sha1"] } globset = "0.4.19" ignore = "0.4.31" lasso = { version = "0.7.3", features = ["multi-threaded"] }