rconf 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +56 -0
- data/Rakefile +63 -0
- data/bin/rconf +102 -0
- data/examples/sample.rc +9 -0
- data/lib/rconf.rb +24 -0
- data/lib/rconf/command.rb +112 -0
- data/lib/rconf/configurator.rb +179 -0
- data/lib/rconf/configurator_registry.rb +63 -0
- data/lib/rconf/configurators/bundler_configurator.rb +85 -0
- data/lib/rconf/configurators/ruby_configurator.rb +151 -0
- data/lib/rconf/language.rb +91 -0
- data/lib/rconf/platform.rb +114 -0
- data/lib/rconf/platforms/darwin.rb +27 -0
- data/lib/rconf/platforms/linux.rb +40 -0
- data/lib/rconf/platforms/windows.rb +40 -0
- data/lib/rconf/progress_reporter.rb +72 -0
- data/lib/rconf/progress_reporters/base_reporter.rb +156 -0
- data/lib/rconf/progress_reporters/file_reporter.rb +58 -0
- data/lib/rconf/progress_reporters/stdout_reporter.rb +83 -0
- data/lib/rconf/ruby_extensions.rb +56 -0
- data/lib/rconf/trollop.rb +782 -0
- data/lib/rconf/version.rb +30 -0
- data/rconf.gemspec +24 -0
- data/spec/command_spec.rb +38 -0
- data/spec/configurator_spec.rb +64 -0
- data/spec/configurators/bundler_configurator_spec.rb +51 -0
- data/spec/configurators/ruby_configurator_spec.rb +60 -0
- data/spec/language_spec.rb +60 -0
- data/spec/platform_spec.rb +37 -0
- data/spec/progress_reporters/base_reporter_spec.rb +84 -0
- data/spec/progress_reporters/file_reporter_spec.rb +31 -0
- data/spec/progress_reporters/stdout_reporter_spec.rb +23 -0
- data/spec/ruby_extensions_spec.rb +35 -0
- data/spec/spec_helper.rb +21 -0
- metadata +129 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
# Copyright (C) 2011 RightScale, Inc, All Rights Reserved Worldwide.
|
2
|
+
#
|
3
|
+
# THIS PROGRAM IS CONFIDENTIAL AND PROPRIETARY TO RIGHTSCALE
|
4
|
+
# AND CONSTITUTES A VALUABLE TRADE SECRET. Any unauthorized use,
|
5
|
+
# reproduction, modification, or disclosure of this program is
|
6
|
+
# strictly prohibited. Any use of this program by an authorized
|
7
|
+
# licensee is strictly subject to the terms and conditions,
|
8
|
+
# including confidentiality obligations, set forth in the applicable
|
9
|
+
# License Agreement between RightScale.com, Inc. and
|
10
|
+
# the licensee
|
11
|
+
|
12
|
+
module RightConf
|
13
|
+
|
14
|
+
# Linux specific implementation
|
15
|
+
class Platform
|
16
|
+
|
17
|
+
attr_reader :flavor, :release
|
18
|
+
|
19
|
+
# Initialize flavor and release
|
20
|
+
def init
|
21
|
+
@flavor = 'mac_os_x'
|
22
|
+
@release = `sw_vers -productVersion`
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# Copyright (C) 2011 RightScale, Inc, All Rights Reserved Worldwide.
|
2
|
+
#
|
3
|
+
# THIS PROGRAM IS CONFIDENTIAL AND PROPRIETARY TO RIGHTSCALE
|
4
|
+
# AND CONSTITUTES A VALUABLE TRADE SECRET. Any unauthorized use,
|
5
|
+
# reproduction, modification, or disclosure of this program is
|
6
|
+
# strictly prohibited. Any use of this program by an authorized
|
7
|
+
# licensee is strictly subject to the terms and conditions,
|
8
|
+
# including confidentiality obligations, set forth in the applicable
|
9
|
+
# License Agreement between RightScale.com, Inc. and
|
10
|
+
# the licensee
|
11
|
+
|
12
|
+
module RightConf
|
13
|
+
|
14
|
+
# Linux specific implementation
|
15
|
+
class Platform
|
16
|
+
|
17
|
+
FEDORA_REL = '/etc/fedora-release'
|
18
|
+
FEDORA_SIG = /Fedora release ([0-9]+) \(.*\)/
|
19
|
+
|
20
|
+
attr_reader :flavor, :release
|
21
|
+
|
22
|
+
# Initialize flavor and release
|
23
|
+
def init
|
24
|
+
system('lsb_release --help > /dev/null 2>&1')
|
25
|
+
if $?.success?
|
26
|
+
# Use the lsb_release utility if it's available
|
27
|
+
@flavor = `lsb_release -is`.strip.downcase
|
28
|
+
@release = `lsb_release -rs`.strip
|
29
|
+
elsif File.exist?(FEDORA_REL) && (match = FEDORA_SIG.match(File.read(FEDORA_REL)))
|
30
|
+
# Parse the fedora-release file if it exists
|
31
|
+
@distro = 'fedora'
|
32
|
+
@release = match[1]
|
33
|
+
else
|
34
|
+
@distro = @release = 'unknown'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
|
2
|
+
# Copyright (C) 2011 RightScale, Inc, All Rights Reserved Worldwide.
|
3
|
+
#
|
4
|
+
# THIS PROGRAM IS CONFIDENTIAL AND PROPRIETARY TO RIGHTSCALE
|
5
|
+
# AND CONSTITUTES A VALUABLE TRADE SECRET. Any unauthorized use,
|
6
|
+
# reproduction, modification, or disclosure of this program is
|
7
|
+
# strictly prohibited. Any use of this program by an authorized
|
8
|
+
# licensee is strictly subject to the terms and conditions,
|
9
|
+
# including confidentiality obligations, set forth in the applicable
|
10
|
+
# License Agreement between RightScale.com, Inc. and
|
11
|
+
# the licensee
|
12
|
+
|
13
|
+
require 'Win32API'
|
14
|
+
|
15
|
+
module RightConf
|
16
|
+
|
17
|
+
# Linux specific implementation
|
18
|
+
class Platform
|
19
|
+
|
20
|
+
attr_reader :flavor, :release
|
21
|
+
|
22
|
+
# Initialize flavor and release
|
23
|
+
def init
|
24
|
+
GetVersionEx = Win32API.new("kernel32", "GetVersionEx", 'P', 'L')
|
25
|
+
osversioninfo = [
|
26
|
+
148, # size of this struct (IN)
|
27
|
+
0, # major version (OUT)
|
28
|
+
0, # minor version (OUT)
|
29
|
+
0, # build (OUT)
|
30
|
+
0, # platform (OUT)
|
31
|
+
"\0" * 128 # additional info (OUT)
|
32
|
+
].pack('LLLLLa128')
|
33
|
+
|
34
|
+
raise 'Failed to detect Windows version' unless GetVersionEx.call(osversioninfo) == 1 # => 1, means succeeded
|
35
|
+
version = osversioninfo.unpack('LLLLLZ128') # 'Z' means ASCIIZ string
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# Copyright (C) 2011 RightScale, Inc, All Rights Reserved Worldwide.
|
2
|
+
#
|
3
|
+
# THIS PROGRAM IS CONFIDENTIAL AND PROPRIETARY TO RIGHTSCALE
|
4
|
+
# AND CONSTITUTES A VALUABLE TRADE SECRET. Any unauthorized use,
|
5
|
+
# reproduction, modification, or disclosure of this program is
|
6
|
+
# strictly prohibited. Any use of this program by an authorized
|
7
|
+
# licensee is strictly subject to the terms and conditions,
|
8
|
+
# including confidentiality obligations, set forth in the applicable
|
9
|
+
# License Agreement between RightScale.com, Inc. and
|
10
|
+
# the licensee
|
11
|
+
|
12
|
+
module RightConf
|
13
|
+
|
14
|
+
# Provide progress report methods used by configurators
|
15
|
+
module ProgressReporter
|
16
|
+
|
17
|
+
# Create list of reporters upon inclusion
|
18
|
+
# Also setup forwarders
|
19
|
+
#
|
20
|
+
# === Parameters
|
21
|
+
# base(Object):: Object including this module
|
22
|
+
def self.included(base)
|
23
|
+
@@reporters ||= []
|
24
|
+
[ :report_section, :report, :report_check, :report_success,
|
25
|
+
:report_failure, :report_fatal, :report_result ].each do |meth|
|
26
|
+
meta_def(meth) { |*args| @@reporters.each { |r| r.__send__(meth, *args) } }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Print progress reports to stdout, default behavior
|
31
|
+
#
|
32
|
+
# === Return
|
33
|
+
# true:: Always return true
|
34
|
+
def self.report_to_stdout
|
35
|
+
@@reporters ||= []
|
36
|
+
@@reporters << StdoutReporter.new
|
37
|
+
true
|
38
|
+
end
|
39
|
+
|
40
|
+
# Save progress reports to given file
|
41
|
+
#
|
42
|
+
# === Parameters
|
43
|
+
# path(String):: Path to file where progress reports should be saved
|
44
|
+
#
|
45
|
+
# === Return
|
46
|
+
# true:: Always return true
|
47
|
+
def self.report_to_file(path)
|
48
|
+
@@reporters ||= []
|
49
|
+
@@reporters << FileReporter.new(path)
|
50
|
+
true
|
51
|
+
end
|
52
|
+
|
53
|
+
protected
|
54
|
+
|
55
|
+
# Define method programmatically (a.k.a. meta-programming a.k.a use-sparingly)
|
56
|
+
#
|
57
|
+
# === Parameters
|
58
|
+
# name(String):: Method name
|
59
|
+
# blk(Proc):: Method implementation
|
60
|
+
#
|
61
|
+
# === Return
|
62
|
+
# true:: Always return true
|
63
|
+
def self.meta_def(name, &blk)
|
64
|
+
self.instance_eval { define_method(name, &blk) }
|
65
|
+
true
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Load all progress reporters
|
72
|
+
Dir[File.join(File.dirname(__FILE__), 'progress_reporters', '*.rb')].each { |r| require r }
|
@@ -0,0 +1,156 @@
|
|
1
|
+
# Copyright (C) 2011 RightScale, Inc, All Rights Reserved Worldwide.
|
2
|
+
#
|
3
|
+
# THIS PROGRAM IS CONFIDENTIAL AND PROPRIETARY TO RIGHTSCALE
|
4
|
+
# AND CONSTITUTES A VALUABLE TRADE SECRET. Any unauthorized use,
|
5
|
+
# reproduction, modification, or disclosure of this program is
|
6
|
+
# strictly prohibited. Any use of this program by an authorized
|
7
|
+
# licensee is strictly subject to the terms and conditions,
|
8
|
+
# including confidentiality obligations, set forth in the applicable
|
9
|
+
# License Agreement between RightScale.com, Inc. and
|
10
|
+
# the licensee
|
11
|
+
|
12
|
+
module RightConf
|
13
|
+
|
14
|
+
# Common base to all progress reporters
|
15
|
+
#
|
16
|
+
# Reporters expose the following report methods whose default implementations
|
17
|
+
# can be overridden in descendants:
|
18
|
+
#
|
19
|
+
# - report_message:: Standard progress report message
|
20
|
+
# - report_section:: Title
|
21
|
+
# - report_error:: Non fatal error
|
22
|
+
# - report_fatal:: Fatal error, will raise after reporting message
|
23
|
+
# - report_check:: Report a check being done on system, should be followed by
|
24
|
+
# - report_success:: Report check success
|
25
|
+
# - report_failure:: Report check failure
|
26
|
+
# - report_result:: Report check success or failure depending on argument
|
27
|
+
#
|
28
|
+
# Alternatively reporters can override any associated formatting method
|
29
|
+
# (:format_message, :format_section, etc.) and/or the :write method used to
|
30
|
+
# write the progress report.
|
31
|
+
class BaseReporter
|
32
|
+
|
33
|
+
# Report methods are associated with formatting methods
|
34
|
+
# Call the formatting method then call the reporter 'write' method
|
35
|
+
# Reporters can override any formatting method and/or the write method
|
36
|
+
#
|
37
|
+
# === Parameters
|
38
|
+
# meth(Symbol):: Reporting method
|
39
|
+
# args(Array):: Arguments
|
40
|
+
#
|
41
|
+
# === Return
|
42
|
+
# true:: Always return true
|
43
|
+
#
|
44
|
+
# === Raise
|
45
|
+
# (Exception):: If there is no formatting method
|
46
|
+
def method_missing(meth, *args)
|
47
|
+
# Shortcut for standard progress report message
|
48
|
+
meth = :report_message if meth == :report
|
49
|
+
if meth.to_s =~ /^report_([a-zA-Z]+)$/
|
50
|
+
format_method = "format_#{Regexp.last_match[1]}".to_s
|
51
|
+
if self.respond_to?(format_method)
|
52
|
+
text = self.__send__(format_method, *args)
|
53
|
+
write(text)
|
54
|
+
exit 1 if Regexp.last_match[1] == 'fatal'
|
55
|
+
else
|
56
|
+
super(meth, *args)
|
57
|
+
end
|
58
|
+
else
|
59
|
+
super(meth, *args)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Report success or failure
|
64
|
+
#
|
65
|
+
# === Parameters
|
66
|
+
# res(TrueClass|FalseClass):: true for success, false for failure
|
67
|
+
#
|
68
|
+
# === Return
|
69
|
+
# true:: Always return true
|
70
|
+
def report_result(res)
|
71
|
+
res ? report_success : report_failure
|
72
|
+
end
|
73
|
+
|
74
|
+
protected
|
75
|
+
|
76
|
+
# Actually write text, implement in descendant
|
77
|
+
#
|
78
|
+
# === Parameters
|
79
|
+
# text(String):: Text to be written
|
80
|
+
#
|
81
|
+
# === Return
|
82
|
+
# true:: Always return true
|
83
|
+
def write(text)
|
84
|
+
raise "Implement!"
|
85
|
+
end
|
86
|
+
|
87
|
+
# Generic progress report formatting
|
88
|
+
#
|
89
|
+
# === Parameters
|
90
|
+
# message(String):: Progress report content
|
91
|
+
#
|
92
|
+
# === Return
|
93
|
+
# text(String):: Resulting text
|
94
|
+
def format_message(message)
|
95
|
+
text = message + "\n"
|
96
|
+
end
|
97
|
+
|
98
|
+
# Format new progress report section
|
99
|
+
#
|
100
|
+
# === Parameters
|
101
|
+
# section(String):: Section title
|
102
|
+
#
|
103
|
+
# === Return
|
104
|
+
# text(String):: Resulting text
|
105
|
+
def format_section(section)
|
106
|
+
text = ['', '-' * 80, section.upcase, '-' * 80, ''].join("\n")
|
107
|
+
end
|
108
|
+
|
109
|
+
# Format non-fatal error
|
110
|
+
#
|
111
|
+
# === Parameters
|
112
|
+
# error(String):: Error to report
|
113
|
+
#
|
114
|
+
# === Return
|
115
|
+
# text(String):: Resulting text
|
116
|
+
def format_error(error)
|
117
|
+
text = '**WARN: ' + error + "\n"
|
118
|
+
end
|
119
|
+
|
120
|
+
# Format check
|
121
|
+
#
|
122
|
+
# === Parameters
|
123
|
+
# check(String):: Check title
|
124
|
+
#
|
125
|
+
# === Return
|
126
|
+
# text(String):: Resulting text
|
127
|
+
def format_check(check)
|
128
|
+
text = check + '...'
|
129
|
+
end
|
130
|
+
|
131
|
+
# Format check success
|
132
|
+
#
|
133
|
+
# === Return
|
134
|
+
# text(String):: Resulting text
|
135
|
+
def format_success
|
136
|
+
text ="OK\n"
|
137
|
+
end
|
138
|
+
|
139
|
+
# Format check failure
|
140
|
+
#
|
141
|
+
# === Return
|
142
|
+
# text(String):: Resulting text
|
143
|
+
def format_failure
|
144
|
+
text ="FAILED\n"
|
145
|
+
end
|
146
|
+
|
147
|
+
# Format fatal error
|
148
|
+
#
|
149
|
+
# === Return
|
150
|
+
# text(String):: Resulting text
|
151
|
+
def format_fatal(error)
|
152
|
+
text = "\n***FATAL: " + error + "\n"
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# Copyright (C) 2011 RightScale, Inc, All Rights Reserved Worldwide.
|
2
|
+
#
|
3
|
+
# THIS PROGRAM IS CONFIDENTIAL AND PROPRIETARY TO RIGHTSCALE
|
4
|
+
# AND CONSTITUTES A VALUABLE TRADE SECRET. Any unauthorized use,
|
5
|
+
# reproduction, modification, or disclosure of this program is
|
6
|
+
# strictly prohibited. Any use of this program by an authorized
|
7
|
+
# licensee is strictly subject to the terms and conditions,
|
8
|
+
# including confidentiality obligations, set forth in the applicable
|
9
|
+
# License Agreement between RightScale.com, Inc. and
|
10
|
+
# the licensee
|
11
|
+
|
12
|
+
module RightConf
|
13
|
+
|
14
|
+
# File progress reporter, logs progress to file
|
15
|
+
class FileReporter < BaseReporter
|
16
|
+
|
17
|
+
# Set filename and check file can be written to
|
18
|
+
# Create file directory if needed
|
19
|
+
#
|
20
|
+
# === Parameters
|
21
|
+
# path(String):: Path to progress reports file
|
22
|
+
#
|
23
|
+
# === Raise
|
24
|
+
# (Exception):: If progress report file is not writable
|
25
|
+
def initialize(path)
|
26
|
+
FileUtils.mkdir_p(File.dirname(path))
|
27
|
+
system("touch #{path}")
|
28
|
+
raise "Could not initialize progress report file #{path}" unless $?.success?
|
29
|
+
@path = path
|
30
|
+
end
|
31
|
+
|
32
|
+
# Write lines to progress report file, prepend timestamp
|
33
|
+
#
|
34
|
+
# === Parameters
|
35
|
+
# lines(Array|String):: Lines to be written as array of strings or strings
|
36
|
+
#
|
37
|
+
# === Return
|
38
|
+
# true:: Always return true
|
39
|
+
def write(lines)
|
40
|
+
lines = '' if lines.nil?
|
41
|
+
lines = lines.split("\n") if lines.is_a?(String)
|
42
|
+
lines = lines.flatten
|
43
|
+
begin
|
44
|
+
File.open(@path, 'a') do |f|
|
45
|
+
lines.each do |line|
|
46
|
+
f.puts Time.now.strftime("[%m/%d/%Y %H:%M:%S] ") + line
|
47
|
+
end
|
48
|
+
end
|
49
|
+
rescue Exception => e
|
50
|
+
puts lines.join("\n")
|
51
|
+
end
|
52
|
+
true
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# Copyright (C) 2011 RightScale, Inc, All Rights Reserved Worldwide.
|
2
|
+
#
|
3
|
+
# THIS PROGRAM IS CONFIDENTIAL AND PROPRIETARY TO RIGHTSCALE
|
4
|
+
# AND CONSTITUTES A VALUABLE TRADE SECRET. Any unauthorized use,
|
5
|
+
# reproduction, modification, or disclosure of this program is
|
6
|
+
# strictly prohibited. Any use of this program by an authorized
|
7
|
+
# licensee is strictly subject to the terms and conditions,
|
8
|
+
# including confidentiality obligations, set forth in the applicable
|
9
|
+
# License Agreement between RightScale.com, Inc. and
|
10
|
+
# the licensee
|
11
|
+
|
12
|
+
$stdout.sync = true
|
13
|
+
|
14
|
+
module RightConf
|
15
|
+
|
16
|
+
# STDOUT progress reporter, logs progress to console
|
17
|
+
class StdoutReporter < BaseReporter
|
18
|
+
|
19
|
+
# Print given text to STDOUT
|
20
|
+
#
|
21
|
+
# === Parameters
|
22
|
+
# text(String):: Text to be printed
|
23
|
+
#
|
24
|
+
# === Return
|
25
|
+
# true:: Always return true
|
26
|
+
def write(text)
|
27
|
+
$stdout.print(text)
|
28
|
+
true
|
29
|
+
end
|
30
|
+
|
31
|
+
# Format new progress report section
|
32
|
+
#
|
33
|
+
# === Parameters
|
34
|
+
# section(String):: Section title
|
35
|
+
#
|
36
|
+
# === Return
|
37
|
+
# text(String):: Formatted text
|
38
|
+
def format_section(section)
|
39
|
+
text = super(section).green
|
40
|
+
end
|
41
|
+
|
42
|
+
# Format check, should be followed by +report_success+ or +report_failure+
|
43
|
+
#
|
44
|
+
# === Parameters
|
45
|
+
# check(String):: Check title
|
46
|
+
#
|
47
|
+
# === Return
|
48
|
+
# text(String):: Formatted text
|
49
|
+
def format_check(check)
|
50
|
+
text = super(check)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Format check success
|
54
|
+
#
|
55
|
+
# === Return
|
56
|
+
# text(String):: Formatted text
|
57
|
+
def format_success
|
58
|
+
text = super.blue
|
59
|
+
end
|
60
|
+
|
61
|
+
# Format check failure
|
62
|
+
#
|
63
|
+
# === Return
|
64
|
+
# text(String):: Formatted text
|
65
|
+
def format_failure
|
66
|
+
text = super.red
|
67
|
+
end
|
68
|
+
|
69
|
+
# Format fatal error and raise exception to stop execution
|
70
|
+
#
|
71
|
+
# === Return
|
72
|
+
# text(String):: Formatted text
|
73
|
+
def format_fatal(error)
|
74
|
+
text = super.split("\n")
|
75
|
+
text[0] = text[0].red.bold
|
76
|
+
text[1] = text[1].red.bold if text.size > 1
|
77
|
+
text.join("\n") + "\n"
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
|