Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions lychee-bin/tests/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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]
Expand Down Expand Up @@ -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()
Expand All @@ -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"));
}

Expand Down
11 changes: 10 additions & 1 deletion lychee-lib/src/checker/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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| {
Expand All @@ -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.
Expand Down
12 changes: 7 additions & 5 deletions lychee-lib/src/types/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<String>),

/// The given path cannot be converted to a URI
#[error("Invalid path to URL conversion: {0}")]
Expand Down Expand Up @@ -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),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had no clue you could do init @ ..

}.into()
}
}

Expand Down