olson-sean-k / wax

Opinionated and portable globs that can be matched against paths and directory trees.
https://glob.guide
MIT License
115 stars 10 forks source link

Single wildcard tree does never matches #54

Open rnza0u opened 10 months ago

rnza0u commented 10 months ago

Hello,

I might have noticed a bug.

It is stated in the documentation that "If a glob expression consists solely of a tree wildcard, then it matches any and all paths and the complete contents of any and all directory trees, including the root".

I have the following file structure in /tmp/files:

├── dir1
 |   ├── file.txt
├── dir2
 |   ├── file.txt
├── dir3
 |   ├── file.txt

with the following Rust code:

fn main() {
    let paths = wax::Glob::new("**").unwrap()
        .walk(std::path::Path::new("/tmp/files"))
        .not::<[&str; 0]>([]).unwrap()
        .map(|entry| entry.unwrap().path().to_owned())
        .collect::<Vec<_>>();

    println!("{:?}", paths);
}

The output is:

[]

when i remove the negation:

fn main() {
    let paths = wax::Glob::new("**").unwrap()
        .walk(std::path::Path::new("/tmp/files"))
        .map(|entry| entry.unwrap().path().to_owned())
        .collect::<Vec<_>>();

    println!("{:?}", paths);
}

it works:

["/tmp/files", "/tmp/files/dir3", "/tmp/files/dir3/file.txt", "/tmp/files/dir2", "/tmp/files/dir2/file.txt", "/tmp/files/dir1", "/tmp/files/dir1/file.txt"]

Did i miss anything ?

olson-sean-k commented 10 months ago

Thanks for the report! Yes, this is definitely a bug! Your first example should indeed yield the entire contents of the directory.

When given an empty collection, not constructs a bogus Any token. This particular API has already been fixed in 76afaa1. However, there isn't yet a test for this and only not has been fixed: this can still happen via the any function in the crate root. To be sure, I just tried a test very similar to this one where the collection is empty and confirmed the correct behavior.

I'll leave this issue open until I land an appropriate test and change all of the concerned APIs such that they don't construct garbage from empty collections.

rnza0u commented 10 months ago

Yes, i read the code and i came to the same conclusion.

The exhaustive and nonexhaustive generated regexes in the WalkNegation were both set to something like this if i remember correctly: ^()$