Class: Mergit::Processor

Inherits:
Object
  • Object
show all
Defined in:
lib/mergit/processor.rb

Overview

The class that actually does the merge processing.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(search_path, replacements, options) ⇒ Processor

All required 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.

Parameters:

  • search_path (Array<Pathname, String>)

    The list of directories to search.

  • replacements (Hash)

    A list of keywords to replace.

  • options (Hash)

    Either :filename or :string should be set.



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# 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

Instance Attribute Details

#replacementsHash (readonly)

Returns A frozen hash with the rules for replacements.

Returns:

  • (Hash)

    A frozen hash with the rules for replacements.



14
15
16
# File 'lib/mergit/processor.rb', line 14

def replacements
  @replacements
end

#search_pathArray<Pathname> (readonly)

Returns A frozen array of Pathnames.

Returns:

  • (Array<Pathname>)

    A frozen array of Pathnames



11
12
13
# File 'lib/mergit/processor.rb', line 11

def search_path
  @search_path
end

Instance Method Details

#emit(string) ⇒ Nil

Sends a string to the #output

Parameters:

  • string (String)

    The string to send to #output.

Returns:

  • (Nil)


127
128
129
# File 'lib/mergit/processor.rb', line 127

def emit string
  @output.puts string
end

#find_requirement(filename) ⇒ Nil, Pathname

Finds a library using the #search_path

Parameters:

  • filename (String, Pathname)

    The name of the library to look for.

Returns:

  • (Nil, Pathname)

    Returns nil if it isn't found or a Pathname if it is found.



44
45
46
47
48
49
50
51
# 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

#outputString

The resulting processed output.

Returns:

  • (String)


118
119
120
121
# File 'lib/mergit/processor.rb', line 118

def output
  @output.close unless @output.closed?
  @final_output ||= @output.string
end

#scan(string) ⇒ Nil

Scans a string

It splits a string up into individual lines via #string_split and passes them to #scan_line.

Parameters:

  • string (String)

    The string to parse.

Returns:

  • (Nil)


103
104
105
# File 'lib/mergit/processor.rb', line 103

def scan string
  string_split(string).each { |line| scan_line line }
end

#scan_file(filename) ⇒ FalseClass, TrueClass

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.

Parameters:

  • filename (Pathname)

    The file to scan.

Returns:

  • (FalseClass, TrueClass)

    Returns true if the file was emitted. Returns false if it cannot find the file in #search_path



84
85
86
87
88
89
90
91
92
93
94
# 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

#scan_line(line) ⇒ Nil

Scans a single line of the file.

It looks for things that need to be changed, and #emits the resulting (changed) line.

Parameters:

  • line (String)

    The line to parse

Returns:

  • (Nil)


60
61
62
63
64
65
66
67
68
69
70
71
72
# 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

#string_split(string) ⇒ Array<String>

Split a string into lines.

Parameters:

  • string (String)

    The string to split into lines.

Returns:

  • (Array<String>)

    The split up string.



111
112
113
# File 'lib/mergit/processor.rb', line 111

def string_split string
  string.split(/\n|\r\n/)
end