Skip to content

Commit

Permalink
chore: create newtype to better handle globs with working directory
Browse files Browse the repository at this point in the history
  • Loading branch information
ematipico committed Jan 22, 2025
1 parent abe70bf commit f39271a
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 12 deletions.
2 changes: 1 addition & 1 deletion crates/biome_glob/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ impl schemars::JsonSchema for Glob {
pub struct CandidatePath<'a>(globset::Candidate<'a>);
impl<'a> CandidatePath<'a> {
/// Create a new candidate for matching from the given path.
pub fn new(path: &'a impl AsRef<std::path::Path>) -> Self {
pub fn new<P: AsRef<std::path::Path> + ?Sized>(path: &'a P) -> Self {
Self(globset::Candidate::new(path))
}

Expand Down
89 changes: 81 additions & 8 deletions crates/biome_service/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -600,12 +600,80 @@ pub struct FilesSettings {
pub included_files: Matcher,

/// List of included paths/files
pub includes_files: Box<[biome_glob::Glob]>,
pub includes_files: IncludesFiles,

/// Files not recognized by Biome should not emit a diagnostic
pub ignore_unknown: Option<FilesIgnoreUnknownEnabled>,
}

#[derive(Clone, Default, Debug)]
pub struct IncludesFiles {
working_directory: Option<Utf8PathBuf>,
includes_files: Option<Box<[biome_glob::Glob]>>,
}

impl IncludesFiles {
fn new(
working_directory: Option<Utf8PathBuf>,
includes_files: Option<&[biome_glob::Glob]>,
) -> Self {
if let Some(includes_files) = includes_files {
// NOTE: when Bpaf deserialize this value, it returns `Some([])` as default value, even when
// there aren't any globs. This is a limitation/bug, which means that we need to treat
// `Some([])` as no globs provided.
if includes_files.is_empty() {
Self {
working_directory,
includes_files: None,
}
} else {
Self {
working_directory,
includes_files: Some(includes_files.to_vec().into_boxed_slice()),
}
}
} else {
Self {
working_directory,
includes_files: None,
}
}
}

pub fn is_empty(&self) -> bool {
self.includes_files.is_none()
}

pub fn matches_with_exceptions(&self, path: &Utf8Path) -> bool {
if let Some(includes_files) = self.includes_files.as_ref() {
let path = if let Some(working_directory) = &self.working_directory {
path.strip_prefix(working_directory).unwrap_or(path)
} else {
path
};
let candidate_path = biome_glob::CandidatePath::new(path);

candidate_path.matches_with_exceptions(includes_files)
} else {
true
}
}

pub fn matches_directory_with_exceptions(&self, path: &Utf8Path) -> bool {
if let Some(includes_files) = self.includes_files.as_ref() {
let path = if let Some(working_directory) = &self.working_directory {
path.strip_prefix(working_directory).unwrap_or(path)
} else {
path
};
let candidate_path = biome_glob::CandidatePath::new(path);
candidate_path.matches_directory_with_exceptions(includes_files)
} else {
true
}
}
}

fn to_file_settings(
working_directory: Option<Utf8PathBuf>,
config: Option<FilesConfiguration>,
Expand All @@ -632,8 +700,11 @@ fn to_file_settings(
working_directory.clone(),
config.ignore.as_deref(),
)?,
included_files: Matcher::from_globs(working_directory, config.include.as_deref())?,
includes_files: config.includes.unwrap_or_default().into(),
included_files: Matcher::from_globs(
working_directory.clone(),
config.include.as_deref(),
)?,
includes_files: IncludesFiles::new(working_directory, config.includes.as_deref()),
ignore_unknown: config.ignore_unknown,
})
} else {
Expand Down Expand Up @@ -1016,7 +1087,7 @@ impl OverrideSettings {
pub struct OverrideSettingPattern {
exclude: Matcher,
include: Matcher,
includes: Box<[biome_glob::Glob]>,
includes_files: IncludesFiles,
/// Formatter settings applied to all files in the workspaces
pub formatter: OverrideFormatSettings,
/// Linter settings applied to all files in the workspace
Expand All @@ -1037,9 +1108,8 @@ impl OverrideSettingPattern {
return false;
}
self.include.matches_path(file_path)
|| if !self.includes.is_empty() {
let candidate_path = biome_glob::CandidatePath::new(&file_path);
candidate_path.matches_with_exceptions(&self.includes)
|| if !self.includes_files.is_empty() {
self.includes_files.matches_with_exceptions(&file_path)
} else {
false
}
Expand Down Expand Up @@ -1318,7 +1388,10 @@ pub fn to_override_settings(
languages.html = to_html_language_settings(html, &current_settings.languages.html);

let pattern_setting = OverrideSettingPattern {
includes: pattern.includes.unwrap_or_default().into(),
includes_files: IncludesFiles::new(
working_directory.clone(),
pattern.includes.as_deref(),
),
include: Matcher::from_globs(working_directory.clone(), pattern.include.as_deref())?,
exclude: Matcher::from_globs(working_directory.clone(), pattern.ignore.as_deref())?,
formatter,
Expand Down
7 changes: 4 additions & 3 deletions crates/biome_service/src/workspace/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -484,11 +484,12 @@ impl WorkspaceServer {
};
let mut is_included = true;
if !files_settings.includes_files.is_empty() {
let candidate_path = biome_glob::CandidatePath::new(&path);
is_included = if is_dir(path) {
candidate_path.matches_directory_with_exceptions(&files_settings.includes_files)
files_settings
.includes_files
.matches_directory_with_exceptions(path)
} else {
candidate_path.matches_with_exceptions(&files_settings.includes_files)
files_settings.includes_files.matches_with_exceptions(path)
};
}
if !files_settings.included_files.is_empty() {
Expand Down

0 comments on commit f39271a

Please sign in to comment.