Skip to content

Commit

Permalink
fixed support for JARs and allow Ant-style patterns in the additional…
Browse files Browse the repository at this point in the history
… classpath option
  • Loading branch information
daspilker committed Jan 17, 2015
1 parent fe39ed3 commit 2377e40
Show file tree
Hide file tree
Showing 8 changed files with 221 additions and 50 deletions.
17 changes: 14 additions & 3 deletions Vagrantfile
Expand Up @@ -4,12 +4,23 @@
$script = <<SCRIPT
wget --quiet --output-document=/etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat-stable/jenkins.repo
rpm --import http://pkg.jenkins-ci.org/redhat-stable/jenkins-ci.org.key
yum --assumeyes --quiet install java-1.7.0-openjdk jenkins-1.565.3-1.1
yum --assumeyes --quiet install java-1.7.0-openjdk jenkins-1.565.3-1.1 git
service jenkins start
SCRIPT

$node_script = <<SCRIPT
yum --assumeyes --quiet install java-1.7.0-openjdk git
SCRIPT

Vagrant.configure("2") do |config|
config.vm.box = "chef/centos-7.0"
config.vm.network "forwarded_port", guest: 8080, host: 8081
config.vm.provision "shell", inline: $script

config.vm.define "master", primary: true do |master|
master.vm.network "forwarded_port", guest: 8080, host: 8081
master.vm.provision "shell", inline: $script
end

