Skip to content

Commit 7423038

Browse files
committed
Merge branch 'feature/list-jobs-using-dsl' of git://github.com/sahal/jenkins_api_client into sahal-feature/list-jobs-using-dsl
2 parents b1c4129 + 9af3e1d commit 7423038

File tree

2 files changed

+129
-16
lines changed

2 files changed

+129
-16
lines changed

lib/jenkins_api_client/job.rb

+62-8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#
1+
22
# Copyright (c) 2012-2013 Kannan Manickam <[email protected]>
33
#
44
# Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -653,16 +653,70 @@ def list_by_status(status, jobs = [])
653653
#
654654
def list(filter, ignorecase = true)
655655
@logger.info "Obtaining jobs matching filter '#{filter}'"
656-
response_json = @client.api_get_request("")
657-
jobs = []
656+
groovy_script_output = @client.exec_script(<<'EOS')
657+
def Map findJobs(Object obj, String namespace = null) {
658+
def found = [:]
659+
660+
// groovy apparently can't #collect on a list and return a map?
661+
obj.items.each { job ->
662+
// a possibly better approach would be to walk the parent chain from //
663+
// each job
664+
def path = job.getName()
665+
if (namespace) {
666+
path = "${namespace}/" + path
667+
}
668+
found[path] = job
669+
// intentionally not using `instanceof` here so we don't blow up if the
670+
// cloudbees-folder plugin is not installed
671+
if (job.getClass().getName() == 'com.cloudbees.hudson.plugins.folder.Folder') {
672+
found << findJobs(job, path)
673+
}
674+
}
675+
676+
found
677+
}
678+
679+
void job_list_json() {
680+
def jobs = findJobs(Jenkins.getInstance())
681+
682+
def allInfo = jobs.collect { path, job ->
683+
// at least these job classes do not respond to respond to #isDisabled:
684+
// - org.jenkinsci.plugins.workflow.job.WorkflowJob
685+
// - com.cloudbees.hudson.plugins.folder.Folder
686+
def enabled = false
687+
if (job.metaClass.respondsTo(job, 'isDisabled')) {
688+
enabled = !job.isDisabled()
689+
}
690+
691+
[
692+
_class: job.getClass().getCanonicalName().toString(),
693+
name: path,
694+
url: Hudson.getInstance().getRootUrl().toString() + job.getUrl().toString(),
695+
]
696+
}
697+
698+
def builder = new groovy.json.JsonBuilder(allInfo)
699+
out.println(builder.toString())
700+
}
701+
702+
job_list_json()
703+
EOS
704+
705+
response_json = groovy_script_output
706+
707+
jobs = Array.new
658708
response_json["jobs"].each do |job|
659-
if ignorecase
660-
jobs << job["name"] if job["name"] =~ /#{filter}/i
661-
else
662-
jobs << job["name"] if job["name"] =~ /#{filter}/
709+
if job.is_a?(Hash)
710+
if job.key? :_class and job[:_class] !~ /com.cloudbees.hudson.plugins.folder.Folder/
711+
if ignorecase
712+
jobs << job[:name] if job[:name] =~ /#{filter}/i
713+
else
714+
jobs << job[:name] if job[:name] =~ /#{filter}/
715+
end
716+
end
663717
end
664718
end
665-
jobs
719+
jobs.to_a
666720
end
667721

668722
# List all jobs on the Jenkins CI server along with their details

spec/unit_tests/job_spec.rb

+67-8
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,54 @@
2828
end
2929

3030
describe "InstanceMethods" do
31+
script_text = <<'EOS'
32+
def Map findJobs(Object obj, String namespace = null) {
33+
def found = [:]
34+
35+
// groovy apparently can't #collect on a list and return a map?
36+
obj.items.each { job ->
37+
// a possibly better approach would be to walk the parent chain from //
38+
// each job
39+
def path = job.getName()
40+
if (namespace) {
41+
path = "${namespace}/" + path
42+
}
43+
found[path] = job
44+
// intentionally not using `instanceof` here so we don't blow up if the
45+
// cloudbees-folder plugin is not installed
46+
if (job.getClass().getName() == 'com.cloudbees.hudson.plugins.folder.Folder') {
47+
found << findJobs(job, path)
48+
}
49+
}
50+
51+
found
52+
}
53+
54+
void job_list_json() {
55+
def jobs = findJobs(Jenkins.getInstance())
56+
57+
def allInfo = jobs.collect { path, job ->
58+
// at least these job classes do not respond to respond to #isDisabled:
59+
// - org.jenkinsci.plugins.workflow.job.WorkflowJob
60+
// - com.cloudbees.hudson.plugins.folder.Folder
61+
def enabled = false
62+
if (job.metaClass.respondsTo(job, 'isDisabled')) {
63+
enabled = !job.isDisabled()
64+
}
65+
66+
[
67+
_class: job.getClass().getCanonicalName().toString(),
68+
name: path,
69+
url: Hudson.getInstance().getRootUrl().toString() + job.getUrl().toString(),
70+
]
71+
}
72+
73+
def builder = new groovy.json.JsonBuilder(allInfo)
74+
out.println(builder.toString())
75+
}
76+
77+
job_list_json()
78+
EOS
3179

