Skip to content

Commit 8ecef6a

Browse files
authored
Merge pull request #176 from Cognifide/develop
Release 4.0.0-beta2
2 parents 84bea73 + 76935bd commit 8ecef6a

17 files changed

Lines changed: 138 additions & 48 deletions

File tree

README.md

Lines changed: 56 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -109,19 +109,29 @@ so that this repository need to be included in *buildscript* section.
109109

110110
#### Minimal:
111111

112+
File *settings.gradle*:
112113
```groovy
113-
buildscript {
114-
repositories {
115-
jcenter()
116-
maven { url "http://dl.bintray.com/cognifide/maven-public" }
117-
}
118-
119-
dependencies {
120-
classpath 'com.cognifide.gradle:aem-plugin:4.0.0-beta'
121-
}
114+
pluginManagement {
115+
repositories {
116+
jcenter()
117+
maven { url "http://dl.bintray.com/cognifide/maven-public" }
118+
}
119+
resolutionStrategy {
120+
eachPlugin {
121+
if (requested.id.namespace == 'com.cognifide.aem') {
122+
useModule('com.cognifide.gradle:aem-plugin:4.0.0-beta2')
123+
}
124+
}
125+
}
122126
}
127+
```
123128

124-
apply plugin: 'com.cognifide.aem.package'
129+
File *build.gradle*:
130+
```groovy
131+
plugins {
132+
id 'com.cognifide.aem.bundle' // or 'package' for JCR content only
133+
134+
}
125135
```
126136

127137
Building and deploying to AEM via command: `gradlew aemDeploy`.
@@ -131,8 +141,11 @@ Building and deploying to AEM via command: `gradlew aemDeploy`.
131141
AEM configuration section contains all default values for demonstrative purpose.
132142

133143
```groovy
134-
apply plugin: 'com.cognifide.aem.instance'
135-
apply plugin: 'kotlin' // 'java' or whatever you like to compile bundle
144+
plugins {
145+
id 'com.cognifide.aem.bundle'
146+
id 'com.cognifide.aem.instance'
147+
id 'org.jetbrains.kotlin.jvm' // or any other like 'java' to compile OSGi bundle
148+
}
136149
137150
defaultTasks = [':aemSatisfy', ':aemDeploy', ':aemAwait']
138151
@@ -481,20 +494,32 @@ Upload & install dependent CRX package(s) before deployment. Available methods:
481494
* `downloadSftpAuth(url: String, username: String, password: String)`, download package using SFTP protocol.
482495
* `downloadSftpAuth(url: String)`, as above, but credentials must be specified in variables: `aem.sftp.username`, `aem.sftp.password`. Optionally enable strict host checking by setting property `aem.sftp.hostChecking` to `true`.
483496
* `dependency(notation: String)`, use OSGi bundle that will be resolved from defined repositories (for instance from Maven) then wrapped to CRX package: `dependency('com.neva.felix:search-webconsole-plugin:1.2.0')`.
484-
* `group(name: String, configurer: Closure)`, useful for declaring group of packages (or just naming single package) to be installed only on demand. For instance: `group 'tools', { url('http://example.com/package.zip'); url('smb://internal-nt/package2.zip') }`. Then to install only packages in group `tools`, use command: `gradlew aemSatisfy -Paem.satisfy.group=tools`.
497+
* `group(name: String, configurer: Closure)`, useful for declaring group of packages (or just optionally naming single package) to be installed only on demand. For instance: `group 'tools', { url('http://example.com/package.zip'); url('smb://internal-nt/package2.zip') }`. Then to install only packages in group `tools`, use command: `gradlew aemSatisfy -Paem.satisfy.group=tools`.
498+
499+
It is also possible to specify packages to be deployed only once via command line parameter. Also for local files at any file system paths.
500+
501+
```bash
502+
gradlew aemSatisfy -Paem.satisfy.urls=[url1,url2]
503+
```
504+
505+
For instance:
506+
507+
```bash
508+
gradlew aemSatisfy -Paem.satisfy.urls=[https://github.com/OlsonDigital/aem-groovy-console/releases/download/11.0.0/aem-groovy-console-11.0.0.zip,https://github.com/neva-dev/felix-search-webconsole-plugin/releases/download/search-webconsole-plugin-1.2.0/search-webconsole-plugin-1.2.0.jar]
509+
```
485510

486511
#### Task `aemAwait`
487512

488513
Wait until all local or remote AEM instance(s) be stable.
489514

490515
AEM Config Param | CMD Property | Default Value | Purpose
491516
--- | --- | --- | ---
492-
`awaitStableInterval` | *aem.await.interval* | `1000` | Time in milliseconds used as interval between next instance stability checks being performed. Optimization could be necessary only when instance is heavily loaded.
517+
`awaitStableInterval` | *aem.await.stable.interval* | `1000` | Time in milliseconds used as interval between next instance stability checks being performed. Optimization could be necessary only when instance is heavily loaded.
493518
`awaitStableTimeout` | *aem.await.stable.timeout* | `900` | After each await interval, instance stability check is being performed. This value is a HTTP connection timeout (in millis) which must be smaller than interval to avoid race condition.
494519
`awaitStableTimes` | *aem.await.stable.times* | `300` | Maximum intervals after which instance stability checks will be skipped if there is still some unstable instance left.
495520
`awaitStableAssurances` | *aem.await.stable.assurances* | `3L` | Number of intervals / additional instance stability checks to assure all stable instances.
496521
`awaitStableCheck` | n/a | `{ it.checkBundleStable(500) }` | Hook for customizing instance stability check. Check will be repeated if assurance is configured.
497-
`awaitHealthCheck` | n/a | { `it.checkComponentState(awaitHealthComponentsActive) }` | Hook for customizing instance health check.
522+
`awaitHealthCheck` | n/a | { `it.checkComponentState(10000) }` | Hook for customizing instance health check.
498523
`awaitFast` | *aem.await.fast* | `false` | Skip stable check assurances and health checking. Alternative, quicker type of awaiting stable instances.
499524
`awaitFastDelay` | *aem.await.fast.delay* | `1000` | Time in milliseconds to postpone instance stability checks to avoid race condition related with actual operation being performed on AEM like starting JCR package installation or even creating launchpad.
500525
`awaitResume` | *aem.await.resume* | `false` | Do not fail build but log warning when there is still some unstable or unhealthy instance.
@@ -558,27 +583,27 @@ allprojects { subproject ->
558583
plugins.withId 'com.cognifide.aem.base', {
559584
aem {
560585
config {
561-
localInstance "http://localhost:6502"
586+
remoteInstance "http://localhost:6502"
562587
contentPath = subproject.file("src/main/aem")
563588
}
564589
}
565590
}
566591
}
567592
```
568593

