domo 0.0.2

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.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ # A sample Gemfile
2
+ source :rubygems
3
+
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,24 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ domo (0.0.1)
5
+ bundler
6
+ highline
7
+ mechanize
8
+ nokogiri
9
+ thor
10
+
11
+ GEM
12
+ remote: http://rubygems.org/
13
+ specs:
14
+ highline (1.6.2)
15
+ mechanize (1.0.0)
16
+ nokogiri (>= 1.2.1)
17
+ nokogiri (1.4.4)
18
+ thor (0.14.6)
19
+
20
+ PLATFORMS
21
+ ruby
22
+
23
+ DEPENDENCIES
24
+ domo!
data/LICENCE.txt ADDED
@@ -0,0 +1,18 @@
1
+ Permission is hereby granted, free of charge, to any person obtaining
2
+ a copy of this software and associated documentation files (the
3
+ 'Software'), to deal in the Software without restriction, including
4
+ without limitation the rights to use, copy, modify, merge, publish,
5
+ distribute, sublicense, and/or sell copies of the Software, and to
6
+ permit persons to whom the Software is furnished to do so, subject to
7
+ the following conditions:
8
+
9
+ The above copyright notice and this permission notice shall be
10
+ included in all copies or substantial portions of the Software.
11
+
12
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
13
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
15
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
16
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
17
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
18
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rst ADDED
@@ -0,0 +1,66 @@
1
+ ----
2
+ Domo
3
+ ----
4
+
5
+ Super-duper simple command client for Jenkins.
6
+
7
+ Requirements
8
+ ------------
9
+
10
+ * ruby-1.9.2 (probably work with 1.8 as well)
11
+ * bundler_
12
+
13
+
14
+ Install
15
+ -------
16
+
17
+ ::
18
+
19
+ rake install
20
+
21
+ Usage
22
+ -----
23
+
24
+ ::
25
+
26
+ Usage: domo [command] [options]
27
+ Commands:
28
+ domo help [command] # show help for domo
29
+ domo list <jenkins_url> # list the all of jobs on target jenkins
30
+ domo trigger <jenkins_url> <job_list_path> [options] # trigger jobs specified in the list file
31
+ domo toggle_all <jenkins_url> <enable|disable> # en[dis]able all jobs specified jenkins owns
32
+ domo toggle <jenkins_url> <enable|disable> <job_list> # en[dis]able jobs specified in the list file
33
+ domo clone <src_jenkins_url> <dest_jenkins_url> <job_list_path> # clone jobs from jenkins to another jenkins
34
+ domo delete <jenkins_url> <job_list_path> [options] # delete jobs specified in the list file
35
+ domo delete_all <jenkins_url> [options] # delete all jobs that specified jenkins owns
36
+ domo install <jenkins_url> <plugin_list_path> # install plugins specified in the list file
37
+ domo backup_config <jenkins_url> [options] # backup all job configs that specified jenkins owns
38
+ domo create_jobs <jenkins_url> <config_files_dir> # create jobs from specified 'config.xml's
39
+ domo version # show version information
40
+
41
+ License
42
+ -------
43
+
44
+ ::
45
+
46
+ Copyright (c) <2011> cynipe
47
+
48
+ Permission is hereby granted, free of charge, to any person obtaining
49
+ a copy of this software and associated documentation files (the "Software"),
50
+ to deal in the Software without restriction, including without limitation
51
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
52
+ and/or sell copies of the Software, and to permit persons to whom the
53
+ Software is furnished to do so, subject to the following conditions:
54
+
55
+ The above copyright notice and this permission notice shall be included
56
+ in all copies or substantial portions of the Software.
57
+
58
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
59
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
60
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
61
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
62
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
63
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
64
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
65
+
66
+ .. _bundler: https://rvm.beginrescueend.com/
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.2
data/bin/domo ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby -U
2
+ require "domo"
3
+
4
+ Domo::CLI.start
data/domo.gemspec ADDED
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "domo/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "domo"
7
+ s.version = Domo::Version.to_s
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["cynipe"]
10
+ s.email = ["cynipe@cynipe.net"]
11
+ s.summary = %q{Domo is the super-duper simple client for Jenkins}
12
+
13
+ s.files = Dir.glob("**/*")
14
+ s.executables = ["domo"]
15
+ s.require_paths = ["lib"]
16
+
17
+ s.add_dependency("bundler")
18
+ s.add_dependency("mechanize")
19
+ s.add_dependency("nokogiri")
20
+ s.add_dependency("highline")
21
+ s.add_dependency("thor")
22
+ end
data/lib/domo.rb ADDED
@@ -0,0 +1,3 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require "domo/core"
3
+ require "domo/cli"
data/lib/domo/cli.rb ADDED
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env ruby -U
2
+ require "thor"
3
+ require "domo"
4
+
5
+ module Domo
6
+
7
+ class CLI < Thor
8
+
9
+ def initialize(args=[], options={}, config={})
10
+ super(args, options, config)
11
+ @domo = Domo::Core.new
12
+ end
13
+
14
+ map "-v" => :version, "--version" => :version, "-h" => :help, "--help" => :help
15
+
16
+ desc "list <jenkins_url>", "list the all of jobs on target jenkins"
17
+ def list(target)
18
+ @domo.list(target, true)
19
+ end
20
+
21
+ desc "trigger <jenkins_url> <job_list_path> [options]", "trigger jobs specified in the list file"
22
+ method_option :dryrun,
23
+ :desc => "execute except actually send request",
24
+ :type => :boolean,
25
+ :default => true
26
+ def trigger(target, job_list)
27
+ @domo.trigger(target, job_list, options[:dryrun])
28
+ end
29
+
30
+ desc "toggle_all <jenkins_url> <enable|disable>", "en[dis]able all jobs specified jenkins owns"
31
+ def toggle_all(target, action)
32
+ @domo.toggle_all(target, action)
33
+ end
34
+
35
+ desc "toggle <jenkins_url> <enable|disable> <job_list>", "en[dis]able jobs specified in the list file"
36
+ def toggle(target, action, job_list)
37
+ @domo.toggle(target, action, job_list)
38
+ end
39
+
40
+ desc "clone <src_jenkins_url> <dest_jenkins_url> <job_list_path>", "clone jobs from jenkins to another jenkins"
41
+ def clone(src, dest, job_list)
42
+ @domo.clone(src, dest, job_list)
43
+ end
44
+
45
+
46
+ desc "delete <jenkins_url> <job_list_path> [options]", "delete jobs specified in the list file"
47
+ method_option :dryrun,
48
+ :desc => "execute except actually send request",
49
+ :type => :boolean,
50
+ :default => true
51
+ def delete(target, job_list)
52
+ @domo.delete(target, job_list, options[:dryrun])
53
+ end
54
+
55
+ desc "delete_all <jenkins_url> [options]", "delete all jobs that specified jenkins owns"
56
+ method_option :dryrun,
57
+ :desc => "execute except actually send request",
58
+ :type => :boolean,
59
+ :default => true
60
+ def delete_all(target)
61
+ @domo.delete_all(target, options[:dryrun])
62
+ end
63
+
64
+ desc "install <jenkins_url> <plugin_list_path>", "install plugins specified in the list file"
65
+ def install(target, plugin_list)
66
+ @domo.install(target, plugin_list)
67
+ end
68
+
69
+ desc "backup_config <jenkins_url> [options]", "backup all job configs that specified jenkins owns"
70
+ method_option :dest,
71
+ :desc => "config.xml dest dir",
72
+ :type => :string,
73
+ :default => "#{Dir::pwd}/jobs"
74
+ def backup_config(target)
75
+ @domo.backup_config(target, options[:dest])
76
+ end
77
+
78
+ desc "create_jobs <jenkins_url> <config_files_dir>", "create jobs from specified 'config.xml's"
79
+ def create_jobs(target, config_dir)
80
+ @domo.create_jobs(target, config_dir)
81
+ end
82
+
83
+ desc "version", "show version information"
84
+ def version
85
+ puts Domo::Version.to_s
86
+ end
87
+
88
+ desc "help [command]", "show help for domo"
89
+ def help(*args)
90
+ super(*args)
91
+ end
92
+
93
+ def self.help(shell, *)
94
+ list = printable_tasks
95
+ shell.say "Usage: domo [command] [options]"
96
+ shell.say "Commands:"
97
+ shell.print_table(list, :ident => 2, :truncate => true)
98
+ shell.say
99
+ class_options_help(shell)
100
+ end
101
+
102
+ end
103
+
104
+ end
data/lib/domo/core.rb ADDED
@@ -0,0 +1,189 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'rubygems'
3
+ require 'bundler/setup'
4
+ require 'open-uri'
5
+ require 'nokogiri'
6
+ require 'mechanize'
7
+ require 'erb'
8
+ require 'highline'
9
+
10
+ # オレオレ証明を無視する為
11
+ require 'openssl'
12
+ module OpenSSL
13
+ module SSL
14
+ remove_const :VERIFY_PEER
15
+ end
16
+ end
17
+ OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
18
+
19
+ # work around problem where HighLine detects an eof on $stdin and raises an
20
+ # error.
21
+ HighLine.track_eof = false
22
+
23
+ module Domo
24
+
25
+ class Core
26
+ include ERB::Util
27
+
28
+ def initialize
29
+ @agent = Mechanize.new
30
+ end
31
+
32
+ # 対象とするJenkinsのジョブの一覧を返す
33
+ def list(target, verbose=false)
34
+ login(target) if auth_required?(target)
35
+ jenkins_info = Nokogiri.XML(@agent.get_file("#{target}/api/xml"))
36
+ jenkins_info.css("job>name").map do |name|
37
+ result = name.text
38
+ puts result if verbose
39
+ result
40
+ end
41
+ end
42
+
43
+ # ジョブ名一覧ファイルをもとにビルドをトリガリングする
44
+ def trigger(target, job_list, dryrun=true)
45
+ raise "target file unreadable" unless File.readable? job_list
46
+ puts "!!dryrun mode!!" if dryrun
47
+ login(target) if auth_required?(target)
48
+ File.read(job_list).each_line do |name|
49
+ encoded_name = url_encode(name.strip!)
50
+ @agent.post("#{target}/job/#{encoded_name}/build") unless dryrun
51
+ puts "#{name} triggerd"
52
+ end
53
+ end
54
+
55
+ # 対象のJenkins上にある全てのジョブを有効/無効化する
56
+ def toggle_all(target, action)
57
+ list(target).each do |name|
58
+ @agent.post("#{target}/job/#{url_encode(name)}/#{action}")
59
+ puts "#{name} #{action}d."
60
+ end
61
+ end
62
+
63
+ # ジョブ名一覧ファイルを元に対象のJenkins上にあるジョブを有効/無効化する
64
+ def toggle(target, action, job_list)
65
+ raise "target file unreadable" unless File.readable? job_list
66
+ File.read(job_list).each_line do |name|
67
+ encoded_name = url_encode(name.strip!)
68
+ @agent.post("#{target}/job/#{encoded_name}/#{action}")
69
+ puts "#{name} #{action}d."
70
+ end
71
+ end
72
+
73
+ # 対象のJenkinsから全てを削除する
74
+ # 破壊的なメソッドなのでdryrunがデフォルト
75
+ def delete_all(target, dryrun=true)
76
+ puts "!!dryrun mode!!" if dryrun
77
+ list(target).each do |name|
78
+ @agent.post("#{target}/job/#{url_encode(name)}/doDelete") unless dryrun
79
+ puts "#{name} deleted"
80
+ end
81
+ end
82
+
83
+ # ジョブ名一覧ファイルをもとに対象のJenkinsからジョブを削除する
84
+ # 破壊的なメソッドなのでdryrunがデフォルト
85
+ def delete(target, joblist, dryrun=true)
86
+ raise "target file unreadable" unless File.readable? job_list
87
+ login(target) if auth_required?(target)
88
+ puts "!!dryrun mode!!" if dryrun
89
+ File.read(job_list).each_line do |name|
90
+ @agent.post("#{target}/job/#{url_encode(name.strip!)}/doDelete") unless dryrun
91
+ puts "#{name} deleted"
92
+ end
93
+ end
94
+
95
+ # ジョブ名一覧ファイルを元に、Jenkins AからJenkins BへJobをクローンする
96
+ def clone(from, to, job_list)
97
+ raise "target file unreadable" unless File.readable? job_list
98
+
99
+ login(from) if auth_required?(from)
100
+ login(to) if auth_required?(to)
101
+ File.read(job_list).each_line do |name|
102
+ @agent.get("#{from}/job/#{url_encode(name.strip!)}/config.xml") do |res|
103
+ create_job(to, name, res.body)
104
+ end
105
+ end
106
+ end
107
+
108
+ # プラグイン一覧ファイルを元にJenkinsにプラグインをインストールする
109
+ # プラグイン一覧ファイルの内容はインストール可能なプラグインページのチェックボックスのname属性値
110
+ def install(target, plugin_list)
111
+ login(target) if auth_required?(target)
112
+ form = @agent.get("#{target}/pluginManager/available").form_with(:action => 'install')
113
+ File.read(plugin_list).each_line do |plugin|
114
+ form.checkbox_with(:name => plugin.strip!) do |checkbox|
115
+ puts "trying to mark: #{plugin}"
116
+ if checkbox != nil
117
+ puts " => #{plugin} marked as an install target."
118
+ checkbox.check
119
+ end
120
+ end
121
+ end
122
+ form.submit
123
+ puts "plugins installed, please restart your butler after installation done."
124
+ puts "see #{target}/updateCenter/ for instalation progress."
125
+ end
126
+
127
+ def backup_config(target, dest)
128
+ list(target).each do |name|
129
+ FileUtils.mkdir_p(dest) unless File.exists?(dest)
130
+ file_to_write = "#{dest}/#{name}.xml"
131
+ File.open(file_to_write, "w") do |f|
132
+ f.write @agent.get_file("#{target}/job/#{url_encode(name)}/config.xml")
133
+ end
134
+ puts "backed up successfully: #{file_to_write}"
135
+ end
136
+ end
137
+
138
+ def create_jobs(target, config_dir)
139
+ login(target) if auth_required?(target)
140
+ Dir.glob("#{config_dir}/*.xml").each do |file_name|
141
+ job_name = File.split(file_name)[1].sub(/\.xml$/, "")
142
+ create_job(target, job_name, File.read(file_name))
143
+ end
144
+ end
145
+
146
+ def create_job(target, name, config)
147
+ create_api = "#{target}/createItem?name=#{url_encode(name)}"
148
+ @agent.post(create_api, config, {'Content-Type'=>'text/xml'})
149
+ puts "#{name} successfully created at #{target}"
150
+
151
+ rescue Mechanize::ResponseCodeError => e
152
+ case e.response_code
153
+ when '400'
154
+ puts "#{name} already exists, so just skiped."
155
+ else
156
+ raise e
157
+ end
158
+ end
159
+
160
+ def auth_required?(target)
161
+ ui = HighLine.new
162
+ prompt = "Need login for #{target}?[y|n]: "
163
+ ui.ask(prompt) do |q|
164
+ q.overwrite = false
165
+ q.default = "n"
166
+ q.validate = /y|n|\n/i
167
+ q.responses[:not_valid] = prompt
168
+ end == "y"
169
+ end
170
+
171
+ def login(target)
172
+ ui = HighLine.new
173
+ user = ui.ask("User: ")
174
+ pass = ui.ask("Password: ") { |q| q.echo = false }
175
+
176
+ puts "logging in... => #{target}"
177
+ @agent.get("#{target}/login") do |page|
178
+ page.form_with(:name => 'login') {|form|
179
+ form['j_username'] = user
180
+ form['j_password'] = pass
181
+ }.submit
182
+ end
183
+ end
184
+
185
+ private :login, :auth_required?
186
+
187
+ end
188
+
189
+ end
@@ -0,0 +1,14 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'scanf'
3
+
4
+ module Domo
5
+
6
+ class Version
7
+
8
+ def self.to_s
9
+ File.read(File.expand_path("../../../VERSION", __FILE__))
10
+ end
11
+
12
+ end
13
+
14
+ end
Binary file
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: domo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - cynipe
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-06-11 00:00:00.000000000 +09:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: bundler
17
+ requirement: &2165237860 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *2165237860
26
+ - !ruby/object:Gem::Dependency
27
+ name: mechanize
28
+ requirement: &2165237420 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: *2165237420
37
+ - !ruby/object:Gem::Dependency
38
+ name: nokogiri
39
+ requirement: &2165237000 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ type: :runtime
46
+ prerelease: false
47
+ version_requirements: *2165237000
48
+ - !ruby/object:Gem::Dependency
49
+ name: highline
50
+ requirement: &2165236580 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :runtime
57
+ prerelease: false
58
+ version_requirements: *2165236580
59
+ - !ruby/object:Gem::Dependency
60
+ name: thor
61
+ requirement: &2165252520 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ type: :runtime
68
+ prerelease: false
69
+ version_requirements: *2165252520
70
+ description:
71
+ email:
72
+ - cynipe@cynipe.net
73
+ executables:
74
+ - domo
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - bin/domo
79
+ - domo.gemspec
80
+ - Gemfile
81
+ - Gemfile.lock
82
+ - lib/domo/cli.rb
83
+ - lib/domo/core.rb
84
+ - lib/domo/version.rb
85
+ - lib/domo.rb
86
+ - LICENCE.txt
87
+ - pkg/domo-0.0.1.gem
88
+ - Rakefile
89
+ - README.rst
90
+ - VERSION
91
+ has_rdoc: true
92
+ homepage:
93
+ licenses: []
94
+ post_install_message:
95
+ rdoc_options: []
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ requirements: []
111
+ rubyforge_project:
112
+ rubygems_version: 1.6.2
113
+ signing_key:
114
+ specification_version: 3
115
+ summary: Domo is the super-duper simple client for Jenkins
116
+ test_files: []