teapot 0.0.3 → 0.1.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 CHANGED
@@ -33,51 +33,59 @@ task :fetch do
33
33
  config = Teapot::Config.load_default
34
34
  context = Teapot::Context.new(config)
35
35
 
36
- base_uri = URI(config.options[:source].to_s + '/')
36
+ base_uri = URI(config.options[:source].to_s)
37
+
38
+ if base_uri.scheme == nil || base_uri.scheme == 'file'
39
+ base_uri = URI "file://" + File.expand_path(base_uri.path, config.root) + "/"
40
+ end
41
+
42
+ puts "Base URI: #{base_uri}".color(:cyan)
37
43
 
38
44
  config.records.each do |record|
45
+ next if record.transient?
46
+
39
47
  destination_path = record.destination_path
40
48
 
41
- puts "Fetching #{record}...".color(:blue)
49
+ puts "Fetching #{record}...".color(:cyan)
42
50
 
43
51
  unless File.exist? destination_path
44
- puts "Cloning package at path #{destination_path} ...".color(:green)
52
+ puts "Cloning package at path #{destination_path} ...".color(:cyan)
53
+ FileUtils.mkdir_p(destination_path.to_s)
45
54
 
46
- source_uri = URI(record.uri)
55
+ source_uri = URI record.uri
47
56
 
48
57
  unless source_uri.absolute?
49
58
  source_uri = base_uri + source_uri
50
59
  end
51
60
 
61
+ # Git can't handle the default formatting that Ruby uses for file URIs.
52
62
  if source_uri.scheme == "file"
53
- source_uri = source_uri.path
63
+ source_uri = "file://" + source_uri.path
54
64
  end
55
65
 
56
- Teapot::Commands.run("git", "clone", "--recursive", source_uri.to_s, destination_path.to_s)
66
+ clone_arguments = [
67
+ "--recursive",
68
+ source_uri, destination_path,
69
+ "--depth", 1,
70
+ ]
71
+
72
+ if record.options[:version]
73
+ clone_arguments << "--branch"
74
+ clone_arguments << record.options[:version]
75
+ end
76
+
77
+ Teapot::Commands.run("git", "clone", *clone_arguments)
57
78
  else
58
- puts "Updating package at path #{destination_path} ...".color(:green)
79
+ puts "Updating package at path #{destination_path} ...".color(:cyan)
59
80
 
60
81
  Dir.chdir(destination_path) do
61
- Teapot::Commands.run("git", "pull")
82
+ Teapot::Commands.run("git", "pull", "--depth", 1)
62
83
  Teapot::Commands.run("git", "submodule", "update", "--init")
63
84
  end
64
85
  end
65
86
  end
66
- end
67
-
68
- task :build do
69
- config = Teapot::Config.load_default
70
- context = Teapot::Context.new(config)
71
87
 
72
- config.records.each do |record|
73
- destination_path = record.destination_path
74
-
75
- bundles = record.load(context)
76
-
77
- bundles.each do |bundle|
78
-
79
- end
80
- end
88
+ puts "Completed fetch successfully.".color(:green)
81
89
  end
82
90
 
83
91
  task :build do |task, arguments|
@@ -85,8 +93,6 @@ task :build do |task, arguments|
85
93
  context = Teapot::Context.new(config)
86
94
 
87
95
  config.records.each do |record|
88
- destination_path = record.destination_path
89
-
90
96
  record.load(context)
91
97
  end
92
98
 
@@ -108,7 +114,7 @@ task :build do |task, arguments|
108
114
  end
109
115
 
110
116
  if build_platform
111
- platform = context.platforms[build_platform.to_sym]
117
+ platform = context.platforms[build_platform]
112
118
 
113
119
  unless platform
114
120
  puts "Could not find platform #{build_platform}".color(:red)
@@ -117,24 +123,41 @@ task :build do |task, arguments|
117
123
  end
118
124
 
119
125
  platforms = [platform]
126
+ else
127
+ platforms = context.platforms.values
120
128
  end
121
129
 
