-
Notifications
You must be signed in to change notification settings - Fork 221
/
PluginHelper.groovy
195 lines (165 loc) · 6.99 KB
/
PluginHelper.groovy
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
/*
* This file is part of the gradle-release plugin.
*
* (c) Eric Berry
* (c) ResearchGate GmbH
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
package net.researchgate.release
import groovy.text.SimpleTemplateEngine
import net.researchgate.release.cli.Executor
import org.apache.tools.ant.BuildException
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.slf4j.Logger
import org.slf4j.LoggerFactory
class PluginHelper {
private static final String LINE_SEP = System.getProperty('line.separator')
private static final String PROMPT = "${LINE_SEP}??>"
protected Project project
protected ReleaseExtension extension
protected Executor executor
protected Map<String, Object> attributes = [:]
/**
* Retrieves SLF4J {@link Logger} instance.
*
* The logger is taken from the {@link Project} instance if it's initialized already
* or from SLF4J {@link LoggerFactory} if it's not.
*
* @return SLF4J {@link Logger} instance
*/
Logger getLog() { project?.logger ?: LoggerFactory.getLogger(this.class) }
boolean useAutomaticVersion() {
findProperty('release.useAutomaticVersion', null, 'gradle.release.useAutomaticVersion') == 'true'
}
/**
* Executes command specified and retrieves its "stdout" output.
*
* @param failOnStderr whether execution should fail if there's any "stderr" output produced, "true" by default.
* @param commands commands to execute
* @return command "stdout" output
*/
String exec(
Map options = [:],
List<String> commands
) {
initExecutor()
options['directory'] = options['directory'] ?: project.rootDir
executor.exec(options, commands)
}
private void initExecutor() {
if (!executor) {
executor = new Executor(log)
}
}
File findPropertiesFile() {
File propertiesFile = project.file(extension.versionPropertyFile)
if (!propertiesFile.file) {
if (!isVersionDefined()) {
project.version = getReleaseVersion('1.0.0')
}
if (!useAutomaticVersion() && promptYesOrNo('Do you want to use SNAPSHOT versions in between releases')) {
attributes.usesSnapshot = true
}
if (useAutomaticVersion() || promptYesOrNo("[$propertiesFile.canonicalPath] not found, create it with version = ${project.version}")) {
writeVersion(propertiesFile, 'version', project.version)
attributes.propertiesFileCreated = true
} else {
log.debug "[$propertiesFile.canonicalPath] was not found, and user opted out of it being created. Throwing exception."
throw new GradleException("[$propertiesFile.canonicalPath] not found and you opted out of it being created,\n please create it manually and specify the version property.")
}
}
propertiesFile
}
protected void writeVersion(File file, String key, version) {
try {
if (!file.file) {
project.ant.echo(file: file, message: "$key=$version")
} else {
// we use replace here as other ant tasks escape and modify the whole file
project.ant.replaceregexp(file: file, byline: true) {
regexp(pattern: "^(\\s*)$key((\\s*[=|:]\\s*)|(\\s+)).+\$")
substitution(expression: "\\1$key\\2$version")
}
}
} catch (BuildException be) {
throw new GradleException('Unable to write version property.', be)
}
}
boolean isVersionDefined() {
project.version && Project.DEFAULT_VERSION != project.version
}
void warnOrThrow(boolean doThrow, String message) {
if (doThrow) {
throw new GradleException(message)
} else {
log.warn("!!WARNING!! $message")
}
}
String tagName() {
def engine = new SimpleTemplateEngine()
def binding = [
"version": project.version,
"name" : project.name
]
return engine.createTemplate(extension.tagTemplate.get()).make(binding).toString()
}
String findProperty(String key, Object defaultVal = null, String deprecatedKey = null) {
def property = System.getProperty(key) ?: project.hasProperty(key) ? project.property(key) : null
if (!property && deprecatedKey) {
property = System.getProperty(deprecatedKey) ?: project.hasProperty(deprecatedKey) ? project.property(deprecatedKey) : null
if (property) {
log.warn("You are using the deprecated parameter '${deprecatedKey}'. Please use the new parameter '$key'. The deprecated parameter will be removed in 3.0")
}
}
property ?: defaultVal
}
String getReleaseVersion(String candidateVersion = "${project.version}") {
String releaseVersion = findProperty('release.releaseVersion', null, 'releaseVersion')
if (useAutomaticVersion()) {
return releaseVersion ?: candidateVersion
}
return readLine("This release version:", releaseVersion ?: candidateVersion)
}
/**
* Updates properties file (<code>gradle.properties</code> by default) with new version specified.
* If configured in plugin convention then updates other properties in file additionally to <code>version</code> property
*
* @param newVersion new version to store in the file
*/
void updateVersionProperty(String newVersion) {
String oldVersion = project.version as String
if (oldVersion != newVersion) {
project.version = newVersion
attributes.versionModified = true
project.subprojects?.each { it.version = newVersion }
List<String> versionProperties = extension.versionProperties.get() + 'version'
versionProperties.each { writeVersion(findPropertiesFile(), it, project.version) }
}
}
/**
* Reads user input from the console.
*
* @param message Message to display
* @param defaultValue (optional) default value to display
* @return User input entered or default value if user enters no data
*/
protected static String readLine(String message, String defaultValue = null) {
String _message = "$PROMPT $message" + (defaultValue ? " [$defaultValue] " : "")
if (System.console()) {
return System.console().readLine(_message) ?: defaultValue
}
println "$_message (WAITING FOR INPUT BELOW)"
System.in.newReader().readLine() ?: defaultValue
}
private static boolean promptYesOrNo(String message, boolean defaultValue = false) {
String defaultStr = defaultValue ? 'Y' : 'n'
String consoleVal = readLine("${message} (Y|n)", defaultStr)
if (consoleVal) {
return consoleVal.toLowerCase().startsWith('y')
}
defaultValue
}
}