This chapter is a work in progress.
Most builds work with files. Gradle adds some concepts and APIs to help you do this.
You can locate a file relative to the project directory using the
Project.file()
method.
Example 14.1. Locating files
build.gradle
// Using a relative path File configFile = file('src/config.xml') // Using an absolute path configFile = file(configFile.absolutePath) // Using a File object with a relative path configFile = file(new File('src/config.xml'))
You can pass any object to the file()
method, though usually you would pass it a
String
or File
. The supplied object's toString()
value is treated as a file path. If this path is an absolute path, it is used to construct a
File
instance. Otherwise, a File
instance is constructed by
prepending the project directory path to the supplied path.
Using this method is a useful way to convert some user provided value into an absolute File
.
It is preferable to using new File(somePath)
, as file()
always evaluates
the supplied path relative to the project directory, which is fixed, rather than the current working
directory, which may not always be the same.
A file collection is simply a set of files. It is represented by the
FileCollection
interface. Many objects in Gradle implement this
interface. For example, dependency configurations implement
FileCollection
.
One way to obtain a FileCollection
instance is to use the
Project.files()
method. You can pass this method any number of objects, which are then converted into a set of File
objects. The files()
method accepts File
and String
arguments. These are evaluated relative to the project directory, as described in Section 14.1, “Locating files”.
You can also pass collections, maps and arrays to the files()
method. These are flattened
and the contents converted to File
instances.
Example 14.2. Creating a file collection
build.gradle
FileCollection collection = files('src/file1.txt', file('src/file2.txt'), ['src/file3.txt', 'src/file4.txt'])
A file collection is iterable, and can be converted to a number of other types using the as
operator. You can also add 2 file collections together using the +
operator. Here are some examples.
Example 14.3. Using a file collection
build.gradle
// Iterate over the files in the collection collection.each {File file -> file.name } // Convert the collection to various types Set set = collection.files Set set2 = collection as Set List list = collection as List String path = collection.asPath File file = collection.singleFile File file2 = collection as File // Add collections together def collection2 = collection + files('src/file3.txt')
You can also pass the files()
method a closure or a Callable
instance. This is called when the contents of the collection are queried, and its return value is converted
to a set of File
instances. The return value can be an object of any of the types
supported by the files()
method. This is a simple way to 'implement' the
FileCollection
interface.
Example 14.4. Implementing a file collection
build.gradle
task list << { File srcDir // Create a file collection using a closure collection = files { srcDir.listFiles() } // Create a file collection using a Callable Callable callable = { srcDir.listFiles() } as Callable collection = files(callable) srcDir = file('src') println "Contents of $srcDir.name" collection.each { println relativePath(it) } srcDir = file('src2') println "Contents of $srcDir.name" collection.each { println relativePath(it) } }
Output of gradle -q list
> gradle -q list Contents of src src/dir1 src/file1.txt Contents of src2 src2/dir1 src2/dir2
The files()
method also accepts FileCollection
instances.
A file tree is a hierarchy of files, such as a directory tree. It is represented
by the
FileTree
interface. The FileTree
interface
extends FileCollection
, so you can treat a file tree exactly the same way as you would a
file collection. Several objects in Gradle implement the FileTree
interface, such as
source sets.
One way to obtain a FileTree
instance is to use the
Project.fileTree()
method.
This creates a FileTree
defined with a base directory, and optionally some Ant-style
include and exclude patterns.
Example 14.5. Creating a file tree
build.gradle
// Create a file tree with a base directory def tree = fileTree(dir: 'src/main') // Add include and exclude patterns to the tree tree.include '**/*.java' tree.exclude '**/Abstract*' // Create a tree using path tree = fileTree('src').include('**/*.java') // Create a tree using closure tree = fileTree { from 'src' include '**/*.java' } // Create a tree using a map tree = fileTree(dir: 'src', includes: ['**/*.java'])
You use a file tree in the same way you use a file collection. You can also visit the contents of the tree, and select a subtree using Ant-style patterns:
Example 14.6. Using a file tree
build.gradle
// Iterate over the contents of a tree tree.each {File file -> println file } // Filter a tree def filtered = tree.matching { include 'org/gradle/api/**' } // Add trees together def sum = tree + fileTree(dir: 'src/test') // Visit the nodes of the tree tree.visit {node -> println "$node.relativePath => $node.file" }
Many objects in Gradle have properties which accept a logical set of files. For example, the
Compile
task has a source
property,
which defines the source files to compile. You can set the value of this property using any of the types
supported by the files() method, which we have seen above. This
means you can set the property using, for example, a File
, String
,
collection, FileCollection
or even a closure.
Here are some examples:
Example 14.7. Specifying a set of files
build.gradle
compile { source = file('src/main/java') } compile { source = 'src/main/java' } compile { source = ['src/main/java', '../shared/java'] } compile { source = fileTree(dir: 'src/main/java').matching { include 'org/gradle/api/**' } } compile { source = { fileTree(dir: 'src/main/java') + fileTree(dir: '../shared/java') } }
Usually, there is a method with the same name as the property, which appends to the set of files. Again, this method accepts any of the types supported by the files() method.
Example 14.8. Specifying a set of files
build.gradle
compile { source 'src/main/java', 'src/main/groovy' source file('../shared/java') source { file('src/test/').listFiles() } }
You can use the
Copy
task to copy files. The copy task allows
you to filter the contents of the files as they are copied, and to map the files names.
Example 14.9. Copying files using the copy task
build.gradle
task copyTask(type: Copy) { from 'src/main/webapp' into 'build/explodedWar' include '**/*.html' include '**/*.jsp' include 'assets/**' }
You can also use the
Project.copy()
method.
Example 14.10. Copying files using the copy() method
build.gradle
task copyMethod << { copy { from 'src/main/webapp' into 'build/explodedWar' include '**/*.html' include '**/*.jsp' include 'assets/**' } }