From ce8179544fab7b0fea45f2a77c52460b563d1514 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20August=C3=BDn?= Date: Mon, 2 Aug 2021 20:18:17 +0200 Subject: [PATCH] chore: regular properties instead of raw fields used (#311) --- .../dockercompose/ComposeExecutor.groovy | 28 +- .../dockercompose/ComposeSettings.groovy | 267 ++++++++++-------- .../dockercompose/DockerExecutor.groovy | 10 +- .../dockercompose/tasks/ComposeBuild.groovy | 4 +- .../dockercompose/tasks/ComposeDown.groovy | 2 +- .../tasks/ComposeDownForced.groovy | 27 +- .../dockercompose/tasks/ComposeLogs.groovy | 5 +- .../dockercompose/tasks/ComposePull.groovy | 8 +- .../dockercompose/tasks/ComposePush.groovy | 4 +- .../dockercompose/tasks/ComposeUp.groovy | 59 ++-- .../dockercompose/CaptureOutputTest.groovy | 4 +- .../DockerComposePluginTest.groovy | 16 +- 12 files changed, 232 insertions(+), 202 deletions(-) diff --git a/src/main/groovy/com/avast/gradle/dockercompose/ComposeExecutor.groovy b/src/main/groovy/com/avast/gradle/dockercompose/ComposeExecutor.groovy index c271b9c5..f16e5ad0 100644 --- a/src/main/groovy/com/avast/gradle/dockercompose/ComposeExecutor.groovy +++ b/src/main/groovy/com/avast/gradle/dockercompose/ComposeExecutor.groovy @@ -43,12 +43,12 @@ class ComposeExecutor { void executeWithCustomOutput(OutputStream os, Boolean ignoreExitValue, Boolean noAnsi, Boolean captureStderr, String... args) { def settings = this.settings def er = exec.exec { ExecSpec e -> - if (settings.dockerComposeWorkingDirectory) { - e.setWorkingDir(settings.dockerComposeWorkingDirectory) + if (settings.dockerComposeWorkingDirectory.isPresent()) { + e.setWorkingDir(settings.dockerComposeWorkingDirectory.get().asFile) } - e.environment = settings.environment - def finalArgs = [settings.executable] - finalArgs.addAll(settings.composeAdditionalArgs) + e.environment = settings.environment.get() + def finalArgs = [settings.executable.get()] + finalArgs.addAll(settings.composeAdditionalArgs.get()) if (noAnsi) { if (version >= VersionNumber.parse('1.28.0')) { finalArgs.addAll(['--ansi', 'never']) @@ -56,7 +56,7 @@ class ComposeExecutor { finalArgs.add('--no-ansi') } } - finalArgs.addAll(settings.useComposeFiles.collectMany { ['-f', it].asCollection() }) + finalArgs.addAll(settings.useComposeFiles.get().collectMany { ['-f', it].asCollection() }) String pn = settings.projectName if (pn) { finalArgs.addAll(['-p', pn]) @@ -73,7 +73,7 @@ class ComposeExecutor { } if (!ignoreExitValue && er.exitValue != 0) { def stdout = os != null ? os.toString().trim() : "N/A" - throw new RuntimeException("Exit-code ${er.exitValue} when calling ${settings.executable}, stdout: $stdout") + throw new RuntimeException("Exit-code ${er.exitValue} when calling ${settings.executable.get()}, stdout: $stdout") } } @@ -149,20 +149,20 @@ class ComposeExecutor { } Iterable getServiceNames() { - if (!settings.startedServices.empty) { - if(settings.includeDependencies) + if (!settings.startedServices.get().empty) { + if(settings.includeDependencies.get()) { - def dependentServices = getDependentServices(settings.startedServices).toList() - [*settings.startedServices, *dependentServices].unique() + def dependentServices = getDependentServices(settings.startedServices.get()).toList() + [*settings.startedServices.get(), *dependentServices].unique() } else { - settings.startedServices + settings.startedServices.get() } } else if (version >= VersionNumber.parse('1.6.0')) { execute('config', '--services').readLines() } else { - def composeFiles = settings.useComposeFiles.empty ? getStandardComposeFiles() : getCustomComposeFiles() + def composeFiles = settings.useComposeFiles.get().empty ? getStandardComposeFiles() : getCustomComposeFiles() composeFiles.collectMany { composeFile -> def compose = (Map) (new Yaml().load(fileOps.file(composeFile).text)) // if there is 'version' on top-level then information about services is in 'services' sub-tree @@ -193,7 +193,7 @@ class ComposeExecutor { } Iterable getCustomComposeFiles() { - settings.useComposeFiles.collect { + settings.useComposeFiles.get().collect { def f = fileOps.file(it) if (!f.exists()) { throw new IllegalArgumentException("Custom Docker Compose file not found: $f") diff --git a/src/main/groovy/com/avast/gradle/dockercompose/ComposeSettings.groovy b/src/main/groovy/com/avast/gradle/dockercompose/ComposeSettings.groovy index 83f1b6ed..9e46c9e4 100644 --- a/src/main/groovy/com/avast/gradle/dockercompose/ComposeSettings.groovy +++ b/src/main/groovy/com/avast/gradle/dockercompose/ComposeSettings.groovy @@ -12,6 +12,11 @@ import groovy.transform.CompileStatic import groovy.transform.PackageScope import org.gradle.api.Project import org.gradle.api.Task +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.ListProperty +import org.gradle.api.provider.MapProperty +import org.gradle.api.provider.Property import org.gradle.api.tasks.TaskProvider import org.gradle.internal.os.OperatingSystem import org.gradle.process.JavaForkOptions @@ -37,39 +42,52 @@ abstract class ComposeSettings { final ComposeExecutor composeExecutor final ServiceInfoCache serviceInfoCache - boolean buildBeforeUp = true - boolean buildBeforePull = true - - boolean waitForTcpPorts = true - List tcpPortsToIgnoreWhenWaiting = [] - Duration waitAfterTcpProbeFailure = Duration.ofSeconds(1) - Duration waitForTcpPortsTimeout = Duration.ofMinutes(15) - Duration waitForTcpPortsDisconnectionProbeTimeout = Duration.ofMillis(1000) - Duration waitAfterHealthyStateProbeFailure = Duration.ofSeconds(5) - Duration waitForHealthyStateTimeout = Duration.ofMinutes(15) - boolean checkContainersRunning = true - - List useComposeFiles = [] - - boolean captureContainersOutput = false - File captureContainersOutputToFile = null - File captureContainersOutputToFiles = null - File composeLogToFile = null - File containerLogToDir - - List startedServices = [] - Map scale = [:] - boolean removeOrphans = false - boolean forceRecreate = false - boolean noRecreate = false - List buildAdditionalArgs = [] - List pullAdditionalArgs = [] - List upAdditionalArgs = [] - List downAdditionalArgs = [] - List composeAdditionalArgs = [] + abstract ListProperty getUseComposeFiles() + abstract ListProperty getStartedServices() + abstract Property getIncludeDependencies() + abstract MapProperty getScale() + + abstract ListProperty getBuildAdditionalArgs() + abstract ListProperty getPullAdditionalArgs() + abstract ListProperty getUpAdditionalArgs() + abstract ListProperty getDownAdditionalArgs() + abstract ListProperty getComposeAdditionalArgs() + + abstract Property getBuildBeforeUp() + abstract Property getBuildBeforePull() + + abstract Property getRemoveOrphans() + abstract Property getForceRecreate() + abstract Property getNoRecreate() + + abstract Property getStopContainers() + abstract Property getRemoveContainers() + abstract Property getRetainContainersOnStartupFailure() + abstract Property getRemoveImages() + abstract Property getRemoveVolumes() + + abstract Property getIgnorePullFailure() + abstract Property getIgnorePushFailure() + abstract ListProperty getPushServices() + + abstract Property getWaitForTcpPorts() + abstract ListProperty getTcpPortsToIgnoreWhenWaiting() + abstract Property getWaitAfterTcpProbeFailure() + abstract Property getWaitForTcpPortsTimeout() + abstract Property getWaitForTcpPortsDisconnectionProbeTimeout() + abstract Property getWaitAfterHealthyStateProbeFailure() + abstract Property getWaitForHealthyStateTimeout() + abstract Property getCheckContainersRunning() + + abstract Property getCaptureContainersOutput() + abstract RegularFileProperty getCaptureContainersOutputToFile() + abstract DirectoryProperty getCaptureContainersOutputToFiles() + abstract RegularFileProperty getComposeLogToFile() + abstract DirectoryProperty getContainerLogToDir() protected String customProjectName protected Boolean customProjectNameSet + protected String safeProjectNamePrefix void setProjectName(String customProjectName) { this.customProjectName = customProjectName @@ -83,35 +101,77 @@ abstract class ComposeSettings { return "${projectNamePrefix}_${nestedName}" } else { - return "${generateSafeProjectNamePrefix(project)}_${nestedName}" + return "${safeProjectNamePrefix}_${nestedName}" } } String projectNamePrefix String nestedName - boolean stopContainers = true - boolean removeContainers = true - boolean retainContainersOnStartupFailure = false - RemoveImages removeImages = RemoveImages.None - boolean removeVolumes = true - boolean includeDependencies = false + abstract Property getExecutable() + abstract Property getDockerExecutable() + abstract MapProperty getEnvironment() - boolean ignorePullFailure = false - boolean ignorePushFailure = false - List pushServices = [] - - String executable = 'docker-compose' - Map environment = new HashMap(System.getenv()) - - String dockerExecutable = 'docker' - - String dockerComposeWorkingDirectory = null - Duration dockerComposeStopTimeout = Duration.ofSeconds(10) + abstract DirectoryProperty getDockerComposeWorkingDirectory() + abstract Property getDockerComposeStopTimeout() @Inject ComposeSettings(Project project, String name = '', String parentName = '') { this.project = project this.nestedName = parentName + name + this.safeProjectNamePrefix = generateSafeProjectNamePrefix(project) + + useComposeFiles.empty() + startedServices.empty() + includeDependencies.set(false) + scale.empty() + + buildAdditionalArgs.empty() + pullAdditionalArgs.empty() + upAdditionalArgs.empty() + downAdditionalArgs.empty() + composeAdditionalArgs.empty() + + buildBeforeUp.set(true) + buildBeforePull.set(true) + + removeOrphans.set(false) + forceRecreate.set(false) + noRecreate.set(false) + + stopContainers.set(true) + removeContainers.set(true) + retainContainersOnStartupFailure.set(false) + removeImages.set(RemoveImages.None) + removeVolumes.set(true) + + ignorePullFailure.set(false) + ignorePushFailure.set(false) + pushServices.empty() + + waitForTcpPorts.set(true) + tcpPortsToIgnoreWhenWaiting.empty() + waitAfterTcpProbeFailure.set(Duration.ofSeconds(1)) + waitForTcpPortsTimeout.set(Duration.ofMinutes(15)) + waitForTcpPortsDisconnectionProbeTimeout.set(Duration.ofMillis(1000)) + waitAfterHealthyStateProbeFailure.set(Duration.ofSeconds(5)) + waitForHealthyStateTimeout.set(Duration.ofMinutes(15)) + checkContainersRunning.set(true) + + captureContainersOutput.set(false) + + if (OperatingSystem.current().isMacOsX()) { + // Default installation is inaccessible from path, so set sensible + // defaults for this platform. + executable.set('/usr/local/bin/docker-compose') + dockerExecutable.set('/usr/local/bin/docker') + } else { + executable.set('docker-compose') + dockerExecutable.set('docker') + } + environment.set(System.getenv()) + dockerComposeStopTimeout.set(Duration.ofSeconds(10)) + + this.containerLogToDir.set(project.buildDir.toPath().resolve('containers-logs').toFile()) upTask = project.tasks.register(name ? "${name}ComposeUp".toString() : 'composeUp', ComposeUp, { it.settings = this }) buildTask = project.tasks.register(name ? "${name}ComposeBuild".toString() : 'composeBuild', ComposeBuild, { it.settings = this }) @@ -124,15 +184,6 @@ abstract class ComposeSettings { this.dockerExecutor = project.objects.newInstance(DockerExecutor, this) this.composeExecutor = project.objects.newInstance(ComposeExecutor, this) this.serviceInfoCache = new ServiceInfoCache(this) - - this.containerLogToDir = project.buildDir.toPath().resolve('containers-logs').toFile() - - if (OperatingSystem.current().isMacOsX()) { - // Default installation is inaccessible from path, so set sensible - // defaults for this platform. - this.executable = '/usr/local/bin/docker-compose' - this.dockerExecutable = '/usr/local/bin/docker' - } } private static String generateSafeProjectNamePrefix(Project project) { @@ -142,48 +193,50 @@ abstract class ComposeSettings { protected ComposeSettings cloneAsNested(String name) { def r = project.objects.newInstance(ComposeSettings, project, name, this.nestedName) - r.buildBeforeUp = this.buildBeforeUp - r.buildBeforePull = this.buildBeforePull - - r.waitForTcpPorts = this.waitForTcpPorts - r.tcpPortsToIgnoreWhenWaiting = new ArrayList<>(this.tcpPortsToIgnoreWhenWaiting) - r.waitAfterTcpProbeFailure = this.waitAfterTcpProbeFailure - r.waitForTcpPortsTimeout = this.waitForTcpPortsTimeout - r.waitForTcpPortsDisconnectionProbeTimeout = this.waitForTcpPortsDisconnectionProbeTimeout - r.waitAfterHealthyStateProbeFailure = this.waitAfterHealthyStateProbeFailure - r.waitForHealthyStateTimeout = this.waitForHealthyStateTimeout - r.checkContainersRunning = this.checkContainersRunning - - r.captureContainersOutput = this.captureContainersOutput - - r.removeOrphans = this.removeOrphans - r.forceRecreate = this.forceRecreate - r.noRecreate = this.noRecreate - r.buildAdditionalArgs = new ArrayList<>(this.buildAdditionalArgs) - r.pullAdditionalArgs = new ArrayList<>(this.pullAdditionalArgs) - r.upAdditionalArgs = new ArrayList<>(this.upAdditionalArgs) - r.downAdditionalArgs = new ArrayList<>(this.downAdditionalArgs) - r.composeAdditionalArgs = new ArrayList<>(this.composeAdditionalArgs) - r.projectNamePrefix = this.projectNamePrefix + r.includeDependencies.set(includeDependencies.get()) + + r.buildAdditionalArgs.set(new ArrayList(this.buildAdditionalArgs.get())) + r.pullAdditionalArgs.set(new ArrayList(this.pullAdditionalArgs.get())) + r.upAdditionalArgs.set(new ArrayList(this.upAdditionalArgs.get())) + r.downAdditionalArgs.set(new ArrayList(this.downAdditionalArgs.get())) + r.composeAdditionalArgs.set(new ArrayList(this.composeAdditionalArgs.get())) - r.stopContainers = this.stopContainers - r.removeContainers = this.removeContainers - r.retainContainersOnStartupFailure = this.retainContainersOnStartupFailure - r.removeImages = this.removeImages - r.removeVolumes = this.removeVolumes - r.includeDependencies = this.includeDependencies + r.buildBeforeUp.set(this.buildBeforeUp.get()) + r.buildBeforePull.set(this.buildBeforePull.get()) - r.ignorePullFailure = this.ignorePullFailure - r.ignorePushFailure = this.ignorePushFailure + r.removeOrphans.set(this.removeOrphans.get()) + r.forceRecreate.set(this.forceRecreate.get()) + r.noRecreate.set(this.noRecreate.get()) - r.executable = this.executable - r.environment = new HashMap<>(this.environment) + r.stopContainers.set(stopContainers.get()) + r.removeContainers.set(removeContainers.get()) + r.retainContainersOnStartupFailure.set(retainContainersOnStartupFailure.get()) + r.removeImages.set(removeImages.get()) + r.removeVolumes.set(removeVolumes.get()) - r.dockerExecutable = this.dockerExecutable + r.ignorePullFailure.set(ignorePullFailure.get()) + r.ignorePushFailure.set(ignorePushFailure.get()) - r.dockerComposeWorkingDirectory = this.dockerComposeWorkingDirectory - r.dockerComposeStopTimeout = this.dockerComposeStopTimeout + r.waitForTcpPorts.set(this.waitForTcpPorts.get()) + r.tcpPortsToIgnoreWhenWaiting.set(new ArrayList(this.tcpPortsToIgnoreWhenWaiting.get())) + r.waitAfterTcpProbeFailure.set(waitAfterTcpProbeFailure.get()) + r.waitForTcpPortsTimeout.set(waitForTcpPortsTimeout.get()) + r.waitForTcpPortsDisconnectionProbeTimeout.set(waitForTcpPortsDisconnectionProbeTimeout.get()) + r.waitAfterHealthyStateProbeFailure.set(waitAfterHealthyStateProbeFailure.get()) + r.waitForHealthyStateTimeout.set(waitForHealthyStateTimeout.get()) + r.checkContainersRunning.set(checkContainersRunning.get()) + + r.captureContainersOutput.set(captureContainersOutput.get()) + + r.projectNamePrefix = this.projectNamePrefix + + r.executable.set(this.executable.get()) + r.dockerExecutable.set(this.dockerExecutable.get()) + r.environment.set(new HashMap(this.environment.get())) + + r.dockerComposeWorkingDirectory.set(this.dockerComposeWorkingDirectory.getOrNull()) + r.dockerComposeStopTimeout.set(this.dockerComposeStopTimeout.get()) r } @@ -255,32 +308,8 @@ abstract class ComposeSettings { systemProperties } - void setCaptureContainersOutputToFile(CharSequence path) { - captureContainersOutputToFile = project.file(path) - } - - void setCaptureContainersOutputToFile(File file) { - captureContainersOutputToFile = file - } - - void setCaptureContainersOutputToFiles(CharSequence path) { - captureContainersOutputToFiles = project.file(path) - } - - void setCaptureContainersOutputToFiles(File file) { - captureContainersOutputToFiles = file - } - - void setComposeLogToFile(CharSequence path) { - composeLogToFile = project.file(path) - } - - void setComposeLogToFile(File file) { - composeLogToFile = file - } - boolean removeOrphans() { - composeExecutor.version >= VersionNumber.parse('1.7.0') && this.removeOrphans + composeExecutor.version >= VersionNumber.parse('1.7.0') && this.removeOrphans.get() } boolean scale() { @@ -288,7 +317,7 @@ abstract class ComposeSettings { if (v < VersionNumber.parse('1.13.0') && this.scale) { throw new UnsupportedOperationException("docker-compose version $v doesn't support --scale option") } - this.scale + !this.scale.get().isEmpty() } } diff --git a/src/main/groovy/com/avast/gradle/dockercompose/DockerExecutor.groovy b/src/main/groovy/com/avast/gradle/dockercompose/DockerExecutor.groovy index 202ca6b1..763b47de 100644 --- a/src/main/groovy/com/avast/gradle/dockercompose/DockerExecutor.groovy +++ b/src/main/groovy/com/avast/gradle/dockercompose/DockerExecutor.groovy @@ -25,8 +25,8 @@ class DockerExecutor { def settings = this.settings new ByteArrayOutputStream().withStream { os -> def er = exec.exec { ExecSpec e -> - e.environment = settings.environment - def finalArgs = [settings.dockerExecutable] + e.environment = settings.environment.get() + def finalArgs = [settings.dockerExecutable.get()] finalArgs.addAll(args) e.commandLine finalArgs e.standardOutput = os @@ -34,7 +34,7 @@ class DockerExecutor { } def stdout = os.toString().trim() if (er.exitValue != 0) { - throw new RuntimeException("Exit-code ${er.exitValue} when calling ${settings.dockerExecutable}, stdout: $stdout") + throw new RuntimeException("Exit-code ${er.exitValue} when calling ${settings.dockerExecutable.get()}, stdout: $stdout") } stdout } @@ -102,12 +102,12 @@ class DockerExecutor { } ServiceHost getContainerHost(Map inspection, String serviceName, Logger logger = this.logger) { - String servicesHost = settings.environment['SERVICES_HOST'] ?: System.getenv('SERVICES_HOST') + String servicesHost = settings.environment.get()['SERVICES_HOST'] ?: System.getenv('SERVICES_HOST') if (servicesHost) { logger.lifecycle("SERVICES_HOST environment variable detected - will be used as hostname of service $serviceName ($servicesHost)'") return new ServiceHost(host: servicesHost, type: ServiceHostType.RemoteDockerHost) } - String dockerHost = settings.environment['DOCKER_HOST'] ?: System.getenv('DOCKER_HOST') + String dockerHost = settings.environment.get()['DOCKER_HOST'] ?: System.getenv('DOCKER_HOST') if (dockerHost) { def host = dockerHost.toURI().host ?: 'localhost' logger.lifecycle("DOCKER_HOST environment variable detected - will be used as hostname of service $serviceName ($host)'") diff --git a/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeBuild.groovy b/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeBuild.groovy index 646b3a29..9fcd73c9 100644 --- a/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeBuild.groovy +++ b/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeBuild.groovy @@ -20,8 +20,8 @@ class ComposeBuild extends DefaultTask { @TaskAction void build() { String[] args = ['build'] - args += settings.buildAdditionalArgs - args += settings.startedServices + args += (List)settings.buildAdditionalArgs.get() + args += (List)settings.startedServices.get() settings.composeExecutor.execute(args) } } diff --git a/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeDown.groovy b/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeDown.groovy index 09aa4c71..47d0f2ea 100644 --- a/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeDown.groovy +++ b/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeDown.groovy @@ -12,7 +12,7 @@ class ComposeDown extends ComposeDownForced { @TaskAction void down() { - if (settings.stopContainers) { + if (settings.stopContainers.get()) { super.down() } else { logger.lifecycle('You\'re trying to stop the containers, but stopContainers is set to false. Please use composeDownForced task instead.') diff --git a/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeDownForced.groovy b/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeDownForced.groovy index 6eb797eb..fd13659a 100644 --- a/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeDownForced.groovy +++ b/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeDownForced.groovy @@ -20,43 +20,44 @@ class ComposeDownForced extends DefaultTask { void down() { def servicesToStop = settings.composeExecutor.serviceNames settings.serviceInfoCache.clear() - settings.composeExecutor.execute(*['stop', '--timeout', settings.dockerComposeStopTimeout.getSeconds().toString(), *servicesToStop]) - if (settings.removeContainers) { + settings.composeExecutor.execute(*['stop', '--timeout', settings.dockerComposeStopTimeout.get().getSeconds().toString(), *servicesToStop]) + if (settings.removeContainers.get()) { if (settings.composeExecutor.version >= VersionNumber.parse('1.6.0')) { String[] args = [] - if (!settings.startedServices.empty) { + if (!settings.startedServices.get().empty) { args += ['rm', '-f'] - if (settings.removeVolumes) { + if (settings.removeVolumes.get()) { args += ['-v'] } args += servicesToStop } else { args += ['down'] - switch (settings.removeImages) { + switch (settings.removeImages.get()) { case RemoveImages.All: case RemoveImages.Local: - args += ['--rmi', "${settings.removeImages}".toLowerCase()] + args += ['--rmi', "${settings.removeImages.get()}".toLowerCase()] break default: break } - if (settings.removeVolumes) { + if (settings.removeVolumes.get()) { args += ['--volumes'] } if (settings.removeOrphans()) { args += '--remove-orphans' } - args += settings.downAdditionalArgs + args += settings.downAdditionalArgs.get() } def composeLog = null - if(settings.composeLogToFile) { - logger.debug "Logging docker-compose down to: ${settings.composeLogToFile}" - settings.composeLogToFile.parentFile.mkdirs() - composeLog = new FileOutputStream(settings.composeLogToFile, true) + if(settings.composeLogToFile.isPresent()) { + File logFile = settings.composeLogToFile.get().asFile + logger.debug "Logging docker-compose down to: $logFile" + logFile.parentFile.mkdirs() + composeLog = new FileOutputStream(logFile, true) } settings.composeExecutor.executeWithCustomOutputWithExitValue(composeLog, args) } else { - if (!settings.startedServices.empty) { + if (!settings.startedServices.get().empty) { settings.composeExecutor.execute(*['rm', '-f', *servicesToStop]) } else { settings.composeExecutor.execute('rm', '-f') diff --git a/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeLogs.groovy b/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeLogs.groovy index 07e3192b..80b88a57 100644 --- a/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeLogs.groovy +++ b/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeLogs.groovy @@ -21,8 +21,9 @@ class ComposeLogs extends DefaultTask { void logs() { settings.composeExecutor.serviceNames.each { service -> println "Extracting container log from service '${service}'" - settings.containerLogToDir.mkdirs() - def logStream = new FileOutputStream("${settings.containerLogToDir.absolutePath}/${service}.log") + File logFile = settings.containerLogToDir.get().asFile + logFile.mkdirs() + def logStream = new FileOutputStream("${logFile.absolutePath}/${service}.log") String[] args = ['logs', '-t', service] settings.composeExecutor.executeWithCustomOutputWithExitValue(logStream, args) } diff --git a/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposePull.groovy b/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposePull.groovy index f9e395bd..19990464 100644 --- a/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposePull.groovy +++ b/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposePull.groovy @@ -19,15 +19,15 @@ class ComposePull extends DefaultTask { @TaskAction void pull() { - if (settings.buildBeforePull) { + if (settings.buildBeforePull.get()) { settings.buildTask.get().build() } String[] args = ['pull'] - if (settings.ignorePullFailure) { + if (settings.ignorePullFailure.get()) { args += '--ignore-pull-failures' } - args += settings.pullAdditionalArgs - args += settings.startedServices + args += (List)settings.pullAdditionalArgs.get() + args += (List)settings.startedServices.get() settings.composeExecutor.execute(args) } } diff --git a/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposePush.groovy b/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposePush.groovy index b0804edc..ab5ff234 100644 --- a/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposePush.groovy +++ b/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposePush.groovy @@ -20,10 +20,10 @@ class ComposePush extends DefaultTask { @TaskAction void push() { String[] args = ['push'] - if (settings.ignorePushFailure) { + if (settings.ignorePushFailure.get()) { args += '--ignore-push-failures' } - args += settings.pushServices + args += (List)settings.pushServices.get() settings.composeExecutor.execute(args) } } \ No newline at end of file diff --git a/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeUp.groovy b/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeUp.groovy index 9d55e2eb..2e64f683 100644 --- a/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeUp.groovy +++ b/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeUp.groovy @@ -32,7 +32,7 @@ class ComposeUp extends DefaultTask { @TaskAction void up() { - if (!settings.stopContainers) { + if (!settings.stopContainers.get()) { def cachedServicesInfos = settings.serviceInfoCache.get({ getStateForCache() }) if (cachedServicesInfos) { servicesInfos = cachedServicesInfos @@ -45,45 +45,44 @@ class ComposeUp extends DefaultTask { } settings.serviceInfoCache.clear() wasReconnected = false - if (settings.buildBeforeUp) { + if (settings.buildBeforeUp.get()) { settings.buildTask.get().build() } String[] args = ['up', '-d'] if (settings.removeOrphans()) { args += '--remove-orphans' } - if (settings.forceRecreate) { + if (settings.forceRecreate.get()) { args += '--force-recreate' args += '--renew-anon-volumes' - } else if (settings.noRecreate) { + } else if (settings.noRecreate.get()) { args += '--no-recreate' } if (settings.scale()) { - args += settings.scale.collect { service, value -> + args += settings.scale.get().collect { service, value -> ['--scale', "$service=$value"] }.flatten() } - if (settings.upAdditionalArgs) { - args += settings.upAdditionalArgs - } - args += settings.startedServices + args += settings.upAdditionalArgs.get() + args += settings.startedServices.get() try { def composeLog = null - if(settings.composeLogToFile) { - logger.debug "Logging docker-compose up to: ${settings.composeLogToFile}" - settings.composeLogToFile.parentFile.mkdirs() - composeLog = new FileOutputStream(settings.composeLogToFile) + if(settings.composeLogToFile.isPresent()) { + File logFile = settings.composeLogToFile.get().asFile + logger.debug "Logging docker-compose up to: $logFile" + logFile.parentFile.mkdirs() + composeLog = new FileOutputStream(logFile) } settings.composeExecutor.executeWithCustomOutputWithExitValue(composeLog, args) def servicesToLoad = settings.composeExecutor.getServiceNames() servicesInfos = loadServicesInfo(servicesToLoad).collectEntries { [(it.name): (it)] } startCapturing() waitForHealthyContainers(servicesInfos.values()) - if (settings.waitForTcpPorts) { + if (settings.waitForTcpPorts.get()) { servicesInfos = waitForOpenTcpPorts(servicesInfos.values()).collectEntries { [(it.name): (it)] } } printExposedPorts() - if (!settings.stopContainers) { + if (!settings.stopContainers.get()) { settings.serviceInfoCache.set(servicesInfos, getStateForCache()) } else { settings.serviceInfoCache.clear() @@ -91,7 +90,7 @@ class ComposeUp extends DefaultTask { } catch (Exception e) { logger.debug("Failed to start-up Docker containers", e) - if (!settings.retainContainersOnStartupFailure) { + if (!settings.retainContainersOnStartupFailure.get()) { settings.downForcedTask.get().down() } throw e @@ -122,16 +121,16 @@ class ComposeUp extends DefaultTask { } protected void startCapturing() { - if (settings.captureContainersOutput) { + if (settings.captureContainersOutput.get()) { settings.composeExecutor.captureContainersOutput(logger.&lifecycle) } - if (settings.captureContainersOutputToFile != null) { - def logFile = settings.captureContainersOutputToFile + if (settings.captureContainersOutputToFile.isPresent()) { + def logFile = settings.captureContainersOutputToFile.get().asFile logFile.parentFile.mkdirs() settings.composeExecutor.captureContainersOutput({ logFile.append(it + '\n') }) } - if (settings.captureContainersOutputToFiles != null) { - def logDir = settings.captureContainersOutputToFiles + if (settings.captureContainersOutputToFiles.isPresent()) { + def logDir = settings.captureContainersOutputToFiles.get().asFile logDir.mkdirs() logDir.listFiles().each { it.delete() } servicesInfos.keySet().each { @@ -143,7 +142,7 @@ class ComposeUp extends DefaultTask { @Internal protected def getStateForCache() { - settings.composeExecutor.execute('ps') + settings.composeExecutor.execute('config') + settings.startedServices.join(',') + settings.composeExecutor.execute('ps') + settings.composeExecutor.execute('config') + settings.startedServices.get().join(',') } protected Iterable loadServicesInfo(Iterable servicesNames) { @@ -185,15 +184,15 @@ class ComposeUp extends DefaultTask { break } logger.lifecycle("Waiting for ${instanceName} to become healthy (it's $healthStatus)") - if (!firstIteration) sleep(settings.waitAfterHealthyStateProbeFailure.toMillis()) + if (!firstIteration) sleep(settings.waitAfterHealthyStateProbeFailure.get().toMillis()) } else { logger.debug("Service ${instanceName} or this version of Docker doesn't support healthchecks") break } - if (settings.checkContainersRunning && !"running".equalsIgnoreCase(inspectionState.Status) && !"restarting".equalsIgnoreCase(inspectionState.Status)) { + if (settings.checkContainersRunning.get() && !"running".equalsIgnoreCase(inspectionState.Status) && !"restarting".equalsIgnoreCase(inspectionState.Status)) { throw new RuntimeException("Container ${containerInfo.containerId} of ${instanceName} is not running nor restarting. Logs:${System.lineSeparator()}${settings.dockerExecutor.getContainerLogs(containerInfo.containerId)}") } - if (start.plus(settings.waitForHealthyStateTimeout) < Instant.now()) { + if (start.plus(settings.waitForHealthyStateTimeout.get()) < Instant.now()) { throw new RuntimeException("Container ${containerInfo.containerId} of ${instanceName} is still reported as '${healthStatus}'. Logs:${System.lineSeparator()}${settings.dockerExecutor.getContainerLogs(containerInfo.containerId)}") } firstIteration = false @@ -208,14 +207,14 @@ class ComposeUp extends DefaultTask { servicesInfos.forEach { serviceInfo -> serviceInfo.containerInfos.each { instanceName, containerInfo -> containerInfo.tcpPorts - .findAll { ep, fp -> !settings.tcpPortsToIgnoreWhenWaiting.any { it == ep } } + .findAll { ep, fp -> !settings.tcpPortsToIgnoreWhenWaiting.get().any { it == ep } } .forEach { exposedPort, forwardedPort -> logger.lifecycle("Probing TCP socket on ${containerInfo.host}:${forwardedPort} of '${instanceName}'") Integer portToCheck = forwardedPort while (true) { try { def s = new Socket(containerInfo.host, portToCheck) - s.setSoTimeout(settings.waitForTcpPortsDisconnectionProbeTimeout.toMillis() as int) + s.setSoTimeout(settings.waitForTcpPortsDisconnectionProbeTimeout.get().toMillis() as int) try { // in case of Windows and Mac, we must ensure that the socket is not disconnected immediately // if the socket is closed then it returns -1 @@ -237,13 +236,13 @@ class ComposeUp extends DefaultTask { break } catch (Exception e) { - if (start.plus(settings.waitForTcpPortsTimeout) < Instant.now()) { + if (start.plus(settings.waitForTcpPortsTimeout.get()) < Instant.now()) { throw new RuntimeException("TCP socket on ${containerInfo.host}:${portToCheck} of '${instanceName}' is still failing. Logs:${System.lineSeparator()}${settings.dockerExecutor.getContainerLogs(containerInfo.containerId)}") } logger.lifecycle("Waiting for TCP socket on ${containerInfo.host}:${portToCheck} of '${instanceName}' (${e.message})") - sleep(settings.waitAfterTcpProbeFailure.toMillis()) + sleep(settings.waitAfterTcpProbeFailure.get().toMillis()) def inspection = settings.dockerExecutor.getInspection(containerInfo.containerId) - if (settings.checkContainersRunning && !"running".equalsIgnoreCase(inspection.State.Status) && !"restarting".equalsIgnoreCase(inspection.State.Status)) { + if (settings.checkContainersRunning.get() && !"running".equalsIgnoreCase(inspection.State.Status) && !"restarting".equalsIgnoreCase(inspection.State.Status)) { throw new RuntimeException("Container ${containerInfo.containerId} of ${instanceName} is not running nor restarting. Logs:${System.lineSeparator()}${settings.dockerExecutor.getContainerLogs(containerInfo.containerId)}") } ContainerInfo newContainerInfo = createContainerInfo(inspection, serviceInfo.name) diff --git a/src/test/groovy/com/avast/gradle/dockercompose/CaptureOutputTest.groovy b/src/test/groovy/com/avast/gradle/dockercompose/CaptureOutputTest.groovy index 76308f78..29fa401a 100644 --- a/src/test/groovy/com/avast/gradle/dockercompose/CaptureOutputTest.groovy +++ b/src/test/groovy/com/avast/gradle/dockercompose/CaptureOutputTest.groovy @@ -58,7 +58,7 @@ class CaptureOutputTest extends Specification { def f = Fixture.custom(composeFileContent) def logFile = new File(f.project.projectDir, "web.log") when: - f.extension.captureContainersOutputToFile = "${logFile.absolutePath}" + f.extension.captureContainersOutputToFile = f.project.file("${logFile.absolutePath}") f.project.tasks.composeUp.up() then: noExceptionThrown() @@ -87,7 +87,7 @@ class CaptureOutputTest extends Specification { def f = Fixture.custom(composeFileContent) def logFile = new File(f.project.projectDir, "compose.log") when: - f.extension.composeLogToFile = "${logFile.absolutePath}" + f.extension.composeLogToFile = f.project.file("${logFile.absolutePath}") f.project.tasks.composeUp.up() then: f.project.tasks.composeDown.down() diff --git a/src/test/groovy/com/avast/gradle/dockercompose/DockerComposePluginTest.groovy b/src/test/groovy/com/avast/gradle/dockercompose/DockerComposePluginTest.groovy index 0ad05d6a..adbcb9ad 100644 --- a/src/test/groovy/com/avast/gradle/dockercompose/DockerComposePluginTest.groovy +++ b/src/test/groovy/com/avast/gradle/dockercompose/DockerComposePluginTest.groovy @@ -67,7 +67,7 @@ class DockerComposePluginTest extends Specification { project.tasks.nestedComposeBuild instanceof ComposeBuild project.tasks.nestedComposeLogs instanceof ComposeLogs ComposeUp up = project.tasks.nestedComposeUp - up.settings.useComposeFiles == ['test.yml'] + up.settings.useComposeFiles.get() == ['test.yml'] } def "is possible to access servicesInfos of nested setting"() { @@ -97,12 +97,12 @@ class DockerComposePluginTest extends Specification { } } then: - project.dockerCompose.nested.removeVolumes == false - project.dockerCompose.removeVolumes == true - project.dockerCompose.ignorePullFailure == false - project.dockerCompose.ignorePushFailure == false - project.dockerCompose.nested.ignorePullFailure == true - project.dockerCompose.nested.ignorePushFailure == true + project.dockerCompose.nested.removeVolumes.get() == false + project.dockerCompose.removeVolumes.get() == true + project.dockerCompose.ignorePullFailure.get() == false + project.dockerCompose.ignorePushFailure.get() == false + project.dockerCompose.nested.ignorePullFailure.get() == true + project.dockerCompose.nested.ignorePushFailure.get() == true } def "isRequiredBy() adds dependencies"() { @@ -175,7 +175,7 @@ class DockerComposePluginTest extends Specification { project.tasks.integrationTestComposeBuild instanceof ComposeBuild project.tasks.integrationTestComposeLogs instanceof ComposeLogs ComposeUp up = project.tasks.integrationTestComposeUp - up.settings.useComposeFiles == ['test.yml'] + up.settings.useComposeFiles.get() == ['test.yml'] task.dependsOn.find { it instanceof TaskProvider && ((TaskProvider)it).get() == project.tasks.integrationTestComposeUp } task.getFinalizedBy().getDependencies(task).any { it == project.tasks.integrationTestComposeDown } }