Class: SC::Manifest
- Inherits:
-
HashStruct
- Object
- Hash
- HashStruct
- SC::Manifest
- Defined in:
- lib/sproutcore/models/manifest.rb
Overview
A Manifest describes all of the files that should be found inside of a single bundle/language. A Manifest can have global properties assigned to it which will be used by the manifest entries themselves. This is largly defined by the manifest build tasks.
Defined Under Namespace
Classes: EntryList
Instance Attribute Summary collapse
-
#target ⇒ Object
readonly
Returns the value of attribute target.
Instance Method Summary collapse
-
#add_composite(filename, opts = {}) ⇒ Object
Creates a composite entry with the passed filename.
-
#add_entry(filename, opts = {}) ⇒ Object
Creates a new manifest entry with the passed options.
-
#add_transform(entry, opts = {}) ⇒ Object
Creates an entry with will apply a build task to the source entry.
-
#build! ⇒ Object
Builds the manifest if it has not been built yet.
- #built? ⇒ Boolean
- #entries(opts = {}) ⇒ Object
-
#entry_for(filename, opts = {}) ⇒ Object
Finds the first visible entry with the specified filename.
-
#find_entry(fragment, opts = {}, seen = nil) ⇒ Object
Attempts to find any entry matching the specified static URL fragment.
-
#initialize(target, opts) ⇒ Manifest
constructor
A new instance of Manifest.
- #inspect ⇒ Object
-
#load(hash) ⇒ Object
Loads a hash into the manifest, replacing whatever contents are already here.
-
#prepare! ⇒ Object
Invoked just before a manifest is built.
- #prepared? ⇒ Boolean
-
#reset! ⇒ Object
Resets this manifest, and all same-variation manifests the target depends on.
-
#reset_entries! ⇒ Object
Resets the manifest entries.
-
#to_hash(opts = {}) ⇒ Object
Returns the manifest as a hash that can be serialized to json or yaml.
-
#unique_cache_path(path) ⇒ Object
Finds a unique cache path starting with the root proposed staging path.
-
#unique_staging_path(path) ⇒ Object
Finds a unique staging path starting with the root proposed staging path.
-
#variation ⇒ Object
Returns the options that select the current variation.
Methods inherited from HashStruct
#deep_clone, #has_options?, #merge, #merge!, #method_missing, #print_first_caller
Constructor Details
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class SC::HashStruct
Instance Attribute Details
#target ⇒ Object (readonly)
Returns the value of attribute target.
18 19 20 |
# File 'lib/sproutcore/models/manifest.rb', line 18 def target @target end |
Instance Method Details
#add_composite(filename, opts = {}) ⇒ Object
Creates a composite entry with the passed filename. Expects you to a source_entries option. This automatically hides the source entries unless you pass the :hide_entries => false option.
207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/sproutcore/models/manifest.rb', line 207 def add_composite(filename, opts = {}) should_hide_entries = opts.delete(:hide_entries) should_hide_entries = true if should_hide_entries.nil? opts[:filename] = filename opts[:source_entries] ||= [] opts[:composite] = true @entries << (ret = ManifestEntry.new(self, opts)).prepare! ret[:source_entries].each { |entry| entry.hide! } if should_hide_entries return ret end |
#add_entry(filename, opts = {}) ⇒ Object
Creates a new manifest entry with the passed options. Will setup extra tracking needed by entry.
Params
opts:: the you want to set on the entry
Returns
the new manifest entry
198 199 200 201 202 |
# File 'lib/sproutcore/models/manifest.rb', line 198 def add_entry(filename, opts = {}) opts[:filename] = filename @entries << (ret = ManifestEntry.new(self, opts)).prepare! return ret end |
#add_transform(entry, opts = {}) ⇒ Object
Creates an entry with will apply a build task to the source entry. Use this method when you need to apply a build task to an entry to convert it into another format or to perform some kind of incremental build.
Params
entry:: the entry that should be the source of the transform
Options
You can assign any options you like and they will be copied onto the new entry. The following options, however, have special meaning:
:build_task:: name the new build task you use. otherwise uses copy
:ext:: the new file extension. if you don't override, the build_path
staging_path and filename will all be adjusted to have this ext.
:hide_entry:: the source entry will be hidden unless set to false
Returns
the new ManifestEntry
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 |
# File 'lib/sproutcore/models/manifest.rb', line 238 def add_transform(entry, opts ={}) should_hide_entries = opts.delete(:hide_entries) || opts.delete(:hide_entry) should_hide_entries = true if should_hide_entries.nil? # Clone important properties to new transform... opts = HashStruct.new(opts) opts[:filename] ||= entry[:filename] opts[:build_path] ||= entry[:build_path] opts[:url] ||= entry[:url] # generate a unique staging path. If the original entry has its # staging_path set == to source_root (optimization for build:copy), then # first rebase staging path against the staging root. if (staging_path = entry[:staging_path]) == entry[:source_path] staging_path = File.join(self[:staging_root], entry[:filename]) end opts[:staging_path] ||= unique_staging_path(staging_path) # generate a unique cache path from the staging page. just sub the # staging root for the cache root opts[:cache_path] ||= unique_cache_path(entry[:cache_path]) # copy other useful entries opts[:source_entry] = entry opts[:source_entries] = [entry] opts[:composite] = true opts[:transform] = true # make .transform? = true # Normalize to new extension if provided. else copy ext from entry... if ext = opts[:ext] opts[:url] = opts[:url].ext(ext) opts[:staging_path] = opts[:staging_path].ext(ext) opts[:build_path] = opts[:build_path].ext(ext) opts[:filename] = opts[:filename].ext(ext) else opts[:ext] = entry[:ext] end # Create new entry and hide old one @entries << (ret = ManifestEntry.new(self, opts)).prepare! entry.hide! if should_hide_entries # done! return ret end |
#build! ⇒ Object
Builds the manifest if it has not been built yet.
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/sproutcore/models/manifest.rb', line 80 def build! prepare! if !@is_built @is_built = true if target.buildfile.task_defined? 'manifest:build' target.buildfile.invoke 'manifest:build', :manifest => self, :target => self.target, :config => self.target.config, :project => self.target.project end # Information indicating where the built app can be found. This is useful # when manually uploading builds, to ensure we have the newest build. if target[:target_type] == :app SC.logger.info "Built #{target[:target_name]} to #{target[:build_root]}/#{target[:build_number]}" end end return self end |
#built? ⇒ Boolean
101 |
# File 'lib/sproutcore/models/manifest.rb', line 101 def built?; @is_built; end |
#entries(opts = {}) ⇒ Object
20 21 22 |
# File 'lib/sproutcore/models/manifest.rb', line 20 def entries(opts = {}) opts[:hidden] ? @entries : @entries.visible end |
#entry_for(filename, opts = {}) ⇒ Object
Finds the first visible entry with the specified filename. You may also pass any number of additional options which will be used to further restrict your search. If you pass :hidden => true only hidden entries will be returned. Otherwise, only visible entries will be returned.
You may also include the name of the target you would like to search. The target name should be relative to the target you are requesting from.
Examples
entry = manifest.entry_for('javascript.js')
=> returns local javascript.js entry
entry = manifest.entry_for('sproutcore:javascript.js')
=> returns entry for javascript.js in 'sproutcore' bundle
entry = manifest.entry_for('sproutcore/costello:javascript.js')
Params
filename:: the filename to search
Options
:hidden:: if true, include hidden entries
Returns
the manifest entry
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 |
# File 'lib/sproutcore/models/manifest.rb', line 315 def entry_for(filename, opts = {}) target_name, filename = filename.split(':') if filename.nil? # no targetname given... manifest = self filename = target_name else if (_manifest_target = target.target_for(target_name)).nil? throw "Cannot file target #{target_name} for entry #{filename}" end manifest = _manifest_target.manifest_for(self.variation) manifest.build! end manifest.entries(opts).find do |entry| (entry[:filename] == filename) && entry.(opts) end end |
#find_entry(fragment, opts = {}, seen = nil) ⇒ Object
Attempts to find any entry matching the specified static URL fragment. the fragment you pass may contain only a portion of the url, and it may exclude the file extension if you choose. The filter will select the entry with the broadest match possible.
This is the root search method used by static_url().
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 |
# File 'lib/sproutcore/models/manifest.rb', line 340 def find_entry(fragment, opts = {}, seen=nil) entry_extname = entry_rootname = ret = target_name = nil # optionally you can specify an explicit target name split_index = fragment.to_s.index(':') # find first index unless split_index.nil? target_name = '/' + fragment[0..(split_index-1)] if split_index>0 fragment = fragment[(split_index+1)..-1] # remove colon end # find the current manifest if target_name cur_target = self.target.target_for(target_name) || self.target cur_manifest = cur_target.manifest_for(self.variation).build! else cur_manifest = self end extname = File.extname(fragment.to_s) extname = nil if extname.empty? # Add leading slash and remove extension rootname = fragment.to_s.sub(/\/?/, '/').sub(/#{extname}$/, '') # look on our own target only if target is named ret = cur_manifest.entries(opts).find do |entry| next unless entry.(opts) next if extname && (entry.extension != extname) normalized_rootname = entry.rootname.sub!(/\/?/, '/') # Add leading slash normalized_rootname[-rootname.length, rootname.length] == rootname end return ret if ret # if no match was found, search the same manifests in required targets seen ||= Set.new seen << cur_manifest.target cur_manifest.target.(:theme => true).each do |t| next if seen.include?(t) # avoid recursion manifest = t.manifest_for(self.variation).build! ret = manifest.find_entry(fragment, opts, seen) return ret if ret end nil end |
#inspect ⇒ Object
37 38 39 40 41 42 |
# File 'lib/sproutcore/models/manifest.rb', line 37 def inspect opts = variation.dup opts[:target] = target[:target_name] desc = opts.keys.sort { |a,b| a.to_s <=> b.to_s }.map { |k| [k, opts[k]].join("=") }.join(" ") "SC::Manifest(#{desc})" end |
#load(hash) ⇒ Object
Loads a hash into the manifest, replacing whatever contents are already here.
Params
hash:: the hash loaded from disk
Returns
Manifest (self)
178 179 180 181 182 183 184 185 186 187 |
# File 'lib/sproutcore/models/manifest.rb', line 178 def load(hash) merge!(hash) entry_hashes = self.delete(:entries) || [] @entries = EntryList.new entry_hashes.each do |opts| @entries << ManifestEntry.new(self, opts) end return self end |
#prepare! ⇒ Object
Invoked just before a manifest is built. If you load a manifest file this method will not be invoked.
Returns
self
48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/sproutcore/models/manifest.rb', line 48 def prepare! if !@is_prepared @is_prepared = true target.prepare! if target.buildfile.task_defined? 'manifest:prepare' target.buildfile.invoke 'manifest:prepare', :manifest => self, :target => self.target, :config => self.target.config, :project => self.target.project end end return self end |
#prepared? ⇒ Boolean
63 |
# File 'lib/sproutcore/models/manifest.rb', line 63 def prepared?; @is_prepared || false; end |
#reset! ⇒ Object
Resets this manifest, and all same-variation manifests the target depends on. This is useful when building: it clears the entries and frees up memory so building doesn’t take multiple gigabytes.
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/sproutcore/models/manifest.rb', line 108 def reset! return if @is_resetting @is_resetting = true targets = target.({ :theme => true }) + [target] entries = targets.map do |t| t.manifest_for(variation).reset! end targets = target.modules({ :debug => false, :test => false, :theme => true }).each do |t| t.manifest_for(variation).reset! end reset_entries! @is_resetting = false return self end |
#reset_entries! ⇒ Object
Resets the manifest entries. this is called before a build is performed. This will reset only the entries, none of the other props.
Returns
Manifest (self)
134 135 136 137 138 139 |
# File 'lib/sproutcore/models/manifest.rb', line 134 def reset_entries! @is_built = false self.delete(:entries) @entries = EntryList.new return self end |
#to_hash(opts = {}) ⇒ Object
Returns the manifest as a hash that can be serialized to json or yaml
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/sproutcore/models/manifest.rb', line 142 def to_hash(opts={}) ret = super() if only_keys = opts[:only] filtered = {} ret.each do |key, value| filtered[key] = value if only_keys.include?(key) end ret = filtered end # Always include entries unless they are explicitly excluded ret[:entries] = entries(opts).map { |e| e.to_hash(opts) } if except_keys = opts[:except] filtered = {} ret.each do |key, value| filtered[key] = value unless except_keys.include?(key) end ret = filtered end # always add target name. needed to reload ret[:target_name] = target.target_name return ret end |
#unique_cache_path(path) ⇒ Object
Finds a unique cache path starting with the root proposed staging path.
403 404 405 406 407 408 409 |
# File 'lib/sproutcore/models/manifest.rb', line 403 def unique_cache_path(path) # paths = entries(:hidden => true).map { |e| e[:cache_path] } # while paths.include?(path) # path = path.sub(/(__\$[0-9]+)?(\.\w+)?$/,"__#{next_staging_uuid}\\2") # end return path end |
#unique_staging_path(path) ⇒ Object
Finds a unique staging path starting with the root proposed staging path.
393 394 395 396 397 398 399 |
# File 'lib/sproutcore/models/manifest.rb', line 393 def unique_staging_path(path) # paths = entries(:hidden => true).map { |e| e[:staging_path] } # while paths.include?(path) # path = path.sub(/(__\$[0-9]+)?(\.\w+)?$/,"__#{next_staging_uuid}\\2") # end return path end |
#variation ⇒ Object
Returns the options that select the current variation. The current implementation is hardcoded to return the language, but this may be generalized in the future.
You can use this method to select the same manifest in other targets.
Examples
other_manifest = other_target.manifest_for(my_manifest.variation)
75 76 77 |
# File 'lib/sproutcore/models/manifest.rb', line 75 def variation return { :language => self[:language] } end |