boxen 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|