teapot 2.2.0 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/teapot/loader.rb CHANGED
@@ -30,7 +30,8 @@ module Teapot
30
30
  # Cannot load packages newer than this.
31
31
  # Version 1.3: Added support for build-dependency library which allows options for `#depends`. The primary use case is private dependencies.
32
32
  # Version 2.0: Generators removed and refactored into build.
33
- LOADER_VERSION = "2.0"
33
+ # Version 2.3: Rework install_prefix -> build_prefix.
34
+ LOADER_VERSION = "3.0"
34
35
 
35
36
  # Cannot load packages older than this.
36
37
  MINIMUM_LOADER_VERSION = "1.0"
@@ -46,7 +47,7 @@ module Teapot
46
47
  attr :version
47
48
  end
48
49
 
49
- class NonexistantTeapotError < StandardError
50
+ class MissingTeapotError < StandardError
50
51
  def initialize(path)
51
52
  super "Could not read file at #{path}!"
52
53
  end
@@ -66,6 +67,8 @@ module Teapot
66
67
  @defined = []
67
68
  @version = nil
68
69
 
70
+ @configurations = Build::Dependency::Set.new
71
+
69
72
  @default_project = nil
70
73
  @default_configuration = nil
71
74
 
@@ -77,6 +80,8 @@ module Teapot
77
80
  attr :defined
78
81
  attr :version
79
82
 
83
+ attr :configurations
84
+
80
85
  attr :default_project
81
86
  attr :default_configuration
82
87
 
@@ -103,9 +108,11 @@ module Teapot
103
108
 
104
109
  def define_target(*args)
105
110
  target = Target.new(@context, @package, *args)
106
-
111
+
107
112
  yield target
108
-
113
+
114
+ target.update_environments!
115
+
109
116
  @defined << target
110
117
  end
111
118
 
@@ -116,6 +123,7 @@ module Teapot
116
123
 
117
124
  @default_configuration ||= configuration
118
125
  @defined << configuration
126
+ @configurations << configuration
119
127
  end
120
128
 
121
129
  # Checks the host patterns and executes the block if they match.
@@ -162,7 +170,7 @@ module Teapot
162
170
 
163
171
  # Load a teapot.rb file relative to the root of the @package.
164
172
  def load!(path = teapot_path)
165
- raise NonexistantTeapotError.new(path) unless File.exist?(path)
173
+ raise MissingTeapotError.new(path) unless File.exist?(path)
166
174
 
167
175
  script = Script.new(@context, @package)
168
176
 
