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