Skip to content

Commit

Permalink
feat: shorten output for grammar fetching and building
Browse files Browse the repository at this point in the history
New look:

```
./target/debug/hx --grammar build
Building 102 grammars ... done
100 grammars already built
02 grammars built now
    ["bash", "rust"]
```
  • Loading branch information
poliorcetics committed Aug 11, 2022
1 parent d773a6e commit c0a9eeb
Showing 1 changed file with 151 additions and 28 deletions.
179 changes: 151 additions & 28 deletions helix-loader/src/grammar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,106 @@ pub fn fetch_grammars() -> Result<()> {
let mut grammars = get_grammar_configs()?;
grammars.retain(|grammar| !matches!(grammar.source, GrammarSource::Local { .. }));

run_parallel(grammars, fetch_grammar, "fetch")
print!("Fetching {} grammars", grammars.len());
let results = run_parallel(grammars, fetch_grammar);
println!(" ... done");

let mut errors = Vec::new();
let mut git_updated = Vec::new();
let mut git_up_to_date = Vec::new();
let mut non_git = Vec::new();

for res in results {
match res {
Ok(FetchSuccess {
grammar_id,
action: FetchAction::GitUpdated { revision },
}) => git_updated.push(format!("{grammar_id}->{revision}")),
Ok(FetchSuccess {
grammar_id,
action: FetchAction::GitUpToDate,
}) => git_up_to_date.push(grammar_id),
Ok(FetchSuccess {
grammar_id,
action: FetchAction::NonGit,
}) => non_git.push(grammar_id),
Err(e) => errors.push(e),
}
}

// People will easily find the grammar they want that way
git_updated.sort_unstable();
git_up_to_date.sort_unstable();
non_git.sort_unstable();

if !git_up_to_date.is_empty() {
println!("{:02} up to date git grammars", git_up_to_date.len());
}
if !non_git.is_empty() {
println!("{:02} non git grammars", non_git.len());
println!(" {:?}", non_git);
}

if !git_updated.is_empty() {
println!("{:02} updated grammars", git_updated.len());
println!(" {:?}", git_updated);
}
if !errors.is_empty() {
let len = errors.len();
println!("{len:02} grammars failed to fetch");
for (i, error) in errors.into_iter().enumerate() {
println!(" Failure {i:02}/{len:02}: {error}")
}
}

Ok(())
}

pub fn build_grammars(target: Option<String>) -> Result<()> {
run_parallel(
get_grammar_configs()?,
move |grammar| build_grammar(grammar, target.as_deref()),
"build",
)
let grammars = get_grammar_configs()?;
print!("Building {} grammars", grammars.len());
let results = run_parallel(grammars, move |grammar| {
build_grammar(grammar, target.as_deref())
});
println!(" ... done");

let mut errors = Vec::new();
let mut built = Vec::new();
let mut already_built = Vec::new();

for res in results {
match res {
Ok(BuildSuccess {
grammar_id,
action: BuildAction::Built,
}) => built.push(grammar_id),
Ok(BuildSuccess {
grammar_id,
action: BuildAction::AlreadyBuilt,
}) => already_built.push(grammar_id),
Err(e) => errors.push(e),
}
}

built.sort_unstable();
already_built.sort_unstable();

if !already_built.is_empty() {
println!("{:02} grammars already built", already_built.len());
}
if !built.is_empty() {
println!("{:02} grammars built now", built.len());
println!(" {:?}", built);
}
if !errors.is_empty() {
let len = errors.len();
println!("{len:02} grammars failed to build");
for (i, error) in errors.into_iter().enumerate() {
println!(" Failure {i:02}/{len:02}: {error}")
}
}

Ok(())
}

// Returns the set of grammar configurations the user requests.
Expand Down Expand Up @@ -126,9 +217,10 @@ fn get_grammar_configs() -> Result<Vec<GrammarConfiguration>> {
Ok(grammars)
}

