Gradle学习(十七)——Ant操作

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lastsweetop/article/details/79043654

转载请注明:http://blog.csdn.net/lastsweetop/article/details/79043654

简介

Gradle提供了与Ant的完美集成,你可以在Gradle构建中使用单个Ant任务或者全部由Ant构建。在Gradle的构建脚本里写Ant要比原来在xml中更加的简易而且还强力,强大到你可以把Gradle只是Ant的脚本工具

Ant可以分为两层:第一层是Ant的语言,他为build.xml文件,目标的处理和宏的特殊构造提供了语言,可以说除了任务和类型之外的一切。Gradle支持Ant的语言,你可以直接把build.xml文件导入到Gradle项目,然后你就是像使用Gradle的task那样,使用Ant构建的target。第二层是Ant丰富的task和type,比如javac, copy or jar。对于这一层Gradle委托给了Groovy强力的AntBuilder。

还有,因为Gradle脚本是Groovy语言的,因此你可以把ant当做是外部程序,"ant clean compile".execute()这样的脚本可以直接执行。

你可以把Gradle对Ant的集成当做是Ant构建迁移到Gradle的一种途径。你可以把导入Ant构建当做你的第一步,然后你把Ant中的依赖转移到构建脚本中,最后你可以一步步的用Gradle的插件来替换你Ant中的target,task和type,迁移可以分步来,整个过程Gradle都是可用的。

构建中使用Ant的task和type

在构建脚本中,有个指向AntBuilder实例的引用ant,可以用过它来访问Ant的任务,类型和属性。通过调用ant上的方法你可以执行Ant的任务,你可以把Ant任务名当做ant的方法名来使用,比如ant.echo()其实是调用Ant的echo任务。Ant任务的属性通过ant任务Map类型的参数传入,可以看看下面这个例子:

task hello {
    doLast {
        ant {
            echo message: 'hello from Ant'
        }
    }
}

执行任务:

± % gradle hello                                                                                                
> Task :hello
[ant:echo] hello from Ant


BUILD SUCCESSFUL in 1s
1 actionable task: 1 executed

还可以当做是嵌套的文本当做参数传入进行(上个例子可以用<echo message='hello from Ant'></echo>表示,嵌套就是<echo>hello from Ant</echo>),比如:

task hello {
    doLast {
        ant {
            echo 'hello from Ant'
        }
    }
}

执行任务

± % gradle hello                                                                                                
> Task :hello
[ant:echo] hello from Ant


BUILD SUCCESSFUL in 1s
1 actionable task: 1 executed

嵌套的元素则用闭包的方式传入:

task zipTask {
    doLast {
        ant {
            zip(destfile: 'archive.zip') {
                fileset(dir: 'src') {
                    include name: '**.txt'
                    exclude name: '**.java'
                }
            }
        }
    }
}

你还可以以访问Ant任务的方式访问它的属性,也就是类型名换成方法名,方法返回的数据你可以直接就在脚本中使用它:

task listPath {
    doLast {
        def path = ant.path {
            fileset(dir: 'src', includes: '**.txt')
        }
        path.list().each {
            println it
        }
    }
}

在构建中使用自定义任务

如果想要在脚本中自定义Ant任务,可以使用taskdeftypedef,就像你在build.xml文件做的那样。然后你就可以像使用ant自带的任务那样使用自定义的任务

task check {
    doLast {
        ant.taskdef(resource: 'checkstyletask.properties') {
            classpath {
                fileset(dir: 'libs', includes: '*.jar')
            }
        }
        ant.checkstyle(config: 'checkstyle.xml') {
            fileset(dir: 'src')
        }
    }
}

你还可以使用Gradle的依赖管理来给Ant自定义任务使用的classpath,只需要在,只需要为classpath添加个自定义的配置,然后就可以在这个配置上添加依赖了。

configurations {
    pmd
}

dependencies {
    pmd group: 'pmd', name: 'pmd', version: '4.2.5'
}

想使用这个classpath,只需要在这个自定义的配置上使用asPath属性就可以了

task check {
    doLast {
        ant.taskdef(name: 'pmd',
                classname: 'net.sourceforge.pmd.ant.PMDTask',
                classpath: configurations.pmd.asPath)
        ant.pmd(shortFilenames: 'true',
                failonruleviolation: 'true',
                rulesetfiles: file('pmd-rules.xml').toURI().toString()) {
            formatter(type: 'text', toConsole: 'true')
            fileset(dir: 'src/main/java')
        }
    }
}

Ant构建导入

你可以使用ant.importBuild()把Ant的构建导入到Gradle的构建之中,导入之后Ant的每个target都变成了Gradle的一个task,这样你就可以像Gradle的任务那样操作Ant的target
Gradle导入Ant:

ant.importBuild 'build.xml'

build.xml

<project>
    <target name="hello">
        <echo>Hello from Ant build.xml</echo>
    </target>
</project>

执行任务:

± % gradle hello

> Task :hello
[ant:echo] Hello from Ant build.xml


BUILD SUCCESSFUL in 1s
1 actionable task: 1 executed

你还可以用Ant的target添加依赖:

