Class: Rake::Pipeline

Inherits:
Object
  • Object
show all
Defined in:
lib/rake-pipeline.rb,
lib/rake-pipeline/cli.rb,
lib/rake-pipeline/dsl.rb,
lib/rake-pipeline/error.rb,
lib/rake-pipeline/graph.rb,
lib/rake-pipeline/filter.rb,
lib/rake-pipeline/server.rb,
lib/rake-pipeline/matcher.rb,
lib/rake-pipeline/project.rb,
lib/rake-pipeline/railtie.rb,
lib/rake-pipeline/version.rb,
lib/rake-pipeline/manifest.rb,
lib/rake-pipeline/middleware.rb,
lib/rake-pipeline/file_wrapper.rb,
lib/rake-pipeline/manifest_entry.rb,
lib/rake-pipeline/dsl/project_dsl.rb,
lib/rake-pipeline/dsl/pipeline_dsl.rb,
lib/rake-pipeline/dynamic_file_task.rb,
lib/rake-pipeline/filters/concat_filter.rb,
lib/rake-pipeline/filters/ordering_concat_filter.rb,
lib/rake-pipeline/filters/pipeline_finalizing_filter.rb,
lib/generators/rake/pipeline/install/install_generator.rb

Overview

A Pipeline is responsible for taking a directory of input files, applying a number of filters to the inputs, and outputting them into an output directory.

The normal way to build and configure a pipeline is by using Pipeline.build. Inside the block passed to Pipeline.build, all methods of DSL are available.

Examples:

Rake::Pipeline.build do
  # process all js, css and html files in app/assets
  input "app/assets", "**/*.{js,coffee,css,scss,html}"

  # processed files should be outputted to public
  output "public"

  # process all coffee files
  match "*.coffee" do
    # compile all CoffeeScript files. the output file
    # for the compilation should be the input name
    # with the .coffee extension replaced with .js
    filter(CoffeeCompiler) do |input|
      input.sub(/\.coffee$/, '.js')
    end
  end

  # specify filters for js files. this includes the
  # output of the previous step, which converted
  # coffee files to js files
  match "*.js" do
    # first, wrap all JS files in a custom filter
    filter ClosureFilter
    # then, concatenate all JS files into a single file
    concat "application.js"
  end

  # specify filters for css and scss files
  match "*.{css,scss}" do
    # compile CSS and SCSS files using the SCSS
    # compiler. if an input file has the extension
    # scss, replace it with css
    filter(ScssCompiler) do |input|
      input.sub(/\.scss$/, 'css')
    end
    # then, concatenate all CSS files into a single file
    concat "application.css"
  end

  # the remaining files not specified by a matcher (the
  # HTML files) are simply copied over.

  # you can also specify filters here that will apply to
  # all processed files (application.js and application.css)
  # up until this point, as well as the HTML files.
end

See Also:

Direct Known Subclasses

Matcher

Defined Under Namespace

Modules: DSL Classes: CLI, ConcatFilter, DynamicFileTask, EncodingError, Error, FileWrapper, Filter, Graph, InstallGenerator, Manifest, ManifestEntry, Matcher, Middleware, OrderingConcatFilter, PipelineFinalizingFilter, Project, Railtie, Server, UnopenedFile

Constant Summary collapse

VERSION =

Version:

  • 0.7.0

"0.7.0"
@@tmp_id =
0

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Pipeline

Returns a new instance of Pipeline.

Parameters:

  • options (Hash) (defaults to: {})

Options Hash (options):

  • :inputs (Hash)

    set the pipeline’s #inputs.

  • :tmpdir (String)

    set the pipeline’s #tmpdir.

  • :output_root (String)

    set the pipeline’s #output_root.

  • :rake_application (Rake::Application)

    set the pipeline’s #rake_application.



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/rake-pipeline.rb', line 145

def initialize(options={})
  @filters         = []
  @invoke_mutex    = Mutex.new
  @clean_mutex     = Mutex.new
  @inputs          = options[:inputs] || {}
  @tmpdir          = options[:tmpdir] || "tmp"
  @project         = options[:project]

  if options[:output_root]
    self.output_root = options[:output_root]
  end

  if options[:rake_application]
    self.rake_application = options[:rake_application]
  end
