jenkins_api_client 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,11 @@
1
1
  = CHANGELOG
2
2
 
3
+ ===== v0.5.0 [22-DEC-2012]
4
+ * Added functionality to create jobs with params.
5
+ * Added View class and added methods accessing List Views of Jenkins server.
6
+ * Added functionality to abort a running job.
7
+ * Deprecated list_running of Job class. list_by_status('running') is suggested.
8
+
3
9
  ===== v0.4.0 [07-DEC-2012]
4
10
  * Added some methods for handling jobs.
5
11
  * The status 'not run' is not returned as 'not_run' from job status.
data/README.md CHANGED
@@ -5,6 +5,8 @@ Copyright © 2012, Kannan Manickam [![endorse](http://api.coderwall.com/aran
5
5
 
6
6
  Client libraries for communicating with a Jenkins CI server and programatically managing jobs.
7
7
 
8
+ IRC Channel: ##jenkins-api-client
9
+
8
10
  OVERVIEW:
9
11
  ---------
10
12
  This project is a simple API client for interacting with Jenkins Continuous Integration server.
@@ -87,6 +87,12 @@ module JenkinsApi
87
87
  JenkinsApi::Client::Node.new(self)
88
88
  end
89
89
 
90
+ # Creates an instance to the View class by passing a reference to self
91
+ #
92
+ def view
93
+ JenkinsApi::Client::View.new(self)
94
+ end
95
+
90
96
  # Returns a string representing the class name
91
97
  #
92
98
  def to_s
@@ -136,6 +142,7 @@ module JenkinsApi
136
142
  request = Net::HTTP::Post.new("#{url_prefix}")
137
143
  puts "[INFO] PUT #{url_prefix}" if @debug
138
144
  request.basic_auth @username, @password
145
+ request.content_type = 'application/json'
139
146
  response = http.request(request)
140
147
  case response.code.to_i
141
148
  when 200, 302
@@ -45,6 +45,142 @@ module JenkinsApi
45
45
  @client.post_config("/createItem?name=#{job_name}", xml)
46
46
  end
47
47
 
48
+ # Create a job with params given as a hash instead of the xml
49
+ # This gives some flexibility for creating simple jobs so the user doesn't have to
50
+ # learn about handling xml.
51
+ #
52
+ # @param [Hash] params
53
+ # * +:name+ name of the job
54
+ # * +:keep_dependencies+ true or false
55
+ # * +:block_build_when_downstream_building+ true or false
56
+ # * +:block_build_when_upstream_building+ true or false
57
+ # * +:concurrent_build+ true or false
58
+ # * +:scm_provider+ type of source control system. Supported: git, subversion
59
+ # * +:scm_url+ remote url for scm
60
+ # * +:scm_branch+ branch to use in scm. Uses master by default
61
+ # * +:shell_command+ command to execute in the shell
62
+ # * +:child_projects+ projects to add as downstream projects
63
+ # * +:child_threshold+ threshold for child projects. success, failure, or unstable. Default: failure.
64
+ #
65
+ def create_freestyle(params)
66
+ # TODO: Add support for all SCM providers supported by Jenkins
67
+ supported_scm_providers = ['git', 'subversion']
68
+
69
+ # Set default values for params that are not specified and Error handling.
70
+ raise 'Job name must be specified' unless params[:name]
71
+ params[:keep_dependencies] = false if params[:keep_dependencies].nil?
72
+ params[:block_build_when_downstream_building] = false if params[:block_build_when_downstream_building].nil?
73
+ params[:block_build_when_upstream_building] = false if params[:block_build_when_upstream_building].nil?
74
+ params[:concurrent_build] = false if params[:concurrent_build].nil?
75
+
76
+ # SCM configurations and Error handling. Presently only Git plugin is supported.
77
+ unless supported_scm_providers.include?(params[:scm_provider]) || params[:scm_provider].nil?
78
+ raise "SCM #{params[:scm_provider]} is currently not supported"
79
+ end
80
+ raise 'SCM URL must be specified' if params[:scm_url].nil? && !params[:scm_provider].nil?
81
+ params[:scm_branch] = "master" if params[:scm_branch].nil? && !params[:scm_provider].nil?
82
+
83
+ # Child projects configuration and Error handling
84
+ params[:child_threshold] = 'failure' if params[:child_threshold].nil? && !params[:child_projects].nil?
85
+
86
+ # Build the Job xml file based on the parameters given
87
+ builder = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') { |xml|
88
+ xml.project {
89
+ xml.actions
90
+ xml.description
91
+ xml.keepDependencies "#{params[:keep_dependencies]}"
92
+ xml.properties
93
+ # SCM related stuff
94
+ if params[:scm_provider] == 'subversion'
95
+ xml.scm(:class => "hudson.scm.SubversionSCM", :plugin => "subversion@1.39") {
96
+ xml.locations {
97
+ xml.send("hudson.scm.SubversionSCM_-ModuleLocation") {
98
+ xml.remote "#{params[:scm_url]}"
99
+ xml.local "."
100
+ }
101
+ }
102
+ xml.excludedRegions
103
+ xml.includedRegions
104
+ xml.excludedUsers
105
+ xml.excludedRevprop
106
+ xml.excludedCommitMessages
107
+ xml.workspaceUpdater(:class => "hudson.scm.subversion.UpdateUpdater")
108
+ }
109
+ elsif params[:scm_provider] == 'git'
110
+ xml.scm(:class => "hudson.plugins.git.GitSCM") {
111
+ xml.configVersion "2"
112
+ xml.userRemoteConfigs {
113
+ xml.send("hudson.plugins.git.UserRemoteConfig") {
114
+ xml.name
115
+ xml.refspec
116
+ xml.url "#{params[:scm_url]}"
117
+ }
118
+ }
119
+ xml.branches {
120
+ xml.send("hudson.plugins.git.BranchSpec") {
121
+ xml.name "#{params[:scm_branch]}"
122
+ }
123
+ }
124
+ xml.disableSubmodules "false"
125
+ xml.recursiveSubmodules "false"
126
+ xml.doGenerateSubmoduleConfigurations "false"
127
+ xml.authorOrCommitter "false"
128
+ xml.clean "false"
129
+ xml.wipeOutWorkspace "false"
130
+ xml.pruneBranches "false"
131
+ xml.remotePoll "false"
132
+ xml.ignoreNotifyCommit "false"
133
+ xml.useShallowClone "false"
134
+ xml.buildChooser(:class => "hudson.plugins.git.util.DefaultBuildChooser")
135
+ xml.gitTool "Default"
136
+ xml.submoduleCfg(:class => "list")
137
+ xml.relativeTargetDir
138
+ xml.reference
139
+ xml.excludedRegions
140
+ xml.excludedUsers
141
+ xml.gitConfigName
142
+ xml.gitConfigEmail
143
+ xml.skipTag "false"
144
+ xml.includedRegions
145
+ xml.scmName
146
+ }
147
+ else
148
+ xml.scm(:class => "hudson.scm.NullSCM")
149
+ end
150
+ xml.canRoam "true"
151
+ xml.disabled "false"
152
+ xml.blockBuildWhenDownstreamBuilding "#{params[:block_build_when_downstream_building]}"
153
+ xml.blockBuildWhenUpstreamBuilding "#{params[:block_build_when_upstream_building]}"
154
+ xml.triggers.vector
155
+ xml.concurrentBuild "#{params[:concurrent_build]}"
156
+ # Shell command stuff
157
+ xml.builders {
158
+ if params[:shell_command]
159
+ xml.send("hudson.tasks.Shell") {
160
+ xml.command "#{params[:shell_command]}"
161
+ }
162
+ end
163
+ }
164
+ # Adding Downstream projects
165
+ xml.publishers {
166
+ if params[:child_projects]
167
+ xml.send("hudson.tasks.BuildTrigger") {
168
+ xml.childProjects"#{params[:child_projects]}"
169
+ name, ordinal, color = get_threshold_params(params[:child_threshold])
170
+ xml.threshold {
171
+ xml.name "#{name}"
172
+ xml.ordinal "#{ordinal}"
173
+ xml.color "#{color}"
174
+ }
175
+ }
176
+ end
177
+ }
178
+ xml.buildWrappers
179
+ }
180
+ }
181
+ create(params[:name], builder.to_xml)
182
+ end
183
+
48
184
  # Delete a job given the name
49
185
  #
50
186
  # @param [String] job_name
@@ -84,9 +220,7 @@ module JenkinsApi
84
220
  def list_all
85
221
  response_json = @client.api_get_request("")
86
222
  jobs = []
87
- response_json["jobs"].each { |job|
88
- jobs << job["name"]
89
- }
223
+ response_json["jobs"].each { |job| jobs << job["name"] }
90
224
  jobs.sort!
91
225
  end
92
226
 
@@ -95,7 +229,7 @@ module JenkinsApi
95
229
  # @param [String] job_name
96
230
  #
97
231
  def exists?(job_name)
98
- list(job_name).include?(job_name) ? true : false
232
+ list(job_name).include?(job_name)
99
233
  end
100
234
 
101
235
  # List all Jobs matching the given status
@@ -108,9 +242,9 @@ module JenkinsApi
108
242
  jobs = list_all if jobs.empty?
109
243
  xml_response = @client.api_get_request("", "tree=jobs[name,color]")
110
244
  filtered_jobs = []
111
- xml_response["jobs"].each { |job|
245
+ xml_response["jobs"].each do |job|
112
246
  filtered_jobs << job["name"] if color_to_status(job["color"]) == status && jobs.include?(job["name"])
113
- }
247
+ end
114
248
  filtered_jobs
115
249
  end
116
250
 
@@ -122,13 +256,13 @@ module JenkinsApi
122
256
  def list(filter, ignorecase = true)
123
257
  response_json = @client.api_get_request("")
124
258
  jobs = []
125
- response_json["jobs"].each { |job|
259
+ response_json["jobs"].each do |job|
126
260
  if ignorecase
127
261
  jobs << job["name"] if job["name"] =~ /#{filter}/i
128
262
  else
129
263
  jobs << job["name"] if job["name"] =~ /#{filter}/
130
264
  end
131
- }
265
+ end
132
266
  jobs
133
267
  end
134
268
 
@@ -219,8 +353,10 @@ module JenkinsApi
219
353
  end
220
354
 
221
355
  # This functions lists all jobs that are currently running on the Jenkins CI server
356
+ # This method is deprecated. Please use list_by_status instead.
222
357
  #
223
358
  def list_running
359
+ puts "[WARN] list_running is deprecated. Please use list_by_status('running') instead."
224
360
  xml_response = @client.api_get_request("", "tree=jobs[name,color]")
225
361
  running_jobs = []
226
362
  xml_response["jobs"].each { |job|
@@ -268,15 +404,163 @@ module JenkinsApi
268
404
  post_config(job_name, xml_modified)
269
405
  end
270
406
 
271
- # Add downstream projects to a specific job given the job name, projects to be
272
- # added as downstream projects, and the threshold
407
+ # Block the build of the job when downstream is building
273
408
  #
274
409
  # @param [String] job_name
275
- # @param [String] downstream_projects
276
- # @param [String] threshold - failure, success, or unstable
277
- # @param [Bool] overwrite - true or false
278
410
  #
279
- def add_downstream_projects(job_name, downstream_projects, threshold, overwrite = false)
411
+ def block_build_when_downstream_building(job_name)
412
+ xml = get_config(job_name)
413
+ n_xml = Nokogiri::XML(xml)
414
+ node = n_xml.xpath("//blockBuildWhenDownstreamBuilding").first
415
+ if node.content == "false"
416
+ node.content = "true"
417
+ xml_modified = n_xml.to_xml
418
+ post_config(job_name, xml_modified)
419
+ end
420
+ end
421
+
422
+ # Unblock the build of the job when downstream is building
423
+ #
424
+ # @param [String] job_name
425
+ #
426
+ def unblock_build_when_downstream_building(job_name)
427
+ xml = get_config(job_name)
428
+ n_xml = Nokogiri::XML(xml)
429
+ node = n_xml.xpath("//blockBuildWhenDownstreamBuilding").first
430
+ if node.content == "true"
431
+ node.content = "false"
432
+ xml_modified = n_xml.to_xml
433
+ post_config(job_name, xml_modified)
434
+ end
435
+ end
436
+
437
+ # Block the build of the job when upstream is building
438
+ #
439
+ # @param [String] job_name
440
+ #
441
+ def block_build_when_upstream_building(job_name)
442
+ xml = get_config(job_name)
443
+ n_xml = Nokogiri::XML(xml)
444
+ node = n_xml.xpath("//blockBuildWhenUpstreamBuilding").first
445
+ if node.content == "false"
446
+ node.content = "true"
447
+ xml_modified = n_xml.to_xml
448
+ post_config(job_name, xml_modified)
449
+ end
450
+ end
451
+
452
+ # Unblock the build of the job when upstream is building
453
+ #
454
+ # @param [String] job_name
455
+ #
456
+ def unblock_build_when_upstream_building(job_name)
457
+ xml = get_config(job_name)
458
+ n_xml = Nokogiri::XML(xml)
459
+ node = n_xml.xpath("//blockBuildWhenUpstreamBuilding").first
460
+ if node.content == "true"
461
+ node.content = "false"
462
+ xml_modified = n_xml.to_xml
463
+ post_config(job_name, xml_modified)
464
+ end
465
+ end
466
+
467
+ # Allow to either execute concurrent builds or disable concurrent execution
468
+ #
469
+ # @param [String] job_name
470
+ # @param [Bool] option true or false
471
+ #
472
+ def execute_concurrent_builds(job_name, option)
473
+ xml = get_config(job_name)
474
+ n_xml = Nokogiri::XML(xml)
475
+ node = n_xml.xpath("//concurrentBuild").first
476
+ if node.content != "#{option}"
477
+ node.content = option == true ? "true" : "false"
478
+ xml_modified = n_xml.to_xml
479
+ post_config(job_name, xml_modified)
480
+ end
481
+ end
482
+
483
+ # Obtain the build parameters of a job. It returns an array of hashes with
484
+ # details of job params.
485
+ #
486
+ # @param [String] job_name
487
+ #
488
+ # @return [Array] params_array
489
+ #
490
+ def get_build_params(job_name)
491
+ xml = get_config(job_name)
492
+ n_xml = Nokogiri::XML(xml)
493
+ params = n_xml.xpath("//parameterDefinitions").first
494
+ params_array = []
495
+ if params
496
+ params.children.each do |param|
497
+ param_hash = {}
498
+ case param.name
499
+ when "hudson.model.StringParameterDefinition", "hudson.model.BooleanParameterDefinition", "hudson.model.TextParameterDefinition", "hudson.model.PasswordParameterDefinition"
500
+ param_hash[:type] = 'string' if param.name =~ /string/i
501
+ param_hash[:type] = 'boolean' if param.name =~ /boolean/i
502
+ param_hash[:type] = 'text' if param.name =~ /text/i
503
+ param_hash[:type] = 'password' if param.name =~ /password/i
504
+ param.children.each do |value|
505
+ param_hash[:name] = value.content if value.name == "name"
506
+ param_hash[:description] = value.content if value.name == "description"
507
+ param_hash[:default] = value.content if value.name == "defaultValue"
508
+ end
509
+ when "hudson.model.RunParameterDefinition"
510
+ param_hash[:type] = 'run'
511
+ param.children.each do |value|
512
+ param_hash[:name] = value.content if value.name == "name"
513
+ param_hash[:description] = value.content if value.name == "description"
514
+ param_hash[:project] = value.content if value.name == "projectName"
515
+ end
516
+ when "hudson.model.FileParameterDefinition"
517
+ param_hash[:type] = 'file'
518
+ param.children.each do |value|
519
+ param_hash[:name] = value.content if value.name == "name"
520
+ param_hash[:description] = value.content if value.name == "description"
521
+ end
522
+ when "hudson.scm.listtagsparameter.ListSubversionTagsParameterDefinition"
523
+ param_hash[:type] = 'list_tags'
524
+ param.children.each do |value|
525
+ param_hash[:name] = value.content if value.name == "name"
526
+ param_hash[:description] = value.content if value.name == "description"
527
+ param_hash[:tags_dir] = value.content if value.name == "tagsDir"
528
+ param_hash[:tags_filter] = value.content if value.name == "tagsFilter"
529
+ param_hash[:reverse_by_date] = value.content if value.name == "reverseByDate"
530
+ param_hash[:reverse_by_name] = value.content if value.name == "reverseByName"
531
+ param_hash[:default] = value.content if value.name == "defaultValue"
532
+ param_hash[:max_tags] = value.content if value.name == "maxTags"
533
+ param_hash[:uuid] = value.content if value.name == "uuid"
534
+ end
535
+ when "hudson.model.ChoiceParameterDefinition"
536
+ param_hash[:type] = 'choice'
537
+ param.children.each do |value|
538
+ param_hash[:name] = value.content if value.name == "name"
539
+ param_hash[:description] = value.content if value.name == "description"
540
+ choices = []
541
+ if value.name == "choices"
542
+ value.children.each do |value_child|
543
+ if value_child.name == "a"
544
+ value_child.children.each do |choice_child|
545
+ choices << choice_child.content.strip unless choice_child.content.strip.empty?
546
+ end
547
+ end
548
+ end
549
+ end
550
+ param_hash[:choices] = choices unless choices.empty?
551
+ end
552
+ end
553
+ params_array << param_hash unless param_hash.empty?
554
+ end
555
+ end
556
+ params_array
557
+ end
558
+
559
+ # Obtains the threshold params used by jenkins in the XML file given the threshold
560
+ #
561
+ # @param [String] threshold success, failure, or unstable
562
+ #
563
+ def get_threshold_params(threshold)
280
564
  case threshold
281
565
  when 'success'
282
566
  name = 'SUCCESS'
@@ -291,6 +575,19 @@ module JenkinsApi
291
575
  ordinal = 2
292
576
  color = 'RED'
293
577
  end
578
+ return name, ordinal, color
579
+ end
580
+
581
+ # Add downstream projects to a specific job given the job name, projects to be
582
+ # added as downstream projects, and the threshold
583
+ #
584
+ # @param [String] job_name
585
+ # @param [String] downstream_projects
586
+ # @param [String] threshold - failure, success, or unstable
587
+ # @param [Bool] overwrite - true or false
588
+ #
589
+ def add_downstream_projects(job_name, downstream_projects, threshold, overwrite = false)
590
+ name, ordinal, color = get_threshold_params(threshold)
294
591
  xml = get_config(job_name)
295
592
  n_xml = Nokogiri::XML(xml)
296
593
  child_projects_node = n_xml.xpath("//childProjects").first
@@ -318,24 +615,24 @@ module JenkinsApi
318
615
  def remove_downstream_projects(job_name)
319
616
  xml = get_config(job_name)
320
617
  n_xml = Nokogiri::XML(xml)
321
- n_xml.search("//hudson.tasks.BuildTrigger").each{ |node|
618
+ n_xml.search("//hudson.tasks.BuildTrigger").each do |node|
322
619
  child_project_trigger = false
323
- node.search("//childProjects").each { |child_node|
620
+ node.search("//childProjects").each do |child_node|
324
621
  child_project_trigger = true
325
- child_node.search("//threshold").each { |threshold_node|
326
- threshold_node.children.each { |threshold_value_node|
622
+ child_node.search("//threshold").each do |threshold_node|
623
+ threshold_node.children.each do |threshold_value_node|
327
624
  threshold_value_node.content = nil
328
625
  threshold_value_node.remove
329
- }
626
+ end
330
627
  threshold_node.content = nil
331
628
  threshold_node.remove
332
- }
629
+ end
333
630
  child_node.content = nil
334
631
  child_node.remove
335
- }
632
+ end
336
633
  node.content = nil
337
634
  node.remove
338
- }
635
+ end
339
636
  publisher_node = n_xml.search("//publishers").first
340
637
  publisher_node.content = nil if publisher_node.children.empty?
341
638
  xml_modified = n_xml.to_xml
@@ -388,15 +685,15 @@ module JenkinsApi
388
685
  filtered_job_names = job_names
389
686
  else
390
687
  puts "[INFO] Criteria is specified. Filtering jobs..." if @client.debug
391
- job_names.each { |job|
688
+ job_names.each do |job|
392
689
  filtered_job_names << job if criteria.include?(@client.job.get_current_build_status(job))
393
- }
690
+ end
394
691
  end
395
- filtered_job_names.each_with_index { |job_name, index|
692
+ filtered_job_names.each_with_index do |job_name, index|
396
693
  break if index >= (filtered_job_names.length - parallel)
397
694
  puts "[INFO] Adding <#{filtered_job_names[index+1]}> as a downstream project to <#{job_name}> with <#{threshold}> as the threshold" if @client.debug
398
695
  @client.job.add_downstream_projects(job_name, filtered_job_names[index + parallel], threshold, true)
399
- }
696
+ end
400
697
  parallel = filtered_job_names.length if parallel > filtered_job_names.length
401
698
  filtered_job_names[0..parallel-1]
402
699
  end
@@ -23,7 +23,7 @@
23
23
  module JenkinsApi
24
24
  class Client
25
25
  MAJOR = 0
26
- MINOR = 4
26
+ MINOR = 5
27
27
  TINY = 0
28
28
  PRE = nil
29
29
  VERSION = [MAJOR, MINOR, TINY, PRE].compact.join('.')
@@ -0,0 +1,129 @@
1
+ #
2
+ # Copyright (c) 2012 Kannan Manickam <arangamani.kannan@gmail.com>
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+
23
+ module JenkinsApi
24
+ class Client
25
+ class View
26
+
27
+ # Initializes a new view object
28
+ #
29
+ # @param [Object] client reference to Client
30
+ #
31
+ def initialize(client)
32
+ @client = client
33
+ end
34
+
35
+ # Return a string representation of the object
36
+ #
37
+ def to_s
38
+ "#<JenkinsApi::Client::View>"
39
+ end
40
+
41
+ # Create a new view
42
+ #
43
+ # @param [String] view_name
44
+ #
45
+ def create(view_name)
46
+ @client.api_post_request("/createView?name=#{view_name}&mode=hudson.model.ListView&json={\"name\":\"#{view_name}\",\"mode\":\"hudson.model.ListView\"}")
47
+ end
48
+
49
+ # Delete a view
50
+ #
51
+ # @param [String] view_name
52
+ #
53
+ def delete(view_name)
54
+ @client.api_post_request("/view/#{view_name}/doDelete")
55
+ end
56
+
57
+ # This method lists all views
58
+ #
59
+ # @param [String] filter a regex to filter view names
60
+ # @param [Bool] ignorecase whether to be case sensitive or not
61
+ #
62
+ def list(filter = nil, ignorecase = true)
63
+ view_names = []
64
+ response_json = @client.api_get_request("/")
65
+ response_json["views"].each { |view|
66
+ view_names << view["name"] if view["name"] =~ /#{filter}/i
67
+ }
68
+ view_names
69
+ end
70
+
71
+ # Checks if the given view exists in Jenkins
72
+ #
73
+ # @param [String] view_name
74
+ #
75
+ def exists?(view_name)
76
+ list(view_name).include?(view_name)
77
+ end
78
+
79
+ # List jobs in a view
80
+ #
81
+ # @param [String] view_name
82
+ #
83
+ def list_jobs(view_name)
84
+ job_names = []
85
+ response_json = @client.api_get_request("/view/#{view_name}")
86
+ response_json["jobs"].each do |job|
87
+ job_names << job["name"]
88
+ end
89
+ job_names
90
+ end
91
+
92
+ # Add a job to view
93
+ #
94
+ # @param [String] view_name
95
+ # @param [String] job_name
96
+ #
97
+ def add_job(view_name, job_name)
98
+ @client.api_post_request("/view/#{view_name}/addJobToView?name=#{job_name}")
99
+ end
100
+
101
+ # Remove a job from view
102
+ #
103
+ # @param [String] view_name
104
+ # @param [String] job_name
105
+ #
106
+ def remove_job(view_name, job_name)
107
+ @client.api_post_request("/view/#{view_name}/removeJobFromView?name=#{job_name}")
108
+ end
109
+
110
+ # Obtain the configuration stored in config.xml of a specific view
111
+ #
112
+ # @param [String] view_name
113
+ #
114
+ def get_config(view_name)
115
+ @client.get_config("/view/#{view_name}")
116
+ end
117
+
118
+ # Post the configuration of a view given the view name and the config.xml
119
+ #
120
+ # @param [String] view_name
121
+ # @param [String] xml
122
+ #
123
+ def post_config(view_name, xml)
124
+ @client.post_config("/view/#{view_name}/config.xml", xml)
125
+ end
126
+
127
+ end
128
+ end
129
+ end
@@ -117,16 +117,16 @@ describe JenkinsApi::Client::Job do
117
117
  end
118
118
  end
119
119
 
120
- it "Should be able to abort a recent build of a running job" do
121
- @client.job.get_current_build_status(@job_name).should_not == "running"
122
- @client.job.build(@job_name)
123
- sleep 20
124
- @client.job.get_current_build_status(@job_name).should == "running"
125
- sleep 20
126
- @client.job.stop_build(@job_name).should == 302
127
- sleep 20
128
- @client.job.get_current_build_status(@job_name).should == "aborted"
129
- end
120
+ # it "Should be able to abort a recent build of a running job" do
121
+ # @client.job.get_current_build_status(@job_name).should_not == "running"
122
+ # @client.job.build(@job_name)
123
+ # sleep 20
124
+ # @client.job.get_current_build_status(@job_name).should == "running"
125
+ # sleep 20
126
+ # @client.job.stop_build(@job_name).should == 302
127
+ # sleep 20
128
+ # @client.job.get_current_build_status(@job_name).should == "aborted"
129
+ # end
130
130
 
131
131
  it "Should be able to restrict a job to a node" do
132
132
  @client.job.restrict_to_node(@job_name, 'master').to_i.should == 200
metadata CHANGED
@@ -1,186 +1,189 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: jenkins_api_client
3
- version: !ruby/object:Gem::Version
4
- hash: 15
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 4
9
- - 0
10
- version: 0.4.0
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Kannan Manickam
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2012-12-08 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
21
- prerelease: false
22
- type: :runtime
23
- requirement: &id001 !ruby/object:Gem::Requirement
24
- none: false
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- hash: 3
29
- segments:
30
- - 0
31
- version: "0"
32
- version_requirements: *id001
12
+ date: 2012-12-22 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
33
15
  name: nokogiri
34
- - !ruby/object:Gem::Dependency
35
- prerelease: false
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
36
22
  type: :runtime
37
- requirement: &id002 !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: activesupport
32
+ requirement: !ruby/object:Gem::Requirement
38
33
  none: false
39
- requirements:
34
+ requirements:
40
35
  - - ~>
41
- - !ruby/object:Gem::Version
42
- hash: 31
43
- segments:
44
- - 3
45
- - 2
46
- - 8
36
+ - !ruby/object:Gem::Version
47
37
  version: 3.2.8
48
- version_requirements: *id002
49
- name: activesupport
50
- - !ruby/object:Gem::Dependency
51
- prerelease: false
52
38
  type: :runtime
53
- requirement: &id003 !ruby/object:Gem::Requirement
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
54
41
  none: false
55
- requirements:
42
+ requirements:
56
43
  - - ~>
57
- - !ruby/object:Gem::Version
58
- hash: 95
59
- segments:
60
- - 0
61
- - 16
62
- - 0
63
- version: 0.16.0
64
- version_requirements: *id003
44
+ - !ruby/object:Gem::Version
45
+ version: 3.2.8
46
+ - !ruby/object:Gem::Dependency
65
47
  name: thor
66
- - !ruby/object:Gem::Dependency
67
- prerelease: false
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 0.16.0
68
54
  type: :runtime
69
- requirement: &id004 !ruby/object:Gem::Requirement
70
- none: false
71
- requirements:
72
- - - ">="
73
- - !ruby/object:Gem::Version
74
- hash: 3
75
- segments:
76
- - 0
77
- version: "0"
78
- version_requirements: *id004
79
- name: json
80
- - !ruby/object:Gem::Dependency
81
55
  prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.16.0
62
+ - !ruby/object:Gem::Dependency
63
+ name: json
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
82
70
  type: :runtime
83
- requirement: &id005 !ruby/object:Gem::Requirement
84
- none: false
85
- requirements:
86
- - - ">="
87
- - !ruby/object:Gem::Version
88
- hash: 7
89
- segments:
90
- - 1
91
- - 4
92
- - 0
93
- version: 1.4.0
94
- version_requirements: *id005
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
95
79
  name: terminal-table
96
- - !ruby/object:Gem::Dependency
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: 1.4.0
86
+ type: :runtime
97
87
  prerelease: false
98
- type: :development
99
- requirement: &id006 !ruby/object:Gem::Requirement
100
- none: false
101
- requirements:
102
- - - ">="
103
- - !ruby/object:Gem::Version
104
- hash: 15
105
- segments:
106
- - 1
107
- - 0
108
- version: "1.0"
109
- version_requirements: *id006
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: 1.4.0
94
+ - !ruby/object:Gem::Dependency
110
95
  name: bundler
111
- - !ruby/object:Gem::Dependency
112
- prerelease: false
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '1.0'
113
102
  type: :development
114
- requirement: &id007 !ruby/object:Gem::Requirement
115
- none: false
116
- requirements:
117
- - - ">="
118
- - !ruby/object:Gem::Version
119
- hash: 7
120
- segments:
121
- - 1
122
- - 6
123
- - 4
124
- version: 1.6.4
125
- version_requirements: *id007
126
- name: jeweler
127
- - !ruby/object:Gem::Dependency
128
103
  prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '1.0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: jeweler
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: 1.6.4
129
118
  type: :development
130
- requirement: &id008 !ruby/object:Gem::Requirement
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
131
121
  none: false
132
- requirements:
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: 1.6.4
126
+ - !ruby/object:Gem::Dependency
127
+ name: builder
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
133
131
  - - ~>
134
- - !ruby/object:Gem::Version
135
- hash: 5
136
- segments:
137
- - 3
138
- - 1
139
- - 3
132
+ - !ruby/object:Gem::Version
140
133
  version: 3.1.3
141
- version_requirements: *id008
142
- name: builder
143
- - !ruby/object:Gem::Dependency
144
- prerelease: false
145
134
  type: :development
146
- requirement: &id009 !ruby/object:Gem::Requirement
147
- none: false
148
- requirements:
149
- - - ">="
150
- - !ruby/object:Gem::Version
151
- hash: 3
152
- segments:
153
- - 0
154
- version: "0"
155
- version_requirements: *id009
156
- name: simplecov
157
- - !ruby/object:Gem::Dependency
158
135
  prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ~>
140
+ - !ruby/object:Gem::Version
141
+ version: 3.1.3
142
+ - !ruby/object:Gem::Dependency
143
+ name: simplecov
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
159
150
  type: :development
160
- requirement: &id010 !ruby/object:Gem::Requirement
161
- none: false
162
- requirements:
163
- - - ">="
164
- - !ruby/object:Gem::Version
165
- hash: 3
166
- segments:
167
- - 0
168
- version: "0"
169
- version_requirements: *id010
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ - !ruby/object:Gem::Dependency
170
159
  name: rspec
171
- description: |-
172
-
160
+ requirement: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ! '>='
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ! '>='
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ description: ! '
175
+
173
176
  This is a simple and easy-to-use Jenkins Api client with features focused on
174
- automating Job configuration programaticaly and so forth
175
- email:
177
+
178
+ automating Job configuration programaticaly and so forth'
179
+ email:
176
180
  - arangamani.kannan@gmail.com
177
- executables:
181
+ executables:
178
182
  - jenkinscli
179
183
  extensions: []
180
-
181
- extra_rdoc_files:
184
+ extra_rdoc_files:
182
185
  - CHANGELOG.rdoc
183
- files:
186
+ files:
184
187
  - .gitignore
185
188
  - .travis.yml
186
189
  - CHANGELOG.rdoc
@@ -202,6 +205,7 @@ files:
202
205
  - lib/jenkins_api_client/node.rb
203
206
  - lib/jenkins_api_client/system.rb
204
207
  - lib/jenkins_api_client/version.rb
208
+ - lib/jenkins_api_client/view.rb
205
209
  - scripts/login_with_irb.rb
206
210
  - spec/client_spec.rb
207
211
  - spec/job_spec.rb
@@ -210,36 +214,26 @@ files:
210
214
  - spec/system_spec.rb
211
215
  homepage: https://github.com/arangamani/jenkins_api_client
212
216
  licenses: []
213
-
214
217
  post_install_message:
215
218
  rdoc_options: []
216
-
217
- require_paths:
219
+ require_paths:
218
220
  - lib
219
- required_ruby_version: !ruby/object:Gem::Requirement
221
+ required_ruby_version: !ruby/object:Gem::Requirement
220
222
  none: false
221
- requirements:
222
- - - ">="
223
- - !ruby/object:Gem::Version
224
- hash: 3
225
- segments:
226
- - 0
227
- version: "0"
228
- required_rubygems_version: !ruby/object:Gem::Requirement
223
+ requirements:
224
+ - - ! '>='
225
+ - !ruby/object:Gem::Version
226
+ version: '0'
227
+ required_rubygems_version: !ruby/object:Gem::Requirement
229
228
  none: false
230
- requirements:
231
- - - ">="
232
- - !ruby/object:Gem::Version
233
- hash: 3
234
- segments:
235
- - 0
236
- version: "0"
229
+ requirements:
230
+ - - ! '>='
231
+ - !ruby/object:Gem::Version
232
+ version: '0'
237
233
  requirements: []
238
-
239
234
  rubyforge_project:
240
235
  rubygems_version: 1.8.24
241
236
  signing_key:
242
237
  specification_version: 3
243
238
  summary: Jenkins JSON API Client
244
239
  test_files: []
245
-