569-
Project `:app` specific configuration like CRX package options should be defined in `app/build.gradle`:
594+
For instance, project `:app:core` specific configuration like OSGi bundle or CRX package options should be defined in `app/core/build.gradle`:
570595

571596
```groovy
572597
aem {
573598
config {
574-
contentPath = project.file("src/main/aem")
599+
bundlePackage = 'com.company.aem.example.core'
575600
}
576601
}
577602
578603
aemCompose {
579-
baseName = 'company-example'
604+
includeProjects ':content:*'
605+
baseName = 'example-core'
580606
duplicatesStrategy = "EXCLUDE"
581-
includeProject ':app:core'
582607
}
583608
```
584609

@@ -640,6 +665,17 @@ aem {
640665
}
641666
```
642667

668+
The above configuration can be also specified through *gradle.properties* file using dedicated syntax.
669+
670+
`aem.instance.$TYPE.$ENVIRONMENT-$TYPE_NAME.$PROP_NAME=$PROP_VALUE`
671+
672+
Part | Possible values | Description |
673+
--- | --- | --- |
674+
`$TYPE` | `local` or `remote` (only) | Type of instance. Local means that for each one there will be set up AEM Quickstart at local file system. |
675+
`$ENVIRONMENT` | `local`, `int`, `stg` etc | Environment name. |
676+
`$TYPE_NAME` | `author`, `publish`, `publish2`, etc | Combination of AEM instance type and semantic suffix useful when more than one of instance of same type is being configured. |
677+
`$PROP_NAME=$PROP_VALUE` | Local instances: `httpUrl=http://admin:admin@localhost:4502`, `password=foo`, `runModes=nosamplecontent`, `jvmOpts=-server -Xmx2048m -XX:MaxPermSize=512M -Djava.awt.headless=true`, `startOpts=...`, `debugPort=24502`. Remote instances: `httpUrl`, `user`, `password`. | Run modes, JVM opts and start opts should be comma delimited. |
678+
643679
**Rules:**
644680

