From 24b3b38b5ef929f4c2697db490c87a3b4cc98c36 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sat, 13 Feb 2021 10:44:28 +0000 Subject: resource: Remove doc comment which confuses CLI help Signed-off-by: Daniel Silverstone --- src/resource.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/resource.rs b/src/resource.rs index 6f2b33b..a03086c 100644 --- a/src/resource.rs +++ b/src/resource.rs @@ -10,11 +10,12 @@ use std::path::{Path, PathBuf}; use std::sync::Mutex; use structopt::StructOpt; +#[allow(missing_docs)] #[derive(Debug, StructOpt)] -/// Options which relate to resource management -/// -/// To use this, include them *flat* in your options struct, and then after -/// parsing, call the [ResourceOpts::handle()] function. +// Options which relate to resource management +// +// To use this, include them *flat* in your options struct, and then after +// parsing, call the [ResourceOpts::handle()] function. pub struct ResourceOpts { #[structopt( long, -- cgit v1.2.1 From d11605662b06ab6756404fab006ff91c4a251cae Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sat, 13 Feb 2021 10:44:58 +0000 Subject: CLI: Refactor out document loading Signed-off-by: Daniel Silverstone --- src/bin/cli/mod.rs | 14 ++++++++++++++ src/bin/sp-codegen.rs | 10 ++++------ src/bin/sp-docgen.rs | 7 ++++--- src/bin/sp-extract.rs | 6 +++--- src/bin/sp-meta.rs | 6 +++--- 5 files changed, 28 insertions(+), 15 deletions(-) create mode 100644 src/bin/cli/mod.rs diff --git a/src/bin/cli/mod.rs b/src/bin/cli/mod.rs new file mode 100644 index 0000000..1bb5ea3 --- /dev/null +++ b/src/bin/cli/mod.rs @@ -0,0 +1,14 @@ +//! CLI Functionality abstractions + +use anyhow::Result; +use subplot::{Document, Style}; + +use std::path::Path; + +pub fn load_document>(filename: P, style: Style) -> Result { + let filename = filename.as_ref(); + let base_path = subplot::get_basedir_from(filename)?; + let doc = Document::from_file(&base_path, filename, style)?; + + Ok(doc) +} diff --git a/src/bin/sp-codegen.rs b/src/bin/sp-codegen.rs index f83cf59..c316bea 100644 --- a/src/bin/sp-codegen.rs +++ b/src/bin/sp-codegen.rs @@ -4,16 +4,14 @@ use std::process::Command; use anyhow::Result; use structopt::StructOpt; -use subplot::{ - generate_test_program, resource, template_spec, Document, Style, SubplotError, TemplateSpec, -}; +use subplot::{generate_test_program, resource, template_spec, Style, SubplotError, TemplateSpec}; + +mod cli; fn main() -> Result<()> { let opt = Opt::from_args(); opt.resources.handle(); - let basedir = subplot::get_basedir_from(&opt.filename)?; - let style = Style::default(); - let mut doc = Document::from_file(&basedir, &opt.filename, style)?; + let mut doc = cli::load_document(&opt.filename, Style::default())?; doc.lint()?; if !doc.check_named_files_exist()? { eprintln!("Unable to continue"); diff --git a/src/bin/sp-docgen.rs b/src/bin/sp-docgen.rs index 61522ce..d633791 100644 --- a/src/bin/sp-docgen.rs +++ b/src/bin/sp-docgen.rs @@ -8,7 +8,9 @@ use structopt::StructOpt; use anyhow::Result; -use subplot::{get_basedir_from, resource, Document, Style}; +use subplot::{resource, Style}; + +mod cli; // Define the command line arguments. #[derive(Debug, StructOpt)] @@ -42,8 +44,7 @@ fn main() -> Result<()> { style.typeset_links_as_notes(); } - let basedir = get_basedir_from(first_file)?; - let mut doc = Document::from_file(&basedir, &first_file, style)?; + let mut doc = cli::load_document(&first_file, style)?; doc.lint()?; if !doc.check_named_files_exist()? { eprintln!("Continuing despite warnings"); diff --git a/src/bin/sp-extract.rs b/src/bin/sp-extract.rs index cdd9fba..9be159f 100644 --- a/src/bin/sp-extract.rs +++ b/src/bin/sp-extract.rs @@ -6,6 +6,8 @@ use structopt::StructOpt; use subplot::{DataFile, Document, Style, SubplotError}; +mod cli; + #[derive(Debug, StructOpt)] #[structopt(name = "sp-meta", about = "Show Subplot document metadata.")] struct Opt { @@ -24,9 +26,7 @@ struct Opt { fn main() -> Result<()> { let opt = Opt::from_args(); - let basedir = subplot::get_basedir_from(&opt.filename)?; - let style = Style::default(); - let doc = Document::from_file(&basedir, &opt.filename, style)?; + let doc = cli::load_document(&opt.filename, Style::default())?; for filename in opt.embedded { let file = get_embedded(&doc, &filename)?; diff --git a/src/bin/sp-meta.rs b/src/bin/sp-meta.rs index c633c59..33e6ca4 100644 --- a/src/bin/sp-meta.rs +++ b/src/bin/sp-meta.rs @@ -8,6 +8,8 @@ use structopt::StructOpt; use subplot::{Document, Style}; +mod cli; + #[derive(Debug)] enum OutputFormat { Plain, @@ -115,9 +117,7 @@ impl Metadata { fn main() -> Result<()> { let opt = Opt::from_args(); - let basedir = subplot::get_basedir_from(&opt.filename)?; - let style = Style::default(); - let mut doc = Document::from_file(&basedir, &opt.filename, style)?; + let mut doc = cli::load_document(&opt.filename, Style::default())?; let meta = Metadata::try_from(&mut doc)?; match opt.output_format { -- cgit v1.2.1 From 279c4335737667cbcf640bda799a783d14ad4b2b Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sat, 13 Feb 2021 10:52:22 +0000 Subject: sp-extract: Move file extraction Signed-off-by: Daniel Silverstone --- src/bin/cli/mod.rs | 13 ++++++++++++- src/bin/sp-extract.rs | 13 ++----------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/bin/cli/mod.rs b/src/bin/cli/mod.rs index 1bb5ea3..855a066 100644 --- a/src/bin/cli/mod.rs +++ b/src/bin/cli/mod.rs @@ -1,7 +1,9 @@ //! CLI Functionality abstractions +#![allow(unused)] + use anyhow::Result; -use subplot::{Document, Style}; +use subplot::{DataFile, Document, Style, SubplotError}; use std::path::Path; @@ -12,3 +14,12 @@ pub fn load_document>(filename: P, style: Style) -> Result(doc: &'a Document, filename: &str) -> Result<&'a DataFile> { + for file in doc.files() { + if file.filename() == filename { + return Ok(file); + } + } + Err(SubplotError::EmbeddedFileNotFound(filename.to_owned()).into()) +} diff --git a/src/bin/sp-extract.rs b/src/bin/sp-extract.rs index 9be159f..86bc15a 100644 --- a/src/bin/sp-extract.rs +++ b/src/bin/sp-extract.rs @@ -4,7 +4,7 @@ use std::path::PathBuf; use structopt::StructOpt; -use subplot::{DataFile, Document, Style, SubplotError}; +use subplot::Style; mod cli; @@ -29,19 +29,10 @@ fn main() -> Result<()> { let doc = cli::load_document(&opt.filename, Style::default())?; for filename in opt.embedded { - let file = get_embedded(&doc, &filename)?; + let file = cli::extract_file(&doc, &filename)?; let output = opt.directory.join(filename); write(output, file.contents())?; } Ok(()) } - -fn get_embedded<'a>(doc: &'a Document, filename: &str) -> Result<&'a DataFile> { - for file in doc.files() { - if file.filename() == filename { - return Ok(file); - } - } - Err(SubplotError::EmbeddedFileNotFound(filename.to_owned()).into()) -} -- cgit v1.2.1 From c01c05e6cb9199832b9067b66f757044b7493170 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sat, 13 Feb 2021 12:10:27 +0000 Subject: bin: Initial subplot binary, only implements extract Signed-off-by: Daniel Silverstone --- src/bin/subplot.rs | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 src/bin/subplot.rs diff --git a/src/bin/subplot.rs b/src/bin/subplot.rs new file mode 100644 index 0000000..38e129e --- /dev/null +++ b/src/bin/subplot.rs @@ -0,0 +1,111 @@ +//! Subplot top level binary +//! + +use anyhow::Result; + +use structopt::StructOpt; +use subplot::{resource, DataFile, Style}; + +use std::fs::write; +use std::path::PathBuf; +use std::process; + +mod cli; + +#[derive(Debug, StructOpt)] +struct Toplevel { + #[structopt(flatten)] + resources: resource::ResourceOpts, + + #[structopt(flatten)] + command: Cmd, +} + +impl Toplevel { + fn run(&self) -> Result<()> { + self.command.run() + } +} + +#[derive(Debug, StructOpt)] +enum Cmd { + Extract(Extract), +} + +impl Cmd { + fn run(&self) -> Result<()> { + match self { + Cmd::Extract(e) => e.run(), + } + } +} + +#[derive(Debug, StructOpt)] +/// Extract embedded files from a subplot document +/// +/// If no embedded filenames are provided, this will +/// extract all embedded files. if the output directory +/// is not specified then this will extract to the current directory. +struct Extract { + /// Directory to write extracted files to + #[structopt( + name = "DIR", + long = "directory", + short = "d", + parse(from_os_str), + default_value = "." + )] + directory: PathBuf, + + /// Don't actually write the files out + #[structopt(long)] + dry_run: bool, + + /// Input subplot document filename + #[structopt(parse(from_os_str))] + filename: PathBuf, + + /// Names of embedded files to be extracted. + embedded: Vec, +} + +impl Extract { + fn run(&self) -> Result<()> { + let doc = cli::load_document(&self.filename, Style::default())?; + + let files: Vec<&DataFile> = if self.embedded.is_empty() { + doc.files() + .iter() + .map(Result::Ok) + .collect::>>() + } else { + self.embedded + .iter() + .map(|filename| cli::extract_file(&doc, filename)) + .collect::>>() + }?; + + for f in files { + let outfile = self.directory.join(f.filename()); + if self.dry_run { + println!("Would write out {}", outfile.display()); + } else { + write(outfile, f.contents())? + } + } + + Ok(()) + } +} + +fn main() { + let args = Toplevel::from_args(); + args.resources.handle(); + match args.run() { + Ok(_) => {} + Err(e) => { + eprintln!("Failure: {:?}", e); + process::exit(1); + } + } +} -- cgit v1.2.1 From 316b90d5c645702336c08d1f5e7d716f993ca6a6 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sat, 27 Mar 2021 12:18:04 +0000 Subject: bin: Add filter support to subplot binary Signed-off-by: Daniel Silverstone --- src/bin/subplot.rs | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/src/bin/subplot.rs b/src/bin/subplot.rs index 38e129e..94c4b53 100644 --- a/src/bin/subplot.rs +++ b/src/bin/subplot.rs @@ -4,10 +4,11 @@ use anyhow::Result; use structopt::StructOpt; -use subplot::{resource, DataFile, Style}; +use subplot::{resource, DataFile, Document, Style}; -use std::fs::write; -use std::path::PathBuf; +use std::fs::{write, File}; +use std::io::{Read, Write}; +use std::path::{Path, PathBuf}; use std::process; mod cli; @@ -30,12 +31,14 @@ impl Toplevel { #[derive(Debug, StructOpt)] enum Cmd { Extract(Extract), + Filter(Filter), } impl Cmd { fn run(&self) -> Result<()> { match self { Cmd::Extract(e) => e.run(), + Cmd::Filter(f) => f.run(), } } } @@ -98,6 +101,55 @@ impl Extract { } } +#[derive(Debug, StructOpt)] +/// Filter a pandoc JSON document. +/// +/// This filters a pandoc JSON document, applying Subplot's formatting rules and +/// image conversion support. +/// +/// If input/output filename is provided, this operates on STDIN/STDOUT. +struct Filter { + #[structopt(name = "INPUT", long = "input", short = "i", parse(from_os_str))] + /// Input file (uses STDIN if omitted) + input: Option, + + #[structopt(name = "OUTPUT", long = "output", short = "o", parse(from_os_str))] + /// Output file (uses STDOUT if omitted) + output: Option, + + #[structopt(name = "BASE", long = "base", short = "b", parse(from_os_str))] + /// Base directory (defaults to dir of input if given, or '.' if using STDIN) + base: Option, +} + +impl Filter { + fn run(&self) -> Result<()> { + let mut buffer = String::new(); + if let Some(filename) = &self.input { + File::open(filename)?.read_to_string(&mut buffer)?; + } else { + std::io::stdin().read_to_string(&mut buffer)?; + } + let basedir = if let Some(path) = &self.base { + path.as_path() + } else if let Some(path) = &self.input { + path.parent().unwrap_or_else(|| Path::new(".")) + } else { + Path::new(".") + }; + let style = Style::default(); + let mut doc = Document::from_json(basedir, vec![], &buffer, style)?; + doc.typeset(); + let bytes = doc.ast()?.into_bytes(); + if let Some(filename) = &self.output { + File::create(filename)?.write_all(&bytes)?; + } else { + std::io::stdout().write_all(&bytes)?; + } + Ok(()) + } +} + fn main() { let args = Toplevel::from_args(); args.resources.handle(); -- cgit v1.2.1 From f49c399f1dd8c391c756776b31f13cd5473bc885 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sat, 27 Mar 2021 13:15:15 +0000 Subject: bin: Abstract metadata handling Signed-off-by: Daniel Silverstone --- src/bin/cli/mod.rs | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/bin/sp-meta.rs | 111 ++--------------------------------------------------- 2 files changed, 111 insertions(+), 108 deletions(-) diff --git a/src/bin/cli/mod.rs b/src/bin/cli/mod.rs index 855a066..f3225db 100644 --- a/src/bin/cli/mod.rs +++ b/src/bin/cli/mod.rs @@ -3,9 +3,12 @@ #![allow(unused)] use anyhow::Result; +use serde::Serialize; use subplot::{DataFile, Document, Style, SubplotError}; +use std::convert::TryFrom; use std::path::Path; +use std::str::FromStr; pub fn load_document>(filename: P, style: Style) -> Result { let filename = filename.as_ref(); @@ -23,3 +26,108 @@ pub fn extract_file<'a>(doc: &'a Document, filename: &str) -> Result<&'a DataFil } Err(SubplotError::EmbeddedFileNotFound(filename.to_owned()).into()) } + +#[derive(Serialize)] +pub struct Metadata { + sources: Vec, + title: String, + binding_files: Vec, + function_files: Vec, + bibliographies: Vec, + scenarios: Vec, + files: Vec, +} + +impl TryFrom<&mut Document> for Metadata { + type Error = subplot::SubplotError; + fn try_from(doc: &mut Document) -> std::result::Result { + let sources: Vec<_> = doc + .sources() + .into_iter() + .map(|p| filename(Some(&p))) + .collect(); + let title = doc.meta().title().to_owned(); + let binding_files = doc + .meta() + .bindings_filenames() + .into_iter() + .map(|p| filename(Some(&p))) + .collect(); + let function_files = doc + .meta() + .functions_filenames() + .into_iter() + .map(|p| filename(Some(&p))) + .collect(); + let bibliographies = doc + .meta() + .bibliographies() + .into_iter() + .map(|p| filename(Some(&p))) + .collect(); + let scenarios = doc + .scenarios()? + .into_iter() + .map(|s| s.title().to_owned()) + .collect(); + let files = doc + .files() + .iter() + .map(|f| f.filename().to_owned()) + .collect(); + Ok(Self { + sources, + title, + binding_files, + function_files, + bibliographies, + scenarios, + files, + }) + } +} + +impl Metadata { + fn write_list(v: &[String], prefix: &str) { + v.iter().for_each(|entry| println!("{}: {}", prefix, entry)) + } + + pub fn write_out(&self) { + Self::write_list(&self.sources, "source"); + println!("title: {}", self.title); + Self::write_list(&self.binding_files, "bindings"); + Self::write_list(&self.function_files, "functions"); + Self::write_list(&self.bibliographies, "bibliography"); + Self::write_list(&self.files, "file"); + Self::write_list(&self.scenarios, "scenario"); + } +} + +fn filename(name: Option<&Path>) -> String { + let path = match name { + None => return "".to_string(), + Some(x) => x, + }; + match path.to_str() { + None => "non-UTF8 filename".to_string(), + Some(x) => x.to_string(), + } +} + +#[derive(Debug)] +pub enum OutputFormat { + Plain, + Json, +} + +impl FromStr for OutputFormat { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match s.to_ascii_lowercase().as_ref() { + "plain" => Ok(OutputFormat::Plain), + "json" => Ok(OutputFormat::Json), + _ => Err(format!("Unknown output format: `{}`", s)), + } + } +} diff --git a/src/bin/sp-meta.rs b/src/bin/sp-meta.rs index 33e6ca4..b907999 100644 --- a/src/bin/sp-meta.rs +++ b/src/bin/sp-meta.rs @@ -1,32 +1,14 @@ use anyhow::Result; use std::convert::TryFrom; -use std::path::{Path, PathBuf}; -use std::str::FromStr; +use std::path::PathBuf; -use serde::Serialize; use structopt::StructOpt; -use subplot::{Document, Style}; +use subplot::Style; mod cli; -#[derive(Debug)] -enum OutputFormat { - Plain, - Json, -} - -impl FromStr for OutputFormat { - type Err = String; - - fn from_str(s: &str) -> std::result::Result { - match s.to_ascii_lowercase().as_ref() { - "plain" => Ok(OutputFormat::Plain), - "json" => Ok(OutputFormat::Json), - _ => Err(format!("Unknown output format: `{}`", s)), - } - } -} +use cli::{Metadata, OutputFormat}; #[derive(Debug, StructOpt)] #[structopt(name = "sp-meta", about = "Show Subplot document metadata.")] @@ -39,82 +21,6 @@ struct Opt { filename: PathBuf, } -#[derive(Serialize)] -struct Metadata { - sources: Vec, - title: String, - binding_files: Vec, - function_files: Vec, - bibliographies: Vec, - scenarios: Vec, - files: Vec, -} - -impl TryFrom<&mut Document> for Metadata { - type Error = subplot::SubplotError; - fn try_from(doc: &mut Document) -> std::result::Result { - let sources: Vec<_> = doc - .sources() - .into_iter() - .map(|p| filename(Some(&p))) - .collect(); - let title = doc.meta().title().to_owned(); - let binding_files = doc - .meta() - .bindings_filenames() - .into_iter() - .map(|p| filename(Some(&p))) - .collect(); - let function_files = doc - .meta() - .functions_filenames() - .into_iter() - .map(|p| filename(Some(&p))) - .collect(); - let bibliographies = doc - .meta() - .bibliographies() - .into_iter() - .map(|p| filename(Some(&p))) - .collect(); - let scenarios = doc - .scenarios()? - .into_iter() - .map(|s| s.title().to_owned()) - .collect(); - let files = doc - .files() - .iter() - .map(|f| f.filename().to_owned()) - .collect(); - Ok(Self { - sources, - title, - binding_files, - function_files, - bibliographies, - scenarios, - files, - }) - } -} - -impl Metadata { - fn write_list(v: &[String], prefix: &str) { - v.iter().for_each(|entry| println!("{}: {}", prefix, entry)) - } - - fn write_out(&self) { - Self::write_list(&self.sources, "source"); - println!("title: {}", self.title); - Self::write_list(&self.binding_files, "bindings"); - Self::write_list(&self.function_files, "functions"); - Self::write_list(&self.bibliographies, "bibliography"); - Self::write_list(&self.files, "file"); - Self::write_list(&self.scenarios, "scenario"); - } -} - fn main() -> Result<()> { let opt = Opt::from_args(); let mut doc = cli::load_document(&opt.filename, Style::default())?; @@ -127,14 +33,3 @@ fn main() -> Result<()> { Ok(()) } - -fn filename(name: Option<&Path>) -> String { - let path = match name { - None => return "".to_string(), - Some(x) => x, - }; - match path.to_str() { - None => "non-UTF8 filename".to_string(), - Some(x) => x.to_string(), - } -} -- cgit v1.2.1 From e093e297f39e2c8602ae5ac5f60ffad1158c78a0 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sat, 27 Mar 2021 13:15:27 +0000 Subject: bin: Add metadata subcommand to subplot Signed-off-by: Daniel Silverstone --- src/bin/subplot.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/bin/subplot.rs b/src/bin/subplot.rs index 94c4b53..fabb0f2 100644 --- a/src/bin/subplot.rs +++ b/src/bin/subplot.rs @@ -6,6 +6,7 @@ use anyhow::Result; use structopt::StructOpt; use subplot::{resource, DataFile, Document, Style}; +use std::convert::TryFrom; use std::fs::{write, File}; use std::io::{Read, Write}; use std::path::{Path, PathBuf}; @@ -32,6 +33,7 @@ impl Toplevel { enum Cmd { Extract(Extract), Filter(Filter), + Metadata(Metadata), } impl Cmd { @@ -39,6 +41,7 @@ impl Cmd { match self { Cmd::Extract(e) => e.run(), Cmd::Filter(f) => f.run(), + Cmd::Metadata(m) => m.run(), } } } @@ -150,6 +153,34 @@ impl Filter { } } +#[derive(Debug, StructOpt)] +/// Extract metadata about a document +/// +/// Load and process a subplot document, extracting various metadata about the +/// document. This can then render that either as a plain text report for humans, +/// or as a JSON object for further scripted processing. +struct Metadata { + /// Form that you want the output to take + #[structopt(short = "o", default_value = "plain", possible_values=&["plain", "json"])] + output_format: cli::OutputFormat, + + /// Input subplot document filename + #[structopt(parse(from_os_str))] + filename: PathBuf, +} + +impl Metadata { + fn run(&self) -> Result<()> { + let mut doc = cli::load_document(&self.filename, Style::default())?; + let meta = cli::Metadata::try_from(&mut doc)?; + match self.output_format { + cli::OutputFormat::Plain => meta.write_out(), + cli::OutputFormat::Json => println!("{}", serde_json::to_string_pretty(&meta)?), + } + Ok(()) + } +} + fn main() { let args = Toplevel::from_args(); args.resources.handle(); -- cgit v1.2.1 From 595d78b39667be7e15fb0a0b35176a98c3e550c0 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Fri, 9 Apr 2021 16:59:06 +0100 Subject: subplot: Copy in sp-docgen content Signed-off-by: Daniel Silverstone --- src/bin/subplot.rs | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 1 deletion(-) diff --git a/src/bin/subplot.rs b/src/bin/subplot.rs index fabb0f2..6e1945d 100644 --- a/src/bin/subplot.rs +++ b/src/bin/subplot.rs @@ -3,14 +3,17 @@ use anyhow::Result; +use chrono::{Local, TimeZone}; use structopt::StructOpt; use subplot::{resource, DataFile, Document, Style}; use std::convert::TryFrom; -use std::fs::{write, File}; +use std::ffi::OsString; +use std::fs::{self, write, File}; use std::io::{Read, Write}; use std::path::{Path, PathBuf}; use std::process; +use std::time::UNIX_EPOCH; mod cli; @@ -34,6 +37,7 @@ enum Cmd { Extract(Extract), Filter(Filter), Metadata(Metadata), + Docgen(Docgen), } impl Cmd { @@ -42,6 +46,7 @@ impl Cmd { Cmd::Extract(e) => e.run(), Cmd::Filter(f) => f.run(), Cmd::Metadata(m) => m.run(), + Cmd::Docgen(d) => d.run(), } } } @@ -181,6 +186,96 @@ impl Metadata { } } +#[derive(Debug, StructOpt)] +/// Typeset subplot document +/// +/// Process a subplot document and typeset it using Pandoc. +struct Docgen { + // Input Subplot document + #[structopt(parse(from_os_str))] + input: PathBuf, + + // Output document filename + #[structopt(name = "FILE", long = "--output", short = "-o", parse(from_os_str))] + output: PathBuf, + + // Set date. + #[structopt(name = "DATE", long = "--date")] + date: Option, +} + +impl Docgen { + fn run(&self) -> Result<()> { + let mut style = Style::default(); + if self.output.extension() == Some(&OsString::from("pdf")) { + style.typeset_links_as_notes(); + } + let mut doc = cli::load_document(&self.input, style)?; + doc.lint()?; + if !doc.check_named_files_exist()? { + eprintln!("Continuing despite warnings"); + } + + let mut pandoc = pandoc::new(); + // Metadata date from command line or file mtime. However, we + // can't set it directly, since we don't want to override the date + // in the actual document, if given, so we only set + // user-provided-date. Our parsing code will use that if date is + // not document metadata. + let date = if let Some(date) = self.date.clone() { + date + } else if let Some(date) = doc.meta().date() { + date.to_string() + } else { + Self::mtime_formatted(Self::mtime(&self.input)?) + }; + pandoc.add_option(pandoc::PandocOption::Meta("date".to_string(), Some(date))); + pandoc.add_option(pandoc::PandocOption::TableOfContents); + pandoc.add_option(pandoc::PandocOption::Standalone); + pandoc.add_option(pandoc::PandocOption::NumberSections); + + if Self::need_output(&mut doc, &self.output) { + doc.typeset(); + pandoc.set_input_format(pandoc::InputFormat::Json, vec![]); + pandoc.set_input(pandoc::InputKind::Pipe(doc.ast()?)); + pandoc.set_output(pandoc::OutputKind::File(self.output.clone())); + pandoc.execute()?; + } + + Ok(()) + } + + fn mtime(filename: &Path) -> Result<(u64, u32)> { + let mtime = fs::metadata(filename)?.modified()?; + let mtime = mtime.duration_since(UNIX_EPOCH)?; + Ok((mtime.as_secs(), mtime.subsec_nanos())) + } + + fn mtime_formatted(mtime: (u64, u32)) -> String { + let secs: i64 = format!("{}", mtime.0).parse().unwrap_or(0); + let dt = Local.timestamp(secs, mtime.1); + dt.format("%Y-%m-%d %H:%M").to_string() + } + + fn need_output(doc: &mut subplot::Document, output: &Path) -> bool { + let output = match Self::mtime(output) { + Err(_) => return true, + Ok(ts) => ts, + }; + + for filename in doc.sources() { + let source = match Self::mtime(&filename) { + Err(_) => return true, + Ok(ts) => ts, + }; + if source >= output { + return true; + } + } + false + } +} + fn main() { let args = Toplevel::from_args(); args.resources.handle(); -- cgit v1.2.1 From beb4a5a27862e2261c3a12257aae23990ae52a39 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Fri, 9 Apr 2021 18:09:19 +0100 Subject: subplot: Add initial Codegen code into binary Signed-off-by: Daniel Silverstone --- src/bin/subplot.rs | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/src/bin/subplot.rs b/src/bin/subplot.rs index 6e1945d..ebbdec8 100644 --- a/src/bin/subplot.rs +++ b/src/bin/subplot.rs @@ -5,14 +5,14 @@ use anyhow::Result; use chrono::{Local, TimeZone}; use structopt::StructOpt; -use subplot::{resource, DataFile, Document, Style}; +use subplot::{generate_test_program, resource, template_spec, DataFile, Document, Style}; use std::convert::TryFrom; use std::ffi::OsString; use std::fs::{self, write, File}; use std::io::{Read, Write}; use std::path::{Path, PathBuf}; -use std::process; +use std::process::{self, Command}; use std::time::UNIX_EPOCH; mod cli; @@ -38,6 +38,7 @@ enum Cmd { Filter(Filter), Metadata(Metadata), Docgen(Docgen), + Codegen(Codegen), } impl Cmd { @@ -47,6 +48,7 @@ impl Cmd { Cmd::Filter(f) => f.run(), Cmd::Metadata(m) => m.run(), Cmd::Docgen(d) => d.run(), + Cmd::Codegen(c) => c.run(), } } } @@ -276,6 +278,64 @@ impl Docgen { } } +#[derive(Debug, StructOpt)] +/// Generate test suites from Subplot documents +/// +/// This reads a subplot document, extracts the scenarios, and writes out a test +/// program capable of running the scenarios in the subplot document. +struct Codegen { + /// Input filename. + #[structopt(parse(from_os_str))] + filename: PathBuf, + + /// Write generated test program to this file. + #[structopt( + long, + short, + parse(from_os_str), + help = "Writes generated test program to FILE" + )] + output: PathBuf, + + /// Run the generated test program after writing it? + #[structopt(long, short, help = "Runs generated test program")] + run: bool, +} + +impl Codegen { + fn run(&self) -> Result<()> { + let mut doc = cli::load_document(&self.filename, Style::default())?; + doc.lint()?; + if !doc.check_named_files_exist()? { + eprintln!("Unable to continue"); + std::process::exit(1); + } + + let spec = template_spec(&doc)?; + generate_test_program(&mut doc, &spec, &self.output)?; + + if self.run { + let run = match spec.run() { + None => { + eprintln!( + "Template {} does not specify how to run suites", + spec.template_filename().display() + ); + std::process::exit(1); + } + Some(x) => x, + }; + + let status = Command::new(run).arg(&self.output).status()?; + if !status.success() { + eprintln!("Test suite failed!"); + std::process::exit(2); + } + } + Ok(()) + } +} + fn main() { let args = Toplevel::from_args(); args.resources.handle(); -- cgit v1.2.1 From 68908d369d5a8cdec182a1fa51007cdff71e68dd Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Fri, 9 Apr 2021 18:13:46 +0100 Subject: check: Update to use subplot binary Signed-off-by: Daniel Silverstone --- check | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/check b/check index 5dc60ed..6102b24 100755 --- a/check +++ b/check @@ -101,11 +101,12 @@ class Runcmd: [ "run", "--package=subplot", - "--bin=sp-codegen", + "--bin=subplot", "--", + f"--resources={os.path.abspath('share')}", + "codegen", md, f"--output={output}", - f"--resources={os.path.abspath('share')}", ], **kwargs, ) @@ -116,11 +117,12 @@ class Runcmd: [ "run", "--package=subplot", - "--bin=sp-docgen", + "--bin=subplot", "--", + f"--resources={os.path.abspath('share')}", + "docgen", md, f"--output={output}", - f"--resources={os.path.abspath('share')}", ], **kwargs, ) -- cgit v1.2.1 From 76a22e7053c8be6db3cbf1ec6cec085ba6f49898 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Fri, 9 Apr 2021 18:23:19 +0100 Subject: testing: Rework sp-{doc,code}gen into subplot {doc,code}gen in tests Signed-off-by: Daniel Silverstone --- stress | 4 +- subplot.md | 130 ++++++++++++++++++++++++++++++------------------------------- subplot.py | 6 +-- 3 files changed, 70 insertions(+), 70 deletions(-) diff --git a/stress b/stress index e70984a..acda0ed 100755 --- a/stress +++ b/stress @@ -18,11 +18,11 @@ ts() { } docgen() { - cargo run -q --bin sp-docgen -- "$1" -o "$2" + cargo run -q --bin subplot -- docgen "$1" -o "$2" } codegen() { - cargo run -q --bin sp-codegen -- "$1" -o "$2" -t templates + cargo run -q --bin subplot -- codegen "$1" -o "$2" } start="$(ts 0)" diff --git a/subplot.md b/subplot.md index 2db50f6..bc744b1 100644 --- a/subplot.md +++ b/subplot.md @@ -72,7 +72,7 @@ use, for example, LaTeX. Subplot interprets parts of the Markdown input file itself. Subplot actually consists mainly of two separate programs: -**sp-docgen** for generating output documents, and **sp-codegen** for +**subplot docgen** for generating output documents, and **subplot codegen** for generating the test program. There are a couple of additional tools (**sp-meta** for reporting meta data about a Subplot document, and **sp-filter** for doing the document generation as a Pandoc filter). @@ -90,10 +90,10 @@ bindings [shape=box]; impl [label="foo.py \n (step implemenations, Python)"] impl [shape=box]; -docgen [label="sp-docgen"]; +docgen [label="subplot docgen"]; docgen [shape=ellipse]; -codegen [label="sp-codegen"]; +codegen [label="subplot codegen"]; codegen [shape=ellipse]; pdf [label="foo.pdf \n PDF (generated)"] @@ -224,7 +224,7 @@ using itself: ~~~sh $ cargo build -q -$ cargo run --bin sp-codegen -- subplot.md -o test.py +$ cargo run --bin subplot codegen -- subplot.md -o test.py $ python3 test.py ... much output OK, all scenarios finished successfully @@ -237,7 +237,7 @@ tree: ~~~sh $ cargo build -q -$ cargo run --bin sp-codegen -- subplot.md -o test.py +$ cargo run --bin subplot codegen -- subplot.md -o test.py $ python3 test.py --env SUBPLOT_DIR=/usr/local/bin ... much output OK, all scenarios finished successfully @@ -248,7 +248,7 @@ You can do this with an installed Subplot as well: ~~~sh $ cargo clean -$ /usr/local/bin/sp-codegen subplot.md -o test.py +$ /usr/local/bin/subplot codegen subplot.md -o test.py $ python3 test.py --env SUBPLOT_DIR=/usr/local/bin ... much output OK, all scenarios finished successfully @@ -611,8 +611,8 @@ load the binding. Typically the type map is used by the code generators to, for example, distinguish between `"12"` and `12` (i.e. between a string and what should be a number). This permits the generated test suites to use native language types directly. The -`file` type, if used, must refer to an embedded file in the document; sp-docgen -will emit a warning if the file is not found, and sp-codegen will emit an error. +`file` type, if used, must refer to an embedded file in the document; subplot docgen +will emit a warning if the file is not found, and subplot codegen will emit an error. ### Embedded file name didn't match @@ -621,9 +621,9 @@ given file badfilename.md and file b.yaml and file f.py and an installed subplot -when I run sp-docgen badfilename.md -o foo.pdf +when I run subplot docgen badfilename.md -o foo.pdf then file foo.pdf exists -when I try to run sp-codegen --run badfilename.md -o test.py +when I try to run subplot codegen --run badfilename.md -o test.py then command fails ``` @@ -848,11 +848,11 @@ given file simple.md and file b.yaml and file f.py and an installed subplot -when I run sp-docgen simple.md -o simple.pdf +when I run subplot docgen simple.md -o simple.pdf then file simple.pdf exists -when I run sp-docgen simple.md -o simple.html +when I run subplot docgen simple.md -o simple.html then file simple.html exists -when I run sp-codegen --run simple.md -o test.py +when I run subplot codegen --run simple.md -o test.py then scenario "Simple" was run and step "given precondition foo" was run and step "when I do bar" was run @@ -876,9 +876,9 @@ given file allkeywords.md and file b.yaml and file f.py and an installed subplot -when I run sp-docgen allkeywords.md -o foo.pdf +when I run subplot docgen allkeywords.md -o foo.pdf then file foo.pdf exists -when I run sp-codegen --run allkeywords.md -o test.py +when I run subplot codegen --run allkeywords.md -o test.py then scenario "All keywords" was run and step "given precondition foo" was run and step "when I do bar" was run @@ -914,7 +914,7 @@ given file aliases.md and file b.yaml and file f.py and an installed subplot -when I run sp-docgen aliases.md -o aliases.html +when I run subplot docgen aliases.md -o aliases.html then file aliases.html matches regex /given<[^>]*> precondition foo/ and file aliases.html matches regex /when<[^>]*> I do bar/ and file aliases.html matches regex /and<[^>]*> I do foobar/ @@ -953,9 +953,9 @@ given file continuationmisuse.md and file b.yaml and file f.py and an installed subplot -when I run sp-docgen continuationmisuse.md -o foo.pdf +when I run subplot docgen continuationmisuse.md -o foo.pdf then file foo.pdf exists -when I try to run sp-codegen --run continuationmisuse.md -o test.py +when I try to run subplot codegen --run continuationmisuse.md -o test.py then command fails ~~~ @@ -989,11 +989,11 @@ given file emptylines.md and file b.yaml and file f.py and an installed subplot -when I run sp-docgen emptylines.md -o emptylines.pdf +when I run subplot docgen emptylines.md -o emptylines.pdf then file emptylines.pdf exists -when I run sp-docgen emptylines.md -o emptylines.html +when I run subplot docgen emptylines.md -o emptylines.html then file emptylines.html exists -when I run sp-codegen --run emptylines.md -o test.py +when I run subplot codegen --run emptylines.md -o test.py then scenario "Simple" was run and step "given precondition foo" was run and step "when I do bar" was run @@ -1086,7 +1086,7 @@ given file cleanup-success-python.md and file cleanup.yaml and file cleanup.py and an installed subplot -when I run sp-codegen --run cleanup-success-python.md -o test.py +when I run subplot codegen --run cleanup-success-python.md -o test.py then scenario "Cleanup" was run and step "given foo" was run, and then step "given bar" and cleanup for "given bar" was run, and then for "given foo" @@ -1118,7 +1118,7 @@ given file cleanup-fail-python.md and file cleanup.yaml and file cleanup.py and an installed subplot -when I try to run sp-codegen --run cleanup-fail-python.md -o test.py +when I try to run subplot codegen --run cleanup-fail-python.md -o test.py then scenario "Cleanup" was run and step "given foo" was run, and then step "given bar" and cleanup for "given bar" was run, and then for "given foo" @@ -1151,7 +1151,7 @@ given file cleanup-success-bash.md and file cleanup.yaml and file cleanup.sh and an installed subplot -when I run sp-codegen --run cleanup-success-bash.md -o test.sh +when I run subplot codegen --run cleanup-success-bash.md -o test.sh then scenario "Cleanup" was run and step "given foo" was run, and then step "given bar" and cleanup for "given bar" was run, and then for "given foo" @@ -1185,7 +1185,7 @@ given file cleanup-fail-bash.md and file cleanup.yaml and file cleanup.sh and an installed subplot -when I try to run sp-codegen --run cleanup-fail-bash.md -o test.sh +when I try to run subplot codegen --run cleanup-fail-bash.md -o test.sh then scenario "Cleanup" was run and step "given foo" was run, and then step "given bar" and cleanup for "given bar" was run, and then for "given foo" @@ -1227,7 +1227,7 @@ given file tmpdir.md and file tmpdir.yaml and file tmpdir.py and an installed subplot -when I run sp-codegen --run tmpdir.md -o test.py +when I run subplot codegen --run tmpdir.md -o test.py then command is successful and scenario "TMPDIR" was run and step "then TMPDIR is set" was run @@ -1276,7 +1276,7 @@ given file simplepattern.md and file simplepattern.yaml and file capture.py and an installed subplot -when I run sp-codegen --run simplepattern.md -o test.py +when I run subplot codegen --run simplepattern.md -o test.py then scenario "Simple pattern" was run and step "given I am Tomjon" was run and stdout contains "function got argument name as Tomjon" @@ -1320,7 +1320,7 @@ given file confusedpattern.md and file confusedpattern.yaml and file capture.py and an installed subplot -when I try to run sp-codegen --run confusedpattern.md -o test.py +when I try to run subplot codegen --run confusedpattern.md -o test.py then command fails and stderr contains "simple pattern contains regex" ~~~ @@ -1352,7 +1352,7 @@ given file confusedbutok.md and file confusedbutok.yaml and file capture.py and an installed subplot -when I run sp-codegen --run confusedbutok.md -o test.py +when I run subplot codegen --run confusedbutok.md -o test.py then command is successful ~~~ @@ -1384,7 +1384,7 @@ given file regex.md and file regex.yaml and file capture.py and an installed subplot -when I run sp-codegen --run regex.md -o test.py +when I run subplot codegen --run regex.md -o test.py then scenario "Regex" was run and step "given I am Tomjon" was run and stdout contains "function got argument name as Tomjon" @@ -1432,7 +1432,7 @@ given file values.md and file values.yaml and file values.py and an installed subplot -when I run sp-codegen values.md -o test.py +when I run subplot codegen values.md -o test.py when I run python3 test.py then command is successful ~~~ @@ -1488,7 +1488,7 @@ installation directory should be added to the PATH variable so that scenarios can invoke the scripts easily. The scenario in this section verifies that the Python test program -generated by `sp-codegen` accepts the option `--env NAME=VALUE`. +generated by `subplot codegen` accepts the option `--env NAME=VALUE`. There is currently no equivalent functionality for the generated Bash test program. Patches for that are welcome. @@ -1498,7 +1498,7 @@ given file env.md and file env.yaml and file env.py and an installed subplot -when I run sp-codegen env.md -o test.py +when I run subplot codegen env.md -o test.py when I try to run python3 test.py then command fails when I try to run python3 test.py --env FOO=foo @@ -1549,10 +1549,10 @@ given file simple.md and file b.yaml and file f.py and an installed subplot -when I run sp-docgen simple.md -o simple.pdf +when I run subplot docgen simple.md -o simple.pdf then file simple.pdf exists when I remember metadata for file simple.pdf -and I run sp-docgen simple.md -o simple.pdf +and I run subplot docgen simple.md -o simple.pdf then file simple.pdf has same metadata as before and only files simple.md, b.yaml, f.py, simple.pdf exist ~~~ @@ -1564,11 +1564,11 @@ given file simple.md and file b.yaml and file f.py and an installed subplot -when I run sp-docgen simple.md -o simple.pdf +when I run subplot docgen simple.md -o simple.pdf then file simple.pdf exists when I remember metadata for file simple.pdf and I touch file simple.md -and I run sp-docgen simple.md -o simple.pdf +and I run subplot docgen simple.md -o simple.pdf then file simple.pdf has changed from before ~~~ @@ -1579,11 +1579,11 @@ given file simple.md and file b.yaml and file f.py and an installed subplot -when I run sp-docgen simple.md -o simple.pdf +when I run subplot docgen simple.md -o simple.pdf then file simple.pdf exists when I remember metadata for file simple.pdf and I touch file f.py -and I run sp-docgen simple.md -o simple.pdf +and I run subplot docgen simple.md -o simple.pdf then file simple.pdf has changed from before ~~~ @@ -1594,11 +1594,11 @@ given file simple.md and file b.yaml and file f.py and an installed subplot -when I run sp-docgen simple.md -o simple.pdf +when I run subplot docgen simple.md -o simple.pdf then file simple.pdf exists when I remember metadata for file simple.pdf and I touch file b.yaml -and I run sp-docgen simple.md -o simple.pdf +and I run subplot docgen simple.md -o simple.pdf then file simple.pdf has changed from before ~~~ @@ -1618,7 +1618,7 @@ given file scenarioislowest.md and file b.yaml and file f.py and an installed subplot -when I run sp-codegen --run scenarioislowest.md -o test.py +when I run subplot codegen --run scenarioislowest.md -o test.py then scenario "heading 1.1.1" was run and command is successful ~~~ @@ -1648,7 +1648,7 @@ given file subisnotnewscenario.md and file b.yaml and file f.py and an installed subplot -when I run sp-codegen --run subisnotnewscenario.md -o test.py +when I run subplot codegen --run subisnotnewscenario.md -o test.py then scenario "heading 1.1a" was run and command is successful ~~~ @@ -1681,7 +1681,7 @@ given file samelevelisnewscenario.md and file b.yaml and file f.py and an installed subplot -when I run sp-codegen --run samelevelisnewscenario.md -o test.py +when I run subplot codegen --run samelevelisnewscenario.md -o test.py then scenario "heading 1.1.1" was run and scenario "heading 1.1.2" was run and command is successful @@ -1718,7 +1718,7 @@ given file higherisnewscenario.md and file b.yaml and file f.py and an installed subplot -when I run sp-codegen --run higherisnewscenario.md -o test.py +when I run subplot codegen --run higherisnewscenario.md -o test.py then scenario "heading 1.1.1" was run and scenario "heading 1.2" was run and command is successful @@ -1761,7 +1761,7 @@ ikiwiki, and ikiwiki has a different way of specifying page titles. ~~~scenario given file notitle.md and an installed subplot -when I try to run sp-docgen notitle.md -o foo.md +when I try to run subplot docgen notitle.md -o foo.md then command fails ~~~ @@ -1788,7 +1788,7 @@ then bar was done ~~~scenario given file notitle.md and an installed subplot -when I try to run sp-codegen --run notitle.md -o test.py +when I try to run subplot codegen --run notitle.md -o test.py then command fails ~~~ @@ -1803,9 +1803,9 @@ given file fancytitle.md and file b.yaml and file f.py and an installed subplot -when I try to run sp-docgen fancytitle.md -o foo.md +when I try to run subplot docgen fancytitle.md -o foo.md then command is successful -when I try to run sp-codegen fancytitle.md -o foo.md +when I try to run subplot codegen fancytitle.md -o foo.md then command is successful ~~~ @@ -1850,7 +1850,7 @@ given file twoscenarios-python.md and file b.yaml and file f.py and an installed subplot -when I run sp-codegen twoscenarios-python.md -o test.py +when I run subplot codegen twoscenarios-python.md -o test.py and I run python3 test.py on then scenario "One" was run and scenario "Two" was not run @@ -1892,7 +1892,7 @@ given file twoscenarios-bash.md and file b.yaml and file f.sh and an installed subplot -when I run sp-codegen twoscenarios-bash.md -o test.sh +when I run subplot codegen twoscenarios-bash.md -o test.sh and I run bash test.sh on then scenario "One" was run and scenario "Two" was not run @@ -1982,7 +1982,7 @@ specified. ~~~scenario given file metadate.md and an installed subplot -when I run sp-docgen metadate.md -o metadate.html +when I run subplot docgen metadate.md -o metadate.html then file metadate.html exists and file metadate.html contains "The Fabulous Title" and file metadate.html contains "Alfred Pennyworth" @@ -2009,7 +2009,7 @@ This scenario tests that the `--date` command line option is used. ~~~scenario given file dateless.md and an installed subplot -when I run sp-docgen dateless.md -o dateoption.html --date=FANCYDATE +when I run subplot docgen dateless.md -o dateoption.html --date=FANCYDATE then file dateoption.html exists and file dateoption.html contains "The Fabulous Title" and file dateoption.html contains "Alfred Pennyworth" @@ -2039,7 +2039,7 @@ modification time of the input file, and shall have the date in ISO given file dateless.md and file dateless.md has modification time 2020-02-26 07:53:17 and an installed subplot -when I run sp-docgen dateless.md -o mtime.html +when I run subplot docgen dateless.md -o mtime.html then file mtime.html exists and file mtime.html contains "The Fabulous Title" and file mtime.html contains "Alfred Pennyworth" @@ -2055,7 +2055,7 @@ missing file. ~~~scenario given file missing-binding.md and an installed subplot -when I try to run sp-docgen missing-binding.md -o foo.htmlh +when I try to run subplot docgen missing-binding.md -o foo.htmlh then command fails and stderr contains ": missing-binding.yaml:" ~~~ @@ -2076,7 +2076,7 @@ missing file. given file missing-functions.md and file b.yaml and an installed subplot -when I try to run sp-codegen --run missing-functions.md -o foo.py +when I try to run subplot codegen --run missing-functions.md -o foo.py then command fails and stderr contains ": missing-functions.py:" ~~~ @@ -2236,7 +2236,7 @@ in a subplot. ~~~scenario given file embedded.md and an installed subplot -when I run sp-docgen embedded.md -o foo.html +when I run subplot docgen embedded.md -o foo.html then file foo.html exists and file foo.html matches regex /embedded\.txt/ ~~~ @@ -2364,7 +2364,7 @@ This file does not end in a newline. ~~~scenario given file onefiletwice.md and an installed subplot -when I try to run sp-docgen onefiletwice.md -o onefiletwice.html +when I try to run subplot docgen onefiletwice.md -o onefiletwice.html then command fails and file onefiletwice.html does not exist ~~~ @@ -2389,7 +2389,7 @@ This is another embedded file, and has the same name. ~~~scenario given file casediff.md and an installed subplot -when I try to run sp-docgen casediff.md -o casediff.html +when I try to run subplot docgen casediff.md -o casediff.html then command fails and file casediff.html does not exist ~~~ @@ -2446,7 +2446,7 @@ then nothing works given file nobinding.md and file badbindings.yaml and an installed subplot -when I try to run sp-codegen --run nobinding.md -o test.py +when I try to run subplot codegen --run nobinding.md -o test.py then command fails ``` @@ -2470,7 +2470,7 @@ given a capitalised binding given file casemismatch.md and file badbindings.yaml and an installed subplot -when I try to run sp-codegen --run casemismatch.md -o test.py +when I try to run subplot codegen --run casemismatch.md -o test.py then command fails ``` @@ -2494,7 +2494,7 @@ given a binding given file twobindings.md and file badbindings.yaml and an installed subplot -when I try to run sp-codegen --run twobindings.md -o test.py +when I try to run subplot codegen --run twobindings.md -o test.py then command fails ``` @@ -2538,7 +2538,7 @@ into SVGs such as this one. ~~~pikchr arrow right 200% "Markdown" "Source" -box rad 10px "Subplot" "Document Generator" "(sp-docgen)" fit +box rad 10px "Subplot" "Document Generator" "(subplot docgen)" fit arrow right 200% "HTML+SVG/PDF" "Output" arrow <-> down 70% from last box.s box same "Pikchr" "Formatter" "(docs.rs/pikchr)" fit @@ -2781,11 +2781,11 @@ given file unknown-class-name.md and file known-class-name.md and file b.yaml and an installed subplot -when I try to run sp-docgen unknown-class-name.md -o unknown-class-name.html +when I try to run subplot docgen unknown-class-name.md -o unknown-class-name.html then command fails and file unknown-class-name.html does not exist and stderr contains "Unknown classes found in the document: foobar" -when I run sp-docgen known-class-name.md -o known-class-name.html +when I run subplot docgen known-class-name.md -o known-class-name.html then file known-class-name.html exists ~~~ diff --git a/subplot.py b/subplot.py index 975b579..40678c2 100644 --- a/subplot.py +++ b/subplot.py @@ -4,7 +4,7 @@ import shutil import tempfile -# A shell script to run the sp-codegen binary from the source directory's Rust +# A shell script to run the subplot binary from the source directory's Rust # build target directory, adding the -t option to use the source directory's # template directory. # @@ -12,7 +12,7 @@ import tempfile wrapper = """\ #!/bin/sh set -eu -exec '{srcdir}/target/debug/{prog}' "$@" --resources '{srcdir}/share' +exec '{srcdir}/target/debug/{prog}' --resources '{srcdir}/share' "$@" """ @@ -33,7 +33,7 @@ def install_subplot(ctx): # Create a "bin" directory for the wrapper. Can't put this into datadir, as # some of Subplot's scenarios make assumptions on what files exist there. bindir = ctx["bin-dir"] = tempfile.mkdtemp() - for prog in ["sp-codegen", "sp-docgen"]: + for prog in ["subplot"]: filename = os.path.join(bindir, prog) with open(filename, "w") as f: f.write(wrapper.format(prog=prog, srcdir=srcdir)) -- cgit v1.2.1 From 358b4c7ac81d4cb71406b55851e6eac0a272f2c0 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Fri, 9 Apr 2021 18:29:44 +0100 Subject: subplot.md: Use subplot metadata over sp-meta Signed-off-by: Daniel Silverstone --- subplot.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/subplot.md b/subplot.md index bc744b1..095aad5 100644 --- a/subplot.md +++ b/subplot.md @@ -74,7 +74,7 @@ input file itself. Subplot actually consists mainly of two separate programs: **subplot docgen** for generating output documents, and **subplot codegen** for generating the test program. There are a couple of additional tools -(**sp-meta** for reporting meta data about a Subplot document, and +(**subplot metadata** for reporting meta data about a Subplot document, and **sp-filter** for doing the document generation as a Pandoc filter). Thus a more detailed architecture view is shown below. @@ -2092,11 +2092,11 @@ template: python ### Extracting metadata from a document -The **sp-meta** program extracts metadata from a document. It is +The **subplot metadata** program extracts metadata from a document. It is useful to see the scenarios, for example. For example, given a document like this: -sp-meta would extract this information from the **simple.md** example: +subplot metadata would extract this information from the **simple.md** example: ~~~ title: Test scenario @@ -2105,7 +2105,7 @@ functions: f.py scenario Simple ~~~ -This scenario check sp-meta works. Note that it requires the bindings +This scenario check subplot metadata works. Note that it requires the bindings or functions files. ~~~scenario @@ -2118,7 +2118,7 @@ and file foo.bib and file bar.bib and file expected.json and an installed subplot -when I run sp-meta images.md +when I run subplot metadata images.md then stdout contains "source: images.md" and stdout contains "source: b.yaml" and stdout contains "source: other.yaml" @@ -2130,7 +2130,7 @@ and stdout contains "source: image.gif" and stdout contains "bindings: b.yaml" and stdout contains "bindings: other.yaml" and stdout contains "functions: f.py" -when I run sp-meta images.md -o json +when I run subplot metadata images.md -o json then JSON output matches expected.json ~~~ @@ -2501,12 +2501,12 @@ then command fails ### List embedded files -The `sp-meta` command lists embedded files in its output. +The `subplot metadata` command lists embedded files in its output. ~~~scenario given file two-embedded.md and an installed subplot -when I run sp-meta two-embedded.md +when I run subplot metadata two-embedded.md then stdout contains "foo.txt" and stdout contains "bar.yaml" ~~~ -- cgit v1.2.1 From bbf6d308a8c5a94a1021eeff526d1585c32a178a Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Fri, 9 Apr 2021 18:33:11 +0100 Subject: subplot.md: Use subplot extract rather than sp-extract Signed-off-by: Daniel Silverstone --- subplot.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subplot.md b/subplot.md index 095aad5..ef63b30 100644 --- a/subplot.md +++ b/subplot.md @@ -2853,13 +2853,13 @@ It does not have a YAML metadata block. ## Extract embedded files -`sp-extract` extracts embedded files from a subplot file. +`subplot extract` extracts embedded files from a subplot file. ~~~scenario given file embedded-file.md and file expected.txt and an installed subplot -when I run sp-extract embedded-file.md foo.txt -d . +when I run subplot extract embedded-file.md foo.txt -d . then files foo.txt and expected.txt match ~~~ -- cgit v1.2.1 From de9ee5afd4ec8d3a4b0835b865d7f10c3bf8bb8e Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Fri, 9 Apr 2021 18:37:19 +0100 Subject: chore: Clear some clippy lints Signed-off-by: Daniel Silverstone --- src/bindings.rs | 4 ++-- src/codegen.rs | 4 ++-- src/doc.rs | 5 ++--- src/typeset.rs | 5 +---- 4 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/bindings.rs b/src/bindings.rs index fe26690..99fd6cf 100644 --- a/src/bindings.rs +++ b/src/bindings.rs @@ -557,14 +557,14 @@ fn from_hashmap(parsed: &ParsedBinding) -> Result { regex_from_simple_pattern(pattern, parsed.regex.is_some(), &mut types)? }; - Ok(Binding::new( + Binding::new( kind, &pattern, &parsed.function, parsed.cleanup.as_deref(), parsed.case_sensitive, types, - )?) + ) } #[cfg(test)] diff --git a/src/codegen.rs b/src/codegen.rs index 91f3358..588fe1b 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -21,8 +21,8 @@ pub fn template_spec(doc: &Document) -> Result { let mut filename = PathBuf::from(template); filename.push("template"); filename.push("template.yaml"); - Ok(TemplateSpec::from_file(&filename) - .with_context(|| format!("Failed to read template file: {}", filename.display()))?) + TemplateSpec::from_file(&filename) + .with_context(|| format!("Failed to read template file: {}", filename.display())) } /// Generate a test program from a document, using a template spec. diff --git a/src/doc.rs b/src/doc.rs index c9296d2..6812915 100644 --- a/src/doc.rs +++ b/src/doc.rs @@ -317,11 +317,10 @@ impl<'a> Document { pub fn matched_scenarios(&mut self) -> Result> { let scenarios = self.scenarios()?; let bindings = self.meta().bindings(); - let vec: Result> = scenarios + scenarios .iter() .map(|scen| MatchedScenario::new(scen, bindings)) - .collect(); - Ok(vec?) + .collect() } } diff --git a/src/typeset.rs b/src/typeset.rs index a30df6f..ca257a9 100644 --- a/src/typeset.rs +++ b/src/typeset.rs @@ -92,10 +92,7 @@ fn step( } }; - let mut inlines = Vec::new(); - - inlines.push(keyword(&step)); - inlines.push(space()); + let mut inlines = vec![keyword(&step), space()]; for part in m.parts() { match part { -- cgit v1.2.1