From c337d1d59526fb8dfe569d49bfd355c64bbf07eb Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Mon, 8 Jun 2020 08:00:28 +0300 Subject: test(files): add binding and function for comparing file contents This will be used soon by a program to extract data files from subplots, but I expect it to be more generally useful in the future. --- files.py | 9 +++++++++ files.yaml | 3 +++ 2 files changed, 12 insertions(+) diff --git a/files.py b/files.py index 9ee1739..1a7451f 100644 --- a/files.py +++ b/files.py @@ -50,6 +50,15 @@ def file_matches(ctx, filename=None, regex=None): assert_eq(bool(m), True) +# Check that two files have the same content +def files_match(ctx, filename1=None, filename2=None): + with open(filename1, "rb") as f: + data1 = f.read() + with open(filename2, "rb") as f: + data2 = f.read() + assert_eq(data1, data2) + + # Check that a file contains a fixed string. def file_contains(ctx, filename=None, pattern=None): with open(filename) as f: diff --git a/files.yaml b/files.yaml index 2cc53e1..4fc44ac 100644 --- a/files.yaml +++ b/files.yaml @@ -21,6 +21,9 @@ function: file_matches regex: true +- then: files {filename1} and {filename2} match + function: files_match + - then: file (?P\S+) contains "(?P.+)" function: file_contains regex: true -- cgit v1.2.1 From 163ec445c2474698ba073333c11140be6bb4fddc Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Mon, 8 Jun 2020 07:59:03 +0300 Subject: refactor: export DataFile so programs can use embedded files This will be used soon by a program to extract data files from subplots, but I expect it to be more generally useful in the future. --- src/ast.rs | 2 ++ src/lib.rs | 1 + 2 files changed, 3 insertions(+) diff --git a/src/ast.rs b/src/ast.rs index bc3547d..a10707a 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -980,10 +980,12 @@ impl DataFile { DataFile { filename, contents } } + /// Return name of embedded file. pub fn filename(&self) -> &str { &self.filename } + /// Return contents of embedded file. pub fn contents(&self) -> &str { &self.contents } diff --git a/src/lib.rs b/src/lib.rs index d717a36..c2a2ec7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,6 +14,7 @@ pub use graphmarkup::{DotMarkup, GraphMarkup, PlantumlMarkup}; mod ast; pub use ast::get_basedir_from; +pub use ast::DataFile; pub use ast::Document; mod scenarios; -- cgit v1.2.1 From b16749ca50ced58631e79aadf0f74152c24435de Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Mon, 8 Jun 2020 07:58:46 +0300 Subject: feat: add sp-extract for extracting data files from subplots --- src/bin/sp-extract.rs | 46 ++++++++++++++++++++++++++++++++++++++++++++++ src/error.rs | 4 ++++ subplot.md | 29 ++++++++++++++++++++++++++++- subplot.py | 6 ++++++ subplot.yaml | 3 +++ 5 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 src/bin/sp-extract.rs diff --git a/src/bin/sp-extract.rs b/src/bin/sp-extract.rs new file mode 100644 index 0000000..d63fa0a --- /dev/null +++ b/src/bin/sp-extract.rs @@ -0,0 +1,46 @@ +use anyhow::Result; +use std::fs::write; +use std::path::PathBuf; + +use structopt::StructOpt; + +use subplot::{DataFile, Document, SubplotError}; + +#[derive(Debug, StructOpt)] +#[structopt(name = "sp-meta", about = "Show Subplot document metadata.")] +struct Opt { + /// Input subplot document filename + #[structopt(parse(from_os_str))] + filename: PathBuf, + + /// Names of embedded files to be extracted. + #[structopt()] + embedded: Vec, + + // Set output directory. + #[structopt(name = "DIR", long = "--directory", short = "-o", parse(from_os_str))] + directory: PathBuf, +} + +fn main() -> Result<()> { + let opt = Opt::from_args(); + let basedir = subplot::get_basedir_from(&opt.filename)?; + let doc = Document::from_file(&basedir, &opt.filename)?; + + for filename in opt.embedded { + let file = get_embedded(&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()) +} diff --git a/src/error.rs b/src/error.rs index f988c86..1f4fcc7 100644 --- a/src/error.rs +++ b/src/error.rs @@ -187,6 +187,10 @@ pub enum SubplotError { #[error("template.yaml does not specify how to run generated program")] TemplateNoRun, + /// An embedded file was not found. + #[error("emedded file {0} was not found in the subplot document")] + EmbeddedFileNotFound(String), + /// I/O error /// /// Subplot did some I/O, and it failed. This is a generic wrapper diff --git a/subplot.md b/subplot.md index b2cdecf..e0a31b2 100644 --- a/subplot.md +++ b/subplot.md @@ -2093,8 +2093,35 @@ It does not have a YAML metadata block. ~~~~~~~~ +# Extract embedded files + +`sp-extract` extracts embedded files from a subplot file. + +~~~scenario +given file embedded-file.md +and file expected.txt +when I run sp-extract embedded-file.md foo.txt -d . +then files foo.txt and expected.txt match +~~~ + +~~~~~~{#embedded-file.md .file .markdown .numberLines} +--- +title: Embedded file +... + +~~~{#foo.txt .file} +This is a test file. +~~~ + +~~~~~~ + +~~~{#expected.txt .file} +This is a test file. +~~~ + + + - --- title: "Subplot" author: The Subplot project diff --git a/subplot.py b/subplot.py index fa3d502..1bb42d7 100644 --- a/subplot.py +++ b/subplot.py @@ -61,6 +61,12 @@ def run_meta_json(ctx, filename=None): exit_code_is(ctx, 0) +def run_extract(ctx, filename=None, embedded=None, dirname=None): + extract = binary("sp-extract") + runcmd(ctx, [extract, filename, embedded, "-o", dirname]) + exit_code_is(ctx, 0) + + def run_pandoc_with_filter(ctx, filename=None, output=None): sp_filter = binary("sp-filter") runcmd(ctx, ["pandoc", "--filter", sp_filter, filename, "-o", output]) diff --git a/subplot.yaml b/subplot.yaml index 84e52e4..0b63302 100644 --- a/subplot.yaml +++ b/subplot.yaml @@ -28,6 +28,9 @@ - when: I run sp-meta {filename} -o json function: run_meta_json +- when: I run sp-extract {filename} {embedded} -d {dirname} + function: run_extract + - when: I run pandoc --filter sp-filter {filename} -o {output} function: run_pandoc_with_filter -- cgit v1.2.1 From 5ad766749a214a0ce0b320258d16fb5a74fa81b6 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Sat, 20 Jun 2020 11:38:16 +0000 Subject: Apply 1 suggestion(s) to 1 file(s) --- src/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/error.rs b/src/error.rs index 1f4fcc7..2a94397 100644 --- a/src/error.rs +++ b/src/error.rs @@ -188,7 +188,7 @@ pub enum SubplotError { TemplateNoRun, /// An embedded file was not found. - #[error("emedded file {0} was not found in the subplot document")] + #[error("embedded file {0} was not found in the subplot document")] EmbeddedFileNotFound(String), /// I/O error -- cgit v1.2.1