645681
* Instance name is a combination of *${environment}-${typeName}* e.g *local-author*, *integration-publish* etc.

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ plugins {
66
}
77

88
group 'com.cognifide.gradle'
9-
version '4.0.0-beta'
9+
version '4.0.0-beta2'
1010
description = 'Gradle AEM Plugin'
1111
defaultTasks = ['clean', 'build', 'publishToMavenLocal']
1212

src/main/kotlin/com/cognifide/gradle/aem/api/AemConfig.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ class AemConfig(
413413
*/
414414
@Internal
415415
@get:JsonIgnore
416-
var awaitHealthCheck: (InstanceState) -> Boolean = { it.checkComponentState( setOf("com.day.crx.packaging.*", "org.apache.sling.installer.*"), 10000) }
416+
var awaitHealthCheck: (InstanceState) -> Boolean = { it.checkComponentState(10000) }
417417

418418
/**
419419
* Time in milliseconds to postpone instance stability checks after triggering instances restart.

src/main/kotlin/com/cognifide/gradle/aem/api/AemDefaultTask.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ abstract class AemDefaultTask : DefaultTask(), AemTask {
1414
protected val notifier = AemNotifier.of(project)
1515

1616
@Internal
17-
protected val propertyParser = PropertyParser(project)
17+
protected val props = PropertyParser(project)
1818

1919
init {
2020
group = AemTask.GROUP

src/main/kotlin/com/cognifide/gradle/aem/instance/CreateTask.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@ open class CreateTask : AemDefaultTask() {
3535
}
3636

3737
private fun instanceFilesByProperties() {
38-
val jarUrl = propertyParser.string(JAR_URL_PROP)
38+
val jarUrl = props.string(JAR_URL_PROP)
3939
if (!jarUrl.isNullOrBlank()) {
4040
instanceFileResolver.url(jarUrl!!)
4141
}
4242

43-
val licenseUrl = propertyParser.string(LICENSE_URL_PROP)
43+
val licenseUrl = props.string(LICENSE_URL_PROP)
4444
if (!licenseUrl.isNullOrBlank()) {
4545
instanceFileResolver.url(licenseUrl!!)
4646
}

src/main/kotlin/com/cognifide/gradle/aem/instance/DestroyTask.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ open class DestroyTask : AemDefaultTask() {
1515

1616
@TaskAction
1717
fun destroy() {
18-
propertyParser.checkForce()
18+
props.checkForce()
1919

2020
val handles = Instance.handles(project)
2121
handles.parallelStream().forEach { it.destroy() }

src/main/kotlin/com/cognifide/gradle/aem/instance/InstanceState.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ class InstanceState(private var _sync: InstanceSync, val instance: Instance) {
4545
})
4646
}
4747

48+
fun checkComponentState(connectionTimeout: Int = 10000): Boolean {
49+
return checkComponentState(PLATFORM_COMPONENTS, connectionTimeout)
50+
}
51+
4852
fun checkComponentState(packagesActive: Collection<String>, connectionTimeout: Int = 10000): Boolean {
4953
return check({
5054
it.connectionTimeout = connectionTimeout
@@ -74,4 +78,11 @@ class InstanceState(private var _sync: InstanceSync, val instance: Instance) {
7478
.isEquals
7579
}
7680

81+
companion object {
82+
val PLATFORM_COMPONENTS = setOf(
83+
"com.day.crx.packaging.*",
84+
"org.apache.sling.installer.*"
85+
)
86+
}
87+
7788
}

src/main/kotlin/com/cognifide/gradle/aem/instance/SatisfyTask.kt

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,39 @@ open class SatisfyTask : AemDefaultTask() {
3232

3333
@get:Internal
3434
val packageGroups by lazy {
35-
logger.info("Providing packages from local and remote sources.")
35+
val result = if (cmdGroups) {
36+
logger.info("Providing packages defined via command line.")
37+
packageProvider.filterGroups("cmd.*")
38+
} else {
39+
logger.info("Providing packages defined in build script.")
40+
packageProvider.filterGroups(groupFilter)
41+
}
3642

37-
val packageGroups = packageProvider.filterGroups(groupFilter)
38-
val packageFiles = packageGroups.flatMap { it.files }
43+
val files = result.flatMap { it.files }
3944

40-
logger.info("Packages provided (${packageFiles.size}).")
45+
logger.info("Packages provided (${files.size}).")
4146

4247
@Suppress("unchecked_cast")
43-
packageGroups as List<PackageGroup>
48+
result as List<PackageGroup>
4449
}
4550

51+
@get:Internal
52+
val cmdGroups: Boolean
53+
get() = project.properties["aem.satisfy.urls"] != null
54+
4655
init {
4756
group = AemTask.GROUP
4857
description = "Satisfies AEM by uploading & installing dependent packages on instance(s)."
58+
59+
defineCmdGroups()
60+
}
61+
62+
fun defineCmdGroups() {
63+
if (cmdGroups) {
64+
props.list("aem.satisfy.urls").forEachIndexed { index, url ->
65+
packageProvider.group("cmd.${index + 1}", { url(url) })
66+
}
67+
}
4968
}
5069

5170
fun packages(closure: Closure<*>) {

src/main/kotlin/com/cognifide/gradle/aem/internal/PropertyParser.kt

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,21 @@ class PropertyParser(val project: Project) {
4545
}
4646

4747
private fun prop(name: String): String? {
48-
var value = project.properties[name] as String?
49-
if (value == null) {
50-
value = systemProps[name]
48+
if (project.hasProperty(name)) {
49+
return project.property(name).toString()
5150
}
52-
if (value == null) {
53-
value = envProps[name]
51+
52+
var systemValue = System.getProperty(name)
53+
if (systemValue != null) {
54+
return systemValue
55+
}
56+
57+
var envValue = System.getenv(name)
58+
if (envValue != null) {
59+
return envValue
5460
}
5561

56-
return value
62+
return null
5763
}
5864

5965
fun flag(name: String): Boolean {

src/main/kotlin/com/cognifide/gradle/aem/internal/file/resolver/FileResolver.kt

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.cognifide.gradle.aem.internal.file.resolver
22

33
import com.cognifide.gradle.aem.internal.Formats
4+
import com.cognifide.gradle.aem.internal.Patterns
5+
import com.cognifide.gradle.aem.internal.file.FileException
46
import com.cognifide.gradle.aem.internal.file.downloader.HttpFileDownloader
57
import com.cognifide.gradle.aem.internal.file.downloader.SftpFileDownloader
68
import com.cognifide.gradle.aem.internal.file.downloader.SmbFileDownloader
@@ -68,13 +70,21 @@ open class FileResolver(val project: Project, val downloadDir: File) {
6870
return filterGroups(filter).flatMap { it.files }
6971
}
7072

73+
fun group(name: String): FileGroup {
74+
return groups.find { it.name == name } ?: throw FileException("File group '$name' is not defined.")
75+
}
76+
77+
fun filterGroups(filter: String): List<FileGroup> {
78+
return filterGroups { Patterns.wildcard(it, filter) }
79+
}
80+
7181
fun filterGroups(filter: (String) -> Boolean): List<FileGroup> {
7282
return groups.filter { filter(it.name) }.filter { it.resolutions.isNotEmpty() }
7383
}
7484

7585
fun dependency(notation: Any) {
7686
resolve(notation, {
77-
val configName = "fileResolver_dependency_${DigestUtils.md5Hex(downloadDir.path + notation)}"
87+
val configName = "fileResolver_dependency_${DigestUtils.md5Hex(downloadDir.path + notation)}"
7888
val configOptions: (Configuration) -> Unit = { it.isTransitive = false }
7989
val config = project.configurations.create(configName, configOptions)
8090

@@ -227,14 +237,22 @@ open class FileResolver(val project: Project, val downloadDir: File) {
227237
resolve(sourceFile.absolutePath, { sourceFile })
228238
}
229239

230-
fun group(name: String, configurer: Closure<*>) {
240+
fun group(name: String, configurer: FileResolver.() -> Unit) {
231241
groupCurrent = groups.find { it.name == name } ?: createGroup(name).apply { groups.add(this) }
232-
ConfigureUtil.configureSelf(configurer, this)
242+
apply(configurer)
233243
groupCurrent = groupDefault
234244
}
235245

246+
fun group(name: String, configurer: Closure<*>) {
247+
group(name, { ConfigureUtil.configure(configurer, this) })
248+
}
249+
250+
fun config(configurer: FileGroup.() -> Unit) {
251+
groupCurrent.apply(configurer)
252+
}
253+
236254
fun config(configurer: Closure<*>) {
237-
ConfigureUtil.configureSelf(configurer, groupCurrent)
255+
config { ConfigureUtil.configure(configurer, this) }
238256
}
239257

240258
}

0 commit comments

Comments
 (0)