Project类中有一个file方法可以用来定位文件。
build.gradle:
File configFile = file('src/config.xml') configFile = file(configFile.absolutePath) println configFile.path configFile = file(new File('src/config.xml'))
D:\GRADLE~2\0112>gradle -q D:\gradle_product\0112\src\config.xml Welcome to Gradle 2.2.1. To run a build, run gradle <task> ... To see a list of available tasks, run gradle tasks To see a list of command-line options, run gradle --help
从上面的脚本中可以看出,file方法可以接受字符串和File对象作为参数。file方法一般都会将项目的根目录作为默认的父目录,而不是当前工作目录。
项目集合在gradle中用FileCollection接口来表示。而且gradle中很多对象都是实现该接口的,例如依赖配置就是实现该接口的。
调用Project.files()方法可以获得FileCollection实例,你可以传入任意数量的对象,然后会被转换为File对象的集合,下面创建一个FileCollection集合。
FileCollection collection = files('src/file1.txt',new File('src/file2.txt'),['src/file3.txt','src/file4.txt'])
文件结合是可迭代的,支持下面的操作:
as操作符:将集合转化为其他类型
+操作符:合并2个文件集合
-操作符:从一个集合扣除一个集合
看下面一个综合的例子:
FileCollection collection = files('src/file1.txt' ,new File('src/file2.txt'), ['src/file3.txt', 'src/file4.txt']) collection.each{File file -> println file.name } Set set = collection.files Set set2 = collection as Set List list = collection as List String path = collection.asPath def union = collection + files('src/file5.txt') def different = collection - files('src/file5.txt')
D:\GRADLE~2\0112>gradle -q file1.txt file2.txt file3.txt file4.txt Welcome to Gradle 2.2.1. To run a build, run gradle <task> ... To see a list of available tasks, run gradle tasks To see a list of command-line options, run gradle --help
task list << { File srcDir // Create a file collection using a closure FileCollection collection = files { srcDir.listFiles() } srcDir = file('src') println "Contents of $srcDir.name" collection.collect { relativePath(it) }.sort().each { println it } srcDir = file('src2') println "Contents of $srcDir.name" collection.collect { relativePath(it) }.sort().each { println it } }
build.gradle在之前的基础上添加了一个list任务,可以看到files方法中传入的是什么?是一个闭包代码块,然后当调用sort()方法来查询集合内容的时候,才会调用闭包代码块,所以srcDir写在了collection的定义后。
FileTree接口继承于FileCollection接口,在gradle中有一些对象是继承FileTree,比如SourseSet。
Project.fileTree方法,
FileTree tree = fileTree(dir: 'src/main') tree.include '**/*.java' tree.exclude '**/Abstract*' tree = fileTree('src').include('**/*.java') tree = fileTree('src') { include '**/*.java' } tree = fileTree(dir: 'src', include: '**/*.java') tree = fileTree(dir: 'src', includes: ['**/*.java', '**/*.xml']) tree = fileTree(dir: 'src', include: '**/*.java', exclude: '**/*test*/**')
第二个定义中,采用连写的方式,包括src目录下的所有的java文件。
第三个定义中,类似第二种,只是采用的方式是闭包形式来定义所包含的文件。
第四种-第六中,根据构造函数的重载特性,传入不同的参数创建的。
task findTree(dependsOn:'create') <<{ FileTree filtered = tree.matching{ include 'org/gradle/api/**' } FileTree sum = tree + fileTree(dir:'src/test') tree.visit{ element -> println "$element.relativePath =>$element.file" } } task create { File testFile = file('src/test/java') testFile.mkdirs() }
D:\GRADLE~2\0112>gradle -q findTree main =>D:\gradle_product\0112\src\main main/java =>D:\gradle_product\0112\src\main\java test =>D:\gradle_product\0112\src\test test/java =>D:\gradle_product\0112\src\test\java
针对压缩文件有2个方法zipTree和tarTree两个方法。
FileTree zip = zipTree('someFile.zip') FileTree tar = tarTree('someFile.tar') FileTree someTar = tarTree(resources.gzip('someTar.ext'))
compile{ source = file('src/main/java') } compile{ source = 'src/main/java' } compile{ source = ['src/main/java','../shared/java'] } compile{ source={ file('src').listFiles.findAll{ it.name.endsWith('.zip') }.collect{ zipTree(it) } } }
上面的4中方式都是重新设置了source文件夹的位置,也就是输入文件的位置。
Project下还有一个source方法来定义输入文件。
compile{ source 'src/main/java','src/main/groovy' source file('../shared/java') source{ file('src/test').listFiles() } }
继承Copy对象来复制文件
task copyTask(type:Copy){ from 'src/main/webapp' into 'build/explodedWar' }
from定义要被复制的文件目录,into定义的是复制到的目录。
from的来源有很多,类似files()
1.目录:目录下的所有文件都会包含在内
2.文件
3.不存在的文件:忽略
4.任务:任务的输出文件
into方法类似file方法
task copyTask(type:Copy){ from 'src/main/webapp' into 'build/explodedWar' } task copyTaskWithPaths(type:Copy){ from 'src/main/webapp' into 'build/explodedWar' include '**/*.html' include '**/*.jsp' exclude{ details ->details.file.name.endsWith('/html')&& details.file.text.contains('staging') } } task anotherCopyTask(type:Copy){ from 'src/main/webapp' from 'index.html' from copyTask from copyTaskWithPaths.outputs from zipTree(asserts.zip) into { getDestDir() } }
任务copyTaskWithPaths可以来删选所选目录中的文件。
anotherCopyTask任务说明from的来源有多种形式。
还有一种复制文件的方式是调用Project的copy方法,需要注意的一点是,在任务中使用copy方法,必须显示的定义输入和输出文件。
task copyMethod <<{ copy{ from 'src/main/webapp' into 'build/explodedWar' include '**/*.html' include '**/*.jsp' } }
task rename(type:Copy){ from 'src/main/webapp' into 'build/explodedWar' rename{ String fileName-> fileName.replace('1','2') } }
上面的任务是将src/main/webapp目录下的文件移到build/explodedWar下,在移动后,将文件名为1的文件重命名为2。
task rename(type:Copy){ from 'src/main/webapp' into 'build/explodedWar' rename{ String fileName-> fileName.replace('1','2') } rename '(.+)1(.+)','$1$2' rename(/(.+)1(.+)/,'$1$2') }
import org.apache.tools.ant.filters.FixCrLfFilter import org.apache.tools.ant.filters.ReplaceTokens task filter(type:Copy){ from 'src/main/webapp' into 'build/explodedWar' expand(copyright:'2009',version:'2.3.2') expand(project.properties) filter(FixCrLfFilter) filter(ReplaceTokens,tokens:[copyright:'2009',version:'2.3.1']) filter{ "[$line]" } }
expand 和filter都是寻找一个叫token的东西,形式有点像@tokenName@
复制规范形成一个层次结构。一份规范继承目的地路径,包括模式、排除模式,复制操作,名称映射和过滤器。嵌套复制:
task nestedSpecs(type:Copy){ into 'build/explodedWar' exclude '**/*staging' from('src/dist'){ include '**/*.html' } into('libs'){ from configurations.runtime } }
但是执行的时候报错。是因为我们没有定义runtime的依赖,所以会报如下错误。
qianhuis-Mac-mini:0112 qianhui$ gradle -q nestedSpecs FAILURE: Build failed with an exception. * Where: Build file '/Users/qianhui/Documents/Developer/gradle_project/0112/build.gradle' line: 8 * What went wrong: A problem occurred evaluating root project '0112'. > Could not find property 'runtime' on configuration container. * Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
同步任务继承与copy任务,当它执行的时候,将source文件copy到目标目录中,然后删除目标文件中不是copy过来的文件。
task libs(type:Sync){ from configurations.runtime into "$buildDir/libs" } repositories{ mavenCentral() } dependencies{ runtime 'junit:junit:4.11' }
将runtime运行时所依赖的jar文件复制到build/libs目录下。
apply plugin:'java' version = 1.0 task myZip(type:Zip){ from 'src' } println myZip.archiveName println relativePath(myZip.destinationDir) println relativePath(myZip.archivePath)
qianhuis-Mac-mini:0112 qianhui$ gradle -q myZip 0112-1.0.zip build/distributions build/distributions/0112-1.0.zip