122
130
  unless ENV['ONLY']
123
- ordered = Teapot::Package.build_order(context.packages, packages)
131
+ build_order = Teapot::Package.build_order(context.packages, packages)
124
132
  else
125
- ordered = packages
133
+ build_order = {:ordered => packages, :unresolved => []}
126
134
  end
127
135
 
128
- puts "Building #{ordered.join(', ')} for variant #{config.variant}".color(:blue)
136
+ if build_order[:unresolved].size > 0
137
+ puts "Unresolved packages:"
138
+ build_order[:unresolved].each do |(name, from)|
139
+ puts "\tPackage: #{name} (from #{from})".color(:red)
140
+ end
141
+
142
+ fail "Cannot continue build due to unresolved dependencies!".color(:red)
143
+ else
144
+ ordered = build_order[:ordered]
145
+ end
129
146
 
130
- context.platforms.each do |name, platform|
147
+ puts "Building #{ordered.join(', ')} for variant #{config.variant}".color(:cyan)
148
+
149
+ platforms.each do |platform|
131
150
  next unless platform.available?
132
151
 
133
- puts "Building for #{platform}...".color(:blue)
152
+ puts "Building for #{platform}...".color(:cyan)
134
153
 
135
154
  platform.prepare!
136
155
 
137
156
  ordered.each do |package|
157
+ next if package.record.transient?
158
+
159
+ puts "Building #{package}...".color(:cyan)
160
+
138
161
  package.build!(platform, :variant => config.variant)
139
162
  end
140
163
  end
@@ -147,33 +170,35 @@ task :list do
147
170
  context = Teapot::Context.new(config)
148
171
 
149
172
  config.records.each do |record|
150
- destination_path = record.destination_path
151
-
152
173
  record.load(context)
153
174
  end
154
175
 
155
- ordered = Teapot::Package::build_order(context.packages, context.packages.values)
176
+ build_order = Teapot::Package.build_order(context.packages, context.packages.values)
156
177
 
157
- ordered.each do |package|
158
- puts "Package: #{package.name}"
178
+ if build_order[:unresolved].size > 0
179
+ puts "Unresolved packages:"
180
+ build_order[:unresolved].each do |(name, from)|
181
+ puts "\tPackage: #{name} (from #{from})".color(:red)
182
+ end
183
+ end
184
+
185
+ puts "Ordered packages:"
186
+ build_order[:ordered].each do |package|
187
+ puts "\t#{package.class}: #{package.name}".color(:green)
159
188
 
160
189
  if package.depends.size > 0
161
- puts " (depends on #{package.depends.join(', ')})"
190
+ puts "\t\t(depends on #{package.depends.join(', ')})".color(:green)
162
191
  end
163
192
  end
164
193
 
165
- context.platforms.each do |platform|
166
- puts "Platform: #{platform.name}"
194
+ puts "Platforms:"
195
+ context.platforms.each do |name, platform|
196
+ puts "\t#{platform.class}: #{platform.name}".color(:green)
167
197
  end
168
198
  end
169
199
 
170
- task :help do
171
- puts "To create a new teapot, use the setup task:"
172
- puts "$ #{File.basename($0)} setup project-path"
173
- end
174
-
175
- task :install => [:fetch, :build]
200
+ task :install => [:fetch, :build, :list]
176
201
 
177
- task :default => :help
202
+ task :default => :install
178
203
 
179
204
  $app.top_level
@@ -22,11 +22,19 @@ require 'rainbow'
22
22
 
23
23
  module Teapot
24
24
  module Commands
25
+ class CommandError < StandardError
26
+ end
27
+
25
28
  def self.run(*args)
26
29
  args.collect!(&:to_s)
27
30
 
28
31
  puts args.join(' ').color(:blue)
29
- system(*args)
32
+
33
+ if system(*args)
34
+ true
35
+ else
36
+ raise CommandError.new("Non-zero exit status")
37
+ end
30
38
  end
31
39
  end
32
40
  end
@@ -53,16 +53,20 @@ module Teapot
53
53
  attr :options
