Add support for dumping links to file (#810)

This commit is contained in:
Matthias 2022-11-08 00:33:16 +01:00 committed by GitHub
parent 5ebb3fff6e
commit 35ccfb87c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 70 additions and 6 deletions

View file

@ -1,12 +1,32 @@
use lychee_lib::Request;
use lychee_lib::Result;
use std::fs;
use std::io::{self, Write};
use std::path::PathBuf;
use tokio_stream::StreamExt;
use crate::ExitCode;
use super::CommandParams;
// Helper function to create an output writer.
//
// If the output file is not specified, it will use `stdout`.
//
// # Errors
//
// If the output file cannot be opened, an error is returned.
fn create_writer(output: Option<PathBuf>) -> Result<Box<dyn Write>> {
let out = if let Some(output) = output {
let out = fs::OpenOptions::new().append(true).open(output)?;
Box::new(out) as Box<dyn Write>
} else {
let out = io::stdout();
Box::new(out.lock()) as Box<dyn Write>
};
Ok(out)
}
/// Dump all detected links to stdout without checking them
pub(crate) async fn dump<S>(params: CommandParams<S>) -> Result<ExitCode>
where
@ -15,6 +35,12 @@ where
let requests = params.requests;
tokio::pin!(requests);
if let Some(outfile) = &params.cfg.output {
fs::File::create(outfile)?;
}
let mut writer = create_writer(params.cfg.output)?;
while let Some(request) = requests.next().await {
let mut request = request?;
@ -32,7 +58,7 @@ where
if excluded && !verbose {
continue;
}
if let Err(e) = write(&request, verbose, excluded) {
if let Err(e) = write(&mut writer, &request, verbose, excluded) {
if e.kind() != io::ErrorKind::BrokenPipe {
eprintln!("{e}");
return Ok(ExitCode::UnexpectedFailure);
@ -44,7 +70,12 @@ where
}
/// Dump request to stdout
fn write(request: &Request, verbose: bool, excluded: bool) -> io::Result<()> {
fn write(
writer: &mut Box<dyn Write>,
request: &Request,
verbose: bool,
excluded: bool,
) -> io::Result<()> {
let request = if verbose {
// Only print source in verbose mode. This way the normal link output
// can be fed into another tool without data mangling.
@ -52,9 +83,17 @@ fn write(request: &Request, verbose: bool, excluded: bool) -> io::Result<()> {
} else {
request.uri.to_string()
};
if excluded {
writeln!(io::stdout(), "{} [excluded]", request)
// Mark excluded links
let out_str = if excluded {
format!("{request} [excluded]")
} else {
writeln!(io::stdout(), "{}", request)
}
request
};
write_out(writer, &out_str)
}
fn write_out(writer: &mut Box<dyn Write>, out_str: &str) -> io::Result<()> {
writeln!(writer, "{}", out_str)
}

View file

@ -449,6 +449,31 @@ mod cli {
Ok(())
}
/// Test writing output of `--dump` command to file
#[test]
fn test_dump_to_file() -> Result<()> {
let mut cmd = main_command();
let test_path = fixtures_path().join("TEST.md");
let outfile = format!("{}", Uuid::new_v4());
cmd.arg("--output")
.arg(&outfile)
.arg("--dump")
.arg(test_path)
.assert()
.success();
let output = fs::read_to_string(&outfile)?;
// We expect 11 links in the test file
// Running the command from the command line will print 9 links,
// because the actual `--dump` command filters out the two
// http(s)://example.com links
assert_eq!(output.lines().count(), 11);
fs::remove_file(outfile)?;
Ok(())
}
/// Test excludes
#[test]
fn test_exclude_wildcard() -> Result<()> {