Gradle 的文件操作

2018-11-20 17:12:27 浏览数 (1)

众所周知,Gradle 作为一个项目构建工具,使用了 Groovy 语言来表述其脚本代码,而 Groovy 语言中的很多特性设计的有点“反人类”,这些特性对于老手来说写起来非常舒服,但是对于新手就很不友好了,因为不便于理解,很多萌新看着 Gradle 的脚本感觉很简单很清晰的样子,但是真到了自己去写的时候就会感觉无从下手,怎么写怎么报错;本文就从Gradle 的几个简单的文件操作顺带来分析一下这些奇葩的坑点,让大家对 Groovy 语法特性有个大致认知。

准备一个文件目录如下:点击下载

image.png

准确的Tree结构:

代码语言:javascript复制
root
│  build.gradle
│  solution.gradle
│  
└──src
    ├──docs
    │      aa.aa
    │      install.md
    │      install.txt
    │      readme.txt
    │      
    └──web
        │  index.html
        │  
        └──images
                cat.jpg
                dog.jpg

任务

  1. 拷贝src/web目录到build/web目录,并且拷贝src/docs目录下的所有 txt 文件到build/web/help下。
  2. 打包build/web目录下除 images 文件夹外的所有文件为web.zip,并将web.zip放置于build目录下。
  3. 解压build/web.zipbuild/exploded
  4. 删除build/web/help

解决方案

代码语言:javascript复制
//1.Copy
task copyWeb(type:Copy){
    from 'src/web'
    from ('src/docs'){
        include '*.txt'
        into 'help'
    }
    into 'build/web'
}
//2.Zip
task bundleWeb(type:Zip,dependsOn:copyWeb){
    baseName 'web'
    destinationDir file('build')

    from 'build/web'
    exclude 'images/**'
}
//3.UnZip
task unpackBundle(type:Copy,dependsOn:bundleWeb){
    from zipTree('build/web.zip')
    into 'build/exploded'
}
//4.Delete
task deleteHelp(type:Delete,dependsOn:copyWeb){
    delete 'build/web/help'
}

是的你没有看错,任务中的4个问题就用上面这20几行代码轻松解决;但是,你可能还是不太清楚这些这些配置的规则,它们看上去就像一堆键值对类似于Json,然而实际上它们都是由属性和方法构成的,就像Java一样:

属性

描述

类型

excludes

排除模式集合

Set<String>

includes

包含模式集合

Set<String>

baseName

文件的基本名称

String

destinationDir

文件生成的目录

File

方法

描述

返回

from(sourcePaths)

指定副本的源文件或目录

AbstractCopyTask

include(includes)

指定包含模式

AbstractCopyTask

exclude(excludes)

指定排除模式

AbstractCopyTask

into(destDir)

指定副本的目标目录

AbstractCopyTask

所以上面解决方案的完整写法:

代码语言:javascript复制
//1.Copy
task copyWeb(type:Copy){
    from('src/web')
    from('src/docs'){
        include('*.txt')
        into('help')
    }
    into('build/web')
}
//2.Zip
task bundleWeb(type:Zip,dependsOn:copyWeb){
    baseName='web'
    destinationDir=file('build')

    from('build/web')
    exclude('images/**')
}
//3.UnZip
task unpackBundle(type:Copy,dependsOn:bundleWeb){
    from(zipTree('build/web.zip'))
    into('build/exploded')
}
//4.Delete
task deleteHelp(type:Delete,dependsOn:copyWeb){
    delete('build/web/help')
}

这样看起来就清晰多了,以上脚本中用到的所有方法及属性都可以在 Gradle DSL Reference 文档中查到,该文档详尽的解释了每个方法及参数的作用,由于 Groovy 语言的特性,一般 Gradle 脚本都会使用简写的方式,也就是省略掉‘()’、‘=’等符号,因为省略掉这些符号不会影响到语法歧义,说到歧义大家可以看到 3.UnZip 中有一行代码 from(zipTree('build/web.zip')) 即使简写也只能写成 from zipTree('build/web.zip') 而非 from zipTree 'build/web.zip',因为最后这种写法显然使 Groovy 无法理解你要将 'build/web.zip' 作为 zipTree 的参数还是 from 的参数

其实在任何一种计算机语言中各种‘()’、‘[]’、‘{}’都是为了避免产生语法歧义,只要你掌握其中规则,知道怎么写才能避免歧义使代码正常运作,再了解其特有的语言特性如闭包lambda委托等,你就大致掌握了这门语言。现在再来看看 Groovy ,它其实就是一种不需要 public修饰符、类型说明、构造函数以及 ()的 Java简化版。

0 人点赞