config.vm.define "node", autostart: false do |node|
node.vm.provision "shell", inline: $node_script
end
end
2 changes: 2 additions & 0 deletions config/codenarc/rules.groovy
Expand Up @@ -69,6 +69,8 @@ ruleset {
ruleset('rulesets/security.xml') {
// we don't care because our classes need not to satisfy the Java Beans specification
exclude 'JavaIoPackageAccess'
// we don't care for now
exclude 'FileCreateTempFile'
}

ruleset('rulesets/serialization.xml') {
Expand Down
2 changes: 2 additions & 0 deletions docs/Home.md
Expand Up @@ -22,6 +22,8 @@ And finally, if you want to get more involved, [here's how...](https://github.co
* Added support for renaming existing Jobs based on a regular expression
* Added support for the [Repository Connector Plugin](https://wiki.jenkins-ci.org/display/JENKINS/Repository+Connector+Plugin)
* Enhanced DSL support for the Job DSL plugin
* Fixed support for JARs in the "Additional classpath" option of the "Process Job DSLs" build step
* Allow Ant-style patterns in the "Additional classpath" option of the "Process Job DSLs" build step
* 1.28 (January 01 2015)
* Added support for the [Credentials Binding Plugin](https://wiki.jenkins-ci.org/display/JENKINS/Credentials+Binding+Plugin)
* Added support for the [HTTP Request Plugin](https://wiki.jenkins-ci.org/display/JENKINS/HTTP+Request+Plugin)
Expand Down
Expand Up @@ -188,36 +188,40 @@ public boolean perform(final AbstractBuild<?, ?> build, final Launcher launcher,
JenkinsJobManagement jm = new JenkinsJobManagement(listener.getLogger(), env, build, getLookupStrategy());

ScriptRequestGenerator generator = new ScriptRequestGenerator(build, env);
Set<ScriptRequest> scriptRequests = generator.getScriptRequests(
targets, usingScriptText, scriptText, ignoreExisting, additionalClasspath
);

Set<GeneratedJob> freshJobs = Sets.newLinkedHashSet();
Set<GeneratedView> freshViews = Sets.newLinkedHashSet();
Set<GeneratedConfigFile> freshConfigFiles = Sets.newLinkedHashSet();
for (ScriptRequest request : scriptRequests) {
LOGGER.log(Level.FINE, String.format("Request for %s", request.getLocation()));

GeneratedItems generatedItems = DslScriptLoader.runDslEngine(request, jm);
freshJobs.addAll(generatedItems.getJobs());
freshViews.addAll(generatedItems.getViews());
freshConfigFiles.addAll(generatedItems.getConfigFiles());
}
try {
Set<ScriptRequest> scriptRequests = generator.getScriptRequests(
targets, usingScriptText, scriptText, ignoreExisting, additionalClasspath
);

Set<GeneratedJob> freshJobs = Sets.newLinkedHashSet();
Set<GeneratedView> freshViews = Sets.newLinkedHashSet();
Set<GeneratedConfigFile> freshConfigFiles = Sets.newLinkedHashSet();
for (ScriptRequest request : scriptRequests) {
LOGGER.log(Level.FINE, String.format("Request for %s", request.getLocation()));

GeneratedItems generatedItems = DslScriptLoader.runDslEngine(request, jm);
freshJobs.addAll(generatedItems.getJobs());
freshViews.addAll(generatedItems.getViews());
freshConfigFiles.addAll(generatedItems.getConfigFiles());
}

updateTemplates(build, listener, freshJobs);
updateGeneratedJobs(build, listener, freshJobs);
updateGeneratedViews(build, listener, freshViews);
updateGeneratedConfigFiles(build, listener, freshConfigFiles);
updateTemplates(build, listener, freshJobs);
updateGeneratedJobs(build, listener, freshJobs);
updateGeneratedViews(build, listener, freshViews);
updateGeneratedConfigFiles(build, listener, freshConfigFiles);

// Save onto Builder, which belongs to a Project.
build.addAction(new GeneratedJobsBuildAction(freshJobs, getLookupStrategy()));
build.addAction(new GeneratedViewsBuildAction(freshViews, getLookupStrategy()));
build.addAction(new GeneratedConfigFilesBuildAction(freshConfigFiles));
// Save onto Builder, which belongs to a Project.
build.addAction(new GeneratedJobsBuildAction(freshJobs, getLookupStrategy()));
build.addAction(new GeneratedViewsBuildAction(freshViews, getLookupStrategy()));
build.addAction(new GeneratedConfigFilesBuildAction(freshConfigFiles));

// Hint that our new jobs might have really shaken things up
Jenkins.getInstance().rebuildDependencyGraph();
// Hint that our new jobs might have really shaken things up
Jenkins.getInstance().rebuildDependencyGraph();

return true;
return true;
} finally {
generator.close();
}
} catch (DslException e) {
LOGGER.log(Level.FINE, String.format("Exception while processing DSL scripts: %s", e.getMessage()));
throw new AbortException(e.getMessage());
Expand Down
Expand Up @@ -8,10 +8,11 @@ import javaposse.jobdsl.dsl.ScriptRequest

import static javaposse.jobdsl.plugin.WorkspaceProtocol.createWorkspaceUrl

class ScriptRequestGenerator {
class ScriptRequestGenerator implements Closeable {

final AbstractBuild build
EnvVars env
final Map<FilePath, File> cachedFiles = [:]

ScriptRequestGenerator(AbstractBuild build, EnvVars env) {
this.build = build
Expand All @@ -26,7 +27,13 @@ class ScriptRequestGenerator {
List<URL> classpath = []
if (additionalClasspath) {
String expandedClasspath = env.expand(additionalClasspath)
expandedClasspath.split('\n').each { classpath << createWorkspaceUrl(build, build.workspace.child(it)) }
expandedClasspath.split('\n').each {
if (it.contains('*') || it.contains('?')) {
classpath.addAll(build.workspace.list(it).collect { createClasspathURL(it) })
} else {
classpath << createClasspathURL(build.workspace.child(it))
}
}
}
if (usingScriptText) {
URL[] urlRoots = ([createWorkspaceUrl(build.project)] + classpath) as URL[]
Expand All @@ -44,4 +51,34 @@ class ScriptRequestGenerator {
}
scriptRequests
}

@Override
void close() throws IOException {
cachedFiles.values().each {
it.delete()
}
}

private URL createClasspathURL(FilePath filePath) {
if (filePath.isRemote()) {
if (filePath.directory) {
createWorkspaceUrl(build, filePath)
} else {
File file = cachedFiles[filePath]
if (!file) {
file = copyToLocal(filePath)
cachedFiles.put(filePath, file)
}
file.toURI().toURL()
}
} else {
filePath.toURI().toURL()
}
}

private static File copyToLocal(FilePath filePath) {
File file = File.createTempFile('jobdsl', '.jar')
filePath.copyTo(new FilePath(file))
file
}
}
Expand Up @@ -23,7 +23,8 @@ class WorkspaceProtocol {
static URL createWorkspaceUrl(AbstractBuild build, FilePath filePath) {
String relativePath = filePath.getRemote() - build.workspace.getRemote()
relativePath = relativePath.replaceAll('\\\\', '/') // normalize for Windows
new URL(createWorkspaceUrl(build.project), "$relativePath/", new WorkspaceUrlHandler())
String slash = filePath.directory ? '/' : ''
new URL(createWorkspaceUrl(build.project), "$relativePath$slash", new WorkspaceUrlHandler())
}

/**
Expand Down
Expand Up @@ -2,6 +2,8 @@ package javaposse.jobdsl.plugin

import hudson.EnvVars
import hudson.model.AbstractBuild
import hudson.model.FreeStyleProject
import hudson.model.Label
import javaposse.jobdsl.dsl.ScriptRequest
import org.junit.Rule
import org.jvnet.hudson.test.JenkinsRule
Expand Down Expand Up @@ -52,6 +54,7 @@ class ScriptRequestGeneratorSpec extends Specification {
def 'script text with additional classpath entry'() {
setup:
AbstractBuild build = jenkinsRule.buildAndAssertSuccess(jenkinsRule.createFreeStyleProject('foo'))
build.workspace.child('classes').mkdirs()
EnvVars env = new EnvVars()
ScriptRequestGenerator generator = new ScriptRequestGenerator(build, env)

Expand All @@ -64,13 +67,14 @@ class ScriptRequestGeneratorSpec extends Specification {
requests[0].body == SCRIPT
requests[0].urlRoots.length == 2
requests[0].urlRoots[0].toString() == 'workspace://foo/'
requests[0].urlRoots[1].toString() == 'workspace://foo/classes/'
requests[0].urlRoots[1] == new URL(build.workspace.toURI().toURL(), 'classes/')
!requests[0].ignoreExisting
}

def 'script text with additional classpath entry with variable expansion'() {
setup:
AbstractBuild build = jenkinsRule.buildAndAssertSuccess(jenkinsRule.createFreeStyleProject('foo'))
build.workspace.child('test/classes').mkdirs()
EnvVars env = new EnvVars([FOO: 'test'])
ScriptRequestGenerator generator = new ScriptRequestGenerator(build, env)

Expand All @@ -83,13 +87,15 @@ class ScriptRequestGeneratorSpec extends Specification {
requests[0].body == SCRIPT
requests[0].urlRoots.length == 2
requests[0].urlRoots[0].toString() == 'workspace://foo/'
requests[0].urlRoots[1].toString() == 'workspace://foo/test/classes/'
requests[0].urlRoots[1] == new URL(build.workspace.toURI().toURL(), 'test/classes/')
!requests[0].ignoreExisting
}

def 'script text with additional classpath entries'() {
setup:
AbstractBuild build = jenkinsRule.buildAndAssertSuccess(jenkinsRule.createFreeStyleProject('foo'))
build.workspace.child('classes').mkdirs()
build.workspace.child('output').mkdirs()
EnvVars env = new EnvVars()
ScriptRequestGenerator generator = new ScriptRequestGenerator(build, env)

Expand All @@ -104,8 +110,8 @@ class ScriptRequestGeneratorSpec extends Specification {
requests[0].body == SCRIPT
requests[0].urlRoots.length == 3
requests[0].urlRoots[0].toString() == 'workspace://foo/'
requests[0].urlRoots[1].toString() == 'workspace://foo/classes/'
requests[0].urlRoots[2].toString() == 'workspace://foo/output/'
requests[0].urlRoots[1] == new URL(build.workspace.toURI().toURL(), 'classes/')
requests[0].urlRoots[2] == new URL(build.workspace.toURI().toURL(), 'output/')
!requests[0].ignoreExisting
}

Expand Down Expand Up @@ -223,6 +229,8 @@ class ScriptRequestGeneratorSpec extends Specification {
AbstractBuild build = jenkinsRule.buildAndAssertSuccess(jenkinsRule.createFreeStyleProject('foo'))
build.workspace.child('a.groovy').write(SCRIPT, 'UTF-8')
build.workspace.child('b.groovy').write(SCRIPT, 'UTF-8')
build.workspace.child('classes').mkdirs()
build.workspace.child('output').mkdirs()
EnvVars env = new EnvVars()
ScriptRequestGenerator generator = new ScriptRequestGenerator(build, env)

Expand All @@ -237,15 +245,78 @@ class ScriptRequestGeneratorSpec extends Specification {
requests[0].body == null
requests[0].urlRoots.length == 3
requests[0].urlRoots[0].toString() == 'workspace://foo/'
requests[0].urlRoots[1].toString() == 'workspace://foo/classes/'
requests[0].urlRoots[2].toString() == 'workspace://foo/output/'
requests[0].urlRoots[1] == new URL(build.workspace.toURI().toURL(), 'classes/')
requests[0].urlRoots[2] == new URL(build.workspace.toURI().toURL(), 'output/')
!requests[0].ignoreExisting
requests[1].location == 'b.groovy'
requests[1].body == null
requests[1].urlRoots.length == 3
requests[1].urlRoots[0].toString() == 'workspace://foo/'
requests[1].urlRoots[1].toString() == 'workspace://foo/classes/'
requests[1].urlRoots[2].toString() == 'workspace://foo/output/'
requests[0].urlRoots[1] == new URL(build.workspace.toURI().toURL(), 'classes/')
requests[0].urlRoots[2] == new URL(build.workspace.toURI().toURL(), 'output/')
!requests[1].ignoreExisting
}

def 'additional classpath entries with pattern'() {
setup:
AbstractBuild build = jenkinsRule.buildAndAssertSuccess(jenkinsRule.createFreeStyleProject('foo'))
build.workspace.child('a.groovy').write(SCRIPT, 'UTF-8')
build.workspace.child('lib/a.jar').write(SCRIPT, 'UTF-8')
build.workspace.child('lib/b.jar').write(SCRIPT, 'UTF-8')
EnvVars env = new EnvVars()
ScriptRequestGenerator generator = new ScriptRequestGenerator(build, env)

when:
List<ScriptRequest> requests = generator.getScriptRequests(
'a.groovy\nb.groovy', false, null, false, 'lib/*.jar'
).toList()

then:
requests.size() == 1
requests[0].location == 'a.groovy'
requests[0].body == null
requests[0].urlRoots.length == 3
requests[0].urlRoots[0].toString() == 'workspace://foo/'
requests[0].urlRoots[1] == new URL(build.workspace.toURI().toURL(), 'lib/a.jar')
requests[0].urlRoots[2] == new URL(build.workspace.toURI().toURL(), 'lib/b.jar')
!requests[0].ignoreExisting
}

def 'additional classpath entries with pattern building on remote'() {
setup:
jenkinsRule.createSlave('label1', null)
FreeStyleProject job = jenkinsRule.createFreeStyleProject('foo')
job.assignedLabel = Label.get('label1')
AbstractBuild build = jenkinsRule.buildAndAssertSuccess(job)
build.workspace.child('a.groovy').write(SCRIPT, 'UTF-8')
build.workspace.child('lib/a.jar').write(SCRIPT, 'UTF-8')
build.workspace.child('lib/b.jar').write(SCRIPT, 'UTF-8')
EnvVars env = new EnvVars()
ScriptRequestGenerator generator = new ScriptRequestGenerator(build, env)

when:
List<ScriptRequest> requests = generator.getScriptRequests(
'a.groovy\nb.groovy', false, null, false, 'lib/*.jar'
).toList()

then:
requests.size() == 1
requests[0].location == 'a.groovy'
requests[0].body == null
requests[0].urlRoots.length == 3
requests[0].urlRoots[0].toString() == 'workspace://foo/'
URL tempDirUrl = new File(System.getProperty('java.io.tmpdir')).toURI().toURL()
requests[0].urlRoots[1] =~ "${tempDirUrl}jobdsl.*\\.jar"
requests[0].urlRoots[2] =~ "${tempDirUrl}jobdsl.*\\.jar"
!requests[0].ignoreExisting
new File(requests[0].urlRoots[1].toURI()).exists()
new File(requests[0].urlRoots[2].toURI()).exists()

when:
generator.close()

then:
!(new File(requests[0].urlRoots[1].toURI()).exists())
!(new File(requests[0].urlRoots[2].toURI()).exists())
}
}

0 comments on commit 2377e40

Please sign in to comment.