How do /** and /* differ in terms of directory navigation in Grunt? - directory

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.

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.

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.

Related

Return one folder above current directory in Julia

In Julia, I can get the current directory from
#__DIR__
For example, when I run the above in the "Current" folder, it gives me
"/Users/jtheath/Dropbox/Research/Projects/Coding/Current"
However, I want it to return one folder above the present folder; i.e.,
"/Users/jtheath/Dropbox/Research/Projects/Coding"
Is there an easy way to do this in a Julia script?
First, please note that #__DIR__ generally expands to the directory of the current source file (it does however return the current working directory if there are no source files involved, e.g when run from the REPL). In order to reliably get the current working directory, you should rather use pwd().
Now to your real question: I think the easiest way to get the path to the parent directory would be to simply use dirname:
julia> dirname("/Users/jtheath/Dropbox/Research/Projects/Coding/Current")
"/Users/jtheath/Dropbox/Research/Projects/Coding"
Note that AFAIU this only uses string manipulations, and does not care whether the paths involved actually exist in the filesystem (which is why the example above works on my system although I do not have the same filesystem structure as you). dirname is also relatively sensitive to the presence/absence of a trailing slash (which shouldn't be a problem if you feed it something that comes directly from pwd() or #__DIR__).
I sometimes also use something like this, in the hope that it might be more robust when I want to work with paths that actually exist in the filesystem:
julia> curdir = pwd()
"/home/francois"
julia> abspath(joinpath(curdir, ".."))
"/home/"

Why does gnu make delete this file?

Consider this Makefile:
.PHONY: all
all: main.txt
main.txt: build/main.txt
cp build/main.txt .
%/main.txt: %/data.txt
cp $*/data.txt $*/main.txt
%/data.txt:
touch $*/data.txt
After running make, build/data.txt is removed automatically. Why is this the case?
I tried adding .PRECIOUS: build/% to the file, but it it not help, the file was still removed. How can I prevent this?
According to the GNU Make documentation
You can also list the target pattern of an implicit rule (such as ‘%.o’) as a prerequisite file of the special target .PRECIOUS to preserve intermediate files created by rules whose target patterns match that file’s name.
the prerequisite for.PRECIOUS needs to be the (exact) target pattern of an existing implicit rule.
In your case this would be %/data.txt instead.
The documentation hints at this, but is not particularly clear about it.
As a side note: As far as I can tell build/main.txt is not automatically deleted since it is explicitly named as a prerequisite for the main.txt target and build/data.txt is automatically deleted since it is never explicitly named.

what is the meaning of ${PWD:A}?

I am reading some zsh scripts and found this syntax ${PWD:A}. I know what $PWD is and the bash variable substitution syntax (largely thanks to this excellent tutorial). Despite of that, I haven't found any docs that explain about the ${variable:flag} syntax for zsh.
${PWD:A} returns the symlink-free absolute path of $PWD. It does so by:
prepending the current directory
resolving any .. and .
resolving symbolic links, if the system has the realpath system call - which modern systems do.
As $PWD already is the absolute path of the current directory and does not contain .. or . elements (at least it really should not), ${PWD:A} only has to resolve any symbolic links.
The ${name:flag} syntax allows the use of History Expansion Modifiers on parameters.
It actually is explained in the section Parameter Expansion of the ZSH Manual (see also man zshexpn). Unfortunately it is just a single sentence in the text and not listed with the other ${nameXXXXX} expansions:
In addition to the following operations, the colon modifiers described in Modifiers in History Expansion can be applied: for example, ${i:s/foo/bar/} performs string substitution on the expansion of parameter $i.
A list of the available modifiers can be found in the subsection Modifiers under History Expansion. In the case of A:
a
Turn a file name into an absolute path: prepends the current directory, if necessary, and resolves any use of .. and . in the path. Note that the transformation takes place even if the file or any intervening directories do not exist.
A
As a, but also resolve use of symbolic links where possible. Note that resolution of .. occurs before resolution of symbolic links. This call is equivalent to a unless your system has the realpath system call (modern systems do).

make does not realize that a relative path name dependency is the same as an absolute pathname target

The following is a simplified makefile for a problem I'm having:
all: /tmp/makey/../filey
#echo All done
/tmp/filey:
#echo Filey
When I run make it says:
make-3.79.1-p7: * No rule to make target /tmp/makey/../filey', needed byall'. Stop.
Clearly it does not realize that /tmp/makey/../filey is the same as /tmp/filey. Any ideas how I can make this work?
Thanks
Ciao
-- Murali
Newer versions of GNU make have $(abspath ...) and $(realpath ...) functions you can apply to your prerequisites and targets to resolve the paths to the same string. If you've constructed these names yourself (for example, $(PREFIX)/../filey) then you can use $(dir $(PREFIX))filey instead.
Other than that, there's no way to solve this problem. Make uses string matching on targets and if the strings are not identical, they don't match (there's a special case to ignore the simple prefix ./) Even if make understood this distinction (by applying abspath itself to each target name, maybe) it would still not help in the face of symbolic links for example.
The only "real" answer would be for make to understand something about the underlying file system (device IDs and inodes for example) that let you talk about files without referring to their pathname. However, in a portable program like make doing this is problematic.

Server.MapPath does not like ~/ and ./

I am using the following code to try and find a file contained in another directory from my code file.
Set fi=fs.OpenTextFile(Server.MapPath("~/counter/counter.txt"), 1)
I have also tried.
Set fi=fs.OpenTextFile(Server.MapPath("./root/folder1/counter/counter.txt"), 1)
In either case this should get me back to the counter.txt file. From what I understand ~/ moves up 1 directory and ./ moves up to the root directory.
Both times however I receive an error saying an invalid character has been used. When removing these I get a different error saying the path cannot be found (Which I would expect because it is not a valid path without moving up 1 directory).
What are the valid characters to do the following in VBscript:
move up a single directory?
move up to the root directory?
Thanks for the help
A few things:
The tilde character "~" is not valid here.
The single period character "." is for specifying the current directory/folder.
A set of period characters ".." is for specifying the parent directory/folder. For example, to refer to a file found in the parent of the current directory, you might use:
Server.MapPath("../counter.txt")
You can chain these to walk up more than a single parent path. To refer to a file found three directories above the current, you might use:
Server.MapPath("../../../counter.txt")
The documentation on MSDN for the MapPath function outlines this. Pay attention to the caution listed here about enabling parent paths if you want to be able to refer to relative paths above the current directory. If you get an error when trying to refer to a parent path, then you do not have parent paths enabled.

Resources