install multiple + better reporting
This commit is contained in:
parent
d84b074dde
commit
e9b3f5073f
6 changed files with 307 additions and 36 deletions
194
Cargo.lock
generated
194
Cargo.lock
generated
|
@ -38,7 +38,7 @@ version = "1.1.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -49,7 +49,7 @@ checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
|
|||
dependencies = [
|
||||
"anstyle",
|
||||
"once_cell",
|
||||
"windows-sys",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -58,6 +58,12 @@ version = "1.0.97"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.9.0"
|
||||
|
@ -91,6 +97,7 @@ dependencies = [
|
|||
"clap",
|
||||
"clap-cargo",
|
||||
"config",
|
||||
"crossterm",
|
||||
"git2",
|
||||
"lazy_static",
|
||||
"phf",
|
||||
|
@ -168,6 +175,31 @@ dependencies = [
|
|||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossterm"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"crossterm_winapi",
|
||||
"mio",
|
||||
"parking_lot",
|
||||
"rustix 0.38.44",
|
||||
"signal-hook",
|
||||
"signal-hook-mio",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossterm_winapi"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "displaydoc"
|
||||
version = "0.2.5"
|
||||
|
@ -192,7 +224,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -219,7 +251,7 @@ dependencies = [
|
|||
"cfg-if",
|
||||
"libc",
|
||||
"r-efi",
|
||||
"wasi",
|
||||
"wasi 0.14.2+wasi-0.2.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -465,6 +497,12 @@ dependencies = [
|
|||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.9.3"
|
||||
|
@ -477,6 +515,16 @@ version = "0.7.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.26"
|
||||
|
@ -489,6 +537,18 @@ version = "2.7.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.1"
|
||||
|
@ -513,6 +573,29 @@ dependencies = [
|
|||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pathdiff"
|
||||
version = "0.2.3"
|
||||
|
@ -612,6 +695,28 @@ version = "0.6.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys 0.4.15",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "1.0.3"
|
||||
|
@ -621,10 +726,16 @@ dependencies = [
|
|||
"bitflags",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
"linux-raw-sys 0.9.3",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.219"
|
||||
|
@ -660,6 +771,36 @@ version = "1.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"signal-hook-registry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-mio"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"mio",
|
||||
"signal-hook",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "1.0.1"
|
||||
|
@ -715,8 +856,8 @@ dependencies = [
|
|||
"fastrand",
|
||||
"getrandom",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
"rustix 1.0.3",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -824,6 +965,12 @@ version = "0.2.15"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.14.2+wasi-0.2.4"
|
||||
|
@ -833,6 +980,37 @@ dependencies = [
|
|||
"wit-bindgen-rt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.59.0"
|
||||
|
|
|
@ -11,6 +11,7 @@ anyhow = "1.0.97"
|
|||
clap = { version = "4.5.32", features = ["derive"] }
|
||||
clap-cargo = "0.15.2"
|
||||
config = { version = "0.15.11", default-features = false, features = ["toml"] }
|
||||
crossterm = "0.28.1"
|
||||
git2 = "0.20.1"
|
||||
lazy_static = "1.5.0"
|
||||
phf = { version = "0.11.3", features = ["macros"] }
|
||||
|
|
|
@ -23,6 +23,15 @@ pub enum Error {
|
|||
ExecFailed { status: ExitStatus, stderr: Vec<u8> },
|
||||
}
|
||||
|
||||
impl Error {
|
||||
pub fn fatal(&self) -> bool {
|
||||
matches!(
|
||||
self,
|
||||
Self::NoCompiler | Self::BadCompiler { .. } | Self::EmptyCompiler
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn to_res(Output { status, stderr, .. }: Output) -> Result<(), Error> {
|
||||
status
|
||||
.success()
|
||||
|
|
|
@ -7,8 +7,10 @@ use std::{
|
|||
use anstream::AutoStream;
|
||||
use anstyle::{AnsiColor, Effects, Style};
|
||||
use clap::ValueEnum;
|
||||
use crossterm::{ExecutableCommand, cursor::MoveToPreviousLine};
|
||||
|
||||
pub const ERROR: Style = AnsiColor::Red.on_default().effects(Effects::BOLD);
|
||||
pub const GOOD: Style = AnsiColor::Green.on_default().effects(Effects::BOLD);
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, ValueEnum)]
|
||||
pub enum Color {
|
||||
|
@ -36,9 +38,20 @@ impl Console {
|
|||
}
|
||||
|
||||
pub fn print(&self, status: &str, style: &Style, msg: impl Display) {
|
||||
let mut stream = AutoStream::new(stderr(), self.0).lock();
|
||||
let mut stream = AutoStream::new(stderr(), self.0);
|
||||
let _ = writeln!(stream, "{style}{status}{style:#} {msg}");
|
||||
}
|
||||
|
||||
pub fn print_right(&self, status: &str, style: &Style, msg: impl Display) {
|
||||
let mut stream = AutoStream::new(stderr(), self.0);
|
||||
let _ = writeln!(stream, "{style}{status:>12}{style:#} {msg}");
|
||||
}
|
||||
|
||||
pub fn update_right(&self, status: &str, style: &Style, msg: impl Display) {
|
||||
let mut stream = AutoStream::new(stderr(), self.0).lock();
|
||||
let _ = stream.execute(MoveToPreviousLine(1));
|
||||
let _ = writeln!(stream, "{style}{status:>12}{style:#} {msg}");
|
||||
}
|
||||
}
|
||||
|
||||
static CONSOLE: OnceLock<Console> = OnceLock::new();
|
||||
|
@ -54,10 +67,6 @@ pub fn init(color: Color) {
|
|||
}
|
||||
|
||||
macro_rules! error {
|
||||
($arg:expr) => (
|
||||
crate::console::console().print("error:", &crate::console::ERROR, ($arg))
|
||||
);
|
||||
|
||||
($($arg:tt)+) => (
|
||||
crate::console::console().print(
|
||||
"error:",
|
||||
|
@ -67,4 +76,34 @@ macro_rules! error {
|
|||
);
|
||||
}
|
||||
|
||||
macro_rules! info {
|
||||
($status:expr, $($arg:tt)+) => (
|
||||
crate::console::console().print_right(
|
||||
$status,
|
||||
&crate::console::GOOD,
|
||||
format_args!($($arg)+),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
macro_rules! fail {
|
||||
($($arg:tt)+) => {
|
||||
crate::console::console().update_right("Failed", &crate::console::ERROR, "");
|
||||
error!($($arg)+);
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! update {
|
||||
($status:expr, $($arg:tt)+) => (
|
||||
crate::console::console().update_right(
|
||||
$status,
|
||||
&crate::console::GOOD,
|
||||
format_args!($($arg)+),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
pub(crate) use error;
|
||||
pub(crate) use fail;
|
||||
pub(crate) use info;
|
||||
pub(crate) use update;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use phf::phf_map;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Debug)]
|
||||
pub struct InstallInfo {
|
||||
pub url: &'static str,
|
||||
pub files: &'static [&'static str],
|
||||
|
@ -29,6 +29,6 @@ static LANGUAGES: phf::Map<&'static str, InstallInfo> = phf_map! {
|
|||
},
|
||||
};
|
||||
|
||||
pub fn get_install_info(language: &str) -> Option<InstallInfo> {
|
||||
LANGUAGES.get(language).copied()
|
||||
pub fn get_install_info(language: &str) -> Option<&InstallInfo> {
|
||||
LANGUAGES.get(language)
|
||||
}
|
||||
|
|
84
src/main.rs
84
src/main.rs
|
@ -9,7 +9,7 @@ mod console;
|
|||
mod languages;
|
||||
mod settings;
|
||||
|
||||
use console::{Color, error};
|
||||
use console::{Color, error, fail, info, update};
|
||||
use languages::{InstallInfo, get_install_info};
|
||||
use settings::{Settings, get_settings};
|
||||
|
||||
|
@ -21,7 +21,7 @@ struct Cli {
|
|||
#[arg(short, long, value_enum, default_value_t = Color::Auto)]
|
||||
color: Color,
|
||||
|
||||
language: String,
|
||||
languages: Vec<String>,
|
||||
}
|
||||
|
||||
fn main() -> ExitCode {
|
||||
|
@ -29,15 +29,16 @@ fn main() -> ExitCode {
|
|||
|
||||
console::init(cli.color);
|
||||
|
||||
if let Err(e) = main_inner(cli) {
|
||||
error!(e);
|
||||
ExitCode::FAILURE
|
||||
} else {
|
||||
ExitCode::SUCCESS
|
||||
match install_all(cli.languages) {
|
||||
Err(e) => {
|
||||
error!("{e}");
|
||||
ExitCode::FAILURE
|
||||
}
|
||||
Ok(code) => code,
|
||||
}
|
||||
}
|
||||
|
||||
fn main_inner(Cli { language, .. }: Cli) -> anyhow::Result<()> {
|
||||
fn install_all(mut languages: Vec<String>) -> anyhow::Result<ExitCode> {
|
||||
let Settings {
|
||||
parser_dir,
|
||||
compiler,
|
||||
|
@ -50,37 +51,78 @@ fn main_inner(Cli { language, .. }: Cli) -> anyhow::Result<()> {
|
|||
// have to use a canonical path bc compiler runs elsewhere
|
||||
let parser_dir = parser_dir.canonicalize()?;
|
||||
|
||||
Ok(install(
|
||||
&language,
|
||||
&parser_dir,
|
||||
src_dir.as_ref(),
|
||||
compiler.as_deref(),
|
||||
)?)
|
||||
let mut errors = 0;
|
||||
let mut installed = 0;
|
||||
|
||||
languages.sort();
|
||||
languages.dedup();
|
||||
|
||||
for language in &languages {
|
||||
if let Some(info) = get_install_info(language) {
|
||||
if let Err(e) = install(
|
||||
language,
|
||||
info,
|
||||
&parser_dir,
|
||||
src_dir.as_ref(),
|
||||
compiler.as_deref(),
|
||||
) {
|
||||
fail!("{e}");
|
||||
if e.fatal() {
|
||||
return Ok(ExitCode::FAILURE);
|
||||
} else {
|
||||
errors += 1;
|
||||
}
|
||||
} else {
|
||||
installed += 1;
|
||||
}
|
||||
} else {
|
||||
error!("unknown language `{language}`");
|
||||
}
|
||||
}
|
||||
|
||||
info!("Finished", "installed {installed} parsers");
|
||||
|
||||
Ok(if errors > 0 {
|
||||
ExitCode::FAILURE
|
||||
} else {
|
||||
ExitCode::SUCCESS
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
enum InstallError {
|
||||
#[error("unknown language `{0}`")]
|
||||
UnknownLanguage(String),
|
||||
|
||||
#[error("couldn't clone `{0}`")]
|
||||
Clone(&'static str),
|
||||
|
||||
#[error(transparent)]
|
||||
Git(#[from] git2::Error),
|
||||
|
||||
#[error(transparent)]
|
||||
Compile(#[from] cc::Error),
|
||||
}
|
||||
|
||||
impl InstallError {
|
||||
fn fatal(&self) -> bool {
|
||||
match self {
|
||||
Self::Compile(e) => e.fatal(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn install(
|
||||
language: &str,
|
||||
InstallInfo { url, files }: &InstallInfo,
|
||||
parser_dir: &Path,
|
||||
src_dir: &Path,
|
||||
compiler: Option<&str>,
|
||||
) -> Result<(), InstallError> {
|
||||
let InstallInfo { url, files } =
|
||||
get_install_info(language).ok_or(InstallError::UnknownLanguage(language.to_owned()))?;
|
||||
info!("Installing", "{language}");
|
||||
|
||||
let repo_path = src_dir.join(language);
|
||||
Repository::clone(url, &repo_path).map_err(|_| InstallError::Clone(url))?;
|
||||
let repo = Repository::clone(url, &repo_path).map_err(|_| InstallError::Clone(url))?;
|
||||
|
||||
let version = repo.head()?.peel_to_commit()?.id();
|
||||
|
||||
let output_path = parser_dir.join(language).with_extension(DLL_EXTENSION);
|
||||
|
||||
|
@ -88,5 +130,7 @@ fn install(
|
|||
build.compiler(compiler).dir(&repo_path).input_files(files);
|
||||
build.compile(&output_path)?;
|
||||
|
||||
update!("Installed", "{language} {version:.7}");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue