Class: DirectoryTemplate
- Defined in:
- lib/directory_template.rb,
lib/directory_template/version.rb,
lib/directory_template/processor.rb,
lib/directory_template/blank_slate.rb,
lib/directory_template/erb_template.rb,
lib/directory_template/process_data.rb,
lib/directory_template/processor/erb.rb,
lib/directory_template/processor/stop.rb,
lib/directory_template/processor/format.rb,
lib/directory_template/processor/markdown.rb
Overview
DirectoryTemplate Create directory structures from template directory structures or template data.
Preregistered processors
-
:stop: Stops the preprocessing chain, it’s advised to add that to all files for
future-proofness.
Defined Under Namespace
Classes: BlankSlate, ErbTemplate, ProcessData, Processor
Constant Summary collapse
- Processors =
All registered processors
[]
- StandardPathProcessor =
The standard path processor, just replaces ‘%sprintf_style_variables` with their values.
Processor::Format
- DefaultOptions =
The default options used by DirectoryTemplate
{ :verbose => false, :silent => false, :out => $stdout, :processors => Processors, :path_processor => StandardPathProcessor, :source => '(unknown)', :meta => {}, }
- Version =
The version of DirectoryTemplate
Gem::Version.new("1.0.1")
Instance Attribute Summary collapse
-
#directories ⇒ Array
readonly
All directories of the template.
-
#dry_run(in_path = '.', env = {}, &on_collision) ⇒ Object
readonly
Same as #materialize, but doesn’t actually do anything, except print the debug and info messages.
-
#files ⇒ Hash<String,String>
readonly
All files of the template and their content.
-
#meta ⇒ Object
readonly
Meta information can be used by processors.
-
#out ⇒ IO, #puts
readonly
The object on which info and debug messages are printed.
-
#path_processor ⇒ #call
readonly
The path processor used by this template.
-
#processors ⇒ Array<DirectoryTemplate::Processor>
readonly
The content processors used by this template.
-
#silent ⇒ Object
When true, will not even output info messages.
-
#verbose ⇒ Object
When true, will additionally output debug messages.
Class Method Summary collapse
-
.convert_recursive_structure(current, stack = [], dirs = [], files = {}) ⇒ Object
Converts a recursive hash into a suitable data structure for DirectoryTemplate::new.
-
.directory(template_path, options = {}) ⇒ Object
Create a DirectoryTemplate from an existing directory structure.
-
.from_hash(hash, options = nil) ⇒ Object
Create a DirectoryTemplate from a nested hash structure.
-
.register(processor) ⇒ Object
You can register custom processors for templates.
-
.yaml_file(path, options = {}) ⇒ Object
Create a DirectoryTemplate from a YAML file.
Instance Method Summary collapse
-
#create_directory(path, mode = 0755, &message) ⇒ Object
Create the given directory and emit an info message (unless in dry_run mode).
-
#create_file(path, content = "", mode = 0644, &message) ⇒ Object
Create the given file and emit an info message (unless in dry_run mode).
-
#debug ⇒ Object
Emit a debug string (the return value of the block).
-
#info ⇒ Object
Emit an info string (the return value of the block).
-
#initialize(data, options = nil) ⇒ DirectoryTemplate
constructor
Create a new DirectoryTemplate.
-
#inspect ⇒ Object
See Object#inspect.
-
#materialize(in_path = '.', env = {}, &on_collision) ⇒ Object
Creates all the directories and files from the template in the given path.
-
#process_content(path, content, env) ⇒ Object
Preprocesses the given content.
-
#process_path(path, env) ⇒ Object
Preprocesses the given path.
-
#processor_for(data) ⇒ Processor?
Returns the processor or nil.
Constructor Details
#initialize(data, options = nil) ⇒ DirectoryTemplate
Create a new DirectoryTemplate
151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/directory_template.rb', line 151 def initialize(data, =nil) = ? DefaultOptions.merge() : DefaultOptions.dup @directories = data[:directories] || [] @files = data[:files] || [] @source = .delete(:source) = .delete(:meta) @verbose = .delete(:verbose) @silent = .delete(:silent) @out = .delete(:out) @processors = .delete(:processors) @path_processor = .delete(:path_processor) @dry_run = false raise ArgumentError, "Unknown options: #{options.keys.join(', ')}" unless .empty? end |
Instance Attribute Details
#directories ⇒ Array (readonly)
Returns All directories of the template.
112 113 114 |
# File 'lib/directory_template.rb', line 112 def directories @directories end |
#dry_run(in_path = '.', env = {}, &on_collision) ⇒ Object (readonly)
Same as #materialize, but doesn’t actually do anything, except print the debug and info messages. It additionally prints an info message, containing the file content of files that would be created.
128 129 130 |
# File 'lib/directory_template.rb', line 128 def dry_run @dry_run end |
#files ⇒ Hash<String,String> (readonly)
Returns All files of the template and their content.
115 116 117 |
# File 'lib/directory_template.rb', line 115 def files @files end |
#meta ⇒ Object (readonly)
Meta information can be used by processors. There’s no requirements on them, except that the toplevel container is a hash.
109 110 111 |
# File 'lib/directory_template.rb', line 109 def end |
#out ⇒ IO, #puts (readonly)
Returns The object on which info and debug messages are printed.
124 125 126 |
# File 'lib/directory_template.rb', line 124 def out @out end |
#path_processor ⇒ #call (readonly)
Returns The path processor used by this template.
121 122 123 |
# File 'lib/directory_template.rb', line 121 def path_processor @path_processor end |
#processors ⇒ Array<DirectoryTemplate::Processor> (readonly)
Returns The content processors used by this template.
118 119 120 |
# File 'lib/directory_template.rb', line 118 def processors @processors end |
#silent ⇒ Object
When true, will not even output info messages
131 132 133 |
# File 'lib/directory_template.rb', line 131 def silent @silent end |
#verbose ⇒ Object
When true, will additionally output debug messages
134 135 136 |
# File 'lib/directory_template.rb', line 134 def verbose @verbose end |
Class Method Details
.convert_recursive_structure(current, stack = [], dirs = [], files = {}) ⇒ Object
Converts a recursive hash into a suitable data structure for DirectoryTemplate::new
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/directory_template.rb', line 70 def self.convert_recursive_structure(current, stack=[], dirs=[], files={}) current.each do |segment, content| new_stack = stack+[segment] path = new_stack.join('/') case content when String,nil files[path] = content || '' when Hash dirs << path convert_recursive_structure(content, new_stack, dirs, files) else raise "Invalid structure" end end return dirs, files end |
.directory(template_path, options = {}) ⇒ Object
Create a DirectoryTemplate from an existing directory structure.
55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/directory_template.rb', line 55 def self.directory(template_path, ={}) data = Dir.chdir(template_path) { paths = Dir['**/{*,.*}'] paths -= paths.grep(/(?:^|\/)\.\.?$/) directories, files = paths.sort.partition { |path| File.directory?(path) } filemap = Hash[files.map { |path| [path, File.read(path)] }] {:directories => directories, :files => filemap} } new(data, .merge(:source => template_path)) end |
.from_hash(hash, options = nil) ⇒ Object
Create a DirectoryTemplate from a nested hash structure. The hash should just be a recursive hash of strings. Use an empty hash to indicate an empty directory. Leaf-strings are considered to be the content of a file. Use nil to indicate an empty file.
92 93 94 95 96 97 |
# File 'lib/directory_template.rb', line 92 def self.from_hash(hash, =nil) dirs, files = convert_recursive_structure(hash) data = {:directories => dirs, :files => files} new(data, ) end |
.register(processor) ⇒ Object
You can register custom processors for templates. They’re triggered based on the pattern. A processor can change the ProcessData struct passed to it, which will be reflected when creating the file or directory
34 35 36 |
# File 'lib/directory_template.rb', line 34 def self.register(processor) Processors << processor end |
.yaml_file(path, options = {}) ⇒ Object
Create a DirectoryTemplate from a YAML file. The yaml should just be a recursive hash of strings. Use an empty hash to indicate an empty directory. Leaf-strings are considered to be the content of a file. Use nil to indicate an empty file.
103 104 105 |
# File 'lib/directory_template.rb', line 103 def self.yaml_file(path, ={}) from_hash(YAML.load_file(path), .merge(:source => template_path)) end |
Instance Method Details
#create_directory(path, mode = 0755, &message) ⇒ Object
The mode param is currently unused.
Create the given directory and emit an info message (unless in dry_run mode).
255 256 257 258 259 260 |
# File 'lib/directory_template.rb', line 255 def create_directory(path, mode=0755, &) unless File.exist?(path) then info(&) FileUtils.mkdir_p(path) unless @dry_run end end |
#create_file(path, content = "", mode = 0644, &message) ⇒ Object
The mode param is currently unused.
Create the given file and emit an info message (unless in dry_run mode).
266 267 268 269 270 271 272 273 274 275 |
# File 'lib/directory_template.rb', line 266 def create_file(path, content="", mode=0644, &) info(&) if @dry_run then info { " Content:\n#{content.gsub(/^/, ' ')}" } else File.open(path, 'wb:binary') do |fh| fh.write(content) end end end |
#debug ⇒ Object
Emit a debug string (the return value of the block). Will only be emitted if DirectoryTemplate#debug is true
297 298 299 |
# File 'lib/directory_template.rb', line 297 def debug @out.puts yield if @verbose end |
#info ⇒ Object
Emit an info string (the return value of the block). Will not be emitted if DirectoryTemplate#silent is true
290 291 292 |
# File 'lib/directory_template.rb', line 290 def info @out.puts yield unless @silent end |
#inspect ⇒ Object
See Object#inspect
303 304 305 |
# File 'lib/directory_template.rb', line 303 def inspect sprintf "#<%s:0x%x source=%p>", self.class, object_id<<1, @source end |
#materialize(in_path = '.', env = {}, &on_collision) ⇒ Object
Creates all the directories and files from the template in the given path.
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
# File 'lib/directory_template.rb', line 192 def materialize(in_path='.', env={}, &on_collision) in_path = File.(in_path) create_directory(in_path) { "Creating root '#{in_path}'" } Dir.chdir(in_path) do if @directories.empty? then info { "No directories to create" } else info { "Creating directories" } @directories.each do |source_dir_path| target_dir_path = process_path(source_dir_path, env) create_directory(target_dir_path) { " #{target_dir_path}" } end end if @files.empty? then info { "No files to create" } else info { "Creating files" } @files.each do |source_file_path, content| target_file_path = process_path(source_file_path, env) data = process_content(target_file_path, content, env) if File.exist?(data.path) then if block_given? && yield(data) then create_file(data.path, data.content) { " #{data.path} (overwrite)" } else info { " #{data.path} (exists already)" } end else create_file(data.path, data.content) { " #{data.path} (new)" } end end end end self end |
#process_content(path, content, env) ⇒ Object
Preprocesses the given content
238 239 240 241 242 243 244 245 246 247 248 249 |
# File 'lib/directory_template.rb', line 238 def process_content(path, content, env) data = ProcessData.new(self, path, content, env) catch(:stop_processing) { #p :process_content => path, :available => @processors.size, :processors => processors_for(data).tap { |x| x && x.size } while processor = processor_for(data) debug { " -> Applying #{processor.name}" } processor.call(data) end } data end |
#process_path(path, env) ⇒ Object
Preprocesses the given path
232 233 234 |
# File 'lib/directory_template.rb', line 232 def process_path(path, env) @path_processor.call(ProcessData.new(self, path, nil, env)).path end |
#processor_for(data) ⇒ Processor?
Returns the processor or nil
283 284 285 |
# File 'lib/directory_template.rb', line 283 def processor_for(data) @processors.find { |processor| processor === data } end |