boxen23 3.1.3a

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.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.travis.yml +6 -0
  4. data/Gemfile +2 -0
  5. data/LICENSE +20 -0
  6. data/README.md +50 -0
  7. data/boxen.gemspec +29 -0
  8. data/lib/boxen/check.rb +72 -0
  9. data/lib/boxen/checkout.rb +25 -0
  10. data/lib/boxen/cli.rb +61 -0
  11. data/lib/boxen/config.rb +345 -0
  12. data/lib/boxen/error.rb +4 -0
  13. data/lib/boxen/flags.rb +291 -0
  14. data/lib/boxen/hook.rb +47 -0
  15. data/lib/boxen/hook/github_issue.rb +120 -0
  16. data/lib/boxen/hook/web.rb +56 -0
  17. data/lib/boxen/keychain.rb +61 -0
  18. data/lib/boxen/postflight.rb +13 -0
  19. data/lib/boxen/postflight/active.rb +16 -0
  20. data/lib/boxen/postflight/env.rb +29 -0
  21. data/lib/boxen/preflight.rb +13 -0
  22. data/lib/boxen/preflight/creds.rb +149 -0
  23. data/lib/boxen/preflight/directories.rb +32 -0
  24. data/lib/boxen/preflight/etc_my_cnf.rb +12 -0
  25. data/lib/boxen/preflight/identity.rb +16 -0
  26. data/lib/boxen/preflight/os.rb +33 -0
  27. data/lib/boxen/preflight/rbenv.rb +12 -0
  28. data/lib/boxen/preflight/rvm.rb +12 -0
  29. data/lib/boxen/project.rb +20 -0
  30. data/lib/boxen/puppeteer.rb +122 -0
  31. data/lib/boxen/runner.rb +149 -0
  32. data/lib/boxen/service.rb +58 -0
  33. data/lib/boxen/util.rb +19 -0
  34. data/lib/facter/boxen.rb +34 -0
  35. data/script/Boxen +0 -0
  36. data/script/bootstrap +7 -0
  37. data/script/build-keychain-helper +6 -0
  38. data/script/release +38 -0
  39. data/script/tests +10 -0
  40. data/src/keychain-helper.c +85 -0
  41. data/test/boxen/test.rb +7 -0
  42. data/test/boxen_check_test.rb +55 -0
  43. data/test/boxen_checkout_test.rb +42 -0
  44. data/test/boxen_cli_test.rb +39 -0
  45. data/test/boxen_config_test.rb +400 -0
  46. data/test/boxen_directories_test.rb +40 -0
  47. data/test/boxen_flags_test.rb +223 -0
  48. data/test/boxen_hook_github_issue_test.rb +294 -0
  49. data/test/boxen_hook_web_test.rb +58 -0
  50. data/test/boxen_keychain_test.rb +21 -0
  51. data/test/boxen_postflight_active_test.rb +29 -0
  52. data/test/boxen_postflight_env_test.rb +6 -0
  53. data/test/boxen_preflight_creds_test.rb +177 -0
  54. data/test/boxen_preflight_etc_my_cnf_test.rb +10 -0
  55. data/test/boxen_preflight_rvm_test.rb +10 -0
  56. data/test/boxen_project_test.rb +14 -0
  57. data/test/boxen_puppeteer_test.rb +101 -0
  58. data/test/boxen_runner_test.rb +171 -0
  59. data/test/boxen_service_test.rb +39 -0
  60. data/test/boxen_util_test.rb +21 -0
  61. data/test/fixtures/repo/modules/projects/manifests/first-project.pp +0 -0
  62. data/test/fixtures/repo/modules/projects/manifests/second-project.pp +0 -0
  63. metadata +257 -0
