node.jsglobautomataminimatch

How to detect programmatically if two Globs intersect or not in Node.js?


In below array, the first glob is a subset of the second one:

[
  "HomePage/03-LocalDevelopmentBuild/public/**/*.@(js)",
  "HomePage/03-LocalDevelopmentBuild/**/*.@(js)"
]

But how can we detect it programmatically? AFAIK, the "minimatch" compares only the file path or directory path with the glob, not 2 globs.


Solution

  • As you found out, minimatch is not a good match for this task. Instead, we will have to create the algorithm ourselves (this allows for greater time efficiency when running the code since it is only handling strings). First, we have to separate the globs into the main path and the part with asterisks. We will call them path and juice, respectively:

    function splitGlobs(glob) {
        let glob_arr = glob.split("*");
        let globPath = glob_arr[0];
        let globJuice = "";
        for (let i = 0; i < glob_arr.length; i++) {
            if (i != 0) {
                globJuice += "*" + glob_arr[i];
            }
        }
        return { path: globPath, juice: globJuice };
    }
    

    Now, we will have to input our globs and separate them using splitGlobs():

    const globs = [
        "HomePage/03-LocalDevelopmentBuild/**/*.@(js)",
        "HomePage/03-LocalDevelopmentBuild/public/**/*.@(js)",
    ];
    
    let glob0 = splitGlobs(globs[0]);
    let glob1 = splitGlobs(globs[1]);
    

    And now, for the main logic of the algorithm, we just have to check if one is or is not a subset of the other:

    if (glob0.juice != glob1.juice) {
        console.log(
            `${globs[0]} and ${globs[1]} are not subsets -- they do not target the same file type.`,
        );
    } else if (glob0.path.includes(glob1.path)) {
        console.log(`${globs[0]} is a subset of ${globs[1]}.`);
    } else if (glob1.path.includes(glob0.path)) {
        console.log(`${globs[1]} is a subset of ${globs[0]}.`);
    } else {
        console.log(
            `${globs[0]} and ${globs[1]} target the same file type, yet they are not subsets.`,
        );
    }
    

    Executing all the code yields

    HomePage/03-LocalDevelopmentBuild/public/**/*.@(js) is a subset of HomePage/03-LocalDevelopmentBuild/**/*.@(js).

    as expected. Now it is up to you to change the dummy text for real functionalities!

    Hope this helped! And may the code be with you...