improved_jenkins_client 1.6.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.
@@ -0,0 +1,134 @@
1
+ #
2
+ # Copyright (c) 2012-2013 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
+ require 'timeout'
24
+
25
+ module JenkinsApi
26
+ class Client
27
+ # This class is used to communicate with Jenkins and performing some admin
28
+ # level operations such as restarting and reloading Jenkins.
29
+ #
30
+ class System
31
+
32
+ # Initializes a new System object.
33
+ #
34
+ # @param client [Client] the client object
35
+ #
36
+ # @return [System] the system object
37
+ #
38
+ def initialize(client)
39
+ @client = client
40
+ @logger = @client.logger
41
+ @timeout = @client.timeout
42
+ end
43
+
44
+ # Returns a string representation of System class.
45
+ #
46
+ def to_s
47
+ "#<JenkinsApi::Client::System>"
48
+ end
49
+
50
+ # Sends a quiet down request to the server.
51
+ #
52
+ def quiet_down
53
+ @logger.info "Performing a quiet down of jenkins..."
54
+ @client.api_post_request("/quietDown")
55
+ end
56
+
57
+ # Cancels the quiet down request sent to the server.
58
+ #
59
+ def cancel_quiet_down
60
+ @logger.info "Cancelling jenkins form quiet down..."
61
+ @client.api_post_request("/cancelQuietDown")
62
+ end
63
+
64
+ # Checks if server is in quiet down mode.
65
+ #
66
+ def check_quiet_down?
67
+ @logger.info "Checking if jenkins is in quiet down mode..."
68
+ @client.root.quieting_down?
69
+ end
70
+
71
+ # Restarts the Jenkins server
72
+ #
73
+ # @param [Boolean] force whether to force restart or wait till all
74
+ # jobs are completed.
75
+ #
76
+ def restart(force = false)
77
+ if force
78
+ @logger.info "Performing a force restart of jenkins..."
79
+ @client.api_post_request("/restart")
80
+ else
81
+ @logger.info "Performing a safe restart of jenkins..."
82
+ @client.api_post_request("/safeRestart")
83
+ end
84
+ end
85
+
86
+ # Performs a force restart of Jenkins server
87
+ #
88
+ def restart!
89
+ restart(true)
90
+ end
91
+
92
+ # Reload the Jenkins server
93
+ #
94
+ def reload
95
+ @logger.info "Reloading jenkins..."
96
+ @client.api_post_request("/reload")
97
+ end
98
+
99
+ # List all users known to Jenkins by their Full Name
100
+ #
101
+ def list_users
102
+ warn "DEPRECATION: System#list_users is deprecated. Please use User#list instead"
103
+ @logger.info "Obtaining the list of users from jenkins"
104
+ users = @client.api_get_request("/asynchPeople")
105
+ names = []
106
+ users['users'].each { |user|
107
+ names << user['user']['fullName']
108
+ } unless users.nil?
109
+ return names
110
+ end
111
+
112
+ # This method waits till the server becomes ready after a start
113
+ # or restart.
114
+ #
115
+ def wait_for_ready
116
+ Timeout::timeout(@timeout) do
117
+ while true do
118
+ response = @client.get_root
119
+ @logger.info "Waiting for jenkins to restart..."
120
+ if (response.body =~ /Please wait while Jenkins is restarting/ ||
121
+ response.body =~ /Please wait while Jenkins is getting ready to work/)
122
+ sleep 30
123
+ redo
124
+ else
125
+ return true
126
+ end
127
+ end
128
+ end
129
+ false
130
+ end
131
+
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,18 @@
1
+ require 'uri'
2
+ require 'addressable/uri'
3
+
4
+ module JenkinsApi
5
+ module UriHelper
6
+ # Encode a string for using in the query part of an URL
7
+ #
8
+ def form_encode(string)
9
+ URI.encode_www_form_component string.encode(Encoding::UTF_8)
10
+ end
11
+
12
+ # Encode a string for use in the hiearchical part of an URL
13
+ #
14
+ def path_encode(path)
15
+ Addressable::URI.escape(path.encode(Encoding::UTF_8))
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,131 @@
1
+ #
2
+ # Copyright (c) 2012-2013 Douglas Henderson <dougforpres@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
+ require 'timeout'
24
+ require 'improved_jenkins_client/urihelper'
25
+
26
+ module JenkinsApi
27
+ class Client
28
+ # This class is used to communicate with Jenkins and performing some user
29
+ # level operations - currently limited to fetching user info, but can
30
+ # be extended to support updating user fields
31
+ #
32
+ # @since 0.14.0
33
+ #
34
+ class User
35
+ include JenkinsApi::UriHelper
36
+
37
+ # Initializes a new User object.
38
+ #
39
+ # @param client [Client] the client object
40
+ #
41
+ # @return [User] the user object
42
+ #
43
+ def initialize(client)
44
+ @client = client
45
+ @logger = @client.logger
46
+ @timeout = @client.timeout
47
+ end
48
+
49
+ # Returns a string representation of User class.
50
+ #
51
+ def to_s
52
+ "#<JenkinsApi::Client::User>"
53
+ end
54
+
55
+ # Get a list of users
56
+ # Response will include same as is available from
57
+ # http://jenkins/user/#{username}
58
+ # userid, display name, and email-address
59
+ #
60
+ # @return [Hash] of [Hash], keyed by Jenkins user id
61
+ # * +fullName+ The jenkins user idoutput+ Console output of the job
62
+ # * +properties+ Size of the text. This ca
63
+ #
64
+ def list
65
+ @logger.info "Obtaining the list of users from jenkins"
66
+ # First we need to get the list of users.
67
+ # This is the same as "System.list_users", but since I didn't want to
68
+ # depend on that class I reproduced the request here.
69
+ userlist = @client.api_get_request("/asynchPeople")
70
+ users = {}
71
+
72
+ userlist['users'].each { |user|
73
+ # Jenkins seems ok to fetch by full-name, as long as perfect match
74
+ # since the name *came* from Jenkins this seems reasonably safe
75
+ user = get(user['user']['fullName'])
76
+ users[user['id']] = user if user
77
+ } unless userlist.nil?
78
+
79
+ return users
80
+ end
81
+
82
+ # Get a single user
83
+ #
84
+ # @param user_id [String] User ID or Full Name
85
+ #
86
+ # @return [Hash]
87
+ # * +id+ Jenkins user id
88
+ # * +fullName+ Full name of user (or user id if not set)
89
+ # * other fields populated by Jenkins - this may vary based on version/plugins
90
+ #
91
+ # @example Example JSON for user info
92
+ # {
93
+ # "absoluteUrl" : "https://myjenkins.example.com/jenkins/user/fred",
94
+ # "description" : "",
95
+ # "fullName" : "Fred Flintstone",
96
+ # "id" : "fred",
97
+ # "property" : [
98
+ # {
99
+ # },
100
+ # {
101
+ # },
102
+ # {
103
+ # "address" : "fred@slaterockandgravel.com"
104
+ # },
105
+ # {
106
+ # },
107
+ # {
108
+ # },
109
+ # {
110
+ # "insensitiveSearch" : false
111
+ # }
112
+ # ]
113
+ # }
114
+ #
115
+ def get(user_id)
116
+ @client.api_get_request("/user/#{path_encode user_id}")
117
+ end
118
+
119
+ def get_api_token(user_id)
120
+ response = @client.api_get_request("/user/#{path_encode user_id}/configure", nil, '')
121
+ html = Nokogiri::HTML(response)
122
+ attr = html.xpath('//input[@id="apiToken"]/@value').first
123
+ if attr.nil?
124
+ raise Exceptions::ApiException.new(@logger, "Failed to get api token")
125
+ end
126
+ attr.value
127
+ end
128
+
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,36 @@
1
+ #
2
+ # Copyright (c) 2012-2013 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
+ # Major version of the gem
26
+ MAJOR = 1
27
+ # Minor version of the gem
28
+ MINOR = 6
29
+ # Tiny version of the gem used for patches
30
+ TINY = 0
31
+ # Used for pre-releases
32
+ PRE = nil
33
+ # Version String of Jenkins API Client.
34
+ VERSION = [MAJOR, MINOR, TINY, PRE].compact.join('.')
35
+ end
36
+ end
@@ -0,0 +1,313 @@
1
+ #
2
+ # Copyright (c) 2012-2013 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
+ require 'improved_jenkins_client/urihelper'
24
+
25
+ module JenkinsApi
26
+ class Client
27
+ # This class communicates with Jenkins "/view" API and used to create,
28
+ # delete, update, and various other operations permitted on the Jenkins
29
+ # API.
30
+ #
31
+ class View
32
+ include JenkinsApi::UriHelper
33
+
34
+ # Initializes a new view object
35
+ #
36
+ # @param client [Client] the client object
37
+ #
38
+ # @return [View] the client object
39
+ #
40
+ def initialize(client)
41
+ @client = client
42
+ @logger = @client.logger
43
+ end
44
+
45
+ # Return a string representation of the object
46
+ #
47
+ def to_s
48
+ "#<JenkinsApi::Client::View>"
49
+ end
50
+
51
+ # Creates a new empty view of the given type
52
+ #
53
+ # @param [String] view_name Name of the view to be created
54
+ # @param [String] type Type of view to be created. Valid options:
55
+ # listview, myview. Default: listview
56
+ #
57
+ def create(view_name, type = "listview")
58
+ @logger.info "Creating a view '#{view_name}' of type '#{type}'"
59
+ mode = case type
60
+ when "listview"
61
+ "hudson.model.ListView"
62
+ when "myview"
63
+ "hudson.model.MyView"
64
+ else
65
+ raise "Type #{type} is not supported by Jenkins."
66
+ end
67
+ initial_post_params = {
68
+ "name" => view_name,
69
+ "mode" => mode,
70
+ "json" => {
71
+ "name" => view_name,
72
+ "mode" => mode
73
+ }.to_json
74
+ }
75
+ @client.api_post_request("/createView", initial_post_params)
76
+ end
77
+
78
+ # Creates a listview by accepting the given parameters hash
79
+ #
80
+ # @param [Hash] params options to create the new view
81
+ # @option params [String] :name Name of the view
82
+ # @option params [String] :description Description of the view
83
+ # @option params [String] :status_filter Filter jobs based on the status.
84
+ # Valid options: all_selected_jobs, enabled_jobs_only,
85
+ # disabled_jobs_only. Default: all_selected_jobs
86
+ # @option params [Boolean] :filter_queue true or false
87
+ # @option params [Boolean] :filter_executors true or false
88
+ # @option params [String] :regex Regular expression to filter jobs that
89
+ # are to be added to the view
90
+ #
91
+ # @raise [ArgumentError] if the required parameter +:name+ is not
92
+ # specified
93
+ #
94
+ def create_list_view(params)
95
+ # Name is a required parameter. Raise an error if not specified
96
+ raise ArgumentError, "Name is required for creating view" \
97
+ unless params.is_a?(Hash) && params[:name]
98
+ create(params[:name], "listview")
99
+ @logger.debug "Creating a list view with params: #{params.inspect}"
100
+ status_filter = case params[:status_filter]
101
+ when "all_selected_jobs"
102
+ ""
103
+ when "enabled_jobs_only"
104
+ "1"
105
+ when "disabled_jobs_only"
106
+ "2"
107
+ else
108
+ ""
109
+ end
110
+ post_params = {
111
+ "name" => params[:name],
112
+ "mode" => "hudson.model.ListView",
113
+ "description" => params[:description],
114
+ "statusFilter" => status_filter,
115
+ "json" => {
116
+ "name" => params[:name],
117
+ "description" => params[:description],
118
+ "mode" => "hudson.model.ListView",
119
+ "statusFilter" => "",
120
+ "columns" => [
121
+ {
122
+ "stapler-class" => "hudson.views.StatusColumn",
123
+ "kind"=> "hudson.views.StatusColumn"
124
+ },
125
+ {
126
+ "stapler-class" => "hudson.views.WeatherColumn",
127
+ "kind" => "hudson.views.WeatherColumn"
128
+ },
129
+ {
130
+ "stapler-class" => "hudson.views.JobColumn",
131
+ "kind" => "hudson.views.JobColumn"
132
+ },
133
+ {
134
+ "stapler-class" => "hudson.views.LastSuccessColumn",
135
+ "kind" => "hudson.views.LastSuccessColumn"
136
+ },
137
+ {
138
+ "stapler-class" => "hudson.views.LastFailureColumn",
139
+ "kind" => "hudson.views.LastFailureColumn"
140
+ },
141
+ {
142
+ "stapler-class" => "hudson.views.LastDurationColumn",
143
+ "kind" => "hudson.views.LastDurationColumn"
144
+ },
145
+ {
146
+ "stapler-class" => "hudson.views.BuildButtonColumn",
147
+ "kind" => "hudson.views.BuildButtonColumn"
148
+ }
149
+ ]
150
+ }.to_json
151
+ }
152
+ post_params.merge!("filterQueue" => "on") if params[:filter_queue]
153
+ post_params.merge!("filterExecutors" => "on") if params[:filter_executors]
154
+ post_params.merge!("useincluderegex" => "on",
155
+ "includeRegex" => params[:regex]) if params[:regex]
156
+ @client.api_post_request("/view/#{path_encode params[:name]}/configSubmit",
157
+ post_params)
158
+ end
159
+
160
+ # Delete a view
161
+ #
162
+ # @param [String] view_name
163
+ #
164
+ def delete(view_name)
165
+ @logger.info "Deleting view '#{view_name}'"
166
+ @client.api_post_request("/view/#{path_encode view_name}/doDelete")
167
+ end
168
+
169
+ # Deletes all views (except the All view) in Jenkins.
170
+ #
171
+ # @note This method deletes all views (except the All view) available
172
+ # in Jenkins. Please use with caution.
173
+ #
174
+ def delete_all!
175
+ @logger.info "Deleting all views from jenkins"
176
+ list.each { |view| delete(view) unless view == "All"}
177
+ end
178
+
179
+ # This method lists all views
180
+ #
181
+ # @param [String] filter a regex to filter view names
182
+ # @param [Bool] ignorecase whether to be case sensitive or not
183
+ #
184
+ def list(filter = "", ignorecase = true)
185
+ @logger.info "Obtaining views based on filter '#{filter}'"
186
+ view_names = []
187
+ response_json = @client.api_get_request("", "tree=views[name]")
188
+ response_json["views"].each { |view|
189
+ if ignorecase
190
+ view_names << view["name"] if view["name"] =~ /#{filter}/i
191
+ else
192
+ view_names << view["name"] if view["name"] =~ /#{filter}/
193
+ end
194
+ }
195
+ view_names
196
+ end
197
+
198
+ # Checks if the given view exists in Jenkins
199
+ #
200
+ # @param [String] view_name
201
+ #
202
+ def exists?(view_name)
203
+ list(view_name).include?(view_name)
204
+ end
205
+
206
+ # List jobs in a view
207
+ #
208
+ # @param [String] view_name
209
+ #
210
+ # @return [Array] job_names list of jobs in the specified view
211
+ #
212
+ def list_jobs(view_name)
213
+ @logger.info "Obtaining the jobs present in view '#{view_name}'"
214
+ job_names = []
215
+ raise "The view #{view_name} doesn't exists on the server"\
216
+ unless exists?(view_name)
217
+ response_json = @client.api_get_request("/view/#{path_encode view_name}")
218
+ response_json["jobs"].each do |job|
219
+ job_names << job["name"]
220
+ end
221
+ job_names
222
+ end
223
+
224
+ # List jobs in view along with their details
225
+ #
226
+ # @param [String] view_name
227
+ #
228
+ # @return [Array<Hash>] the details of jobs in the specified view
229
+ #
230
+ def list_jobs_with_details(view_name)
231
+ @logger.info "Obtaining the jobs present in view '#{view_name}'"
232
+ raise "The view #{view_name} doesn't exists on the server"\
233
+ unless exists?(view_name)
234
+ response_json = @client.api_get_request("/view/#{path_encode view_name}")
235
+ response_json["jobs"]
236
+ end
237
+
238
+ # Add a job to view
239
+ #
240
+ # @param [String] view_name
241
+ # @param [String] job_name
242
+ #
243
+ def add_job(view_name, job_name)
244
+ @logger.info "Adding job '#{job_name}' to view '#{view_name}'"
245
+ post_msg = "/view/#{path_encode view_name}/addJobToView?name=#{form_encode job_name}"
246
+ @client.api_post_request(post_msg)
247
+ end
248
+
249
+ # Remove a job from view
250
+ #
251
+ # @param [String] view_name
252
+ # @param [String] job_name
253
+ #
254
+ def remove_job(view_name, job_name)
255
+ @logger.info "Removing job '#{job_name}' from view '#{view_name}'"
256
+ post_msg = "/view/#{path_encode view_name}/removeJobFromView?name=#{form_encode job_name}"
257
+ @client.api_post_request(post_msg)
258
+ end
259
+
260
+ # List (sub-)views in a view
261
+ #
262
+ # @param [String] view_name
263
+ #
264
+ # @return [Array] view_names list of (sub-)views in the specified view
265
+ #
266
+ def list_views(view_name)
267
+ @logger.info "Obtaining the views present in view '#{view_name}'"
268
+ view_names = []
269
+ raise "The view #{view_name} doesn't exists on the server"\
270
+ unless exists?(view_name)
271
+ response_json = @client.api_get_request("/view/#{path_encode view_name}")
272
+ response_json["views"].each do |view|
273
+ view_names << view["name"]
274
+ end
275
+ view_names
276
+ end
277
+
278
+ # List (sub-)views in view along with their details
279
+ #
280
+ # @param [String] view_name
281
+ #
282
+ # @return [Array<Hash>] the details of (sub-)views in the specified view
283
+ #
284
+ def list_views_with_details(view_name)
285
+ @logger.info "Obtaining the views present in view '#{view_name}'"
286
+ raise "The view #{view_name} doesn't exists on the server"\
287
+ unless exists?(view_name)
288
+ response_json = @client.api_get_request("/view/#{path_encode view_name}")
289
+ response_json["views"]
290
+ end
291
+
292
+ # Obtain the configuration stored in config.xml of a specific view
293
+ #
294
+ # @param [String] view_name
295
+ #
296
+ def get_config(view_name)
297
+ @logger.info "Obtaining the configuration of view '#{view_name}'"
298
+ @client.get_config("/view/#{path_encode view_name}")
299
+ end
300
+
301
+ # Post the configuration of a view given the view name and the config.xml
302
+ #
303
+ # @param [String] view_name
304
+ # @param [String] xml
305
+ #
306
+ def post_config(view_name, xml)
307
+ @logger.info "Posting the configuration of view '#{view_name}'"
308
+ @client.post_config("/view/#{path_encode view_name}/config.xml", xml)
309
+ end
310
+
311
+ end
312
+ end
313
+ end
@@ -0,0 +1,52 @@
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
+ require 'improved_jenkins_client/version'
24
+ require 'improved_jenkins_client/exceptions'
25
+ require 'improved_jenkins_client/client'
26
+ require 'improved_jenkins_client/job'
27
+ require 'improved_jenkins_client/node'
28
+ require 'improved_jenkins_client/system'
29
+ require 'improved_jenkins_client/view'
30
+ require 'improved_jenkins_client/build_queue'
31
+ require 'improved_jenkins_client/plugin_manager'
32
+ require 'improved_jenkins_client/user'
33
+ require 'improved_jenkins_client/root'
34
+
35
+ require 'improved_jenkins_client/cli/helper'
36
+ require 'improved_jenkins_client/cli/base'
37
+ require 'improved_jenkins_client/cli/job'
38
+ require 'improved_jenkins_client/cli/node'
39
+ require 'improved_jenkins_client/cli/system'
40
+
41
+ module JenkinsApi
42
+ class Client
43
+ module PluginSettings
44
+ class InvalidType < Exception; end
45
+
46
+ autoload :Base, 'improved_jenkins_client/plugin_settings/base'
47
+ autoload :Hipchat, 'improved_jenkins_client/plugin_settings/hipchat'
48
+ autoload :WorkspaceCleanup, 'improved_jenkins_client/plugin_settings/workspace_cleanup'
49
+ autoload :Collection, 'improved_jenkins_client/plugin_settings/collection'
50
+ end
51
+ end
52
+ end