class Mergit::Processor
The class that actually does the merge processing.
Attributes
@return {Hash} A frozen hash with the rules for replacements.
@return {Array<Pathname>} A frozen array of {rubydoc.info/stdlib/pathname/frames Pathname}s
Public Class Methods
All `require`d files will have 'MERGIT' start and end comments around them showing what file was included.
The initial `:filename` or `:string` will not have 'MERGIT' comments.
@param [Array<Pathname, String>] search_path
The list of directories to search. @param [Hash] replacements A list of keywords to replace. @param [Hash] options Either `:filename` or `:string` should be set.
# File lib/mergit/processor.rb, line 23 def initialize search_path, replacements, options @search_path = search_path.map{|p| Pathname.new p}.freeze @replacements = replacements.freeze @visited_files = [] @output = StringIO.new begin if options.key?(:filename) Pathname.new(options[:filename]).open('r') { |fp| scan(fp.read) } elsif options.key?(:string) scan(options[:string]) end ensure @output.close unless options[:do_not_close] end end
Public Instance Methods
Sends a string to the {#output}
@param [String] string The string to send to {#output}. @return [Nil]
# File lib/mergit/processor.rb, line 127 def emit string @output.puts string end
Finds a library using the {#search_path}
@param [String, Pathname] filename The name of the library to look for. @return [Nil, Pathname] Returns `nil` if it isn't found or a {rubydoc.info/stdlib/pathname/frames Pathname} if it is found.
# File lib/mergit/processor.rb, line 44 def find_requirement filename filename = Pathname.new filename @search_path.each do |directory| possible_path = directory + filename.dirname + "#{filename.basename('.rb')}.rb" return possible_path.realpath if possible_path.file? end nil end
The resulting processed output.
@return [String]
# File lib/mergit/processor.rb, line 118 def output @output.close unless @output.closed? @final_output ||= @output.string end
Scans a string
It splits a string up into individual lines via {#string_split} and passes them to {#scan_line}.
@param [String] string The string to parse. @return [Nil]
# File lib/mergit/processor.rb, line 103 def scan string string_split(string).each { |line| scan_line line } end
Scans an entire file
It passes each line of the file to {#scan_line} for parsing.
If the `filename` was already scanned, it'll do nothing and return `true`.
If the `filename` doesn't exist in the {#search_path}, then it'll return `false`.
@param [Pathname] filename The file to scan. @return [FalseClass, TrueClass] Returns true if the file was emitted. Returns false if it cannot find the file in {#search_path}
# File lib/mergit/processor.rb, line 84 def scan_file filename filename_path = find_requirement(filename) return false if filename_path.nil? return true if @visited_files.include? filename_path @visited_files << filename_path emit "### MERGIT: Start of '#{filename}'" filename_path.readlines.each { |line| scan_line line } emit "### MERGIT: End of '#{filename}'" return true end
Scans a single line of the file.
It looks for things that need to be changed, and {#emit}s the resulting (changed) line.
@param [String] line The line to parse @return [Nil]
# File lib/mergit/processor.rb, line 60 def scan_line line line.chomp! if line =~ /#\s*MERGIT:\s*skip\s*$/ nil # do nothing elsif line =~ /^\s*require\s+'([^']+)'/ or line =~ /^\s*require\s+"([^"]+)"/ scan_file($1) or emit(line) else replacements.each_key do |string_to_replace| line.gsub!(string_to_replace, replacements[string_to_replace]) end emit line end end
Split a string into lines.
@param [String] string The string to split into lines. @return [Array<String>] The split up string.
# File lib/mergit/processor.rb, line 111 def string_split string string.split(/\n|\r\n/) end