comparison init40.gradle @ 263:0a6a5a7470c4

add scripts for gradle 4+ to use new gradle dependency locking and cleanup accumulated clutter
author smith@nwoca.org
date Tue, 13 Nov 2018 18:14:45 +0000
parents init20.gradle@e531b09c4659
children d063b759e419
comparison
equal deleted inserted replaced
262:e531b09c4659 263:0a6a5a7470c4
1 import groovy.transform.Sortable
2 import groovy.transform.ToString
3 import groovy.transform.TupleConstructor
4
5 buildscript {
6 repositories {
7 maven { url 'http://repos.ssdt.nwoca.org/artifactory/ssdt-repo' }
8 maven { url 'http://repos.ssdt.nwoca.org/artifactory/gradle-plugins' }
9 }
10 }
11
12 final GradleVersion gradleCurrent = GradleVersion.current()
13 final GradleVersion gradleV410 = GradleVersion.version('4.10')
14
15 println "Gradle Version: $gradleCurrent"
16
17 if (gradleCurrent < gradleV410) {
18 throw new RuntimeException("this init script requires Gradle version 4.10 or higher")
19 }
20
21 gradle.ext.ssdtDevelkitLocation = gradle.ext.has('ssdtDevelkitLocation') ? gradle.ssdtDevelkitLocation : 'http://hg.ssdt-ohio.org/browse/public/develkit'
22
23 ant.property(file: System.getProperty('user.home') + "/.ssdt/private.properties")
24 gradle.ext.ivyUserDir = ant.properties['ivy.default.ivy.user.dir'] ?: System.getProperty('user.home') + "/.ivy2"
25
26 gradle.ext.ssdtProjectId = System.getenv('bamboo_project_id') ?: rootProject.name
27
28 gradle.addListener(new ArtifactoryGradleSettings())
29
30 def hostname
31 try {
32 hostname = "hostname".execute().text.toLowerCase().readLines().first()
33 } catch (e) {
34 hostname = 'unknown'
35 }
36
37 gradle.ext.bambooBuild = System.getenv().any {
38 it.key.toLowerCase().contains('bamboo')
39 } || hostname?.startsWith('ssdt-ba')
40
41 gradle.ext.bambooPlan = (System.getenv('BAMBOO_PLAN') ?: 'UNKNOWN-UNKNOWN-JOB1').split('-')[0..1].join('-')
42 logger.info "Bamboo plan: ${gradle.bambooPlan}"
43
44 gradle.ext.buildTimestamp = System.currentTimeMillis().toString().padLeft(14, '0')
45
46 gradle.ext.hgRepositoryUrl = ""
47
48 try {
49 gradle.ext.hgRepositoryUrl = ("hg path".execute().text.split('=') ?: ['', ''])[1].trim()
50 } catch (e) {
51 }
52
53 def springModuleTranslator = [
54 'spring-transaction': 'spring-tx',
55 'spring-web-servlet': 'spring-webmvc',
56 ].withDefault { it }
57
58 gradle.ext.normalizeSpring = { DependencyResolveDetails details ->
59 if (details.requested.group == 'org.springframework' && details.requested.name.startsWith('org.springframework.')) {
60 def shortName = springModuleTranslator[details.requested.name.replace('org.springframework.', 'spring-').replace('.', '-')]
61 details.useTarget(group: 'org.springframework', name: shortName, version: details.requested.version)
62 }
63 if (details.requested.group == 'org.springframework.security' && details.requested.name.startsWith('org.springframework.')) {
64 def shortName = springModuleTranslator[details.requested.name.replace('org.springframework.', 'spring-').replace('.', '-')]
65 details.useTarget("${details.requested.group}:$shortName:${details.requested.version}")
66 }
67 }
68
69 gradle.ext.runtimeInfo = new RuntimeInfo()
70
71
72 if (System.env.DOCKER_HOST ) {
73 if (System.env.DOCKER_HOST.contains('tcp:')) {
74 gradle.ext.dockerEngineUrl = "https:${System.env.DOCKER_HOST?.minus('tcp:')}"
75 }
76 gradle.ext.dockerEngineUrl = System.env.DOCKER_HOST
77 }
78
79 setBranchInfo()
80
81 loadEnvironments()
82
83 gradle.environment.put('hgRepositoryUrl', gradle.hgRepositoryUrl)
84 gradle.environment.put('branchName', gradle.branch.name)
85 gradle.environment.put('branchStream', gradle.branch.stream)
86 gradle.environment.put('branchHash', gradle.branch.hash)
87
88
89 def cacheTimeout = 60 * 60 * 8
90 if (gradle.environment['dependencyTimeout']) {
91 cacheTimeout = gradle.environment['dependencyTimeout'] as Integer
92 println "setting changing dependency timeout to $cacheTimeout seconds"
93 }
94
95 gradle.ext.cacheTimeout = cacheTimeout
96
97 rootProject.ext.indyCapable = {
98 boolean capable = true
99 try {
100 Class.forName('java.lang.invoke.MethodHandle')
101 } catch (e) {
102 capable = false
103 }
104 capable && !rootProject.hasProperty('skipIndy')
105 }
106
107 rootProject.ext.useIndy = {
108 boolean indy = false
109 // first, check if a system property activates indy support
110 indy |= System.hasProperty('indy') && Boolean.valueOf(System.getProperty('indy'))
111
112 // check ssdt environment for indy property.
113 indy |= (gradle.environment.indy) ? gradle.environment.indy.toBoolean() : false
114
115 // check if the main project has an extension property setting indy (-Pindy).
116 if (rootProject.hasProperty('indy')) {
117 indy = (Boolean.valueOf(rootProject.indy))
118 }
119
120 // set the groovy runtime system property to ensure forked junit test will get the indy flag properly
121 if (indy && rootProject.indyCapable()) System.setProperty("groovy.target.indy", "true")
122
123 indy && rootProject.indyCapable()
124 }
125
126 println "Indy available: ${rootProject.indyCapable()} enabled: ${rootProject.useIndy()}"
127
128 if (gradle.bambooBuild) {
129
130 file('build-number.txt').text = "build.number=${gradle.branch.buildNumber ?: -1 }\n"
131 gradle.ext.ssdtGradlekitLocation = gradle.ext.has('ssdtGradlekitLocation') ? gradle.ssdtGradlekitLocation : 'http://hg.ssdt-ohio.org/ssdt/gradlekit/raw-file/tip'
132 logger.info "applying SSDT artifactory Gradle Settings (bamboo: $gradle.bambooBuild host: $hostname)"
133 apply from: "${gradle.ssdtGradlekitLocation}/artifactory40.gradle"
134 }
135
136 if (!rootProject.hasProperty('disableMetrics')) {
137 apply from: "${gradle.ssdtDevelkitLocation}/metrics40.gradle"
138 }
139
140 rootProject.afterEvaluate { r ->
141 if (gradle.bambooBuild && r.hasProperty('requireJavaVersion')) {
142 gradle.runtimeInfo.requireJava( r.getProperty('requireJavaVersion') )
143 }
144 }
145
146 def findComponent(project, name) {
147 project.component.find { it.@name == name }
148 }
149
150 wrapper {
151 distributionType = org.gradle.api.tasks.wrapper.Wrapper.DistributionType.ALL
152 }
153
154 allprojects {
155
156 configurations.all {
157 resolutionStrategy.cacheChangingModulesFor gradle.cacheTimeout, 'seconds'
158 resolutionStrategy.cacheDynamicVersionsFor gradle.cacheTimeout, 'seconds'
159 }
160 configurations.all {
161 resolutionStrategy.eachDependency { DependencyResolveDetails details ->
162 if (details.requested.group == 'org.ssdt_ohio' && !details.requested.version ) {
163 details.useVersion( "latest.${gradle.branch.defaultDependencyStatus}" )
164 }
165 if (details.requested.version == 'default') {
166 details.useVersion("latest.${gradle.branch.defaultDependencyStatus}" )
167 }
168 if (project.hasProperty("overrideCommon")) {
169 if (details.requested.group == 'org.ssdt_ohio' && details.requested.name.contains('ssdt.common.')) {
170 details.useVersion(project.overrideCommon)
171 }
172 }
173 if (project.hasProperty("overrideVui")) {
174 if (details.requested.group == 'org.ssdt_ohio' && details.requested.name.startsWith('vui.')) {
175 details.useVersion(project.overrideVui)
176 }
177 }
178 if (project.hasProperty("overrideUsasCore")) {
179 if (details.requested.group == 'org.ssdt_ohio' && details.requested.name.startsWith('usas.') && !details.requested.name.startsWith('usas.vui')) {
180 details.useVersion(project.overrideUsasCore)
181 }
182 }
183 if (project.hasProperty("overrideUspsCore")) {
184 if (details.requested.group == 'org.ssdt_ohio' && details.requested.name.startsWith('usps.') && !details.requested.name.startsWith('usps.vui')) {
185 details.useVersion(project.overrideUspsCore)
186 }
187 }
188 }
189 }
190
191 task cleanLocal(description: "removes all artifacts from developer's local repository") {
192
193 doLast {
194 def local = project.repositories.find { it.name == 'local' }
195 if (local) {
196 logger.info "removing local repo: $it"
197 new File(System.properties['user.home'] + "/.ssdt/local-repo").deleteDir()
198 def localDir = new File(gradle.ivyUserDir + "/local")
199 localDir.deleteDir()
200 logger.info "verifying removal of local repo"
201 if (localDir.exists()) {
202 throw new org.gradle.api.GradleException("Unable to clean ${localDir}. Files may be locked by another process.")
203 }
204 }
205 }
206 }
207
208 cleanLocal.onlyIf {
209 project.repositories.any { it.name == 'local' }
210 }
211
212 project.ext.previousBuildenv = project.file('build/buildenv.txt').exists() ? project.file('build/buildenv.txt').text : 'none'
213
214 tasks.addRule("Pattern: <environment>As[Test]Properties: Generates <environment>.properties as resource or Test resource") { String taskName ->
215 if ((taskName - 'Test').endsWith("AsProperties") && !taskName.startsWith('clean')) {
216 // def t = taskName.contains('Test') ? processTestResources.destinationDir : processResources.destinationDir
217 def t = taskName.contains('Test') ? sourceSets.test.output.resourcesDir : sourceSets.main.output.resourcesDir
218 def e = (taskName - 'Test' - 'AsProperties').capitalize()
219 task(taskName) {
220 ext.outputDir = t
221 ext.propertyFile = "${e.toLowerCase()}.properties"
222 ext.buildenv = project.file('build/buildenv.txt')
223 inputs.files project.file("../environment${e}.groovy"), project.file("../private${e}.groovy"), project.file('../private.properties')
224 outputs.files new File(outputDir,propertyFile), buildenv
225 outputs.upToDateWhen {
226 gradle.env == project.previousBuildenv && outputs.getFiles().every { it.exists() }
227 }
228 doLast {
229 t.mkdirs()
230 outputDir.mkdirs()
231 buildenv.text = gradle.env
232 def ps = gradle."environment${e}".toProperties()
233 ps['ssdt.project'] = project.name
234 def pf = new File(outputDir,propertyFile)
235 ext.outputPropertyFile = pf
236 ps.store(pf.newOutputStream(), "by $taskName of $this")
237 def l = pf.readLines().sort()
238 pf.text = l.join('\n').replaceAll("\\.PARENT","")
239 }
240 }
241 }
242 }
243
244 }
245
246 subprojects {
247
248 dependencyLocking {
249 if (gradle.branch.isRelease() ) {
250 lockAllConfigurations()
251 }
252 }
253
254 task("releaseLock" ) {
255 description = "Create release dependencies Lock files"
256 doFirst {
257 assert gradle.startParameter.writeDependencyLocks : "must include --write-locks or --update-locks option when locking dependencies"
258 }
259 doLast {
260
261 if (!gradle.branch.isRelease()) {
262 throw new BuildCancelledException("releaseLock is only valid on release or hotfix branch.")
263 }
264
265 configurations.findAll {
266 it.canBeResolved
267 }.findAll { c ->
268 def n = c.name.toLowerCase()
269 ['compile','runtime','provided'].any { n.contains(it) }
270 }.each {
271 println "resolving $it"
272 it.resolve()
273 }
274 }
275 }
276
277 }
278
279 rootProject.afterEvaluate {
280
281 tasks.addRule("release{Major|Minor|Patch|n.n.n}: create release branch or update release Lock file") { String taskName ->
282
283 def matcher = (taskName =~ /^release(Major|Minor|Patch|\d{1,3}\.\d{1,3}\.\d{1,3})$/)
284 if (matcher.matches()) {
285
286 task('doReleaseBranch') {
287 ext.requested = matcher[0][1].toLowerCase()
288 doLast {
289 def releaseVersion = determineReleaseVersion(requested)
290 def releaseStream = releaseVersion.isHotfix() ? 'hotfix' : 'release'
291
292 println "-" * 60
293 println "Preparing to create branch\n"
294 println "\tproject:\t${gradle.rootProject.name}"
295 println "\tcurrent:\t${gradle.branch} ($gradle.branch.version)"
296 println()
297 println "\ttype :\t${releaseStream.toUpperCase()}"
298 println "\tversion:\t${releaseVersion}"
299 println "\ttarget :\t${releaseStream}/v${releaseVersion}"
300 println()
301 println("-" * 60)
302 println "DRY RUN".center(60)
303 println("-" * 60)
304
305 println "hg flow ${releaseStream} start v${releaseVersion} --dirty --dry-run".execute().text
306
307 println "-" * 60
308
309 if (!confirmPrompt("Continue?")) {
310 throw new BuildCancelledException("release branching canceled by user request")
311 }
312
313 println "hg flow ${releaseStream} start v${releaseVersion} --dirty".execute().text
314 println "hg update ${releaseStream}/v${releaseVersion}".execute().text
315
316 setBranchInfo()
317
318 println "-" * 60
319 println " Be sure to execute 'releaseLock' task to update the release.lock file before proceeding."
320 println "-" * 60
321
322 }
323 }
324
325
326 def branchTasks = ['doReleaseBranch']
327
328 task(taskName) {
329 dependsOn branchTasks
330 }
331
332 branchTasks.tail().inject(branchTasks.head()) { a, b ->
333 tasks[b].mustRunAfter a
334 b
335 }
336
337 }
338 }
339
340 }
341
342 private static String readLine(String message, String defaultValue = null) {
343 String _message = "> $message" + (defaultValue ? " [$defaultValue] " : "")
344 if (System.console()) {
345 return System.console().readLine(_message) ?: defaultValue
346 }
347 println "$_message "
348
349 System.in.newReader().readLine() ?: defaultValue
350 }
351
352 private static boolean confirmPrompt(String message, boolean defaultValue = false) {
353 String defaultStr = defaultValue ? 'Y' : 'n'
354 String consoleVal = readLine("${message} (Y|n)", defaultStr)
355 if (consoleVal) {
356 return consoleVal.toLowerCase().startsWith('y')
357 }
358
359 defaultValue
360 }
361
362 private Version determineReleaseVersion(String requested) {
363 if (requested == 'major') {
364 return gradle.branch.version.nextMajor()
365 } else if (requested == 'minor') {
366 return gradle.branch.version.nextMinor()
367 } else if (requested == 'patch') {
368 return gradle.branch.version.nextPatch()
369 } else {
370 return new Version(*requested.split(/\./)*.toInteger(), false)
371 }
372 }
373
374 class ArtifactoryGradleSettings extends BuildAdapter implements BuildListener {
375
376 def void projectsEvaluated(Gradle gradle) {
377 def ssdtArtifactory = 'http://repos.ssdt.nwoca.org/artifactory'
378 Project root = gradle.getRootProject()
379
380
381 def branchVersioning = gradle.rootProject.version == 'unspecified'
382
383 root.allprojects {
384
385 def thisProject = delegate
386 thisProject.status = 'integration'
387 if (gradle.branchStream) {
388 if (branchVersioning) {
389 thisProject.version = gradle.branch.version
390 thisProject.status = gradle.branch.defaultDependencyStatus
391 } else {
392
393 thisProject.status = 'integration'
394 def fixupVersion = thisProject.version - ".SNAPSHOT"
395 if (gradle.branchStream == 'feature') {
396 fixupVersion = fixupVersion + ".SNAPSHOT"
397 }
398 if (gradle.branchStream == 'develop') {
399 fixupVersion = fixupVersion + ".SNAPSHOT"
400 }
401 if (gradle.branchStream in ['production', 'release', 'hotfix']) {
402 thisProject.status = 'release'
403 }
404 thisProject.version = fixupVersion
405 }
406 }
407
408 repositories {
409
410 if (!gradle.bambooBuild) {
411 ivy {
412 name = 'local'
413 artifactPattern gradle.ivyUserDir + '/local/[artifact]-[revision](-[classifier]).[ext]'
414 ivyPattern gradle.ivyUserDir + "/local/[module]-ivy-[revision].xml"
415 }
416 mavenLocal()
417 }
418
419 if (gradle.branchStream == 'feature') {
420 ivy {
421 name = 'ssdt-branches'
422 url = "${ssdtArtifactory}/ssdt-branches/${gradle.branchHash}/"
423 layout "pattern", {
424 artifact "[organization]/[module]/[revision]/[module]-[revision](-[classifier]).[ext]"
425 ivy "[organization]/[module]/ivy-[revision].xml"
426 }
427 }
428 }
429
430 ivy {
431 name = 'ssdt-snapshots'
432 url = "${ssdtArtifactory}/ssdt-snapshots"
433 layout "pattern", {
434 artifact "[organization]/[module]/[revision]/[module]-[revision](-[classifier]).[ext]"
435 artifact "[organization]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]"
436 ivy "[organization]/[module]/ivy-[revision].xml"
437 m2compatible = true
438 }
439 }
440
441 maven {
442 name = 'ssdt-repository'
443 url = "${ssdtArtifactory}/repository"
444 }
445
446 }
447
448 def remoteRepos = thisProject.repositories.findAll { it.hasProperty('url') && !(it.name.toLowerCase().contains('local') || it.url.toString().contains('ssdt')) }
449 if (remoteRepos) {
450 logger.warn "WARNING: Remote repositories configured for $thisProject:\n" + remoteRepos.collect { "\t$it.name $it.url " }.join('\n') + "\n Moved to lowest priority..."
451 remoteRepos.each {
452 thisProject.repositories.remove(it)
453 thisProject.repositories.addLast(it)
454 }
455 }
456 logger.info "$thisProject configured repositories:\n" + thisProject.repositories.collect {"\t$it.name ${it.hasProperty('url') ? it.url : '' }" }.join('\n')
457
458 if (thisProject.repositories.find { it.name == 'local' } && thisProject.getTasksByName('uploadArchives', false)) {
459 uploadArchives {
460 repositories {
461 add thisProject.repositories.local
462 }
463 }
464
465 thisProject.tasks.create("publishLocal") {
466 description = "Publishes this projects artifacts to developer's local repository"
467 dependsOn = ["uploadArchives"]
468 }
469 }
470
471 }
472
473 root.subprojects { p ->
474 if (root.useIndy()) {
475 def groovyIndy = p.configurations.compile.files.find { f -> f.name.startsWith('groovy-all') && f.name.contains('-indy') }
476 if (groovyIndy) {
477 println "enabling indy compilation on $p"
478 [compileGroovy.groovyOptions, compileTestGroovy.groovyOptions]*.with {
479 optimizationOptions = [indy: true]
480 }
481 }
482 }
483 }
484 }
485 }
486
487
488 task showEnvironments {
489
490 doLast {
491 println "Defined environments: $gradle.environments"
492 gradle.environments.each { e ->
493 println "\n $e:"
494 gradle.getProperty(e).flatten().sort { it.key }.each { k, v ->
495 println String.format(' %25s = %s', k, k.contains('password') ? "********" : v)
496 }
497 }
498 if (logger.isInfoEnabled()) {
499 println "System properties:"
500 System.properties.each { println " $it" }
501 println "env variables:"
502 System.getenv().each { println " $it" }
503 }
504 }
505 }
506
507 def loadEnvironments() {
508 def developerPrivate = new Properties()
509 if (file('private.properties').exists()) {
510 developerPrivate.load(file('private.properties').newReader())
511 }
512 def envOverrides = [:]
513
514 if (!hasProperty('env')) {
515 gradle.ext.env = developerPrivate.env ?: 'dev'
516 } else {
517 def values = getProperty('env').split(',')
518 gradle.ext.env = values.first()
519 values.tail().each {
520 def (k, v) = it.split('=')
521 envOverrides.put(k, v)
522 }
523 }
524
525 println "Environment is: $gradle.env ($envOverrides)"
526 def slurper = new ConfigSlurper(gradle.env)
527 slurper.setBinding(['gradle': gradle])
528
529 def environment = slurper.parse(
530 '''deploy.mode="production"
531 environments {
532 test { deploy.mode="test" }
533 dev { deploy.mode="development"}
534 }''')
535 if (developerPrivate['deploy.mode']) {
536 environment.put('deploy.mode', developerPrivate['deploy.mode'])
537 }
538
539 environment.put('branchInfo',gradle.branch)
540 environment.put('branchVersion',gradle.branch.version.toString())
541 def environments = []
542 gradle.ext.environment = environment
543 file('.').listFiles().findAll { it.name ==~ /^environment.*\.groovy$/ }.sort { it.name }.each { envFile ->
544 def envName = envFile.name - '.groovy'
545 def privateFile = file("private" + envName - "environment" + ".groovy")
546 logger.info("loading environment $envFile.name")
547
548 def envCfg = slurper.parse(envFile.toURL())
549 envCfg.merge(slurper.parse(developerPrivate))
550 envCfg.put('ssdt.projectid', gradle.ssdtProjectId)
551 envCfg.put('ssdt.environment', gradle.env)
552 if (privateFile.exists()) {
553 logger.info("loading private environment $privateFile")
554 envCfg.merge(slurper.parse(privateFile.toURL()))
555 }
556
557 gradle.rootProject.getProperties().find { it.key.startsWith('environment') }.each {
558 it.value.split(',').each { p ->
559 def (k, v) = p.split('=')
560 logger.info("$envName: overriding " + k + "=" + v + " in $it")
561 envCfg.put(k, v)
562 }
563 }
564
565 envOverrides.each { k, v ->
566 logger.info("$envName: overriding " + k + "=" + v)
567 envCfg.put(k, v)
568 }
569 environment.merge(envCfg)
570 if (envName != 'environment') {
571 gradle.ext[envName] = envCfg
572 environments << envName
573 }
574 }
575 environment.merge(slurper.parse(developerPrivate))
576 def deployMode = environment.deploy.mode ?: 'development'
577 environments.each { gradle.ext[it].put('ssdt.deployment.mode', deployMode) }
578 environments << 'environment'
579 gradle.ext.environments = environments
580
581 }
582
583
584 @ToString(includeNames=true)
585 class RuntimeInfo {
586 // OS memory in megabytes, zero if unknown
587 int systemMemory = 0
588 int systemFreeMemory = 0
589 String javaVersion = System.getProperty('java.version')
590
591 RuntimeInfo() {
592 try {
593 new File('/proc/meminfo').readLines().findAll { it.startsWith 'Mem' }.collect { it.split(/\s+/) }.each {
594 int value = (it[1] as Long) / 1024
595 if (it[0].startsWith('MemTotal')) { systemMemory = value }
596 if (it[0].startsWith('MemFree')) { systemFreeMemory = value }
597 }
598
599 } catch (e) { }
600
601 }
602
603 void requireMemory(int megabytes) {
604 if (systemFreeMemory > 0 && systemFreeMemory < megabytes) {
605 println "WARNING: potentially insufficent OS memory for this build"
606 // throw new GradleException("insufficent free OS memory for this build (available: ${systemFreeMemory}m, required: ${megabytes}m)")
607 }
608 }
609 /**
610 * Returns maximum memory available upto the value specified.
611 */
612 int maxMemory(int megabytes) {
613 if (systemFreeMemory) {
614 [systemFreeMemory,megabytes].min()
615 } else { megabytes }
616
617 }
618
619 void requireJava(String version) {
620
621 if ( version && !javaVersion.startsWith(version)) {
622 throw new GradleException("Requires java version $version but running under $javaVersion")
623 }
624 }
625
626 }
627
628
629 @TupleConstructor
630 @Sortable
631 class Version {
632
633 Integer major = 0
634 Integer minor = 0
635 Integer patch = 0
636 Boolean snapshot = true
637
638 Integer previousMinor = 0
639 Integer previousPatch = 0
640
641 Version nextMajor() {
642 new Version(major + 1, 0, 0, false)
643 }
644
645 Version nextMinor() {
646 if (snapshot) {
647 new Version(major, minor , 0,false)
648 } else {
649 new Version(major, minor + 1, 0,false)
650 }
651 }
652
653 Version nextPatch() {
654 if (snapshot) {
655 new Version(major, previousMinor, previousPatch + 1,false)
656 }
657 }
658
659 Version nextSnapshot() {
660 new Version(major, minor + 1, 0,true,minor,patch)
661 }
662
663 boolean isHotfix() {
664 !snapshot && patch > 0
665 }
666
667 String toString() {
668 "${major}.${minor}.${patch}${snapshot ? '.SNAPSHOT' : ''}"
669 }
670
671 }
672
673 void setBranchInfo() {
674 gradle.ext.branch = new BranchInfo(System.getenv('bamboo_planRepository_branch'))
675 gradle.ext.branchName = gradle.branch.name
676 gradle.ext.branchStream = gradle.branch.stream
677 gradle.ext.branchHash = gradle.branch.hash
678 println "${gradle.hgRepositoryUrl} ${gradle.branch} ${gradle.branch.version}"
679 }
680
681
682 @ToString(includes=['name','shortName','buildVersion','imageId','deployName'],includeNames= true)
683 class BranchInfo {
684 def name
685 def stream = "none"
686 def buildNumber = ""
687 def changeset = ""
688 def version
689
690 BranchInfo(name) {
691 this.name = name
692 if (!name) {
693 this.name = determineName() ?: ''
694 }
695 this.name = this.name.replace('@', '-')
696 determineStream()
697 buildNumber = System.getenv('bamboo_buildNumber') ?: ""
698 changeset = System.getenv('bamboo_planRepository_revision') ?: ""
699 }
700
701 String getDefaultDependencyStatus() {
702 return isRelease() ? 'release' : 'integration'
703 }
704
705 private boolean isRelease() {
706 return stream in ['release', 'hotfix']
707 }
708
709 def getShortName() {
710 def result = name.contains('/') ? name.split('/')[1] : name
711 }
712
713 String getBuildVersion() {
714 def v = isRelease() ? shortName - "v": ""
715 return v
716 }
717
718 def Version getVersion() {
719 if (!version) {
720 if (isRelease()) {
721 version = new Version(*getBuildVersion().split('\\.')*.toInteger(), false)
722 } else {
723 version = findSnapshotVersion()
724 }
725 }
726 return version
727 }
728
729 def getImageId() {
730 (buildVersion ?: shortName.take(25)) + (buildNumber ? "-${buildNumber}" : "-0")
731 }
732
733 def getDeployName() {
734 (buildVersion ?: shortName.take(25)).toLowerCase().collectReplacements {
735 ('a'..'z').contains(it) || ('0'..'9').contains(it) || it == "-" ? null : '-'
736 }
737 }
738
739 def getHash() {
740 generateMD5(name)
741 }
742 def generateMD5(String s) {
743 def digest = java.security.MessageDigest.getInstance("MD5")
744 digest.update(s.bytes);
745 new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
746 }
747
748 private findSnapshotVersion() {
749
750 try {
751 def repositoryUrl = System.getenv('bamboo_planRepository_repositoryUrl')
752 if (repositoryUrl) {
753 println "hg pull $repositoryUrl".execute().text
754 }
755 def versions = "hg branches --closed".execute().text.split('\n').findAll {
756 it.startsWith( 'release') || it.startsWith( 'hotfix')
757 }.collect {
758 it.replaceAll('\\s+',' ').split(' ')[0].split('/')[1] - 'v'
759 }.collect {
760 new Version(*it.split('\\.')*.toInteger())
761 }.sort { v1, v2 -> v2 <=> v1 }
762
763 return versions ? versions.first().nextSnapshot() : new Version().nextSnapshot()
764
765 } catch (e) {
766 return new Version().nextSnapshot()
767 }
768
769 }
770
771 def determineName() {
772 try {
773 def branch = "hg branch".execute().text.trim()
774 def rawParents = 'hg parents'.execute().text
775 def parent = rawParents.split('\n').find { it.startsWith("branch") }?.split(":")?.getAt(1)?.trim()
776 return parent ?: branch
777 } catch (e) {
778 ['.hg/branch', '../.hg/branch'].findResult {
779 new File(it).exists() ? new File(it).text : null
780 }
781 }
782 }
783
784 void determineStream() {
785 def flowConfig = new File('.hgflow').exists() ? new File('.hgflow') : new File('../.hgflow')
786 if (flowConfig.exists()) {
787 def flows = new Properties()
788 flows.load(flowConfig.newReader())
789 flows.stringPropertyNames().each {
790 if (!it.startsWith("[") && name.startsWith(flows.getProperty(it))) {
791 stream = it
792 }
793 }
794 }
795 }
796
797 }
798