How do /** and /* differ in terms of directory navigation in Grunt?
Asked Answered
A

2

5

This is quite an easy one for you guys, but I can't find a definitive/formal answer to this question.

Suppose we are in directory A. Then,

"A/* " probably means: Every file and folder directly inside A.

"A/** " then may mean: Every file and folder inside A, and every file and folder directly inside every child that is directly inside A. (Basically, an extension of /* operator that traverses one level deeper of the root folder? aka "/** " = "/* /* " )

My "directly inside" terminology might be wrong. May be its better to say "direct child" or something, but you get the idea.

Then, what does "A/**/* " mean? Is it equal to "A/* /* /* " ?

Although this seems basic, its quite confusing when I don't have a formal definition of the operators.

I'm currently using Javascript and trying to modify a Gruntfile. But I guess these operators may come up in any context.

Alternation answered 19/12, 2014 at 22:11 Comment(0)
B
10

This behavior is not intrinsic to JavaScript and is not related to any operators: as far as JavaScript is concerned, it is just a string.

The handling of such glob expansion is determined by the specific library/consumer. For gruntjs it is covered in Grunt Globbing Patterns:

It is often impractical to specify all source filepaths individually, so Grunt supports filename expansion (also know as globbing) via the built-in node-glob and minimatch libraries ..

  • * matches any number of characters, but not /

  • ** matches any number of characters, including /, as long as it's the only thing in a path part

All most people need to know is that foo/*.js will match all files ending with .js in the foo/ subdirectory, but foo/**/*.js will match all files ending with .js in the foo/ subdirectory and all of its subdirectories.

As such (but refer to the specific documentation!), /**/ generally means "match any depth of directories" and /*/ or /* means "match a single directory or file part".


The gruntjs documentation is a bit vague on the specific mechanics of ** in the standard "/**/*.x" pattern, but referring to node-glob says:

If a "globstar" (**) is alone in a path portion, then it matches zero or more directories and subdirectories searching for matches. It does not crawl symlinked directories.

[.. The double-star character] is supported in the manner of bsdglob and bash 4.3, where ** only has special significance if it is the only thing in a path part. That is, a/**/b will match a/x/y/b, but a/**b will not.

Using this knowledge we get the equivalency (when used as a path component), of A/**/f with A/f, A/*/f, A/*/*/f, etc for every number of intermediate directories.

Bewilderment answered 19/12, 2014 at 22:16 Comment(6)
Oh I see better now, thanks. But I don't get this: why do I need A/**/* instead of A/** ? The way I see it, A/** can mean any file inside A and inside its subdirectories ?Alternation
@Alternation Updated the answer for the specific case.Bewilderment
Thank you for the help. I need one more specific clarification about this, because I think I understand the explanation you provide, but it is inconsistent with what I have in my hand. I'm pretty new in grunt, so I may be wrong with my assumption: I have this line: ......files: [{ expand: true, cwd: 'src/', src: ['img/**'], dest: 'www/' }]..... So what I was expecting that Its going to copy any file under img. However, if it is not matching any files, what does it do then? Return only the sub-folders and leave the file-search to grunt inside those sub-folders?Alternation
Use "img/**/*" to copy every file recursively. Without the trailing /* the globstar is not in a "path component" and thus does not expand to subdirectories as desired.Bewilderment
Actually that line does copy every folder and file under "img" to "www". So my guess is that grunt only wants the folders-list to be copied, not the files itself.Alternation
@Alternation Both approaches "should" work (but I'm not on node right now, so I can't test it and could be wrong). I would use the specific directory "img", and let normal copy recursion work, if does accomplish the desired goal.Bewilderment
S
1

If you see A/**/* that means to recursively search all the way down the tree of every folder under folder A. For more information look up basic linux style file commands.

Sibby answered 19/12, 2014 at 22:15 Comment(2)
A/**/*.js then means that every js file inside every sub-folder of A, including the A folder itself? Btw cant still find a legitimate documentation of this :/Alternation
yes, **/*.js will match any .js file under the directory. The * is a wildcard matcher for file manipulation. ** is a special wildcard that means every directory starting here so it won't match file names.Sibby

© 2022 - 2024 — McMap. All rights reserved.