From 0f05af9070709ef807e5d316d5e44e8160cbfe43 Mon Sep 17 00:00:00 2001 From: Huw Walters Date: Sat, 4 Jan 2025 21:54:43 +0000 Subject: [PATCH] Write docs to standard output (#655) * Write docs to stdout with target "-". * Minor refactoring. * Make Clippy happy. --- src/compiler.rs | 59 +++++++++++++++++++++++++++---------------------- src/main.rs | 3 ++- 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/src/compiler.rs b/src/compiler.rs index bb1204fc..aceebbb6 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -9,11 +9,13 @@ use postprocessor::PostProcessor; use chrono::prelude::*; use colored::Colorize; use heraclitus_compiler::prelude::*; +use itertools::Itertools; use wildmatch::WildMatchPattern; use std::env; use std::fs; use std::fs::File; use std::io::{ErrorKind, Write}; +use std::iter::once; use std::path::PathBuf; use std::process::{Command, ExitStatus}; use std::time::Instant; @@ -203,7 +205,7 @@ impl AmberCompiler { Ok(format!("{}{}", header, result)) } - pub fn document(&self, block: Block, meta: ParserMetadata, output: String) { + pub fn document(&self, block: Block, meta: ParserMetadata, output: Option) { let base_path = meta.get_path() .map(PathBuf::from) .expect("Input file must exist in docs generation"); @@ -227,38 +229,43 @@ impl AmberCompiler { Ok(path) => path, Err(_) => continue, }; - if !dep_path.starts_with(&base_dir) { continue; } - dep_path }; let document = block.document(&meta); - // Save to file; replace the base directory if the output - // path is absolute, otherwise append the output path. - let dir_path = { - let file_path = dep_path.strip_prefix(&base_dir).unwrap(); - let file_dir = file_path.parent().unwrap(); - base_dir.join(&output).join(file_dir) - }; - if let Err(err) = fs::create_dir_all(dir_path.clone()) { - Message::new_err_msg(format!( - "Couldn't create directory `{}`. Do you have sufficient permissions?", dir_path.display() - )) - .comment(err.to_string()) - .show(); - std::process::exit(1); + // Check if an output directory was specified. + if let Some(output) = &output { + // Save to file; replace the base directory if the output + // path is absolute, otherwise append the output path. + let dir_path = { + let file_path = dep_path.strip_prefix(&base_dir).unwrap(); + let file_dir = file_path.parent().unwrap(); + base_dir.join(output).join(file_dir) + }; + if let Err(err) = fs::create_dir_all(dir_path.clone()) { + let message = format!("Couldn't create directory `{}`. Do you have sufficient permissions?", dir_path.display()); + Message::new_err_msg(message) + .comment(err.to_string()) + .show(); + std::process::exit(1); + } + let filename = dep_path.file_stem().unwrap().to_string_lossy(); + let path = dir_path.join(format!("{filename}.md")); + let mut file = File::create(path.clone()).unwrap(); + file.write_all(document.as_bytes()).unwrap(); + paths.push(String::from(path.to_string_lossy())); + } else { + // Write to standard output. + std::io::stdout().write_all(document.as_bytes()).unwrap(); } - let filename = dep_path.file_stem().unwrap().to_string_lossy(); - let path = dir_path.join(format!("{filename}.md")); - let mut file = File::create(path.clone()).unwrap(); - file.write_all(document.as_bytes()).unwrap(); - paths.push(String::from(path.to_string_lossy())); } - let file_text = if paths.len() > 1 { "Files" } else { "File" }; - Message::new_info_msg(format!("{file_text} generated at:\n{}", paths.join("\n"))) - .show(); + if !paths.is_empty() { + let files = if paths.len() > 1 { "Files" } else { "File" }; + let message = once(format!("{files} generated at:")).chain(paths).join("\n"); + Message::new_info_msg(message).show(); + } } pub fn compile(&self) -> Result<(Vec, String), Message> { @@ -285,7 +292,7 @@ impl AmberCompiler { } } - pub fn generate_docs(&self, output: String, usage: bool) -> Result<(), Message> { + pub fn generate_docs(&self, output: Option, usage: bool) -> Result<(), Message> { let tokens = self.tokenize()?; let (block, mut meta) = self.parse(tokens)?; meta.doc_usage = usage; diff --git a/src/main.rs b/src/main.rs index 3b8b591d..cf3d90a8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -118,7 +118,7 @@ struct DocsCommand { /// Input filename ('-' to read from stdin) input: PathBuf, - /// Output directory (relative to input file, default 'docs') + /// Output directory (relative to input file, default 'docs', '-' to write to stdout) output: Option, /// Show standard library usage in documentation @@ -255,6 +255,7 @@ fn handle_docs(command: DocsCommand) -> Result<(), Box> { let compiler = AmberCompiler::new(code, Some(input), options); let output = command.output.unwrap_or_else(|| PathBuf::from("docs")); let output = output.to_string_lossy().to_string(); + let output = if output != "-" { Some(output) } else { None }; match compiler.generate_docs(output, command.usage) { Ok(_) => Ok(()), Err(err) => {