jenkins2 0.1.0 → 1.0.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +43 -22
- data/README.md +140 -76
- data/bin/jenkins2 +8 -1
- data/lib/jenkins2.rb +10 -5
- data/lib/jenkins2/api.rb +33 -0
- data/lib/jenkins2/api/computer.rb +49 -0
- data/lib/jenkins2/api/credentials.rb +151 -0
- data/lib/jenkins2/api/job.rb +50 -0
- data/lib/jenkins2/api/plugins.rb +55 -0
- data/lib/jenkins2/api/root.rb +34 -0
- data/lib/jenkins2/api/rud.rb +21 -0
- data/lib/jenkins2/api/user.rb +35 -0
- data/lib/jenkins2/api/view.rb +40 -0
- data/lib/jenkins2/cli.rb +157 -0
- data/lib/jenkins2/cli/credentials.rb +232 -0
- data/lib/jenkins2/cli/job.rb +48 -0
- data/lib/jenkins2/cli/nodes.rb +233 -0
- data/lib/jenkins2/cli/plugins.rb +101 -0
- data/lib/jenkins2/cli/root.rb +65 -0
- data/lib/jenkins2/cli/user.rb +16 -0
- data/lib/jenkins2/cli/view.rb +155 -0
- data/lib/jenkins2/connection.rb +90 -0
- data/lib/jenkins2/errors.rb +37 -0
- data/lib/jenkins2/log.rb +8 -7
- data/lib/jenkins2/resource_proxy.rb +46 -0
- data/lib/jenkins2/util.rb +67 -0
- data/lib/jenkins2/version.rb +3 -1
- metadata +33 -49
- data/lib/jenkins2/client.rb +0 -127
- data/lib/jenkins2/client/credential_commands.rb +0 -134
- data/lib/jenkins2/client/node_commands.rb +0 -105
- data/lib/jenkins2/client/plugin_commands.rb +0 -53
- data/lib/jenkins2/cmdparse.rb +0 -51
- data/lib/jenkins2/command_line.rb +0 -221
- data/lib/jenkins2/try.rb +0 -36
- data/lib/jenkins2/uri.rb +0 -10
- data/lib/jenkins2/wait.rb +0 -29
@@ -0,0 +1,151 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'rud'
|
4
|
+
|
5
|
+
module Jenkins2
|
6
|
+
class API
|
7
|
+
module Credentials
|
8
|
+
def credentials(params={})
|
9
|
+
Proxy.new connection, 'credentials', params
|
10
|
+
end
|
11
|
+
|
12
|
+
class Proxy < ::Jenkins2::ResourceProxy
|
13
|
+
def store(id, params={})
|
14
|
+
path = build_path 'store', id
|
15
|
+
Store::Proxy.new connection, path, params
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module Store
|
20
|
+
class Proxy < ::Jenkins2::ResourceProxy
|
21
|
+
def domain(id, params={})
|
22
|
+
Domain::Proxy.new(connection, build_path('domain', id), params)
|
23
|
+
end
|
24
|
+
|
25
|
+
def create_domain(config_xml)
|
26
|
+
connection.post(build_path('createDomain'), config_xml) do |req|
|
27
|
+
req['Content-Type'] = 'text/xml'
|
28
|
+
end.code == '200'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
module Domain
|
33
|
+
class Proxy < ::Jenkins2::ResourceProxy
|
34
|
+
include ::Jenkins2::API::RUD
|
35
|
+
|
36
|
+
BOUNDARY = '----Jenkins2RubyMultipartClient' + rand(1_000_000).to_s
|
37
|
+
|
38
|
+
# Creates ssh username with private key credentials. Jenkins must have ssh-credentials
|
39
|
+
# plugin installed, to use this functionality. Accepts the following key-word
|
40
|
+
# parameters.
|
41
|
+
# +scope+:: Scope of the credential. GLOBAL or SYSTEM
|
42
|
+
# +id+:: Id of the credential. Will be Generated by Jenkins, if not provided.
|
43
|
+
# +description+:: Human readable text, what this credential is used for.
|
44
|
+
# +username+:: Ssh username.
|
45
|
+
# +private_key+:: Ssh private key, with new lines replaced by <tt>\n</tt> sequence.
|
46
|
+
# +passphrase+:: Passphrase for the private key. Empty string, if not provided.
|
47
|
+
def create_ssh(private_key:, **args)
|
48
|
+
json_body = {
|
49
|
+
'' => '1',
|
50
|
+
credentials: args.merge(
|
51
|
+
privateKeySource: {
|
52
|
+
value: '0',
|
53
|
+
privateKey: private_key,
|
54
|
+
'stapler-class' => 'com.cloudbees.jenkins.plugins.sshcredentials.impl.'\
|
55
|
+
'BasicSSHUserPrivateKey$DirectEntryPrivateKeySource'
|
56
|
+
},
|
57
|
+
'$class' => 'com.cloudbees.jenkins.plugins.sshcredentials.impl.'\
|
58
|
+
'BasicSSHUserPrivateKey'
|
59
|
+
)
|
60
|
+
}.to_json
|
61
|
+
create_("json=#{::CGI.escape json_body}")
|
62
|
+
end
|
63
|
+
|
64
|
+
# Creates a secret text credential. Jenkins must have plain-credentials plugin
|
65
|
+
# installed, to use this functionality. Accepts hash with the following parameters.
|
66
|
+
# +scope+:: Scope of the credential. GLOBAL or SYSTEM
|
67
|
+
# +id+:: Id of the credential. Will be Generated by Jenkins, if not provided.
|
68
|
+
# +description+:: Human readable text, what this credential is used for.
|
69
|
+
# +secret+:: Some secret text.
|
70
|
+
def create_secret_text(**args)
|
71
|
+
json_body = {
|
72
|
+
'' => '3',
|
73
|
+
credentials: args.merge(
|
74
|
+
'$class' => 'org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl'
|
75
|
+
)
|
76
|
+
}.to_json
|
77
|
+
create_("json=#{::CGI.escape json_body}")
|
78
|
+
end
|
79
|
+
|
80
|
+
# Creates a secret file credential. Jenkins must have plain-credentials plugin
|
81
|
+
# installed, to use this functionality. Accepts hash with the following parameters.
|
82
|
+
# +scope+:: Scope of the credential. GLOBAL or SYSTEM
|
83
|
+
# +id+:: Id of the credential. Will be Generated by Jenkins, if not provided.
|
84
|
+
# +description+:: Human readable text, what this credential is used for.
|
85
|
+
# +filename+:: Name of the file.
|
86
|
+
# +content+:: File content.
|
87
|
+
def create_secret_file(filename:, content:, **args)
|
88
|
+
body = "--#{BOUNDARY}\r\n"\
|
89
|
+
"Content-Disposition: form-data; name=\"file0\"; filename=\"#{filename}\"\r\n"\
|
90
|
+
"Content-Type: application/octet-stream\r\n\r\n"\
|
91
|
+
"#{content}\r\n"\
|
92
|
+
"--#{BOUNDARY}\r\n"\
|
93
|
+
"Content-Disposition: form-data; name=\"json\"\r\n\r\n"\
|
94
|
+
"#{{
|
95
|
+
'' => '2',
|
96
|
+
credentials: args.merge(
|
97
|
+
'$class' => 'org.jenkinsci.plugins.plaincredentials.impl.FileCredentialsImpl',
|
98
|
+
'file' => 'file0'
|
99
|
+
)
|
100
|
+
}.to_json}"\
|
101
|
+
"\r\n\r\n--#{BOUNDARY}--\r\n"
|
102
|
+
create_(body, "multipart/form-data, boundary=#{BOUNDARY}")
|
103
|
+
end
|
104
|
+
|
105
|
+
# Creates username and password credential. Accepts hash with the following parameters.
|
106
|
+
# +scope+:: Scope of the credential. GLOBAL or SYSTEM
|
107
|
+
# +id+:: Id of the credential. Will be Generated by Jenkins, if not provided.
|
108
|
+
# +description+:: Human readable text, what this credential is used for.
|
109
|
+
# +username+:: Username.
|
110
|
+
# +password+:: Password in plain text.
|
111
|
+
def create_username_password(**args)
|
112
|
+
json_body = {
|
113
|
+
'' => '0',
|
114
|
+
credentials: args.merge(
|
115
|
+
'$class' => 'com.cloudbees.plugins.credentials.impl.'\
|
116
|
+
'UsernamePasswordCredentialsImpl'
|
117
|
+
)
|
118
|
+
}.to_json
|
119
|
+
create_("json=#{::CGI.escape json_body}")
|
120
|
+
end
|
121
|
+
|
122
|
+
def create_(body, content_type='application/x-www-form-urlencoded')
|
123
|
+
connection.post(build_path('createCredentials'), body) do |req|
|
124
|
+
req['Content-Type'] = content_type
|
125
|
+
end.code == '302'
|
126
|
+
end
|
127
|
+
|
128
|
+
def create(config_xml)
|
129
|
+
connection.post(build_path('createCredentials'), config_xml) do |req|
|
130
|
+
req['Content-Type'] = 'text/xml'
|
131
|
+
end.code == '200'
|
132
|
+
end
|
133
|
+
|
134
|
+
# Returns credential as json. Raises Net::HTTPNotFound, if no such credential
|
135
|
+
# +id+:: Credential's id
|
136
|
+
def credential(id, params={})
|
137
|
+
path = build_path 'credential', id
|
138
|
+
Credential::Proxy.new connection, path, params
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
module Credential
|
143
|
+
class Proxy < ::Jenkins2::ResourceProxy
|
144
|
+
include ::Jenkins2::API::RUD
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'rud'
|
4
|
+
|
5
|
+
module Jenkins2
|
6
|
+
class API
|
7
|
+
module Job
|
8
|
+
def job(name, **params)
|
9
|
+
proxy = Proxy.new connection, 'job', params
|
10
|
+
proxy.id = name
|
11
|
+
proxy
|
12
|
+
end
|
13
|
+
|
14
|
+
class Proxy < ::Jenkins2::ResourceProxy
|
15
|
+
attr_accessor :id
|
16
|
+
include ::Jenkins2::API::RUD
|
17
|
+
|
18
|
+
def create(config_xml)
|
19
|
+
connection.post('createItem', config_xml, name: id) do |req|
|
20
|
+
req['Content-Type'] = 'text/xml'
|
21
|
+
end.code == '200'
|
22
|
+
end
|
23
|
+
|
24
|
+
def copy(from)
|
25
|
+
connection.post('createItem', nil, name: id, from: from, mode: 'copy').code == '302'
|
26
|
+
end
|
27
|
+
|
28
|
+
def disable
|
29
|
+
connection.post(build_path('disable')).code == '302'
|
30
|
+
end
|
31
|
+
|
32
|
+
def enable
|
33
|
+
connection.post(build_path('enable')).code == '302'
|
34
|
+
end
|
35
|
+
|
36
|
+
def build(build_parameters={})
|
37
|
+
if build_parameters.empty?
|
38
|
+
connection.post(build_path('build'))
|
39
|
+
else
|
40
|
+
connection.post(build_path('buildWithParameters'), nil, build_parameters)
|
41
|
+
end.code == '201'
|
42
|
+
end
|
43
|
+
|
44
|
+
def polling
|
45
|
+
connection.post(build_path('polling')).code == '302'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jenkins2
|
4
|
+
class API
|
5
|
+
module Plugins
|
6
|
+
def plugins(**params)
|
7
|
+
Proxy.new connection, 'pluginManager', params
|
8
|
+
end
|
9
|
+
|
10
|
+
class Proxy < ::Jenkins2::ResourceProxy
|
11
|
+
BOUNDARY = '----Jenkins2RubyMultipartClient' + rand(1_000_000).to_s
|
12
|
+
|
13
|
+
def install(*short_names)
|
14
|
+
path = build_path 'install'
|
15
|
+
form_data = short_names.flatten.inject({}) do |memo, obj|
|
16
|
+
memo.merge "plugin.#{obj}.default" => 'on'
|
17
|
+
end.merge('dynamicLoad' => 'Install without restart')
|
18
|
+
connection.post(path, ::URI.encode_www_form(form_data)).code == '302'
|
19
|
+
end
|
20
|
+
|
21
|
+
def upload(hpi_file, filename)
|
22
|
+
body = "--#{BOUNDARY}\r\n"\
|
23
|
+
"Content-Disposition: form-data; name=\"file0\"; filename=\"#{filename}\"\r\n"\
|
24
|
+
"Content-Type: application/octet-stream\r\n\r\n"\
|
25
|
+
"#{hpi_file}\r\n"\
|
26
|
+
"--#{BOUNDARY}\r\n"\
|
27
|
+
"Content-Disposition: form-data; name=\"json\"\r\n\r\n"\
|
28
|
+
"\r\n\r\n--#{BOUNDARY}--\r\n"
|
29
|
+
connection.post(build_path('uploadPlugin'), body) do |req|
|
30
|
+
req['Content-Type'] = "multipart/form-data, boundary=#{BOUNDARY}"
|
31
|
+
end.code == '302'
|
32
|
+
end
|
33
|
+
|
34
|
+
def plugin(id, params={})
|
35
|
+
path = build_path 'plugin', id
|
36
|
+
Plugin::Proxy.new connection, path, params
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
module Plugin
|
41
|
+
class Proxy < ::Jenkins2::ResourceProxy
|
42
|
+
def uninstall
|
43
|
+
path = build_path 'doUninstall'
|
44
|
+
form_data = { 'Submit' => 'Yes', 'json' => '{}' }
|
45
|
+
connection.post(path, ::URI.encode_www_form(form_data)).code == '302'
|
46
|
+
end
|
47
|
+
|
48
|
+
def active?
|
49
|
+
raw.instance_of? ::Net::HTTPOK and subject.active
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jenkins2
|
4
|
+
class API
|
5
|
+
module Root
|
6
|
+
def root(**params)
|
7
|
+
Proxy.new connection, '', params
|
8
|
+
end
|
9
|
+
|
10
|
+
def version
|
11
|
+
connection.head('/')['X-Jenkins']
|
12
|
+
end
|
13
|
+
|
14
|
+
def quiet_down
|
15
|
+
connection.post('quietDown').code == '302'
|
16
|
+
end
|
17
|
+
|
18
|
+
def cancel_quiet_down
|
19
|
+
connection.post('cancelQuietDown').code == '302'
|
20
|
+
end
|
21
|
+
|
22
|
+
def restart
|
23
|
+
connection.post('safeRestart').code == '302'
|
24
|
+
end
|
25
|
+
|
26
|
+
def restart!
|
27
|
+
connection.post('restart').code == '302'
|
28
|
+
end
|
29
|
+
|
30
|
+
class Proxy < ::Jenkins2::ResourceProxy
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jenkins2
|
4
|
+
class API
|
5
|
+
module RUD
|
6
|
+
# = Read
|
7
|
+
def config_xml
|
8
|
+
connection.get(build_path('config.xml')).body
|
9
|
+
end
|
10
|
+
|
11
|
+
def update(config_xml)
|
12
|
+
connection.post(build_path('config.xml'), config_xml).code == '200'
|
13
|
+
end
|
14
|
+
|
15
|
+
def delete
|
16
|
+
connection.post(build_path('doDelete')).code == '302'
|
17
|
+
# connection.delete(build_path('config.xml')).code == '302'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jenkins2
|
4
|
+
class API
|
5
|
+
module User
|
6
|
+
def me(**params)
|
7
|
+
Me::Proxy.new connection, 'me', params
|
8
|
+
end
|
9
|
+
|
10
|
+
def user(id, **params)
|
11
|
+
proxy = Proxy.new connection, 'user', params
|
12
|
+
proxy.id = id
|
13
|
+
proxy
|
14
|
+
end
|
15
|
+
|
16
|
+
def people(**params)
|
17
|
+
People::Proxy.new connection, 'people', params
|
18
|
+
end
|
19
|
+
|
20
|
+
class Proxy < ::Jenkins2::ResourceProxy
|
21
|
+
attr_accessor :id
|
22
|
+
end
|
23
|
+
|
24
|
+
module Me
|
25
|
+
class Proxy < ::Jenkins2::ResourceProxy
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
module People
|
30
|
+
class Proxy < ::Jenkins2::ResourceProxy
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'rud'
|
4
|
+
|
5
|
+
module Jenkins2
|
6
|
+
class API
|
7
|
+
module View
|
8
|
+
MODE_LIST_VIEW = 'hudson.model.ListView'
|
9
|
+
|
10
|
+
def view(id, **params)
|
11
|
+
proxy = Proxy.new connection, 'view', params
|
12
|
+
proxy.id = id
|
13
|
+
proxy
|
14
|
+
end
|
15
|
+
|
16
|
+
def views(**params)
|
17
|
+
::Jenkins2::ResourceProxy.new(connection, '', params).views
|
18
|
+
end
|
19
|
+
|
20
|
+
class Proxy < ::Jenkins2::ResourceProxy
|
21
|
+
attr_accessor :id
|
22
|
+
include ::Jenkins2::API::RUD
|
23
|
+
|
24
|
+
def create(config_xml)
|
25
|
+
connection.post('createView', config_xml, name: id) do |req|
|
26
|
+
req['Content-Type'] = 'text/xml'
|
27
|
+
end.code == '200'
|
28
|
+
end
|
29
|
+
|
30
|
+
def add_job(job_name)
|
31
|
+
connection.post(build_path('addJobToView'), nil, name: job_name).code == '200'
|
32
|
+
end
|
33
|
+
|
34
|
+
def remove_job(job_name)
|
35
|
+
connection.post(build_path('removeJobFromView'), nil, name: job_name).code == '200'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/jenkins2/cli.rb
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'optparse/uri'
|
4
|
+
require 'yaml'
|
5
|
+
|
6
|
+
require_relative 'version'
|
7
|
+
require_relative 'cli/credentials'
|
8
|
+
require_relative 'cli/nodes'
|
9
|
+
require_relative 'cli/root'
|
10
|
+
require_relative 'cli/plugins'
|
11
|
+
require_relative 'cli/user'
|
12
|
+
require_relative 'cli/view'
|
13
|
+
|
14
|
+
module Jenkins2
|
15
|
+
class CLI
|
16
|
+
attr_reader :options, :errors
|
17
|
+
|
18
|
+
def initialize(options={})
|
19
|
+
@options = options.dup
|
20
|
+
@command = []
|
21
|
+
@errors = []
|
22
|
+
@parser = nil
|
23
|
+
add_options
|
24
|
+
end
|
25
|
+
|
26
|
+
def call
|
27
|
+
if options[:help]
|
28
|
+
summary
|
29
|
+
elsif options[:version]
|
30
|
+
Jenkins2::VERSION
|
31
|
+
elsif !errors.empty?
|
32
|
+
errors.join("\n") + "\n" + summary
|
33
|
+
else
|
34
|
+
run
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def parse(args)
|
39
|
+
parser.order! args do |nonopt|
|
40
|
+
@command << nonopt
|
41
|
+
return command_to_class.new(options).parse(args) if command_to_class
|
42
|
+
next
|
43
|
+
end
|
44
|
+
missing = mandatory_arguments.select{|a| options[a].nil? }
|
45
|
+
@errors << "Missing argument(s): #{missing.join(', ')}." unless missing.empty?
|
46
|
+
self
|
47
|
+
end
|
48
|
+
|
49
|
+
# This method should be overwritten in subclasses
|
50
|
+
def self.description; end
|
51
|
+
|
52
|
+
def self.class_to_command
|
53
|
+
to_s.split('::').last.gsub(/(.)([A-Z])/, '\1-\2').downcase if superclass == Jenkins2::CLI
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.subcommands
|
57
|
+
constants(false).collect{|c| const_get(c) }.select do |c|
|
58
|
+
c.is_a?(Class) and c.superclass == Jenkins2::CLI
|
59
|
+
end.sort_by(&:to_s)
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
# This method can be overwritten in subclasses, to add more mandatory arguments
|
65
|
+
def mandatory_arguments
|
66
|
+
[:server]
|
67
|
+
end
|
68
|
+
|
69
|
+
# This method should be overwritten in subclasses
|
70
|
+
def add_options; end
|
71
|
+
|
72
|
+
# This method should be overwritten in subclasses
|
73
|
+
def run
|
74
|
+
summary
|
75
|
+
end
|
76
|
+
|
77
|
+
def summary
|
78
|
+
if self.class.subcommands.empty?
|
79
|
+
global_parser.to_s + parser.to_s
|
80
|
+
else
|
81
|
+
parser.separator 'Commands:'
|
82
|
+
self.class.subcommands.each do |sc|
|
83
|
+
key = sc.class_to_command
|
84
|
+
parser.base.append(OptionParser::Switch::NoArgument.new(key, nil, [key], nil, nil,
|
85
|
+
[sc.description], proc{ OptionParser.new(&block) }), [], [key])
|
86
|
+
end
|
87
|
+
parser.to_s
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def parser
|
92
|
+
@parser ||= if (key = self.class.class_to_command)
|
93
|
+
OptionParser.new do |parser|
|
94
|
+
parser.banner = 'Command:'
|
95
|
+
parser.top.append(OptionParser::Switch::NoArgument.new(key, nil, [key], nil,
|
96
|
+
nil, [self.class.description], proc{ OptionParser.new(&block) }), [], [key])
|
97
|
+
end
|
98
|
+
else
|
99
|
+
global_parser
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def global_parser
|
104
|
+
@global_parser ||= OptionParser.new do |parser|
|
105
|
+
parser.banner = 'Usage: jenkins2 [global-arguments] <command> [command-arguments]'
|
106
|
+
parser.separator ''
|
107
|
+
parser.separator 'Global arguments (accepted by all commands):'
|
108
|
+
parser.on '-s', '--server URL', ::URI, 'Jenkins Server Url' do |s|
|
109
|
+
@options[:server] = s
|
110
|
+
end
|
111
|
+
parser.on '-u', '--user USER', 'Jenkins API User' do |u|
|
112
|
+
@options[:user] = u
|
113
|
+
end
|
114
|
+
parser.on '-k', '--key KEY', 'Jenkins API Key' do |k|
|
115
|
+
@options[:key] = k
|
116
|
+
end
|
117
|
+
parser.on '-c', '--config [PATH]', %(Read configuration file. All global options can be \
|
118
|
+
configured in configuration file. File format is yaml. Arguments provided in command line will \
|
119
|
+
overwrite those in configuration file. Program looks for .jenkins2.conf in current directory if \
|
120
|
+
no PATH is provided.) do |c|
|
121
|
+
@options[:config] = c || ::File.join('.jenkins2.conf')
|
122
|
+
config_file_options = YAML.load_file(options[:config])
|
123
|
+
@options = config_file_options.merge options
|
124
|
+
end
|
125
|
+
parser.on '-l', '--log FILE', 'Log file. Prints to standard out, if not provided' do |l|
|
126
|
+
@options[:log] = l
|
127
|
+
end
|
128
|
+
parser.on '-v', '--verbose VALUE', Integer, 'Print more info. 1 up to 3. Prints only '\
|
129
|
+
'errors by default.' do |v|
|
130
|
+
@options[:verbose] = v
|
131
|
+
end
|
132
|
+
parser.on '-h', '--help', 'Show help' do
|
133
|
+
@options[:help] = true
|
134
|
+
end
|
135
|
+
parser.on '-V', '--version', 'Show version' do
|
136
|
+
@options[:version] = true
|
137
|
+
end
|
138
|
+
parser.separator ''
|
139
|
+
parser.separator 'For command specific arguments run: jenkins2 --help <command>'
|
140
|
+
parser.separator ''
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def command_to_class
|
145
|
+
const = @command.join('-').split('-').map(&:capitalize).join
|
146
|
+
if self.class.const_defined?(const)
|
147
|
+
klass = self.class.const_get(const)
|
148
|
+
return klass if klass.is_a?(Class) and klass.superclass == Jenkins2::CLI
|
149
|
+
end
|
150
|
+
nil
|
151
|
+
end
|
152
|
+
|
153
|
+
def jc
|
154
|
+
@jc ||= Jenkins2.connect options
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|