boxen 3.0.0.beta1 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +0 -1
  3. data/README.md +1 -1
  4. data/boxen.gemspec +13 -13
  5. data/lib/boxen/check.rb +39 -8
  6. data/lib/boxen/cli.rb +45 -19
  7. data/lib/boxen/config.rb +61 -43
  8. data/lib/boxen/flags.rb +282 -0
  9. data/lib/boxen/hook.rb +8 -15
  10. data/lib/boxen/hook/github_issue.rb +120 -0
  11. data/lib/boxen/hook/web.rb +56 -0
  12. data/lib/boxen/keychain.rb +1 -1
  13. data/lib/boxen/postflight/env.rb +1 -1
  14. data/lib/boxen/preflight.rb +7 -4
  15. data/lib/boxen/preflight/creds.rb +47 -8
  16. data/lib/boxen/preflight/identity.rb +0 -2
  17. data/lib/boxen/preflight/os.rb +6 -2
  18. data/lib/boxen/puppeteer.rb +121 -0
  19. data/lib/boxen/runner.rb +149 -0
  20. data/script/bootstrap +1 -1
  21. data/script/tests +0 -1
  22. data/test/boxen/test.rb +1 -1
  23. data/test/boxen_check_test.rb +55 -0
  24. data/test/boxen_cli_test.rb +31 -8
  25. data/test/boxen_config_test.rb +31 -1
  26. data/test/boxen_directories_test.rb +4 -4
  27. data/test/boxen_flags_test.rb +217 -0
  28. data/test/{postflight/boxen_postflight_github_issue_test.rb → boxen_hook_github_issue_test.rb} +82 -72
  29. data/test/{postflight/boxen_postflight_web_hook_test.rb → boxen_hook_web_test.rb} +11 -12
  30. data/test/{postflight/boxen_postflight_active_test.rb → boxen_postflight_active_test.rb} +3 -3
  31. data/test/{postflight/boxen_postflight_env_test.rb → boxen_postflight_env_test.rb} +0 -0
  32. data/test/boxen_preflight_creds_test.rb +177 -0
  33. data/test/{preflight/boxen_preflight_etc_my_cnf_test.rb → boxen_preflight_etc_my_cnf_test.rb} +1 -1
  34. data/test/{preflight/boxen_preflight_rvm_test.rb → boxen_preflight_rvm_test.rb} +1 -1
  35. data/test/boxen_puppeteer_test.rb +101 -0
  36. data/test/boxen_runner_test.rb +171 -0
  37. metadata +172 -251
  38. data/lib/boxen/command.rb +0 -142
  39. data/lib/boxen/command/help.rb +0 -40
  40. data/lib/boxen/command/preflight.rb +0 -38
  41. data/lib/boxen/command/project.rb +0 -49
  42. data/lib/boxen/command/project/install.rb +0 -33
  43. data/lib/boxen/command/run.rb +0 -199
  44. data/lib/boxen/command/service.rb +0 -61
  45. data/lib/boxen/command/service/disable.rb +0 -15
  46. data/lib/boxen/command/service/enable.rb +0 -15
  47. data/lib/boxen/command/service/restart.rb +0 -24
  48. data/lib/boxen/command/version.rb +0 -29
  49. data/lib/boxen/command_status.rb +0 -15
  50. data/lib/boxen/postflight/github_issue.rb +0 -124
  51. data/lib/boxen/postflight/hooks.rb +0 -16
  52. data/lib/boxen/postflight/web_hook.rb +0 -63
  53. data/lib/boxen/preflight/facts.rb +0 -36
  54. data/lib/boxen/preflight/homebrew.rb +0 -13
  55. data/lib/boxen/preflight/offline.rb +0 -33
  56. data/lib/boxen/preflight/update.rb +0 -109
  57. data/lib/boxen/util/logging.rb +0 -59
  58. data/lib/boxen/version.rb +0 -3
  59. data/lib/system_timer.rb +0 -13
  60. data/test/boxen_command_test.rb +0 -93
  61. data/test/boxen_hook_test.rb +0 -25
  62. data/test/command/help_test.rb +0 -49
  63. data/test/command/project/install_test.rb +0 -34
  64. data/test/command/project_test.rb +0 -32
  65. data/test/command/run_test.rb +0 -21
  66. data/test/command/service/disable_test.rb +0 -49
  67. data/test/command/service/enable_test.rb +0 -49
  68. data/test/command/service/restart_test.rb +0 -53
  69. data/test/command/service_test.rb +0 -55
  70. data/test/command/version_test.rb +0 -15
  71. data/test/preflight/boxen_preflight_creds_test.rb +0 -82
  72. data/test/preflight/boxen_preflight_homebrew_test.rb +0 -10
  73. data/test/system_timer.rb +0 -10
