0
@@ -270,29 +270,195 @@ module Merb
0
def remove_app_paths(*args)
0
args.each { |arg| self.app_paths.delete(arg) }
0
+ # Return all application path component types
0
+ # @return <Array[Symbol]> Component types.
0
+ [:view, :model, :controller, :helper, :mailer, :part]
0
+ # Return all public path component types
0
+ # @return <Array[Symbol]> Component types.
0
+ [:stylesheet, :javascript, :image]
0
+ # Return all path component types to mirror
0
+ # If config option :mirror is set return a subset, otherwise return all types.
0
+ # @return <Array[Symbol]> Component types.
0
+ def mirrored_components
0
+ all = slice_paths.keys
0
+ config[:mirror].is_a?(Array) ? config[:mirror] & all : all
0
+ # Return all application path component types to mirror
0
+ # @return <Array[Symbol]> Component types.
0
+ def mirrored_app_components
0
+ mirrored_components & app_components
0
+ # Return all public path component types to mirror
0
+ # @return <Array[Symbol]> Component types.
0
+ def mirrored_public_components
0
+ mirrored_components & public_components
0
+ # Unpack all files from the slice to their app-level location; this will
0
+ # also copy /lib, causing merb-slices to pick up the slice there.
0
+ # @return <Array[Array]>
0
+ # Array of two arrays, one for all copied files, the other for overrides
0
+ # that may have been preserved to resolve collisions.
0
+ app_slice_root = app_dir_for(:root)
0
+ copied, duplicated = [], []
0
+ Dir.glob(self.root / "**/*").each do |source|
0
+ relative_path = source.relative_path_from(root)
0
+ mirror_file(source, app_slice_root / relative_path, copied, duplicated) if unpack_file?(relative_path)
0
+ public_copied, public_duplicated = mirror_public!
0
+ [copied + public_copied, duplicated + public_duplicated]
0
+ # Copies all files from mirrored_components to their app-level location
0
+ # This includes :application, :as well
0
+ # @return <Array[Array]>
0
+ # Array of two arrays, one for all copied files, the other for overrides
0
+ # that may have been preserved to resolve collisions.
0
+ mirror_files_for mirrored_components + mirrored_public_components
0
+ # Copies all application files from mirrored_components to their app-level location
0
+ # @return <Array[Array]>
0
+ # Array of two arrays, one for all copied files, the other for overrides
0
+ # that may have been preserved to resolve collisions.
0
+ mirror_files_for mirrored_app_components
0
+ # Copies all application files from mirrored_components to their app-level location
0
+ # @return <Array[Array]>
0
+ # Array of two arrays, one for all copied files, the other for overrides
0
+ # that may have been preserved to resolve collisions.
0
+ mirror_files_for mirrored_public_components
0
+ # Copies all view files to their app-level location - so you can easily modify them
0
+ # @return <Array[Array]>
0
+ # Array of two arrays, one for all copied files, the other for overrides
0
+ # that may have been preserved to resolve collisions.
0
+ mirror_files_for :view
0
+ # Copy files from specified component path types to their app-level location
0
+ # App-level overrides are preserved by creating duplicates before writing gem-level files.
0
+ # Because of their _override postfix they will load after their original implementation.
0
+ # In the case of views, this won't work, but the user override is preserved nonetheless.
0
+ # @return <Array[Array]>
0
+ # Array of two arrays, one for all copied files, the other for overrides
0
+ # that may have been preserved to resolve collisions.
0
+ def mirror_files_for(*types)
0
+ seen, copied, duplicated = [], [], [] # keep track of files we copied
0
+ types.flatten.each do |type|
0
+ if File.directory?(src_path = dir_for(type)) && (dst_path = app_dir_for(type))
0
+ glob = ((type == :view) ? "**/*.{#{Merb::Template.template_extensions.join(',')}}" : glob_for(type) || "**/*")
0
+ Dir[src_path / glob].each do |src|
0
+ next if seen.include?(src)
0
+ mirror_file(src, dst_path / src.relative_path_from(src_path), copied, duplicated)
0
+ # Helper method to copy a source file to destination while resolving any conflicts.
0
+ # @param source<String> The source path.
0
+ # @param dest<String> The destination path.
0
+ # @param copied<Array> Keep track of all copied files - relative paths.
0
+ # @param duplicated<Array> Keep track of all duplicated files - relative paths.
0
+ # @param postfix<String> The postfix to use for resolving conflicting filenames.
0
+ def mirror_file(source, dest, copied = [], duplicated = [], postfix = '_override')
0
+ base, rest = split_name(source)
0
+ dst_dir = File.dirname(dest)
0
+ dup_path = dst_dir / "#{base}#{postfix}.#{rest}"
0
+ mkdir_p(dst_dir) unless File.directory?(dst_dir)
0
+ if File.exists?(dest) && !File.exists?(dup_path) && !FileUtils.identical?(source, dest)
0
+ # copy app-level override to *_override.ext
0
+ copy_entry(dest, dup_path, false, false, true)
0
+ duplicated << dup_path.relative_path_from(Merb.root)
0
+ # copy gem-level original to location
0
+ if !File.exists?(dest) || (File.exists?(dest) && !FileUtils.identical?(source, dest))
0
+ copy_entry(source, dest, false, false, true)
0
+ copied << dest.relative_path_from(Merb.root)
0
+ # Predicate method to check if a file should be taken into account when unpacking files
0
+ # @param file<String> The relative path to test.
0
+ # @return <TrueClass,FalseClass> True if the file may be mirrored.
0
+ def unpack_file?(file)
0
+ @mirror_exceptions_regexp ||= begin
0
+ skip_paths = mirrored_public_components.map { |type| dir_for(type).relative_path_from(self.root) }
0
+ skip_paths += config[:skip_files] if config[:skip_files].is_a?(Array)
0
+ Regexp.new("^(#{skip_paths.join('|')})")
0
+ not file.match(@mirror_exceptions_regexp)
0
# This sets up the default slice-level and app-level structure.
0
# You can create your own structure by implementing setup_structure and
0
# using the push_path and push_app_paths. By default this setup matches
0
# what the merb-gen slice generator creates.
0
def setup_default_structure!
0
- self.push_path(:application, self.root / 'app')
0
- self.push_app_path(:application, Merb.root / 'slices' / self.identifier / 'app')
0
+ self.push_app_path(:root, Merb.root / 'slices' / self.identifier)
0
+ self.push_path(:application, root_path('app'))
0
+ self.push_app_path(:application, app_dir_for(:root) / 'app')
0
-
[:view, :model, :controller, :helper, :mailer, :part].each do |component|
0
+
app_components.each do |component|
0
self.push_path(component, dir_for(:application) / "#{component}s")
0
self.push_app_path(component, app_dir_for(:application) / "#{component}s")
0
- self.push_path(:public, self.root / 'public', nil)
0
- self.push_app_path(:public, Merb.root / 'public' / 'slices' / self.identifier, nil)
0
+ self.push_path(:public, root_path('public'), nil)
0
+ self.push_app_path(:public, Merb.dir_for(:public) / 'slices' / self.identifier, nil)
0
-
[:stylesheet, :javascript, :image].each do |component|
0
+
public_components.each do |component|
0
self.push_path(component, dir_for(:public) / "#{component}s", nil)
0
self.push_app_path(component, app_dir_for(:public) / "#{component}s", nil)
0
+ file_name = File.basename(name)
0
+ mres = /^([^\/\.]+)\.(.+)$/i.match(file_name)
0
+ mres.nil? ? [file_name, ''] : [mres[1], mres[2]]
Comments
No one has commented yet.