Class: Impromptu::Folder
- Inherits:
-
Object
- Object
- Impromptu::Folder
- Defined in:
- lib/impromptu/folder.rb
Constant Summary collapse
- DEFAULT_OPTIONS =
{nested_namespaces: true, reloadable: true, implicitly_loaded: true, namespace: nil, preload: false}
- SOURCE_EXTENSIONS =
%w{rb so bundle}
Instance Attribute Summary collapse
-
#component ⇒ Object
Returns the value of attribute component.
-
#files ⇒ Object
Returns the value of attribute files.
-
#folder ⇒ Object
Returns the value of attribute folder.
Instance Method Summary collapse
-
#create_namespace ⇒ Object
If an overriding namespace has been defined for this folder, create a resource representing it and define it as a namespace.
-
#eql?(other) ⇒ Boolean
Override eql? so two folders with the same path will be considered equal by ordered set.
-
#file(name, options = {}) ⇒ Object
Explicitly include a file from this folder.
-
#hash ⇒ Object
Override hash so two folders with the same path will result in the same hash value.
-
#implicitly_loaded? ⇒ Boolean
True if the folder is implicitly loaded (we scan the folder for source files and automatically infer resources).
-
#initialize(path, component, options = {}, block) ⇒ Folder
constructor
Register a new folder containing source files for a component.
-
#load ⇒ Object
Load a folders definition and files after the set of components has been defined.
-
#namespace ⇒ Object
A string or symbol for this folder which overrides the components default namespace.
-
#nested_namespaces? ⇒ Boolean
True if the folder uses nested namespaces.
-
#preload ⇒ Object
Preload the resources defined by this folder.
-
#preload! ⇒ Object
Turn preloading on for this folder (can be done after initialisation) and run an initial preload.
-
#preload? ⇒ Boolean
True if the resources of the folder are loaded immediately on startup, and won’t be autoloaded.
-
#relative_path_to(path) ⇒ Object
Return the ‘base’ folder for a file contained within this folder.
-
#reload ⇒ Object
Reload the files provided by this folder.
-
#reload_file_set ⇒ Object
Determine changes between the set of files this folder knows about, and the set of files existing on disk.
-
#reloadable? ⇒ Boolean
True if the folder is reloadable.
Constructor Details
#initialize(path, component, options = {}, block) ⇒ Folder
Register a new folder containing source files for a component. Path is a Pathname object representing the folder, and options may be:
-
nested_namespaces: true by default. If true, sub- folders indicate a new namespace for resources. For instance, a folder with a root of ‘src’, containing a folder called ‘plugins’ which has a file ‘klass.rb’ would define the resource Plugins::Klass. When false, the file would simply represent Klass.
-
reloadable: true by default. If true, this folder will be reloaded every time Impromptu.update is called, and any modified files will be reloaded, removed files unloaded, and new files tracked.
-
implicitly_loaded: true by default. When true, reloads and the initial load of this folder will scan for source files and automatically infer resource definitions.
-
namespace: override a component’s default namespace with a namespace specific to this folder. The normal rules with nested namespaces apply.
-
preload: forces the loading of all files within a folder. The resources defined can still be reloaded, but loading won’t wait until the resource is referenced.
29 30 31 32 33 34 35 |
# File 'lib/impromptu/folder.rb', line 29 def initialize(path, component, ={}, block) @folder = path.realpath @component = component @options = DEFAULT_OPTIONS.merge() @block = block @files = OrderedSet.new end |
Instance Attribute Details
#component ⇒ Object
Returns the value of attribute component.
3 4 5 |
# File 'lib/impromptu/folder.rb', line 3 def component @component end |
#files ⇒ Object
Returns the value of attribute files.
3 4 5 |
# File 'lib/impromptu/folder.rb', line 3 def files @files end |
#folder ⇒ Object
Returns the value of attribute folder.
3 4 5 |
# File 'lib/impromptu/folder.rb', line 3 def folder @folder end |
Instance Method Details
#create_namespace ⇒ Object
If an overriding namespace has been defined for this folder, create a resource representing it and define it as a namespace.
109 110 111 112 |
# File 'lib/impromptu/folder.rb', line 109 def create_namespace return if self.namespace.nil? Impromptu.root_resource.get_or_create_child(self.namespace).namespace! end |
#eql?(other) ⇒ Boolean
Override eql? so two folders with the same path will be considered equal by ordered set.
39 40 41 |
# File 'lib/impromptu/folder.rb', line 39 def eql?(other) other.folder == @folder end |
#file(name, options = {}) ⇒ Object
Explicitly include a file from this folder. Combined with the implicitly_loaded option set to false, this method allows you to manually define a set of files to load from a folder. If implicitly_loaded is true, this method can be used to provide definitions of exceptional files (for example files which define multiple resources, or files with exceptional names). Options may be:
-
provides (required): an array of symbols, or a symbol indicating the name of the resource(s) provided by the file
139 140 141 142 143 |
# File 'lib/impromptu/folder.rb', line 139 def file(name, ={}) file_preload = [:preload] || preload? file = Impromptu::File.new(@folder.join(*name).realpath, self, file_preload, [:provides]) @files.push(file).add_resource_definition end |
#hash ⇒ Object
Override hash so two folders with the same path will result in the same hash value.
45 46 47 |
# File 'lib/impromptu/folder.rb', line 45 def hash @folder.hash end |
#implicitly_loaded? ⇒ Boolean
True if the folder is implicitly loaded (we scan the folder for source files and automatically infer resources)
74 75 76 |
# File 'lib/impromptu/folder.rb', line 74 def implicitly_loaded? @options[:implicitly_loaded] end |
#load ⇒ Object
Load a folders definition and files after the set of components has been defined. For folders provided a block, the block is run in the context of this folder (allowing ‘file’ to be called). Otherwise the folder is scanned to produce an initial set of files and resources provided by this folder.
54 55 56 57 58 59 60 |
# File 'lib/impromptu/folder.rb', line 54 def load unless @block.nil? instance_eval &@block @block = nil # prevent the block from being run twice end self.reload_file_set end |
#namespace ⇒ Object
A string or symbol for this folder which overrides the components default namespace. Nil if no namespace has been defined.
103 104 105 |
# File 'lib/impromptu/folder.rb', line 103 def namespace @options[:namespace] end |
#nested_namespaces? ⇒ Boolean
True if the folder uses nested namespaces
63 64 65 |
# File 'lib/impromptu/folder.rb', line 63 def nested_namespaces? @options[:nested_namespaces] end |
#preload ⇒ Object
Preload the resources defined by this folder. Should only be called by the Impromptu module, and only once (at app startup).
94 95 96 97 98 99 |
# File 'lib/impromptu/folder.rb', line 94 def preload return unless preload? || force @files.each do |file| file.reload end end |
#preload! ⇒ Object
Turn preloading on for this folder (can be done after initialisation) and run an initial preload. Ensures files are always loaded.
86 87 88 89 90 |
# File 'lib/impromptu/folder.rb', line 86 def preload! @options[:preload] = true @files.each {|file| file.preload = true} preload end |
#preload? ⇒ Boolean
True if the resources of the folder are loaded immediately on startup, and won’t be autoloaded.
80 81 82 |
# File 'lib/impromptu/folder.rb', line 80 def preload? @options[:preload] end |
#relative_path_to(path) ⇒ Object
Return the ‘base’ folder for a file contained within this folder. For instance, a folder with nested namespaces would return the path to a file from the root folder. Without namespaces, the relative path to a file would be the enclosing folder of the file. i.e relative path to framework/a/b.rb (where framework is the root folder) would return ‘a/b.rb’ for a nested namespace folder, or just ‘b.rb’ for a non nested namespace folder.
122 123 124 125 126 127 128 |
# File 'lib/impromptu/folder.rb', line 122 def relative_path_to(path) if nested_namespaces? path.relative_path_from(@folder) else path.basename end end |
#reload ⇒ Object
Reload the files provided by this folder. If the folder is tracking a specific set of files, only those files will be reloaded. Otherwise, the folder is scanned again and any previously unseen files loaded, existing files reloaded, and removed files unloaded.
150 151 152 153 |
# File 'lib/impromptu/folder.rb', line 150 def reload reload_file_set if implicitly_loaded? @files.each {|file| file.reload_if_modified} end |
#reload_file_set ⇒ Object
Determine changes between the set of files this folder knows about, and the set of files existing on disk. Any files which have been removed are unloaded (and their resources reloaded if other files define the resources as well), and any new files insert their resources in to the known resources tree.
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/impromptu/folder.rb', line 161 def reload_file_set return unless implicitly_loaded? old_file_set = @files.to_a new_file_set = [] changes = false # find all source files and add unseen files to the files list @folder.find do |path| next unless source_file?(path) file = Impromptu::File.new(path.realpath, self, preload?) new_file_set << file unless @files.include?(file) changes = true @files.push(file).add_resource_definition end end # remove any files which have been deleted deleted_files = old_file_set - new_file_set deleted_files.each {|file| @files.delete(file).remove} changes = true if deleted_files.size > 0 # refreeze each files association lists if the set of # files has changed if changes @files.each do |file| file.refreeze end end end |
#reloadable? ⇒ Boolean
True if the folder is reloadable
68 69 70 |
# File 'lib/impromptu/folder.rb', line 68 def reloadable? @options[:reloadable] end |