Class: Rudder::DSL::Pipeline
- Inherits:
-
Object
- Object
- Rudder::DSL::Pipeline
- Includes:
- Util
- Defined in:
- lib/rudder/dsl/pipeline.rb
Overview
Concourse Pipeline. Main entry of the DSL. Evaluates user defined pipelines.
DSL Usage:
Pipeline's are composed of various components:
-
Resource: basic inputs and output of jobs.
-
Job: basic computation unit of a pipeline
-
ResourceType: custom resource definitions
-
Group: logical grouping of jobs in the UI. Either every job is in a Group or no job is (hard Concourse requirement)
Adding Components
Components are added to the Pipeline by component type, followed by name, optional arguments, then typically a block.
Loading Other Pipelines
Pipeline's can load other pipeline definitions using #load. This is a useful mechanism for abstracting out common subsections of pipelines, then merging them into larger pipelines.
Loading Individual Components
Individual pipeline components can also be defined on a per-file basis and then loaded into a Pipeline using #load_component. This is useful for factoring out common resources for multiple pipeline's to use.
Instance Attribute Summary collapse
-
#groups ⇒ Hash<(String, Symbol), Rudder::DSL::Group>
Hash of names to Group.
-
#jobs ⇒ Hash<(String, Symbol), Rudder::DSL::Job>
Hash of names to Job.
-
#resource_types ⇒ Hash<(String, Symbol), Rudder::DSL::ResourceType>
Hash of names to ResourceType.
-
#resources ⇒ Hash<(String, Symbol), Rudder::DSL::Resource>
Hash of names to Resource.
Instance Method Summary collapse
-
#_get_local_component(component) ⇒ Object
Yikes! Seems like a bad idea - if someone uses the same name twice (say, 1 resource and 1 job), then this will return one pretty much at random.
-
#eval(file_path = nil) ⇒ Rudder::DSL::Pipeline
Evaluates the given file path.
-
#initialize(file_path = nil, resources: {}, jobs: {}, groups: {}, resource_types: {}) ⇒ Pipeline
constructor
All pipelines require: - Jobs - Resources.
-
#load(other_pipeline_path, resources: {}, resource_types: {}, jobs: {}, groups: {}) ⇒ Object
Given a path relative to this pipeline, loads another pipeline and returns it.
-
#load_component(component_path, class_sym, name, *args) ⇒ Object
Given a path to a component, its class, and any args required to construct it, creates a new component.
-
#method_missing(method, *args, &component_block) ⇒ Rudder::DSL::Component?
Populates this Pipeline with components and optionally fetches defined components.
- #respond_to?(name, _include_all = true) ⇒ Boolean
-
#respond_to_missing?(*_) ⇒ Boolean
Pipeline's respond to missing.
-
#to_h ⇒ Hash
Renders all of this pipeline's components to their
Hash
representations.
Methods included from Util
Constructor Details
#initialize(file_path = nil, resources: {}, jobs: {}, groups: {}, resource_types: {}) ⇒ Pipeline
All pipelines require:
-
Jobs
-
Resources
Concourse Pipelines may optionally provide:
-
Resource Types
-
Groups
Rudder
Pipelines may optionally include a
file_path
. This is required when loading resources from
neighboring files.
All pipeline requirements are only needed at the Pipeline render time (after evaluation), and need not be specified for initialization.
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/rudder/dsl/pipeline.rb', line 166 def initialize(file_path = nil, resources: {}, jobs: {}, groups: {}, resource_types: {}) @resources = resources @jobs = jobs @groups = groups @resource_types = resource_types # rubocop:disable Layout/AlignHash, Layout/SpaceBeforeComma @known_classes = { resource: { clazz: Resource , pipeline_group: @resources }, job: { clazz: Job , pipeline_group: @jobs }, group: { clazz: Group , pipeline_group: @groups }, resource_type: { clazz: ResourceType, pipeline_group: @resource_types } } # rubocop:enable Layout/AlignHash, Layout/SpaceBeforeComma @pipelines = {} @file_path = file_path end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args, &component_block) ⇒ Rudder::DSL::Component?
Populates this Rudder::DSL::Pipeline with components and optionally fetches defined components.
Fetching
When method
is called with no arguments it is treated as a
Rudder::DSL::Pipeline getter method. method
is translated to
the name of a Component and the Component
is
returned if defined, otherwise nil is returned.
Setting
When method
is passed any arguments (positional,
placement, or block) then method
is treated as a setter.
When setting, method
must be the name of a known
Component. The first argument is a required name
for the component. All arguments and keyword arguments are then
delegated to the Component's specific initializer.
Finally, when a block is provided it is evaluated within the context of the newly constructed Component with full priveleges to operate on it.
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/rudder/dsl/pipeline.rb', line 237 def method_missing(method, *args, &component_block) local_component = _get_local_component(method) if !@known_classes.include?(method) && !local_component return super.send(method, args, component_block) end # Look up a previously defined component from the pipeline return local_component if local_component && args.empty? && !block_given? component_group = @known_classes[method][:pipeline_group] name = args[0] raise "Overlapping component name: #{method}" if component_group.include? name component = @known_classes[method][:clazz].new(*args) component.instance_exec self, &component_block if block_given? component_group[name] = component end |
Instance Attribute Details
#groups ⇒ Hash<(String, Symbol), Rudder::DSL::Group>
Hash of names to Group
138 139 140 |
# File 'lib/rudder/dsl/pipeline.rb', line 138 def groups @groups end |
#jobs ⇒ Hash<(String, Symbol), Rudder::DSL::Job>
Hash of names to Job
132 133 134 |
# File 'lib/rudder/dsl/pipeline.rb', line 132 def jobs @jobs end |
#resource_types ⇒ Hash<(String, Symbol), Rudder::DSL::ResourceType>
Hash of names to ResourceType
135 136 137 |
# File 'lib/rudder/dsl/pipeline.rb', line 135 def resource_types @resource_types end |
#resources ⇒ Hash<(String, Symbol), Rudder::DSL::Resource>
Hash of names to Resource
129 130 131 |
# File 'lib/rudder/dsl/pipeline.rb', line 129 def resources @resources end |
Instance Method Details
#_get_local_component(component) ⇒ Object
Yikes! Seems like a bad idea - if someone uses the same name twice (say, 1 resource and 1 job), then this will return one pretty much at random. TODO: Make this not bad Oh well.. TODO: This may be returning a non-nil/non-falsey type that causes some issues
363 364 365 366 367 368 369 370 371 |
# File 'lib/rudder/dsl/pipeline.rb', line 363 def _get_local_component(component) component = component.to_sym locals = @known_classes.values.map do |m| m[:pipeline_group][component] end.compact # TODO: Add a logger here.. puts "Found multiple bindings for: #{p}. Getting first found" unless locals.size <= 1 locals[0] end |
#eval(file_path = nil) ⇒ Rudder::DSL::Pipeline
Evaluates the given file path. If file_path nil, defaults to the one provided at construction time If both are nil, raises an exception
279 280 281 282 283 284 285 286 287 288 289 |
# File 'lib/rudder/dsl/pipeline.rb', line 279 def eval(file_path = nil) @file_path = file_path || @file_path if @file_path.nil? raise 'File path must be provided at Pipeline initialization or eval call' end File.open(@file_path) do |f| instance_eval f.read, @file_path end self end |
#load(other_pipeline_path, resources: {}, resource_types: {}, jobs: {}, groups: {}) ⇒ Object
Given a path relative to this pipeline, loads another pipeline and returns it
Note that this includes nothing from the relative pipeline in this one, instead just returning the pipeline to be manipulated
May also optionally provides hashes for
-
resources
-
resource_types
-
jobs
-
groups
314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 |
# File 'lib/rudder/dsl/pipeline.rb', line 314 def load(other_pipeline_path, resources: {}, resource_types: {}, jobs: {}, groups: {}) if @pipelines.key? other_pipeline_path @pipelines[other_pipeline_path] else dir = File.dirname(@file_path) full_path = File.join(dir, other_pipeline_path) pipeline = Rudder::DSL::Pipeline.new( full_path, resources: resources, resource_types: resource_types, jobs: jobs, groups: groups ).eval @pipelines[other_pipeline_path] = pipeline pipeline end end |
#load_component(component_path, class_sym, name, *args) ⇒ Object
Given a path to a component, its class, and any args required to construct it, creates a new component
Note that this automatically includes the component into this pipeline
347 348 349 350 351 352 353 354 355 356 |
# File 'lib/rudder/dsl/pipeline.rb', line 347 def load_component(component_path, class_sym, name, *args) raise "Unable to load #{class_sym}" unless @known_classes.keys.include? class_sym raise 'Name must not be nil' if name.nil? full_path = File.join(File.dirname(@file_path), component_path) component = @known_classes[class_sym][:clazz].new(name, *args) component.instance_eval File.read(full_path), full_path @known_classes[class_sym][:pipeline_group][name] = component component end |
#respond_to?(name, _include_all = true) ⇒ Boolean
265 266 267 |
# File 'lib/rudder/dsl/pipeline.rb', line 265 def respond_to?(name, _include_all = true) @known_classes.key? name end |
#respond_to_missing?(*_) ⇒ Boolean
Rudder::DSL::Pipeline's respond to missing
261 262 263 |
# File 'lib/rudder/dsl/pipeline.rb', line 261 def respond_to_missing?(*_) true end |
#to_h ⇒ Hash
Renders all of this pipeline's components to their Hash
representations.
192 193 194 195 196 197 198 199 200 |
# File 'lib/rudder/dsl/pipeline.rb', line 192 def to_h h = { 'resources' => _convert_h_val(@resources.values), 'jobs' => _convert_h_val(@jobs.values) } h['groups'] = _convert_h_val(@groups.values) unless @groups.empty? h['resource_types'] = _convert_h_val(@resource_types.values) unless @resource_types.empty? h end |