@@ -0,0 +1,148 @@
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_relative 'loader'
22
+ require_relative 'package'
23
+
24
+ require 'build/rulebook'
25
+ require 'build/text/substitutions'
26
+ require 'build/text/merge'
27
+
28
+ module Teapot
29
+ class AlreadyDefinedError < StandardError
30
+ def initialize(definition, previous)
31
+ super "Definition #{definition.name} in #{definition.path} has already been defined in #{previous.path}!"
32
+ end
33
+
34
+ def self.check(definition, definitions)
35
+ previous = definitions[definition.name]
36
+
37
+ raise self.new(definition, previous) if previous
38
+ end
39
+ end
40
+
41
+ # A selection is a specific view of the data exposed by the context at a specific point in time.
42
+ class Select
43
+ def initialize(context, configuration, names = [])
44
+ @context = context
45
+ @configuration = Configuration.new(context, configuration.package, configuration.name, [], configuration.options)
46
+
47
+ @targets = {}
48
+ @configurations = {}
49
+ @projects = {}
50
+
51
+ @dependencies = []
52
+ @selection = Set.new
53
+ @resolved = Build::Dependency::Set.new
54
+ @unresolved = Build::Dependency::Set.new
55
+
56
+ load!(configuration, names)
57
+
58
+ @chain = nil
59
+ end
60
+
61
+ attr :context
62
+ attr :configuration
63
+
64
+ attr :targets
65
+ attr :projects
66
+
67
+ # Alises as defined by Configuration#targets
68
+ attr :aliases
69
+
70
+ # All public configurations.
71
+ attr :configurations
72
+
73
+ attr :dependencies
74
+ attr :selection
75
+
76
+ attr :resolved
77
+ attr :unresolved
78
+
79
+ def chain
80
+ @chain ||= Build::Dependency::Chain.expand(@dependencies, @targets.values, @selection)
81
+ end
82
+
83
+ def direct_targets(ordered)
84
+ @dependencies.collect do |dependency|
85
+ ordered.find{|(package, _)| package.provides? dependency}
86
+ end.compact
87
+ end
88
+
89
+ private
90
+
91
+ # Add a definition to the current context.
92
+ def append definition
93
+ case definition
94
+ when Target
95
+ AlreadyDefinedError.check(definition, @targets)
96
+ @targets[definition.name] = definition
97
+ when Configuration
98
+ # We define configurations in two cases, if they are public, or if they are part of the root package of this context.
99
+ if definition.public? or definition.package == @context.root_package
100
+ AlreadyDefinedError.check(definition, @configurations)
101
+ @configurations[definition.name] = definition
102
+ end
103
+ when Project
104
+ AlreadyDefinedError.check(definition, @projects)
105
+ @projects[definition.name] = definition
106
+ end
107
+ end
108
+
109
+ def load_package!(package)
110
+ begin
111
+ script = @context.load(package)
112
+
113
+ # Load the definitions into the current selection:
114
+ script.defined.each do |definition|
115
+ append(definition)
116
+ end
117
+
118
+ @resolved << package
119
+ rescue MissingTeapotError, IncompatibleTeapotError
120
+ # If the package doesn't exist or the teapot version is too old, it failed:
121
+ @unresolved << package
122
+ end
123
+ end
124
+
125
+ def load!(configuration, names)
126
+ # Load the root package which makes all the named configurations and targets available.
127
+ load_package!(@context.root_package)
128
+
129
+ # Load all packages defined by this configuration.
130
+ configuration.traverse(@configurations) do |configuration|
131
+ @configuration.merge(configuration) do |package|
132
+ # puts "Load package: #{package} from #{configuration}"
133
+ load_package!(package)
134
+ end
135
+ end
136
+
137
+ @configuration.freeze
138
+
139
+ names.each do |name|
140
+ if @targets.key? name
141
+ @selection << name
142
+ else
143
+ @dependencies << name
144
+ end
145
+ end
146
+ end
147
+ end
148
+ end
data/lib/teapot/target.rb CHANGED
@@ -32,40 +32,20 @@ module Teapot
32
32
  class Target < Definition
33
33
  include Build::Dependency
34
34
 
35
- def initialize(context, package, name)
36
- super context, package, name
35
+ def initialize(*)
36
+ super
37
37
 
38
38
  @build = nil
39
-
40
- @rulebook = Build::Rulebook.new
41
39
  end
42
40
 
43
- attr :rulebook
44
-
45
41
  def freeze
42
+ return self if frozen?
43
+
46
44
  @build.freeze
47
- @rulebook.freeze
48
45
 
49
46
  super
50
47
  end
51
48
 
52
- # Given a specific configuration, generate the build environment based on this target and it's provision chain.
53
- def environment(configuration, chain)
54
- chain = chain.partial(self)
55
-
56
- # Calculate the dependency chain's ordered environments:
57
- environments = chain.provisions.collect do |provision|
58
- Build::Environment.new(&provision.value)
59
- end
60
-
61
- # Merge all the environments together:
62
- environment = Build::Environment.combine(*environments)
63
-
64
- environment.merge do
65
- default platforms_path configuration.platforms_path
66
- end
67
- end
68
-
69
49
  def build(&block)
70
50
  if block_given?
71
51
  @build = block
@@ -73,5 +53,23 @@ module Teapot
73
53
 
74
54
  return @build
75
55
  end
