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