From 563aef8f1fb59803e00b320c18a28d63a0efad50 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Thu, 12 Dec 2024 13:30:09 -0800 Subject: [PATCH] Move root dir check --- lychee-bin/src/main.rs | 8 +----- lychee-lib/src/collector.rs | 48 +++++++++++++++++++++-------------- lychee-lib/src/types/error.rs | 5 ++++ 3 files changed, 35 insertions(+), 26 deletions(-) diff --git a/lychee-bin/src/main.rs b/lychee-bin/src/main.rs index 8c9635b2b2..521a9b8eef 100644 --- a/lychee-bin/src/main.rs +++ b/lychee-bin/src/main.rs @@ -288,13 +288,7 @@ fn underlying_io_error_kind(error: &Error) -> Option { async fn run(opts: &LycheeOptions) -> Result { let inputs = opts.inputs()?; - if let Some(root_dir) = &opts.config.root_dir { - if root_dir.is_relative() { - bail!("`--root_dir` must be an absolute path"); - } - } - - let mut collector = Collector::new(opts.config.root_dir.clone(), opts.config.base.clone()) + let mut collector = Collector::new(opts.config.root_dir.clone(), opts.config.base.clone())? .skip_missing_inputs(opts.config.skip_missing) .skip_hidden(!opts.config.hidden) .skip_ignored(!opts.config.no_ignore) diff --git a/lychee-lib/src/collector.rs b/lychee-lib/src/collector.rs index cd07af9da1..1021df9f5d 100644 --- a/lychee-lib/src/collector.rs +++ b/lychee-lib/src/collector.rs @@ -1,3 +1,4 @@ +use crate::ErrorKind; use crate::InputSource; use crate::{ basic_auth::BasicAuthExtractor, extract::Extractor, types::uri::raw::RawUri, utils::request, @@ -43,9 +44,18 @@ impl Default for Collector { impl Collector { /// Create a new collector with an empty cache + /// + /// # Errors + /// + /// Returns an `Err` if the root_dir is not an absolute path #[must_use] - pub const fn new(root_dir: Option, base: Option) -> Self { - Collector { + pub fn new(root_dir: Option, base: Option) -> Result { + if let Some(root_dir) = &root_dir { + if root_dir.is_relative() { + return Err(ErrorKind::RootDirMustBeAbsolute(root_dir.clone())); + } + } + Ok(Collector { basic_auth_extractor: None, skip_missing_inputs: false, include_verbatim: false, @@ -54,7 +64,7 @@ impl Collector { skip_ignored: true, root_dir, base, - } + }) } /// Skip missing input files (default is to error if they don't exist) @@ -177,9 +187,9 @@ mod tests { inputs: Vec, root_dir: Option, base: Option, - ) -> HashSet { - let responses = Collector::new(root_dir, base).collect_links(inputs); - responses.map(|r| r.unwrap().uri).collect().await + ) -> Result> { + let responses = Collector::new(root_dir, base)?.collect_links(inputs); + Ok(responses.map(|r| r.unwrap().uri).collect().await) } // Helper function for collecting verbatim links @@ -187,11 +197,11 @@ mod tests { inputs: Vec, root_dir: Option, base: Option, - ) -> HashSet { - let responses = Collector::new(root_dir, base) + ) -> Result> { + let responses = Collector::new(root_dir, base)? .include_verbatim(true) .collect_links(inputs); - responses.map(|r| r.unwrap().uri).collect().await + Ok(responses.map(|r| r.unwrap().uri).collect().await) } const TEST_STRING: &str = "http://test-string.com"; @@ -279,7 +289,7 @@ mod tests { }, ]; - let links = collect_verbatim(inputs, None, None).await; + let links = collect_verbatim(inputs, None, None).await.ok().unwrap(); let expected_links = HashSet::from_iter([ website(TEST_STRING), @@ -302,7 +312,7 @@ mod tests { file_type_hint: Some(FileType::Markdown), excluded_paths: None, }; - let links = collect(vec![input], None, Some(base)).await; + let links = collect(vec![input], None, Some(base)).await.ok().unwrap(); let expected_links = HashSet::from_iter([ website("https://endler.dev"), @@ -328,7 +338,7 @@ mod tests { file_type_hint: Some(FileType::Html), excluded_paths: None, }; - let links = collect(vec![input], None, Some(base)).await; + let links = collect(vec![input], None, Some(base)).await.ok().unwrap(); let expected_links = HashSet::from_iter([ website("https://github.com/lycheeverse/lychee/"), @@ -357,7 +367,7 @@ mod tests { file_type_hint: Some(FileType::Html), excluded_paths: None, }; - let links = collect(vec![input], None, Some(base)).await; + let links = collect(vec![input], None, Some(base)).await.ok().unwrap(); let expected_links = HashSet::from_iter([ website("https://example.com/static/image.png"), @@ -384,7 +394,7 @@ mod tests { excluded_paths: None, }; - let links = collect(vec![input], None, Some(base)).await; + let links = collect(vec![input], None, Some(base)).await.ok().unwrap(); let expected = HashSet::from_iter([ website("https://localhost.com/@/internal.md"), @@ -406,7 +416,7 @@ mod tests { file_type_hint: Some(FileType::Html), excluded_paths: None, }; - let links = collect(vec![input], None, Some(base)).await; + let links = collect(vec![input], None, Some(base)).await.ok().unwrap(); let expected_links = HashSet::from_iter([ // the body links wouldn't be present if the file was parsed strictly as XML @@ -439,7 +449,7 @@ mod tests { excluded_paths: None, }; - let links = collect(vec![input], None, None).await; + let links = collect(vec![input], None, None).await.ok().unwrap(); let expected_urls = HashSet::from_iter([ website("https://github.com/lycheeverse/lychee/"), @@ -458,7 +468,7 @@ mod tests { file_type_hint: None, excluded_paths: None, }; - let links = collect(vec![input], None, None).await; + let links = collect(vec![input], None, None).await.ok().unwrap(); let expected_links = HashSet::from_iter([mail("user@example.com")]); @@ -501,7 +511,7 @@ mod tests { }, ]; - let links = collect(inputs, None, None).await; + let links = collect(inputs, None, None).await.ok().unwrap(); let expected_links = HashSet::from_iter([ website(&format!( @@ -535,7 +545,7 @@ mod tests { excluded_paths: None, }; - let links = collect(vec![input], None, Some(base)).await; + let links = collect(vec![input], None, Some(base)).await.ok().unwrap(); let expected_links = HashSet::from_iter([ path("/path/to/root/index.html"), diff --git a/lychee-lib/src/types/error.rs b/lychee-lib/src/types/error.rs index 7246fe7e84..cbcfefe5e9 100644 --- a/lychee-lib/src/types/error.rs +++ b/lychee-lib/src/types/error.rs @@ -94,6 +94,10 @@ pub enum ErrorKind { #[error("Cannot convert path '{0}' to a URI")] InvalidPathToUri(String), + /// Root dir must be an absolute path + #[error("Root dir must be an absolute path: '{0}'")] + RootDirMustBeAbsolute(PathBuf), + /// The given URI type is not supported #[error("Unsupported URI type: '{0}'")] UnsupportedUriType(String), @@ -310,6 +314,7 @@ impl Hash for ErrorKind { Self::InvalidBase(base, e) => (base, e).hash(state), Self::InvalidBaseJoin(s) => s.hash(state), Self::InvalidPathToUri(s) => s.hash(state), + Self::RootDirMustBeAbsolute(s) => s.hash(state), Self::UnsupportedUriType(s) => s.hash(state), Self::InvalidUrlRemap(remap) => (remap).hash(state), Self::InvalidHeader(e) => e.to_string().hash(state),