teapot 0.3.1 → 0.3.2
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/bin/teapot +11 -10
- data/lib/teapot/build/linker.rb +3 -3
- data/lib/teapot/build.rb +16 -15
- data/lib/teapot/environment/base.rb +62 -0
- data/lib/teapot/environment/constructor.rb +101 -0
- data/lib/teapot/environment/evaluator.rb +51 -0
- data/lib/teapot/environment/flatten.rb +62 -0
- data/lib/teapot/environment/system.rb +74 -0
- data/lib/teapot/environment.rb +5 -239
- data/lib/teapot/package.rb +3 -3
- data/lib/teapot/platform.rb +1 -1
- data/lib/teapot/version.rb +1 -1
- data/test/test_environment.rb +5 -5
- metadata +8 -3
data/bin/teapot
CHANGED
@@ -29,6 +29,7 @@ require 'rainbow'
|
|
29
29
|
$app = Rake.application = Rake::Application.new
|
30
30
|
$app.init('teapot')
|
31
31
|
|
32
|
+
# Fetch remote packages and link local packages based on the Teapot configuration:
|
32
33
|
task :fetch do
|
33
34
|
config = Teapot::Config.load_default
|
34
35
|
context = Teapot::Context.new(config)
|
@@ -51,6 +52,9 @@ task :fetch do
|
|
51
52
|
|
52
53
|
local_path = config.root + record.options[:local]
|
53
54
|
|
55
|
+
# Make the top level directory if required:
|
56
|
+
FileUtils.mkdir_p(destination_path.dirname.to_s)
|
57
|
+
|
54
58
|
unless File.exist? destination_path
|
55
59
|
FileUtils.ln_s local_path, destination_path
|
56
60
|
end
|
@@ -100,6 +104,7 @@ task :fetch do
|
|
100
104
|
puts "Completed fetch successfully.".color(:green)
|
101
105
|
end
|
102
106
|
|
107
|
+
# Build packages based on the Teapot configuration:
|
103
108
|
task :build do |task, arguments|
|
104
109
|
config = Teapot::Config.load_default
|
105
110
|
context = Teapot::Context.new(config)
|
@@ -107,7 +112,8 @@ task :build do |task, arguments|
|
|
107
112
|
config.records.each do |record|
|
108
113
|
record.load(context)
|
109
114
|
end
|
110
|
-
|
115
|
+
|
116
|
+
# Configure the packages and platforms based on the ENV provided by the user:
|
111
117
|
build_package = ENV['PACKAGE']
|
112
118
|
build_platform = ENV['PLATFORM']
|
113
119
|
|
@@ -115,9 +121,7 @@ task :build do |task, arguments|
|
|
115
121
|
package = context.packages[build_package]
|
116
122
|
|
117
123
|
unless package
|
118
|
-
|
119
|
-
|
120
|
-
next
|
124
|
+
fail "Could not find package #{build_package}".color(:red)
|
121
125
|
end
|
122
126
|
|
123
127
|
packages = [package]
|
@@ -129,9 +133,7 @@ task :build do |task, arguments|
|
|
129
133
|
platform = context.platforms[build_platform]
|
130
134
|
|
131
135
|
unless platform
|
132
|
-
|
133
|
-
|
134
|
-
next
|
136
|
+
fail "Could not find platform #{build_platform}".color(:red)
|
135
137
|
end
|
136
138
|
|
137
139
|
platforms = [platform]
|
@@ -177,6 +179,7 @@ task :build do |task, arguments|
|
|
177
179
|
puts "Completed build successfully.".color(:green)
|
178
180
|
end
|
179
181
|
|
182
|
+
# List available/installed packages based on the Teapot configuration:
|
180
183
|
task :list do
|
181
184
|
config = Teapot::Config.load_default
|
182
185
|
context = Teapot::Context.new(config)
|
@@ -209,8 +212,6 @@ task :list do
|
|
209
212
|
end
|
210
213
|
end
|
211
214
|
|
212
|
-
task :
|
213
|
-
|
214
|
-
task :default => :install
|
215
|
+
task :default => [:fetch, :build, :list]
|
215
216
|
|
216
217
|
$app.top_level
|
data/lib/teapot/build/linker.rb
CHANGED
@@ -24,13 +24,13 @@ module Teapot
|
|
24
24
|
def self.link_static(environment, library_file, objects)
|
25
25
|
if RUBY_PLATFORM =~ /darwin/
|
26
26
|
Teapot::Commands.run(
|
27
|
-
|
27
|
+
environment[:libtool] || "libtool",
|
28
28
|
"-static", "-o", library_file, objects,
|
29
29
|
)
|
30
30
|
elsif RUBY_PLATFORM =~ /linux/
|
31
31
|
Commands.run(
|
32
|
-
|
33
|
-
|
32
|
+
environment[:ar] || 'ar',
|
33
|
+
environment[:arflags] || "-cru",
|
34
34
|
library_file, objects
|
35
35
|
)
|
36
36
|
else
|
data/lib/teapot/build.rb
CHANGED
@@ -67,17 +67,18 @@ module Teapot
|
|
67
67
|
|
68
68
|
def execute(command, environment, *arguments)
|
69
69
|
if @configure
|
70
|
-
environment =
|
71
|
-
environment,
|
72
|
-
Environment.new(&@configure),
|
73
|
-
)
|
70
|
+
environment = environment.merge &@configure
|
74
71
|
end
|
75
72
|
|
76
|
-
environment
|
77
|
-
|
78
|
-
|
73
|
+
# Flatten the environment to a hash:
|
74
|
+
values = environment.flatten
|
75
|
+
|
76
|
+
puts "Executing command #{command} for #{root}...".color(:cyan)
|
77
|
+
|
78
|
+
# Show the environment to the user:
|
79
|
+
Environment::System::dump(values)
|
79
80
|
|
80
|
-
self.send(command,
|
81
|
+
self.send(command, values, *arguments)
|
81
82
|
end
|
82
83
|
end
|
83
84
|
|
@@ -111,14 +112,14 @@ module Teapot
|
|
111
112
|
case source_file.extname
|
112
113
|
when ".cpp"
|
113
114
|
Commands.run(
|
114
|
-
|
115
|
-
|
115
|
+
environment[:cxx],
|
116
|
+
environment[:cxxflags],
|
116
117
|
"-c", source_file, "-o", object_file
|
117
118
|
)
|
118
119
|
when ".c"
|
119
120
|
Commands.run(
|
120
|
-
|
121
|
-
|
121
|
+
environment[:cc],
|
122
|
+
environment[:cflags],
|
122
123
|
"-c", source_file, "-o", object_file
|
123
124
|
)
|
124
125
|
end
|
@@ -191,10 +192,10 @@ module Teapot
|
|
191
192
|
executable_file = build_prefix!(environment) + "#{@name}"
|
192
193
|
|
193
194
|
Commands.run(
|
194
|
-
|
195
|
-
|
195
|
+
environment[:cxx],
|
196
|
+
environment[:cxxflags],
|
196
197
|
"-o", executable_file, objects,
|
197
|
-
|
198
|
+
environment[:ldflags]
|
198
199
|
)
|
199
200
|
|
200
201
|
return executable_file
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
module Teapot
|
22
|
+
# This is the basic environment data structure which is essentially a linked list of hashes. It is primarily used for organising build configurations across a wide range of different sub-systems, e.g. platform configuration, target configuration, local project configuration, etc. The majority of the actual functionality is exposed in the `environment/*.rb` files.
|
23
|
+
class Environment
|
24
|
+
def initialize(parent = nil, values = {}, &block)
|
25
|
+
@values = (values || {}).to_hash
|
26
|
+
@parent = parent
|
27
|
+
|
28
|
+
if block_given?
|
29
|
+
Constructor.new(self).instance_exec(&block)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
attr :values
|
34
|
+
attr :parent
|
35
|
+
|
36
|
+
def lookup(name)
|
37
|
+
if @values.include? name
|
38
|
+
self
|
39
|
+
elsif @parent
|
40
|
+
@parent.lookup(name)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def [] (key)
|
45
|
+
environment = lookup(key)
|
46
|
+
|
47
|
+
environment ? environment.values[key] : nil
|
48
|
+
end
|
49
|
+
|
50
|
+
def []= (key, value)
|
51
|
+
@values[key] = value
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_hash
|
55
|
+
@values
|
56
|
+
end
|
57
|
+
|
58
|
+
def to_s
|
59
|
+
"<#{self.class} #{self.values}>"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
module Teapot
|
22
|
+
class Environment
|
23
|
+
Default = Struct.new(:value)
|
24
|
+
Replace = Struct.new(:value)
|
25
|
+
|
26
|
+
class Constructor
|
27
|
+
def initialize(environment)
|
28
|
+
@environment = environment
|
29
|
+
end
|
30
|
+
|
31
|
+
def method_missing(name, value = nil, &block)
|
32
|
+
if block_given?
|
33
|
+
@environment[name] = block
|
34
|
+
else
|
35
|
+
@environment[name] = value
|
36
|
+
end
|
37
|
+
|
38
|
+
name
|
39
|
+
end
|
40
|
+
|
41
|
+
def [] key
|
42
|
+
@environment[key]
|
43
|
+
end
|
44
|
+
|
45
|
+
def default(name)
|
46
|
+
@environment[name] = Default.new(@environment[name])
|
47
|
+
end
|
48
|
+
|
49
|
+
def replace(name)
|
50
|
+
@environment[name] = Replace.new(@environment[name])
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.combine(*environments)
|
55
|
+
# Flatten the list of environments:
|
56
|
+
environments = environments.collect do |environment|
|
57
|
+
if Environment === environment
|
58
|
+
environment.to_a
|
59
|
+
else
|
60
|
+
environment
|
61
|
+
end
|
62
|
+
end.flatten
|
63
|
+
|
64
|
+
# Resequence based on order:
|
65
|
+
first = Environment.new(nil, environments.shift)
|
66
|
+
top = first
|
67
|
+
|
68
|
+
environments.each do |tail|
|
69
|
+
top = Environment.new(top, tail)
|
70
|
+
end
|
71
|
+
|
72
|
+
return top
|
73
|
+
end
|
74
|
+
|
75
|
+
def merge(&block)
|
76
|
+
self.class.combine(
|
77
|
+
self,
|
78
|
+
self.class.new(&block)
|
79
|
+
)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Convert the hierarchy of environments to an array where the parent comes before the child.
|
83
|
+
def to_a
|
84
|
+
flat = []
|
85
|
+
|
86
|
+
flatten_to_array(flat)
|
87
|
+
|
88
|
+
return flat
|
89
|
+
end
|
90
|
+
|
91
|
+
protected
|
92
|
+
|
93
|
+
def flatten_to_array(array)
|
94
|
+
if @parent
|
95
|
+
@parent.flatten_to_array(array)
|
96
|
+
end
|
97
|
+
|
98
|
+
array << self
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
module Teapot
|
22
|
+
class Environment
|
23
|
+
class Evaluator
|
24
|
+
def initialize(environment)
|
25
|
+
@environment = environment
|
26
|
+
end
|
27
|
+
|
28
|
+
def method_missing(name)
|
29
|
+
object_value(@environment[name])
|
30
|
+
end
|
31
|
+
|
32
|
+
# Compute the literal object value for a given key:
|
33
|
+
def object_value(value)
|
34
|
+
case value
|
35
|
+
when Array
|
36
|
+
value.collect{|item| object_value(item)}.flatten
|
37
|
+
when Symbol
|
38
|
+
object_value(@environment[value])
|
39
|
+
when Proc
|
40
|
+
object_value(instance_exec(&value))
|
41
|
+
when Default
|
42
|
+
object_value(value.value)
|
43
|
+
when Replace
|
44
|
+
object_value(value.value)
|
45
|
+
else
|
46
|
+
value
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
module Teapot
|
22
|
+
class Environment
|
23
|
+
def flatten
|
24
|
+
hash = {}
|
25
|
+
|
26
|
+
# Flatten this chain of environments:
|
27
|
+
flatten_to_hash(hash)
|
28
|
+
|
29
|
+
# Evaluate all items to their respective object value:
|
30
|
+
evaluator = Evaluator.new(hash)
|
31
|
+
|
32
|
+
# Evaluate all the individual environment values so that they are flat:
|
33
|
+
Hash[hash.map{|key, value| [key, evaluator.object_value(value)]}]
|
34
|
+
end
|
35
|
+
|
36
|
+
protected
|
37
|
+
|
38
|
+
def flatten_to_hash(hash)
|
39
|
+
if @parent
|
40
|
+
@parent.flatten_to_hash(hash)
|
41
|
+
end
|
42
|
+
|
43
|
+
@values.each do |key, value|
|
44
|
+
previous = hash[key]
|
45
|
+
|
46
|
+
if Replace === value
|
47
|
+
# Replace the parent value
|
48
|
+
hash[key] = value
|
49
|
+
elsif Array === previous
|
50
|
+
# Merge with the parent value
|
51
|
+
hash[key] = previous + Array(value)
|
52
|
+
elsif Default === value
|
53
|
+
# Update the parent value if not defined.
|
54
|
+
hash[key] = previous || value
|
55
|
+
else
|
56
|
+
hash[key] = value
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require 'rexec/environment'
|
22
|
+
require 'rainbow'
|
23
|
+
|
24
|
+
module Teapot
|
25
|
+
class Environment
|
26
|
+
module System
|
27
|
+
def self.shell_escape(value)
|
28
|
+
case value
|
29
|
+
when Array
|
30
|
+
value.flatten.collect{|argument| shell_escape(argument)}.join(' ')
|
31
|
+
else
|
32
|
+
# Ensure that any whitespace has been escaped:
|
33
|
+
value.to_s.gsub(/ /, '\ ')
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.convert_to_shell(values)
|
38
|
+
Hash[values.map{|key, value| [
|
39
|
+
key.to_s.upcase,
|
40
|
+
shell_escape(value)
|
41
|
+
]}]
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.dump(environment, io = STDOUT)
|
45
|
+
environment.to_hash.each do |key, value|
|
46
|
+
io.puts "#{key}:".rjust(20).color(:magenta) + " #{value.inspect}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Construct an environment from a given system environment:
|
52
|
+
def self.system_environment(env = ENV)
|
53
|
+
self.new(Hash[env.map{|key, value| [key.downcase.to_sym, value]}])
|
54
|
+
end
|
55
|
+
|
56
|
+
# Apply the environment to the current process temporarily:
|
57
|
+
def use(options = {}, &block)
|
58
|
+
# Flatten the environment to a hash:
|
59
|
+
values = flatten
|
60
|
+
|
61
|
+
# Convert the hash to suit typical shell specific arguments:
|
62
|
+
build_environment = System::convert_to_shell(values)
|
63
|
+
|
64
|
+
# Show the environment to the user:
|
65
|
+
System::dump(build_environment)
|
66
|
+
|
67
|
+
Dir.chdir(options[:in] || ".") do
|
68
|
+
RExec.env(build_environment) do
|
69
|
+
block.call(Environment::Evaluator.new(values))
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/teapot/environment.rb
CHANGED
@@ -18,242 +18,8 @@
|
|
18
18
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
|
-
require '
|
22
|
-
require '
|
23
|
-
|
24
|
-
require '
|
25
|
-
require '
|
26
|
-
|
27
|
-
require 'teapot/package'
|
28
|
-
require 'teapot/platform'
|
29
|
-
require 'teapot/commands'
|
30
|
-
|
31
|
-
module Teapot
|
32
|
-
class Environment
|
33
|
-
def self.system_environment(env = ENV)
|
34
|
-
self.new(Hash[env.to_hash.collect{|key, value| [key.downcase.to_sym, value]}])
|
35
|
-
end
|
36
|
-
|
37
|
-
def merge(&block)
|
38
|
-
self.class.combine(
|
39
|
-
self,
|
40
|
-
self.class.new(&block)
|
41
|
-
)
|
42
|
-
end
|
43
|
-
|
44
|
-
Default = Struct.new(:value)
|
45
|
-
Replace = Struct.new(:value)
|
46
|
-
|
47
|
-
class Constructor
|
48
|
-
def initialize(environment)
|
49
|
-
@environment = environment
|
50
|
-
end
|
51
|
-
|
52
|
-
def method_missing(name, value = nil, &block)
|
53
|
-
if block_given?
|
54
|
-
@environment[name] = block
|
55
|
-
else
|
56
|
-
@environment[name] = value
|
57
|
-
end
|
58
|
-
|
59
|
-
name
|
60
|
-
end
|
61
|
-
|
62
|
-
def [] key
|
63
|
-
@environment[key]
|
64
|
-
end
|
65
|
-
|
66
|
-
def default(name)
|
67
|
-
@environment[name] = Default.new(@environment[name])
|
68
|
-
end
|
69
|
-
|
70
|
-
def replace(name)
|
71
|
-
@environment[name] = Replace.new(@environment[name])
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
class Evaluator
|
76
|
-
def initialize(environment)
|
77
|
-
@environment = environment
|
78
|
-
end
|
79
|
-
|
80
|
-
def method_missing(name)
|
81
|
-
object_value(@environment[name])
|
82
|
-
end
|
83
|
-
|
84
|
-
private
|
85
|
-
|
86
|
-
# Compute the literal object value for a given key:
|
87
|
-
def object_value(value)
|
88
|
-
case value
|
89
|
-
when Array
|
90
|
-
value.collect{|item| object_value(item)}
|
91
|
-
when Symbol
|
92
|
-
object_value(@values[value])
|
93
|
-
when Proc
|
94
|
-
object_value(instance_exec(&value))
|
95
|
-
when Default
|
96
|
-
object_value(value.value)
|
97
|
-
when Replace
|
98
|
-
object_value(value.value)
|
99
|
-
else
|
100
|
-
value
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
def self.combine(*environments)
|
106
|
-
# Flatten the list of environments:
|
107
|
-
environments = environments.collect do |environment|
|
108
|
-
if Environment === environment
|
109
|
-
environment.to_a
|
110
|
-
else
|
111
|
-
environment
|
112
|
-
end
|
113
|
-
end.flatten
|
114
|
-
|
115
|
-
# Resequence based on order:
|
116
|
-
first = Environment.new(nil, environments.shift)
|
117
|
-
top = first
|
118
|
-
|
119
|
-
environments.each do |tail|
|
120
|
-
top = Environment.new(top, tail)
|
121
|
-
end
|
122
|
-
|
123
|
-
return top
|
124
|
-
end
|
125
|
-
|
126
|
-
def initialize(parent = nil, values = {}, &block)
|
127
|
-
@values = (values || {}).to_hash
|
128
|
-
@parent = parent
|
129
|
-
|
130
|
-
@evaluator = Evaluator.new(self)
|
131
|
-
|
132
|
-
if block_given?
|
133
|
-
construct(&block)
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
def construct(&block)
|
138
|
-
Constructor.new(self).instance_exec(&block)
|
139
|
-
end
|
140
|
-
|
141
|
-
def dup
|
142
|
-
self.class.new(@values)
|
143
|
-
end
|
144
|
-
|
145
|
-
attr :values
|
146
|
-
attr :parent
|
147
|
-
|
148
|
-
def lookup(name)
|
149
|
-
if @values.include? name
|
150
|
-
self
|
151
|
-
elsif @parent
|
152
|
-
@parent.lookup(name)
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
def [] (key)
|
157
|
-
environment = lookup(key)
|
158
|
-
|
159
|
-
environment ? environment.values[key] : nil
|
160
|
-
end
|
161
|
-
|
162
|
-
def []= (key, value)
|
163
|
-
@values[key] = value
|
164
|
-
end
|
165
|
-
|
166
|
-
def to_hash
|
167
|
-
@values
|
168
|
-
end
|
169
|
-
|
170
|
-
def flatten
|
171
|
-
hash = {}
|
172
|
-
|
173
|
-
flatten_to_hash(hash)
|
174
|
-
|
175
|
-
Environment.new(nil, hash)
|
176
|
-
end
|
177
|
-
|
178
|
-
def to_string_hash
|
179
|
-
Hash[@values.map{|key, value| [key, string_value(value)]}]
|
180
|
-
end
|
181
|
-
|
182
|
-
def to_system_environment_hash
|
183
|
-
Hash[@values.map{|key, value| [key.to_s.upcase, string_value(value)]}]
|
184
|
-
end
|
185
|
-
|
186
|
-
def use(options = {}, &block)
|
187
|
-
system_environment = flatten.to_system_environment_hash
|
188
|
-
|
189
|
-
puts YAML::dump(system_environment).color(:magenta)
|
190
|
-
|
191
|
-
Dir.chdir(options[:in] || ".") do
|
192
|
-
RExec.env(system_environment) do
|
193
|
-
block.call(@evaluator)
|
194
|
-
end
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
|
-
def to_s
|
199
|
-
"<#{self.class} #{self.values}>"
|
200
|
-
end
|
201
|
-
|
202
|
-
def to_a
|
203
|
-
flat = []
|
204
|
-
|
205
|
-
flatten_to_array(flat)
|
206
|
-
|
207
|
-
return flat
|
208
|
-
end
|
209
|
-
|
210
|
-
protected
|
211
|
-
|
212
|
-
def flatten_to_array(array)
|
213
|
-
if @parent
|
214
|
-
@parent.flatten_to_array(array)
|
215
|
-
end
|
216
|
-
|
217
|
-
array << self
|
218
|
-
end
|
219
|
-
|
220
|
-
def flatten_to_hash(hash)
|
221
|
-
if @parent
|
222
|
-
@parent.flatten_to_hash(hash)
|
223
|
-
end
|
224
|
-
|
225
|
-
@values.each do |key, value|
|
226
|
-
previous = hash[key]
|
227
|
-
|
228
|
-
if Replace === value
|
229
|
-
# Replace the parent value
|
230
|
-
hash[key] = value
|
231
|
-
elsif Array === previous
|
232
|
-
# Merge with the parent value
|
233
|
-
hash[key] = previous + Array(value)
|
234
|
-
elsif Default === value
|
235
|
-
# Update the parent value if not defined.
|
236
|
-
hash[key] = previous || value
|
237
|
-
else
|
238
|
-
hash[key] = value
|
239
|
-
end
|
240
|
-
end
|
241
|
-
end
|
242
|
-
|
243
|
-
# Compute the literal string value for a given key:
|
244
|
-
def string_value(value)
|
245
|
-
case value
|
246
|
-
when Array
|
247
|
-
value.collect{|item| string_value(item)}.join(' ')
|
248
|
-
when Symbol
|
249
|
-
string_value(@values[value])
|
250
|
-
when Proc
|
251
|
-
string_value(@evaluator.instance_exec(&value))
|
252
|
-
when Default
|
253
|
-
string_value(value.value)
|
254
|
-
else
|
255
|
-
value.to_s
|
256
|
-
end
|
257
|
-
end
|
258
|
-
end
|
259
|
-
end
|
21
|
+
require 'teapot/environment/base'
|
22
|
+
require 'teapot/environment/constructor'
|
23
|
+
require 'teapot/environment/evaluator'
|
24
|
+
require 'teapot/environment/flatten'
|
25
|
+
require 'teapot/environment/system'
|
data/lib/teapot/package.rb
CHANGED
@@ -110,15 +110,15 @@ module Teapot
|
|
110
110
|
)
|
111
111
|
|
112
112
|
local_build = environment.merge do
|
113
|
-
default build_prefix "build/cache/#{platform.name}-#{config[:variant]}"
|
113
|
+
default build_prefix Pathname.new("build/cache/#{platform.name}-#{config[:variant]}")
|
114
114
|
default install_prefix platform.prefix
|
115
115
|
|
116
116
|
buildflags [
|
117
|
-
"-I"
|
117
|
+
->{"-I" + (platform.prefix + "include").to_s},
|
118
118
|
]
|
119
119
|
|
120
120
|
linkflags [
|
121
|
-
"-L"
|
121
|
+
->{"-L" + (platform.prefix + "lib").to_s},
|
122
122
|
]
|
123
123
|
end
|
124
124
|
|
data/lib/teapot/platform.rb
CHANGED
data/lib/teapot/version.rb
CHANGED
data/test/test_environment.rb
CHANGED
@@ -40,7 +40,7 @@ class TestEnvironment < Test::Unit::TestCase
|
|
40
40
|
def test_environment_lambda
|
41
41
|
a = Teapot::Environment.new do
|
42
42
|
sdk "bob-2.6"
|
43
|
-
|
43
|
+
cflags [->{"-sdk=#{sdk}"}]
|
44
44
|
end
|
45
45
|
|
46
46
|
b = Teapot::Environment.new(a) do
|
@@ -48,21 +48,21 @@ class TestEnvironment < Test::Unit::TestCase
|
|
48
48
|
end
|
49
49
|
|
50
50
|
c = Teapot::Environment.new(b) do
|
51
|
-
|
51
|
+
cflags ["-pipe"]
|
52
52
|
end
|
53
53
|
|
54
54
|
expected = {'SDK' => "bob-2.8", 'CCFLAGS' => "-sdk=bob-2.8"}
|
55
55
|
|
56
|
-
assert_equal [:
|
56
|
+
assert_equal [:cflags, :sdk], b.flatten.to_hash.keys.sort
|
57
57
|
assert_equal expected, b.flatten.to_system_environment_hash
|
58
58
|
|
59
|
-
assert_equal "-sdk=bob-2.8 -pipe", c.flatten.to_string_hash[:
|
59
|
+
assert_equal "-sdk=bob-2.8 -pipe", c.flatten.to_string_hash[:cflags]
|
60
60
|
end
|
61
61
|
|
62
62
|
def test_environment_nested_lambda
|
63
63
|
a = Teapot::Environment.new do
|
64
64
|
sdk "bob-2.6"
|
65
|
-
|
65
|
+
cflags [->{"-sdk=#{sdk}"}]
|
66
66
|
end
|
67
67
|
|
68
68
|
b = Teapot::Environment.new(a) do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: teapot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -82,6 +82,11 @@ files:
|
|
82
82
|
- lib/teapot/config.rb
|
83
83
|
- lib/teapot/context.rb
|
84
84
|
- lib/teapot/environment.rb
|
85
|
+
- lib/teapot/environment/base.rb
|
86
|
+
- lib/teapot/environment/constructor.rb
|
87
|
+
- lib/teapot/environment/evaluator.rb
|
88
|
+
- lib/teapot/environment/flatten.rb
|
89
|
+
- lib/teapot/environment/system.rb
|
85
90
|
- lib/teapot/package.rb
|
86
91
|
- lib/teapot/platform.rb
|
87
92
|
- lib/teapot/version.rb
|
@@ -101,7 +106,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
101
106
|
version: '0'
|
102
107
|
segments:
|
103
108
|
- 0
|
104
|
-
hash:
|
109
|
+
hash: 4295501369315822730
|
105
110
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
106
111
|
none: false
|
107
112
|
requirements:
|
@@ -110,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
110
115
|
version: '0'
|
111
116
|
segments:
|
112
117
|
- 0
|
113
|
-
hash:
|
118
|
+
hash: 4295501369315822730
|
114
119
|
requirements: []
|
115
120
|
rubyforge_project:
|
116
121
|
rubygems_version: 1.8.24
|