mirror of
https://github.com/Noratrieb/cargo-minimize.git
synced 2026-01-14 16:35:01 +01:00
lol
This commit is contained in:
commit
a2bc92d651
10 changed files with 1548 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
target
|
||||||
|
expanded.rs
|
||||||
1310
Cargo.lock
generated
Normal file
1310
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
16
Cargo.toml
Normal file
16
Cargo.toml
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
[workspace]
|
||||||
|
exclude = ["test-cases/*"]
|
||||||
|
|
||||||
|
[package]
|
||||||
|
name = "cargo-minimize"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
anyhow = "1.0.65"
|
||||||
|
cargo = "0.65.0"
|
||||||
|
prettyplease = "0.1.19"
|
||||||
|
proc-macro2 = "1.0.46"
|
||||||
|
syn = { version = "1.0.101", features = ["full"] }
|
||||||
28
src/build.rs
Normal file
28
src/build.rs
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
use anyhow::{Context, Result};
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
pub struct Build {
|
||||||
|
path: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Build {
|
||||||
|
pub fn new(path: impl Into<PathBuf>) -> Self {
|
||||||
|
Self { path: path.into() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build(&self) -> Result<BuildResult> {
|
||||||
|
let mut cmd = std::process::Command::new("cargo");
|
||||||
|
|
||||||
|
cmd.current_dir(&self.path).arg("build");
|
||||||
|
|
||||||
|
let output = cmd.output().context("spawning cargo")?;
|
||||||
|
|
||||||
|
Ok(BuildResult {
|
||||||
|
success: output.status.success(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct BuildResult {
|
||||||
|
pub success: bool,
|
||||||
|
}
|
||||||
108
src/expand.rs
Normal file
108
src/expand.rs
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
use anyhow::{bail, Context, Result};
|
||||||
|
use cargo::{
|
||||||
|
core::{
|
||||||
|
compiler::{BuildContext, Unit, UnitInterner},
|
||||||
|
manifest::TargetSourcePath,
|
||||||
|
Workspace,
|
||||||
|
},
|
||||||
|
ops::{self, CompileOptions},
|
||||||
|
util::{command_prelude::CompileMode, Config},
|
||||||
|
};
|
||||||
|
use std::{ops::Not, path::Path, process::Command};
|
||||||
|
|
||||||
|
fn cargo_expand(cargo_dir: &TargetSourcePath) -> Result<syn::File> {
|
||||||
|
let cargo_dir = cargo_dir
|
||||||
|
.path()
|
||||||
|
.context("target path is not a path")?
|
||||||
|
.parent()
|
||||||
|
.context("target path has no parent")?;
|
||||||
|
|
||||||
|
let mut cmd = Command::new("cargo");
|
||||||
|
|
||||||
|
cmd.current_dir(cargo_dir).arg("expand");
|
||||||
|
|
||||||
|
let output = cmd.output().context(format!(
|
||||||
|
"spawning cargo with target path {}",
|
||||||
|
cargo_dir.display()
|
||||||
|
))?;
|
||||||
|
|
||||||
|
if output.status.success().not() {
|
||||||
|
bail!(String::from_utf8(output.stderr).context("stderr utf8")?);
|
||||||
|
}
|
||||||
|
|
||||||
|
let src = String::from_utf8(output.stdout).context("stdout utf8")?;
|
||||||
|
|
||||||
|
let root = syn::parse_str(&src).context("parsing crate")?;
|
||||||
|
|
||||||
|
Ok(root)
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DepExpander<'ws, 'cfg> {
|
||||||
|
bcx: BuildContext<'ws, 'cfg>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ws, 'cfg> DepExpander<'ws, 'cfg> {
|
||||||
|
fn source(unit: &Unit) -> Result<&Path> {
|
||||||
|
unit.target
|
||||||
|
.src_path()
|
||||||
|
.path()
|
||||||
|
.context("unit source path not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expand(&self) -> Result<syn::File> {
|
||||||
|
let unit = self.bcx.roots.get(0).context("root unit not found")?;
|
||||||
|
self.expand_recursively(unit)
|
||||||
|
.context(format!("expanding {} crate", unit.target.crate_name()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expand_recursively(&self, unit: &Unit) -> Result<syn::File> {
|
||||||
|
let mut ast = cargo_expand(unit.target.src_path()).context("expanding unit")?;
|
||||||
|
|
||||||
|
let deps = self
|
||||||
|
.bcx
|
||||||
|
.unit_graph
|
||||||
|
.get(unit)
|
||||||
|
.context("dependencies not found for crate")?;
|
||||||
|
|
||||||
|
for dep in deps {
|
||||||
|
let crate_name = dep.unit.target.crate_name();
|
||||||
|
|
||||||
|
let file = self
|
||||||
|
.expand_recursively(&dep.unit)
|
||||||
|
.context(format!("expanding {crate_name} crate"))?;
|
||||||
|
|
||||||
|
let name = proc_macro2::Ident::new(&crate_name, proc_macro2::Span::call_site());
|
||||||
|
|
||||||
|
let module = syn::ItemMod {
|
||||||
|
attrs: file.attrs,
|
||||||
|
vis: syn::Visibility::Inherited,
|
||||||
|
mod_token: Default::default(),
|
||||||
|
ident: name,
|
||||||
|
content: Some((Default::default(), file.items)),
|
||||||
|
semi: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
ast.items.push(syn::Item::Mod(module));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(ast)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Expands the crate in `cargo_dir` into a single file without dependencies
|
||||||
|
pub fn expand(cargo_dir: &Path) -> Result<syn::File> {
|
||||||
|
let cargo_dir = cargo_dir.canonicalize().context("could not find path")?;
|
||||||
|
let manifest_path = cargo_dir.join("Cargo.toml");
|
||||||
|
|
||||||
|
let cfg = Config::default().context("create cargo config")?;
|
||||||
|
let ws = Workspace::new(&manifest_path, &cfg).context("getting workspace")?;
|
||||||
|
let interner = UnitInterner::new();
|
||||||
|
let options = CompileOptions::new(&cfg, CompileMode::Build).context("create options")?;
|
||||||
|
let bcx = ops::create_bcx(&ws, &options, &interner).context("resolve dep graph")?;
|
||||||
|
|
||||||
|
let expander = DepExpander { bcx };
|
||||||
|
|
||||||
|
let root = expander.expand()?;
|
||||||
|
|
||||||
|
Ok(root)
|
||||||
|
}
|
||||||
30
src/lib.rs
Normal file
30
src/lib.rs
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
mod build;
|
||||||
|
mod expand;
|
||||||
|
|
||||||
|
use anyhow::{Context, Result};
|
||||||
|
|
||||||
|
pub fn minimize(cargo_dir: &Path) -> Result<()> {
|
||||||
|
let file = expand::expand(cargo_dir).context("during expansion")?;
|
||||||
|
|
||||||
|
|
||||||
|
let file = prettyplease::unparse(&file);
|
||||||
|
|
||||||
|
println!("// EXPANDED-START\n\n{file}\n\n// EXPANDED-END");
|
||||||
|
|
||||||
|
std::fs::write("expanded.rs", file)?;
|
||||||
|
|
||||||
|
println!("wow, expanded");
|
||||||
|
Ok(())
|
||||||
|
|
||||||
|
/*
|
||||||
|
let build = Build::new(cargo_dir);
|
||||||
|
|
||||||
|
if build.build()?.success {
|
||||||
|
bail!("build must initially fail!");
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
13
src/main.rs
Normal file
13
src/main.rs
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use anyhow::{Context, Result};
|
||||||
|
|
||||||
|
fn main() -> Result<()> {
|
||||||
|
let dir = std::env::args().nth(1).context("expected an argument")?;
|
||||||
|
|
||||||
|
cargo_minimize::minimize(&Path::new(&dir))?;
|
||||||
|
|
||||||
|
println!("Exit");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
25
test-cases/uwu/Cargo.lock
generated
Normal file
25
test-cases/uwu/Cargo.lock
generated
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "is-even"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "83d558b5cf9dbf1e6c224d9cea60821ad82e09092ade7aed6d83aef48ed382d0"
|
||||||
|
dependencies = [
|
||||||
|
"is-odd",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "is-odd"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5741cc4ac9f6105f6bb067d09bb5685dc255e5bdec6f3bf6d86f4bda6187d17e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uwu"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"is-even",
|
||||||
|
]
|
||||||
11
test-cases/uwu/Cargo.toml
Normal file
11
test-cases/uwu/Cargo.toml
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
[workspace]
|
||||||
|
|
||||||
|
[package]
|
||||||
|
name = "uwu"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
is-even = "1.0.0"
|
||||||
5
test-cases/uwu/src/main.rs
Normal file
5
test-cases/uwu/src/main.rs
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
use is_even::IsEven;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("{}", 4.is_even());
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue