pleaserun 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +73 -0
- data/Guardfile +17 -0
- data/Makefile +50 -0
- data/README.md +98 -0
- data/bin/pleaserun +7 -0
- data/examples/runit.rb +16 -0
- data/lib/pleaserun/cli.rb +241 -0
- data/lib/pleaserun/configurable.rb +143 -0
- data/lib/pleaserun/detector.rb +58 -0
- data/lib/pleaserun/mustache_methods.rb +41 -0
- data/lib/pleaserun/namespace.rb +3 -0
- data/lib/pleaserun/platform/base.rb +144 -0
- data/lib/pleaserun/platform/launchd.rb +27 -0
- data/lib/pleaserun/platform/runit.rb +18 -0
- data/lib/pleaserun/platform/systemd.rb +24 -0
- data/lib/pleaserun/platform/sysv.rb +12 -0
- data/lib/pleaserun/platform/upstart.rb +11 -0
- data/pleaserun.gemspec +27 -0
- data/spec/pleaserun/configurable_spec.rb +215 -0
- data/spec/pleaserun/mustache_methods_spec.rb +46 -0
- data/spec/pleaserun/platform/base_spec.rb +27 -0
- data/spec/pleaserun/platform/launchd_spec.rb +93 -0
- data/spec/pleaserun/platform/systemd_spec.rb +119 -0
- data/spec/pleaserun/platform/sysv_spec.rb +133 -0
- data/spec/pleaserun/platform/upstart_spec.rb +117 -0
- data/spec/testenv.rb +69 -0
- data/templates/launchd/10.9/program.plist +47 -0
- data/templates/runit/log +4 -0
- data/templates/runit/run +17 -0
- data/templates/systemd/default/prestart.sh +2 -0
- data/templates/systemd/default/program.service +17 -0
- data/templates/sysv/lsb-3.1/default +0 -0
- data/templates/sysv/lsb-3.1/init.d +141 -0
- data/templates/upstart/1.5/init.conf +41 -0
- data/templates/upstart/1.5/init.d.sh +4 -0
- data/test.rb +33 -0
- data/test/helpers.rb +20 -0
- data/test/test.rb +60 -0
- data/test/vagrant/Vagrantfile +40 -0
- data/test/vagrant/fedora-18/Vagrantfile +28 -0
- data/test/vagrant/fedora-18/provision.sh +10 -0
- metadata +187 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
atomic (1.1.15)
|
5
|
+
avl_tree (1.1.3)
|
6
|
+
cabin (0.6.1)
|
7
|
+
celluloid (0.15.2)
|
8
|
+
timers (~> 1.1.0)
|
9
|
+
clamp (0.6.3)
|
10
|
+
coderay (1.1.0)
|
11
|
+
diff-lcs (1.2.5)
|
12
|
+
ffi (1.9.3)
|
13
|
+
formatador (0.2.4)
|
14
|
+
guard (2.2.5)
|
15
|
+
formatador (>= 0.2.4)
|
16
|
+
listen (~> 2.1)
|
17
|
+
lumberjack (~> 1.0)
|
18
|
+
pry (>= 0.9.12)
|
19
|
+
thor (>= 0.18.1)
|
20
|
+
guard-rspec (4.0.4)
|
21
|
+
guard (>= 2.1.1)
|
22
|
+
rspec (~> 2.14)
|
23
|
+
hitimes (1.2.1)
|
24
|
+
insist (1.0.0)
|
25
|
+
listen (2.4.0)
|
26
|
+
celluloid (>= 0.15.2)
|
27
|
+
rb-fsevent (>= 0.9.3)
|
28
|
+
rb-inotify (>= 0.9)
|
29
|
+
lumberjack (1.0.4)
|
30
|
+
method_source (0.8.2)
|
31
|
+
metriks (0.9.9.6)
|
32
|
+
atomic (~> 1.0)
|
33
|
+
avl_tree (~> 1.1.2)
|
34
|
+
hitimes (~> 1.1)
|
35
|
+
mustache (0.99.5)
|
36
|
+
net-ssh (2.8.0)
|
37
|
+
peach (0.5.1)
|
38
|
+
pry (0.9.12.4)
|
39
|
+
coderay (~> 1.0)
|
40
|
+
method_source (~> 0.8)
|
41
|
+
slop (~> 3.4)
|
42
|
+
rb-fsevent (0.9.4)
|
43
|
+
rb-inotify (0.9.3)
|
44
|
+
ffi (>= 0.5.0)
|
45
|
+
rspec (2.14.1)
|
46
|
+
rspec-core (~> 2.14.0)
|
47
|
+
rspec-expectations (~> 2.14.0)
|
48
|
+
rspec-mocks (~> 2.14.0)
|
49
|
+
rspec-core (2.14.7)
|
50
|
+
rspec-expectations (2.14.4)
|
51
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
52
|
+
rspec-mocks (2.14.4)
|
53
|
+
slop (3.4.7)
|
54
|
+
stud (0.0.17)
|
55
|
+
ffi
|
56
|
+
metriks
|
57
|
+
thor (0.18.1)
|
58
|
+
timers (1.1.0)
|
59
|
+
|
60
|
+
PLATFORMS
|
61
|
+
ruby
|
62
|
+
|
63
|
+
DEPENDENCIES
|
64
|
+
cabin
|
65
|
+
clamp
|
66
|
+
guard
|
67
|
+
guard-rspec
|
68
|
+
insist
|
69
|
+
mustache
|
70
|
+
net-ssh
|
71
|
+
peach
|
72
|
+
rspec
|
73
|
+
stud
|
data/Guardfile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
notification :tmux,
|
5
|
+
display_message: true,
|
6
|
+
timeout: 5, # in seconds
|
7
|
+
default_message_format: '%s >> %s',
|
8
|
+
success: 'green',
|
9
|
+
default_message_color: 'black',
|
10
|
+
line_separator: ' > ', # since we are single line we need a separator
|
11
|
+
color_location: 'status-left-bg' # to customize which tmux element will change color
|
12
|
+
|
13
|
+
guard :rspec, cmd: 'rspec --color --order rand:$RANDOM' do
|
14
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
15
|
+
watch(%r{^spec/.*\.rb$}) { |m| m[0] }
|
16
|
+
end
|
17
|
+
|
data/Makefile
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
GEMSPEC=$(shell ls *.gemspec)
|
2
|
+
VERSION=$(shell awk -F\" '/spec.version/ { print $$2 }' $(GEMSPEC))
|
3
|
+
NAME=$(shell awk -F\" '/spec.name/ { print $$2 }' $(GEMSPEC))
|
4
|
+
GEM=$(NAME)-$(VERSION).gem
|
5
|
+
|
6
|
+
.PHONY: test
|
7
|
+
test:
|
8
|
+
sh notify-failure.sh ruby test/all.rb
|
9
|
+
|
10
|
+
.PHONY: testloop
|
11
|
+
testloop:
|
12
|
+
while true; do \
|
13
|
+
$(MAKE) test; \
|
14
|
+
$(MAKE) wait-for-changes; \
|
15
|
+
done
|
16
|
+
|
17
|
+
.PHONY: serve-coverage
|
18
|
+
serve-coverage:
|
19
|
+
cd coverage; python -mSimpleHTTPServer
|
20
|
+
|
21
|
+
.PHONY: wait-for-changes
|
22
|
+
wait-for-changes:
|
23
|
+
-inotifywait --exclude '\.swp' -e modify $$(find $(DIRS) -name '*.rb'; find $(DIRS) -type d)
|
24
|
+
|
25
|
+
.PHONY: package
|
26
|
+
package: | $(GEM)
|
27
|
+
|
28
|
+
.PHONY: gem
|
29
|
+
gem: $(GEM)
|
30
|
+
|
31
|
+
$(GEM):
|
32
|
+
gem build $(GEMSPEC)
|
33
|
+
|
34
|
+
.PHONY: test-package
|
35
|
+
test-package: $(GEM)
|
36
|
+
# Sometimes 'gem build' makes a faulty gem.
|
37
|
+
gem unpack $(GEM)
|
38
|
+
rm -rf $(NAME)-$(VERSION)/
|
39
|
+
|
40
|
+
.PHONY: publish
|
41
|
+
publish: test-package
|
42
|
+
gem push $(GEM)
|
43
|
+
|
44
|
+
.PHONY: install
|
45
|
+
install: $(GEM)
|
46
|
+
gem install $(GEM)
|
47
|
+
|
48
|
+
.PHONY: clean
|
49
|
+
clean:
|
50
|
+
-rm -rf .yardoc $(GEM) $(NAME)-$(VERSION)/
|
data/README.md
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
# Please, Run!
|
2
|
+
|
3
|
+
Pleaserun is a tool to generate startup scripts for the wasteland of sorrow
|
4
|
+
that is process launchers.
|
5
|
+
|
6
|
+
Ideally, you should be able to specify a configuration of how to run a given
|
7
|
+
service command (like apache, syslog-ng, whatever), and this tool should
|
8
|
+
be able to spit out a script or config file for your target platform.
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
```
|
13
|
+
gem install pleaserun
|
14
|
+
```
|
15
|
+
|
16
|
+
## Your First Process
|
17
|
+
|
18
|
+
First, we need a program to run!
|
19
|
+
|
20
|
+
### Example: redis
|
21
|
+
|
22
|
+
For no particular reason, this example will choose redis to run. The idea is to
|
23
|
+
simulate the same workflow you would normally go through in production: acquire
|
24
|
+
software, deploy it, run it. Pleaserun helps you with the 'run it' part, but
|
25
|
+
first let's get redis and build it.
|
26
|
+
|
27
|
+
```
|
28
|
+
wget http://download.redis.io/releases/redis-2.8.6.tar.gz
|
29
|
+
tar -zxf redis-2.8.6.tar.gz
|
30
|
+
cd redis-2.8.6
|
31
|
+
make -j4
|
32
|
+
make install PREFIX=/tmp/redis
|
33
|
+
```
|
34
|
+
|
35
|
+
Assuming the above succeeds (it did for me!), we now have redis installed to `/tmp/redis`:
|
36
|
+
|
37
|
+
```
|
38
|
+
% ls /tmp/redis/bin
|
39
|
+
redis-benchmark redis-check-aof redis-check-dump redis-cli redis-server
|
40
|
+
```
|
41
|
+
|
42
|
+
You might be thinking - why /tmp? This is just a demo! That's why! :)
|
43
|
+
|
44
|
+
### Generate a runner
|
45
|
+
|
46
|
+
What platform are you on? Do you know the best way to run a server process? I
|
47
|
+
can never remember.
|
48
|
+
|
49
|
+
Luckily, pleaserun remembers.
|
50
|
+
|
51
|
+
```
|
52
|
+
# Run as root so pleaserun has permissions to write to
|
53
|
+
# any files required to install this as a service!
|
54
|
+
% sudo pleaserun --install /tmp/redis/bin/redis-server
|
55
|
+
No platform selected. Autodetecting... {:platform=>"upstart", :version=>"1.5", :level=>:warn}
|
56
|
+
No name given, setting reasonable default {:name=>"redis-server", :level=>:warn}
|
57
|
+
Writing file {:destination=>"/etc/init/redis-server.conf"}
|
58
|
+
Writing file {:destination=>"/etc/init.d/redis-server"}
|
59
|
+
```
|
60
|
+
|
61
|
+
Note: The `--install` flag above tells pleaserun to install it on this current system. The
|
62
|
+
default behavior without this flag is to install it in a temp directory so you can copy
|
63
|
+
it elsewhere if desired.
|
64
|
+
|
65
|
+
Now what? You can see above it automatically detected that "Upstart 1.5" was
|
66
|
+
the right process runner to target. Let's try using it!
|
67
|
+
|
68
|
+
```
|
69
|
+
% status redis-server
|
70
|
+
redis-server stop/waiting
|
71
|
+
|
72
|
+
% sudo start redis-server
|
73
|
+
redis-server start/running, process 395
|
74
|
+
|
75
|
+
% status redis-server
|
76
|
+
redis-server start/running, process 395
|
77
|
+
|
78
|
+
% ps -fwwp 395
|
79
|
+
UID PID PPID C STIME TTY TIME CMD
|
80
|
+
root 395 1 0 06:27 ? 00:00:00 /tmp/redis/bin/redis-server *:6379
|
81
|
+
|
82
|
+
# Is it running? Let's check with redis-cli
|
83
|
+
% redis-cli
|
84
|
+
127.0.0.1:6379> ping
|
85
|
+
PONG
|
86
|
+
|
87
|
+
% sudo stop redis-server
|
88
|
+
redis-server stop/waiting
|
89
|
+
```
|
90
|
+
|
91
|
+
Bam. Pretty easy, right? Let's recap!
|
92
|
+
|
93
|
+
### Recap
|
94
|
+
|
95
|
+
* You ran `pleaserun --install /tmp/redis/bin/redis-server`
|
96
|
+
* Pleaserun detected the platform as Upstart 1.5
|
97
|
+
* You didn't have to write an init script.
|
98
|
+
* You didn't have to know how to write an Upstart config.
|
data/bin/pleaserun
ADDED
data/examples/runit.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'pleaserun/runit'
|
4
|
+
|
5
|
+
pr = PleaseRun::RunIt.new('debian-7.0')
|
6
|
+
pr.name = 'foo'
|
7
|
+
pr.user = 'nobody'
|
8
|
+
pr.command = '/bin/true'
|
9
|
+
pr.args = []
|
10
|
+
|
11
|
+
pr.files.each do |path, content|
|
12
|
+
puts path => content.bytes.size
|
13
|
+
puts "#{path}:"
|
14
|
+
puts content.gsub(/^/, ' ')
|
15
|
+
end
|
16
|
+
|
@@ -0,0 +1,241 @@
|
|
1
|
+
|
2
|
+
require "pleaserun/namespace"
|
3
|
+
require "clamp"
|
4
|
+
require "cabin"
|
5
|
+
require "stud/temporary"
|
6
|
+
|
7
|
+
require "pleaserun/platform/base"
|
8
|
+
|
9
|
+
class PleaseRun::CLI < Clamp::Command
|
10
|
+
class Error < StandardError; end
|
11
|
+
class ConfigurationError < Error; end
|
12
|
+
class PlatformLoadError < Error; end
|
13
|
+
class FileWritingFailure < Error; end
|
14
|
+
|
15
|
+
option ["-p", "--platform"], "PLATFORM", "The name of the platform to target, such as sysv, upstart, etc"
|
16
|
+
option ["-v", "--version"], "VERSION", "The version of the platform to target, such as 'lsb-3.1' for sysv or '1.5' for upstart",
|
17
|
+
:default => "default", :attribute_name => :target_version
|
18
|
+
|
19
|
+
option "--log", "LOGFILE", "The path to use for writing pleaserun logs."
|
20
|
+
option "--json", :flag, "Output a result in JSON. Intended to be consumed by other programs. This will emit the file contents and install actions as a JSON object."
|
21
|
+
|
22
|
+
option "--install", :flag, "Install the program on this system. This will write files to the correct location and execute any actions to make the program available to the system."
|
23
|
+
|
24
|
+
option "--verbose", :flag, "More verbose logging"
|
25
|
+
option "--debug", :flag, "Debug-level logging"
|
26
|
+
option "--quiet", :flag, "Only errors or worse will be logged"
|
27
|
+
|
28
|
+
PleaseRun::Platform::Base.attributes.each do |facet|
|
29
|
+
# Skip program and args which we don't want to make into flags.
|
30
|
+
next if [:program, :args, :target_version].include?(facet.name)
|
31
|
+
|
32
|
+
# Turn the attribute name into a flag.
|
33
|
+
option "--#{facet.name}", facet.name.to_s.upcase, facet.description,
|
34
|
+
:attribute_name => facet.name
|
35
|
+
end
|
36
|
+
|
37
|
+
# TODO(sissel): Make options based on other platforms
|
38
|
+
|
39
|
+
# Make program and args attributes into parameters
|
40
|
+
base = PleaseRun::Platform::Base
|
41
|
+
|
42
|
+
# Load the 'program' attribute from the Base class and use it as the first
|
43
|
+
# cli parameter.
|
44
|
+
program = base.attributes.find { |f| f.name == :program }
|
45
|
+
raise "Something is wrong; Base missing 'program' attribute" if program.nil?
|
46
|
+
parameter "PROGRAM", program.description, :attribute_name => program.name
|
47
|
+
|
48
|
+
# Load the 'args' attribute from the Base class
|
49
|
+
# and use it as the remaining arguments setting
|
50
|
+
args = base.attributes.find { |f| f.name == :args }
|
51
|
+
raise "Something is wrong; Base missing 'args' attribute" if program.nil?
|
52
|
+
|
53
|
+
parameter "[ARGS] ...", args.description, :attribute_name => args.name
|
54
|
+
|
55
|
+
def help
|
56
|
+
return <<-HELP
|
57
|
+
Welcome to pleaserun!
|
58
|
+
|
59
|
+
This program aims to help you generate 'init' scripts/configs for various
|
60
|
+
platforms. The simplest example takes only the command you wish to run.
|
61
|
+
For example, let's run elasticsearch:
|
62
|
+
|
63
|
+
% pleaserun /opt/elasticsearch/bin/elasticsearch
|
64
|
+
|
65
|
+
The above will automatically detect what platform you are running on
|
66
|
+
and try to use the most sensible init system. For Ubuntu, this means
|
67
|
+
Upstart. For Debian, this means sysv init scripts. For Fedora, this
|
68
|
+
means systemd.
|
69
|
+
|
70
|
+
You can the running environment and settings for your runner with various
|
71
|
+
flags. By way of example, let's make our elasticsearch service run as the
|
72
|
+
'elasticsearch' user!
|
73
|
+
|
74
|
+
% pleaserun --user elasticsearch /opt/elasticsearch/bin/elasticsearch
|
75
|
+
|
76
|
+
If you don't want the platform autodetected, you can always specify the
|
77
|
+
exact process launcher to target:
|
78
|
+
|
79
|
+
# Generate a sysv (/etc/init.d) script for LSB 3.1 (Debian uses this)
|
80
|
+
% pleaserun -p sysv -v lsb-3.1 /opt/elasticsearch/bin/elasticsearch
|
81
|
+
|
82
|
+
Let's do another example. How about running nagios in systemd, but we
|
83
|
+
want to abort if the nagios config is invalid?
|
84
|
+
|
85
|
+
% pleaserun -t systemd \
|
86
|
+
--prestart "/usr/sbin/nagios -v /etc/nagios/nagios.cfg" \
|
87
|
+
/usr/sbin/nagios /etc/nagios/nagios.cfg
|
88
|
+
|
89
|
+
The above makes 'nagios -v ...' run before any start/restart attempts
|
90
|
+
are made. If it fails, nagios will not start. Yay!
|
91
|
+
|
92
|
+
#{super}
|
93
|
+
HELP
|
94
|
+
end
|
95
|
+
|
96
|
+
def execute
|
97
|
+
setup_logger
|
98
|
+
|
99
|
+
# Provide any dynamic defaults if necessary
|
100
|
+
if platform.nil?
|
101
|
+
require "pleaserun/detector"
|
102
|
+
self.platform, self.target_version = PleaseRun::Detector.detect
|
103
|
+
@logger.warn("No platform selected. Autodetecting...", :platform => platform, :version => target_version)
|
104
|
+
end
|
105
|
+
|
106
|
+
if name.nil?
|
107
|
+
self.name = File.basename(program)
|
108
|
+
@logger.warn("No name given, setting reasonable default", :name => self.name)
|
109
|
+
end
|
110
|
+
|
111
|
+
# Load the platform implementation
|
112
|
+
platform_klass = load_platform(platform)
|
113
|
+
runner = platform_klass.new(target_version)
|
114
|
+
|
115
|
+
platform_klass.all_attributes.each do |facet|
|
116
|
+
# Get the value of this attribute
|
117
|
+
# The idea here is to translate CLI options to runner settings
|
118
|
+
value = send(facet.name)
|
119
|
+
next if value.nil?
|
120
|
+
@logger.debug("Setting runner attribute", :name => facet.name, :value => value)
|
121
|
+
|
122
|
+
# Set the value in the runner we've selected
|
123
|
+
# This is akin to `obj.someattribute = value`
|
124
|
+
runner.send("#{facet.name}=", value)
|
125
|
+
end
|
126
|
+
|
127
|
+
if json?
|
128
|
+
return run_json(runner)
|
129
|
+
else
|
130
|
+
return run_human(runner)
|
131
|
+
end
|
132
|
+
return 0
|
133
|
+
rescue Error => e
|
134
|
+
@logger.error("An error occurred: #{e}")
|
135
|
+
return 1
|
136
|
+
end # def execute
|
137
|
+
|
138
|
+
def run_json(runner)
|
139
|
+
require "json"
|
140
|
+
|
141
|
+
result = {}
|
142
|
+
result["files"] = []
|
143
|
+
runner.files.each do |path, content, perms|
|
144
|
+
result["files"] << {
|
145
|
+
"path" => path,
|
146
|
+
"content" => content,
|
147
|
+
"perms" => perms
|
148
|
+
}
|
149
|
+
end
|
150
|
+
|
151
|
+
result["install_actions"] = runner.install_actions
|
152
|
+
|
153
|
+
puts JSON.dump(result)
|
154
|
+
return 0
|
155
|
+
end # def run_json
|
156
|
+
|
157
|
+
def run_human(runner)
|
158
|
+
tmp = Stud::Temporary.directory
|
159
|
+
errors = []
|
160
|
+
|
161
|
+
runner.files.each do |path, content, perms|
|
162
|
+
#perms ||= (0666 ^ File.umask)
|
163
|
+
fullpath = install? ? path : File.join(tmp, path)
|
164
|
+
success = write(fullpath, content, perms)
|
165
|
+
errors << fullpath unless success
|
166
|
+
end
|
167
|
+
|
168
|
+
if errors.any?
|
169
|
+
raise FileWritingFailure, "Errors occurred while writing files"
|
170
|
+
end
|
171
|
+
|
172
|
+
# TODO(sissel): Refactor this to be less lines of code or put into methods.
|
173
|
+
if runner.install_actions.any?
|
174
|
+
if install?
|
175
|
+
runner.install_actions.each do |action|
|
176
|
+
@logger.info("Running install action", :action => action)
|
177
|
+
system(action)
|
178
|
+
if !$?.success?
|
179
|
+
@logger.warn("Install action failed", :action => action, :code => $?.exitstatus)
|
180
|
+
end
|
181
|
+
end # each install action
|
182
|
+
else
|
183
|
+
path = File.join(tmp, "install_actions.sh")
|
184
|
+
@logger.log("Writing install actions. You will want to run this script to properly activate your service on the target host", :path => path)
|
185
|
+
File.open(path, "w") do |fd|
|
186
|
+
runner.install_actions.each do |action|
|
187
|
+
fd.puts(action)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end # if runner.install_actions.any?
|
192
|
+
end # def run_human
|
193
|
+
|
194
|
+
def write(fullpath, content, perms)
|
195
|
+
@logger.log("Writing file", :destination => fullpath)
|
196
|
+
FileUtils.mkdir_p(File.dirname(fullpath))
|
197
|
+
File.write(fullpath, content)
|
198
|
+
@logger.debug("Setting permissions", :destination => fullpath, :perms => perms)
|
199
|
+
File.chmod(perms, fullpath) if perms
|
200
|
+
return true
|
201
|
+
rescue Errno::EACCES
|
202
|
+
@logger.error("Access denied in writing a file. Maybe we need to be root?", :path => fullpath)
|
203
|
+
return false
|
204
|
+
end
|
205
|
+
|
206
|
+
def setup_logger
|
207
|
+
@logger = Cabin::Channel.new
|
208
|
+
if quiet?
|
209
|
+
@logger.level = :error
|
210
|
+
elsif verbose?
|
211
|
+
@logger.level = :info
|
212
|
+
elsif debug?
|
213
|
+
@logger.level = :debug
|
214
|
+
else
|
215
|
+
@logger.level = :warn
|
216
|
+
end
|
217
|
+
|
218
|
+
if log
|
219
|
+
logfile = File.new(logfile, "a")
|
220
|
+
@logger.subscribe(logfile)
|
221
|
+
STDERR.puts "Sending all logs to #{log}" if STDERR.tty?
|
222
|
+
else
|
223
|
+
@logger.subscribe(STDERR)
|
224
|
+
end
|
225
|
+
end # def setup_logger
|
226
|
+
|
227
|
+
def load_platform(v)
|
228
|
+
@logger.debug("Loading platform", :platform => v)
|
229
|
+
platform_lib = "pleaserun/platform/#{v}"
|
230
|
+
require(platform_lib)
|
231
|
+
|
232
|
+
const = PleaseRun::Platform.constants.find { |c| c.to_s.downcase == v.downcase }
|
233
|
+
if const.nil?
|
234
|
+
raise PlatformLoadError, "Could not find platform named '#{v}' after loading library '#{platform_lib}'. This is probably a bug."
|
235
|
+
end
|
236
|
+
|
237
|
+
return PleaseRun::Platform.const_get(const)
|
238
|
+
rescue LoadError => e
|
239
|
+
raise PlatformLoadError, "Failed to find or load platform '#{v}'. This could be a typo or a bug. If it helps, the error is: #{e}"
|
240
|
+
end # def load_platform
|
241
|
+
end # class PleaseRun::CLI
|