56
+
57
+ def update_environments!
58
+ return unless @build
59
+
60
+ self.provisions.each do |key, provision|
61
+ build = @build
62
+ original = provision.value
63
+
64
+ wrapper = proc do |*arguments|
65
+ self.instance_exec(*arguments, &original) if original
66
+ self.instance_exec(*arguments, &build) if build
67
+ end
68
+
69
+ provision.value = wrapper
70
+ end
71
+
72
+ @build = nil
73
+ end
76
74
  end
77
75
  end
@@ -19,5 +19,5 @@
19
19
  # THE SOFTWARE.
20
20
 
21
21
  module Teapot
22
- VERSION = "2.2.0"
22
+ VERSION = "3.2.0"
23
23
  end
data/spec/spec_helper.rb CHANGED
@@ -1,29 +1,5 @@
1
1
 
2
- if ENV['COVERAGE'] || ENV['TRAVIS']
3
- begin
4
- require 'simplecov'
5
-
6
- SimpleCov.start do
7
- add_filter "/spec/"
8
- end
9
-
10
- if ENV['TRAVIS']
11
- require 'coveralls'
12
- Coveralls.wear!
13
- end
14
- rescue LoadError
15
- warn "Could not load simplecov: #{$!}"
16
- end
17
- end
18
-
19
- require "bundler/setup"
20
- require "teapot"
21
- require 'pry'
22
-
23
- RSpec.shared_context Teapot::Context do
24
- let(:root) {Build::Files::Path[__dir__] + 'context'}
25
- let(:context) {Teapot::Context.new(root, load_root: false)}
26
- end
2
+ require "covered/rspec"
27
3
 
28
4
  RSpec.configure do |config|
29
5
  # Enable flags like --only-failures and --next-failure
@@ -23,7 +23,7 @@ require 'teapot/command'
23
23
 
24
24
  RSpec.describe Teapot::Command::Clone, order: :defined do
25
25
  let(:root) {Build::Files::Path.new(__dir__) + "clone_spec"}
26
- let(:source) {'http://github.com/kurocha/tagged-format'}
26
+ let(:source) {'https://github.com/kurocha/tagged-format'}
27
27
 
28
28
  let(:top) {Teapot::Command::Top["--root", root.to_s]}
29
29
 
@@ -27,14 +27,32 @@ RSpec.describe Teapot::Context do
27
27
  it "should specify correct number of packages" do
28
28
  default_configuration = context.configuration
29
29
 
30
- expect(default_configuration.packages.count).to be == 13
30
+ expect(default_configuration.packages.count).to be == 0
31
31
  end
32
32
 
33
- it "should load teapot.rb file" do
33
+ it "should select configuration" do
34
+ expect(context.configuration.name).to be == 'development'
35
+ end
36
+
37
+ context "with specific configuration" do
38
+ let(:context) {Teapot::Context.new(root, configuration: 'context_spec')}
39
+
40
+ it "should select configuration" do
41
+ expect(context.configuration.name).to be == 'context_spec'
42
+ end
43
+
44
+ it "should specify correct number of packages" do
45
+ default_configuration = context.configuration
46
+
47
+ expect(default_configuration.packages.count).to be == 13
48
+ end
49
+ end
50
+
51
+ it "should load teapot script" do
34
52
  selection = context.select
35
53
 
36
54
  # There is one configuration:
37
- expect(selection.configurations.count).to be == 1
55
+ expect(selection.configurations.count).to be == 2
38
56
  expect(selection.targets.count).to be == 1
39
57
 
40
58
  # We didn't expect any of them to actually load...
@@ -3,9 +3,16 @@
3
3
  # This file is part of the "Teapot" project, and is released under the MIT license.
4
4
  #
5
5
 
6
- teapot_version "1.0.0"
6
+ teapot_version "3.0.0"
7
7
 
8
- define_configuration 'test' do |configuration|
8
+ define_target "context_spec" do |target|
9
+ end
10
+
11
+ define_configuration 'development' do |configuration|
12
+ configuration.import 'context_spec'
13
+ end
14
+
15
+ define_configuration 'context_spec' do |configuration|
9
16
  configuration.public!
10
17
 
11
18
  configuration[:source] = "../kurocha"
@@ -31,6 +38,3 @@ define_configuration 'test' do |configuration|
31
38
 
32
39
  configuration.require "opencv"
33
40
  end
34
-
35
- define_target "context_spec" do |target|
36
- end
@@ -23,7 +23,7 @@ require 'teapot/context'
23
23
  RSpec.describe Teapot::Target do
24
24
  let(:root) {Build::Files::Path.new(__dir__) + "target_spec"}
25
25
 
26
- it "should generate environment for configuration" do
26
+ it "should generate correct chain for configuration" do
27
27
  context = Teapot::Context.new(root)
28
28
  selection = context.select(["Test/TargetSpec"])
29
29
 
@@ -39,15 +39,6 @@ RSpec.describe Teapot::Target do
39
39
  expect(chain.ordered[1].name).to be == 'Platform/generic'
40
40
  expect(chain.ordered[2].name).to be == 'Test/TargetSpec'
41
41
  expect(chain.ordered[2].provider).to be == target
42
-
43
- environment = target.environment(selection.configuration, chain)
44
- # Environment#to_hash flattens the environment and evaluates all values:
45
- hash = environment.to_hash
46
-
47
- expect(hash[:variant]).to be == 'debug'
48
- expect(hash[:platform_name]).to be == 'generic'
49
-
50
- expect(hash).to include(:buildflags, :linkflags, :build_prefix, :install_prefix, :platforms_path)
51
42
  end
52
43
 
53
44
  it "should match wildcard packages" do
data/teapot.gemspec CHANGED
@@ -16,34 +16,29 @@ Gem::Specification.new do |spec|
16
16
  spec.summary = %q{Teapot is a tool for managing complex cross-platform builds.}
17
17
  spec.homepage = "http://www.teapot.nz"
18
18
  spec.license = "MIT"
19
-
19
+
20
20
  spec.files = `git ls-files`.split($/)
21
21
  spec.executables = spec.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
22
22
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
23
23
  spec.require_paths = ["lib"]
24
24
 
25
- spec.has_rdoc = 'yard'
26
-
27
25
  spec.required_ruby_version = '>= 2.1.0'
28
26
 
29
- spec.add_dependency "rainbow", "~> 2.0"
27
+ spec.add_dependency "graphviz", "~> 1.0"
28
+ spec.add_dependency "rugged", "~> 0.27.0"
30
29
 
31
- spec.add_dependency "graphviz", "~> 0.4"
32
-
33
- spec.add_dependency "rugged"
34
-
35
- spec.add_dependency "build", "~> 1.1"
36
- spec.add_dependency "build-files", "~> 1.3"
37
- spec.add_dependency "build-dependency", "~> 1.1"
30
+ spec.add_dependency "build", "~> 2.4"
31
+ spec.add_dependency "build-environment", "~> 1.10"
32
+ spec.add_dependency "build-files", "~> 1.4"
33
+ spec.add_dependency "build-dependency", "~> 1.4"
38
34
  spec.add_dependency "build-uri", "~> 1.0"
39
35
  spec.add_dependency "build-text", "~> 1.0"
40
36
 
41
- spec.add_dependency "samovar", "~> 1.7"
42
-
43
- # This could be a good option in the future for teapot fetch:
44
- #spec.add_dependency "rugged"
37
+ spec.add_dependency "console", "~> 1.0"
38
+ spec.add_dependency "samovar", "~> 2.0"
45
39
 
46
- spec.add_development_dependency "bundler", "~> 1.3"
40
+ spec.add_development_dependency "covered"
41
+ spec.add_development_dependency "bundler"
47
42
  spec.add_development_dependency "rspec", "~> 3.6"
48
43
  spec.add_development_dependency "rake"
49
44
  end