rake-pipeline 0.5.0 → 0.7.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/.travis.yml +12 -0
- data/Gemfile +1 -0
- data/README.markdown +1 -1
- data/README.yard +61 -32
- data/Rakefile +9 -0
- data/bin/rakep +1 -24
- data/lib/generators/rake/pipeline/install/install_generator.rb +70 -0
- data/lib/rake-pipeline.rb +117 -53
- data/lib/rake-pipeline/cli.rb +56 -0
- data/lib/rake-pipeline/dsl.rb +3 -140
- data/lib/rake-pipeline/dsl/pipeline_dsl.rb +168 -0
- data/lib/rake-pipeline/dsl/project_dsl.rb +108 -0
- data/lib/rake-pipeline/dynamic_file_task.rb +188 -0
- data/lib/rake-pipeline/file_wrapper.rb +1 -1
- data/lib/rake-pipeline/filter.rb +45 -15
- data/lib/rake-pipeline/filters.rb +3 -1
- data/lib/rake-pipeline/filters/{concat.rb → concat_filter.rb} +0 -0
- data/lib/rake-pipeline/filters/ordering_concat_filter.rb +38 -0
- data/lib/rake-pipeline/filters/pipeline_finalizing_filter.rb +19 -0
- data/lib/rake-pipeline/graph.rb +178 -0
- data/lib/rake-pipeline/manifest.rb +63 -0
- data/lib/rake-pipeline/manifest_entry.rb +34 -0
- data/lib/rake-pipeline/matcher.rb +65 -30
- data/lib/rake-pipeline/middleware.rb +15 -12
- data/lib/rake-pipeline/precompile.rake +8 -0
- data/lib/rake-pipeline/project.rb +280 -0
- data/lib/rake-pipeline/railtie.rb +16 -1
- data/lib/rake-pipeline/server.rb +15 -0
- data/lib/rake-pipeline/version.rb +2 -2
- data/rake-pipeline.gemspec +2 -0
- data/spec/cli_spec.rb +71 -0
- data/spec/concat_filter_spec.rb +1 -27
- data/spec/{dsl_spec.rb → dsl/pipeline_dsl_spec.rb} +32 -18
- data/spec/dsl/project_dsl_spec.rb +41 -0
- data/spec/dynamic_file_task_spec.rb +111 -0
- data/spec/encoding_spec.rb +6 -8
- data/spec/file_wrapper_spec.rb +19 -2
- data/spec/filter_spec.rb +120 -22
- data/spec/graph_spec.rb +56 -0
- data/spec/manifest_entry_spec.rb +51 -0
- data/spec/manifest_spec.rb +67 -0
- data/spec/matcher_spec.rb +35 -2
- data/spec/middleware_spec.rb +123 -75
- data/spec/ordering_concat_filter_spec.rb +39 -0
- data/spec/pipeline_spec.rb +95 -34
- data/spec/project_spec.rb +293 -0
- data/spec/rake_acceptance_spec.rb +307 -67
- data/spec/rake_tasks_spec.rb +21 -0
- data/spec/spec_helper.rb +11 -48
- data/spec/support/spec_helpers/file_utils.rb +35 -0
- data/spec/support/spec_helpers/filters.rb +16 -0
- data/spec/support/spec_helpers/input_helpers.rb +23 -0
- data/spec/support/spec_helpers/memory_file_wrapper.rb +31 -0
- data/tools/perfs +107 -0
- metadata +100 -12
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Rake
|
4
|
+
class Pipeline
|
5
|
+
# A Manifest is a container for storing dynamic dependency information.
|
6
|
+
# A {DynamicFileTask} will use a {Manifest} to keep track of its dynamic
|
7
|
+
# dependencies. This allows us to avoid scanning a file for dynamic
|
8
|
+
# dependencies if its contents have not changed.
|
9
|
+
class Manifest
|
10
|
+
attr_accessor :entries
|
11
|
+
attr_accessor :manifest_file
|
12
|
+
|
13
|
+
def initialize(manifest_file="manifest.json")
|
14
|
+
@manifest_file ||= manifest_file
|
15
|
+
@entries = {}
|
16
|
+
end
|
17
|
+
|
18
|
+
# Get the manifest off the file system, if it exists.
|
19
|
+
def read_manifest
|
20
|
+
@entries = File.file?(manifest_file) ? JSON.parse(File.read(manifest_file)) : {}
|
21
|
+
|
22
|
+
# convert the manifest JSON into a Hash of ManifestEntry objects
|
23
|
+
@entries.each do |file, raw|
|
24
|
+
@entries[file] = Rake::Pipeline::ManifestEntry.from_hash(raw)
|
25
|
+
end
|
26
|
+
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
# Write a JSON representation of this manifest out to disk if we
|
31
|
+
# have entries to save.
|
32
|
+
def write_manifest
|
33
|
+
unless @entries.empty?
|
34
|
+
File.open(manifest_file, "w") do |file|
|
35
|
+
file.puts JSON.generate(as_json)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Convert this Manifest into a hash suitable for converting to
|
41
|
+
# JSON.
|
42
|
+
def as_json
|
43
|
+
hash = {}
|
44
|
+
|
45
|
+
@entries.each do |name, entry|
|
46
|
+
hash[name] = entry.as_json
|
47
|
+
end
|
48
|
+
|
49
|
+
hash
|
50
|
+
end
|
51
|
+
|
52
|
+
# Look up an entry by filename.
|
53
|
+
def [](key)
|
54
|
+
@entries[key]
|
55
|
+
end
|
56
|
+
|
57
|
+
# Set an entry
|
58
|
+
def []=(key, value)
|
59
|
+
@entries[key] = value
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Rake
|
2
|
+
class Pipeline
|
3
|
+
# Represents a single entry in a dynamic dependency {Manifest}.
|
4
|
+
class ManifestEntry
|
5
|
+
# Create a new entry from the given hash.
|
6
|
+
def self.from_hash(hash)
|
7
|
+
entry = new
|
8
|
+
|
9
|
+
entry.mtime = DateTime.parse(hash["mtime"]).to_time
|
10
|
+
|
11
|
+
hash["deps"].each do |dep, time_string|
|
12
|
+
entry.deps[dep] = DateTime.parse(time_string).to_time
|
13
|
+
end
|
14
|
+
|
15
|
+
entry
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_accessor :deps, :mtime
|
19
|
+
|
20
|
+
def initialize(deps={}, mtime=nil)
|
21
|
+
@deps, @mtime = deps, mtime
|
22
|
+
end
|
23
|
+
|
24
|
+
def as_json
|
25
|
+
{ :deps => @deps, :mtime => @mtime }
|
26
|
+
end
|
27
|
+
|
28
|
+
def ==(other)
|
29
|
+
mtime == other.mtime
|
30
|
+
deps == other.deps
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -9,7 +9,7 @@ module Rake
|
|
9
9
|
#
|
10
10
|
# For instance, to restrict filters to operating on
|
11
11
|
# JavaScript files in the +app+ directory, the Matcher's
|
12
|
-
# {Pipeline#
|
12
|
+
# {Pipeline#inputs inputs} should include +"app"+,
|
13
13
|
# and its glob would be +"*.js"+.
|
14
14
|
#
|
15
15
|
# In general, you should not use Matcher directly. Instead use
|
@@ -17,13 +17,68 @@ module Rake
|
|
17
17
|
class Matcher < Pipeline
|
18
18
|
attr_reader :glob
|
19
19
|
|
20
|
+
# @return [Rake::Pipeline] the Rake::Pipeline that contains
|
21
|
+
# this matcher.
|
22
|
+
attr_accessor :pipeline
|
23
|
+
|
20
24
|
# A glob matcher that a filter's input files must match
|
21
25
|
# in order to be processed by the filter.
|
22
26
|
#
|
23
27
|
# @return [String]
|
24
28
|
def glob=(pattern)
|
25
29
|
@glob = pattern
|
26
|
-
|
30
|
+
if pattern.kind_of?(Regexp)
|
31
|
+
@pattern = pattern
|
32
|
+
else
|
33
|
+
@pattern = scan_string
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# A list of the output files that invoking this pipeline will
|
38
|
+
# generate. This will include the outputs of files matching
|
39
|
+
# the {#glob glob} and any inputs that did not match the
|
40
|
+
# glob.
|
41
|
+
#
|
42
|
+
# This will make those inputs available to any additional
|
43
|
+
# filters or matchers.
|
44
|
+
#
|
45
|
+
# @return [Array<FileWrapper>]
|
46
|
+
def output_files
|
47
|
+
super + input_files.reject do |file|
|
48
|
+
file.path =~ @pattern
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Override {Pipeline#finalize} to do nothing. We want to pass
|
53
|
+
# on our unmatched inputs to the next part of the pipeline.
|
54
|
+
#
|
55
|
+
# @return [void]
|
56
|
+
# @api private
|
57
|
+
def finalize
|
58
|
+
end
|
59
|
+
|
60
|
+
protected
|
61
|
+
# Let our containing pipeline generate temp directories for us.
|
62
|
+
def generate_tmpdir
|
63
|
+
pipeline.generate_tmpdir
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
# Override the default {Pipeline#eligible_input_files}
|
68
|
+
# to include only files that match the {#glob glob}.
|
69
|
+
#
|
70
|
+
# @return [Array<FileWrapper>]
|
71
|
+
def eligible_input_files
|
72
|
+
input_files.select do |file|
|
73
|
+
file.path =~ @pattern
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Convert string to regexp using StringScanner
|
78
|
+
#
|
79
|
+
# @return [Regexp]
|
80
|
+
def scan_string
|
81
|
+
scanner = StringScanner.new(glob)
|
27
82
|
|
28
83
|
output, pos = "", 0
|
29
84
|
|
@@ -71,34 +126,14 @@ module Rake
|
|
71
126
|
end
|
72
127
|
end
|
73
128
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
# glob.
|
83
|
-
#
|
84
|
-
# This will make those inputs available to any additional
|
85
|
-
# filters or matchers.
|
86
|
-
#
|
87
|
-
# @return [Array<FileWrapper>]
|
88
|
-
def output_files
|
89
|
-
super + input_files.reject do |file|
|
90
|
-
file.path =~ @pattern
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
private
|
95
|
-
# Override the default {Pipeline#eligible_input_files}
|
96
|
-
# to include only files that match the {#glob glob}.
|
97
|
-
#
|
98
|
-
# @return [Array<FileWrapper>]
|
99
|
-
def eligible_input_files
|
100
|
-
input_files.select do |file|
|
101
|
-
file.path =~ @pattern
|
129
|
+
if glob.include?("/")
|
130
|
+
# if the pattern includes a /, it must match the
|
131
|
+
# entire input, not just the end.
|
132
|
+
Regexp.new("^#{output}$", "i")
|
133
|
+
else
|
134
|
+
# anchor the pattern either at the beginning of the
|
135
|
+
# path or at any "/" character
|
136
|
+
Regexp.new("(^|/)#{output}$", "i")
|
102
137
|
end
|
103
138
|
end
|
104
139
|
end
|
@@ -14,19 +14,14 @@ module Rake
|
|
14
14
|
# ...
|
15
15
|
# }
|
16
16
|
class Middleware
|
17
|
-
attr_accessor :
|
17
|
+
attr_accessor :project
|
18
18
|
|
19
|
-
# @param [#call] a Rack application
|
20
|
-
# @param [Pipeline] a
|
19
|
+
# @param [#call] app a Rack application
|
20
|
+
# @param [String|Rake::Pipeline] pipeline either a path to an
|
21
|
+
# Assetfile to use to build a pipeline, or an existing pipeline.
|
21
22
|
def initialize(app, pipeline)
|
22
23
|
@app = app
|
23
|
-
|
24
|
-
if pipeline.is_a?(String)
|
25
|
-
pipeline_source = File.read(pipeline)
|
26
|
-
pipeline = Pipeline.class_eval "build do\n#{pipeline_source}\nend", pipeline, 1
|
27
|
-
end
|
28
|
-
|
29
|
-
@pipeline = pipeline
|
24
|
+
@project = Rake::Pipeline::Project.new(pipeline)
|
30
25
|
end
|
31
26
|
|
32
27
|
# Automatically compiles your assets if required and
|
@@ -35,9 +30,13 @@ module Rake
|
|
35
30
|
# @param [Hash] env a Rack environment
|
36
31
|
# @return [Array(Fixnum, Hash, #each)] A rack response
|
37
32
|
def call(env)
|
38
|
-
|
33
|
+
project.invoke_clean
|
39
34
|
path = env["PATH_INFO"]
|
40
35
|
|
36
|
+
if project.maps.has_key?(path)
|
37
|
+
return project.maps[path].call(env)
|
38
|
+
end
|
39
|
+
|
41
40
|
if filename = file_for(path)
|
42
41
|
if File.directory?(filename)
|
43
42
|
index = File.join(filename, "index.html")
|
@@ -58,7 +57,11 @@ module Rake
|
|
58
57
|
end
|
59
58
|
|
60
59
|
def file_for(path)
|
61
|
-
|
60
|
+
project.pipelines.each do |pipeline|
|
61
|
+
file = Dir[File.join(pipeline.output_root, path)].sort.first
|
62
|
+
return file unless file.nil?
|
63
|
+
end
|
64
|
+
nil
|
62
65
|
end
|
63
66
|
|
64
67
|
def headers_for(path)
|
@@ -0,0 +1,280 @@
|
|
1
|
+
require "digest"
|
2
|
+
|
3
|
+
module Rake
|
4
|
+
class Pipeline
|
5
|
+
# A Project controls the lifecycle of a series of Pipelines,
|
6
|
+
# creating them from an Assetfile and recreating them if the
|
7
|
+
# Assetfile changes.
|
8
|
+
class Project
|
9
|
+
# @return [Pipeline] the list of pipelines in the project
|
10
|
+
attr_reader :pipelines
|
11
|
+
|
12
|
+
attr_reader :maps
|
13
|
+
|
14
|
+
# @return [String|nil] the path to the project's Assetfile
|
15
|
+
# or nil if it was created without an Assetfile.
|
16
|
+
attr_reader :assetfile_path
|
17
|
+
|
18
|
+
# @return [String|nil] the digest of the Assetfile the
|
19
|
+
# project was created with, or nil if the project
|
20
|
+
# was created without an Assetfile.
|
21
|
+
attr_reader :assetfile_digest
|
22
|
+
|
23
|
+
# @return [String] the directory path for temporary files
|
24
|
+
attr_reader :tmpdir
|
25
|
+
|
26
|
+
# @return [String] the directory path where pipelines will
|
27
|
+
# write their outputs by default
|
28
|
+
attr_reader :default_output_root
|
29
|
+
|
30
|
+
# @return [Array] a list of filters to be applied before
|
31
|
+
# the specified filters in every pipeline
|
32
|
+
attr_writer :before_filters
|
33
|
+
|
34
|
+
# @return [Array] a list of filters to be applied after
|
35
|
+
# the specified filters in every pipeline
|
36
|
+
attr_writer :after_filters
|
37
|
+
|
38
|
+
class << self
|
39
|
+
# Configure a new project by evaluating a block with the
|
40
|
+
# Rake::Pipeline::DSL::ProjectDSL class.
|
41
|
+
#
|
42
|
+
# @see Rake::Pipeline::Filter Rake::Pipeline::Filter
|
43
|
+
#
|
44
|
+
# @example
|
45
|
+
# Rake::Pipeline::Project.build do
|
46
|
+
# tmpdir "tmp"
|
47
|
+
# output "public"
|
48
|
+
#
|
49
|
+
# input "app/assets" do
|
50
|
+
# concat "app.js"
|
51
|
+
# end
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# @return [Rake::Pipeline::Project] the newly configured project
|
55
|
+
def build(&block)
|
56
|
+
project = new
|
57
|
+
project.build(&block)
|
58
|
+
end
|
59
|
+
|
60
|
+
# @return [Array[String]] an array of strings that will be
|
61
|
+
# appended to {#digested_tmpdir}.
|
62
|
+
def digest_additions
|
63
|
+
@digest_additions ||= []
|
64
|
+
end
|
65
|
+
|
66
|
+
# Set {.digest_additions} to a sorted copy of the given array.
|
67
|
+
def digest_additions=(additions)
|
68
|
+
@digest_additions = additions.sort
|
69
|
+
end
|
70
|
+
|
71
|
+
# Add a value to the list of strings to append to the digest
|
72
|
+
# temp directory. Libraries can use this to add (for example)
|
73
|
+
# their version numbers so that the pipeline will be rebuilt
|
74
|
+
# if the library version changes.
|
75
|
+
#
|
76
|
+
# @example
|
77
|
+
# Rake::Pipeline::Project.add_to_digest(Rake::Pipeline::Web::Filters::VERSION)
|
78
|
+
#
|
79
|
+
# @param [#to_s] str a value to append to {#digested_tmpdir}.
|
80
|
+
def add_to_digest(str)
|
81
|
+
self.digest_additions << str.to_s
|
82
|
+
self.digest_additions.sort!
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# @param [String|Pipeline] assetfile_or_pipeline
|
87
|
+
# if this a String, create a Pipeline from the Assetfile at
|
88
|
+
# that path. If it's a Pipeline, just wrap that pipeline.
|
89
|
+
def initialize(assetfile_or_pipeline=nil)
|
90
|
+
reset!
|
91
|
+
if assetfile_or_pipeline.kind_of?(String)
|
92
|
+
@assetfile_path = File.expand_path(assetfile_or_pipeline)
|
93
|
+
rebuild_from_assetfile(@assetfile_path)
|
94
|
+
elsif assetfile_or_pipeline
|
95
|
+
@pipelines << assetfile_or_pipeline
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Evaluate a block using the Rake::Pipeline::DSL::ProjectDSL
|
100
|
+
# DSL against an existing project.
|
101
|
+
def build(&block)
|
102
|
+
DSL::ProjectDSL.evaluate(self, &block) if block
|
103
|
+
self
|
104
|
+
end
|
105
|
+
|
106
|
+
# Invoke all of the project's pipelines.
|
107
|
+
#
|
108
|
+
# @see Rake::Pipeline#invoke
|
109
|
+
def invoke
|
110
|
+
@invoke_mutex.synchronize do
|
111
|
+
pipelines.each(&:invoke)
|
112
|
+
manifest.write_manifest
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# Invoke all of the project's pipelines, detecting any changes
|
117
|
+
# to the Assetfile and rebuilding the pipelines if necessary.
|
118
|
+
#
|
119
|
+
# @return [void]
|
120
|
+
# @see Rake::Pipeline#invoke_clean
|
121
|
+
def invoke_clean
|
122
|
+
@invoke_mutex.synchronize do
|
123
|
+
if assetfile_path
|
124
|
+
source = File.read(assetfile_path)
|
125
|
+
if digest(source) != assetfile_digest
|
126
|
+
rebuild_from_assetfile(assetfile_path, source)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
pipelines.each(&:invoke_clean)
|
130
|
+
manifest.write_manifest
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# Remove the project's temporary and output files.
|
135
|
+
def clean
|
136
|
+
files_to_clean.each { |file| FileUtils.rm_rf(file) }
|
137
|
+
end
|
138
|
+
|
139
|
+
# Clean out old tmp directories from the pipeline's
|
140
|
+
# {Rake::Pipeline#tmpdir}.
|
141
|
+
#
|
142
|
+
# @return [void]
|
143
|
+
def cleanup_tmpdir
|
144
|
+
obsolete_tmpdirs.each { |dir| FileUtils.rm_rf(dir) }
|
145
|
+
end
|
146
|
+
|
147
|
+
# Set the default output root of this project and expand its path.
|
148
|
+
#
|
149
|
+
# @param [String] root this pipeline's output root
|
150
|
+
def default_output_root=(root)
|
151
|
+
@default_output_root = File.expand_path(root)
|
152
|
+
end
|
153
|
+
|
154
|
+
# Set the temporary directory for this project and expand its path.
|
155
|
+
#
|
156
|
+
# @param [String] root this project's temporary directory
|
157
|
+
def tmpdir=(dir)
|
158
|
+
@tmpdir = File.expand_path(dir)
|
159
|
+
end
|
160
|
+
|
161
|
+
# @return [String] A subdirectory of {#tmpdir} with the digest of
|
162
|
+
# the Assetfile's contents and any {.digest_additions} in its
|
163
|
+
# name.
|
164
|
+
def digested_tmpdir
|
165
|
+
suffix = assetfile_digest
|
166
|
+
unless self.class.digest_additions.empty?
|
167
|
+
suffix += "-#{self.class.digest_additions.join('-')}"
|
168
|
+
end
|
169
|
+
File.join(tmpdir, "rake-pipeline-#{suffix}")
|
170
|
+
end
|
171
|
+
|
172
|
+
# @return Array[String] a list of the paths to temporary directories
|
173
|
+
# that don't match the pipline's Assetfile digest.
|
174
|
+
def obsolete_tmpdirs
|
175
|
+
if File.directory?(tmpdir)
|
176
|
+
Dir["#{tmpdir}/rake-pipeline-*"].sort.reject do |dir|
|
177
|
+
dir == digested_tmpdir
|
178
|
+
end
|
179
|
+
else
|
180
|
+
[]
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# @return Array[String] a list of files to delete to completely clean
|
185
|
+
# out a project's temporary and output files.
|
186
|
+
def files_to_clean
|
187
|
+
setup_pipelines
|
188
|
+
obsolete_tmpdirs + [digested_tmpdir] + output_files.map(&:fullpath)
|
189
|
+
end
|
190
|
+
|
191
|
+
# @return [Array[FileWrapper]] a list of the files that
|
192
|
+
# will be generated when this project is invoked.
|
193
|
+
def output_files
|
194
|
+
setup_pipelines
|
195
|
+
pipelines.map(&:output_files).flatten
|
196
|
+
end
|
197
|
+
|
198
|
+
# Build a new pipeline and add it to our list of pipelines.
|
199
|
+
def build_pipeline(input, glob=nil, &block)
|
200
|
+
pipeline = Rake::Pipeline.build({
|
201
|
+
:before_filters => @before_filters,
|
202
|
+
:after_filters => @after_filters,
|
203
|
+
:output_root => default_output_root,
|
204
|
+
:tmpdir => digested_tmpdir,
|
205
|
+
:project => self
|
206
|
+
}, &block)
|
207
|
+
|
208
|
+
if input.kind_of?(Array)
|
209
|
+
input.each { |x| pipeline.add_input(x) }
|
210
|
+
elsif input.kind_of?(Hash)
|
211
|
+
pipeline.inputs = input
|
212
|
+
else
|
213
|
+
pipeline.add_input(input, glob)
|
214
|
+
end
|
215
|
+
|
216
|
+
@pipelines << pipeline
|
217
|
+
pipeline
|
218
|
+
end
|
219
|
+
|
220
|
+
# @return [Manifest] the manifest to read dependency information
|
221
|
+
# from
|
222
|
+
def last_manifest
|
223
|
+
@last_manifest ||= begin
|
224
|
+
m = Rake::Pipeline::Manifest.new(manifest_path)
|
225
|
+
m.read_manifest
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
# @return [Manifest] the manifest to write dependency information
|
230
|
+
# to
|
231
|
+
def manifest
|
232
|
+
@manifest ||= Rake::Pipeline::Manifest.new(manifest_path)
|
233
|
+
end
|
234
|
+
|
235
|
+
# @return [String] the path to the dynamic dependency manifest
|
236
|
+
def manifest_path
|
237
|
+
File.join(digested_tmpdir, "manifest.json")
|
238
|
+
end
|
239
|
+
|
240
|
+
private
|
241
|
+
# Reset this project's internal state to the default values.
|
242
|
+
#
|
243
|
+
# @return [void]
|
244
|
+
def reset!
|
245
|
+
@pipelines = []
|
246
|
+
@maps = {}
|
247
|
+
@tmpdir = "tmp"
|
248
|
+
@invoke_mutex = Mutex.new
|
249
|
+
@default_output_root = @assetfile_digest = @assetfile_path = nil
|
250
|
+
@manifest = @last_manifest = nil
|
251
|
+
end
|
252
|
+
|
253
|
+
# Reconfigure this project based on the Assetfile at path.
|
254
|
+
#
|
255
|
+
# @param [String] path the path to the Assetfile
|
256
|
+
# to use to configure the project.
|
257
|
+
# @param [String] source if given, this string is
|
258
|
+
# evaluated instead of reading the file at assetfile_path.
|
259
|
+
#
|
260
|
+
# @return [void]
|
261
|
+
def rebuild_from_assetfile(path, source=nil)
|
262
|
+
reset!
|
263
|
+
source ||= File.read(path)
|
264
|
+
@assetfile_digest = digest(source)
|
265
|
+
@assetfile_path = path
|
266
|
+
build { instance_eval(source, path, 1) }
|
267
|
+
end
|
268
|
+
|
269
|
+
# Setup the pipeline so its output files will be up to date.
|
270
|
+
def setup_pipelines
|
271
|
+
pipelines.map(&:setup_filters)
|
272
|
+
end
|
273
|
+
|
274
|
+
# @return [String] the SHA1 digest of the given string.
|
275
|
+
def digest(str)
|
276
|
+
Digest::SHA1.hexdigest(str)
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|