ant.importBuild 'build.xml'

task intro(dependsOn: hello) {
    doLast {
        println 'Hello from Gradle'
    }
}

执行任务:

± % gradle intro

> Task :hello
[ant:echo] Hello from Ant build.xml

> Task :intro
Hello from Gradle


BUILD SUCCESSFUL in 1s
2 actionable tasks: 2 executed

还可以给Ant的target添加action

hello {
    doLast {
        println 'Action from Gradle'
    }
}

执行任务:

± % gradle hello

> Task :hello
[ant:echo] Hello from Ant build.xml
Action from Gradle


BUILD SUCCESSFUL in 1s
1 actionable task: 1 executed

Ant的target还可以反过来依赖Gradle声明的任务

task intro {
    doLast {
        println 'Hello from Gradle'
    }
}

build.xml:

<project>
    <target name="hello" depends="intro">
        <echo>Hello from Ant build.xml</echo>
    </target>
</project>

执行任务:

± % gradle hello

> Task :intro
Hello from Gradle

> Task :hello
[ant:echo] Hello from Ant build.xml
Action from Gradle


BUILD SUCCESSFUL in 2s
2 actionable tasks: 2 executed

有时候你可能需要对Ant的target进行重命名,以防止和Gradle的任务有冲突。使用AntBuilder.importBuild(java.lang.Object, org.gradle.api.Transformer)方法即可。

ant.importBuild('build.xml') {
    'a_'+it
}

build.xml:

<project>
    <target name="hello">
        <echo>Hello from Ant build.xml</echo>
    </target>
</project>

执行任务:

± % gradle a_hello

> Task :a_hello
[ant:echo] Hello from Ant build.xml
Action from Gradle


BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed

这里有两点需要注意,重命名之后连被Ant依赖Gradle的任务也被重命名了,也就是build.xml里的任务也被重命名了,不知道这算不算一个bug。
第二点需要说明的是虽然AntBuilder.importBuild(java.lang.Object, org.gradle.api.Transformer)的不是闭包,但是Groovy语言的闭包可以自动转换SAM。

Ant的属性和引用

有多种方法可以设置Ant的属性,这些属性可以被Ant任务使用。可以通过AntBuilder的实例进行直接设置,还可以通过Ant的property属性,这个属性是个可以更改的Map,还可以通过ant的property任务进行设置,如下:

ant.buildDir = buildDir
ant.properties['buildDir'] = buildDir
ant.properties.buildDir = buildDir
ant.property name: 'buildDir', location: buildDir

build.xml

<project>
<target name="hello">
    <echo>Hello ${buildDir}</echo>
</target>
</project>

大多数Ant任务在运行时才为属性设置值,获得这些属性值的方法有很多种,可以通过AntBuilder实例去获取:
build.xml

<project>
    <target name="hello">
        <echo>Hello ${buildDir}</echo>
    </target>
    <property name="antProp" value="a property defined in an Ant build"/>
</project>

build.gradle

println ant.antProp
println ant.properties['antProp']
println ant.properties.antProp

设置Ant引用的几种方法:

ant.references['classpath'] = ant.path location: 'libs'
ant.references.classpath = ant.path location: 'libs'
ant.path(id: 'classpath', location: 'lib')

build.xml

 <path refid="classpath"/>

获取Ant引用的方法

println ant.references['myPath']
println ant.references.myPath

build.xml

<path id="myPath" location="libs"></path>

要注意的是id既可以获取也可以设置,但是refid只能获取

Ant日志

Gradle将Ant的消息优先次序映射到了Gradle的日志级别中,映射关系如下:

Ant的消息优先次序 Gradle的日志级别
VERBOSE DEBUG
DEBUG DEBUG
INFO INFO
WARN WARN
ERROR ERROR

Ant的消息优先次序映射到了Gradle的日志级别有时候会出现问题,Ant没有对应的消息有限次序可以映射到Gradle的默认日志级别LIFECYCLE中,Ant的大多数任务都是INFO级别的,转换成Gradle的日志也会是INFO级别的,这样会输出的日志会比你预想要多很多。

反之,如果想让Ant的日志的消息优先次序高一点,那么就需要构建运行在一个更高级别的日志级别上,比如QUIET,但是想要的信息又被屏蔽掉了。

为了解决这个问题,Gradle允许用户对Ant的消息优先次序进行微调并设置映射到Gradle的日志级别。主要是通过AntBuilder.setLifecycleLogLevel(java.lang.String)来设置可以映射到LIFECYCLE日志级别对应的Ant的消息优先次序。如果这个值被设置,那么对应的消息游戏次序以上的日志将被记录,LIFECYCLE以上的日志也被记录。注意一点这个值最低都要设置成INFO的。如下面的例子:

ant.lifecycleLogLevel = 'INFO'
task hello {
    doLast {
        ant.echo level:'info',message:'hello from into info'
    }
}

执行任务

± % gradle hello
> Task :hello
[ant:echo] hello from into info


BUILD SUCCESSFUL in 1s
1 actionable task: 1 executed

猜你喜欢

转载自blog.csdn.net/lastsweetop/article/details/79043654