Move metadata generation and storage to the components

Fixes  #34
This commit is contained in:
R. Tyler Croy 2015-07-07 08:45:18 -07:00
parent c2c91d797f
commit 4477b81aba
No known key found for this signature in database
GPG Key ID: 1426C7DC3F51E16F
9 changed files with 71 additions and 88 deletions

View File

@ -99,7 +99,6 @@ test {
events "passed", "skipped", "failed", "standardOut", "standardError"
}
}
check.dependsOn integrationTest
/* Whenever we're building an artifact, we should run the tests */
assemble.dependsOn check
@ -121,6 +120,7 @@ integrationTest.testLogging {
exceptionFormat = 'full'
events "passed", "skipped", "failed", "standardOut", "standardError"
}
check.dependsOn integrationTest
codenarc {
sourceSets = [sourceSets.main]

View File

@ -158,7 +158,6 @@ task run(type: Exec) {
fileExists(canaryFile)
}
@Ignore("Waiting on a refactor of metadata generation to couple more with components")
def "assemble should produce a zip with an etc/metadata.conf file"() {
given:
Map metadata = null
@ -170,6 +169,10 @@ service {
name '${projectName}'
component('api', type: JRuby) {
}
data {
dependencies 'api-redis'
}
}
"""
when:
@ -188,6 +191,7 @@ service {
and: "the metadata.conf should be valid YAML"
metadata instanceof Map
metadata.component.version == version
metadata.data.dependencies.contains 'api-redis'
}
@ -213,4 +217,4 @@ service {
and: "the VERSION file should be JSON"
json.parseText(zipFileContents(zipPath, versionPath)) instanceof Map
}
}
}

View File

@ -16,9 +16,11 @@ abstract class AbstractComponent {
protected Logger logger = LoggerFactory.getLogger(this.class)
protected Project project
protected Object extension
protected String name
protected Metadata metadata
void apply(Project project, String name) {
void apply(Project project, Object extension, String name) {
if (name?.length() <= 0) {
throw new StopExecutionException("Cannot apply component with a zero-length name")
}
@ -28,7 +30,51 @@ abstract class AbstractComponent {
}
this.project = project
this.extension = extension
this.name = name
this.metadata = new Metadata(extension?.serviceName, name, project.version)
this.metadata.service.dependencies = extension?.serviceDependencies
this.metadata.data = extension?.data
}
boolean createCompressedTasks(String archiveDirName) {
Project project = this.project
String metadataFilePath = String.format("%s/%s-metadata.conf", project.buildDir, this.name)
String metadataTaskName = String.format("%s%s", ServiceArtifactPlugin.METADATA_TASK, this.name.capitalize())
Task metadataTask = project.tasks.create(metadataTaskName) {
group ServiceArtifactPlugin.GROUP_NAME
description "Generate the service artifact etc/metadata.conf"
outputs.file(metadataFilePath).upToDateWhen { false }
doFirst {
new File(metadataFilePath).write(metadata.toYaml())
}
}
/* setting this up last so archiveDirName gets the right version and other things */
project.afterEvaluate {
[ServiceArtifactPlugin.TAR_TASK, ServiceArtifactPlugin.ZIP_TASK].each {
Task versionTask = this.project.tasks.findByName(ServiceArtifactPlugin.VERSION_TASK)
Task archiveTask = this.project.tasks.findByName(it)
if (archiveTask instanceof Task) {
archiveTask.dependsOn(versionTask)
archiveTask.dependsOn(metadataTask)
/* Pack the VERSION file containing some built metadata about
* this artifact to help trace it back to builds in the future
*/
archiveTask.into(archiveDirName) { from versionTask.outputs.files }
archiveTask.into("${archiveDirName}/etc") {
from metadataTask.outputs.files
rename "${this.name}-metadata.conf", "metadata.conf"
}
}
}
}
}
/**

View File

@ -57,8 +57,7 @@ class ServiceArtifactExtension {
* Bootstrap and set up whatever internal tasks/helpers we need to set up
*/
void bootstrap() {
String versionFilePath = String.format("%s/VERSION", this.project.buildDir)
String metadataFilePath = String.format("%s/metadata.conf", this.project.buildDir)
String versionFilePath = String.format("%s/VERSION", project.buildDir)
Task versionTask = project.tasks.create(ServiceArtifactPlugin.VERSION_TASK) {
group ServiceArtifactPlugin.GROUP_NAME
@ -72,35 +71,6 @@ class ServiceArtifactExtension {
new File(versionFilePath).write(builder.toPrettyString())
}
}
Task metadataTask = project.tasks.create(ServiceArtifactPlugin.METADATA_TASK) {
group ServiceArtifactPlugin.GROUP_NAME
description "Generate the service artifact etc/metadata.conf"
outputs.file(metadataFilePath).upToDateWhen { false }
doFirst {
new File(metadataFilePath).write(project.service.metadata.toYaml())
}
}
/* setting this up last so archiveDirName gets the right version and other things */
project.afterEvaluate {
[ServiceArtifactPlugin.TAR_TASK, ServiceArtifactPlugin.ZIP_TASK].each {
Task archiveTask = this.project.tasks.findByName(it)
if (archiveTask instanceof Task) {
archiveTask.dependsOn(versionTask)
archiveTask.dependsOn(metadataTask)
/* Pack the VERSION file containing some built metadata about
* this artifact to help trace it back to builds in the future
*/
archiveTask.into(this.archiveDirName) { from versionTask.outputs.files }
archiveTask.into("${this.archiveDirName}/etc") { from metadataTask.outputs.files }
}
}
}
}
/**
@ -242,8 +212,9 @@ class ServiceArtifactExtension {
}
AbstractComponent instance = keywordArguments.type.newInstance()
instance.apply(this.project, name)
instance.apply(this.project, this, name)
instance.chainCompressedArchives('serviceTar', 'serviceZip')
instance.createCompressedTasks(this.archiveDirName)
configurationSpec.delegate = instance
configurationSpec.call(instance)

View File

@ -26,8 +26,8 @@ class JRubyComponent extends AbstractComponent {
String mainScript = null
@Override
void apply(Project project, String name) {
super.apply(project, name)
void apply(Project project, Object ext, String name) {
super.apply(project, ext, name)
project.apply plugin: 'com.github.jruby-gradle.base'
project.apply plugin: 'com.github.jruby-gradle.jar'

View File

@ -1,6 +1,7 @@
package com.github.lookout.serviceartifact.metadata
import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.annotation.JsonIgnore
import org.gradle.api.Project
import org.gradle.api.file.FileTree
import org.slf4j.Logger
@ -46,6 +47,7 @@ class Data {
}
}
@JsonIgnore
File getProjectDir() {
return project.projectDir
}

View File

@ -29,7 +29,7 @@ class AbstractComponentSpec extends Specification {
def "apply() should raise if Project is not valid"() {
when:
component.apply(null, 'spork')
component.apply(null, null, 'spork')
then:
thrown(StopExecutionException)
@ -40,7 +40,7 @@ class AbstractComponentSpec extends Specification {
this.project = ProjectBuilder.builder().build()
when:
component.apply(project, '')
component.apply(project, null, '')
then:
thrown(StopExecutionException)
@ -52,7 +52,7 @@ class AbstractComponentSpec extends Specification {
String name = 'spock-component'
when:
component.apply(project, name)
component.apply(project, null, name)
then:
component.project == project
@ -64,7 +64,7 @@ class AbstractComponentSpec extends Specification {
String taskName = 'spockTar'
when:
component.apply(project, 'spock')
component.apply(project, null, 'spock')
then:
component.chainCompressedArchives(taskName) == false
@ -77,7 +77,7 @@ class AbstractComponentSpec extends Specification {
def result
when:
component.apply(project, 'spock')
component.apply(project, null, 'spock')
component.artifactTask = artifactTask
result = component.chainCompressedArchives(compressedArchive.name)

View File

@ -82,14 +82,6 @@ class ServiceArtifactExtensionSpec extends Specification {
this.project.tasks.findByName('serviceVersionInfo')
}
def "bootstrap() should define serviceMetadata"() {
when:
extension.bootstrap()
then:
this.project.tasks.findByName('serviceMetadata')
}
def "name() should add service:name to serviceMetadata"() {
given:
String serviceName = 'sample-service'
@ -176,38 +168,6 @@ class ServiceArtifactExtensionSpec extends Specification {
}
}
@Title("Verify complex behaviors manifested by the ServiceArtifactExtension")
class ExtensionIntegrationSpec extends AppliedExtensionSpec {
def "bootstrap() should have set up dependencies for serviceVersionInfo"() {
given:
Closure matcher = { (it instanceof Task) && (it.name == 'serviceVersionInfo') }
Task zip = this.project.tasks.findByName('serviceZip')
Task tar = this.project.tasks.findByName('serviceTar')
when:
project.evaluate()
then: "the compressed archives to rely on serviceVersionInfo"
zip.dependsOn.find(matcher)
tar.dependsOn.find(matcher)
}
def "bootstrap() should have set up dependencies for serviceMetadata"() {
given:
Closure matcher = { (it instanceof Task) && (it.name == 'serviceMetadata') }
Task zip = this.project.tasks.findByName('serviceZip')
Task tar = this.project.tasks.findByName('serviceTar')
when:
project.evaluate()
then: "the compressed archives to rely on serviceVersionInfo"
zip.dependsOn.find(matcher)
tar.dependsOn.find(matcher)
}
}
/**
* Test the functionality of the service { jruby{} } closure
*/

View File

@ -24,7 +24,7 @@ class JRubyComponentSpec extends Specification {
def "apply() should install the necessary plugins"() {
when:
component.apply(project, 'spock')
component.apply(project, null, 'spock')
then:
hasPlugins(project)
@ -37,7 +37,7 @@ class JRubyComponentSpec extends Specification {
def "getArtifactTask() should return a real task after apply()" () {
when:
component.apply(project, 'spock')
component.apply(project, null, 'spock')
then:
component.artifactTask instanceof Task
@ -51,7 +51,7 @@ class JRubyComponentSpec extends Specification {
def "mainScript() should set up the entrypoint in the JRuby Jar"() {
when:
component.apply(project, 'spock')
component.apply(project, null, 'spock')
component.mainScript 'main.rb'
then:
@ -63,7 +63,7 @@ class JRubyComponentSpec extends Specification {
def "include() with null should no-op"() {
when:
component.apply(project, 'spock')
component.apply(project, null, 'spock')
component.include()
then:
@ -72,7 +72,7 @@ class JRubyComponentSpec extends Specification {
def "include() should include files in a consistent relative structure in the JRuby Jar"() {
when:
component.apply(project, 'spock')
component.apply(project, null, 'spock')
component.include 'main.rb'
then: