teapot 0.0.1 → 0.0.3
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/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/README.md +46 -1
- data/Rakefile +8 -0
- data/bin/teapot +103 -35
- data/lib/teapot/commands.rb +32 -0
- data/lib/teapot/config.rb +39 -1
- data/lib/teapot/context.rb +10 -6
- data/lib/teapot/environment.rb +232 -0
- data/lib/teapot/package.rb +75 -60
- data/lib/teapot/platform.rb +42 -42
- data/lib/teapot/version.rb +21 -1
- data/lib/teapot.rb +20 -1
- data/teapot.gemspec +1 -0
- data/test/test_environment.rb +69 -0
- metadata +26 -5
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -4,6 +4,8 @@ Teapot is a tool for managing complex cross-platform builds. It provides
|
|
4
4
|
advanced dependency management via the Teapot file and is supported by
|
5
5
|
the infusions ecosystem of packages and platform tooling.
|
6
6
|
|
7
|
+
[](http://travis-ci.org/ioquatix/teapot)
|
8
|
+
|
7
9
|
## Installation
|
8
10
|
|
9
11
|
Add this line to your application's Gemfile:
|
@@ -20,7 +22,50 @@ Or install it yourself as:
|
|
20
22
|
|
21
23
|
## Usage
|
22
24
|
|
23
|
-
|
25
|
+
Create a Teapot file in the root directory of your project:
|
26
|
+
|
27
|
+
source "https://github.com/infusions"
|
28
|
+
|
29
|
+
host /linux/ do
|
30
|
+
platform "linux"
|
31
|
+
end
|
32
|
+
|
33
|
+
host /darwin/ do
|
34
|
+
platform "darwin-osx"
|
35
|
+
end
|
36
|
+
|
37
|
+
package "png"
|
38
|
+
package "freetype"
|
39
|
+
package "vorbis"
|
40
|
+
package "ogg"
|
41
|
+
package "jpeg"
|
42
|
+
|
43
|
+
Then run
|
44
|
+
|
45
|
+
$ teapot install
|
46
|
+
|
47
|
+
This will download and compile all the selected packages into the `build` directory.
|
48
|
+
|
49
|
+
### CMake ###
|
50
|
+
|
51
|
+
To use these packages in a CMake project, update your `CMakeLists.txt`:
|
52
|
+
|
53
|
+
list(APPEND CMAKE_PREFIX_PATH "${CMAKE_SOURCE_DIR}/build/${TEAPOT_PLATFORM}/")
|
54
|
+
|
55
|
+
Then configure like so:
|
56
|
+
|
57
|
+
cmake path/to/src -DTEAPOT_PLATFORM=linux
|
58
|
+
|
59
|
+
### Xcode ###
|
60
|
+
|
61
|
+
To use these packages in an Xcode project, creating a custom `teapot.xcconfig` is recommended:
|
62
|
+
|
63
|
+
TEAPOT_PLATFORM=darwin-osx
|
64
|
+
TEAPOT_PREFIX_PATH=$(SRCROOT)/build/$(TEAPOT_PLATFORM)
|
65
|
+
|
66
|
+
// Search paths:
|
67
|
+
HEADER_SEARCH_PATHS=$(inherited) "$(TEAPOT_PREFIX_PATH)/include"
|
68
|
+
LIBRARY_SEARCH_PATHS=$(inherited) "$(TEAPOT_PREFIX_PATH)/lib"
|
24
69
|
|
25
70
|
## Contributing
|
26
71
|
|
data/Rakefile
CHANGED
data/bin/teapot
CHANGED
@@ -30,7 +30,7 @@ $app = Rake.application = Rake::Application.new
|
|
30
30
|
$app.init('teapot')
|
31
31
|
|
32
32
|
task :fetch do
|
33
|
-
config = Teapot::Config.
|
33
|
+
config = Teapot::Config.load_default
|
34
34
|
context = Teapot::Context.new(config)
|
35
35
|
|
36
36
|
base_uri = URI(config.options[:source].to_s + '/')
|
@@ -38,10 +38,10 @@ task :fetch do
|
|
38
38
|
config.records.each do |record|
|
39
39
|
destination_path = record.destination_path
|
40
40
|
|
41
|
-
|
41
|
+
puts "Fetching #{record}...".color(:blue)
|
42
42
|
|
43
43
|
unless File.exist? destination_path
|
44
|
-
|
44
|
+
puts "Cloning package at path #{destination_path} ...".color(:green)
|
45
45
|
|
46
46
|
source_uri = URI(record.uri)
|
47
47
|
|
@@ -53,59 +53,127 @@ task :fetch do
|
|
53
53
|
source_uri = source_uri.path
|
54
54
|
end
|
55
55
|
|
56
|
-
|
56
|
+
Teapot::Commands.run("git", "clone", "--recursive", source_uri.to_s, destination_path.to_s)
|
57
57
|
else
|
58
|
-
|
58
|
+
puts "Updating package at path #{destination_path} ...".color(:green)
|
59
59
|
|
60
60
|
Dir.chdir(destination_path) do
|
61
|
-
|
61
|
+
Teapot::Commands.run("git", "pull")
|
62
|
+
Teapot::Commands.run("git", "submodule", "update", "--init")
|
62
63
|
end
|
63
64
|
end
|
64
65
|
end
|
65
66
|
end
|
66
67
|
|
67
|
-
task :
|
68
|
-
config = Teapot::Config.
|
68
|
+
task :build do
|
69
|
+
config = Teapot::Config.load_default
|
69
70
|
context = Teapot::Context.new(config)
|
70
71
|
|
71
72
|
config.records.each do |record|
|
72
|
-
|
73
|
-
|
74
|
-
record.load(context)
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
if !location
|
79
|
-
puts "Could not determine fetch location for #{name}!".color(:red)
|
80
|
-
elsif File.exist? bundle.source_path
|
81
|
-
puts "Source path #{bundle.source_path} already exists!".color(:red)
|
82
|
-
else
|
83
|
-
url = location[:url]
|
84
|
-
local_path = bundle.path + (location[:filename] || File.basename(url))
|
73
|
+
destination_path = record.destination_path
|
74
|
+
|
75
|
+
bundles = record.load(context)
|
76
|
+
|
77
|
+
bundles.each do |bundle|
|
85
78
|
|
86
|
-
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
task :build do |task, arguments|
|
84
|
+
config = Teapot::Config.load_default
|
85
|
+
context = Teapot::Context.new(config)
|
86
|
+
|
87
|
+
config.records.each do |record|
|
88
|
+
destination_path = record.destination_path
|
89
|
+
|
90
|
+
record.load(context)
|
91
|
+
end
|
92
|
+
|
93
|
+
build_package = ENV['PACKAGE']
|
94
|
+
build_platform = ENV['PLATFORM']
|
95
|
+
|
96
|
+
if build_package
|
97
|
+
package = context.packages[build_package]
|
98
|
+
|
99
|
+
unless package
|
100
|
+
puts "Could not find package #{build_package}".color(:red)
|
87
101
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
102
|
+
next
|
103
|
+
end
|
104
|
+
|
105
|
+
packages = [package]
|
106
|
+
else
|
107
|
+
packages = context.packages.values
|
108
|
+
end
|
109
|
+
|
110
|
+
if build_platform
|
111
|
+
platform = context.platforms[build_platform.to_sym]
|
112
|
+
|
113
|
+
unless platform
|
114
|
+
puts "Could not find platform #{build_platform}".color(:red)
|
93
115
|
|
94
|
-
|
95
|
-
sh("mkdir", bundle.source_path.to_s)
|
96
|
-
sh("tar", "-C", bundle.source_path.to_s, "--strip-components", "1", "-xvf", local_path.to_s)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
116
|
+
next
|
100
117
|
end
|
118
|
+
|
119
|
+
platforms = [platform]
|
120
|
+
end
|
121
|
+
|
122
|
+
unless ENV['ONLY']
|
123
|
+
ordered = Teapot::Package.build_order(context.packages, packages)
|
124
|
+
else
|
125
|
+
ordered = packages
|
126
|
+
end
|
127
|
+
|
128
|
+
puts "Building #{ordered.join(', ')} for variant #{config.variant}".color(:blue)
|
129
|
+
|
130
|
+
context.platforms.each do |name, platform|
|
131
|
+
next unless platform.available?
|
132
|
+
|
133
|
+
puts "Building for #{platform}...".color(:blue)
|
134
|
+
|
135
|
+
platform.prepare!
|
136
|
+
|
137
|
+
ordered.each do |package|
|
138
|
+
package.build!(platform, :variant => config.variant)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
puts "Completed build successfully.".color(:green)
|
143
|
+
end
|
144
|
+
|
145
|
+
task :list do
|
146
|
+
config = Teapot::Config.load_default
|
147
|
+
context = Teapot::Context.new(config)
|
148
|
+
|
149
|
+
config.records.each do |record|
|
150
|
+
destination_path = record.destination_path
|
151
|
+
|
152
|
+
record.load(context)
|
153
|
+
end
|
154
|
+
|
155
|
+
ordered = Teapot::Package::build_order(context.packages, context.packages.values)
|
156
|
+
|
157
|
+
ordered.each do |package|
|
158
|
+
puts "Package: #{package.name}"
|
159
|
+
|
160
|
+
if package.depends.size > 0
|
161
|
+
puts " (depends on #{package.depends.join(', ')})"
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
context.platforms.each do |platform|
|
166
|
+
puts "Platform: #{platform.name}"
|
101
167
|
end
|
102
168
|
end
|
103
169
|
|
104
170
|
task :help do
|
105
|
-
|
106
|
-
|
171
|
+
puts "To create a new teapot, use the setup task:"
|
172
|
+
puts "$ #{File.basename($0)} setup project-path"
|
107
173
|
end
|
108
174
|
|
175
|
+
task :install => [:fetch, :build]
|
176
|
+
|
109
177
|
task :default => :help
|
110
178
|
|
111
179
|
$app.top_level
|
@@ -0,0 +1,32 @@
|
|
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 'rainbow'
|
22
|
+
|
23
|
+
module Teapot
|
24
|
+
module Commands
|
25
|
+
def self.run(*args)
|
26
|
+
args.collect!(&:to_s)
|
27
|
+
|
28
|
+
puts args.join(' ').color(:blue)
|
29
|
+
system(*args)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/teapot/config.rb
CHANGED
@@ -21,6 +21,8 @@
|
|
21
21
|
require 'pathname'
|
22
22
|
|
23
23
|
require 'teapot/context'
|
24
|
+
require 'teapot/environment'
|
25
|
+
require 'teapot/commands'
|
24
26
|
|
25
27
|
module Teapot
|
26
28
|
class Config
|
@@ -42,12 +44,14 @@ module Teapot
|
|
42
44
|
end
|
43
45
|
|
44
46
|
@options = options
|
47
|
+
@global = Environment.new
|
45
48
|
end
|
46
49
|
|
47
50
|
attr :klass
|
48
51
|
attr :name
|
49
52
|
attr :uri
|
50
53
|
attr :options
|
54
|
+
attr :global
|
51
55
|
|
52
56
|
def load(context)
|
53
57
|
context.load(self)
|
@@ -84,6 +88,8 @@ module Teapot
|
|
84
88
|
|
85
89
|
@packages = []
|
86
90
|
@platforms = []
|
91
|
+
|
92
|
+
@environment = Environment.new
|
87
93
|
end
|
88
94
|
|
89
95
|
def packages_path
|
@@ -98,9 +104,34 @@ module Teapot
|
|
98
104
|
@root + (@options[:build_path] || "build")
|
99
105
|
end
|
100
106
|
|
107
|
+
def variant(*args, &block)
|
108
|
+
name = @options[:variant] || 'debug'
|
109
|
+
|
110
|
+
if block_given?
|
111
|
+
if args.find{|arg| arg === name}
|
112
|
+
yield
|
113
|
+
end
|
114
|
+
else
|
115
|
+
name
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def host(*args, &block)
|
120
|
+
name = @options[:host_platform] || RUBY_PLATFORM
|
121
|
+
|
122
|
+
if block_given?
|
123
|
+
if args.find{|arg| arg === name}
|
124
|
+
yield
|
125
|
+
end
|
126
|
+
else
|
127
|
+
name
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
101
131
|
attr :options
|
102
132
|
attr :packages
|
103
133
|
attr :platforms
|
134
|
+
attr :environment
|
104
135
|
|
105
136
|
def source(path)
|
106
137
|
@options[:source] = path
|
@@ -115,10 +146,11 @@ module Teapot
|
|
115
146
|
end
|
116
147
|
|
117
148
|
def platform(name, options = {})
|
149
|
+
options = {:environment => @environment}.merge(options)
|
118
150
|
@platforms << Record.new(self, Platform, name, options)
|
119
151
|
end
|
120
152
|
|
121
|
-
def self.load(root
|
153
|
+
def self.load(root, options = {})
|
122
154
|
config = new(root, options)
|
123
155
|
|
124
156
|
teapot_path = File.join(root, "Teapot")
|
@@ -129,5 +161,11 @@ module Teapot
|
|
129
161
|
|
130
162
|
return config
|
131
163
|
end
|
164
|
+
|
165
|
+
def self.load_default(root = Dir.getwd, options = {})
|
166
|
+
options.merge!(:variant => ENV['TEAPOT_VARIANT'])
|
167
|
+
|
168
|
+
load(root, options)
|
169
|
+
end
|
132
170
|
end
|
133
171
|
end
|
data/lib/teapot/context.rb
CHANGED
@@ -19,13 +19,12 @@
|
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
21
|
require 'pathname'
|
22
|
+
require 'rainbow'
|
22
23
|
|
23
24
|
require 'teapot/package'
|
24
25
|
require 'teapot/platform'
|
25
26
|
|
26
27
|
module Teapot
|
27
|
-
PACKAGE_FILE = "package.rb"
|
28
|
-
|
29
28
|
class Context
|
30
29
|
def initialize(config)
|
31
30
|
@config = config
|
@@ -41,6 +40,7 @@ module Teapot
|
|
41
40
|
attr :platforms
|
42
41
|
|
43
42
|
def load(record)
|
43
|
+
@record = record
|
44
44
|
@defined = []
|
45
45
|
|
46
46
|
path = (record.destination_path + record.loader_path).to_s
|
@@ -49,8 +49,8 @@ module Teapot
|
|
49
49
|
@defined
|
50
50
|
end
|
51
51
|
|
52
|
-
def define_package(
|
53
|
-
package = Package.new(self,
|
52
|
+
def define_package(*args, &block)
|
53
|
+
package = Package.new(self, @record, *args)
|
54
54
|
|
55
55
|
yield(package)
|
56
56
|
|
@@ -59,8 +59,8 @@ module Teapot
|
|
59
59
|
@defined << package
|
60
60
|
end
|
61
61
|
|
62
|
-
def define_platform(
|
63
|
-
platform = Platform.new(self,
|
62
|
+
def define_platform(*args, &block)
|
63
|
+
platform = Platform.new(self, @record, *args)
|
64
64
|
|
65
65
|
yield(platform)
|
66
66
|
|
@@ -70,5 +70,9 @@ module Teapot
|
|
70
70
|
|
71
71
|
@defined << platform
|
72
72
|
end
|
73
|
+
|
74
|
+
def global name
|
75
|
+
@config.environment[name]
|
76
|
+
end
|
73
77
|
end
|
74
78
|
end
|
@@ -0,0 +1,232 @@
|
|
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 'pathname'
|
22
|
+
require 'rainbow'
|
23
|
+
|
24
|
+
require 'rexec'
|
25
|
+
require 'yaml'
|
26
|
+
|
27
|
+
require 'teapot/package'
|
28
|
+
require 'teapot/platform'
|
29
|
+
require 'teapot/commands'
|
30
|
+
|
31
|
+
module Teapot
|
32
|
+
class Environment
|
33
|
+
Default = Struct.new(:value)
|
34
|
+
|
35
|
+
class Constructor
|
36
|
+
def initialize(environment)
|
37
|
+
@environment = environment
|
38
|
+
end
|
39
|
+
|
40
|
+
def method_missing(name, value = nil, &block)
|
41
|
+
if block_given?
|
42
|
+
@environment[name] = block
|
43
|
+
else
|
44
|
+
@environment[name] = value
|
45
|
+
end
|
46
|
+
|
47
|
+
name
|
48
|
+
end
|
49
|
+
|
50
|
+
def [] key
|
51
|
+
@environment[key]
|
52
|
+
end
|
53
|
+
|
54
|
+
def default(name)
|
55
|
+
@environment[name] = Default.new(@environment[name])
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
class Evaluator
|
60
|
+
def initialize(environment)
|
61
|
+
@environment = environment
|
62
|
+
end
|
63
|
+
|
64
|
+
def method_missing(name)
|
65
|
+
object_value(@environment[name])
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
# Compute the literal object value for a given key:
|
71
|
+
def object_value(value)
|
72
|
+
case value
|
73
|
+
when Array
|
74
|
+
value.collect{|item| object_value(item)}
|
75
|
+
when Symbol
|
76
|
+
object_value(@values[value])
|
77
|
+
when Proc
|
78
|
+
object_value(instance_eval(&value))
|
79
|
+
when Default
|
80
|
+
object_value(value.value)
|
81
|
+
else
|
82
|
+
value
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.combine(*environments)
|
88
|
+
# Flatten the list of environments:
|
89
|
+
environments = environments.collect do |environment|
|
90
|
+
if Environment === environment
|
91
|
+
environment.to_a
|
92
|
+
else
|
93
|
+
environment
|
94
|
+
end
|
95
|
+
end.flatten
|
96
|
+
|
97
|
+
# Resequence based on order:
|
98
|
+
first = Environment.new(nil, environments.shift)
|
99
|
+
top = first
|
100
|
+
|
101
|
+
environments.each do |tail|
|
102
|
+
top = Environment.new(top, tail)
|
103
|
+
end
|
104
|
+
|
105
|
+
return top
|
106
|
+
end
|
107
|
+
|
108
|
+
def initialize(parent = nil, values = nil, &block)
|
109
|
+
@values = (values || {}).to_hash
|
110
|
+
@parent = parent
|
111
|
+
|
112
|
+
@evaluator = Evaluator.new(self)
|
113
|
+
|
114
|
+
if block_given?
|
115
|
+
construct(&block)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def construct(&block)
|
120
|
+
Constructor.new(self).instance_eval(&block)
|
121
|
+
end
|
122
|
+
|
123
|
+
def dup
|
124
|
+
self.class.new(@values)
|
125
|
+
end
|
126
|
+
|
127
|
+
attr :values
|
128
|
+
attr :parent
|
129
|
+
|
130
|
+
def [] (key)
|
131
|
+
environment = lookup(key)
|
132
|
+
|
133
|
+
environment ? environment.values[key] : nil
|
134
|
+
end
|
135
|
+
|
136
|
+
def []= (key, value)
|
137
|
+
@values[key] = value
|
138
|
+
end
|
139
|
+
|
140
|
+
def to_hash
|
141
|
+
@values
|
142
|
+
end
|
143
|
+
|
144
|
+
def flatten
|
145
|
+
hash = {}
|
146
|
+
|
147
|
+
flatten_to_hash(hash)
|
148
|
+
|
149
|
+
Environment.new(nil, hash)
|
150
|
+
end
|
151
|
+
|
152
|
+
def to_string_hash
|
153
|
+
Hash[@values.map{|key, value| [key.to_s.upcase, string_value(value)]}]
|
154
|
+
end
|
155
|
+
|
156
|
+
def use(options = {}, &block)
|
157
|
+
system_environment = flatten.to_string_hash
|
158
|
+
|
159
|
+
puts YAML::dump(system_environment).color(:magenta)
|
160
|
+
|
161
|
+
Dir.chdir(options[:in] || ".") do
|
162
|
+
RExec.env(system_environment) do
|
163
|
+
@evaluator.instance_eval(&block)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def to_s
|
169
|
+
"<#{self.class} #{self.values}>"
|
170
|
+
end
|
171
|
+
|
172
|
+
def to_a
|
173
|
+
flat = []
|
174
|
+
|
175
|
+
flatten_to_array(flat)
|
176
|
+
|
177
|
+
return flat
|
178
|
+
end
|
179
|
+
|
180
|
+
protected
|
181
|
+
|
182
|
+
def flatten_to_array(array)
|
183
|
+
if @parent
|
184
|
+
@parent.flatten_to_array(array)
|
185
|
+
end
|
186
|
+
|
187
|
+
array << self
|
188
|
+
end
|
189
|
+
|
190
|
+
def flatten_to_hash(hash)
|
191
|
+
if @parent
|
192
|
+
@parent.flatten_to_hash(hash)
|
193
|
+
end
|
194
|
+
|
195
|
+
@values.each do |key, value|
|
196
|
+
previous = hash[key]
|
197
|
+
|
198
|
+
if Array === previous
|
199
|
+
hash[key] = previous + Array(value)
|
200
|
+
elsif Default == previous
|
201
|
+
hash[key] ||= previous
|
202
|
+
else
|
203
|
+
hash[key] = value
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
# Compute the literal string value for a given key:
|
209
|
+
def string_value(value)
|
210
|
+
case value
|
211
|
+
when Array
|
212
|
+
value.collect{|item| string_value(item)}.join(' ')
|
213
|
+
when Symbol
|
214
|
+
string_value(@values[value])
|
215
|
+
when Proc
|
216
|
+
string_value(@evaluator.instance_eval(&value))
|
217
|
+
when Default
|
218
|
+
string_value(value.value)
|
219
|
+
else
|
220
|
+
value.to_s
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
def lookup(name)
|
225
|
+
if @values.include? name
|
226
|
+
self
|
227
|
+
elsif @parent
|
228
|
+
@parent.lookup(name)
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
data/lib/teapot/package.rb
CHANGED
@@ -1,82 +1,71 @@
|
|
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.
|
1
20
|
|
2
21
|
require 'pathname'
|
3
22
|
|
4
23
|
module Teapot
|
5
|
-
class
|
6
|
-
|
24
|
+
class BuildError < StandardError
|
25
|
+
end
|
26
|
+
|
27
|
+
class Task
|
28
|
+
def initialize
|
29
|
+
@callbacks = {}
|
7
30
|
end
|
8
|
-
|
9
|
-
class Task
|
10
|
-
def initialize
|
11
|
-
@callbacks = {}
|
12
|
-
end
|
13
31
|
|
14
|
-
|
15
|
-
|
16
|
-
end
|
17
|
-
|
18
|
-
def [](name)
|
19
|
-
@callbacks[name] || @callbacks[:all]
|
20
|
-
end
|
32
|
+
def define(name, &callback)
|
33
|
+
@callbacks[name] = callback
|
21
34
|
end
|
22
|
-
|
23
|
-
def
|
24
|
-
|
25
|
-
|
26
|
-
expand = lambda do |name|
|
27
|
-
package = available[name]
|
28
|
-
|
29
|
-
unless package
|
30
|
-
puts "Couldn't resolve #{name}"
|
31
|
-
else
|
32
|
-
package.depends.each do |dependency|
|
33
|
-
expand.call(dependency)
|
34
|
-
end
|
35
|
-
|
36
|
-
unless ordered.include? package
|
37
|
-
ordered << package
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
packages.each do |package|
|
43
|
-
expand.call(package.name)
|
44
|
-
end
|
45
|
-
|
46
|
-
return ordered
|
35
|
+
|
36
|
+
def [](name)
|
37
|
+
@callbacks[name] || @callbacks[:all]
|
47
38
|
end
|
48
|
-
|
49
|
-
|
39
|
+
end
|
40
|
+
|
41
|
+
class Package
|
42
|
+
def initialize(context, record, name)
|
50
43
|
@context = context
|
51
|
-
|
44
|
+
@record = record
|
45
|
+
|
52
46
|
parts = name.split('-')
|
53
47
|
@name = parts[0..-2].join('-')
|
54
48
|
@version = parts[-1]
|
55
49
|
|
56
|
-
@path = path || (context.config.packages_path + @name)
|
57
|
-
|
58
50
|
@build = Task.new
|
59
51
|
|
60
52
|
@depends = []
|
61
53
|
|
54
|
+
@path = @record.destination_path
|
62
55
|
@source_path = @path + name
|
63
|
-
@fetch_location = nil
|
64
56
|
end
|
65
57
|
|
58
|
+
attr :context
|
59
|
+
attr :record
|
60
|
+
|
66
61
|
attr :name
|
67
62
|
attr :version
|
63
|
+
|
68
64
|
attr :path
|
69
|
-
attr :variants
|
70
|
-
attr :fetch_location
|
71
65
|
|
72
66
|
attr :depends, true
|
73
67
|
attr :source_path, true
|
74
68
|
|
75
|
-
def install!
|
76
|
-
if @fetch_location
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
69
|
def build(platform, &block)
|
81
70
|
@build.define(platform, &block)
|
82
71
|
end
|
@@ -84,23 +73,49 @@ module Teapot
|
|
84
73
|
def build!(platform = :all, config = {})
|
85
74
|
task = @build[platform.name]
|
86
75
|
|
87
|
-
puts "Building #{@name} for #{platform.name}"
|
88
76
|
if task
|
77
|
+
environment = Environment.combine(
|
78
|
+
@record.options[:environment],
|
79
|
+
platform.environment,
|
80
|
+
config,
|
81
|
+
)
|
82
|
+
|
89
83
|
Dir.chdir(@path) do
|
90
|
-
|
91
|
-
task.call(platform, platform.config.merge(config))
|
84
|
+
task.call(platform, environment)
|
92
85
|
end
|
93
86
|
else
|
94
|
-
raise BuildError.new("Could not find task
|
87
|
+
raise BuildError.new("Could not find build task for #{platform.name}!")
|
95
88
|
end
|
96
89
|
end
|
97
90
|
|
98
|
-
def fetch_from(location)
|
99
|
-
@fetch_location = location
|
100
|
-
end
|
101
|
-
|
102
91
|
def to_s
|
103
92
|
"<Package: #{@name}>"
|
104
93
|
end
|
94
|
+
|
95
|
+
def self.build_order(available, packages)
|
96
|
+
ordered = []
|
97
|
+
|
98
|
+
expand = lambda do |name|
|
99
|
+
package = available[name]
|
100
|
+
|
101
|
+
unless package
|
102
|
+
puts "Couldn't resolve #{name}"
|
103
|
+
else
|
104
|
+
package.depends.each do |dependency|
|
105
|
+
expand.call(dependency)
|
106
|
+
end
|
107
|
+
|
108
|
+
unless ordered.include? package
|
109
|
+
ordered << package
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
packages.each do |package|
|
115
|
+
expand.call(package.name)
|
116
|
+
end
|
117
|
+
|
118
|
+
return ordered
|
119
|
+
end
|
105
120
|
end
|
106
121
|
end
|
data/lib/teapot/platform.rb
CHANGED
@@ -1,32 +1,43 @@
|
|
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.
|
1
20
|
|
2
21
|
require 'fileutils'
|
22
|
+
require 'rexec/environment'
|
3
23
|
|
4
24
|
module Teapot
|
25
|
+
class UnavailableError < StandardError
|
26
|
+
end
|
27
|
+
|
5
28
|
class Platform
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
29
|
+
def initialize(context, record, name)
|
30
|
+
@context = context
|
31
|
+
@record = record
|
32
|
+
|
33
|
+
@name = name
|
34
|
+
@configure = nil
|
35
|
+
|
36
|
+
@available = false
|
37
|
+
end
|
10
38
|
|
11
|
-
|
39
|
+
attr :name
|
12
40
|
|
13
|
-
def method_missing(name, *args)
|
14
|
-
if name.to_s.match(/^(.*?)(\=)?$/)
|
15
|
-
if $2
|
16
|
-
return @values[$1.to_sym] = args[0]
|
17
|
-
else
|
18
|
-
return @values[$1.to_sym]
|
19
|
-
end
|
20
|
-
else
|
21
|
-
super(name, *args)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def merge(config)
|
26
|
-
Config.new(@values.merge(config))
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
41
|
def prefix
|
31
42
|
@context.config.build_path + @name.to_s
|
32
43
|
end
|
@@ -34,30 +45,19 @@ module Teapot
|
|
34
45
|
def cmake_modules_path
|
35
46
|
prefix + "share/cmake/modules"
|
36
47
|
end
|
37
|
-
|
38
|
-
def initialize(context, name)
|
39
|
-
@context = context
|
40
|
-
|
41
|
-
@name = name
|
42
|
-
@config = nil
|
43
|
-
@available = false
|
44
|
-
end
|
45
|
-
|
46
|
-
attr :name
|
47
48
|
|
48
49
|
def configure(&block)
|
49
|
-
@
|
50
|
+
@configure = Proc.new &block
|
50
51
|
end
|
51
52
|
|
52
|
-
def
|
53
|
-
if available
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
return config
|
53
|
+
def environment
|
54
|
+
if @available
|
55
|
+
return Environment.combine(
|
56
|
+
@record.options[:environment],
|
57
|
+
Environment.new(&@configure),
|
58
|
+
)
|
59
59
|
else
|
60
|
-
|
60
|
+
raise UnavailableError.new("Platform is not available for configuration!")
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
@@ -70,7 +70,7 @@ module Teapot
|
|
70
70
|
end
|
71
71
|
|
72
72
|
def to_s
|
73
|
-
"<Platform #{@name}: #{@
|
73
|
+
"<Platform #{@name}: #{@available ? 'available' : 'inactive'}>"
|
74
74
|
end
|
75
75
|
|
76
76
|
def prepare!
|
data/lib/teapot/version.rb
CHANGED
@@ -1,3 +1,23 @@
|
|
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
|
+
|
1
21
|
module Teapot
|
2
|
-
|
22
|
+
VERSION = "0.0.3"
|
3
23
|
end
|
data/lib/teapot.rb
CHANGED
@@ -1,5 +1,24 @@
|
|
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
|
+
|
1
21
|
require "teapot/version"
|
2
22
|
|
3
23
|
module Teapot
|
4
|
-
# Your code goes here...
|
5
24
|
end
|
data/teapot.gemspec
CHANGED
@@ -0,0 +1,69 @@
|
|
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 'pathname'
|
22
|
+
require 'test/unit'
|
23
|
+
require 'stringio'
|
24
|
+
|
25
|
+
require 'teapot/environment'
|
26
|
+
|
27
|
+
class TestEnvironment < Test::Unit::TestCase
|
28
|
+
def test_environment_chaining
|
29
|
+
a = Teapot::Environment.new
|
30
|
+
a[:cflags] = ["-std=c++11"]
|
31
|
+
|
32
|
+
b = Teapot::Environment.new(a)
|
33
|
+
b[:cflags] = ["-stdlib=libc++"]
|
34
|
+
|
35
|
+
expected = {:cflags => ["-std=c++11", "-stdlib=libc++"]}
|
36
|
+
|
37
|
+
assert_equal expected, b.flatten.to_hash
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_environment_lambda
|
41
|
+
a = Teapot::Environment.new do
|
42
|
+
sdk "bob-2.6"
|
43
|
+
cflags {"-sdk=#{sdk}"}
|
44
|
+
end
|
45
|
+
|
46
|
+
b = Teapot::Environment.new(a) do
|
47
|
+
sdk "bob-2.8"
|
48
|
+
end
|
49
|
+
|
50
|
+
expected = {'SDK' => "bob-2.8", 'CFLAGS' => "-sdk=bob-2.8"}
|
51
|
+
|
52
|
+
assert_equal [:cflags, :sdk], b.flatten.to_hash.keys.sort
|
53
|
+
assert_equal expected, b.flatten.to_string_hash
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_combine
|
57
|
+
a = Teapot::Environment.new(nil, {:name => 'a'})
|
58
|
+
b = Teapot::Environment.new(a, {:name => 'b'})
|
59
|
+
c = Teapot::Environment.new(nil, {:name => 'c'})
|
60
|
+
d = Teapot::Environment.new(c, {:name => 'd'})
|
61
|
+
|
62
|
+
top = Teapot::Environment.combine(b, d)
|
63
|
+
|
64
|
+
assert_equal d.values, top.values
|
65
|
+
assert_equal c.values, top.parent.values
|
66
|
+
assert_equal b.values, top.parent.parent.values
|
67
|
+
assert_equal a.values, top.parent.parent.parent.values
|
68
|
+
end
|
69
|
+
end
|
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.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-11-
|
12
|
+
date: 2012-11-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -43,6 +43,22 @@ dependencies:
|
|
43
43
|
- - ! '>='
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rexec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
46
62
|
description: ! "\tTeapot is a tool for managing complex cross-platform builds. It
|
47
63
|
provides\n\tadvanced dependency management via the Teapot file and is supported
|
48
64
|
by\n\tthe infusions ecosystem of packages and platform tooling.\n"
|
@@ -54,17 +70,21 @@ extensions: []
|
|
54
70
|
extra_rdoc_files: []
|
55
71
|
files:
|
56
72
|
- .gitignore
|
73
|
+
- .travis.yml
|
57
74
|
- Gemfile
|
58
75
|
- README.md
|
59
76
|
- Rakefile
|
60
77
|
- bin/teapot
|
61
78
|
- lib/teapot.rb
|
79
|
+
- lib/teapot/commands.rb
|
62
80
|
- lib/teapot/config.rb
|
63
81
|
- lib/teapot/context.rb
|
82
|
+
- lib/teapot/environment.rb
|
64
83
|
- lib/teapot/package.rb
|
65
84
|
- lib/teapot/platform.rb
|
66
85
|
- lib/teapot/version.rb
|
67
86
|
- teapot.gemspec
|
87
|
+
- test/test_environment.rb
|
68
88
|
homepage: ''
|
69
89
|
licenses: []
|
70
90
|
post_install_message:
|
@@ -79,7 +99,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
79
99
|
version: '0'
|
80
100
|
segments:
|
81
101
|
- 0
|
82
|
-
hash: -
|
102
|
+
hash: -2599303512074911541
|
83
103
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
104
|
none: false
|
85
105
|
requirements:
|
@@ -88,11 +108,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
88
108
|
version: '0'
|
89
109
|
segments:
|
90
110
|
- 0
|
91
|
-
hash: -
|
111
|
+
hash: -2599303512074911541
|
92
112
|
requirements: []
|
93
113
|
rubyforge_project:
|
94
114
|
rubygems_version: 1.8.24
|
95
115
|
signing_key:
|
96
116
|
specification_version: 3
|
97
117
|
summary: Teapot is a tool for managing complex cross-platform builds.
|
98
|
-
test_files:
|
118
|
+
test_files:
|
119
|
+
- test/test_environment.rb
|