@@ -0,0 +1,4 @@
1
+ module Boxen
2
+ class Error < RuntimeError
3
+ end
4
+ end
@@ -0,0 +1,291 @@
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 "--skip-puppetfile", "Skip installing librarian-puppet" do
139
+ @skip_puppetfile = true
140
+ end
141
+
142
+ o.on "--projects", "Show available projects." do
143
+ @projects = true
144
+ end
145
+
146
+ o.on "--srcdir DIR", "The directory where repos live." do |srcdir|
147
+ @srcdir = srcdir
148
+ end
149
+
150
+ o.on "--user USER", "Your local user." do |user|
151
+ @user = user
152
+ end
153
+
154
+ o.on "--no-color", "Disable colors." do
155
+ @color = false
156
+ end
157
+ end
158
+
159
+ parse args.flatten.compact
160
+ end
161
+
162
+ # Apply these flags to `config`. Returns `config`.
163
+
164
+ def apply(config)
165
+ config.debug = debug?
166
+ config.fde = fde? if config.fde?
167
+ config.homedir = homedir if homedir
168
+ config.logfile = logfile if logfile
169
+ config.login = login if login
170
+ config.token = token if token
171
+ config.pretend = pretend?
172
+ config.profile = profile?
173
+ config.future_parser = future_parser?
174
+ config.skip_puppetfile = skip_puppetfile?
175
+ config.report = report?
176
+ config.graph = graph?
177
+ config.srcdir = srcdir if srcdir
178
+ config.stealth = stealth?
179
+ config.user = user if user
180
+ config.color = color?
181
+
182
+ config
183
+ end
184
+
185
+ def debug?
186
+ @debug
187
+ end
188
+
189
+ def env?
190
+ @env
191
+ end
192
+
193
+ def fde?
194
+ @fde
195
+ end
196
+
197
+ def help?
198
+ @help
199
+ end
200
+
201
+ def disable_services?
202
+ @disable_services
203
+ end
204
+
205
+ def enable_services?
206
+ @enable_services
207
+ end
208
+
209
+ def disable_service?
210
+ @disable_service
211
+ end
212
+
213
+ def enable_service?
214
+ @enable_service
215
+ end
216
+
217
+ def restart_service?
218
+ @restart_service
219
+ end
220
+
221
+ def restart_services?
222
+ @restart_services
223
+ end
224
+
225
+ def list_services?
226
+ @list_services
227
+ end
228
+
229
+ def run?
230
+ !(
231
+ list_services? ||
232
+ restart_services? || restart_service? ||
233
+ enable_services? || enable_service? ||
234
+ disable_services? || disable_service? ||
235
+ help?
236
+ )
237
+ end
238
+
239
+ # Parse `args` as an array of CLI argument Strings. Raises
240
+ # Boxen::Error if anything goes wrong. Returns `self`.
241
+
242
+ def parse(*args)
243
+ @args = @options.parse! args.flatten.compact.map(&:to_s)
244
+
245
+ self
246
+
247
+ rescue OptionParser::MissingArgument, OptionParser::InvalidOption => e
248
+ raise Boxen::Error, "#{e.message}\n#@options"
249
+ end
250
+
251
+ def pretend?
252
+ @pretend
253
+ end
254
+
255
+ def profile?
256
+ @profile
257
+ end
258
+
259
+ def future_parser?
260
+ @future_parser
261
+ end
262
+
263
+ def skip_puppetfile?
264
+ @skip_puppetfile
265
+ end
266
+
267
+ def report?
268
+ @report
269
+ end
270
+
271
+ def graph?
272
+ @graph
273
+ end
274
+
275
+ def projects?
276
+ @projects
277
+ end
278
+
279
+ def stealth?
280
+ @stealth
281
+ end
282
+
283
+ def color?
284
+ @color
285
+ end
286
+
287
+ def to_s
288
+ @options.to_s
289
+ end
290
+ end
291
+ end
data/lib/boxen/hook.rb ADDED
@@ -0,0 +1,47 @@
1
+ module Boxen
2
+ class Hook
3
+ attr_reader :config
4
+ attr_reader :checkout
5
+ attr_reader :puppet
6
+ attr_reader :result
7
+
8
+ @hooks = []
9
+
10
+ def self.register(hook)
11
+ @hooks << hook
12
+ end
13
+
14
+ def self.unregister(hook)
15
+ @hooks.delete hook
16
+ end
17
+
18
+ def self.all
19
+ @hooks || []
20
+ end
21
+
22
+ def initialize(config, checkout, puppet, result)
23
+ @config = config
24
+ @checkout = checkout
25
+ @puppet = puppet
26
+ @result = result
27
+ end
28
+
29
+ def enabled?
30
+ required_vars = Array(required_environment_variables)
31
+ required_vars.any? && required_vars.all? do |var|
32
+ ENV[var] && !ENV[var].empty?
33
+ end
34
+ end
35
+
36
+ def perform?
37
+ false
38
+ end
39
+
40
+ def run
41
+ call if perform?
42
+ end
43
+ end
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