@@ -0,0 +1,282 @@
1
+ require "optparse"
2
+ require "boxen/error"
3
+
4
+ module Boxen
5
+
6
+ # Various flags and settings parsed from the command line. See
7
+ # Setup::Configuration for more info.
8
+
9
+ class Flags
10
+
11
+ attr_reader :args
12
+ attr_reader :homedir
13
+ attr_reader :logfile
14
+ attr_reader :login
15
+ attr_reader :token
16
+ attr_reader :srcdir
17
+ attr_reader :user
18
+
19
+ attr_reader :disable_service
20
+ attr_reader :enable_service
21
+ attr_reader :restart_service
22
+
23
+ # Create a new instance, optionally providing CLI `args` to
24
+ # parse immediately.
25
+
26
+ def initialize(*args)
27
+ @args = []
28
+ @debug = false
29
+ @env = false
30
+ @fde = true
31
+ @help = false
32
+ @pretend = false
33
+ @profile = false
34
+ @report = false
35
+ @graph = false
36
+ @projects = false
37
+ @stealth = false
38
+ @disable_service = false
39
+ @enable_service = false
40
+ @restart_service = false
41
+ @disable_services = false
42
+ @enable_services = false
43
+ @restart_services = false
44
+ @list_services = false
45
+ @color = true
46
+
47
+ @options = OptionParser.new do |o|
48
+ o.banner = "Usage: #{File.basename $0} [options] [projects...]\n\n"
49
+
50
+ o.on "--debug", "Be really verbose." do
51
+ @debug = true
52
+ end
53
+
54
+ o.on "--pretend", "--noop", "Don't make changes." do
55
+ @pretend = true
56
+ end
57
+
58
+ o.on "--report", "Enable puppet reports." do
59
+ @report = true
60
+ end
61
+
62
+ o.on "--graph", "Enable generation of dependency graphs." do
63
+ @graph = true
64
+ end
65
+
66
+ o.on "--env", "Show useful environment variables." do
67
+ @env = true
68
+ end
69
+
70
+ o.on "--help", "-h", "-?", "Show help." do
71
+ @help = true
72
+ end
73
+
74
+ o.on "--disable-service SERVICE", "Disable a Boxen service." do |service|
75
+ @disable_service = service
76
+ end
77
+
78
+ o.on "--enable-service SERVICE", "Enable a Boxen service." do |service|
79
+ @enable_service = service
80
+ end
81
+
82
+ o.on "--restart-service SERVICE", "Restart a Boxen service." do |service|
83
+ @restart_service = service
84
+ end
85
+
86
+ o.on "--disable-services", "Disable all Boxen services." do
87
+ @disable_services = true
88
+ end
89
+
90
+ o.on "--enable-services", "Enable all Boxen services." do
91
+ @enable_services = true
92
+ end
93
+
94
+ o.on "--restart-services", "Restart all Boxen services." do
95
+ @restart_services = true
96
+ end
97
+
98
+ o.on "--list-services", "List Boxen services." do
99
+ @list_services = true
100
+ end
101
+
102
+ o.on "--homedir DIR", "Boxen's home directory." do |homedir|
103
+ @homedir = homedir
104
+ end
105
+
106
+ o.on "--logfile DIR", "Boxen's log file." do |logfile|
107
+ @logfile = logfile
108
+ end
109
+
110
+ o.on "--login LOGIN", "Your GitHub login." do |login|
111
+ @login = login
112
+ end
113
+
114
+ o.on "--no-fde", "Don't require full disk encryption." do
115
+ @fde = false
116
+ end
117
+
118
+ # --no-pull is used before options are parsed, but consumed here.
119
+
120
+ o.on "--no-pull", "Don't try to update code before applying."
121
+
122
+ o.on "--no-issue", "--stealth", "Don't open an issue on failure." do
123
+ @stealth = true
124
+ end
125
+
126
+ o.on "--token TOKEN", "Your GitHub OAuth token." do |token|
127
+ @token = token
128
+ end
129
+
130
+ o.on "--profile", "Profile the Puppet run." do
131
+ @profile = true
132
+ end
133
+
134
+ o.on "--future-parser", "Enable the Puppet future parser" do
135
+ @future_parser = true
136
+ end
137
+
138
+ o.on "--projects", "Show available projects." do
139
+ @projects = true
140
+ end
141
+
142
+ o.on "--srcdir DIR", "The directory where repos live." do |srcdir|
143
+ @srcdir = srcdir
144
+ end
145
+
146
+ o.on "--user USER", "Your local user." do |user|
147
+ @user = user
148
+ end
149
+
150
+ o.on "--no-color", "Disable colors." do
151
+ @color = false
152
+ end
153
+ end
154
+
155
+ parse args.flatten.compact
156
+ end
157
+
158
+ # Apply these flags to `config`. Returns `config`.
159
+
160
+ def apply(config)
161
+ config.debug = debug?
162
+ config.fde = fde? if config.fde?
163
+ config.homedir = homedir if homedir
164
+ config.logfile = logfile if logfile
165
+ config.login = login if login
166
+ config.token = token if token
167
+ config.pretend = pretend?
168
+ config.profile = profile?
169
+ config.future_parser = future_parser?
170
+ config.report = report?
171
+ config.graph = graph?
172
+ config.srcdir = srcdir if srcdir
173
+ config.stealth = stealth?
174
+ config.user = user if user
175
+ config.color = color?
176
+
177
+ config
178
+ end
179
+
180
+ def debug?
181
+ @debug
182
+ end
183
+
184
+ def env?
185
+ @env
186
+ end
187
+
188
+ def fde?
189
+ @fde
190
+ end
191
+
192
+ def help?
193
+ @help
194
+ end
195
+
196
+ def disable_services?
197
+ @disable_services
198
+ end
199
+
200
+ def enable_services?
201
+ @enable_services
202
+ end
203
+
204
+ def disable_service?
205
+ @disable_service
206
+ end
207
+
208
+ def enable_service?
209
+ @enable_service
210
+ end
211
+
212
+ def restart_service?
213
+ @restart_service
214
+ end
215
+
216
+ def restart_services?
217
+ @restart_services
218
+ end
219
+
220
+ def list_services?
221
+ @list_services
222
+ end
223
+
224
+ def run?
225
+ !(
226
+ list_services? ||
227
+ restart_services? || restart_service? ||
228
+ enable_services? || enable_service? ||
229
+ disable_services? || disable_service? ||
230
+ help?
231
+ )
232
+ end
233
+
234
+ # Parse `args` as an array of CLI argument Strings. Raises
235
+ # Boxen::Error if anything goes wrong. Returns `self`.
236
+
237
+ def parse(*args)
238
+ @args = @options.parse! args.flatten.compact.map(&:to_s)
239
+
240
+ self
241
+
242
+ rescue OptionParser::MissingArgument, OptionParser::InvalidOption => e
243
+ raise Boxen::Error, "#{e.message}\n#@options"
244
+ end
245
+
246
+ def pretend?
247
+ @pretend
248
+ end
249
+
250
+ def profile?
251
+ @profile
252
+ end
253
+
254
+ def future_parser?
255
+ @future_parser
256
+ end
257
+
258
+ def report?
259
+ @report
260
+ end
261
+
262
+ def graph?
263
+ @graph
264
+ end
265
+
266
+ def projects?
267
+ @projects
268
+ end
269
+
270
+ def stealth?
271
+ @stealth
272
+ end
273
+
274
+ def color?
275
+ @color
276
+ end
277
+
278
+ def to_s
279
+ @options.to_s
280
+ end
281
+ end
282
+ end
@@ -2,6 +2,7 @@ module Boxen
2
2
  class Hook
