Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

list matching jobs using dsl #225

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
70 changes: 62 additions & 8 deletions lib/jenkins_api_client/job.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#

# Copyright (c) 2012-2013 Kannan Manickam <[email protected]>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
Expand Down Expand Up @@ -653,16 +653,70 @@ def list_by_status(status, jobs = [])
#
def list(filter, ignorecase = true)
@logger.info "Obtaining jobs matching filter '#{filter}'"
response_json = @client.api_get_request("")
jobs = []
groovy_script_output = @client.exec_script(<<'EOS')
def Map findJobs(Object obj, String namespace = null) {
def found = [:]

// groovy apparently can't #collect on a list and return a map?
obj.items.each { job ->
// a possibly better approach would be to walk the parent chain from //
// each job
def path = job.getName()
if (namespace) {
path = "${namespace}/" + path
}
found[path] = job
// intentionally not using `instanceof` here so we don't blow up if the
// cloudbees-folder plugin is not installed
if (job.getClass().getName() == 'com.cloudbees.hudson.plugins.folder.Folder') {
found << findJobs(job, path)
}
}

found
}

void job_list_json() {
def jobs = findJobs(Jenkins.getInstance())

def allInfo = jobs.collect { path, job ->
// at least these job classes do not respond to respond to #isDisabled:
// - org.jenkinsci.plugins.workflow.job.WorkflowJob
// - com.cloudbees.hudson.plugins.folder.Folder
def enabled = false
if (job.metaClass.respondsTo(job, 'isDisabled')) {
enabled = !job.isDisabled()
}

[
_class: job.getClass().getCanonicalName().toString(),
name: path,
url: Hudson.getInstance().getRootUrl().toString() + job.getUrl().toString(),
]
}

def builder = new groovy.json.JsonBuilder(allInfo)
out.println(builder.toString())
}

job_list_json()
EOS

response_json = groovy_script_output
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This now returns a String instead of a Hash because JSON.parse was removed


jobs = Array.new
response_json["jobs"].each do |job|
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Above the jobs hash key was removed so this no longer works.

if ignorecase
jobs << job["name"] if job["name"] =~ /#{filter}/i
else
jobs << job["name"] if job["name"] =~ /#{filter}/
if job.is_a?(Hash)
if job.key? :_class and job[:_class] !~ /com.cloudbees.hudson.plugins.folder.Folder/
if ignorecase
jobs << job[:name] if job[:name] =~ /#{filter}/i
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is using symbols instead of strings now. When I used JSON.parse it returned strings so this did not work for me.

else
jobs << job[:name] if job[:name] =~ /#{filter}/
end
end
end
end
jobs
jobs.to_a
end

# List all jobs on the Jenkins CI server along with their details
Expand Down
67 changes: 59 additions & 8 deletions spec/unit_tests/job_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,54 @@
end

describe "InstanceMethods" do
script_text = <<'EOS'
def Map findJobs(Object obj, String namespace = null) {
def found = [:]

// groovy apparently can't #collect on a list and return a map?
obj.items.each { job ->
// a possibly better approach would be to walk the parent chain from //
// each job
def path = job.getName()
if (namespace) {
path = "${namespace}/" + path
}
found[path] = job
// intentionally not using `instanceof` here so we don't blow up if the
// cloudbees-folder plugin is not installed
if (job.getClass().getName() == 'com.cloudbees.hudson.plugins.folder.Folder') {
found << findJobs(job, path)
}
}

found
}

void job_list_json() {
def jobs = findJobs(Jenkins.getInstance())

def allInfo = jobs.collect { path, job ->
// at least these job classes do not respond to respond to #isDisabled:
// - org.jenkinsci.plugins.workflow.job.WorkflowJob
// - com.cloudbees.hudson.plugins.folder.Folder
def enabled = false
if (job.metaClass.respondsTo(job, 'isDisabled')) {
enabled = !job.isDisabled()
}

[
_class: job.getClass().getCanonicalName().toString(),
name: path,
url: Hudson.getInstance().getRootUrl().toString() + job.getUrl().toString(),
]
}

def builder = new groovy.json.JsonBuilder(allInfo)
out.println(builder.toString())
}

job_list_json()
EOS

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

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

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

@job.create_or_update(job_name, xml)
Expand All @@ -55,9 +103,9 @@
job_name = 'test_job'
xml = '<name>somename</name>'

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

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

@job.create_or_update(job_name, xml)
Expand Down Expand Up @@ -275,9 +323,10 @@

describe "#exists?" do
it "accepts a job name and returns true if the job exists" do
@client.should_receive(:api_get_request).and_return(
@sample_json_response)
@job.exists?("test_job").should == true
job_name = 'test_job'
mock_job_list_response = { "jobs" => [ { "_class": "hudson.model.FreeStyleProject", "name": job_name,"url": "https://jenkins.example.com/job/#{job_name}/"} ] }
@client.should_receive(:api_post_request).with('/scriptText', {'script' => script_text}, true).and_return(FakeResponse.new(200,mock_job_list_response))
@job.exists?(job_name).should == true
end
end

Expand All @@ -296,8 +345,10 @@

describe "#list" do
it "accepts a filter and returns all jobs matching the filter" do
@client.should_receive(:api_get_request).and_return(
"jobs" => ["test_job"])
job_name = 'test_job'
mock_job_list_response = { "jobs" => [ { "_class": "com.cloudbees.hudson.plugins.folder.Folder", "name": job_name,"url": "https://jenkins.example.com/job/#{job_name}/"} ] }
@client.should_receive(:api_post_request).with('/scriptText', {'script' => script_text}, true).and_return(FakeResponse.new(200,mock_job_list_response))

@job.list("filter").class.should == Array
end
end
Expand Down