Class: Origen::Generator::Compiler
Overview
Instance Attribute Summary collapse
Instance Method Summary
collapse
-
#_get_binding(opts, &block) ⇒ Object
private
-
#buffer_name_for(file) ⇒ Object
Returns the ERB buffer name for the given file, something like "@my_file_name".
-
#check_for_differences(a, b, file) ⇒ Object
-
#compile(file_or_dir, options = {}) ⇒ Object
Compile all files found under the source directory, non-erb files will be copied to the destination un-altered.
-
#compile_file(file, options = {}) ⇒ Object
Compile the supplied file if it is an erb template writing the compiled version to the destination directory.
-
#compile_inline(file, options = {}) ⇒ Object
private
Where compile will place the compiled content in an output file, this method will return it as a string to the caller (i.e. without creating an output file).
-
#current_buffer ⇒ Object
-
#current_buffer=(text) ⇒ Object
-
#display_path_to(file) ⇒ Object
-
#is_erb?(file) ⇒ Boolean
Returns true if the supplied file name has a .erb extension.
-
#merge(file_or_dir, options = {}) ⇒ Object
-
#merge_file(file, _options = {}) ⇒ Object
-
#merge_ref_file(file, options = {}) ⇒ Object
-
#merge_reference_directory ⇒ Object
-
#output_directory ⇒ Object
-
#output_file(file, options = {}) ⇒ Object
Returns the output file corresponding to the given source file, the destination directory will be created if it doesn't exist.
-
#reference_directory ⇒ Object
-
#reference_file(file, options = {}) ⇒ Object
Returns the reference file corresponding to the given source file, the destination directory will be created if it doesn't exist.
-
#replace_output_file(destination) ⇒ Object
-
#run_erb(file, opts = {}, &block) ⇒ Object
-
#stats ⇒ Object
-
#with_output_file_lock(destination) ⇒ Object
Methods included from Renderer
#current_pipeline, #insert, #insert_content, #options, #pipeline, #placeholder, #render, #temporary_file
Methods included from Comparator
#check_for_changes, #relative_path_to
Instance Attribute Details
#current_file ⇒ Object
During a compile this will return the current top-level file being compiled
18
19
20
|
# File 'lib/origen/generator/compiler.rb', line 18
def current_file
@current_file
end
|
Instance Method Details
#_get_binding(opts, &block) ⇒ Object
This method is part of a private API.
You should avoid using this method if possible, as it may be removed or be changed in the future.
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
|
# File 'lib/origen/generator/compiler.rb', line 196
def _get_binding(opts, &block)
b = opts[:binding] || opts[:scope] || binding
unless b.is_a?(Binding)
b.define_singleton_method :_get_binding do |local_opts, &_block|
options = local_opts
binding
end
b = b._get_binding(options, &block)
end
b
end
|
#buffer_name_for(file) ⇒ Object
Returns the ERB buffer name for the given file, something like "@my_file_name"
225
226
227
228
229
230
|
# File 'lib/origen/generator/compiler.rb', line 225
def buffer_name_for(file)
expected_filename = file.basename.to_s.chomp('.erb')
expected_filename.gsub!('-', '_') if expected_filename.match(/-/)
expected_filename.gsub!('.', '_') if expected_filename.match(/./)
@current_buffer = '@_' + expected_filename
end
|
#check_for_differences(a, b, file) ⇒ Object
250
251
252
253
254
255
|
# File 'lib/origen/generator/compiler.rb', line 250
def check_for_differences(a, b, file)
if check_for_changes(a, b, comment_char: ["'", 'logprint'], quiet: true, compile_job: true)
puts "*** CHANGE DETECTED *** To rollback: #{Origen.config.copy_command} #{display_path_to(b)} #{display_path_to(a)}"
"#{Origen.config.diff_command} #{display_path_to(a)} #{display_path_to(b)} & #{ENV['EDITOR']} #{file.cleanpath} &"
end
end
|
#compile(file_or_dir, options = {}) ⇒ Object
Compile all files found under the source directory, non-erb files will be copied
to the destination un-altered
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
# File 'lib/origen/generator/compiler.rb', line 41
def compile(file_or_dir, options = {})
options = {
check_for_changes: true,
sub_template: false,
collect_stats: true,
ignore_blank_lines: true
}.merge(options)
@scope = options[:scope]
options[:output_directory] ||= output_directory
@check_for_changes = options[:check_for_changes]
@options = options
if options[:sub_template]
block = options.delete(:block)
if is_erb?(file_or_dir)
run_erb(file_or_dir, options, &block)
else
f = File.open(file_or_dir)
content = f.read
f.close
insert(content)
end
else
Origen.file_handler.resolve_files(file_or_dir, ignore_with_prefix: '_', import: :template) do |file|
compile_file(file, options)
end
end
end
|
#compile_file(file, options = {}) ⇒ Object
Compile the supplied file if it is an erb template writing the compiled
version to the destination directory.
If the file is not an erb template it is simply copied un-altered to the
destination directory.
File must be an absolute path to the file.
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
# File 'lib/origen/generator/compiler.rb', line 101
def compile_file(file, options = {})
@current_file = Pathname.new(file)
Origen.file_handler.default_extension = nil
begin
Origen.log.info "Compiling... #{relative_path_to(file)}" unless options[:quiet]
rescue
Origen.log.info "Compiling... #{file}" unless options[:quiet]
end
destination = output_file(file, options)
Origen.log.info " Created... #{relative_path_to(destination)}" unless options[:quiet]
stats.completed_files += 1 if options[:collect_stats]
with_output_file_lock(destination) do
replace_output_file(destination) do |temporary_file|
if is_erb?(file)
output = run_erb(file, options)
if output.is_a?(Pathname)
FileUtils.mv(output.to_s, temporary_file.to_s)
else
File.open(temporary_file, 'w') { |out| out.puts output }
end
else
FileUtils.cp(file.to_s, temporary_file.to_s)
end
end
if options[:zip]
`gzip -f -9 #{destination}`
elsif @check_for_changes
check_for_changes(destination, reference_file(file, options),
comment_char: Origen.app.tester ? Origen.app.tester. : nil,
compile_job: true, ignore_blank_lines: options[:ignore_blank_lines])
end
end
end
|
#compile_inline(file, options = {}) ⇒ Object
This method is part of a private API.
You should avoid using this method if possible, as it may be removed or be changed in the future.
Where compile will place the compiled content in an output file, this method will return
it as a string to the caller (i.e. without creating an output file)
It expects an absolute path to a single template file as the file argument.
26
27
28
29
30
31
32
33
34
35
36
37
|
# File 'lib/origen/generator/compiler.rb', line 26
def compile_inline(file, options = {})
initial_options = options.merge({})
options = {
check_for_changes: false,
sub_template: false,
collect_stats: false,
initial_options: initial_options
}.merge(options)
@scope = options[:scope]
file = Pathname.new(file) unless options[:string]
run_erb(file, options).strip
end
|
#current_buffer ⇒ Object
216
217
218
|
# File 'lib/origen/generator/compiler.rb', line 216
def current_buffer
(@scope || self).instance_variable_get(@current_buffer || '@_anonymous')
end
|
#current_buffer=(text) ⇒ Object
220
221
222
|
# File 'lib/origen/generator/compiler.rb', line 220
def current_buffer=(text)
(@scope || self).instance_variable_set(@current_buffer || '@_anonymous', text)
end
|
#display_path_to(file) ⇒ Object
244
245
246
247
248
|
# File 'lib/origen/generator/compiler.rb', line 244
def display_path_to(file)
p = relative_path_to(file).to_s
p.gsub!('/', '\\') if Origen.running_on_windows?
p
end
|
#is_erb?(file) ⇒ Boolean
Returns true if the supplied file name has a .erb extension
258
259
260
|
# File 'lib/origen/generator/compiler.rb', line 258
def is_erb?(file)
!!(file.to_s =~ /.erb$/) || !Origen.config.compile_only_dot_erb_files
end
|
#merge(file_or_dir, options = {}) ⇒ Object
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
# File 'lib/origen/generator/compiler.rb', line 71
def merge(file_or_dir, options = {})
compile(file_or_dir_path, check_for_changes: false, output_directory: merge_reference_directory)
diffs = []
Origen.file_handler.resolve_files(file_or_dir, ignore_with_prefix: '_') do |file|
diffs << merge_file(file, options)
end
diffs.compact!
puts ''
if diffs.size > 0
puts 'The following differences are present in the compiled files and must be resolved manually:'
puts ''
diffs.each do |diff|
puts diff
end
puts ''
else
puts 'Merged successfully!'
end
end
|
#merge_file(file, _options = {}) ⇒ Object
232
233
234
235
236
237
238
239
240
241
242
|
# File 'lib/origen/generator/compiler.rb', line 232
def merge_file(file, _options = {})
file = Pathname.new(file)
Origen.log.info "Merging... #{file.basename}"
if is_erb?(file) && File.exist?(output_file(file))
check_for_differences(output_file(file), merge_ref_file(file), file)
elsif File.exist?(output_file(file))
if check_for_differences(output_file(file), merge_ref_file(file), file)
FileUtils.cp(output_file(file), file.dirname.to_s)
end
end
end
|
#merge_ref_file(file, options = {}) ⇒ Object
305
306
307
308
309
310
311
312
313
314
315
316
317
318
|
# File 'lib/origen/generator/compiler.rb', line 305
def merge_ref_file(file, options = {})
options = {
directory: merge_reference_directory
}.merge(options)
sub_dir = Origen.file_handler.sub_dir_of(file).to_s
sub_dir = nil if sub_dir == '.'
filename = file.basename.to_s.gsub('.erb', '')
output = Pathname.new("#{options[:directory]}#{sub_dir ? '/' + sub_dir : ''}/#{filename}")
FileUtils.mkdir_p(output.dirname.to_s) unless File.exist?(output.dirname.to_s)
output
end
|
#merge_reference_directory ⇒ Object
270
271
272
|
# File 'lib/origen/generator/compiler.rb', line 270
def merge_reference_directory
"#{Origen.root}/.merge_ref"
end
|
#output_directory ⇒ Object
262
263
264
|
# File 'lib/origen/generator/compiler.rb', line 262
def output_directory
Origen.file_handler.output_directory
end
|
#output_file(file, options = {}) ⇒ Object
Returns the output file corresponding to the given source file, the destination
directory will be created if it doesn't exist.
276
277
278
279
280
281
282
283
284
285
286
287
288
289
|
# File 'lib/origen/generator/compiler.rb', line 276
def output_file(file, options = {})
options = {
output_directory: output_directory
}.merge(options)
sub_dir = options[:output_sub_dir] || Origen.file_handler.sub_dir_of(file).to_s
sub_dir = nil if sub_dir == '.'
filename = options[:output_file_name] || file.basename.to_s.gsub('.erb', '')
output = Pathname.new("#{options[:output_directory]}#{sub_dir ? '/' + sub_dir : ''}/#{filename}")
FileUtils.mkdir_p(output.dirname.to_s) unless File.exist?(output.dirname.to_s)
output
end
|
#reference_directory ⇒ Object
266
267
268
|
# File 'lib/origen/generator/compiler.rb', line 266
def reference_directory
Origen.file_handler.reference_directory
end
|
#reference_file(file, options = {}) ⇒ Object
Returns the reference file corresponding to the given source file, the destination
directory will be created if it doesn't exist.
293
294
295
296
297
298
299
300
301
302
303
|
# File 'lib/origen/generator/compiler.rb', line 293
def reference_file(file, options = {})
sub_dir = Origen.file_handler.sub_dir_of(file).to_s
sub_dir = nil if sub_dir == '.'
filename = options[:output_file_name] || file.basename.to_s.gsub('.erb', '')
reference = Pathname.new("#{reference_directory}#{sub_dir ? '/' + sub_dir : ''}/#{filename}")
FileUtils.mkdir_p(reference.dirname.to_s) unless File.exist?(reference.dirname.to_s)
reference
end
|
#replace_output_file(destination) ⇒ Object
153
154
155
156
157
158
159
160
|
# File 'lib/origen/generator/compiler.rb', line 153
def replace_output_file(destination)
temporary_file = destination.dirname.join(".#{destination.basename}.#{Process.pid}.#{Thread.current.object_id}.tmp")
FileUtils.rm_f(temporary_file.to_s)
yield temporary_file
File.rename(temporary_file.to_s, destination.to_s)
ensure
FileUtils.rm_f(temporary_file.to_s) if temporary_file
end
|
#run_erb(file, opts = {}, &block) ⇒ Object
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
191
192
193
|
# File 'lib/origen/generator/compiler.rb', line 162
def run_erb(file, opts = {}, &block)
if opts[:preserve_target]
options[:preserve_target] = opts.delete(:preserve_target)
end
Origen.app.reload_target! unless options[:preserve_target]
Origen.file_handler.current_file = file
if opts[:initial_options] || opts[:options]
options.merge!(opts.delete(:initial_options) || opts.delete(:options))
end
options[:file] = file
options[:top_level_file] = current_file
b = _get_binding(opts, &block)
if opts[:string]
content = file
@current_buffer = '@_string_template'
buffer = @current_buffer
else
content = File.read(file.to_s)
buffer = buffer_name_for(file)
end
if block_given?
content = ERB.new(content, trim_mode: '%<>', eoutvar: buffer).result(b)
else
content = ERB.new(content, trim_mode: Origen.config.erb_trim_mode, eoutvar: buffer).result(b)
end
insert(content)
end
|
92
93
94
|
# File 'lib/origen/generator/compiler.rb', line 92
def stats
Origen.app.stats
end
|
#with_output_file_lock(destination) ⇒ Object
141
142
143
144
145
146
147
148
149
150
151
|
# File 'lib/origen/generator/compiler.rb', line 141
def with_output_file_lock(destination)
lock_dir = Pathname.new(Origen.root).join('tmp', 'origen_output_locks')
FileUtils.mkdir_p(lock_dir.to_s)
lock_name = Digest::SHA256.hexdigest(destination.expand_path.to_s)
File.open(lock_dir.join("#{lock_name}.lock"), 'w') do |lock|
lock.flock(File::LOCK_EX)
yield
ensure
lock.flock(File::LOCK_UN)
end
end
|