Skip to content

Commit

Permalink
boulder: Fix pattern matching
Browse files Browse the repository at this point in the history
Boulder had a needless check for `starts_with` which was causing erroneous package splitting in several cases. For instance, consider the following simplified patterns:

```
- llvm-libs:
  paths:
    - /usr/lib/libLLVM.so.*

- llvm-devel:
  paths:
    - /usr/lib/libLLVM.so
```

With this setup the file `/usr/lib/libLLVM.so.18.1` should be patterned into `llvm-libs`, however since the `starts_with` match was checked first it would end up in `llvm-devel`. The point of this was to ensure that we could have "globs" that matched directories that matched subfiles/subdirectories and in order to preserve that behavior we instead match twice, once on the submitted pattern and again with `/**` appended to get a recursive glob.

Also while we're at it apply a minor adjustment to escape the directory so that all glob patterns work correctly.

Signed-off-by: Reilly Brogan <[email protected]>
  • Loading branch information
ReillyBrogan committed Jan 15, 2025
1 parent dfe12af commit a8c40c2
Showing 1 changed file with 14 additions and 4 deletions.
18 changes: 14 additions & 4 deletions boulder/src/package/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,20 @@ pub struct Rule {

impl Rule {
pub fn matches(&self, path: &str) -> bool {
self.pattern == path
|| path.starts_with(&self.pattern)
|| Pattern::new(&self.pattern)
.map(|pattern| pattern.matches(path))
if self.pattern == path {
return true;
}

// Escape the directory in case it contains characters that have special
// meaning in glob patterns (e.g., `[` or `]`).
let escaped_path = Pattern::escape(path);
Pattern::new(&self.pattern)
.map(|pattern| pattern.matches(&escaped_path))
.unwrap_or_default()
// If the supplied pattern is for a directory we want to match anything that's inside said directory,
// Do this by creating a recursive glob pattern by appending `**` if the pattern already ends in a `/` or `/**` if not
|| Pattern::new(format!("{}/**", &self.pattern.strip_suffix("/").unwrap_or(&self.pattern)).as_str())
.map(|pattern| pattern.matches(&escaped_path))
.unwrap_or_default()
}
}
Expand Down

0 comments on commit a8c40c2

Please sign in to comment.