teapot 0.0.1 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://secure.travis-ci.org/ioquatix/teapot.png)](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
|