Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Write docs to standard output #655

Merged
merged 3 commits into from
Jan 4, 2025
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
59 changes: 33 additions & 26 deletions src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<String>) {
let base_path = meta.get_path()
.map(PathBuf::from)
.expect("Input file must exist in docs generation");
Expand All @@ -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<Message>, String), Message> {
Expand All @@ -285,7 +292,7 @@ impl AmberCompiler {
}
}

pub fn generate_docs(&self, output: String, usage: bool) -> Result<(), Message> {
pub fn generate_docs(&self, output: Option<String>, usage: bool) -> Result<(), Message> {
let tokens = self.tokenize()?;
let (block, mut meta) = self.parse(tokens)?;
meta.doc_usage = usage;
Expand Down
3 changes: 2 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<PathBuf>,

/// Show standard library usage in documentation
Expand Down Expand Up @@ -255,6 +255,7 @@ fn handle_docs(command: DocsCommand) -> Result<(), Box<dyn Error>> {
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) => {
Expand Down
Loading