class IDL::GenFile
Constants
- REGEN_MARKER_DEFAULT
Attributes
content[R]
ext[R]
fullpath[R]
name[R]
path[R]
Public Class Methods
new(path, opts = {})
click to toggle source
# File lib/ridl/genfile.rb, line 95 def initialize(path, opts = {}) if path @path = path @fullpath = File.expand_path(path) @name = File.basename(path) @ext = File.extname(path).sub(/^\./, '') else @path = @fullpath = @name = @ext = '' end @options = { regenerate: false, regen_marker_prefix: '//', regen_marker_postfix: nil, regen_marker: REGEN_MARKER_DEFAULT, regen_keep_header: true, output_file: nil, create_missing_dir: false }.merge(opts) if @options[:regenerate] && File.exist?(@fullpath) parse_regeneration_content else @content = Content.new end @fout = @options[:output_file] || Tempfile.new(@name) self.class.__send__(:_push, self) end
rollback()
click to toggle source
# File lib/ridl/genfile.rb, line 63 def self.rollback _rollback end
transaction(&block)
click to toggle source
# File lib/ridl/genfile.rb, line 52 def self.transaction(&block) _start_transaction begin block.call if block_given? _commit ensure _rollback # after successful transaction should be nothing left _close_transaction end end
Public Instance Methods
<<(txt)
click to toggle source
# File lib/ridl/genfile.rb, line 122 def <<(txt) @fout << txt if @fout self end
_close_transaction()
click to toggle source
# File lib/ridl/genfile.rb, line 28 def _close_transaction _stack.pop @transaction = _stack.last end
_commit()
click to toggle source
# File lib/ridl/genfile.rb, line 37 def _commit _transaction.reject! { |fgen| fgen.save true } end
_push(fgen)
click to toggle source
# File lib/ridl/genfile.rb, line 47 def _push(fgen) _transaction << fgen if _transaction end
_rollback()
click to toggle source
# File lib/ridl/genfile.rb, line 42 def _rollback _transaction.reject! { |fgen| fgen.remove true } if _transaction end
_stack()
click to toggle source
# File lib/ridl/genfile.rb, line 20 def _stack @stack ||= [] end
_start_transaction()
click to toggle source
# File lib/ridl/genfile.rb, line 24 def _start_transaction _stack << (@transaction = []) end
_transaction()
click to toggle source
# File lib/ridl/genfile.rb, line 33 def _transaction @transaction end
regen_end_marker(sectionid)
click to toggle source
# File lib/ridl/genfile.rb, line 131 def regen_end_marker(sectionid) "#{@options[:regen_marker_prefix]}#{@options[:regen_marker]} - END : #{sectionid}#{@options[:regen_marker_postfix]}" end
regen_header_end_marker(sectionid)
click to toggle source
# File lib/ridl/genfile.rb, line 135 def regen_header_end_marker(sectionid) "#{@options[:regen_marker_prefix]}#{@options[:regen_marker]} - HEADER_END : #{sectionid}#{@options[:regen_marker_postfix]}" end
regen_start_marker(sectionid)
click to toggle source
# File lib/ridl/genfile.rb, line 127 def regen_start_marker(sectionid) "#{@options[:regen_marker_prefix]}#{@options[:regen_marker]} - BEGIN : #{sectionid}#{@options[:regen_marker_postfix]}" end
remove()
click to toggle source
# File lib/ridl/genfile.rb, line 201 def remove return if @options[:output_file] if @fout begin @fout.close(true) rescue IDL.log(0, %Q{ERROR: FAILED to clean up temp file #{@fout.path}: #{$!}}) end @fout = nil end end
save()
click to toggle source
# File lib/ridl/genfile.rb, line 158 def save return if @options[:output_file] if @fout fgen = @fout @fout = nil fgen.close(false) # close but do NOT unlink if File.exist?(@fullpath) # create temporary backup ftmp = Tempfile.new(@name) ftmp_name = ftmp.path.dup ftmp.close(true) # close AND unlink FileUtils::mv(@fullpath, ftmp_name) # backup existing file # replace original begin # rename newly generated file FileUtils.mv(fgen.path, @fullpath) # preserve file mode FileUtils.chmod(File.lstat(ftmp_name).mode, @fullpath) rescue IDL.log(0, %Q{ERROR: FAILED updating #{@path}: #{$!}}) # restore backup FileUtils.mv(ftmp_name, @fullpath) raise end # remove backup File.unlink(ftmp_name) else unless File.directory?(File.dirname(@fullpath)) unless @options[:create_missing_dir] IDL.log(0, %Q{ERROR: Cannot access output folder #{File.dirname(@fullpath)}}) exit(1) end FileUtils.mkdir_p(File.dirname(@fullpath)) end # just rename newly generated file FileUtils.mv(fgen.path, @fullpath) # set default mode for new files FileUtils.chmod(0666 - File.umask, @fullpath) end end end
write_regen_section(sectionid, options = {}) { || ... }
click to toggle source
# File lib/ridl/genfile.rb, line 139 def write_regen_section(sectionid, options = {}) indent = options[:indent] || '' self << indent << regen_start_marker(sectionid) << "\n" unless options[:header] if content.has_section?(sectionid) self << content[sectionid].join unless content[sectionid].empty? elsif block_given? yield # block should yield default content elsif default_content = options[:default_content] default_content = (Array === default_content) ? default_content : default_content.to_s.split("\n") self << (default_content.collect { |l| (s = indent.dup) << l << "\n" s }.join) unless default_content.empty? end if options[:header] self << indent << regen_header_end_marker(sectionid) << "\n" else self << indent << regen_end_marker(sectionid) << "\n" unless options[:footer] end end
Private Instance Methods
parse_regeneration_content()
click to toggle source
# File lib/ridl/genfile.rb, line 216 def parse_regeneration_content markers_sel = %w{BEGIN END} _keep_header = (@options[:regen_keep_header] == true) markers_sel << 'HEADER_END' if _keep_header regen_marker_re = /#{@options[:regen_marker]}\s+[-]\s+(#{markers_sel.join('|')})\s+:\s+(.+)/ sections = {} section = [] in_section = _keep_header ? ['HEADER', 0] : nil linenr = 0 File.open(@fullpath) do |fio| fio.each do |line| linenr += 1 if regen_marker_re =~ line case $1 when 'BEGIN' raise "ERROR: Found unterminated regeneration section starting at #{@path}:#{in_section.last}." if in_section in_section = [$2, linenr] section = [] when 'END' raise "ERROR: Found unmatched regeneration end at #{@path}:#{linenr}." unless in_section && ($2 == in_section.first) sections[$2] = section in_section = nil section = [] when 'HEADER_END' raise "ERROR: Found illegal header end marker at #{@path}:#{linenr}." unless _keep_header && in_section && ('HEADER' == in_section.first ) && (in_section.last.zero?) sections[$2] = section in_section = nil section = [] else raise "ERROR: Found invalid regeneration marker at #{@path}:#{linenr}." end elsif in_section section << line end end end sections[in_section.first] = section if in_section @content = Content.new(sections) end