class Gitlab::Git::Attributes
Class for parsing Git
attribute files and extracting the attributes for file patterns.
Unlike Rugged this parser only needs a single IO call (a call to `open`), vastly reducing the time spent in extracting attributes.
This class only supports parsing the attributes file located at `$GIT_DIR/info/attributes` as GitLab doesn't use any other files (`.gitattributes` is copied to this particular path).
Basic usage:
attributes = Gitlab::Git::Attributes.new(some_repo.path) attributes.attributes('README.md') # => { "eol" => "lf }
Public Class Methods
path - The path to the Git
repository.
# File lib/gitlab_git/attributes.rb, line 20 def initialize(path) @path = File.expand_path(path) @patterns = nil end
Public Instance Methods
Returns all the Git
attributes for the given path.
path - A path to a file for which to get the attributes.
Returns a Hash.
# File lib/gitlab_git/attributes.rb, line 30 def attributes(path) full_path = File.join(@path, path) patterns.each do |pattern, attrs| return attrs if File.fnmatch?(pattern, full_path) end {} end
Iterates over every line in the attributes file.
# File lib/gitlab_git/attributes.rb, line 95 def each_line full_path = File.join(@path, 'info/attributes') return unless File.exist?(full_path) File.open(full_path, 'r') do |handle| handle.each_line do |line| break unless line.valid_encoding? yield line.strip end end end
Parses an attribute string.
These strings can be in the following formats:
text # => { "text" => true } -text # => { "text" => false } key=value # => { "key" => "value" }
string - The string to parse.
Returns a Hash containing the attributes and their values.
# File lib/gitlab_git/attributes.rb, line 56 def parse_attributes(string) values = {} dash = '-' equal = '=' binary = 'binary' string.split(/\s+/).each do |chunk| # Data such as "foo = bar" should be treated as "foo" and "bar" being # separate boolean attributes. next if chunk == equal key = chunk # Input: "-foo" if chunk.start_with?(dash) key = chunk.byteslice(1, chunk.length - 1) value = false # Input: "foo=bar" elsif chunk.include?(equal) key, value = chunk.split(equal, 2) # Input: "foo" else value = true end values[key] = value # When the "binary" option is set the "diff" option should be set to # the inverse. If "diff" is later set it should overwrite the # automatically set value. values['diff'] = false if key == binary && value end values end
Returns a Hash containing the file patterns and their attributes.
# File lib/gitlab_git/attributes.rb, line 41 def patterns @patterns ||= parse_file end
Private Instance Methods
Parses the Git
attributes file.
# File lib/gitlab_git/attributes.rb, line 112 def parse_file pairs = [] comment = '#' each_line do |line| next if line.start_with?(comment) || line.empty? pattern, attrs = line.split(/\s+/, 2) parsed = attrs ? parse_attributes(attrs) : {} pairs << [File.join(@path, pattern), parsed] end # Newer entries take precedence over older entries. pairs.reverse.to_h end