end

Instance Attribute Details

#filtersArray (readonly)

Returns this pipeline’s filters.

Returns:

  • (Array)

    this pipeline’s filters.



129
130
131
# File 'lib/rake-pipeline.rb', line 129

def filters
  @filters
end

#input_filesArray<FileWrapper> Also known as: eligible_input_files

If you specify #inputs, this method will calculate the input files for the directory. If you supply input_files directly, this method will simply return the input_files you supplied.

Returns:

  • (Array<FileWrapper>)

    An Array of file wrappers that represent the inputs for the current pipeline.



247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
# File 'lib/rake-pipeline.rb', line 247

def input_files
  return @input_files if @input_files

  assert_input_provided

  result = []

  @inputs.each do |root, glob|
    expanded_root = File.expand_path(root)
    files = Dir[File.join(expanded_root, glob)].sort.select { |f| File.file?(f) }

    files.each do |file|
      relative_path = file.sub(%r{^#{Regexp.escape(expanded_root)}/}, '')
      result << FileWrapper.new(expanded_root, relative_path)
    end
  end

  result.sort
end

#inputsHash[String, String]

Returns the directory paths for the input files and their matching globs.

Returns:

  • (Hash[String, String])

    the directory paths for the input files and their matching globs.



111
112
113
# File 'lib/rake-pipeline.rb', line 111

def inputs
  @inputs
end

#output_filesArray<FileWrapper> (readonly)

A list of the output files that invoking this pipeline will generate.

Returns:



126
127
128
# File 'lib/rake-pipeline.rb', line 126

def output_files
  @output_files
end

#output_rootString

Returns the directory path for the output files.

Returns:

  • (String)

    the directory path for the output files.



114
115
116
# File 'lib/rake-pipeline.rb', line 114

def output_root
  @output_root
end

#projectProject (readonly)

Returns the Project that created this pipeline.

Returns:

  • (Project)

    the Project that created this pipeline



134
135
136
# File 'lib/rake-pipeline.rb', line 134

def project
  @project
end

#rake_tasksArray (readonly)

Returns an Array of Rake::Task objects. This property is populated by the #generate_rake_tasks method.

Returns:

  • (Array)

    an Array of Rake::Task objects. This property is populated by the #generate_rake_tasks method.



122
123
124
# File 'lib/rake-pipeline.rb', line 122

def rake_tasks
  @rake_tasks
end

#tmpdirString

Returns the directory path for temporary files.

Returns:

  • (String)

    the directory path for temporary files



117
118
119
# File 'lib/rake-pipeline.rb', line 117

def tmpdir
  @tmpdir
end

Class Method Details

.build(options = {}, &block) ⇒ Rake::Pipeline

Build a new pipeline taking a block. The block will be evaluated by the Rake::Pipeline::DSL class.

Examples:

Rake::Pipeline.build do
  input "app/assets"
  output "public"

  concat "app.js"
end

Returns:

See Also:



180
181
182
183
# File 'lib/rake-pipeline.rb', line 180

def self.build(options={}, &block)
  pipeline = new(options)
  pipeline.build(options, &block)
end

Instance Method Details

#add_filters(*filters) ⇒ void Also known as: add_filter

This method returns an undefined value.

Add one or more filters to the current pipeline.

Parameters:

  • filters (Array<Filter>)

    a list of filters



290
291
292
293
294
295
296
# File 'lib/rake-pipeline.rb', line 290

def add_filters(*filters)
  filters.each do |filter|
    filter.rake_application = rake_application
    filter.pipeline = self
  end
  @filters.concat(filters)
end

#add_input(root, pattern = nil) ⇒ Object

Add an input directory, optionally filtering which files within the input directory are included.

Parameters:

  • root (String)

    the input root directory; required

  • pattern (String) (defaults to: nil)

    a pattern to match within root; optional; defaults to “*/



235
236
237
238
# File 'lib/rake-pipeline.rb', line 235

def add_input(root, pattern = nil)
  pattern ||= "**/*"
  @inputs[root] = pattern
end

#build(options = {}, &block) ⇒ Rake::Pipeline

Evaluate a block using the Rake::Pipeline DSL against an existing pipeline.

Returns:

  • (Rake::Pipeline)

    this pipeline with any modifications made by the given block.

See Also:



192
193
194
195
# File 'lib/rake-pipeline.rb', line 192

def build(options={}, &block)
  DSL::PipelineDSL.evaluate(self, options, &block) if block
  self
end

#copy(target_class = self.class, &block) ⇒ Pipeline

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Copy the current pipeline’s attributes over.

Parameters:

  • target_class (Class) (defaults to: self.class)

    the class to create a new instance of. Defaults to the class of the current pipeline. Is overridden in Matcher

  • block (Proc)

    a block to pass to the DSL

Returns:



207
208
209
210
211
212
213
# File 'lib/rake-pipeline.rb', line 207

def copy(target_class=self.class, &block)
  pipeline = target_class.build(&block)
  pipeline.inputs = inputs
  pipeline.tmpdir = tmpdir
  pipeline.rake_application = rake_application
  pipeline
end

#finalizevoid

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Add a final filter to the pipeline that will copy the pipeline’s generated files to the output.



381
382
383
# File 'lib/rake-pipeline.rb', line 381

def finalize
  add_filter(Rake::Pipeline::PipelineFinalizingFilter.new)
end

#invokevoid

This method returns an undefined value.

Invoke the pipeline, processing the inputs into the output. If the pipeline has already been invoked, reinvoking will not pick up new input files added to the file system.



304
305
306
307
308
309
310
311
312
313
# File 'lib/rake-pipeline.rb', line 304

def invoke
  @invoke_mutex.synchronize do
    self.rake_application = Rake::Application.new unless @rake_application

    setup

    @rake_tasks.each { |task| task.recursively_reenable(rake_application) }
    @rake_tasks.each { |task| task.invoke }
  end
end

#invoke_cleanvoid

This method returns an undefined value.

Pick up any new files added to the inputs and process them through the filters. Then call #invoke.



319
320
321
322
323
324
# File 'lib/rake-pipeline.rb', line 319

def invoke_clean
  @clean_mutex.synchronize do
    @rake_tasks = @rake_application = nil
    invoke
  end
end

#rake_applicationRake::Application

Returns The Rake::Application to install rake tasks onto. Defaults to Rake.application.

Returns:

  • (Rake::Application)

    The Rake::Application to install rake tasks onto. Defaults to Rake.application



273
274
275
# File 'lib/rake-pipeline.rb', line 273

def rake_application
  @rake_application || Rake.application
end

#rake_application=(rake_application) ⇒ void

This method returns an undefined value.

Set the rake_application on the pipeline and apply it to filters.



280
281
282
283
284
# File 'lib/rake-pipeline.rb', line 280

def rake_application=(rake_application)
  @rake_application = rake_application
  @filters.each { |filter| filter.rake_application = rake_application }
  @rake_tasks = nil
end

#setupvoid

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Set up the filters and generate rake tasks. In general, this method is called by invoke.



331
332
333
334
# File 'lib/rake-pipeline.rb', line 331

def setup
  setup_filters
  generate_rake_tasks
end

#setup_filtersvoid

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Set up the filters. This will loop through all of the filters for the current pipeline and wire up their input_files and output_files.

Because matchers implement the filter API, matchers will also be set up as part of this process.



344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
# File 'lib/rake-pipeline.rb', line 344

def setup_filters
  last = @filters.last

  @filters.inject(eligible_input_files) do |current_inputs, filter|
    filter.input_files = current_inputs

    # if filters are being reinvoked, they should keep their roots but
    # get updated with new files.
    filter.output_root ||= begin
      output = if filter == last
        output_root
      else
        generate_tmpdir
      end

      File.expand_path(output)
    end

    filter.setup_filters if filter.respond_to?(:setup_filters)

    filter.output_files
  end
end