fn run_parallel<F>(grammars: Vec<GrammarConfiguration>, job: F, action: &'static str) -> Result<()>
fn run_parallel<F, Res>(grammars: Vec<GrammarConfiguration>, job: F) -> Vec<Result<Res>>
where
F: Fn(GrammarConfiguration) -> Result<()> + std::marker::Send + 'static + Clone,
F: Fn(GrammarConfiguration) -> Result<Res> + Send + 'static + Clone,
Res: Send + 'static,
{
let pool = threadpool::Builder::new().build();
let (tx, rx) = channel();
Expand All @@ -146,14 +238,21 @@ where

drop(tx);

// TODO: print all failures instead of the first one found.
rx.iter()
.find(|result| result.is_err())
.map(|err| err.with_context(|| format!("Failed to {} some grammar(s)", action)))
.unwrap_or(Ok(()))
rx.iter().collect()
}

fn fetch_grammar(grammar: GrammarConfiguration) -> Result<()> {
struct FetchSuccess {
grammar_id: String,
action: FetchAction,
}

enum FetchAction {
GitUpdated { revision: String },
GitUpToDate,
NonGit,
}

fn fetch_grammar(grammar: GrammarConfiguration) -> Result<FetchSuccess> {
if let GrammarSource::Git {
remote, revision, ..
} = grammar.source
Expand Down Expand Up @@ -189,16 +288,27 @@ fn fetch_grammar(grammar: GrammarConfiguration) -> Result<()> {
)?;
git(&grammar_dir, ["checkout", &revision])?;

println!(
"Grammar '{}' checked out at '{}'.",
grammar.grammar_id, revision
);
Ok(FetchSuccess {
grammar_id: grammar.grammar_id,
action: FetchAction::GitUpdated { revision },
})
// println!(
// "Grammar '{}' checked out at '{}'.",
// grammar.grammar_id, revision
// );
} else {
println!("Grammar '{}' is already up to date.", grammar.grammar_id);
Ok(FetchSuccess {
grammar_id: grammar.grammar_id,
action: FetchAction::GitUpToDate,
})
// println!("Grammar '{}' is already up to date.", grammar.grammar_id);
}
} else {
Ok(FetchSuccess {
grammar_id: grammar.grammar_id,
action: FetchAction::NonGit,
})
}

Ok(())
}

// Sets the remote for a repository to the given URL, creating the remote if
Expand Down Expand Up @@ -245,7 +355,17 @@ where
}
}

fn build_grammar(grammar: GrammarConfiguration, target: Option<&str>) -> Result<()> {
struct BuildSuccess {
grammar_id: String,
action: BuildAction,
}

enum BuildAction {
Built,
AlreadyBuilt,
}

fn build_grammar(grammar: GrammarConfiguration, target: Option<&str>) -> Result<BuildSuccess> {
let grammar_dir = if let GrammarSource::Local { path } = &grammar.source {
PathBuf::from(&path)
} else {
Expand Down Expand Up @@ -285,7 +405,7 @@ fn build_tree_sitter_library(
src_path: &Path,
grammar: GrammarConfiguration,
target: Option<&str>,
) -> Result<()> {
) -> Result<BuildSuccess> {
let header_path = src_path;
let parser_path = src_path.join("parser.c");
let mut scanner_path = src_path.join("scanner.c");
Expand All @@ -308,12 +428,12 @@ fn build_tree_sitter_library(
.context("Failed to compare source and binary timestamps")?;

if !recompile {
println!("Grammar '{}' is already built.", grammar.grammar_id);
return Ok(());
return Ok(BuildSuccess {
grammar_id: grammar.grammar_id,
action: BuildAction::AlreadyBuilt,
});
}

println!("Building grammar '{}'", grammar.grammar_id);

let mut config = cc::Build::new();
config
.cpp(true)
Expand Down Expand Up @@ -381,7 +501,10 @@ fn build_tree_sitter_library(
));
}

Ok(())
Ok(BuildSuccess {
grammar_id: grammar.grammar_id,
action: BuildAction::Built,
})
}

fn needs_recompile(
Expand Down

0 comments on commit c0a9eeb

Please sign in to comment.