mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-22 18:19:54 -04:00
FEATURE: Handle directories and recursing.
The build and validate commands can nor process directories and recurse if desired.
This commit is contained in:
parent
5b38e571ee
commit
3a90812d41
@ -302,7 +302,7 @@ pub struct Builder<'a> {
|
|||||||
root: PathBuf,
|
root: PathBuf,
|
||||||
curr_file: Option<&'a str>,
|
curr_file: Option<&'a str>,
|
||||||
validate_mode: bool,
|
validate_mode: bool,
|
||||||
assert_collector: AssertCollector,
|
pub assert_collector: AssertCollector,
|
||||||
env: Rc<Val>,
|
env: Rc<Val>,
|
||||||
// NOTE(jwall): We use interior mutability here because we need
|
// NOTE(jwall): We use interior mutability here because we need
|
||||||
// our asset cache to be shared by multiple different sub-builders.
|
// our asset cache to be shared by multiple different sub-builders.
|
||||||
@ -477,7 +477,6 @@ impl<'a> Builder<'a> {
|
|||||||
|
|
||||||
/// Builds a ucg file at the named path.
|
/// Builds a ucg file at the named path.
|
||||||
pub fn build_file(&mut self, name: &'a str) -> BuildResult {
|
pub fn build_file(&mut self, name: &'a str) -> BuildResult {
|
||||||
eprintln!("building ucg file {}", name);
|
|
||||||
self.curr_file = Some(name);
|
self.curr_file = Some(name);
|
||||||
let mut f = try!(File::open(name));
|
let mut f = try!(File::open(name));
|
||||||
let mut s = String::new();
|
let mut s = String::new();
|
||||||
|
201
src/main.rs
201
src/main.rs
@ -16,14 +16,15 @@ extern crate clap;
|
|||||||
extern crate ucglib;
|
extern crate ucglib;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
use std::error::Error;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::path::PathBuf;
|
use std::path::{Path, PathBuf};
|
||||||
use std::process;
|
use std::process;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use ucglib::build;
|
use ucglib::build;
|
||||||
use ucglib::build::assets::MemoryCache;
|
use ucglib::build::assets::{Cache, MemoryCache};
|
||||||
use ucglib::build::Val;
|
use ucglib::build::Val;
|
||||||
use ucglib::convert::traits;
|
use ucglib::convert::traits;
|
||||||
use ucglib::convert::ConverterRunner;
|
use ucglib::convert::ConverterRunner;
|
||||||
@ -43,11 +44,17 @@ fn do_flags<'a>() -> clap::ArgMatches<'a> {
|
|||||||
)
|
)
|
||||||
(@subcommand build =>
|
(@subcommand build =>
|
||||||
(about: "Build a list of ucg files.")
|
(about: "Build a list of ucg files.")
|
||||||
(@arg INPUT: ... +required "Input ucg files to build.")
|
(@arg recurse: -r +required conflicts_with[INPUT] "Whether we should recurse in directories or not.")
|
||||||
|
(@arg INPUT: ... "Input ucg files or directories to build. If not provided then build the contents of the current directory.")
|
||||||
)
|
)
|
||||||
(@subcommand validate =>
|
(@subcommand validate =>
|
||||||
(about: "Check a list of ucg files for errors and run assertions.")
|
(about: "Check a list of ucg files for errors and run assertions.")
|
||||||
(@arg INPUT: ... +required "Input ucg files to validate.")
|
(@arg recurse: -r +required conflicts_with[INPUT] "Whether we should recurse or not.")
|
||||||
|
(@arg INPUT: ... "Input ucg files or directories to validate. If not provided scan the director for files with _test.ucg")
|
||||||
|
)
|
||||||
|
(@subcommand converters =>
|
||||||
|
(about: "list the available converters")
|
||||||
|
(@arg name: -c --converter-name +takes_value "Optionally print help for the provided converter")
|
||||||
)
|
)
|
||||||
).get_matches()
|
).get_matches()
|
||||||
}
|
}
|
||||||
@ -65,9 +72,108 @@ fn run_converter(c: ConverterRunner, v: Rc<Val>, f: Option<&str>) -> traits::Res
|
|||||||
c.convert(v, file)
|
c.convert(v, file)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn build_file(
|
||||||
|
file: &str,
|
||||||
|
validate: bool,
|
||||||
|
cache: Rc<RefCell<Cache>>,
|
||||||
|
) -> Result<build::Builder, Box<Error>> {
|
||||||
|
let root = PathBuf::from(file);
|
||||||
|
let mut builder = build::Builder::new(root.parent().unwrap(), cache);
|
||||||
|
if validate {
|
||||||
|
builder.enable_validate_mode();
|
||||||
|
}
|
||||||
|
try!(builder.build_file(file));
|
||||||
|
if validate {
|
||||||
|
println!("{}", builder.assert_collector.summary);
|
||||||
|
}
|
||||||
|
Ok(builder)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_validate(file: &str, cache: Rc<RefCell<Cache>>) -> bool {
|
||||||
|
match build_file(file, true, cache) {
|
||||||
|
Ok(_) => println!("File {} validates", file),
|
||||||
|
Err(msg) => {
|
||||||
|
eprintln!("Err 2: {}", msg);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_compile(file: &str, cache: Rc<RefCell<Cache>>) -> bool {
|
||||||
|
println!("Building {}", file);
|
||||||
|
let builder = match build_file(file, false, cache.clone()) {
|
||||||
|
Ok(builder) => builder,
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("{:?}", err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let (typ, val) = match builder.out_lock {
|
||||||
|
Some((ref typ, ref val)) => (typ, val.clone()),
|
||||||
|
None => {
|
||||||
|
eprintln!("Build results in no value.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
match ConverterRunner::new(typ) {
|
||||||
|
Ok(converter) => {
|
||||||
|
run_converter(converter, val, Some(file)).unwrap();
|
||||||
|
eprintln!("Build successful");
|
||||||
|
process::exit(0);
|
||||||
|
}
|
||||||
|
Err(msg) => {
|
||||||
|
eprintln!("{}", msg);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_ucg_files(
|
||||||
|
path: &Path,
|
||||||
|
recurse: bool,
|
||||||
|
validate: bool,
|
||||||
|
cache: Rc<RefCell<Cache>>,
|
||||||
|
) -> Result<bool, Box<Error>> {
|
||||||
|
let our_path = String::from(path.to_string_lossy());
|
||||||
|
let mut result = true;
|
||||||
|
if path.is_dir() {
|
||||||
|
for entry in try!(std::fs::read_dir(path)) {
|
||||||
|
let next_item = try!(entry);
|
||||||
|
let next_path = next_item.path();
|
||||||
|
let path_as_string = String::from(next_path.to_string_lossy());
|
||||||
|
if next_path.is_dir() && recurse {
|
||||||
|
if let Err(msg) = visit_ucg_files(&next_path, recurse, validate, cache.clone()) {
|
||||||
|
eprintln!("Err 1: {}", msg);
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if validate && path_as_string.ends_with("_test.ucg") {
|
||||||
|
if !do_validate(&path_as_string, cache.clone()) {
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if !do_compile(&path_as_string, cache.clone()) {
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if validate && our_path.ends_with("_test.ucg") {
|
||||||
|
if !do_validate(&our_path, cache) {
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if !do_compile(&our_path, cache) {
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let app = do_flags();
|
let app = do_flags();
|
||||||
let cache = Rc::new(RefCell::new(MemoryCache::new()));
|
let cache: Rc<RefCell<Cache>> = Rc::new(RefCell::new(MemoryCache::new()));
|
||||||
if let Some(matches) = app.subcommand_matches("inspect") {
|
if let Some(matches) = app.subcommand_matches("inspect") {
|
||||||
let file = matches.value_of("INPUT").unwrap();
|
let file = matches.value_of("INPUT").unwrap();
|
||||||
let sym = matches.value_of("sym");
|
let sym = matches.value_of("sym");
|
||||||
@ -105,42 +211,65 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if let Some(matches) = app.subcommand_matches("build") {
|
} else if let Some(matches) = app.subcommand_matches("build") {
|
||||||
let files = matches.values_of("INPUT").unwrap();
|
let files = matches.values_of("INPUT");
|
||||||
for file in files {
|
let recurse = matches.is_present("recurse");
|
||||||
let root = PathBuf::from(file);
|
let mut ok = true;
|
||||||
let mut builder = build::Builder::new(root.parent().unwrap(), cache);
|
if files.is_none() {
|
||||||
let result = builder.build_file(file);
|
let curr_dir = std::env::current_dir().unwrap();
|
||||||
if !result.is_ok() {
|
let ok = visit_ucg_files(curr_dir.as_path(), recurse, false, cache.clone());
|
||||||
eprintln!("{:?}", result.err().unwrap());
|
if let Ok(false) = ok {
|
||||||
process::exit(1);
|
process::exit(1)
|
||||||
}
|
}
|
||||||
let (typ, val) = match builder.out_lock {
|
}
|
||||||
Some((ref typ, ref val)) => (typ, val.clone()),
|
for file in files.unwrap() {
|
||||||
None => {
|
let pb = PathBuf::from(file);
|
||||||
eprintln!("Build results in no value.");
|
if let Ok(false) = visit_ucg_files(&pb, recurse, false, cache.clone()) {
|
||||||
process::exit(1);
|
ok = false;
|
||||||
}
|
|
||||||
};
|
|
||||||
match ConverterRunner::new(typ) {
|
|
||||||
Ok(converter) => {
|
|
||||||
run_converter(converter, val, Some(file)).unwrap();
|
|
||||||
eprintln!("Build successful");
|
|
||||||
process::exit(0);
|
|
||||||
}
|
|
||||||
Err(msg) => {
|
|
||||||
eprintln!("{}", msg);
|
|
||||||
process::exit(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if !ok {
|
||||||
|
process::exit(1)
|
||||||
|
}
|
||||||
} else if let Some(matches) = app.subcommand_matches("validate") {
|
} else if let Some(matches) = app.subcommand_matches("validate") {
|
||||||
let files = matches.values_of("INPUT").unwrap();
|
let files = matches.values_of("INPUT");
|
||||||
let mut builder = build::Builder::new(std::env::current_dir().unwrap(), cache);
|
let recurse = matches.is_present("recurse");
|
||||||
builder.enable_validate_mode();
|
if files.is_none() {
|
||||||
for file in files {
|
let curr_dir = std::env::current_dir().unwrap();
|
||||||
builder.build_file(file).unwrap();
|
let ok = visit_ucg_files(curr_dir.as_path(), recurse, true, cache.clone());
|
||||||
println!("File Validates");
|
if let Ok(false) = ok {
|
||||||
|
process::exit(1)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let mut ok = true;
|
||||||
|
for file in files.unwrap() {
|
||||||
|
let pb = PathBuf::from(file);
|
||||||
|
if pb.is_dir() {
|
||||||
|
if let Ok(false) = visit_ucg_files(pb.as_path(), recurse, true, cache.clone()) {
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
match build_file(file, true, cache.clone()) {
|
||||||
|
Ok(b) => {
|
||||||
|
if b.assert_collector.success {
|
||||||
|
println!("File {} Validates", file);
|
||||||
|
} else {
|
||||||
|
println!("File {} Fails", file);
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(msg) => {
|
||||||
|
// We continue to process the other files despite this failure.
|
||||||
|
eprintln!("{}", msg);
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
process::exit(1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
process::exit(0);
|
process::exit(0);
|
||||||
|
} else if let Some(_todo) = app.subcommand_matches("converters") {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user