Class: Teapot::Context

Inherits:
Object
  • Object
show all
Defined in:
lib/teapot/context.rb

Overview

A context represents a specific root package instance with a given configuration and all related definitions. A context is stateful in the sense that package selection is specialized based on #select and #dependency_chain. These parameters are usually set up initially as part of the context setup.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(root, options = {}) ⇒ Context

Returns a new instance of Context.



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/teapot/context.rb', line 46

def initialize(root, options = {})
	@root = Path[root]
	@options = options

	@metadata = Metadata.new(self)

	@targets = {}
	@generators = {}
	@configurations = {}
	@projects = {}
	@rules = Build::Rulebook.new

	@dependencies = []
	@selection = Set.new

	@loaded = {}

	unless options[:fake]
		load_root_package(options)
	end
end

Instance Attribute Details

#configurationObject (readonly)

The context’s primary configuration.



84
85
86
# File 'lib/teapot/context.rb', line 84

def configuration
  @configuration
end

#configurationsObject (readonly)

All public configurations.



79
80
81
# File 'lib/teapot/context.rb', line 79

def configurations
  @configurations
end

#dependenciesObject (readonly)

Returns the value of attribute dependencies.



89
90
91
# File 'lib/teapot/context.rb', line 89

def dependencies
  @dependencies
end

#generatorsObject (readonly)

Returns the value of attribute generators.



72
73
74
# File 'lib/teapot/context.rb', line 72

def generators
  @generators
end

#metadataObject (readonly)

Context metadata



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

def 
  @metadata
end

#optionsObject (readonly)

Returns the value of attribute options.



69
70
71
# File 'lib/teapot/context.rb', line 69

def options
  @options
end

#projectObject (readonly)

The context’s primary project.



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

def project
  @project
end

#projectsObject (readonly)

Returns the value of attribute projects.



73
74
75
# File 'lib/teapot/context.rb', line 73

def projects
  @projects
end

#rootObject (readonly)

Returns the value of attribute root.



68
69
70
# File 'lib/teapot/context.rb', line 68

def root
  @root
end

#rulesObject (readonly)

Returns the value of attribute rules.



81
82
83
# File 'lib/teapot/context.rb', line 81

def rules
  @rules
end

#selectionObject (readonly)

Returns the value of attribute selection.



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

def selection
  @selection
end

#targetsObject (readonly)

Returns the value of attribute targets.



71
72
73
# File 'lib/teapot/context.rb', line 71

def targets
  @targets
end

Instance Method Details

#<<(definition) ⇒ Object

Add a definition to the current context.



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/teapot/context.rb', line 117

def << definition
	case definition
	when Target
		AlreadyDefinedError.check(definition, @targets)

		@targets[definition.name] = definition
	when Generator
		AlreadyDefinedError.check(definition, @generators)

		@generators[definition.name] = definition
	when Configuration
		# We define configurations in two cases, if they are public, or if they are part of the root package of this context.
		if definition.public? or definition.package == @root_package
			# The root package implicitly defines the default configuration.
			if definition.name == DEFAULT_CONFIGURATION_NAME
				raise AlreadyDefinedError.new(definition, root_package)
			end

			AlreadyDefinedError.check(definition, @configurations)

			@configurations[definition.name] = definition
		end
	when Project
		AlreadyDefinedError.check(definition, @projects)

		@project ||= definition

		@projects[definition.name] = definition
	when Rule
		AlreadyDefinedError.check(definition, @rules)

		@rules << definition
	end
end

#dependency_chain(dependency_names, configuration = @configuration) ⇒ Object



102
103
104
105
106
107
108
# File 'lib/teapot/context.rb', line 102

def dependency_chain(dependency_names, configuration = @configuration)
	configuration.load_all
	
	select(dependency_names)
	
	Dependency::chain(@selection, @dependencies, @targets.values)
end

#direct_targets(ordered) ⇒ Object



110
111
112
113
114
# File 'lib/teapot/context.rb', line 110

def direct_targets(ordered)
	@dependencies.collect do |dependency|
		ordered.find{|(package, _)| package.provides? dependency}
	end.compact
end

#load(package) ⇒ Object



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/teapot/context.rb', line 152

def load(package)
	# In certain cases, a package record might be loaded twice. This typically occurs when multiple configurations are loaded in the same context, or if a package has already been loaded (as is typical with the root package).
	@loaded.fetch(package) do
		loader = Loader.new(self, package)
		
		loader.load(TEAPOT_FILE)
		
		# Load the definitions into the current context:
		loader.defined.each do |definition|
			self << definition
		end

		# Save the definitions per-package:
		@loaded[package] = loader.defined
	end
end

#root_packageObject

The root package is a special package which is used to load definitions from a given root path.



185
186
187
# File 'lib/teapot/context.rb', line 185

def root_package
	@root_package ||= Package.new(@root, "root")
end

#select(names) ⇒ Object



92
93
94
95
96
97
98
99
100
# File 'lib/teapot/context.rb', line 92

def select(names)
	names.each do |name|
		if @targets.key? name
			@selection << name
		else
			@dependencies << name
		end
	end
end

#unresolved(packages) ⇒ Object



169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/teapot/context.rb', line 169

def unresolved(packages)
	failed_to_load = Set.new
	
	packages.collect do |package|
		begin
			definitions = load(package)
		rescue NonexistantTeapotError, IncompatibleTeapotError
			# If the package doesn't exist or the teapot version is too old, it failed:
			failed_to_load << package
		end
	end
	
	return failed_to_load
end