diff --git a/lychee-bin/tests/cli.rs b/lychee-bin/tests/cli.rs index 636d5eebe9..5377e0e09a 100644 --- a/lychee-bin/tests/cli.rs +++ b/lychee-bin/tests/cli.rs @@ -2546,12 +2546,12 @@ mod cli { fn test_index_files_specified() { let input = fixtures_path().join("filechecker/dir_links.md"); - // passing `--index-files index.html` should reject all links + // passing `--index-files index.html,index.htm` should reject all links // to /empty_dir because it doesn't have the index file let result = main_command() - .arg(input) + .arg(&input) .arg("--index-files") - .arg("index.html") + .arg("index.html,index.htm") .arg("--verbose") .assert() .failure(); @@ -2561,7 +2561,18 @@ mod cli { result .stdout(contains("Cannot find index file").count(empty_dir_links)) .stdout(contains("/empty_dir").count(empty_dir_links)) + .stdout(contains("(index.html, or index.htm)").count(empty_dir_links)) .stdout(contains(format!("{index_dir_links} OK"))); + + // within the error message, formatting of the index file name list should + // omit empty names. + main_command() + .arg(&input) + .arg("--index-files") + .arg(",index.html,,,index.htm,") + .assert() + .failure() + .stdout(contains("(index.html, or index.htm)").count(empty_dir_links)); } #[test] @@ -2601,7 +2612,7 @@ mod cli { // passing an empty list to --index-files should reject /all/ // directory links. let result = main_command() - .arg(input) + .arg(&input) .arg("--index-files") .arg("") .assert() @@ -2610,6 +2621,17 @@ mod cli { let num_dir_links = 4; result .stdout(contains("Cannot find index file").count(num_dir_links)) + .stdout(contains("No directory links are allowed").count(num_dir_links)) + .stdout(contains("0 OK")); + + // ... as should passing a number of empty index file names + main_command() + .arg(&input) + .arg("--index-files") + .arg(",,,,,") + .assert() + .failure() + .stdout(contains("No directory links are allowed").count(num_dir_links)) .stdout(contains("0 OK")); } diff --git a/lychee-lib/src/checker/file.rs b/lychee-lib/src/checker/file.rs index 7a1deb97b4..122eadf7f8 100644 --- a/lychee-lib/src/checker/file.rs +++ b/lychee-lib/src/checker/file.rs @@ -229,6 +229,15 @@ impl FileChecker { None => &[".".to_owned()], }; + let invalid_index_error = || { + // Drop empty index file names. These will never be accepted as valid + // index files, and doing this makes cleaner error reporting. + let mut names = index_names_to_try.to_vec(); + names.retain(|x| !x.is_empty()); + + ErrorKind::InvalidIndexFile(names) + }; + index_names_to_try .iter() .find_map(|filename| { @@ -242,7 +251,7 @@ impl FileChecker { let path = dir_path.join(filename); exists(&path).then_some(path) }) - .ok_or_else(|| ErrorKind::InvalidIndexFile(dir_path.to_path_buf())) + .ok_or_else(invalid_index_error) } /// Checks a resolved file, optionally verifying fragments for HTML files. diff --git a/lychee-lib/src/types/error.rs b/lychee-lib/src/types/error.rs index 30019b9bc2..66ad178d3d 100644 --- a/lychee-lib/src/types/error.rs +++ b/lychee-lib/src/types/error.rs @@ -70,9 +70,9 @@ pub enum ErrorKind { #[error("Cannot find fragment")] InvalidFragment(Uri), - /// The given directory is missing a required index file + /// Cannot resolve local directory link using the configured index files #[error("Cannot find index file within directory")] - InvalidIndexFile(PathBuf), + InvalidIndexFile(Vec), /// The given path cannot be converted to a URI #[error("Invalid path to URL conversion: {0}")] @@ -330,9 +330,11 @@ impl ErrorKind { ErrorKind::StatusCodeSelectorError(status_code_selector_error) => Some(format!( "Status code selector error: {status_code_selector_error}. Check accept configuration", )), - ErrorKind::InvalidIndexFile(_path) => Some( - "Index file not found in directory. Check if index.html or other index files exist".to_string() - ), + ErrorKind::InvalidIndexFile(index_files) => match &index_files[..] { + [] => "No directory links are allowed because index_files is defined and empty".to_string(), + [name] => format!("An index file ({name}) is required"), + [init @ .., tail] => format!("An index file ({}, or {}) is required", init.join(", "), tail), + }.into() } }