use std::path::{Path, PathBuf};
use clap::Args as ClapArgs;
use mf2_build::{Build, Config};
use crate::FeatureArgs;
use crate::cargo::resolved_features;
use crate::error::{Error, Result};
#[derive(Debug, ClapArgs)]
pub(crate) struct Args {
#[command(flatten)]
features: FeatureArgs,
#[arg(long, short, value_name = "DIR", default_value = "dist")]
out: PathBuf,
#[arg(long, value_name = "DIR", conflicts_with = "out")]
site: Option<PathBuf>,
#[arg(long, value_name = "PATH", default_value = "::mf2")]
facade: String,
#[arg(long, short)]
verbose: bool,
}
pub(crate) fn run(dir: &Path, args: &Args) -> Result<()> {
let config = Config::load(dir)?;
let features = match &args.site {
Some(_) => site_features(dir, &args.features)?,
None => args.features.features(),
};
let build = Build::at(dir, &args.out)
.config(config)
.features(features)
.facade(&args.facade);
let outcome = if args.site.is_some() {
build.check()?
} else {
build.run()?
};
print!("{}", outcome.report.to_text());
if !outcome.report.is_clean() {
return Err(Error::Corpus);
}
let (to, written, removed) = match &args.site {
Some(site) => {
let published = outcome.publish(site)?;
(site, published.written, published.removed)
}
None => (&args.out, outcome.written.clone(), outcome.removed.clone()),
};
if args.verbose {
for path in &written {
println!("{}", path.display());
}
for path in &removed {
println!("removed {}", path.display());
}
}
println!(
"mf2 compile: {} messages, {} locales to {} ({} file(s) changed)",
outcome.manifest.ids.len(),
outcome.locales.len(),
to.display(),
written.len()
);
Ok(())
}
fn site_features(dir: &Path, args: &FeatureArgs) -> Result<mf2_build::Features> {
let (krate, resolved) = resolved_features(dir)?;
if let Some(given) = args.given()
&& given.for_catalogs() != resolved.for_catalogs()
{
return Err(Error::FeatureMismatch {
krate,
given: list(&given),
resolved: list(&resolved),
});
}
Ok(resolved)
}
fn list(features: &mf2_build::Features) -> String {
let catalog = features.for_catalogs();
let names: Vec<&str> = catalog.names().collect();
if names.is_empty() {
"no function features".to_owned()
} else {
format!("[{}]", names.join(", "))
}
}