54
54
  attr :global
55
55
 
56
+ def transient?
57
+ @klass == FakePackage
58
+ end
59
+
56
60
  def load(context)
57
- context.load(self)
61
+ if @klass == FakePackage
62
+ context.packages[@name] = @klass.new(@context, self, @name)
63
+ else
64
+ context.load(self)
65
+ end
58
66
  end
59
67
 
60
68
  def loader_path
61
- if @klass == Package
62
- "package.rb"
63
- elsif @klass == Platform
64
- "platform.rb"
65
- end
69
+ "infusion.rb"
66
70
  end
67
71
 
68
72
  def destination_path
@@ -92,6 +96,8 @@ module Teapot
92
96
  @environment = Environment.new
93
97
  end
94
98
 
99
+ attr :root
100
+
95
101
  def packages_path
96
102
  @root + (@options[:packages_path] || "packages")
97
103
  end
@@ -150,6 +156,10 @@ module Teapot
150
156
  @platforms << Record.new(self, Platform, name, options)
151
157
  end
152
158
 
159
+ def provides(name, options = {})
160
+ @packages << Record.new(self, FakePackage, name, options)
161
+ end
162
+
153
163
  def self.load(root, options = {})
154
164
  config = new(root, options)
155
165
 
@@ -25,54 +25,82 @@ require 'teapot/package'
25
25
  require 'teapot/platform'
26
26
 
27
27
  module Teapot
28
- class Context
29
- def initialize(config)
30
- @config = config
31
-
32
- @packages = {}
33
- @platforms = {}
34
-
35
- @defined = []
36
- end
37
-
38
- attr :config
39
- attr :packages
40
- attr :platforms
41
-
42
- def load(record)
28
+ INFUSION_VERSION = "0.1"
29
+
30
+ class IncompatibleInfusion < StandardError
31
+ end
32
+
33
+ class Infusion
34
+ def initialize(context, record)
35
+ @context = context
43
36
  @record = record
44
- @defined = []
45
37
 
46
- path = (record.destination_path + record.loader_path).to_s
47
- self.instance_eval(File.read(path), path)
48
-
49
- @defined
38
+ @defined = []
39
+ @version = nil
40
+ end
41
+
42
+ attr :record
43
+ attr :defined
44
+ attr :version
45
+
46
+ def required_version(version)
47
+ if version <= INFUSION_VERSION
48
+ @version = version
49
+ else
50
+ raise IncompatibleInfusion.new("Version #{version} more recent than #{INFUSION_VERSION}!")
51
+ end
50
52
  end
51
53
 
52
54
  def define_package(*args, &block)
53
- package = Package.new(self, @record, *args)
55
+ package = Package.new(@context, @record, *args)
54
56
 
55
57
  yield(package)
56
58
 
57
- @packages[package.name] = package
59
+ @context.packages[package.name] = package
58
60
 
59
61
  @defined << package
60
62
  end
61
63
 
62
64
  def define_platform(*args, &block)
63
- platform = Platform.new(self, @record, *args)
65
+ platform = Platform.new(@context, @record, *args)
64
66
 
65
67
  yield(platform)
66
68
 
67
69
  if platform.available?
68
- @platforms[platform.name] = platform
70
+ @context.platforms[platform.name] = platform
69
71
  end
70
72
 
71
73
  @defined << platform
72
74
  end
73
75
 
74
- def global name
75
- @config.environment[name]
76
+ def load(path)
77
+ self.instance_eval(File.read(path), path)
78
+ end
79
+ end
80
+
81
+ class Context
82
+ def initialize(config)
83
+ @config = config
84
+
85
+ @packages = {}
86
+ @platforms = {}
87
+ end
88
+
89
+ attr :config
90
+ attr :packages
91
+ attr :platforms
92
+
93
+ def load(record)
94
+ infusion = Infusion.new(self, record)
95
+
96
+ path = (record.destination_path + record.loader_path).to_s
97
+ infusion.load(path)
98
+
99
+ if infusion.version == nil
100
+ raise IncompatibleInfusion.new("No version specified in #{path}!")
101
+ end
102
+
103
+ infusion.defined
76
104
  end