3280
describe "#create_job" do
3381
it "accepts job_name and xml and creates the job" do
@@ -45,7 +93,7 @@
4593

4694
mock_job_list_response = { "jobs" => [] } # job response w/ 0 jobs
4795

48-
@client.should_receive(:api_get_request).with('').and_return(mock_job_list_response)
96+
@client.should_receive(:api_post_request).with('/scriptText', {'script' => script_text}, true).and_return(FakeResponse.new(200,mock_job_list_response))
4997
@job.should_receive(:create).with(job_name, xml).and_return(nil)
5098

5199
@job.create_or_update(job_name, xml)
@@ -55,9 +103,9 @@
55103
job_name = 'test_job'
56104
xml = '<name>somename</name>'
57105

58-
mock_job_list_response = { "jobs" => [ { "name" => job_name } ] } # job response w/ 1 job
106+
mock_job_list_response = { "jobs" => [ { "_class": "hudson.model.FreeStyleProject", "name": job_name,"url": "https://jenkins.example.com/job/#{job_name}/"} ] }
59107

60-
@client.should_receive(:api_get_request).with('').and_return(mock_job_list_response)
108+
@client.should_receive(:api_post_request).with('/scriptText', {'script' => script_text}, true).and_return(FakeResponse.new(200,mock_job_list_response))
61109
@job.should_receive(:update).with(job_name, xml).and_return(nil)
62110

63111
@job.create_or_update(job_name, xml)
@@ -275,9 +323,18 @@
275323

276324
describe "#exists?" do
277325
it "accepts a job name and returns true if the job exists" do
278-
@client.should_receive(:api_get_request).and_return(
279-
@sample_json_response)
280-
@job.exists?("test_job").should == true
326+
job_name = 'test_job'
327+
mock_job_list_response = { "jobs" => [ { "_class": "hudson.model.FreeStyleProject", "name": job_name,"url": "https://jenkins.example.com/job/#{job_name}/"} ] }
328+
@client.should_receive(:api_post_request).with('/scriptText', {'script' => script_text}, true).and_return(FakeResponse.new(200,mock_job_list_response))
329+
@job.exists?(job_name).should == true
330+
end
331+
332+
it "does not match folder names" do
333+
job_name = 'test_job'
334+
mock_job_list_response = { "jobs" => [ { "_class": "com.cloudbees.hudson.plugins.folder.Folder", "name": job_name,"url": "https://jenkins.example.com/job/#{job_name}/"} ] }
335+
@client.should_receive(:api_post_request).with('/scriptText', {'script' => script_text}, true).and_return(FakeResponse.new(200,mock_job_list_response))
336+
337+
@job.exists?(job_name).should == false
281338
end
282339
end
283340

@@ -296,8 +353,10 @@
296353

297354
describe "#list" do
298355
it "accepts a filter and returns all jobs matching the filter" do
299-
@client.should_receive(:api_get_request).and_return(
300-
"jobs" => ["test_job"])
356+
job_name = 'test_job'
357+
mock_job_list_response = { "jobs" => [ { "_class": "com.cloudbees.hudson.plugins.folder.Folder", "name": job_name,"url": "https://jenkins.example.com/job/#{job_name}/"} ] }
358+
@client.should_receive(:api_post_request).with('/scriptText', {'script' => script_text}, true).and_return(FakeResponse.new(200,mock_job_list_response))
359+
301360
@job.list("filter").class.should == Array
302361
end
303362
end

0 commit comments

Comments
 (0)