jenkins_api_client 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
-