3
3
  attr_reader :config
4
4
  attr_reader :checkout
5
+ attr_reader :puppet
5
6
  attr_reader :result
6
7
 
7
8
  @hooks = []
@@ -15,24 +16,13 @@ module Boxen
15
16
  end
16
17
 
17
18
  def self.all
18
- @hooks
19
+ @hooks || []
19
20
  end
20
21
 
21
- def self.register(klass)
22
- unless defined? @hooks
23
- @hooks = []
24
- end
25
-
26
- @hooks << klass
27
- end
28
-
29
- def self.run
30
- @hooks.each { |hook| hook.new(nil, nil, nil).run }
31
- end
32
-
33
- def initialize(config, checkout, result)
22
+ def initialize(config, checkout, puppet, result)
34
23
  @config = config
35
24
  @checkout = checkout
25
+ @puppet = puppet
36
26
  @result = result
37
27
  end
38
28
 
@@ -44,7 +34,7 @@ module Boxen
44
34
  end
45
35
 
46
36
  def perform?
47
- enabled?
37
+ false
48
38
  end
49
39
 
50
40
  def run
@@ -52,3 +42,6 @@ module Boxen
52
42
  end
53
43
  end
54
44
  end
45
+
46
+ require "boxen/hook/github_issue"
47
+ require "boxen/hook/web"
@@ -0,0 +1,120 @@
1
+ require "boxen/hook"
2
+
3
+ module Boxen
4
+ class Hook
5
+ class GitHubIssue < Hook
6
+ def perform?
7
+ enabled? &&
8
+ !config.stealth? && !config.pretend? &&
9
+ !config.login.to_s.empty? &&
10
+ checkout.master?
11
+ end
12
+
13
+ def call
14
+ if result.success?
15
+ close_failures
16
+ else
17
+ warn "Sorry! Creating an issue on #{config.reponame}."
18
+ record_failure
19
+ end
20
+ end
21
+
22
+ def compare_url
23
+ return unless config.reponame
24
+ "#{config.ghurl}/#{config.reponame}/compare/#{checkout.sha}...master"
25
+ end
26
+
27
+ def hostname
28
+ `hostname`.strip
29
+ end
30
+
31
+ def os
32
+ `sw_vers -productVersion`.strip
33
+ end
34
+
35
+ def shell
36
+ ENV["SHELL"]
37
+ end
38
+
39
+ def log
40
+ File.read config.logfile
41
+ end
42
+
43
+ def record_failure
44
+ return unless issues?
45
+
46
+ title = "Failed for #{config.user}"
47
+ config.api.create_issue(config.reponame, title, failure_details,
48
+ :labels => [failure_label])
49
+ end
50
+
51
+ def close_failures
52
+ return unless issues?
53
+
54
+ comment = "Succeeded at version #{checkout.sha}."
55
+ failures.each do |issue|
56
+ config.api.add_comment(config.reponame, issue.number, comment)
57
+ config.api.close_issue(config.reponame, issue.number)
58
+ end
59
+ end
60
+
61
+ def failures
62
+ return [] unless issues?
63
+
64
+ issues = config.api.list_issues(config.reponame, :state => 'open',
65
+ :labels => failure_label, :creator => config.login)
66
+ issues.reject! {|i| i.labels.collect(&:name).include?(ongoing_label)}
67
+ issues
68
+ end
69
+
70
+ def failure_details
71
+ body = ''
72
+ body << "Running on `#{hostname}` (OS X #{os}) under `#{shell}`, "
73
+ body << "version #{checkout.sha} ([compare to master](#{compare_url}))."
74
+ body << "\n\n"
75
+
76
+ if checkout.dirty?
77
+ body << "### Changes"
78
+ body << "\n\n"
79
+ body << "```\n#{checkout.changes}\n```"
80
+ body << "\n\n"
81
+ end
82
+
83
+ body << "### Puppet Command"
84
+ body << "\n\n"
85
+ body << "```\n#{puppet.command.join(' ')}\n```"
86
+ body << "\n\n"
87
+
88
+ body << "### Output (from #{config.logfile})"
89
+ body << "\n\n"
90
+ body << "```\n#{log}\n```\n"
91
+
92
+ body
93
+ end
94
+
95
+ def failure_label
96
+ @failure_label ||= 'failure'
97
+ end
98
+ attr_writer :failure_label
99
+
100
+ def ongoing_label
101
+ @ongoing_label ||= 'ongoing'
102
+ end
103
+ attr_writer :ongoing_label
104
+
105
+ def issues?
106
+ return unless config.reponame
107
+ return if config.reponame == 'boxen/our-boxen'
108
+
109
+ config.api.repository(config.reponame).has_issues
110
+ end
111
+
112
+ private
113
+ def required_environment_variables
114
+ ['BOXEN_ISSUES_ENABLED']
115
+ end
116
+ end
117
+ end
118
+ end
119
+
120
+ Boxen::Hook.register Boxen::Hook::GitHubIssue