Menu

#461 Nonsensical behavior from File /r

closed-fixed
5
2006-04-05
2006-03-12
Anonymous
No

(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

Discussion

  • Amir Szekely

    Amir Szekely - 2006-03-14
    • labels: --> Documentation
    • assigned_to: nobody --> kichik
    • status: open --> open-fixed
     
  • Amir Szekely

    Amir Szekely - 2006-03-14

    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\*.*

     
  • Nobody/Anonymous

    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.

     
  • Amir Szekely

    Amir Szekely - 2006-03-21

    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.

     
  • Amir Szekely

    Amir Szekely - 2006-03-25

    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.

     
  • Nobody/Anonymous

    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.

     
  • Nobody/Anonymous

    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.

     
  • Amir Szekely

    Amir Szekely - 2006-04-02

    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.

     
  • Amir Szekely

    Amir Szekely - 2006-04-05
    • status: open-fixed --> closed-fixed
     

Log in to post a comment.