diff --git a/Cargo.lock b/Cargo.lock index 46f20b5..b5e8b04 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,17 +2,6 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "ahash" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" -dependencies = [ - "getrandom 0.2.15", - "once_cell", - "version_check", -] - [[package]] name = "aho-corasick" version = "1.1.3" @@ -73,9 +62,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.83" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" [[package]] name = "arrayvec" @@ -314,9 +303,9 @@ dependencies = [ [[package]] name = "error-stack" -version = "0.5.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe413319145d1063f080f27556fd30b1d70b01e2ba10c2a6e40d4be982ffc5d1" +checksum = "d01a8d4d427153bae0c38ca68d7912cbf9903fdcc97ecac18801738b3656a46d" dependencies = [ "anyhow", "rustc_version", @@ -361,17 +350,6 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", -] - [[package]] name = "getrandom" version = "0.3.3" @@ -381,7 +359,7 @@ dependencies = [ "cfg-if", "libc", "r-efi", - "wasi 0.14.2+wasi-0.2.4", + "wasi", ] [[package]] @@ -408,9 +386,6 @@ name = "hashbrown" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash", -] [[package]] name = "hashbrown" @@ -511,15 +486,6 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" -[[package]] -name = "lru" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999beba7b6e8345721bd280141ed958096a2e4abdf74f67ff4ce49b4b54e47a" -dependencies = [ - "hashbrown 0.12.3", -] - [[package]] name = "matchers" version = "0.2.0" @@ -542,7 +508,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8d1d5792299bab3f8b5d88d1b7a7cb50ad7ef039a8c4d45a6b84880a6526276" dependencies = [ "lazy_static", - "lru", "memoize-inner", ] @@ -721,9 +686,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] @@ -875,7 +840,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "15b61f8f20e3a6f7e0649d825294eaf317edce30f82cf6026e7e4cb9222a7d1e" dependencies = [ "fastrand", - "getrandom 0.3.3", + "getrandom", "once_cell", "rustix", "windows-sys 0.59.0", @@ -997,12 +962,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - [[package]] name = "wait-timeout" version = "0.2.0" @@ -1022,12 +981,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - [[package]] name = "wasi" version = "0.14.2+wasi-0.2.4" diff --git a/Cargo.toml b/Cargo.toml index 0a83a15..c18fc5f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,14 +13,19 @@ path = "src/lib.rs" clap = { version = "4.5.45", features = ["derive"] } clap_derive = "4.5.45" crossbeam-channel = "0.5.15" -error-stack = "0.5.0" +error-stack = "0.8.0" enum_dispatch = "0.3.13" fast-glob = "1.0.0" glob = "0.3.3" ignore = "0.4.23" itertools = "0.14.0" lazy_static = "1.5.0" -memoize = "0.5.1" +# `default-features = false` drops memoize's optional `lru` dependency, which is +# pinned to lru ^0.7 and carries RUSTSEC-2026-0253 (use-after-free in +# `LruCache::pop()`; only fixed in lru >= 0.18.2, which memoize cannot resolve). +# We only use bare `#[memoize]`, so the `Capacity`/`TimeToLive` options that need +# `lru` are unused. +memoize = { version = "0.5.1", default-features = false } path-clean = "1.0.1" rayon = "1.10.0" regex = "1.11.1" diff --git a/src/cache/file.rs b/src/cache/file.rs index 4132ab8..7900139 100644 --- a/src/cache/file.rs +++ b/src/cache/file.rs @@ -1,5 +1,5 @@ use crate::project::Error; -use error_stack::{Result, ResultExt}; +use error_stack::{Report, ResultExt}; use std::{ collections::HashMap, fs::{self, File, OpenOptions}, @@ -20,7 +20,7 @@ pub struct GlobalCache { const DEFAULT_CACHE_CAPACITY: usize = 50000; impl Caching for GlobalCache { - fn get_file_owner(&self, path: &Path) -> Result, Error> { + fn get_file_owner(&self, path: &Path) -> Result, Report> { if let Some(cache_mutex) = self.file_owner_cache.as_ref() && let Ok(cache) = cache_mutex.lock() && let Some(cached_entry) = cache.get(path) @@ -42,7 +42,7 @@ impl Caching for GlobalCache { } } - fn persist_cache(&self) -> Result<(), Error> { + fn persist_cache(&self) -> Result<(), Report> { let cache_path = self.get_cache_path(); let file = OpenOptions::new() .write(true) @@ -60,7 +60,7 @@ impl Caching for GlobalCache { } } - fn delete_cache(&self) -> Result<(), Error> { + fn delete_cache(&self) -> Result<(), Report> { let cache_path = self.get_cache_path(); tracing::debug!("Deleting cache file: {}", cache_path.display()); fs::remove_file(cache_path).change_context(Error::Io) @@ -68,7 +68,7 @@ impl Caching for GlobalCache { } impl GlobalCache { - pub fn new(base_path: PathBuf, cache_directory: String) -> Result { + pub fn new(base_path: PathBuf, cache_directory: String) -> Result> { let mut cache = Self { base_path, cache_directory, @@ -78,7 +78,7 @@ impl GlobalCache { Ok(cache) } - fn load_cache(&mut self) -> Result<(), Error> { + fn load_cache(&mut self) -> Result<(), Report> { let cache_path = self.get_cache_path(); if !cache_path.exists() { self.file_owner_cache = Some(Box::new(Mutex::new(HashMap::with_capacity(DEFAULT_CACHE_CAPACITY)))); @@ -102,7 +102,7 @@ impl GlobalCache { cache_dir.join("project-file-cache.json") } } -fn get_file_timestamp(path: &Path) -> Result { +fn get_file_timestamp(path: &Path) -> Result> { let metadata = fs::metadata(path).change_context(Error::Io)?; metadata .modified() @@ -119,7 +119,7 @@ mod tests { use super::*; #[test] - fn test_cache_dir() -> Result<(), Error> { + fn test_cache_dir() -> Result<(), Report> { let temp_dir = tempdir().change_context(Error::Io)?; let cache_dir = "test-codeowners-cache"; let cache = GlobalCache::new(temp_dir.path().to_path_buf(), cache_dir.to_owned())?; @@ -162,7 +162,7 @@ mod tests { } #[test] - fn test_corrupted_cache() -> Result<(), Error> { + fn test_corrupted_cache() -> Result<(), Report> { let temp_dir = tempdir().change_context(Error::Io)?; let cache_dir = "test-codeowners-cache"; let cache = GlobalCache::new(temp_dir.path().to_path_buf(), cache_dir.to_owned())?; diff --git a/src/cache/mod.rs b/src/cache/mod.rs index 4406a26..380ff04 100644 --- a/src/cache/mod.rs +++ b/src/cache/mod.rs @@ -1,6 +1,6 @@ use crate::project::Error; use enum_dispatch::enum_dispatch; -use error_stack::Result; +use error_stack::Report; use file::GlobalCache; use noop::NoopCache; use std::path::Path; @@ -16,10 +16,10 @@ pub enum Cache { #[enum_dispatch(Cache)] pub trait Caching { - fn get_file_owner(&self, path: &Path) -> Result, Error>; + fn get_file_owner(&self, path: &Path) -> Result, Report>; fn write_file_owner(&self, path: &Path, owner: Option); - fn persist_cache(&self) -> Result<(), Error>; - fn delete_cache(&self) -> Result<(), Error>; + fn persist_cache(&self) -> Result<(), Report>; + fn delete_cache(&self) -> Result<(), Report>; } #[derive(Clone, Debug, serde::Serialize, serde::Deserialize, PartialEq)] diff --git a/src/cache/noop.rs b/src/cache/noop.rs index 4adc015..52cf62a 100644 --- a/src/cache/noop.rs +++ b/src/cache/noop.rs @@ -1,5 +1,5 @@ use crate::project::Error; -use error_stack::Result; +use error_stack::Report; use std::path::Path; use super::{Caching, FileOwnerCacheEntry}; @@ -8,7 +8,7 @@ use super::{Caching, FileOwnerCacheEntry}; pub struct NoopCache {} impl Caching for NoopCache { - fn get_file_owner(&self, _path: &Path) -> Result, Error> { + fn get_file_owner(&self, _path: &Path) -> Result, Report> { Ok(None) } @@ -16,11 +16,11 @@ impl Caching for NoopCache { // noop } - fn persist_cache(&self) -> Result<(), Error> { + fn persist_cache(&self) -> Result<(), Report> { Ok(()) } - fn delete_cache(&self) -> Result<(), Error> { + fn delete_cache(&self) -> Result<(), Report> { Ok(()) } } diff --git a/src/cli.rs b/src/cli.rs index 0721a51..e3e3c08 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,7 +1,7 @@ use clap::{Parser, Subcommand}; use codeowners::runner::RunConfig; use codeowners::runner::{self, Error as RunnerError, RunResult}; -use error_stack::{Result, ResultExt}; +use error_stack::{Report, ResultExt}; use path_clean::PathClean; use std::path::{Path, PathBuf}; @@ -82,30 +82,30 @@ struct Args { } impl Args { - fn absolute_project_root(&self) -> Result { + fn absolute_project_root(&self) -> Result> { self.project_root.canonicalize().change_context(RunnerError::Io(format!( "Can't canonicalize project root: {}", &self.project_root.to_string_lossy() ))) } - fn absolute_config_path(&self) -> Result { + fn absolute_config_path(&self) -> Result> { Ok(self.absolute_path(&self.config_path)?.clean()) } - fn absolute_codeowners_path(&self) -> Result, RunnerError> { + fn absolute_codeowners_path(&self) -> Result, Report> { match &self.codeowners_file_path { Some(path) => Ok(Some(self.absolute_path(path)?.clean())), None => Ok(None), } } - fn absolute_path(&self, path: &Path) -> Result { + fn absolute_path(&self, path: &Path) -> Result> { Ok(self.absolute_project_root()?.join(path)) } } -pub fn cli() -> Result { +pub fn cli() -> Result> { let args = Args::parse(); let config_path = args.absolute_config_path()?; diff --git a/src/main.rs b/src/main.rs index 8afc20a..9961eda 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,18 +2,18 @@ mod cli; use std::process; use codeowners::runner::{Error as RunnerError, RunResult}; -use error_stack::Result; +use error_stack::Report; use crate::cli::cli; -fn main() -> Result<(), RunnerError> { +fn main() -> Result<(), Report> { install_logger(); maybe_print_errors(cli()?)?; Ok(()) } -fn maybe_print_errors(result: RunResult) -> Result<(), RunnerError> { +fn maybe_print_errors(result: RunResult) -> Result<(), Report> { if !result.info_messages.is_empty() { for msg in result.info_messages { println!("{}", msg); diff --git a/src/ownership/validator.rs b/src/ownership/validator.rs index 664de3a..a3896cd 100644 --- a/src/ownership/validator.rs +++ b/src/ownership/validator.rs @@ -5,7 +5,6 @@ use std::fmt::Display; use std::path::PathBuf; use std::sync::Arc; -use error_stack::Context; use itertools::Itertools; use rayon::prelude::IntoParallelRefIterator; use rayon::prelude::ParallelIterator; @@ -258,7 +257,7 @@ impl Display for Errors { } } -impl Context for Errors {} +impl core::error::Error for Errors {} #[cfg(test)] mod tests { diff --git a/src/project.rs b/src/project.rs index 2d9cb71..12b09a6 100644 --- a/src/project.rs +++ b/src/project.rs @@ -6,7 +6,7 @@ use std::{ path::{Path, PathBuf}, }; -use error_stack::{Context, Result, ResultExt}; +use error_stack::{Report, ResultExt}; pub struct Project { pub base_path: PathBuf, @@ -44,7 +44,7 @@ pub struct Team { } impl Team { - pub fn from_team_file_path(absolute_path: PathBuf) -> Result { + pub fn from_team_file_path(absolute_path: PathBuf) -> Result> { let file = File::open(&absolute_path).change_context(Error::Io)?; let deserializer: deserializers::Team = serde_yaml::from_reader(file).change_context(Error::SerdeYaml)?; Ok(Self { @@ -167,10 +167,10 @@ impl fmt::Display for Error { } } -impl Context for Error {} +impl core::error::Error for Error {} impl Project { - pub fn get_codeowners_file(&self) -> Result { + pub fn get_codeowners_file(&self) -> Result> { let codeowners_file: String = if self.codeowners_file_path.exists() { std::fs::read_to_string(&self.codeowners_file_path).change_context(Error::Io)? } else { diff --git a/src/project_builder.rs b/src/project_builder.rs index 689fd10..7652bbd 100644 --- a/src/project_builder.rs +++ b/src/project_builder.rs @@ -4,7 +4,7 @@ use std::{ sync::{Arc, Mutex}, }; -use error_stack::{Report, Result, ResultExt}; +use error_stack::{Report, ResultExt}; use fast_glob::glob_match; use ignore::{DirEntry, WalkBuilder, WalkParallel, WalkState}; use rayon::iter::{IntoParallelIterator, ParallelIterator}; @@ -53,7 +53,7 @@ impl<'a> ProjectBuilder<'a> { } #[instrument(level = "debug", skip_all, fields(base_path = %self.base_path.display()))] - pub fn build(&mut self) -> Result { + pub fn build(&mut self) -> Result> { tracing::info!("Starting project build"); let mut builder = WalkBuilder::new(&self.base_path); builder.hidden(false); @@ -162,7 +162,7 @@ impl<'a> ProjectBuilder<'a> { self.build_project_from_entry_types(entry_types) } - fn build_entry_type(&self, entry: ignore::DirEntry) -> Result { + fn build_entry_type(&self, entry: ignore::DirEntry) -> Result> { let absolute_path = entry.path(); let is_dir = entry.file_type().ok_or(Error::Io).change_context(Error::Io)?.is_dir(); @@ -203,7 +203,7 @@ impl<'a> ProjectBuilder<'a> { } } - fn build_project_from_entry_types(&mut self, entry_types: Vec) -> Result { + fn build_project_from_entry_types(&mut self, entry_types: Vec) -> Result> { type Accumulator = ( Vec, Vec, @@ -232,8 +232,8 @@ impl<'a> ProjectBuilder<'a> { EntryType::Directory(absolute_path, relative_path) => { if relative_path.parent() == Some(Path::new(&self.config.vendored_gems_path)) { let file_name = relative_path.file_name().ok_or_else(|| { - error_stack::report!(Error::Io) - .attach_printable(format!("Vendored gem path has no file name: {}", relative_path.display())) + Report::new(Error::Io) + .attach(format!("Vendored gem path has no file name: {}", relative_path.display())) })?; gems.push(VendoredGem { path: absolute_path, @@ -243,7 +243,7 @@ impl<'a> ProjectBuilder<'a> { } EntryType::RubyPackage(absolute_path, relative_path) => { match ruby_package_owner(&absolute_path) - .attach_printable_lazy(|| format!("Failed to read ruby package: {}", absolute_path.display())) + .attach_with(|| format!("Failed to read ruby package: {}", absolute_path.display())) { Ok(Some(owner)) => { pkgs.push(Package { @@ -258,7 +258,7 @@ impl<'a> ProjectBuilder<'a> { } EntryType::JavascriptPackage(absolute_path, relative_path) => { match javascript_package_owner(&absolute_path) - .attach_printable_lazy(|| format!("Failed to read javascript package: {}", absolute_path.display())) + .attach_with(|| format!("Failed to read javascript package: {}", absolute_path.display())) { Ok(Some(owner)) => { pkgs.push(Package { @@ -274,7 +274,7 @@ impl<'a> ProjectBuilder<'a> { EntryType::CodeownerFile(absolute_path, relative_path) => { let owner = std::fs::read_to_string(&absolute_path) .change_context(Error::Io) - .attach_printable_lazy(|| format!("Failed to read codeowner file: {}", absolute_path.display()))?; + .attach_with(|| format!("Failed to read codeowner file: {}", absolute_path.display()))?; let owner = owner.trim().to_owned(); codeowners.push(DirectoryCodeownersFile { path: relative_path.clone(), @@ -284,7 +284,7 @@ impl<'a> ProjectBuilder<'a> { EntryType::TeamFile(absolute_path, _relative_path) => { let team = Team::from_team_file_path(absolute_path.clone()) .change_context(Error::Io) - .attach_printable_lazy(|| format!("Failed to read team file: {}", absolute_path.display()))?; + .attach_with(|| format!("Failed to read team file: {}", absolute_path.display()))?; team_files.push(team); } EntryType::NullEntry() => {} @@ -336,7 +336,7 @@ fn matches_globs(path: &Path, globs: &[String]) -> bool { } } -fn ruby_package_owner(path: &Path) -> Result, Error> { +fn ruby_package_owner(path: &Path) -> Result, Report> { let file = File::open(path).change_context(Error::Io)?; let deserializer: deserializers::RubyPackage = serde_yaml::from_reader(file).change_context(Error::SerdeYaml)?; @@ -345,7 +345,7 @@ fn ruby_package_owner(path: &Path) -> Result, Error> { // Error if both are present with different values match (top_level_owner.as_ref(), metadata_owner.as_ref()) { - (Some(top), Some(meta)) if top != meta => Err(error_stack::report!(Error::Io).attach_printable(format!( + (Some(top), Some(meta)) if top != meta => Err(Report::new(Error::Io).attach(format!( "Package at {} has conflicting owners: 'owner: {}' vs 'metadata.owner: {}'. Please use only one.", path.display(), top, @@ -355,7 +355,7 @@ fn ruby_package_owner(path: &Path) -> Result, Error> { } } -fn javascript_package_owner(path: &Path) -> Result, Error> { +fn javascript_package_owner(path: &Path) -> Result, Report> { let file = File::open(path).change_context(Error::Io)?; let deserializer: deserializers::JavascriptPackage = serde_json::from_reader(file).change_context(Error::SerdeJson)?; diff --git a/src/project_file_builder.rs b/src/project_file_builder.rs index 2c74c93..21e8f27 100644 --- a/src/project_file_builder.rs +++ b/src/project_file_builder.rs @@ -1,4 +1,4 @@ -use error_stack::Result; +use error_stack::Report; use lazy_static::lazy_static; use regex::Regex; use std::path::{Path, PathBuf}; @@ -34,7 +34,7 @@ impl<'a> ProjectFileBuilder<'a> { project_file } - fn get_project_file_from_cache(&self, path: &Path) -> Result, Error> { + fn get_project_file_from_cache(&self, path: &Path) -> Result, Report> { self.global_cache.get_file_owner(path).map(|entry| { entry.map(|e| ProjectFile { path: path.to_path_buf(), diff --git a/src/runner.rs b/src/runner.rs index e7704b4..f84e034 100644 --- a/src/runner.rs +++ b/src/runner.rs @@ -1,7 +1,7 @@ use std::path::{Path, PathBuf}; use std::process::Command; -use error_stack::{Result, ResultExt}; +use error_stack::{Report, ResultExt}; use fast_glob::glob_match; use serde::Serialize; @@ -47,7 +47,7 @@ where runnable(runner) } -pub(crate) fn config_from_run_config(run_config: &RunConfig) -> Result { +pub(crate) fn config_from_run_config(run_config: &RunConfig) -> Result> { match crate::config::Config::load_from_path(&run_config.config_path) { Ok(mut c) => { if let Some(executable_name) = &run_config.executable_name { @@ -55,7 +55,7 @@ pub(crate) fn config_from_run_config(run_config: &RunConfig) -> Result Err(error_stack::Report::new(Error::Io(msg))), + Err(msg) => Err(Report::new(Error::Io(msg))), } } @@ -79,7 +79,7 @@ pub(crate) fn resolve_codeowners_file_path(run_config: &RunConfig, config: &Conf } impl Runner { - pub fn new(run_config: &RunConfig) -> Result { + pub fn new(run_config: &RunConfig) -> Result> { let config = config_from_run_config(run_config)?; let codeowners_file_path = resolve_codeowners_file_path(run_config, &config); @@ -91,7 +91,7 @@ impl Runner { "Can't create cache: {}", &run_config.config_path.to_string_lossy() ))) - .attach_printable(format!("Can't create cache: {}", &run_config.config_path.to_string_lossy()))? + .attach(format!("Can't create cache: {}", &run_config.config_path.to_string_lossy()))? .into() }; @@ -264,7 +264,7 @@ impl Runner { crate::crosscheck::crosscheck_owners(&self.run_config, &self.cache) } - pub fn owners_for_file(&self, file_path: &str) -> Result, Error> { + pub fn owners_for_file(&self, file_path: &str) -> Result, Report> { use crate::ownership::file_owner_resolver::find_file_owners; let owners = find_file_owners(&self.run_config.project_root, &self.config, std::path::Path::new(file_path)).map_err(Error::Io)?; Ok(owners) diff --git a/src/runner/api.rs b/src/runner/api.rs index 31edbc4..0c09b4a 100644 --- a/src/runner/api.rs +++ b/src/runner/api.rs @@ -2,6 +2,7 @@ use std::collections::HashMap; use crate::project::Team; use crate::{ownership::FileOwner, runner::config_from_run_config}; +use error_stack::Report; use super::{Error, ForFileResult, RunConfig, RunResult, run}; @@ -37,7 +38,7 @@ pub fn crosscheck_owners(run_config: &RunConfig) -> RunResult { } // Returns all owners for a file without creating a Runner (performance optimized) -pub fn owners_for_file(run_config: &RunConfig, file_path: &str) -> error_stack::Result, Error> { +pub fn owners_for_file(run_config: &RunConfig, file_path: &str) -> Result, Report> { let config = config_from_run_config(run_config)?; use crate::ownership::file_owner_resolver::find_file_owners; let owners = find_file_owners(&run_config.project_root, &config, std::path::Path::new(file_path)).map_err(Error::Io)?; @@ -45,12 +46,12 @@ pub fn owners_for_file(run_config: &RunConfig, file_path: &str) -> error_stack:: } // Returns the highest priority owner for a file. More to come here. -pub fn file_owner_for_file(run_config: &RunConfig, file_path: &str) -> error_stack::Result, Error> { +pub fn file_owner_for_file(run_config: &RunConfig, file_path: &str) -> Result, Report> { let owners = owners_for_file(run_config, file_path)?; Ok(owners.first().cloned()) } -pub fn team_for_file(run_config: &RunConfig, file_path: &str) -> error_stack::Result, Error> { +pub fn team_for_file(run_config: &RunConfig, file_path: &str) -> Result, Report> { let owner = file_owner_for_file(run_config, file_path)?; Ok(owner.map(|fo| fo.team.clone())) } @@ -59,7 +60,7 @@ pub fn team_for_file(run_config: &RunConfig, file_path: &str) -> error_stack::Re pub fn teams_for_files_from_codeowners( run_config: &RunConfig, file_paths: &[String], -) -> error_stack::Result>, Error> { +) -> Result>, Report> { let config = config_from_run_config(run_config)?; let codeowners_file_path = super::resolve_codeowners_file_path(run_config, &config); let res = crate::ownership::codeowners_query::teams_for_files_from_codeowners( @@ -72,7 +73,7 @@ pub fn teams_for_files_from_codeowners( Ok(res) } -pub fn team_for_file_from_codeowners(run_config: &RunConfig, file_path: &str) -> error_stack::Result, Error> { +pub fn team_for_file_from_codeowners(run_config: &RunConfig, file_path: &str) -> Result, Report> { let result = teams_for_files_from_codeowners(run_config, &[file_path.to_string()])?; // Since we only passed one file, there should be exactly one result debug_assert_eq!(result.len(), 1); diff --git a/src/runner/types.rs b/src/runner/types.rs index f5e00fd..9d403c0 100644 --- a/src/runner/types.rs +++ b/src/runner/types.rs @@ -1,7 +1,6 @@ use core::fmt; use std::path::PathBuf; -use error_stack::Context; use serde::{Deserialize, Serialize}; #[derive(Debug, Default, Serialize, Deserialize)] @@ -26,7 +25,7 @@ pub enum Error { ValidationFailed, } -impl Context for Error {} +impl core::error::Error for Error {} impl fmt::Display for Error { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {