teapot 0.3.2 → 0.5.0
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 +110 -144
- data/lib/teapot/{platform.rb → build/component.rb} +36 -47
- data/lib/teapot/build/file_list.rb +67 -0
- data/lib/teapot/build/linker.rb +6 -1
- data/lib/teapot/build/target.rb +77 -0
- data/lib/teapot/build/targets/application.rb +55 -0
- data/lib/teapot/build/targets/compiler.rb +69 -0
- data/lib/teapot/build/targets/directory.rb +63 -0
- data/lib/teapot/build/targets/executable.rb +52 -0
- data/lib/teapot/build/targets/files.rb +82 -0
- data/lib/teapot/build/targets/library.rb +106 -0
- data/lib/teapot/build.rb +11 -214
- data/lib/teapot/commands.rb +63 -0
- data/lib/teapot/config.rb +32 -63
- data/lib/teapot/context.rb +47 -38
- data/lib/teapot/dependency.rb +182 -0
- data/lib/teapot/environment/constructor.rb +4 -0
- data/lib/teapot/target.rb +94 -0
- data/lib/teapot/version.rb +1 -1
- data/teapot.gemspec +1 -1
- data/test/test_config.rb +41 -0
- data/test/test_dependency.rb +114 -0
- data/test/test_environment.rb +3 -3
- metadata +22 -9
- data/lib/teapot/package.rb +0 -164
data/bin/teapot
CHANGED
@@ -23,195 +23,161 @@
|
|
23
23
|
require 'teapot/config'
|
24
24
|
|
25
25
|
require 'uri'
|
26
|
-
require 'rake'
|
27
26
|
require 'rainbow'
|
27
|
+
require 'fileutils'
|
28
|
+
require 'benchmark'
|
29
|
+
require 'yaml'
|
28
30
|
|
29
|
-
|
30
|
-
$app.init('teapot')
|
31
|
+
require 'trollop'
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
base_uri = URI "file://" + File.expand_path(base_uri.path, config.root) + "/"
|
41
|
-
end
|
33
|
+
OPTIONS = Trollop::options do
|
34
|
+
opt :only, "Only compiled direct dependencies."
|
35
|
+
end
|
36
|
+
|
37
|
+
module Application
|
38
|
+
def self.fetch
|
39
|
+
config = Teapot::Config.load_default
|
40
|
+
context = Teapot::Context.new(config)
|
42
41
|
|
43
|
-
|
42
|
+
base_uri = URI(config.options[:source].to_s)
|
44
43
|
|
45
|
-
|
46
|
-
|
44
|
+
if base_uri.scheme == nil || base_uri.scheme == 'file'
|
45
|
+
base_uri = URI "file://" + File.expand_path(base_uri.path, config.root) + "/"
|
46
|
+
end
|
47
47
|
|
48
|
-
|
48
|
+
puts "Base URI: #{base_uri}".color(:cyan)
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
50
|
+
config.packages.each do |package|
|
51
|
+
destination_path = package.path
|
52
|
+
|
53
|
+
if package.local?
|
54
|
+
puts "Linking local #{package}...".color(:cyan)
|
54
55
|
|
55
|
-
|
56
|
-
FileUtils.mkdir_p(destination_path.dirname.to_s)
|
56
|
+
local_path = config.root + package.options[:local]
|
57
57
|
|
58
|
-
|
59
|
-
|
60
|
-
end
|
61
|
-
else
|
62
|
-
puts "Fetching #{record}...".color(:cyan)
|
63
|
-
|
64
|
-
branch = record.options.fetch(:version, 'master')
|
65
|
-
|
66
|
-
unless File.exist? destination_path
|
67
|
-
puts "Cloning package at path #{destination_path} ...".color(:cyan)
|
68
|
-
FileUtils.mkdir_p(destination_path.to_s)
|
58
|
+
# Make the top level directory if required:
|
59
|
+
destination_path.dirname.mkpath
|
69
60
|
|
70
|
-
|
71
|
-
|
72
|
-
unless source_uri.absolute?
|
73
|
-
source_uri = base_uri + source_uri
|
61
|
+
unless destination_path.exist?
|
62
|
+
destination_path.make_symlink(local_path)
|
74
63
|
end
|
64
|
+
else
|
65
|
+
puts "Fetching #{package}...".color(:cyan)
|
75
66
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
67
|
+
branch = package.options.fetch(:version, 'master')
|
68
|
+
|
69
|
+
unless destination_path.exist?
|
70
|
+
puts "Cloning package at path #{destination_path} ...".color(:cyan)
|
71
|
+
destination_path.mkpath
|
80
72
|
|
81
|
-
|
73
|
+
Teapot::Commands.run("git", "clone", package.relative_url(base_uri), destination_path, "--branch", branch)
|
82
74
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
75
|
+
Dir.chdir(destination_path) do
|
76
|
+
Teapot::Commands.run("git", "submodule", "update", "--init", "--recursive")
|
77
|
+
end
|
78
|
+
else
|
79
|
+
puts "Updating package at path #{destination_path} ...".color(:cyan)
|
88
80
|
|
89
|
-
|
90
|
-
|
81
|
+
Dir.chdir(destination_path) do
|
82
|
+
Teapot::Commands.run("git", "fetch", "origin")
|
91
83
|
|
92
|
-
|
84
|
+
Teapot::Commands.run("git", "checkout", branch)
|
93
85
|
|
94
|
-
|
95
|
-
|
96
|
-
|
86
|
+
# Pull any changes, if you might get the error from above:
|
87
|
+
# Your branch is behind 'origin/0.1' by 1 commit, and can be fast-forwarded.
|
88
|
+
Teapot::Commands.run("git", "pull")
|
97
89
|
|
98
|
-
|
90
|
+
Teapot::Commands.run("git", "submodule", "update", "--init", "--recursive")
|
91
|
+
end
|
99
92
|
end
|
100
93
|
end
|
101
94
|
end
|
102
|
-
end
|
103
|
-
|
104
|
-
puts "Completed fetch successfully.".color(:green)
|
105
|
-
end
|
106
|
-
|
107
|
-
# Build packages based on the Teapot configuration:
|
108
|
-
task :build do |task, arguments|
|
109
|
-
config = Teapot::Config.load_default
|
110
|
-
context = Teapot::Context.new(config)
|
111
95
|
|
112
|
-
|
113
|
-
record.load(context)
|
96
|
+
puts "Completed fetch successfully.".color(:green)
|
114
97
|
end
|
115
98
|
|
116
|
-
|
117
|
-
|
118
|
-
|
99
|
+
def self.install(package_names = ARGV)
|
100
|
+
config = Teapot::Config.load_default
|
101
|
+
context = Teapot::Context.new(config)
|
119
102
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
unless package
|
124
|
-
fail "Could not find package #{build_package}".color(:red)
|
103
|
+
config.packages.each do |package|
|
104
|
+
context.load(package)
|
125
105
|
end
|
126
106
|
|
127
|
-
|
128
|
-
else
|
129
|
-
packages = context.packages.values
|
130
|
-
end
|
131
|
-
|
132
|
-
if build_platform
|
133
|
-
platform = context.platforms[build_platform]
|
107
|
+
context.select(package_names)
|
134
108
|
|
135
|
-
|
136
|
-
fail "Could not find platform #{build_platform}".color(:red)
|
137
|
-
end
|
109
|
+
chain = Teapot::Dependency::chain(context.selection, context.dependencies, context.targets.values)
|
138
110
|
|
139
|
-
|
140
|
-
|
141
|
-
platforms = context.platforms.values
|
142
|
-
end
|
143
|
-
|
144
|
-
unless ENV['ONLY']
|
145
|
-
build_order = Teapot::Package.build_order(context.packages, packages)
|
146
|
-
else
|
147
|
-
build_order = {:ordered => packages, :unresolved => []}
|
148
|
-
end
|
149
|
-
|
150
|
-
if build_order[:unresolved].size > 0
|
151
|
-
puts "Unresolved packages:"
|
152
|
-
build_order[:unresolved].each do |(name, from)|
|
153
|
-
puts "\tPackage: #{name} (from #{from})".color(:red)
|
154
|
-
end
|
111
|
+
if chain.unresolved.size > 0
|
112
|
+
puts "Unresolved dependencies:"
|
155
113
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
114
|
+
chain.unresolved.each do |(name, parent)|
|
115
|
+
puts "#{parent} depends on #{name.inspect}".color(:red)
|
116
|
+
|
117
|
+
conflicts = chain.conflicts[name]
|
118
|
+
|
119
|
+
if conflicts
|
120
|
+
conflicts.each do |conflict|
|
121
|
+
puts " - provided by #{conflict.inspect}".color(:red)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
abort "Cannot continue build due to unresolved dependencies!"
|
127
|
+
end
|
160
128
|
|
161
|
-
|
129
|
+
puts "Resolved: #{chain.resolved.inspect}".color(:magenta)
|
162
130
|
|
163
|
-
|
164
|
-
next unless platform.available?
|
131
|
+
ordered = chain.ordered
|
165
132
|
|
166
|
-
|
133
|
+
if OPTIONS[:only]
|
134
|
+
ordered = context.direct_targets(ordered)
|
135
|
+
end
|
167
136
|
|
168
|
-
|
137
|
+
ordered.each do |(target, dependency)|
|
138
|
+
puts "Building #{target.name} for dependency #{dependency}...".color(:cyan)
|
169
139
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
puts "Building #{package}...".color(:cyan)
|
174
|
-
|
175
|
-
package.build!(platform, :variant => config.variant)
|
140
|
+
if target.respond_to? :install! and !ENV['TEAPOT_DRY']
|
141
|
+
target.install!(context)
|
142
|
+
end
|
176
143
|
end
|
177
|
-
end
|
178
|
-
|
179
|
-
puts "Completed build successfully.".color(:green)
|
180
|
-
end
|
181
|
-
|
182
|
-
# List available/installed packages based on the Teapot configuration:
|
183
|
-
task :list do
|
184
|
-
config = Teapot::Config.load_default
|
185
|
-
context = Teapot::Context.new(config)
|
186
144
|
|
187
|
-
|
188
|
-
record.load(context)
|
145
|
+
puts "Completed build successfully.".color(:green)
|
189
146
|
end
|
190
147
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
puts "Unresolved packages:"
|
195
|
-
build_order[:unresolved].each do |(name, from)|
|
196
|
-
puts "\tPackage: #{name} (from #{from})".color(:red)
|
197
|
-
end
|
198
|
-
end
|
148
|
+
def self.list
|
149
|
+
config = Teapot::Config.load_default
|
150
|
+
context = Teapot::Context.new(config)
|
199
151
|
|
200
|
-
|
201
|
-
|
202
|
-
puts "\t#{package.class}: #{package.name}".color(:green)
|
152
|
+
config.packages.each do |package|
|
153
|
+
targets = context.load(package)
|
203
154
|
|
204
|
-
|
205
|
-
|
155
|
+
targets.each do |target|
|
156
|
+
puts "Target #{target.name} from #{package.name}"
|
157
|
+
|
158
|
+
target.dependencies.each do |name|
|
159
|
+
puts " - depends on #{name.inspect}".color(:red)
|
160
|
+
end
|
161
|
+
|
162
|
+
target.provisions.each do |(name, provision)|
|
163
|
+
if Teapot::Dependency::Alias === provision
|
164
|
+
puts " - provides #{name.inspect} => #{provision.dependencies.inspect}".color(:green)
|
165
|
+
else
|
166
|
+
puts " - provides #{name.inspect}".color(:green)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
206
170
|
end
|
207
171
|
end
|
208
172
|
|
209
|
-
|
210
|
-
|
211
|
-
puts "\t#{platform.class}: #{platform.name}".color(:green)
|
173
|
+
def self.debug
|
174
|
+
puts ARGV.inspect
|
212
175
|
end
|
213
176
|
end
|
214
177
|
|
215
|
-
|
178
|
+
time = Benchmark.measure do
|
179
|
+
action = ARGV.shift.to_sym
|
180
|
+
Application.send(action) if Application.methods.include?(action)
|
181
|
+
end
|
216
182
|
|
217
|
-
|
183
|
+
puts time.format("Elapsed Time: %r").color(:magenta)
|
@@ -19,62 +19,51 @@
|
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
21
|
require 'fileutils'
|
22
|
-
require 'teapot/environment'
|
23
22
|
|
24
23
|
module Teapot
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
@record = record
|
32
|
-
|
33
|
-
@name = name
|
34
|
-
@configure = nil
|
35
|
-
|
36
|
-
@available = false
|
37
|
-
end
|
38
|
-
|
39
|
-
attr :name
|
24
|
+
module Build
|
25
|
+
class Component
|
26
|
+
def initialize(root, name, environment)
|
27
|
+
@root = root
|
28
|
+
@name = name
|
29
|
+
@environment = environment
|
40
30
|
|
41
|
-
|
42
|
-
|
43
|
-
end
|
31
|
+
@parts = [@name]
|
32
|
+
end
|
44
33
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
end
|
52
|
-
|
53
|
-
def environment
|
54
|
-
if @available
|
55
|
-
return Environment.combine(
|
56
|
-
Environment.new(&@configure),
|
57
|
-
@record.options[:environment],
|
58
|
-
)
|
59
|
-
else
|
60
|
-
raise UnavailableError.new("Platform is not available for configuration!")
|
34
|
+
attr :root
|
35
|
+
attr :name
|
36
|
+
attr :parts
|
37
|
+
|
38
|
+
def add(path)
|
39
|
+
@parts << path
|
61
40
|
end
|
62
|
-
|
41
|
+
|
42
|
+
def variant
|
43
|
+
@environment[:variant]
|
44
|
+
end
|
45
|
+
|
46
|
+
def destination_path
|
47
|
+
@environment[:build_prefix] + "source"
|
48
|
+
end
|
49
|
+
|
50
|
+
def prepare!
|
51
|
+
source_path = destination_path + @name
|
63
52
|
|
64
|
-
|
65
|
-
|
66
|
-
|
53
|
+
if source_path.exist?
|
54
|
+
source_path.rmtree
|
55
|
+
end
|
67
56
|
|
68
|
-
|
69
|
-
@available
|
70
|
-
end
|
57
|
+
source_path.mkpath
|
71
58
|
|
72
|
-
|
73
|
-
|
74
|
-
|
59
|
+
@parts.each do |path|
|
60
|
+
full_path = @root + path
|
61
|
+
|
62
|
+
FileUtils.cp_r(full_path.children, source_path.to_s)
|
63
|
+
end
|
75
64
|
|
76
|
-
|
77
|
-
|
65
|
+
return source_path
|
66
|
+
end
|
78
67
|
end
|
79
68
|
end
|
80
69
|
end
|
@@ -0,0 +1,67 @@
|
|
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 'fileutils'
|
23
|
+
|
24
|
+
module Teapot
|
25
|
+
module Build
|
26
|
+
class FileList
|
27
|
+
include Enumerable
|
28
|
+
|
29
|
+
def self.[] (root, pattern, prefix = nil)
|
30
|
+
self.new(root, pattern, prefix)
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize(root, pattern, prefix = nil)
|
34
|
+
@root = root
|
35
|
+
@pattern = pattern
|
36
|
+
@prefix = Pathname.new(prefix || ".")
|
37
|
+
end
|
38
|
+
|
39
|
+
attr :root
|
40
|
+
attr :pattern
|
41
|
+
attr :prefix
|
42
|
+
|
43
|
+
def each(&block)
|
44
|
+
Pathname.glob(@root + @pattern).each &block
|
45
|
+
end
|
46
|
+
|
47
|
+
def copy(destination)
|
48
|
+
self.each do |path|
|
49
|
+
# Compute the destination path, which is formed using the relative path:
|
50
|
+
relative_path = path.relative_path_from(@root)
|
51
|
+
destination_path = destination + @prefix + relative_path
|
52
|
+
|
53
|
+
if path.directory?
|
54
|
+
# Make a directory at the destination:
|
55
|
+
destination_path.mkpath
|
56
|
+
else
|
57
|
+
# Make the path if it doesn't already exist:
|
58
|
+
destination_path.dirname.mkpath
|
59
|
+
|
60
|
+
# Copy the file to the destination:
|
61
|
+
FileUtils.cp path, destination_path
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/teapot/build/linker.rb
CHANGED
@@ -18,12 +18,17 @@
|
|
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 'teapot/commands'
|
22
|
+
|
21
23
|
module Teapot
|
22
24
|
module Build
|
23
25
|
module Linker
|
26
|
+
class UnsupportedPlatform < StandardError
|
27
|
+
end
|
28
|
+
|
24
29
|
def self.link_static(environment, library_file, objects)
|
25
30
|
if RUBY_PLATFORM =~ /darwin/
|
26
|
-
|
31
|
+
Commands.run(
|
27
32
|
environment[:libtool] || "libtool",
|
28
33
|
"-static", "-o", library_file, objects,
|
29
34
|
)
|
@@ -0,0 +1,77 @@
|
|
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 'teapot/commands'
|
22
|
+
require 'teapot/environment'
|
23
|
+
|
24
|
+
require 'pathname'
|
25
|
+
require 'rainbow'
|
26
|
+
require 'fileutils'
|
27
|
+
|
28
|
+
require 'teapot/build/linker'
|
29
|
+
require 'teapot/build/component'
|
30
|
+
require 'teapot/build/file_list'
|
31
|
+
|
32
|
+
module Teapot
|
33
|
+
module Build
|
34
|
+
class Target
|
35
|
+
def initialize(parent)
|
36
|
+
@parent = parent
|
37
|
+
@configure = nil
|
38
|
+
end
|
39
|
+
|
40
|
+
attr :parent
|
41
|
+
|
42
|
+
def root
|
43
|
+
@parent.root
|
44
|
+
end
|
45
|
+
|
46
|
+
def configure(&block)
|
47
|
+
@configure = Proc.new &block
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.target(*args, &block)
|
51
|
+
instance = self.new(*args)
|
52
|
+
|
53
|
+
if block_given?
|
54
|
+
instance.instance_eval(&block)
|
55
|
+
end
|
56
|
+
|
57
|
+
return instance
|
58
|
+
end
|
59
|
+
|
60
|
+
def execute(command, environment, *arguments)
|
61
|
+
if @configure
|
62
|
+
environment = environment.merge &@configure
|
63
|
+
end
|
64
|
+
|
65
|
+
# Flatten the environment to a hash:
|
66
|
+
values = environment.flatten
|
67
|
+
|
68
|
+
puts "Performing #{self.class}/#{command} for #{root}...".color(:cyan)
|
69
|
+
|
70
|
+
# Show the environment to the user:
|
71
|
+
Environment::System::dump(values)
|
72
|
+
|
73
|
+
self.send(command, values, *arguments)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,55 @@
|
|
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 'teapot/build/targets/library'
|
22
|
+
require 'teapot/build/targets/directory'
|
23
|
+
|
24
|
+
module Teapot
|
25
|
+
module Build
|
26
|
+
module Targets
|
27
|
+
class Application < Directory
|
28
|
+
def initialize(parent, name, options = {})
|
29
|
+
super parent
|
30
|
+
|
31
|
+
@name = name
|
32
|
+
@options = options
|
33
|
+
end
|
34
|
+
|
35
|
+
def subdirectory
|
36
|
+
"apps/#{@name}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def << target
|
40
|
+
if target.respond_to? :subdirectory
|
41
|
+
target.options[:subdirectory] = subdirectory
|
42
|
+
end
|
43
|
+
|
44
|
+
super
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class Directory
|
49
|
+
def add_application(*args, &block)
|
50
|
+
self << Application.target(self, *args, &block)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|