Skip to content

Commit

Permalink
Tidy up classes
Browse files Browse the repository at this point in the history
  • Loading branch information
sagebind committed Feb 21, 2020
1 parent 5b2cacf commit 49b63fa
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 108 deletions.
2 changes: 0 additions & 2 deletions .buildkite/pipeline.extra-steps.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ blockStep(':rocket: Release!') {
}
}

triggerStep 'other-pipeline'

triggerStep 'other-pipeline', {
branches 'master'
async true
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.widen.plugins.buildkite

import groovy.transform.PackageScope
import org.gradle.api.Project

class BuildkiteExtension {
@PackageScope
Project project

@PackageScope
final Map<String, Closure<BuildkitePipeline>> pipelines = [:]

@PackageScope
final Map<String, String> pluginVersions = [
docker: 'v3.2.0',
'docker-compose': 'v3.0.3',
]

/**
* The default agent queue name to use for steps that do not specify one.
*/
String defaultAgentQueue = 'builder'

/**
* Whether detected pipeline script files should be included automatically.
*/
boolean includeScripts = true

/**
* Set the default agent queue name.
*/
void defaultAgentQueue(String queueName) {
defaultAgentQueue = queueName
}

/**
* Specify the version of a Buildkite plugin that should be used inside pipelines if no version is specified.
*/
void pluginVersion(String name, String version) {
pluginVersions[name] = version
}

/**
* Defines the default pipeline.
*/
void pipeline(@DelegatesTo(strategy = Closure.DELEGATE_FIRST, value = BuildkitePipeline) Closure closure) {
pipeline('default', closure)
}

/**
* Defines a named pipeline.
*/
void pipeline(
String name,
@DelegatesTo(strategy = Closure.DELEGATE_FIRST, value = BuildkitePipeline) Closure closure
) {
pipelines[name] = {
def pipeline = new BuildkitePipeline(project, this)
pipeline.with(closure)
return pipeline
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@ package com.widen.plugins.buildkite

import groovy.json.JsonBuilder
import groovy.json.JsonOutput
import org.gradle.api.Project

import java.nio.file.Files
import java.time.Duration

class BuildkitePipeline implements ConfigurableEnvironment {
private final BuildkitePlugin.Config pluginConfig
private final Project project
private final BuildkiteExtension buildkite
private final Map<String, String> env = [:]
private final List steps = []
private final List<Object> steps = []

BuildkitePipeline(BuildkitePlugin.Config pluginConfig) {
this.pluginConfig = pluginConfig
BuildkitePipeline(Project project, BuildkiteExtension buildkite) {
this.project = project
this.buildkite = buildkite
}

/**
Expand Down Expand Up @@ -68,7 +71,7 @@ class BuildkitePipeline implements ConfigurableEnvironment {
class CommandStep extends Step implements ConfigurableEnvironment {
// Set defaults.
{
agentQueue pluginConfig.defaultAgentQueue
agentQueue buildkite.defaultAgentQueue
}

/**
Expand Down Expand Up @@ -216,8 +219,8 @@ class BuildkitePipeline implements ConfigurableEnvironment {
}

// If no version is given and a default version is defined, set it.
if (!name.contains("#") && pluginConfig.pluginVersions.containsKey(name)) {
name += "#${pluginConfig.pluginVersions[name]}"
if (!name.contains("#") && buildkite.pluginVersions.containsKey(name)) {
name += "#${buildkite.pluginVersions[name]}"
}

model.get('plugins', []) << [
Expand Down Expand Up @@ -321,7 +324,7 @@ class BuildkitePipeline implements ConfigurableEnvironment {

// Pre-populate some config files.
['docker-compose.yml', 'docker-compose.buildkite.yml'].each {
if (Files.exists(pluginConfig.rootDir.toPath().resolve(it))) {
if (Files.exists(project.rootDir.toPath().resolve(it))) {
config.composeFile(it)
}
}
Expand Down Expand Up @@ -619,7 +622,7 @@ class BuildkitePipeline implements ConfigurableEnvironment {
closure = (Closure) closure.clone()
closure.delegate = map
closure.resolveStrategy = Closure.OWNER_FIRST
closure()
closure.call()

model.get('build', [:])
.get('meta_data', [:])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,21 @@ package com.widen.plugins.buildkite
import org.codehaus.groovy.control.CompilerConfiguration
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task

class BuildkitePlugin implements Plugin<Project> {
private static final String GROUP = 'Buildkite'

@Override
void apply(Project project) {
def extension = project.extensions.create('buildkite', Extension)
def extension = project.extensions.create('buildkite', BuildkiteExtension)
extension.project = project

extension.config = new Config().with {
rootDir = project.rootDir
it
}
project.task('pipelines') { Task task ->
task.group = GROUP
task.description = "List all Buildkite pipelines."

project.task('pipelines') {
doLast {
task.doLast {
extension.pipelines.each {
println it.key
}
Expand All @@ -25,95 +27,45 @@ class BuildkitePlugin implements Plugin<Project> {
// Run anything that needs to be done after plugin configuration has been evaluated.
project.afterEvaluate {
if (extension.includeScripts) {
def shell = new GroovyShell(project.buildscript.classLoader, new Binding(project: project), new
CompilerConfiguration(
scriptBaseClass: PipelineScript.class.name
))

project.fileTree(project.rootDir) {
loadPipelineScripts(project, extension, project.fileTree(project.rootDir) {
include '.buildkite/pipeline*.gradle'
}.each { file ->
def pipelineName = file.name.find(/pipeline\.([^.]+)\.gradle/) { x, name ->
name.replaceAll(/[^a-zA-Z0-9]+([a-zA-Z0-9]+)/) { y, word ->
word.capitalize()
}
} ?: 'default'

def script = (PipelineScript) shell.parse(file)

extension.pipeline(pipelineName) { BuildkitePipeline pipeline ->
println(pipeline)
script.setPipeline(pipeline)
script.setBuildkite(extension)
script.setProject(project)
script.run()
}
}
})
}

extension.pipelines.each { name, config ->
def taskName = name == 'default' ? 'uploadPipeline' : "upload${name.capitalize()}Pipeline"

project.tasks.create(taskName, UploadPipelineTask) {
pipelineConfigure = config
project.tasks.create(taskName, UploadPipelineTask) { task ->
task.group = GROUP
task.description = "Upload the $name pipeline to the current job."
task.pipelineConfig = config
}
}
}
}

static class Config {
String defaultAgentQueue = 'builder'

final Map<String, String> pluginVersions = [
docker: 'v3.2.0',
'docker-compose': 'v3.0.3',
]

File rootDir
}

static class Extension {
protected final Map<String, Closure<BuildkitePipeline>> pipelines = [:]
protected Config config

/**
* Whether detected pipeline script files should be included automatically.
*/
boolean includeScripts = true

/**
* Set the default agent queue name to use for steps that do not specify one.
*/
void defaultAgentQueue(String queueName) {
config.defaultAgentQueue = queueName
}

/**
* Specify the version of a Buildkite plugin that should be used inside pipelines if no version is specified.
*/
void pluginVersion(String name, String version) {
config.pluginVersions[name] = version
}

/**
* Defines the default pipeline.
*/
void pipeline(@DelegatesTo(strategy = Closure.DELEGATE_FIRST, value = BuildkitePipeline) Closure closure) {
pipeline('default', closure)
private static loadPipelineScripts(Project project, BuildkiteExtension extension, Iterable<File> files) {
def shell = new GroovyShell(project.buildscript.classLoader, new CompilerConfiguration(
scriptBaseClass: PipelineScript.class.name
))

files.each { file ->
extension.pipeline(pipelineNameFromFile(file)) { BuildkitePipeline pipeline ->
// Avoid loading the file until the pipeline spec is actually requested.
def script = (PipelineScript) shell.parse(file)
script.setProject(project)
script.setBuildkite(extension)
script.setPipeline(pipeline)
script.run()
}
}
}

/**
* Defines a named pipeline.
*/
void pipeline(
String name,
@DelegatesTo(strategy = Closure.DELEGATE_FIRST, value = BuildkitePipeline) Closure closure
) {
pipelines[name] = {
def pipeline = new BuildkitePipeline(config)
pipeline.with(closure)
return pipeline
private static String pipelineNameFromFile(File file) {
return file.name.find(/pipeline\.([^.]+)\.gradle/) { x, name ->
name.replaceAll(/[^a-zA-Z0-9]+([a-zA-Z0-9]+)/) { y, word ->
word.capitalize()
}
}
} ?: 'default'
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,30 @@ package com.widen.plugins.buildkite
import org.gradle.api.Project

/**
* Base class for scripts
* Base class for scripts that define a Buildkite pipeline.
*/
abstract class PipelineScript extends Script {
BuildkitePipeline pipeline
BuildkitePlugin.Extension buildkite
Project project
BuildkiteExtension buildkite
BuildkitePipeline pipeline

Object getProperty(String property) {
if ('buildkite' == property) {
return buildkite
try {
return getMetaClass().getProperty(this, property)
} catch (MissingPropertyException e) {
return pipeline.getProperty(property)
}
if ('project' == property) {
return project
}
return pipeline.getProperty(property)
}

void setProperty(String property, Object newValue) {
pipeline.setProperty(property, newValue)
}

Object invokeMethod(String name, Object args) {
return pipeline.invokeMethod(name, args)
try {
return getMetaClass().invokeMethod(this, name, args)
} catch (MissingMethodException e) {
return pipeline.invokeMethod(name, args)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
package com.widen.plugins.buildkite

import groovy.json.JsonOutput
import groovy.transform.PackageScope
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction

/**
* A Gradle task that uploads a pipeline during a build.
*/
class UploadPipelineTask extends DefaultTask {
Closure<BuildkitePipeline> pipelineConfigure
@PackageScope
Closure<BuildkitePipeline> pipelineConfig

/**
* Upload the pipeline to Buildkite to be executed.
*/
@TaskAction
void upload() {
def pipeline = pipelineConfigure.call()
def pipeline = pipelineConfig.call()

if (System.env.BUILDKITE || System.env.CI) {
if (System.getenv('BUILDKITE') || System.getenv('CI')) {
def cmd = ['buildkite-agent', 'pipeline', 'upload']

if (!pipeline.interpolate) {
Expand All @@ -34,7 +36,7 @@ class UploadPipelineTask extends DefaultTask {
it << pipeline.toJson()
}
if (process.waitFor() != 0) {
throw new RuntimeException()
throw new RuntimeException("buildkite-agent returned exit code ${process.exitValue()}")
}
} else {
print(JsonOutput.prettyPrint(pipeline.toJson()))
Expand Down

0 comments on commit 49b63fa

Please sign in to comment.