python in bash in rust

This commit is contained in:
nora 2023-04-04 13:36:46 +02:00
parent ff26987129
commit f84cfd935b
2 changed files with 94 additions and 17 deletions

View file

@ -6,10 +6,11 @@ use std::sync::{
Arc,
};
use anyhow::Result;
use cargo_minimize::{Cargo, Parser};
use tracing::{error, Level};
fn main() {
fn main() -> Result<()> {
let Cargo::Minimize(options) = Cargo::parse();
cargo_minimize::init_recommended_tracing_subscriber(Level::INFO);
@ -34,8 +35,5 @@ fn main() {
error!("Failed to install CTRL-C handler: {err}");
}
if let Err(err) = cargo_minimize::minimize(options, cancel2) {
error!("An error occured:\n{err}");
std::process::exit(1);
}
cargo_minimize::minimize(options, cancel2)
}

View file

@ -1,15 +1,19 @@
use anyhow::{ensure, Context, Result};
use once_cell::sync::Lazy;
use regex::Regex;
use std::fs::Permissions;
use std::io::BufWriter;
use std::os::unix::prelude::PermissionsExt;
use std::path::PathBuf;
use std::process::Command;
use std::{
fs,
io::{self, Write},
path::Path,
};
use tempfile::TempDir;
#[test]
#[ignore = "unfinished"]
fn full_tests() -> Result<()> {
let path = Path::new(file!())
.canonicalize()?
@ -25,16 +29,15 @@ fn full_tests() -> Result<()> {
let child = child?;
let path = child.path();
build(&path)?;
build(&path).with_context(|| format!("building {:?}", path.file_name().unwrap()))?;
}
Ok(())
}
fn build(path: &Path) -> Result<()> {
let cargo_minimize = Path::new("target/debug/cargo-minimize").canonicalize()?;
fn setup_dir(path: &Path) -> Result<(TempDir, PathBuf)> {
let proj_dir = path.file_name().unwrap().to_str().unwrap();
writeln!(io::stdout(), ".... Testing {}", proj_dir)?;
let tempdir = tempfile::tempdir()?;
@ -43,23 +46,98 @@ fn build(path: &Path) -> Result<()> {
let proj_dir = tempdir.path().join(proj_dir).canonicalize()?;
let start_roots = get_roots(&proj_dir).context("getting initial roots")?;
Ok((tempdir, proj_dir))
}
fn setup_scripts(start_roots: &[String], proj_dir: &Path) -> Result<()> {
// FIXME: Do this in a good way.
// What the fuck is this.
{
let file = fs::File::create(proj_dir.join("check.sh"))?;
let expected_roots = start_roots
.iter()
.map(|root| format!("'{}'", root))
.collect::<Vec<_>>()
.join(", ");
write!(
BufWriter::new(&file),
r#"#!/usr/bin/env bash
OUT=$(rg -o "~MINIMIZE-ROOT [\w\-]*" full-tests/ --no-filename --sort path src)
python3 -c "
out = '$OUT'
lines = out.split('\n')
found = set()
for line in lines:
name = line.removeprefix('~MINIMIZE-ROOT').strip()
found.add(name)
expected_roots = {{{expected_roots}}}
for root in expected_roots:
if root in found:
print(f'Found {{root}} in output')
else:
print(f'Did not find {{root}} in output!')
exit(1)
"
"#
)?;
file.set_permissions(Permissions::from_mode(0o777))?;
}
{
let file = fs::File::create(proj_dir.join("lint.sh"))?;
write!(
BufWriter::new(&file),
r#"#!/usr/bin/env bash
cargo check
"#
)?;
file.set_permissions(Permissions::from_mode(0o777))?;
}
Ok(())
}
fn build(path: &Path) -> Result<()> {
let (_tempdir, proj_dir) = setup_dir(path).context("setting up tempdir")?;
let cargo_minimize = Path::new("target/debug/cargo-minimize")
.canonicalize()
.context("canonicalizing target/debug/cargo-minimize")?;
let start_roots = get_roots(&proj_dir).context("getting initial MINIMIZE-ROOTs")?;
eprintln!("Roots: {:?}", start_roots);
setup_scripts(&start_roots, &proj_dir).context("setting up scripts")?;
let mut cmd = Command::new(cargo_minimize);
cmd.current_dir(&proj_dir);
cmd.arg("minimize");
cmd.arg("--script-path=./check.sh");
cmd.arg("--script-path-lints=./lint.sh");
let out = cmd.output().context("spawning cargo-minimize")?;
let stderr = String::from_utf8(out.stderr).unwrap();
ensure!(out.status.success(), "Command failed:\n{stderr}");
let required_deleted = get_required_deleted(&proj_dir)?;
let stdout = String::from_utf8(out.stdout).unwrap();
ensure!(
required_deleted.len() > 0,
out.status.success(),
"Command failed:\n--- stderr:\n{stderr}\n--- stdout:\n{stdout}"
);
let required_deleted = get_required_deleted(&proj_dir).context("get REQUIRED-DELETED")?;
ensure!(
required_deleted.is_empty(),
"Some REQUIRE-DELETED have not been deleted: {required_deleted:?}"
);
@ -79,6 +157,7 @@ fn get_required_deleted(path: &Path) -> Result<Vec<String>> {
}
fn grep(path: &Path, regex: &Regex) -> Result<Vec<String>> {
let path = path.join("src");
let mut results = Vec::new();
let walk = walkdir::WalkDir::new(path);
@ -87,7 +166,7 @@ fn grep(path: &Path, regex: &Regex) -> Result<Vec<String>> {
if !entry.metadata()?.is_file() {
continue;
}
let src = fs::read_to_string(entry.path())?;
let src = fs::read_to_string(entry.path()).context("reading file")?;
let captures = regex.captures_iter(&src);
for cap in captures {
let root_name = cap.get(1).unwrap();