77
105
  end
78
106
  end
@@ -105,7 +105,10 @@ module Teapot
105
105
  return top
106
106
  end
107
107
 
108
- def initialize(parent = nil, values = nil, &block)
108
+ def initialize(*args, &block)
109
+ parent = args.shift if args.size == 2
110
+ values = args.shift
111
+
109
112
  @values = (values || {}).to_hash
110
113
  @parent = parent
111
114
 
@@ -160,7 +163,7 @@ module Teapot
160
163
 
161
164
  Dir.chdir(options[:in] || ".") do
162
165
  RExec.env(system_environment) do
163
- @evaluator.instance_eval(&block)
166
+ block.call(@evaluator)
164
167
  end
165
168
  end
166
169
  end
@@ -38,6 +38,35 @@ module Teapot
38
38
  end
39
39
  end
40
40
 
41
+ class FakePackage
42
+ def initialize(context, record, name)
43
+ @context = context
44
+ @record = record
45
+ @name = name
46
+ @version = nil
47
+ @path = nil
48
+ end
49
+
50
+ attr :context
51
+ attr :record
52
+
53
+ attr :name
54
+ attr :version
55
+
56
+ attr :path
57
+
58
+ def depends
59
+ @record.options.fetch(:depends, [])
60
+ end
61
+
62
+ def build!(platform = :all, config = {})
63
+ end
64
+
65
+ def to_s
66
+ "<FakePackage: #{@name}>"
67
+ end
68
+ end
69
+
41
70
  class Package
42
71
  def initialize(context, record, name)
43
72
  @context = context
@@ -94,15 +123,16 @@ module Teapot
94
123
 
95
124
  def self.build_order(available, packages)
96
125
  ordered = []
126
+ unresolved = []
97
127
 
98
- expand = lambda do |name|
128
+ expand = lambda do |name, parent|
99
129
  package = available[name]
100
130
 
101
131
  unless package
102
- puts "Couldn't resolve #{name}"
132
+ unresolved << [name, parent]
103
133
  else
104
134
  package.depends.each do |dependency|
105
- expand.call(dependency)
135
+ expand.call(dependency, package)
106
136
  end
107
137
 
108
138
  unless ordered.include? package
@@ -112,10 +142,10 @@ module Teapot
112
142
  end
113
143
 
114
144
  packages.each do |package|
115
- expand.call(package.name)
145
+ expand.call(package.name, nil)
116
146
  end
117
147
 
118
- return ordered
148
+ return {:ordered => ordered, :unresolved => unresolved}
119
149
  end
120
150
  end
121
151
  end
@@ -70,7 +70,7 @@ module Teapot
70
70
  end
71
71
 
72
72
  def to_s
73
- "<Platform #{@name}: #{@available ? 'available' : 'inactive'}>"
73
+ "<Platform: #{@name} (#{@available ? 'available' : 'inactive'})>"
74
74
  end
75
75
 
76
76
  def prepare!
@@ -19,5 +19,5 @@
19
19
  # THE SOFTWARE.
20
20
 
21
21
  module Teapot
22
- VERSION = "0.0.3"
22
+ VERSION = "0.1.0"
23
23
  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.3
4
+ version: 0.1.0
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-08 00:00:00.000000000 Z
12
+ date: 2012-11-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -99,7 +99,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
99
99
  version: '0'
100
100
  segments:
101
101
  - 0
102
- hash: -2599303512074911541
102
+ hash: 557922474497580822
103
103
  required_rubygems_version: !ruby/object:Gem::Requirement
104
104
  none: false
105
105
  requirements:
@@ -108,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
108
108
  version: '0'
109
109
  segments:
110
110
  - 0
111
- hash: -2599303512074911541
111
+ hash: 557922474497580822
112
112
  requirements: []
113
113
  rubyforge_project:
114
114
  rubygems_version: 1.8.24