mirror of
https://github.com/Noratrieb/cargo-minimize.git
synced 2026-01-14 16:35:01 +01:00
test infra
This commit is contained in:
parent
1398d3d211
commit
75108c8553
6 changed files with 145 additions and 36 deletions
31
src/build.rs
31
src/build.rs
|
|
@ -3,6 +3,7 @@ use rustfix::diagnostics::Diagnostic;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashSet,
|
collections::HashSet,
|
||||||
|
ffi::OsStr,
|
||||||
fmt::{Debug, Display},
|
fmt::{Debug, Display},
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
process::Command,
|
process::Command,
|
||||||
|
|
@ -39,6 +40,7 @@ struct BuildInner {
|
||||||
verify: Verify,
|
verify: Verify,
|
||||||
env: Vec<EnvVar>,
|
env: Vec<EnvVar>,
|
||||||
allow_color: bool,
|
allow_color: bool,
|
||||||
|
project_dir: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -78,10 +80,19 @@ impl Build {
|
||||||
verify,
|
verify,
|
||||||
env: options.env.clone(),
|
env: options.env.clone(),
|
||||||
allow_color: !options.no_color,
|
allow_color: !options.no_color,
|
||||||
|
project_dir: options.project_dir.clone(),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn cmd(&self, name: impl AsRef<OsStr>) -> Command {
|
||||||
|
let mut cmd = Command::new(name);
|
||||||
|
if let Some(path) = &self.inner.project_dir {
|
||||||
|
cmd.current_dir(path);
|
||||||
|
}
|
||||||
|
cmd
|
||||||
|
}
|
||||||
|
|
||||||
pub fn build(&self) -> Result<BuildResult> {
|
pub fn build(&self) -> Result<BuildResult> {
|
||||||
let inner = &self.inner;
|
let inner = &self.inner;
|
||||||
|
|
||||||
|
|
@ -96,8 +107,12 @@ impl Build {
|
||||||
|
|
||||||
let (is_ice, output) = match &inner.mode {
|
let (is_ice, output) = match &inner.mode {
|
||||||
BuildMode::Cargo { args } => {
|
BuildMode::Cargo { args } => {
|
||||||
let mut cmd = Command::new("cargo");
|
let mut cmd = self.cmd("cargo");
|
||||||
cmd.args(["build", "--color=always"]);
|
cmd.arg("build");
|
||||||
|
|
||||||
|
if inner.allow_color {
|
||||||
|
cmd.arg("--color=always");
|
||||||
|
}
|
||||||
|
|
||||||
for arg in args.iter().flatten() {
|
for arg in args.iter().flatten() {
|
||||||
cmd.arg(arg);
|
cmd.arg(arg);
|
||||||
|
|
@ -118,7 +133,7 @@ impl Build {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
BuildMode::Script(script_path) => {
|
BuildMode::Script(script_path) => {
|
||||||
let mut cmd = Command::new(script_path);
|
let mut cmd = self.cmd(script_path);
|
||||||
|
|
||||||
for env in &inner.env {
|
for env in &inner.env {
|
||||||
cmd.env(&env.key, &env.value);
|
cmd.env(&env.key, &env.value);
|
||||||
|
|
@ -131,10 +146,14 @@ impl Build {
|
||||||
(outputs.status.success(), output)
|
(outputs.status.success(), output)
|
||||||
}
|
}
|
||||||
BuildMode::Rustc => {
|
BuildMode::Rustc => {
|
||||||
let mut cmd = Command::new("rustc");
|
let mut cmd = self.cmd("rustc");
|
||||||
cmd.args(["--edition", "2021"]);
|
cmd.args(["--edition", "2021"]);
|
||||||
cmd.arg(&inner.input_path);
|
cmd.arg(&inner.input_path);
|
||||||
|
|
||||||
|
if inner.allow_color {
|
||||||
|
cmd.arg("--color=always");
|
||||||
|
}
|
||||||
|
|
||||||
for env in &inner.env {
|
for env in &inner.env {
|
||||||
cmd.env(&env.key, &env.value);
|
cmd.env(&env.key, &env.value);
|
||||||
}
|
}
|
||||||
|
|
@ -170,7 +189,7 @@ impl Build {
|
||||||
|
|
||||||
let diags = match &inner.mode {
|
let diags = match &inner.mode {
|
||||||
BuildMode::Cargo { args } => {
|
BuildMode::Cargo { args } => {
|
||||||
let mut cmd = Command::new("cargo");
|
let mut cmd = self.cmd("cargo");
|
||||||
cmd.args(["build", "--message-format=json"]);
|
cmd.args(["build", "--message-format=json"]);
|
||||||
|
|
||||||
for arg in args.iter().flatten() {
|
for arg in args.iter().flatten() {
|
||||||
|
|
@ -195,7 +214,7 @@ impl Build {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
BuildMode::Rustc => {
|
BuildMode::Rustc => {
|
||||||
let mut cmd = std::process::Command::new("rustc");
|
let mut cmd = self.cmd("rustc");
|
||||||
cmd.args(["--edition", "2021", "--error-format=json"]);
|
cmd.args(["--edition", "2021", "--error-format=json"]);
|
||||||
cmd.arg(&inner.input_path);
|
cmd.arg(&inner.input_path);
|
||||||
|
|
||||||
|
|
|
||||||
53
src/lib.rs
53
src/lib.rs
|
|
@ -13,47 +13,52 @@ mod processor;
|
||||||
mod expand;
|
mod expand;
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use clap::Parser;
|
|
||||||
use dylib_flag::RustFunction;
|
use dylib_flag::RustFunction;
|
||||||
use processor::Minimizer;
|
use processor::Minimizer;
|
||||||
|
|
||||||
use crate::processor::Processor;
|
use crate::processor::Processor;
|
||||||
|
|
||||||
|
// Export so that the user doesn't have to add clap themselves.
|
||||||
|
pub use clap::Parser;
|
||||||
|
|
||||||
#[derive(clap::Parser)]
|
#[derive(clap::Parser)]
|
||||||
#[command(version, about, name = "cargo", bin_name = "cargo")]
|
#[command(version, about, name = "cargo", bin_name = "cargo")]
|
||||||
enum Cargo {
|
pub enum Cargo {
|
||||||
Minimize(Options),
|
Minimize(Options),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(clap::Args, Debug)]
|
#[derive(clap::Args, Debug)]
|
||||||
pub struct Options {
|
pub struct Options {
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
script_path: Option<PathBuf>,
|
pub script_path: Option<PathBuf>,
|
||||||
|
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
cargo_args: Option<String>,
|
pub cargo_args: Option<String>,
|
||||||
|
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
no_color: bool,
|
pub no_color: bool,
|
||||||
|
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
rustc: bool,
|
pub rustc: bool,
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
no_verify: bool,
|
pub no_verify: bool,
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
verify_fn: Option<RustFunction>,
|
pub verify_fn: Option<RustFunction>,
|
||||||
|
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
env: Vec<EnvVar>,
|
pub env: Vec<EnvVar>,
|
||||||
|
|
||||||
|
#[arg(long)]
|
||||||
|
pub project_dir: Option<PathBuf>,
|
||||||
|
|
||||||
#[arg(default_value = "src")]
|
#[arg(default_value = "src")]
|
||||||
path: PathBuf,
|
pub path: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct EnvVar {
|
pub struct EnvVar {
|
||||||
key: String,
|
pub key: String,
|
||||||
value: String,
|
pub value: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for EnvVar {
|
impl FromStr for EnvVar {
|
||||||
|
|
@ -72,12 +77,10 @@ impl FromStr for EnvVar {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn minimize() -> Result<()> {
|
pub fn minimize(options: Options) -> Result<()> {
|
||||||
let Cargo::Minimize(options) = Cargo::parse();
|
|
||||||
|
|
||||||
let build = build::Build::new(&options);
|
let build = build::Build::new(&options);
|
||||||
|
|
||||||
let mut minimizer = Minimizer::new_glob_dir(options, build);
|
let mut minimizer = Minimizer::new_glob_dir(options, build)?;
|
||||||
|
|
||||||
minimizer.run_passes([
|
minimizer.run_passes([
|
||||||
Box::<privatize::Privatize>::default() as Box<dyn Processor>,
|
Box::<privatize::Privatize>::default() as Box<dyn Processor>,
|
||||||
|
|
@ -88,3 +91,19 @@ pub fn minimize() -> Result<()> {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for Options {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
script_path: None,
|
||||||
|
cargo_args: None,
|
||||||
|
no_color: false,
|
||||||
|
rustc: false,
|
||||||
|
no_verify: false,
|
||||||
|
verify_fn: None,
|
||||||
|
env: Vec::new(),
|
||||||
|
project_dir: None,
|
||||||
|
path: PathBuf::from("/the/wrong/path/you/need/to/change/it"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use cargo_minimize::{Cargo, Parser};
|
||||||
use tracing::{error, info, Level};
|
use tracing::{error, info, Level};
|
||||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter, Registry};
|
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter, Registry};
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
|
let Cargo::Minimize(options) = Cargo::parse();
|
||||||
|
|
||||||
let registry = Registry::default().with(
|
let registry = Registry::default().with(
|
||||||
EnvFilter::builder()
|
EnvFilter::builder()
|
||||||
.with_default_directive(Level::INFO.into())
|
.with_default_directive(Level::INFO.into())
|
||||||
|
|
@ -18,7 +21,7 @@ fn main() -> Result<()> {
|
||||||
|
|
||||||
registry.with(tree_layer).init();
|
registry.with(tree_layer).init();
|
||||||
|
|
||||||
if let Err(err) = cargo_minimize::minimize() {
|
if let Err(err) = cargo_minimize::minimize(options) {
|
||||||
error!("An error occured:\n{err}");
|
error!("An error occured:\n{err}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ mod reaper;
|
||||||
|
|
||||||
pub(crate) use self::files::SourceFile;
|
pub(crate) use self::files::SourceFile;
|
||||||
use crate::{build::Build, processor::files::Changes, Options};
|
use crate::{build::Build, processor::files::Changes, Options};
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{bail, Context, Result};
|
||||||
use owo_colors::OwoColorize;
|
use owo_colors::OwoColorize;
|
||||||
use std::{collections::HashSet, ffi::OsStr, fmt::Debug};
|
use std::{collections::HashSet, ffi::OsStr, fmt::Debug};
|
||||||
|
|
||||||
|
|
@ -49,7 +49,7 @@ pub(crate) struct Minimizer {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Minimizer {
|
impl Minimizer {
|
||||||
pub(crate) fn new_glob_dir(options: Options, build: Build) -> Self {
|
pub(crate) fn new_glob_dir(options: Options, build: Build) -> Result<Self> {
|
||||||
let path = &options.path;
|
let path = &options.path;
|
||||||
let walk = walkdir::WalkDir::new(path);
|
let walk = walkdir::WalkDir::new(path);
|
||||||
|
|
||||||
|
|
@ -69,13 +69,17 @@ impl Minimizer {
|
||||||
.inspect(|file| {
|
.inspect(|file| {
|
||||||
info!("Collecting file: {}", file.path.display());
|
info!("Collecting file: {}", file.path.display());
|
||||||
})
|
})
|
||||||
.collect();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
Self {
|
if files.is_empty() {
|
||||||
|
bail!("Did not find any files for path {}", path.display());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
files,
|
files,
|
||||||
build,
|
build,
|
||||||
options,
|
options,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn run_passes<'a>(
|
pub(crate) fn run_passes<'a>(
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,51 @@
|
||||||
use anyhow::Result;
|
use std::process::Command;
|
||||||
|
|
||||||
|
use anyhow::{bail, Result};
|
||||||
|
use cargo_minimize::Options;
|
||||||
|
|
||||||
|
fn canonicalize(code: &str) -> Result<String> {
|
||||||
|
let ast = syn::parse_file(code)?;
|
||||||
|
Ok(prettyplease::unparse(&ast))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run_test(code: &str, minimizes_to: &str, options: impl FnOnce(&mut Options)) -> Result<()> {
|
||||||
|
let dir = tempfile::tempdir()?;
|
||||||
|
|
||||||
|
let mut cargo = Command::new("cargo");
|
||||||
|
cargo.args(["new", "project"]);
|
||||||
|
cargo.current_dir(dir.path());
|
||||||
|
|
||||||
|
let output = cargo.output()?;
|
||||||
|
if !output.status.success() {
|
||||||
|
bail!(
|
||||||
|
"Failed to create cargo project, {}",
|
||||||
|
String::from_utf8(output.stderr)?
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let cargo_dir = dir.path().join("project");
|
||||||
|
|
||||||
|
let main_rs = cargo_dir.join("src/main.rs");
|
||||||
|
|
||||||
|
std::fs::write(&main_rs, code)?;
|
||||||
|
|
||||||
|
let mut opts = Options::default();
|
||||||
|
|
||||||
|
let path = cargo_dir.join("src");
|
||||||
|
|
||||||
|
opts.project_dir = Some(cargo_dir);
|
||||||
|
opts.path = path;
|
||||||
|
options(&mut opts);
|
||||||
|
|
||||||
|
cargo_minimize::minimize(opts)?;
|
||||||
|
|
||||||
|
let minimized_main_rs = std::fs::read_to_string(main_rs)?;
|
||||||
|
|
||||||
|
let actual = canonicalize(&minimized_main_rs)?;
|
||||||
|
let expectecd = canonicalize(minimizes_to)?;
|
||||||
|
|
||||||
|
assert_eq!(actual, expectecd);
|
||||||
|
|
||||||
fn run_test(_: &str) -> Result<()> {
|
|
||||||
let _ = tempfile::tempdir()?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn smoke() {
|
|
||||||
run_test("").unwrap();
|
|
||||||
}
|
|
||||||
|
|
|
||||||
24
tests/minimize.rs
Normal file
24
tests/minimize.rs
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
mod helper;
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
|
|
||||||
|
use helper::run_test;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn hello_world_no_verify() -> Result<()> {
|
||||||
|
run_test(
|
||||||
|
r##"
|
||||||
|
fn main() {
|
||||||
|
println!("Hello, world!");
|
||||||
|
}
|
||||||
|
"##,
|
||||||
|
r##"
|
||||||
|
fn main() {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
"##,
|
||||||
|
|opts| {
|
||||||
|
opts.no_verify = true;
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue