teapot 2.2.0 → 3.2.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/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