(I'm using NSIS 2.11)
I've been using NSIS for quite some time (I'm extremely
satisfied with it, THANKS!), and "File /r" usually
works. But in one case, it gives me completely
unexpected behavior that I can't really explain.
The problem is that I run
SetOutPath "$INSTDIR"
File /r /x CVS "..\abc"
My intention is to take the entire "abc" directory tree
outside this directory (the current directory is a
subdirectory I put just the NSIS-related files in) and
copy it in the installer.
This does copy the ..\abc directory and installs it to
$INSTDIR\abc - so far so good. But the problem, it also
takes a directory called ..\hi\there\abc and copies it
to $INSTDIR\hi\there\abc! This makes no sense at all;
From the documentation it appears that if there are no
wild cards, that only one directory tree should be
copied. But even if there were wildcards and NSIS tried
to "match", how on earth did "..\hi\there\abc" match
"..\abc"? How did NSIS even decide to recursively look
for matches in ".." (I could understand if it looks for
matches in the currect directory, but in "..")?
While I'm at it, the manual page doesn't explain where
"File /r" looks for the matching files: is there an
analogue for SetOutPath but for input? Does it always
look in the current directory (in which case, where
does the ".." come from)?
Thank you very much in advance,
Nadav Har'El, nyh@math.technion.ac.il
Logged In: YES
user_id=584402
You should use:
File /r /x CVS "..\abc\*.*"
or else it'll look for all files and directories named abc
under the parent directory - ..
I've added an explanation to the documentation about this
that contains an example and should be very clear. Let me
know what you think about it.
==== snip
Note: when using the /r switch, both matching directories
and files will be searched. This is always done with or
without the use of wildcards, even if the given path
perfectly matches one directory. That means, the following
directory structure:
<DIR> something
file.dat
another.dat
<DIR> dir
something
<DIR> dir2
file2.dat
<DIR> another
<DIR> something
readme.txt
with the following File usage:
File /r something
will match the directory named something on the root
directory, the file named something in the directory named
dir and the directory named something in the directory named
another. To match only the directory named something on the
root directory, use the following:
File /r something\*.*
Logged In: NO
Hi, thanks for looking into this.
I think that the explanation you propose is not clear
enough. If "something" matches the two possible directories
(plus one file with that name), why does "something\*.*" not
match the files in both directories? After all, you explain
that "this is always done with or without the use of wildcards".
Moreover what puzzled me most is exactly which directory is
being recursively searched. I assumed it was the current
directory (where NSIS was started), but when looking for
"..\abc" it actually looked for any directory named "abc" in
".." (above the current directory!) - which to me looks more
a logic bug than a lack of documentation (although, if you
think that this behavior is ok than documenting it should be
ok, I guess).
Thanks,
Nadav.
Logged In: YES
user_id=584402
Everything up to the last path segment is the directory in
which the files and directories will be recursively looked
for. The last path segment is the part which is matched. If
the last segment is also the first segment, then the current
directory is recursively searched.
This is not a bug and it's by design. At the beginning,
`File /r` only recursively searched for files and
directories, if there was no exact match. That was a bug and
its fixed caused this not so clear behavior.
I'll try to come up with a better description over the
weekend. If you have come up with any better descriptions
until then, I'd like to hear them.
Logged In: YES
user_id=584402
How about the following?
===== snip
* If the /r switch is used, matching files and
directories are recursively searched for in subdirectories.
If just one path segment is specified (e.g. File /r
something), the current directory will be recursively
searched. If more than one segment is specified (e.g. File
/r something\*.*), the last path segment will be used as the
matching condition and the rest for the directory to search
recursively. If a directory name matches, all of its
contents is added recursively. Directory structure is preserved.
...
Note: when using the /r switch, both matching directories
and files will be searched. This is always done with or
without the use of wildcards, even if the given path
perfectly matches one directory. That means, the following
directory structure:
<DIR> something
file.dat
another.dat
<DIR> dir
something
<DIR> dir2
file2.dat
<DIR> another
<DIR> something
readme.txt
with the following File usage:
File /r something
will match the directory named something on the root
directory, the file named something in the directory named
dir and the directory named something in the directory named
another. To match only the directory named something on the
root directory, use the following:
File /r something\*.*
When adding \*.*, it will be used as the matching condition
and something will be used as the directory to search. When
only something is specified, the current directory will be
recursively searched for every and directory named something
and another\something will be matched.
Logged In: NO
Thanks for looking into this issue.
The fact that you now treat this issue in the documentation,
and even suggest a workaround, is certainly a good thing and
an improvement over the previous releases. The fact that
"File /r" is recursive not only in it's copying (like Unix's
"cp -r, for example) but also in finding what to copy, was
surprising for me (and probably for others), and now it
won't be, thanks to your proposed changes to the documentation.
However, I still think that something isn't quite right in
the way "File /r" currently behaves. It's not a big problem,
and certainly not an urgent problem, but I think it's
something you should revisit and rethink some time in the
future. There are two problems:
1. The first problem is that even with your explanation, I
expected that if I use "File /r a/b/c", then a
file/directory matching the partial patch a/b/c are searched
for in the current directory in which NSIS was started (not
in the drive's root directory, right?). I don't expect a
file in a/hello/b/c to match, right? In this case, why, when
I used the path "..\abc" does the path "..\hello\abc"
matched? This is the problem that originally bugged me: I
used "..\abc", wrongly thinking it would copy the single
directory abc in the above directory, but then I realized it
recursed in the entire "..", finding a directory looking
like "..\hi\there\abc" and copying it - this still doesn't
make sense to me, not even in light of the improved
documentation.
2. The second problem is that it is still not clear to me -
even after reading the documentation - why the workaround
you suggest works, or why it even should work. If
"abc\hello" is searched for recursively in the whole tree,
why isn't "abc\hello\*.*" also searched for recursively?
Again, the sentence "This [searching] is always done with or
without the use of wildcards" seems to imply that the same
sort of searching will work even when the given parameter is
"abc\hello\*.*". If this doesn't happen, then perhaps that
"with or without" sentence isn't quite accurate.
Thanks again,
And thanks for writing the great NSIS (which is way better
than the commercial alternative I tried!)
Nadav.
Logged In: NO
OOPS, sorry, I just noticed that in this bug tracker, unlike
Bugzilla which I'm used to, comments are listed *in
reverse*. So I didn't see that you wrote a second version of
the documentation, which better explains what is being
searched, and what is being matched.
I think the new documentation is much better, and indeed
answers all my questions (except the question of why you
decided to go with some complicated and unnatural semantics
in the first place :-)). I think you can close this bug now.
Sorry about the mess.
Nadav.
Logged In: YES
user_id=584402
Thanks Nadav, I'll upload the fix and close this ticket once
CVS is back online.
As for the reason, I've tried explaining in my second reply.
I can elaborate further, if you wish.