|
1 | 1 | use std::{ |
2 | 2 | fs::File, |
3 | | - io::BufRead, |
4 | 3 | path::{Path, PathBuf}, |
5 | 4 | }; |
6 | 5 |
|
7 | 6 | use error_stack::{Result, ResultExt}; |
8 | 7 | use fast_glob::glob_match; |
9 | 8 | use ignore::WalkBuilder; |
10 | 9 | use jwalk::{DirEntry, WalkDir}; |
| 10 | +use lazy_static::lazy_static; |
11 | 11 | use rayon::iter::{IntoParallelIterator, ParallelIterator}; |
12 | 12 | use regex::Regex; |
13 | | -use tracing::{info, instrument}; |
| 13 | +use tracing::instrument; |
14 | 14 |
|
15 | 15 | use crate::{ |
16 | 16 | config::Config, |
@@ -350,41 +350,35 @@ fn javascript_package_owner(path: &Path) -> Result<Option<String>, Error> { |
350 | 350 | Ok(deserializer.metadata.and_then(|metadata| metadata.owner)) |
351 | 351 | } |
352 | 352 |
|
| 353 | +lazy_static! { |
| 354 | + static ref TEAM_REGEX: Regex = Regex::new(r#"^(?:#|//) @team (.*)$"#).expect("error compiling regular expression"); |
| 355 | +} |
| 356 | + |
353 | 357 | #[instrument(level = "debug", skip_all)] |
354 | 358 | fn owned_files(owned_file_paths: Vec<PathBuf>) -> Vec<ProjectFile> { |
355 | | - let regexp = Regex::new(r#"^(?:#|//) @team (.*)$"#).expect("error compiling regular expression"); |
356 | | - |
357 | | - info!("opening files to read ownership annotation"); |
358 | | - |
359 | | - owned_file_paths |
360 | | - .into_par_iter() |
361 | | - .map(|path| { |
362 | | - let file = File::open(&path).unwrap_or_else(|_| panic!("Couldn't open {}", path.to_string_lossy())); |
363 | | - let first_line = std::io::BufReader::new(file).lines().next().transpose(); |
364 | | - let first_line = first_line.expect("error reading first line"); |
| 359 | + owned_file_paths.into_par_iter().map(build_project_file).collect() |
| 360 | +} |
365 | 361 |
|
366 | | - if first_line.is_none() { |
367 | | - return ProjectFile { path, owner: None }; |
368 | | - } |
| 362 | +fn build_project_file(path: PathBuf) -> ProjectFile { |
| 363 | + let content = match std::fs::read_to_string(&path) { |
| 364 | + Ok(content) => content, |
| 365 | + Err(_) => return ProjectFile { path, owner: None }, |
| 366 | + }; |
369 | 367 |
|
370 | | - if let Some(first_line) = first_line { |
371 | | - let capture = regexp.captures(&first_line); |
| 368 | + let first_line = content.lines().next(); |
372 | 369 |
|
373 | | - if let Some(capture) = capture { |
374 | | - let first_capture = capture.get(1); |
| 370 | + // Early return if empty file |
| 371 | + let Some(first_line) = first_line else { |
| 372 | + return ProjectFile { path, owner: None }; |
| 373 | + }; |
375 | 374 |
|
376 | | - if let Some(first_capture) = first_capture { |
377 | | - return ProjectFile { |
378 | | - path, |
379 | | - owner: Some(first_capture.as_str().to_string()), |
380 | | - }; |
381 | | - } |
382 | | - } |
383 | | - } |
| 375 | + // Use TEAM_REGEX instead of regexp |
| 376 | + let owner = TEAM_REGEX |
| 377 | + .captures(first_line) |
| 378 | + .and_then(|cap| cap.get(1)) |
| 379 | + .map(|m| m.as_str().to_string()); |
384 | 380 |
|
385 | | - ProjectFile { path, owner: None } |
386 | | - }) |
387 | | - .collect() |
| 381 | + ProjectFile { path, owner } |
388 | 382 | } |
389 | 383 |
|
390 | 384 | #[cfg(test)] |
|
0 commit comments