Module: Amp::Ignore

Extended by:
Ignore
Included in:
Ignore, Match, Repositories::DirState
Defined in:
lib/amp/support/ignore.rb

Constant Summary collapse

COMMENT =
/((^|[^\\])(\\\\)*)#.*/
SYNTAXES =
{'re' => :regexp, 'regexp' => :regexp, 'glob' => :glob,
'relglob' => :relglob, 'relre' => :regexp, 'path' => :glob,
'relpath' => :relglob}

Instance Method Summary collapse

Instance Method Details

#matcher_for_string(string) ⇒ Regexp

Much like matcher_for_text, except tailored to single line strings

Parameters:

  • string (String)

    the string to parse

Returns:

  • (Regexp)

    the regexps generated from the strings and syntaxes

See Also:



75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/amp/support/ignore.rb', line 75

def matcher_for_string(string)
  scanpt = string =~ /(\w+):(.+)/
  if scanpt.nil?
    # just a line, no specified syntax
    syntax = 'regexp'
    # no syntax, the whole thing is a pattern
    include_regexp = string   
  else
    syntax = $1               # the syntax is the first match
    include_regexp = $2.strip # the rest of the string is the pattern
  end
  include_syntax = syntax.to_sym
  parse_line include_syntax, include_regexp
end

#matcher_for_text(text) ⇒ [Regexp]

Produces an array of regexps which can be used for matching files

Parameters:

  • text (String)

    the text to parse

Returns:

  • ([Regexp])

    the regexps generated from the strings and syntaxes



54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/amp/support/ignore.rb', line 54

def matcher_for_text(text)
  return [] unless text
  syntax = nil
  patterns = parse_lines(text).map do |line|
    next if line.empty?
    # check for syntax changes
    if line =~ /^syntax:/
      syntax = SYNTAXES[line[7..-1].strip] || :regexp
      next # move on
    end
    parse_line syntax, line # could be nil, so we need to compact it
  end # parsed_lines(text)
  patterns.compact # kill the nils
end

#parse_ignore(root, files = []) ⇒ Object

Parses the ignore file, file (or “.hgignore”)

Parameters:

  • root (String)

    the root of the repo

  • files (Array<String>) (defaults to: [])

    absolute paths to files



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/amp/support/ignore.rb', line 14

def parse_ignore(root, files=[])
  patterns = {} # not sure what this is
  
  files.each do |file|
    syntax = 're' # default syntax 
    text = File.read File.join(root,file) rescue next
    pattern = matcher_for_text text
    patterns[file] = pattern if pattern
  end # files.each
  
  all_patterns = patterns.values.flatten
  # let the system know that nothing is ignored
  return proc { false } if all_patterns.empty?
  # here's the proc to do the tests
  regexps_to_proc all_patterns
end

#parse_line(syntax, line) ⇒ NilClass, Regexp

Turns a single line, given a syntax, into either a valid regexp or nil. If it is nil, it means the syntax was incorrect.

Parameters:

  • syntax (Symbol)

    the syntax to parse with (:regexp, :glob, :relglob)

  • line (String)

    the line to parse

Returns:

  • (NilClass, Regexp)

    nil means the syntax was a bad choice



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/amp/support/ignore.rb', line 98

def parse_line(syntax, line)
  return nil unless syntax
  
  # find more valid syntax stuff
  # we need to make everything here valid regexps
  case syntax.to_sym
  when :regexp
    # basic regex
    pattern = /#{line}/
  when :glob, :relglob
    # glob: glob (shell style), relative to the root of the repository
    # relglob: glob, except we just match somewhere in the string, not from the root of
    # the repository
    ps = line.split '/**/'
    ps.map! do |l|
      parts = l.split '*' # split it up and we'll escape all the parts
      parts.map! {|p| Regexp.escape p }
      /#{parts.join '[^/]*'}/ # anything but a slash, ie, no change in directories
    end
    joined = ps.join '/(?:.*/)*'
    pattern = (syntax.to_sym == :glob) ? /^#{joined}/ : /#{joined}/
  else
    pattern = nil
  end
  
  pattern
end

#parse_lines(text) ⇒ Object

Parse the lines into valid syntax

Parameters:

  • file (String)

    and open file



35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/amp/support/ignore.rb', line 35

def parse_lines(text)
  lines = text.split("\n").map do |line|
    if line =~ /#/
      line.sub! COMMENT, "\\1"
      line.gsub! "\\#", "#"
    end
    
    line.rstrip!
    line.empty? ? nil : line
  end
  lines.compact
end

#regexps_to_proc(*regexps) ⇒ Proc Also known as: regexp_to_proc

Converts all the ignored regexps into a proc that matches against all of these regexps. That way we can pass around a single proc that checks if a file is ignored.

Parameters:

  • regexps (Array<Regexp>)

    all of the regexes that we need to match against

Returns:

  • (Proc)

    a proc that, when called with a file’s path, will return whether it matches any of the regexps.



133
134
135
136
137
138
139
140
# File 'lib/amp/support/ignore.rb', line 133

def regexps_to_proc(*regexps)
  regexps = regexps.flatten.compact # needed because of possible nils
  if regexps.empty?
    proc { false }
  else
    proc { |file| regexps.any? {|p| file =~ p } }
  end
end