错误现象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
FAILURE: Build failed with an exception.

* Where:
Script 'http://sc.dev.xxxx.com:8080/script/gateway.gradle' line: 87

* What went wrong:
A problem occurred evaluating script.
> Could not find method leftShift() for arguments [gateway_3jdkdl89l6uef4r948spaebo1$_run_closure12@13b89f08] on task ':replaceBuildInfo' of type org.gradle.api.DefaultTask.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 8s

打开脚本查看第87行如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
task replaceBuildInfo << {
def buildFile = file("build/libs/application.yml")
def gitVersion
try {
gitVersion = 'git rev-parse HEAD'.execute().text.trim()
println 'Git commit: ' + gitVersion
} catch (Exception e) {
gitVersion = 'GET FAILED:' + e.getMessage()
}
if (buildFile.exists()) {
def cfgContent = buildFile.getText().replaceAll("\\\$\\{commit\\}", gitVersion)
cfgContent = cfgContent.replaceAll("\\\$\\{version\\}", v)
buildFile.write(cfgContent)
}
buildFile = file("build/libs/bootstrap.yml")
if (buildFile.exists()) {
def cfgContent = buildFile.getText().replaceAll("\\\$\\{commit\\}", gitVersion)
cfgContent = cfgContent.replaceAll("\\\$\\{version\\}", v)
buildFile.write(cfgContent)
}
}

起初以为是文件读取不到,找了另外几个项目对比项目结构,发现并无二致。
后来搜索关键字Could not find method leftShift() for arguments得到解释为 gradle4.x 就废弃了task中左移符号<<的支持,但依然能使用,在 gradle5.x 则彻底移除了左移符号<<的支持。

详见:

解决办法

修改原脚本

最彻底的方案当然是修改原脚本,将左移符号<<更改为doList块。如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// 修改前
task replaceBuildInfo << {
def buildFile = file("build/libs/application.yml")
def gitVersion
try {
gitVersion = 'git rev-parse HEAD'.execute().text.trim()
println 'Git commit: ' + gitVersion
} catch (Exception e) {
gitVersion = 'GET FAILED:' + e.getMessage()
}
if (buildFile.exists()) {
def cfgContent = buildFile.getText().replaceAll("\\\$\\{commit\\}", gitVersion)
cfgContent = cfgContent.replaceAll("\\\$\\{version\\}", v)
buildFile.write(cfgContent)
}
buildFile = file("build/libs/bootstrap.yml")
if (buildFile.exists()) {
def cfgContent = buildFile.getText().replaceAll("\\\$\\{commit\\}", gitVersion)
cfgContent = cfgContent.replaceAll("\\\$\\{version\\}", v)
buildFile.write(cfgContent)
}
}
replaceBuildInfo.dependsOn(taskXxx)

// 修改后
task hello {
dependsOn 'taskXxx'
doLast {
def buildFile = file("build/libs/application.yml")
def gitVersion
try {
gitVersion = 'git rev-parse HEAD'.execute().text.trim()
println 'Git commit: ' + gitVersion
} catch (Exception e) {
gitVersion = 'GET FAILED:' + e.getMessage()
}
if (buildFile.exists()) {
def cfgContent = buildFile.getText().replaceAll("\\\$\\{commit\\}", gitVersion)
cfgContent = cfgContent.replaceAll("\\\$\\{version\\}", v)
buildFile.write(cfgContent)
}
buildFile = file("build/libs/bootstrap.yml")
if (buildFile.exists()) {
def cfgContent = buildFile.getText().replaceAll("\\\$\\{commit\\}", gitVersion)
cfgContent = cfgContent.replaceAll("\\\$\\{version\\}", v)
buildFile.write(cfgContent)
}
}
}

详见:
Build Script Basics

降级gradle

修改脚本固然是根本办法,但是团队开发的规范和限制也不是能一下子就突破的。固针对具体项目使用指定版本。

项目自定义版本

项目根目录下会有一个gradle文件夹
修改此文件夹下gradle/wrapper/gradle-wrapper.properties文件中distributionUrl属性

1
2
#distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-bin.zip

全局指定gradle

idea

eclipse

参考资料

Gradle 5.0 Release Notes
Remove Task#leftShift · Issue #6266 · gradle/gradle
Build Script Basics