boxen 2.9.0 → 3.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- data/boxen.gemspec +12 -12
- data/lib/boxen/check.rb +8 -39
- data/lib/boxen/cli.rb +19 -45
- data/lib/boxen/command.rb +142 -0
- data/lib/boxen/command/help.rb +40 -0
- data/lib/boxen/command/preflight.rb +38 -0
- data/lib/boxen/command/project.rb +49 -0
- data/lib/boxen/command/project/install.rb +33 -0
- data/lib/boxen/command/run.rb +199 -0
- data/lib/boxen/command/service.rb +61 -0
- data/lib/boxen/command/service/disable.rb +15 -0
- data/lib/boxen/command/service/enable.rb +15 -0
- data/lib/boxen/command/service/restart.rb +24 -0
- data/lib/boxen/command/version.rb +29 -0
- data/lib/boxen/command_status.rb +15 -0
- data/lib/boxen/config.rb +43 -61
- data/lib/boxen/hook.rb +15 -8
- data/lib/boxen/keychain.rb +1 -1
- data/lib/boxen/postflight/env.rb +1 -1
- data/lib/boxen/postflight/github_issue.rb +124 -0
- data/lib/boxen/postflight/hooks.rb +16 -0
- data/lib/boxen/postflight/web_hook.rb +63 -0
- data/lib/boxen/preflight.rb +4 -7
- data/lib/boxen/preflight/creds.rb +8 -47
- data/lib/boxen/preflight/facts.rb +36 -0
- data/lib/boxen/preflight/homebrew.rb +13 -0
- data/lib/boxen/preflight/identity.rb +2 -0
- data/lib/boxen/preflight/offline.rb +33 -0
- data/lib/boxen/preflight/os.rb +1 -1
- data/lib/boxen/preflight/update.rb +109 -0
- data/lib/boxen/util/logging.rb +59 -0
- data/lib/boxen/version.rb +3 -0
- data/script/bootstrap +1 -1
- data/script/tests +1 -0
- data/test/boxen/test.rb +1 -1
- data/test/boxen_cli_test.rb +8 -31
- data/test/boxen_command_test.rb +93 -0
- data/test/boxen_config_test.rb +1 -31
- data/test/boxen_directories_test.rb +4 -4
- data/test/boxen_hook_test.rb +25 -0
- data/test/command/help_test.rb +49 -0
- data/test/command/project/install_test.rb +34 -0
- data/test/command/project_test.rb +32 -0
- data/test/command/run_test.rb +21 -0
- data/test/command/service/disable_test.rb +49 -0
- data/test/command/service/enable_test.rb +49 -0
- data/test/command/service/restart_test.rb +53 -0
- data/test/command/service_test.rb +55 -0
- data/test/command/version_test.rb +15 -0
- data/test/{boxen_postflight_active_test.rb → postflight/boxen_postflight_active_test.rb} +3 -3
- data/test/{boxen_postflight_env_test.rb → postflight/boxen_postflight_env_test.rb} +0 -0
- data/test/{boxen_hook_github_issue_test.rb → postflight/boxen_postflight_github_issue_test.rb} +72 -82
- data/test/{boxen_hook_web_test.rb → postflight/boxen_postflight_web_hook_test.rb} +12 -11
- data/test/preflight/boxen_preflight_creds_test.rb +82 -0
- data/test/{boxen_preflight_etc_my_cnf_test.rb → preflight/boxen_preflight_etc_my_cnf_test.rb} +1 -1
- data/test/preflight/boxen_preflight_homebrew_test.rb +10 -0
- data/test/{boxen_preflight_rvm_test.rb → preflight/boxen_preflight_rvm_test.rb} +1 -1
- metadata +247 -171
- checksums.yaml +0 -7
- data/lib/boxen/flags.rb +0 -282
- data/lib/boxen/hook/github_issue.rb +0 -120
- data/lib/boxen/hook/web.rb +0 -56
- data/lib/boxen/puppeteer.rb +0 -121
- data/lib/boxen/runner.rb +0 -149
- data/test/boxen_check_test.rb +0 -55
- data/test/boxen_flags_test.rb +0 -217
- data/test/boxen_preflight_creds_test.rb +0 -177
- data/test/boxen_puppeteer_test.rb +0 -101
- data/test/boxen_runner_test.rb +0 -171
data/boxen.gemspec
CHANGED
@@ -1,30 +1,30 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
|
3
|
+
$:.unshift File.expand_path("../lib", __FILE__)
|
4
|
+
require "boxen/version"
|
5
|
+
|
3
6
|
Gem::Specification.new do |gem|
|
4
7
|
gem.name = "boxen"
|
5
|
-
gem.version =
|
6
|
-
|
7
|
-
|
8
|
-
# to where it is today.
|
9
|
-
gem.authors = ["Jacob Bednarz"]
|
10
|
-
gem.email = ["jacob.bednarz@gmail.com"]
|
8
|
+
gem.version = Boxen::VERSION
|
9
|
+
gem.authors = ["John Barnette", "Will Farrington", "David Goodlad"]
|
10
|
+
gem.email = ["jbarnette@github.com", "wfarr@github.com", "dgoodlad@github.com"]
|
11
11
|
gem.description = "Manage Mac development boxes with love (and Puppet)."
|
12
12
|
gem.summary = "You know, for laptops and stuff."
|
13
13
|
gem.homepage = "https://github.com/boxen/boxen"
|
14
|
-
gem.license = 'MIT'
|
15
14
|
|
16
|
-
gem.files = `git ls-files`.split $/
|
17
|
-
gem.test_files = gem.files.grep
|
15
|
+
gem.files = `git ls-files`.split( $/)
|
16
|
+
gem.test_files = gem.files.grep(/^test/)
|
17
|
+
gem.executables = gem.files.grep(/^bin/).map { |bin| File.basename(bin) }
|
18
18
|
gem.require_paths = ["lib"]
|
19
19
|
|
20
20
|
gem.add_dependency "ansi", "~> 1.4"
|
21
21
|
gem.add_dependency "hiera", "~> 1.0"
|
22
|
-
gem.add_dependency "highline", "~> 1.6
|
22
|
+
gem.add_dependency "highline", "~> 1.6"
|
23
23
|
gem.add_dependency "json_pure", [">= 1.7.7", "< 2.0"]
|
24
24
|
gem.add_dependency "librarian-puppet", "~> 1.0.0"
|
25
25
|
gem.add_dependency "octokit", "~> 2.7", ">= 2.7.1"
|
26
|
-
gem.add_dependency "puppet", "~> 3.
|
26
|
+
gem.add_dependency "puppet", "~> 3.0"
|
27
27
|
|
28
|
-
gem.add_development_dependency "minitest", "
|
28
|
+
gem.add_development_dependency "minitest", "~> 5.0" # pinned for mocha
|
29
29
|
gem.add_development_dependency "mocha", "~> 0.13"
|
30
30
|
end
|
data/lib/boxen/check.rb
CHANGED
@@ -1,20 +1,11 @@
|
|
1
|
-
require "
|
1
|
+
require "boxen/util/logging"
|
2
2
|
|
3
3
|
module Boxen
|
4
4
|
|
5
5
|
# The superclass for preflight and postflight sanity checks.
|
6
6
|
|
7
7
|
class Check
|
8
|
-
|
9
|
-
# A collection of preflight instances for `config`. An instance is
|
10
|
-
# created for every constant under `self` that's also a
|
11
|
-
# subclass of `self`.
|
12
|
-
|
13
|
-
def self.checks(config)
|
14
|
-
constants.map { |n| const_get n }.
|
15
|
-
select { |c| c < self }.
|
16
|
-
map { |c| c.new config }
|
17
|
-
end
|
8
|
+
include Boxen::Util::Logging
|
18
9
|
|
19
10
|
# Search `dir` and load all Ruby files under it.
|
20
11
|
|
@@ -22,16 +13,12 @@ module Boxen
|
|
22
13
|
Dir["#{dir}/*.rb"].sort.each { |f| load f }
|
23
14
|
end
|
24
15
|
|
25
|
-
# Check each instance against `config`.
|
26
|
-
|
27
|
-
def self.run(config)
|
28
|
-
checks(config).each { |check| check.run unless check.ok? }
|
29
|
-
end
|
30
|
-
|
31
16
|
attr_reader :config
|
17
|
+
attr_reader :command
|
32
18
|
|
33
|
-
def initialize(config)
|
34
|
-
@config
|
19
|
+
def initialize(config, command)
|
20
|
+
@config = config
|
21
|
+
@command = command
|
35
22
|
end
|
36
23
|
|
37
24
|
# Is everything good to go? Implemented by subclasses.
|
@@ -46,27 +33,9 @@ module Boxen
|
|
46
33
|
raise "Subclasses must implement this method."
|
47
34
|
end
|
48
35
|
|
49
|
-
# A fancier `abort` and `warn`. This will probably really annoy
|
50
|
-
# someone at some point because it's overriding a Kernel method,
|
51
|
-
# but it's limited to checks.
|
52
|
-
|
53
|
-
def abort(message, *extras)
|
54
|
-
extras << { :color => :red }
|
55
|
-
warn message, *extras
|
56
|
-
exit 1
|
57
|
-
end
|
58
|
-
|
59
|
-
def warn(message, *extras)
|
60
|
-
options = Hash === extras.last ? extras.pop : {}
|
61
|
-
color = options[:color] || :yellow
|
62
|
-
|
63
|
-
$stderr.puts ANSI.send(color) { "--> #{message}" }
|
64
|
-
|
65
|
-
unless extras.empty?
|
66
|
-
extras.each { |line| $stderr.puts " #{line}" }
|
67
|
-
end
|
68
36
|
|
69
|
-
|
37
|
+
def debug?
|
38
|
+
@config.debug?
|
70
39
|
end
|
71
40
|
end
|
72
41
|
end
|
data/lib/boxen/cli.rb
CHANGED
@@ -1,61 +1,35 @@
|
|
1
|
+
require "boxen/command"
|
1
2
|
require "boxen/config"
|
2
|
-
require "boxen/
|
3
|
-
require "boxen/postflight"
|
4
|
-
require "boxen/preflight"
|
5
|
-
require "boxen/runner"
|
6
|
-
require "boxen/util"
|
3
|
+
require "boxen/util/logging"
|
7
4
|
|
8
5
|
module Boxen
|
9
6
|
class CLI
|
10
|
-
|
11
|
-
attr_reader :flags
|
12
|
-
attr_reader :runner
|
13
|
-
|
14
|
-
def initialize(config, flags)
|
15
|
-
@config = config
|
16
|
-
@flags = flags
|
17
|
-
@runner = Boxen::Runner.new(@config, @flags)
|
18
|
-
end
|
19
|
-
|
20
|
-
def run
|
21
|
-
if flags.help?
|
22
|
-
puts flags
|
23
|
-
exit
|
24
|
-
end
|
7
|
+
include Boxen::Util::Logging
|
25
8
|
|
26
|
-
|
9
|
+
def self.run(*args)
|
10
|
+
new.run(*args)
|
27
11
|
end
|
28
12
|
|
29
|
-
|
30
|
-
|
31
|
-
# exit code.
|
32
|
-
|
33
|
-
def self.run(*args)
|
34
|
-
config = Boxen::Config.load
|
35
|
-
flags = Boxen::Flags.new args
|
13
|
+
def initialize
|
14
|
+
end
|
36
15
|
|
37
|
-
|
38
|
-
|
39
|
-
flags.apply config
|
16
|
+
def run(*args)
|
17
|
+
cmd, *cmd_args = args.flatten
|
40
18
|
|
41
|
-
|
42
|
-
|
43
|
-
Boxen::
|
19
|
+
with_friendly_errors do
|
20
|
+
config = Boxen::Config.load
|
21
|
+
status = Boxen::Command.invoke cmd, config, *cmd_args
|
44
22
|
|
45
|
-
|
46
|
-
Boxen::Config.save config
|
23
|
+
status.code
|
47
24
|
end
|
25
|
+
end
|
48
26
|
|
49
|
-
|
50
|
-
status = Boxen::CLI.new(config, flags).run
|
51
|
-
|
52
|
-
if flags.run?
|
53
|
-
# Run the postflight checks.
|
54
|
-
Boxen::Postflight.run config if status.success?
|
55
|
-
end
|
27
|
+
private
|
56
28
|
|
57
|
-
|
58
|
-
|
29
|
+
def with_friendly_errors(&block)
|
30
|
+
yield
|
31
|
+
rescue => e
|
32
|
+
abort "#{e.class.name}: #{e.message}"
|
59
33
|
end
|
60
34
|
end
|
61
35
|
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require "boxen/command_status"
|
2
|
+
|
3
|
+
# Pulled in so the others don't have to
|
4
|
+
require "boxen/preflight"
|
5
|
+
require "boxen/postflight"
|
6
|
+
require "boxen/util/logging"
|
7
|
+
|
8
|
+
class Boxen::Command
|
9
|
+
include Boxen::Util::Logging
|
10
|
+
|
11
|
+
class UnknownCommandError < StandardError; end
|
12
|
+
class CommandNotRunError < StandardError; end
|
13
|
+
|
14
|
+
attr_reader :config
|
15
|
+
|
16
|
+
def self.help
|
17
|
+
raise "You should define this"
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.detailed_help
|
21
|
+
raise "You should definitely define this"
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.preflight(*klasses)
|
25
|
+
preflights.replace preflights | klasses.flatten
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.preflights
|
29
|
+
@preflights ||= []
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.postflight(*klasses)
|
33
|
+
postflights.replace postflights | klasses.flatten
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.postflights
|
37
|
+
@postflights ||= []
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.all
|
41
|
+
@commands
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.register(name, klass, *aliases)
|
45
|
+
unless defined?(@commands)
|
46
|
+
@commands = {}
|
47
|
+
end
|
48
|
+
unless defined?(@aliases)
|
49
|
+
@aliases = {}
|
50
|
+
end
|
51
|
+
|
52
|
+
@commands[name] = klass
|
53
|
+
aliases.each { |a| @aliases[a] = name }
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.reset!
|
57
|
+
@commands = {}
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.invoke(name, *args)
|
61
|
+
if @commands && name && @commands.has_key?(name.to_sym)
|
62
|
+
@commands[name.to_sym].new(*args).invoke
|
63
|
+
elsif @aliases && name && @aliases.has_key?(name.to_sym)
|
64
|
+
invoke(@aliases[name.to_sym], *args)
|
65
|
+
else
|
66
|
+
raise UnknownCommandError,
|
67
|
+
"could not find `#{name.inspect.to_s}` in the list of registered commands"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def initialize(config, *args)
|
72
|
+
@config = config
|
73
|
+
@args = args
|
74
|
+
end
|
75
|
+
|
76
|
+
def invoke
|
77
|
+
if preflights?
|
78
|
+
@cmd_status = self.run
|
79
|
+
|
80
|
+
postflights
|
81
|
+
|
82
|
+
@cmd_status
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def run
|
87
|
+
raise "So your command #{self.class.name} hasn't defined a run method, so we dunno what to do. Sorry."
|
88
|
+
end
|
89
|
+
|
90
|
+
def preflights?
|
91
|
+
if self.class.preflights.any?
|
92
|
+
info "Performing preflight checks"
|
93
|
+
end
|
94
|
+
|
95
|
+
self.class.preflights.all? do |p|
|
96
|
+
|
97
|
+
debug "Performing preflight check: #{p.name}"
|
98
|
+
|
99
|
+
p = p.new(@config, self)
|
100
|
+
status = p.ok?
|
101
|
+
|
102
|
+
if status
|
103
|
+
debug "Passed preflight check: #{p.class.name}"
|
104
|
+
else
|
105
|
+
p.run
|
106
|
+
end
|
107
|
+
|
108
|
+
status
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def postflights
|
113
|
+
if self.class.postflights.any?
|
114
|
+
info "Performing postflight checks"
|
115
|
+
end
|
116
|
+
|
117
|
+
self.class.postflights.each do |p|
|
118
|
+
p = p.new(@config, self)
|
119
|
+
p.run unless p.ok?
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def debug?
|
124
|
+
@config.debug?
|
125
|
+
end
|
126
|
+
|
127
|
+
def success?
|
128
|
+
if @cmd_status
|
129
|
+
@cmd_status.success?
|
130
|
+
else
|
131
|
+
raise CommandNotRunError,
|
132
|
+
"the command hasn't been run, so we can't know if it was successful"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
require "boxen/command/help"
|
138
|
+
require "boxen/command/version"
|
139
|
+
require "boxen/command/run"
|
140
|
+
require "boxen/command/preflight"
|
141
|
+
require "boxen/command/project"
|
142
|
+
require "boxen/command/service"
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require "boxen/command"
|
2
|
+
|
3
|
+
class Boxen::Command::Help < Boxen::Command
|
4
|
+
def self.help
|
5
|
+
"Displays help, obviously"
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.detailed_help
|
9
|
+
<<-EOS
|
10
|
+
|
11
|
+
boxen help [<command>]
|
12
|
+
|
13
|
+
With no arguments, displays short help information for all commands.
|
14
|
+
|
15
|
+
Given a command name as an argument, displays detailed help about that command.
|
16
|
+
|
17
|
+
EOS
|
18
|
+
end
|
19
|
+
|
20
|
+
def run
|
21
|
+
if @args.any?
|
22
|
+
puts Boxen::Command.all[@args.first.to_sym].detailed_help
|
23
|
+
else
|
24
|
+
Boxen::Command.all.each do |name, _|
|
25
|
+
display_help_for_command name
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
Boxen::CommandStatus.new(0)
|
30
|
+
end
|
31
|
+
|
32
|
+
def display_help_for_command(name)
|
33
|
+
# only shows top-level commands, not subcommands
|
34
|
+
unless name =~ /:/
|
35
|
+
puts " #{name.to_s.ljust(16)} #{Boxen::Command.all[name.to_sym].help}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
Boxen::Command.register :help, Boxen::Command::Help, :"--help"
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "boxen/command"
|
2
|
+
|
3
|
+
class Boxen::Command::Preflight < Boxen::Command
|
4
|
+
def self.help
|
5
|
+
"Run a single preflight and return whether or not it's ok."
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.detailed_help
|
9
|
+
<<-EOS
|
10
|
+
|
11
|
+
boxen preflight <check>
|
12
|
+
|
13
|
+
Run preflight named <check> and return whether or not it's ok.
|
14
|
+
|
15
|
+
EOS
|
16
|
+
end
|
17
|
+
|
18
|
+
def run
|
19
|
+
if defined?(preflight)
|
20
|
+
info "#{preflight.name}: #{preflight.new(@config).ok?.inspect}"
|
21
|
+
return Boxen::CommandStatus.new(0)
|
22
|
+
else
|
23
|
+
fail("Could not find a preflight named: #{preflight_name}")
|
24
|
+
end
|
25
|
+
rescue => e
|
26
|
+
fail("Command failed: #{e.message} #{e.backtrace}")
|
27
|
+
end
|
28
|
+
|
29
|
+
def preflight
|
30
|
+
Object.const_get(preflight_name)
|
31
|
+
end
|
32
|
+
|
33
|
+
def preflight_name
|
34
|
+
"Boxen::Preflight::#{ARGV[1].capitalize}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
Boxen::Command.register :preflight, Boxen::Command::Preflight
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require "boxen/command"
|
2
|
+
#require "boxen/service"
|
3
|
+
|
4
|
+
class Boxen::Command::Project < Boxen::Command
|
5
|
+
def self.detailed_help
|
6
|
+
<<-EOS
|
7
|
+
|
8
|
+
boxen project
|
9
|
+
|
10
|
+
Display all projects Boxen knows about.
|
11
|
+
|
12
|
+
boxen project:install <project1> [<project2> ...]
|
13
|
+
|
14
|
+
Install a Boxen-managed project.
|
15
|
+
|
16
|
+
NOTE: 'boxen project' is aliased to 'projects' for convenience
|
17
|
+
|
18
|
+
EOS
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.help
|
22
|
+
"Show and install Boxen-managed projects"
|
23
|
+
end
|
24
|
+
|
25
|
+
def run
|
26
|
+
@args = [] # we don't care about args here
|
27
|
+
|
28
|
+
puts "Boxen knows about the following projects:"
|
29
|
+
puts
|
30
|
+
|
31
|
+
projects.each do |project|
|
32
|
+
puts " #{project.name}"
|
33
|
+
end
|
34
|
+
|
35
|
+
puts
|
36
|
+
puts "You can install any of them by running \"boxen project:install <project>\""
|
37
|
+
puts
|
38
|
+
|
39
|
+
Boxen::CommandStatus.new(0)
|
40
|
+
end
|
41
|
+
|
42
|
+
def projects
|
43
|
+
@projects ||= @config.projects
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
require "boxen/command/project/install"
|
48
|
+
|
49
|
+
Boxen::Command.register :project, Boxen::Command::Project, :projects
|