[GRADLE-1815] Passing a closure to Project.fileTree() yields a FileTree that always resolves to zero files Created: 28/Sep/11  Updated: 04/Jan/13  Resolved: 20/Jan/12

Status: Resolved
Project: Gradle
Affects Version/s: 1.0-milestone-3
Fix Version/s: 1.0-milestone-8

Type: Bug
Reporter: Peter Niederwieser Assignee: Luke Daley
Resolution: Fixed Votes: 0


 Description   

According to the docs, Project.fileTree() can handle the same types of arguments as Project.file(). But passing a closure yields a FileTree that always resolves to zero files. Try this:

println fileTree(projectDir).files
println fileTree { projectDir }.files


 Comments   
Comment by Sean Waters [ 12/Nov/11 ]

If instead of saying fileTree

{ projectDir }

.files you said file

{ dir = projectDir }

.files then your two lines will yield the same results. The project.fileTree(Closure) method doesn't assign the result of the closure to the fileTree, instead it configures the filetree with the closure. Essentially, it is allowing you to build a fileTree in the closure by setting dir, include, exclude, etc.

Maybe this should just be an update to the documentation more than a change to the code, as the current behavior is more powerful than just setting the result of the closure to the dir value of the filetree.

Comment by Luke Daley [ 20/Jan/12 ]

fileTree(Closure) has been deprecated.

http://wiki.gradle.org/display/GRADLE/Gradle+1.0-milestone-8+Migration+Guide#Gradle1.0-milestone-8MigrationGuide-%7B%7BfileTree%28Closure%29%7D%7D

Comment by Matias Bjarland [ 24/Jan/12 ]

EDIT: The below can be ignored, I read the javadocs and realized there was now a recommended fileTree(Object, Closure) which solves the problem. Would perhaps be worth mentioning the new method in the migration guide. Reading the guide I got the impression that the method was just removed without any replacement

In my plugin code I have a situation where I have a customer editable map of the format [from: 'mydir', include: '**/*.txt'] and a static list of conventional excludes ['**/log/', '**/cat/', ...] and I need to construct a fileTree from these. In the current code I can do:

def t = project.fileTree { 
  map.each { k, v -> 
    "$k"(v)
  }
  
  excludes.each { e ->
    exclude(e)
  }
}

how would I go about constructing my FileTree with the closure version deprecated? I can not add multiple 'exclude' keys to the map...as it is, well, a map. We could do:

  //if handles the case where the customer already provided an 'excludes: x' in the map
  if(map['excludes']) map['excludes'] += excludes.join(",")
  else map['excludes'] = excludes.join(",")
  
  def f = project.fileTree(map)

which on the surface should be equivalent, though perhaps getting a bit less readable. Can't put my finger on anything specific that is blocked by this but it does feel like losing the programmatic closure way of configuring a FileTree loses some flexibility.

Comment by Luke Daley [ 25/Jan/12 ]

Good idea, I've added this to the migration guide.

Generated at Wed Jun 30 12:05:05 CDT 2021 using Jira 8.4.2#804003-sha1:d21414fc212e3af190e92c2d2ac41299b89402cf.