skip already installed languages

next up is adding support for updating installed languages but for that
we need to track the currently installed revision in a file somewhere
This commit is contained in:
wires 2025-03-23 10:45:21 -04:00
parent 2b513603b7
commit a8fc500c5a
Signed by: wires
SSH key fingerprint: SHA256:9GtP+M3O2IivPDlw1UY872UPUuJH2gI0yG6ExBxaaiM
3 changed files with 48 additions and 12 deletions

View file

@ -11,6 +11,7 @@ use crossterm::{ExecutableCommand, cursor::MoveToPreviousLine};
pub const ERROR: Style = AnsiColor::Red.on_default().effects(Effects::BOLD); pub const ERROR: Style = AnsiColor::Red.on_default().effects(Effects::BOLD);
pub const GOOD: Style = AnsiColor::Green.on_default().effects(Effects::BOLD); pub const GOOD: Style = AnsiColor::Green.on_default().effects(Effects::BOLD);
pub const NOTE: Style = AnsiColor::Cyan.on_default().effects(Effects::BOLD);
#[derive(Copy, Clone, Debug, PartialEq, Eq, ValueEnum)] #[derive(Copy, Clone, Debug, PartialEq, Eq, ValueEnum)]
pub enum Color { pub enum Color {
@ -76,11 +77,21 @@ macro_rules! error {
); );
} }
macro_rules! info { macro_rules! note {
($status:expr, $($arg:tt)+) => ( ($($arg:tt)+) => (
crate::console::console().print(
" tip:",
&crate::console::NOTE,
format_args!($($arg)+),
)
);
}
macro_rules! status {
($status:expr, $style:expr, $($arg:tt)+) => (
crate::console::console().print_right( crate::console::console().print_right(
$status, $status,
&crate::console::GOOD, $style,
format_args!($($arg)+), format_args!($($arg)+),
) )
); );
@ -96,10 +107,10 @@ macro_rules! fail {
} }
macro_rules! update { macro_rules! update {
($status:expr, $($arg:tt)+) => ( ($status:expr, $style:expr, $($arg:tt)+) => (
crate::console::console().update_right( crate::console::console().update_right(
$status, $status,
&crate::console::GOOD, $style,
format_args!($($arg)+), format_args!($($arg)+),
) )
); );
@ -107,5 +118,6 @@ macro_rules! update {
pub(crate) use error; pub(crate) use error;
pub(crate) use fail; pub(crate) use fail;
pub(crate) use info; pub(crate) use note;
pub(crate) use status;
pub(crate) use update; pub(crate) use update;

View file

@ -4,16 +4,20 @@ use clap::Args;
use git2::Repository; use git2::Repository;
use tempfile::tempdir; use tempfile::tempdir;
use crate::console::{error, fail, info, update}; use crate::console::{GOOD, NOTE, error, fail, note, status, update};
use crate::settings::Settings; use crate::settings::Settings;
mod cc; mod cc;
mod languages; mod languages;
use languages::{InstallInfo, get_install_info}; use languages::{InstallInfo, get_install_info, is_installed};
#[derive(Debug, Args)] #[derive(Debug, Args)]
pub struct Install { pub struct Install {
/// reinstall already present parsers
#[arg(short, long)]
force: bool,
languages: Vec<String>, languages: Vec<String>,
} }
@ -32,15 +36,22 @@ impl Install {
// have to use a canonical path bc compiler runs elsewhere // have to use a canonical path bc compiler runs elsewhere
let parser_dir = parser_dir.canonicalize()?; let parser_dir = parser_dir.canonicalize()?;
let mut languages = self.languages; let Self {
mut languages,
force,
} = self;
languages.sort(); languages.sort();
languages.dedup(); languages.dedup();
let mut errors = 0; let mut errors = 0;
let mut skips = 0;
for language in &languages { for language in &languages {
if let Some(info) = get_install_info(language) { if !force && is_installed(language, &parser_dir) {
status!("Skipping", &NOTE, "{language} (already installed)");
skips += 1;
} else if let Some(info) = get_install_info(language) {
if let Err(Error::Fatal(_)) = install_with_status( if let Err(Error::Fatal(_)) = install_with_status(
language, language,
info, info,
@ -58,6 +69,10 @@ impl Install {
} }
} }
if skips > 0 {
note!("try '{NOTE}--force{NOTE:#}' to reinstall parsers");
}
Ok(if errors > 0 { Ok(if errors > 0 {
ExitCode::FAILURE ExitCode::FAILURE
} else { } else {
@ -73,13 +88,13 @@ fn install_with_status(
src_dir: &Path, src_dir: &Path,
compiler: Option<&str>, compiler: Option<&str>,
) -> Result<languages::Revision, Error> { ) -> Result<languages::Revision, Error> {
info!("Installing", "{language}"); status!("Installing", &GOOD, "{language}");
let res = install(language, install_info, parser_dir, src_dir, compiler); let res = install(language, install_info, parser_dir, src_dir, compiler);
match &res { match &res {
Err(e) => fail!("{e}"), Err(e) => fail!("{e}"),
Ok(revision) => update!("Installed", "{language} {revision:.7}"), Ok(revision) => update!("Installed", &GOOD, "{language} {revision:.7}"),
} }
res res

View file

@ -1,3 +1,5 @@
use std::{env::consts::DLL_EXTENSION, path::Path};
use phf::phf_map; use phf::phf_map;
pub(super) type Revision = git2::Oid; pub(super) type Revision = git2::Oid;
@ -34,3 +36,10 @@ static LANGUAGES: phf::Map<&'static str, InstallInfo> = phf_map! {
pub fn get_install_info(language: &str) -> Option<&InstallInfo> { pub fn get_install_info(language: &str) -> Option<&InstallInfo> {
LANGUAGES.get(language) LANGUAGES.get(language)
} }
pub fn is_installed(language: &str, parser_dir: &Path) -> bool {
parser_dir
.join(language)
.with_extension(DLL_EXTENSION)
.exists()
}