on master help sign in
feat: shorten output for grammar fetching and building (#3396)

New look: ``` Fetching 102 grammars 98 up to date git grammars 4 updated grammars bash now on 275effdfc0edce774acf7d481f9ea195c6c403cd beancount now on 4cbd1f09cd07c1f1fabf867c2cf354f9da53cc4c c now on f05e279aedde06a25801c3f2b2cc8ac17fac52ae c-sharp now on 53a65a908167d6556e1fcdb67f1ee62aac101dda ``` ``` Building 102 grammars 100 grammars already built 2 grammars built now ["bash", "rust"] ```

commit6618cf2d685dbf2255c7357ba90326baba70cb1f authorPoliorcetics <poliorcetics@users.noreply.github.com> dateWed 17 Aug 2022, 03:37 (4 years ago) parent956fbab
1 file changed+129−28
helix-loader/src/grammar.rs+129−28
helix-loader/src/grammar.rs+129−28
@@ -89,15 +89,102 @@ pub fn fetch_grammars() -> Result<()> {
8989 let mut grammars = get_grammar_configs()?;
9090 grammars.retain(|grammar| !matches!(grammar.source, GrammarSource::Local { .. }));
9191
92− run_parallel(grammars, fetch_grammar, "fetch")
92+ println!("Fetching {} grammars", grammars.len());
93+ let results = run_parallel(grammars, fetch_grammar);
94+
95+ let mut errors = Vec::new();
96+ let mut git_updated = Vec::new();
97+ let mut git_up_to_date = 0;
98+ let mut non_git = Vec::new();
99+
100+ for res in results {
101+ match res {
102+ Ok(FetchStatus::GitUpToDate) => git_up_to_date += 1,
103+ Ok(FetchStatus::GitUpdated {
104+ grammar_id,
105+ revision,
106+ }) => git_updated.push((grammar_id, revision)),
107+ Ok(FetchStatus::NonGit { grammar_id }) => non_git.push(grammar_id),
108+ Err(e) => errors.push(e),
109+ }
110+ }
111+
112+ non_git.sort_unstable();
113+ git_updated.sort_unstable_by(|a, b| a.0.cmp(&b.0));
114+
115+ if git_up_to_date != 0 {
116+ println!("{} up to date git grammars", git_up_to_date);
117+ }
118+
119+ if !non_git.is_empty() {
120+ println!("{} non git grammars", non_git.len());
121+ println!("\t{:?}", non_git);
122+ }
123+
124+ if !git_updated.is_empty() {
125+ println!("{} updated grammars", git_updated.len());
126+ // We checked the vec is not empty, unwrapping will not panic
127+ let longest_id = git_updated.iter().map(|x| x.0.len()).max().unwrap();
128+ for (id, rev) in git_updated {
129+ println!(
130+ "\t{id:width$} now on {rev}",
131+ id = id,
132+ width = longest_id,
133+ rev = rev
134+ );
135+ }
136+ }
137+
138+ if !errors.is_empty() {
139+ let len = errors.len();
140+ println!("{} grammars failed to fetch", len);
141+ for (i, error) in errors.into_iter().enumerate() {
142+ println!("\tFailure {}/{}: {}", i, len, error);
143+ }
144+ }
145+
146+ Ok(())
93147}
94148
95149pub fn build_grammars(target: Option<String>) -> Result<()> {
96− run_parallel(
97− get_grammar_configs()?,
98− move |grammar| build_grammar(grammar, target.as_deref()),
99− "build",
100− )
150+ let grammars = get_grammar_configs()?;
151+ println!("Building {} grammars", grammars.len());
152+ let results = run_parallel(grammars, move |grammar| {
153+ build_grammar(grammar, target.as_deref())
154+ });
155+
156+ let mut errors = Vec::new();
157+ let mut already_built = 0;
158+ let mut built = Vec::new();
159+
160+ for res in results {
161+ match res {
162+ Ok(BuildStatus::AlreadyBuilt) => already_built += 1,
163+ Ok(BuildStatus::Built { grammar_id }) => built.push(grammar_id),
164+ Err(e) => errors.push(e),
165+ }
166+ }
167+
168+ built.sort_unstable();
169+
170+ if already_built != 0 {
171+ println!("{} grammars already built", already_built);
172+ }
173+
174+ if !built.is_empty() {
175+ println!("{} grammars built now", built.len());
176+ println!("\t{:?}", built);
177+ }
178+
179+ if !errors.is_empty() {
180+ let len = errors.len();
181+ println!("{} grammars failed to build", len);
182+ for (i, error) in errors.into_iter().enumerate() {
183+ println!("\tFailure {}/{}: {}", i, len, error);
184+ }
185+ }
186+
187+ Ok(())
101188}
102189
103190// Returns the set of grammar configurations the user requests.
@@ -126,9 +213,10 @@ fn get_grammar_configs() -> Result<Vec<GrammarConfiguration>> {
126213 Ok(grammars)
127214}
128215
129−fn run_parallel<F>(grammars: Vec<GrammarConfiguration>, job: F, action: &'static str) -> Result<()>
216+fn run_parallel<F, Res>(grammars: Vec<GrammarConfiguration>, job: F) -> Vec<Result<Res>>
130217where
131− F: Fn(GrammarConfiguration) -> Result<()> + std::marker::Send + 'static + Clone,
218+ F: Fn(GrammarConfiguration) -> Result<Res> + Send + 'static + Clone,
219+ Res: Send + 'static,
132220{
133221 let pool = threadpool::Builder::new().build();
134222 let (tx, rx) = channel();
@@ -146,14 +234,21 @@ where
146234
147235 drop(tx);
148236
149− // TODO: print all failures instead of the first one found.
150− rx.iter()
151− .find(|result| result.is_err())
152− .map(|err| err.with_context(|| format!("Failed to {} some grammar(s)", action)))
153− .unwrap_or(Ok(()))
237+ rx.iter().collect()
238+}
239+
240+enum FetchStatus {
241+ GitUpToDate,
242+ GitUpdated {
243+ grammar_id: String,
244+ revision: String,
245+ },
246+ NonGit {
247+ grammar_id: String,
248+ },
154249}
155250
156−fn fetch_grammar(grammar: GrammarConfiguration) -> Result<()> {
251+fn fetch_grammar(grammar: GrammarConfiguration) -> Result<FetchStatus> {
157252 if let GrammarSource::Git {
158253 remote, revision, ..
159254 } = grammar.source
@@ -189,16 +284,18 @@ fn fetch_grammar(grammar: GrammarConfiguration) -> Result<()> {
189284 )?;
190285 git(&grammar_dir, ["checkout", &revision])?;
191286
192− println!(
193− "Grammar '{}' checked out at '{}'.",
194− grammar.grammar_id, revision
195− );
287+ Ok(FetchStatus::GitUpdated {
288+ grammar_id: grammar.grammar_id,
289+ revision,
290+ })
196291 } else {
197− println!("Grammar '{}' is already up to date.", grammar.grammar_id);
292+ Ok(FetchStatus::GitUpToDate)
198293 }
294+ } else {
295+ Ok(FetchStatus::NonGit {
296+ grammar_id: grammar.grammar_id,
297+ })
199298 }
200−
201− Ok(())
202299}
203300
204301// Sets the remote for a repository to the given URL, creating the remote if
@@ -245,7 +342,12 @@ where
245342 }
246343}
247344
248−fn build_grammar(grammar: GrammarConfiguration, target: Option<&str>) -> Result<()> {
345+enum BuildStatus {
346+ AlreadyBuilt,
347+ Built { grammar_id: String },
348+}
349+
350+fn build_grammar(grammar: GrammarConfiguration, target: Option<&str>) -> Result<BuildStatus> {
249351 let grammar_dir = if let GrammarSource::Local { path } = &grammar.source {
250352 PathBuf::from(&path)
251353 } else {
@@ -285,7 +387,7 @@ fn build_tree_sitter_library(
285387 src_path: &Path,
286388 grammar: GrammarConfiguration,
287389 target: Option<&str>,
288−) -> Result<()> {
390+) -> Result<BuildStatus> {
289391 let header_path = src_path;
290392 let parser_path = src_path.join("parser.c");
291393 let mut scanner_path = src_path.join("scanner.c");
@@ -308,12 +410,9 @@ fn build_tree_sitter_library(
308410 .context("Failed to compare source and binary timestamps")?;
309411
310412 if !recompile {
311− println!("Grammar '{}' is already built.", grammar.grammar_id);
312− return Ok(());
413+ return Ok(BuildStatus::AlreadyBuilt);
313414 }
314415
315− println!("Building grammar '{}'", grammar.grammar_id);
316−
317416 let mut config = cc::Build::new();
318417 config
319418 .cpp(true)
@@ -381,7 +480,9 @@ fn build_tree_sitter_library(
381480 ));
382481 }
383482
384− Ok(())
483+ Ok(BuildStatus::Built {
484+ grammar_id: grammar.grammar_id,
485+ })
385486}
386487
387488fn needs_recompile(