Bug 59114 - Inconsistency in Copy Task with empty FileSet depending on "exclude" pattern
Summary: Inconsistency in Copy Task with empty FileSet depending on "exclude" pattern
Status: NEW
Alias: None
Product: Ant
Classification: Unclassified
Component: Core tasks (show other bugs)
Version: 1.9.6
Hardware: Macintosh other
: P3 minor (vote)
Target Milestone: ---
Assignee: Ant Notifications List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-03-04 08:15 UTC by Pepper LebeckJobe
Modified: 2016-04-11 22:30 UTC (History)
0 users



Attachments
Reproduction Ant Build Script (1.31 KB, text/plain)
2016-03-04 08:15 UTC, Pepper LebeckJobe
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Pepper LebeckJobe 2016-03-04 08:15:01 UTC
Created attachment 33622 [details]
Reproduction Ant Build Script

Overview:
When you are copying an empty FileSet to a target location, the target directory is created if the empty FileSet was accomplished with '<exclude name="*" />' but not if it was accomplished with '<exclude name="**" />'

Steps to Reproduce:
1) Download the attached build.xml into an empty directory.
2) Run 'ant' in that directory.

Actual Results:
The results of 'find .' in that directory are:
$> find .
.
./ant-out
./ant-out/cpyExStar
./build.xml
./src
./src/empty

Expected Results:
Either one of the following would be fine outputs:
$> find .
.
./build.xml
./src
./src/empty

$> find .
.
./ant-out
./ant-out/cpyExStar
./ant-out/cpyExStars
./build.xml
./src
./src/empty

This bug is only concerned with the fact that the Copy task behaves differently based on whether the empty FileSet is obtained with '<exclude name="*" />' or '<exclude name="**" />'

I will admit that I have a slight preference for the first of the two possible 'Expected Results' because if you don't have anything to copy to the destination, why create the destination directory at all. But, I don't really care as long as it is a consistent and reliable result.

Build Environment:
OS: Mac OS X 10.11.3 (although I suspect it could be reproduced on many)
Java Versions: 1.8.0_72, 1.7.0_79, 1.6.0_65
ant version: 1.9.6 (also reproduced from current master branch of any git repo)
Comment 1 Antoine Levy-Lambert 2016-03-07 03:54:25 UTC
I just committed a testcase which illustrates the current behavior of Ant concerning the application of the "**" and the "*" pattern to the empty path.
See https://github.com/apache/ant/commit/8bb69bfdd8201ffbd531097d95f29c8a3e88a7a6

The logic to handle the root directory of a fileset is at this location :

https://github.com/apache/ant/blob/master/src/main/org/apache/tools/ant/DirectoryScanner.java#L897

My understanding is that "**" matches any length of path including file separators, while "*" matches any length of path without the file separator. Why "*" currently does not match the root empty directory is surprising. 

Patterns are documented here :
http://ant.apache.org/manual/dirtasks.html#patterns
Comment 2 Antoine Levy-Lambert 2016-03-07 04:38:33 UTC
This line https://github.com/apache/ant/blob/master/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java#L243 is the line which would need to be changed to deal with the bug report.
Comment 3 Pepper LebeckJobe 2016-03-07 13:08:11 UTC
(In reply to Antoine Levy-Lambert from comment #2)
> This line
> https://github.com/apache/ant/blob/master/src/main/org/apache/tools/ant/
> types/selectors/SelectorUtils.java#L243 is the line which would need to be
> changed to deal with the bug report.

I find that code sort of hard to follow. Are you saying that if we didn't perform that check, then "**" would also match the root directory and create the target directory OR are you saying that we should include "*" in that check as well so that the routine would return false for the case where the only patten is "*"? Or something else?
Comment 4 Antoine Levy-Lambert 2016-04-11 22:30:32 UTC
I meant that to fix the bug we should probably change the condition

!tokenizedPattern[i].equals(DEEP_TREE_MATCH)

to become

!( tokenizedPattern[i].equals(DEEP_TREE_MATCH) || tokenizedPattern[i].equals("*"))

Also there should be a constant in Ant for "*".