boxen 0.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.
- data/.gitignore +4 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +49 -0
- data/LICENSE +20 -0
- data/README.md +7 -0
- data/boxen.gemspec +24 -0
- data/lib/boxen/check.rb +72 -0
- data/lib/boxen/cli.rb +79 -0
- data/lib/boxen/config.rb +251 -0
- data/lib/boxen/error.rb +4 -0
- data/lib/boxen/flags.rb +166 -0
- data/lib/boxen/postflight.rb +13 -0
- data/lib/boxen/postflight/active.rb +16 -0
- data/lib/boxen/postflight/env.rb +29 -0
- data/lib/boxen/preflight.rb +13 -0
- data/lib/boxen/preflight/creds.rb +34 -0
- data/lib/boxen/preflight/etc_my_cnf.rb +12 -0
- data/lib/boxen/preflight/homebrew.rb +13 -0
- data/lib/boxen/preflight/identity.rb +16 -0
- data/lib/boxen/preflight/os.rb +11 -0
- data/lib/boxen/preflight/rbenv.rb +12 -0
- data/lib/boxen/project.rb +24 -0
- data/lib/boxen/puppeteer.rb +68 -0
- data/lib/boxen/util.rb +17 -0
- data/script/bootstrap +9 -0
- data/script/tests +10 -0
- data/test/boxen/test.rb +7 -0
- data/test/boxen_check_test.rb +55 -0
- data/test/boxen_cli_test.rb +15 -0
- data/test/boxen_config_test.rb +157 -0
- data/test/boxen_flags_test.rb +182 -0
- data/test/boxen_postflight_active_test.rb +29 -0
- data/test/boxen_postflight_env_test.rb +6 -0
- data/test/boxen_project_test.rb +21 -0
- data/test/boxen_puppeteer_test.rb +77 -0
- data/test/boxen_util_test.rb +21 -0
- data/test/fixtures/repo/modules/projects/manifests/first-project.pp +0 -0
- data/test/fixtures/repo/modules/projects/manifests/second-project.pp +0 -0
- data/test/system_timer.rb +10 -0
- metadata +211 -0
data/lib/boxen/error.rb
ADDED
data/lib/boxen/flags.rb
ADDED
@@ -0,0 +1,166 @@
|
|
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 :password
|
16
|
+
attr_reader :srcdir
|
17
|
+
attr_reader :user
|
18
|
+
|
19
|
+
# Create a new instance, optionally providing CLI `args` to
|
20
|
+
# parse immediately.
|
21
|
+
|
22
|
+
def initialize(*args)
|
23
|
+
@args = []
|
24
|
+
@debug = false
|
25
|
+
@env = false
|
26
|
+
@fde = true
|
27
|
+
@help = false
|
28
|
+
@pretend = false
|
29
|
+
@profile = false
|
30
|
+
@projects = false
|
31
|
+
@stealth = false
|
32
|
+
|
33
|
+
@options = OptionParser.new do |o|
|
34
|
+
o.banner = "Usage: #{File.basename $0} [options] [projects...]\n\n"
|
35
|
+
|
36
|
+
o.on "--debug", "Be really verbose." do
|
37
|
+
@debug = true
|
38
|
+
end
|
39
|
+
|
40
|
+
o.on "--pretend", "--noop", "Don't make changes." do
|
41
|
+
@pretend = true
|
42
|
+
end
|
43
|
+
|
44
|
+
o.on "--env", "Show useful environment variables." do
|
45
|
+
@env = true
|
46
|
+
end
|
47
|
+
|
48
|
+
o.on "--help", "-h", "-?", "Show help." do
|
49
|
+
@help = true
|
50
|
+
end
|
51
|
+
|
52
|
+
o.on "--homedir DIR", "Boxen's home directory." do |homedir|
|
53
|
+
@homedir = homedir
|
54
|
+
end
|
55
|
+
|
56
|
+
o.on "--logfile DIR", "Boxen's log file." do |logfile|
|
57
|
+
@logfile = logfile
|
58
|
+
end
|
59
|
+
|
60
|
+
o.on "--login LOGIN", "Your GitHub login." do |login|
|
61
|
+
@login = login
|
62
|
+
end
|
63
|
+
|
64
|
+
o.on "--no-fde", "Don't require full disk encryption." do
|
65
|
+
@fde = false
|
66
|
+
end
|
67
|
+
|
68
|
+
# --no-pull is used before options are parsed, but consumed here.
|
69
|
+
|
70
|
+
o.on "--no-pull", "Don't try to update code before applying."
|
71
|
+
|
72
|
+
o.on "--no-issue", "--stealth", "Don't open an issue on failure." do
|
73
|
+
@stealth = true
|
74
|
+
end
|
75
|
+
|
76
|
+
o.on "--password PASSWORD", "Your GitHub password." do |password|
|
77
|
+
@password = password
|
78
|
+
end
|
79
|
+
|
80
|
+
o.on "--profile", "Profile the Puppet run." do
|
81
|
+
@profile = true
|
82
|
+
end
|
83
|
+
|
84
|
+
o.on "--projects", "Show available projects." do
|
85
|
+
@projects = true
|
86
|
+
end
|
87
|
+
|
88
|
+
o.on "--srcdir DIR", "The directory where repos live." do |srcdir|
|
89
|
+
@srcdir = srcdir
|
90
|
+
end
|
91
|
+
|
92
|
+
o.on "--user USER", "Your local user." do |user|
|
93
|
+
@user = user
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
parse args.flatten.compact
|
98
|
+
end
|
99
|
+
|
100
|
+
# Apply these flags to `config`. Returns `config`.
|
101
|
+
|
102
|
+
def apply(config)
|
103
|
+
config.debug = debug?
|
104
|
+
config.fde = fde? if config.fde?
|
105
|
+
config.homedir = homedir if homedir
|
106
|
+
config.logfile = logfile if logfile
|
107
|
+
config.login = login if login
|
108
|
+
config.password = password if password
|
109
|
+
config.pretend = pretend?
|
110
|
+
config.profile = profile?
|
111
|
+
config.srcdir = srcdir if srcdir
|
112
|
+
config.stealth = stealth?
|
113
|
+
config.user = user if user
|
114
|
+
|
115
|
+
config
|
116
|
+
end
|
117
|
+
|
118
|
+
def debug?
|
119
|
+
@debug
|
120
|
+
end
|
121
|
+
|
122
|
+
def env?
|
123
|
+
@env
|
124
|
+
end
|
125
|
+
|
126
|
+
def fde?
|
127
|
+
@fde
|
128
|
+
end
|
129
|
+
|
130
|
+
def help?
|
131
|
+
@help
|
132
|
+
end
|
133
|
+
|
134
|
+
# Parse `args` as an array of CLI argument Strings. Raises
|
135
|
+
# Boxen::Error if anything goes wrong. Returns `self`.
|
136
|
+
|
137
|
+
def parse(*args)
|
138
|
+
@args = @options.parse! args.flatten.compact.map(&:to_s)
|
139
|
+
|
140
|
+
self
|
141
|
+
|
142
|
+
rescue OptionParser::MissingArgument, OptionParser::InvalidOption => e
|
143
|
+
raise Boxen::Error, "#{e.message}\n#@options"
|
144
|
+
end
|
145
|
+
|
146
|
+
def pretend?
|
147
|
+
@pretend
|
148
|
+
end
|
149
|
+
|
150
|
+
def profile?
|
151
|
+
@profile
|
152
|
+
end
|
153
|
+
|
154
|
+
def projects?
|
155
|
+
@projects
|
156
|
+
end
|
157
|
+
|
158
|
+
def stealth?
|
159
|
+
@stealth
|
160
|
+
end
|
161
|
+
|
162
|
+
def to_s
|
163
|
+
@options.to_s
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "boxen/postflight"
|
2
|
+
require "boxen/util"
|
3
|
+
|
4
|
+
# Checks to see if the basic environment is loaded.
|
5
|
+
|
6
|
+
class Boxen::Postflight::Active < Boxen::Postflight
|
7
|
+
def ok?
|
8
|
+
Boxen::Util.active?
|
9
|
+
end
|
10
|
+
|
11
|
+
def run
|
12
|
+
warn "You haven't loaded Boxen's environment yet!",
|
13
|
+
"To permanently fix this, source #{config.envfile} at the end",
|
14
|
+
"of your shell's startup file."
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "boxen/postflight"
|
2
|
+
|
3
|
+
class Boxen::Postflight::Env < Boxen::Postflight
|
4
|
+
|
5
|
+
# Calculate an MD5 checksum for the current environment.
|
6
|
+
|
7
|
+
def self.checksum
|
8
|
+
|
9
|
+
# We can't get this from config 'cause it's static (gotta happen
|
10
|
+
# on load), and GH_HOME might not be set.
|
11
|
+
|
12
|
+
home = ENV["BOXEN_HOME"] || "/opt/boxen"
|
13
|
+
return unless File.file? "#{home}/env.sh"
|
14
|
+
|
15
|
+
`find #{home}/env* -type f 2>&1 | sort | xargs /sbin/md5 | /sbin/md5 -q`.strip
|
16
|
+
end
|
17
|
+
|
18
|
+
# The checksum when this file was loaded.
|
19
|
+
|
20
|
+
CHECKSUM = self.checksum
|
21
|
+
|
22
|
+
def ok?
|
23
|
+
self.class.checksum == CHECKSUM
|
24
|
+
end
|
25
|
+
|
26
|
+
def run
|
27
|
+
warn "Source #{config.envfile} or restart your shell for new stuff!"
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "highline"
|
2
|
+
require "boxen/preflight"
|
3
|
+
|
4
|
+
# HACK: Unless this is `false`, HighLine has some really bizarre
|
5
|
+
# problems with empty/expended streams at bizarre intervals.
|
6
|
+
|
7
|
+
HighLine.track_eof = false
|
8
|
+
|
9
|
+
class Boxen::Preflight::Creds < Boxen::Preflight
|
10
|
+
def ok?
|
11
|
+
config.api.user rescue nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def run
|
15
|
+
console = HighLine.new
|
16
|
+
|
17
|
+
warn "Hey, I need your current GitHub credentials to continue."
|
18
|
+
|
19
|
+
config.login = console.ask "GitHub login: " do |q|
|
20
|
+
q.default = config.login || config.user
|
21
|
+
end
|
22
|
+
|
23
|
+
config.password = console.ask "GitHub password: " do |q|
|
24
|
+
q.echo = "*"
|
25
|
+
end
|
26
|
+
|
27
|
+
unless ok?
|
28
|
+
puts # i <3 vertical whitespace
|
29
|
+
|
30
|
+
abort "Sorry, I can't auth you on GitHub.",
|
31
|
+
"Please check your credentials and teams and give it another try."
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require "boxen/preflight"
|
2
|
+
|
3
|
+
class Boxen::Preflight::EtcMyCnf < Boxen::Preflight
|
4
|
+
def run
|
5
|
+
abort "You have an /etc/my.cnf file.",
|
6
|
+
"This will confuse The Setup's MySQL a lot. Please remove it."
|
7
|
+
end
|
8
|
+
|
9
|
+
def ok?
|
10
|
+
!File.file? "/etc/my.cnf"
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "boxen/preflight"
|
2
|
+
|
3
|
+
class Boxen::Preflight::Homebrew < Boxen::Preflight
|
4
|
+
def run
|
5
|
+
warn "You have an existing Homebrew install in /usr/local",
|
6
|
+
"The Boxen provides its own Homebrew, so consider deleting yours.",
|
7
|
+
"Keeping both will confuse many projects."
|
8
|
+
end
|
9
|
+
|
10
|
+
def ok?
|
11
|
+
!File.exist? "/usr/local/Library/Homebrew"
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "boxen/preflight"
|
2
|
+
|
3
|
+
class Boxen::Preflight::Identity < Boxen::Preflight
|
4
|
+
def ok?
|
5
|
+
!user || (config.email && config.name)
|
6
|
+
end
|
7
|
+
|
8
|
+
def run
|
9
|
+
config.email = user.email
|
10
|
+
config.name = user.name
|
11
|
+
end
|
12
|
+
|
13
|
+
def user
|
14
|
+
@user ||= config.api.user rescue nil
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require "boxen/preflight"
|
2
|
+
|
3
|
+
class Boxen::Preflight::Rbenv < Boxen::Preflight
|
4
|
+
def run
|
5
|
+
warn "You have an existing rbenv installed in ~/.rbenv.",
|
6
|
+
"Boxen provides its own rbenv, so consider deleting yours."
|
7
|
+
end
|
8
|
+
|
9
|
+
def ok?
|
10
|
+
!File.exist? "#{ENV['HOME']}/.rbenv"
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Boxen
|
2
|
+
|
3
|
+
# A project managed by Boxen.
|
4
|
+
|
5
|
+
class Project
|
6
|
+
|
7
|
+
# The directory where this project's repo should live.
|
8
|
+
|
9
|
+
attr_reader :dir
|
10
|
+
|
11
|
+
# The name of this project.
|
12
|
+
|
13
|
+
attr_reader :name
|
14
|
+
|
15
|
+
def initialize(dir)
|
16
|
+
@dir = dir
|
17
|
+
@name = File.basename @dir
|
18
|
+
end
|
19
|
+
|
20
|
+
def installed?
|
21
|
+
File.directory? dir
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
require "boxen/util"
|
3
|
+
|
4
|
+
module Boxen
|
5
|
+
|
6
|
+
# Manages an invocation of puppet.
|
7
|
+
|
8
|
+
class Puppeteer
|
9
|
+
attr_reader :config
|
10
|
+
|
11
|
+
def initialize(config)
|
12
|
+
@config = config
|
13
|
+
end
|
14
|
+
|
15
|
+
def command
|
16
|
+
manifest = "#{config.repodir}/manifests/site.pp"
|
17
|
+
puppet = "#{config.repodir}/bin/puppet"
|
18
|
+
|
19
|
+
[puppet, "apply", flags, manifest].flatten
|
20
|
+
end
|
21
|
+
|
22
|
+
def flags
|
23
|
+
flags = []
|
24
|
+
root = File.expand_path "../../..", __FILE__
|
25
|
+
|
26
|
+
flags << ["--confdir", "#{config.puppetdir}/conf"]
|
27
|
+
flags << ["--vardir", "#{config.puppetdir}/var"]
|
28
|
+
flags << ["--libdir", "#{config.repodir}/lib"]
|
29
|
+
flags << ["--manifestdir", "#{config.repodir}/manifests"]
|
30
|
+
flags << ["--modulepath", "#{config.repodir}/modules:#{config.repodir}/shared"]
|
31
|
+
|
32
|
+
# Log to both the console and a file.
|
33
|
+
|
34
|
+
flags << ["--logdest", config.logfile]
|
35
|
+
flags << ["--logdest", "console"]
|
36
|
+
|
37
|
+
# For some reason Puppet tries to set up a bunch of rrd stuff
|
38
|
+
# (user, group) unless reports are completely disabled.
|
39
|
+
|
40
|
+
flags << "--no-report"
|
41
|
+
flags << "--detailed-exitcodes"
|
42
|
+
|
43
|
+
if config.profile?
|
44
|
+
flags << "--evaltrace"
|
45
|
+
flags << "--summarize"
|
46
|
+
end
|
47
|
+
|
48
|
+
flags << "--debug" if config.debug?
|
49
|
+
flags << "--noop" if config.pretend?
|
50
|
+
|
51
|
+
flags.flatten
|
52
|
+
end
|
53
|
+
|
54
|
+
def run
|
55
|
+
FileUtils.mkdir_p config.puppetdir
|
56
|
+
|
57
|
+
FileUtils.rm_f config.logfile
|
58
|
+
|
59
|
+
FileUtils.mkdir_p File.dirname config.logfile
|
60
|
+
FileUtils.touch config.logfile
|
61
|
+
|
62
|
+
warn command.join " " if config.debug?
|
63
|
+
Boxen::Util.sudo *command
|
64
|
+
|
65
|
+
$?.exitstatus
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|