Skip to content
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
96 changes: 33 additions & 63 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ edition = "2021"

[dependencies]
anyhow = { version = "1" }
clap = { version = "3", default-features = false, features = ["cargo", "std"] }
argh = "0.1"
argh_derive = "0.1"
git2 = { version = "0.18", default-features = false }
globset = { version = "0.4", default-features = false }
rustfmt-wrapper = { version = "0.2" }
Expand Down
71 changes: 44 additions & 27 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use anyhow::{bail, Context};
use clap::{arg, command};
use argh::FromArgs;
use rustfmt_wrapper::rustfmt;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
Expand Down Expand Up @@ -167,31 +167,48 @@ fn find_config_file() -> anyhow::Result<PathBuf> {
))
}

#[derive(FromArgs, PartialEq, Debug)]
/// Codegen - Generate Rust code from templates
struct CliArgs {
/// output file paths (glob pattern)
#[argh(positional, hidden_help)]
glob: Option<String>,

/// force overwrite existing files
#[argh(switch, short = 'f')]
force: bool,

/// output to stdout
#[argh(switch, short = 's')]
stdout: bool,

/// skip formatting output
#[argh(switch, short = 'n')]
nofmt: bool,

/// check mode - compare generated files with existing
#[argh(switch)]
check: bool,

/// verbose output
#[argh(switch, short = 'v')]
verbose: bool,
}

fn main() -> anyhow::Result<()> {
let matches = command!()
.arg(arg!([GLOB]))
.arg(arg!(-f - -force))
.arg(arg!(-s - -stdout))
.arg(arg!(-n - -nofmt))
.arg(arg!(--check))
.arg(arg!(-v - -verbose))
.get_matches();

let force = matches.is_present("force");
let stdout = matches.is_present("stdout");
let fmt_output = !matches.is_present("nofmt");
let output_path_glob = matches.value_of("GLOB");
let check = matches.is_present("check");
let verbose = matches.is_present("verbose");

if stdout && output_path_glob.is_none() {
let args: CliArgs = argh::from_env();

let fmt_output = !args.nofmt;
let output_path_glob = args.glob;

if args.stdout && output_path_glob.is_none() {
// TODO: What if the glob matches multiple files?
bail!("specify a single file to output to stdout.");
}

let glob = if let Some(output_path_glob) = output_path_glob {
let glob = if let Some(ref output_path_glob) = output_path_glob {
Some(
globset::Glob::new(output_path_glob)
globset::Glob::new(output_path_glob.as_str())
.context("failed to compile glob")?
.compile_matcher(),
)
Expand Down Expand Up @@ -255,14 +272,14 @@ fn main() -> anyhow::Result<()> {

let mut output_differences = 0;
for output_path in output_paths {
if !check {
if !args.check {
println!("generating {output_path}");
}

let context = output_pairs.get(output_path).unwrap();
let template_path = context.get("template_path").unwrap().as_str().unwrap();

if !(check || force || stdout) && is_modified(&repo, output_path)? {
if !(args.check || args.force || args.stdout) && is_modified(&repo, output_path)? {
bail!(
"{} is already modified, use `-f` to force overwrite or revert local changes.",
output_path
Expand All @@ -271,7 +288,7 @@ fn main() -> anyhow::Result<()> {

let mut output_str = generate_file(&tera, context, template_path)?;

if fmt_output || check {
if fmt_output || args.check {
output_str = rustfmt(&output_str).context("rustfmt failed")?;
}

Expand All @@ -280,13 +297,13 @@ fn main() -> anyhow::Result<()> {
let output_dir = full_output_path.parent().unwrap();
std::fs::create_dir_all(output_dir)?;

if check {
if args.check {
match std::fs::read_to_string(&full_output_path) {
Ok(original_str) => {
if output_str != original_str {
println!("'{output_path}' is different");
output_differences += 1;
} else if verbose {
} else if args.verbose {
println!("'{output_path}' is the same");
}
}
Expand All @@ -298,7 +315,7 @@ fn main() -> anyhow::Result<()> {
continue;
}

if stdout {
if args.stdout {
print!("{output_str}");
continue;
}
Expand All @@ -307,7 +324,7 @@ fn main() -> anyhow::Result<()> {
.with_context(|| format!("failed to write {}", full_output_path.display()))?;
}

if check && output_differences > 0 {
if args.check && output_differences > 0 {
bail!("{output_differences} files were different");
}

Expand Down
Loading