use std::path::PathBuf;
use anyhow::Result;
use clap::{Parser, Subcommand};
use rypip::convert::{ConvertOptions, WarningMode};
#[derive(Parser)]
#[command(
name = "rypip",
about = "Build Python packages as native Rust binaries, or convert them into Rust crates (optionally importable from Python via PyO3)."
)]
struct Cli {
#[command(subcommand)]
command: Cmd,
}
#[derive(Subcommand)]
enum Cmd {
Convert {
package: PathBuf,
#[arg(long, short)]
out: PathBuf,
#[arg(long)]
pyo3: bool,
#[arg(long)]
stdpython: Option<PathBuf>,
#[arg(long, short = 'W', value_enum, default_value_t = WarningMode::Warn)]
warnings: WarningMode,
#[arg(long)]
no_std: bool,
},
Build {
package: PathBuf,
#[arg(long, short)]
out: Option<PathBuf>,
#[arg(long)]
stdpython: Option<PathBuf>,
#[arg(long, short = 'W', value_enum, default_value_t = WarningMode::Warn)]
warnings: WarningMode,
},
Install {
package: PathBuf,
#[arg(long)]
root: Option<PathBuf>,
#[arg(long)]
stdpython: Option<PathBuf>,
#[arg(long, short = 'W', value_enum, default_value_t = WarningMode::Warn)]
warnings: WarningMode,
},
}
fn main() -> Result<()> {
match Cli::parse().command {
Cmd::Convert {
package,
out,
pyo3,
stdpython,
warnings,
no_std,
} => {
let pkg = rypip::discover(&package)?;
let krate = rypip::convert(
&pkg,
&out,
&ConvertOptions {
pyo3,
stdpython_path: stdpython,
warnings,
no_std,
},
)?;
report_warnings(&krate);
println!(
"converted `{}` -> {}{}",
krate.name,
krate.root.display(),
if pyo3 {
" (with PyO3 bindings: build with --features python)"
} else {
""
}
);
}
Cmd::Build {
package,
out,
stdpython,
warnings,
} => {
let pkg = rypip::discover(&package)?;
let out = out.unwrap_or_else(|| work_dir(&pkg.name));
let krate = rypip::convert(
&pkg,
&out,
&ConvertOptions {
pyo3: false,
stdpython_path: stdpython,
warnings,
no_std: false,
},
)?;
report_warnings(&krate);
rypip::cargo_build(&krate)?;
println!("built `{}` in {}", krate.name, krate.root.display());
}
Cmd::Install {
package,
root,
stdpython,
warnings,
} => {
let pkg = rypip::discover(&package)?;
let out = work_dir(&pkg.name);
let krate = rypip::convert(
&pkg,
&out,
&ConvertOptions {
pyo3: false,
stdpython_path: stdpython,
warnings,
no_std: false,
},
)?;
report_warnings(&krate);
rypip::cargo_install(&krate, root.as_deref())?;
println!("installed `{}`", krate.name);
}
}
Ok(())
}
fn report_warnings(krate: &rypip::ConvertedCrate) {
for warning in &krate.warnings {
eprintln!("warning: {}", warning);
}
}
fn work_dir(name: &str) -> PathBuf {
std::env::temp_dir().join(format!("rypip-{}", name))
}