Class: Teapot::Configuration

Inherits:
Definition show all
Defined in:
lib/teapot/configuration.rb

Overview

A configuration represents a mapping between package/dependency names and actual source locations. Usually, there is only one configuration, but in some cases it is useful to have more than one, e.g. one for local development using local source code, one for continuous integration, and one for deployment.

Defined Under Namespace

Classes: Import

Constant Summary collapse

DEFAULT_OPTIONS =
{
	:import => true
}.freeze

Instance Attribute Summary collapse

Attributes inherited from Definition

#context, #description, #name, #package

Instance Method Summary collapse

Methods inherited from Definition

#inspect, #path

Constructor Details

#initialize(context, package, name, packages = [], **options) ⇒ Configuration

Returns a new instance of Configuration.



38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/teapot/configuration.rb', line 38

def initialize(context, package, name, packages = [], **options)
	super context, package, name

	@options = DEFAULT_OPTIONS.merge(options)

	@packages = Build::Dependency::Set.new(packages)
	@imports = Build::Dependency::Set.new

	@visibility = :private

	# A list of named targets for specific purposes:
	@targets = Hash.new{|hash,key| hash[key] = Array.new}
end

Instance Attribute Details

#importsObject (readonly)

A list of other configurations to include when materialising the list of packages.



96
97
98
# File 'lib/teapot/configuration.rb', line 96

def imports
  @imports
end

#optionsObject (readonly)

Options used to bind packages to this configuration.



90
91
92
# File 'lib/teapot/configuration.rb', line 90

def options
  @options
end

#packagesObject (readonly)

A list of packages which are required by this configuration.



93
94
95
# File 'lib/teapot/configuration.rb', line 93

def packages
  @packages
end

#targetsObject (readonly)

A table of named targets for specific purposes.



87
88
89
# File 'lib/teapot/configuration.rb', line 87

def targets
  @targets
end

#visibilityObject (readonly)

Controls how the configuration is exposed in the context.



76
77
78
# File 'lib/teapot/configuration.rb', line 76

def visibility
  @visibility
end

Instance Method Details

#[](key) ⇒ Object

Get a configuration option.



131
132
133
# File 'lib/teapot/configuration.rb', line 131

def [] key
	@options[key]
end

#[]=(key, value) ⇒ Object

Set a configuration option.



126
127
128
# File 'lib/teapot/configuration.rb', line 126

def []= key, value
	@options[key] = value
end

#build_pathObject Also known as: platforms_path

The path where built products will be placed.



141
142
143
# File 'lib/teapot/configuration.rb', line 141

def build_path
	context.root + "teapot/build/#{name}"
end

#environmentObject



66
67
68
69
70
71
72
73
# File 'lib/teapot/configuration.rb', line 66

def environment
	configuration = self
	
	Build::Environment.new(name: self.name) do
		default build_path configuration.build_path
		default platforms_path configuration.build_path
	end
end

#freezeObject



52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/teapot/configuration.rb', line 52

def freeze
	return self if frozen?
	
	@options.freeze
	@packages.freeze
	@imports.freeze
	@visibility.freeze
	
	@targets.default = [].freeze
	@targets.freeze
	
	super
end

#groupObject

Create a group for configuration options which will be only be active within the group block.



117
118
119
120
121
122
123
# File 'lib/teapot/configuration.rb', line 117

def group
	options = @options.dup
	
	yield
	
	@options = options
end

#import(name, explicit = true) ⇒ Object

Specifies that this package will import additional configuration records from another definition.



112
113
114
# File 'lib/teapot/configuration.rb', line 112

def import(name, explicit = true)
	@imports << Import.new(name, explicit, @options.dup)
end

#lock_pathObject



147
148
149
# File 'lib/teapot/configuration.rb', line 147

def lock_path
	context.root + "#{@name}-lock.yml"
end

#lock_storeObject



151
152
153
# File 'lib/teapot/configuration.rb', line 151

def lock_store
	YAML::Store.new(lock_path.to_s)
end

#merge(configuration) ⇒ Object

Merge an external configuration into this configuration. We won’t override already defined packages.



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/teapot/configuration.rb', line 178

def merge(configuration)
	configuration.packages.each do |package|
		# The top level configuration will override packages that are defined by imported configurations. This is desirable behaviour, as it allows us to flatten the configuration but provide overrides if required.
		unless @packages.include? package
			package = Package.new(packages_path + package.name, package.name, @options.merge(package.options))
			
			@packages << package
			
			yield package
		end
	end
	
	configuration.imports.each do |import|
		unless @imports.include? import
			@imports << Import.new(import.name, import.explicit, @options.merge(import.options))
		end
	end
	
	configuration.targets.each do |key, value|
		@targets[key] += value
	end
	
	return self
end

#packages_pathObject

The path where packages will be located when fetched.



136
137
138
# File 'lib/teapot/configuration.rb', line 136

def packages_path
	context.root + "teapot/packages/#{name}"
end

#public!Object



82
83
84
# File 'lib/teapot/configuration.rb', line 82

def public!
	@visibility = :public
end

#public?Boolean

Returns:

  • (Boolean)


78
79
80
# File 'lib/teapot/configuration.rb', line 78

def public?
	@visibility == :public
end

#require(name, **options) ⇒ Object

Specifies that this configuration depends on an external package of some sort.



99
100
101
102
103
104
105
106
107
108
109
# File 'lib/teapot/configuration.rb', line 99

def require(name, **options)
	options = @options.merge(options)
	
	@packages << Package.new(packages_path + name.to_s, name, options)
	
	if options[:import] == true
		import(name, false)
	elsif String === options[:import]
		import(options[:import])
	end
end

#to_sObject



155
156
157
# File 'lib/teapot/configuration.rb', line 155

def to_s
	"#<#{self.class} #{@name.dump} visibility=#{@visibility}>"
end

#traverse(configurations, imported = Build::Dependency::Set.new) {|_self| ... } ⇒ Object

Process all import directives and return a new configuration based on the current configuration. Import directives bring packages and other import directives from the specififed configuration definition.

Yields:

  • (_self)

Yield Parameters:



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/teapot/configuration.rb', line 160

def traverse(configurations, imported = Build::Dependency::Set.new, &block)
	yield self # Whatever happens here, should ensure that...
	
	@imports.each do |import|
		# So we don't get into some crazy cycle:
		next if imported.include?(import)
		
		# Mark it as being imported:
		imported << import
		
		# ... by here, the configuration is available:
		if configuration = configurations[import.name]
			configuration.traverse(configurations, imported, &block)
		end
	end
end