Class: Gitlab::Git::Attributes

Inherits:
Object
  • Object
show all
Defined in:
lib/gitlab_git/attributes.rb

Overview

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 }

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ Attributes

path - The path to the Git repository.



20
21
22
23
# File 'lib/gitlab_git/attributes.rb', line 20

def initialize(path)
  @path = path
  @patterns = nil
end

Instance Method Details

#attributes(path) ⇒ Object

Returns all the Git attributes for the given path.

path - A path to a file for which to get the attributes.

Returns a Hash.



30
31
32
33
34
35
36
# File 'lib/gitlab_git/attributes.rb', line 30

def attributes(path)
  patterns.each do |pattern, attrs|
    return attrs if File.fnmatch(pattern, path)
  end

  {}
end

#each_lineObject

Iterates over every line in the attributes file.



86
87
88
89
90
91
92
93
94
95
96
# File 'lib/gitlab_git/attributes.rb', line 86

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|
      yield line.strip
    end
  end
end

#parse_attributes(string) ⇒ Object

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.



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/gitlab_git/attributes.rb', line 54

def parse_attributes(string)
  values = {}
  dash = '-'
  equal = '='

  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

    # Input: "-foo"
    if chunk.start_with?(dash)
      key = chunk.byteslice(1, chunk.length - 1)

      values[key] = false

    # Input: "foo=bar"
    elsif chunk.include?(equal)
      key, value = chunk.split(equal, 2)

      values[key] = value

    # Input: "foo"
    else
      values[chunk] = true
    end
  end

  values
end

#patternsObject

Returns a Hash containing the file patterns and their attributes.



39
40
41
# File 'lib/gitlab_git/attributes.rb', line 39

def patterns
  @patterns ||= parse_file
end