Commit d6b36064 authored by Douglas Barbosa Alexandre's avatar Douglas Barbosa Alexandre

Merge branch '215190-parse-codeowners-file-by-section' into 'master'

Add method for sectional processing of CODEOWNERS

See merge request gitlab-org/gitlab!30529
parents e436576a 6a86dd41
...@@ -5,6 +5,8 @@ module Gitlab ...@@ -5,6 +5,8 @@ module Gitlab
class Entry class Entry
include ::Gitlab::Utils::StrongMemoize include ::Gitlab::Utils::StrongMemoize
DEFAULT_SECTION = "codeowners"
Data = Struct.new(:pattern, :owner_line, :section) Data = Struct.new(:pattern, :owner_line, :section)
attr_reader :data attr_reader :data
...@@ -12,7 +14,7 @@ module Gitlab ...@@ -12,7 +14,7 @@ module Gitlab
delegate :pattern, :hash, :owner_line, :section, to: :data delegate :pattern, :hash, :owner_line, :section, to: :data
def initialize(pattern, owner_line, section = "CODEOWNERS") def initialize(pattern, owner_line, section = DEFAULT_SECTION)
@data = Data.new(pattern, owner_line, section) @data = Data.new(pattern, owner_line, section)
end end
......
...@@ -49,21 +49,53 @@ module Gitlab ...@@ -49,21 +49,53 @@ module Gitlab
data.lines.each do |line| data.lines.each do |line|
line = line.strip line = line.strip
next unless line.present?
next if line.starts_with?('#')
pattern, _separator, owners = line.partition(/(?<!\\)\s+/) next if skip?(line)
normalized_pattern = normalize_pattern(pattern) extract_entry_and_populate_parsed(line, parsed)
parsed[normalized_pattern] = Entry.new(pattern, owners)
end end
parsed parsed
end end
def get_parsed_sectional_data def get_parsed_sectional_data
{} parsed = {}
section = ::Gitlab::CodeOwners::Entry::DEFAULT_SECTION
parsed[section] = {}
data.lines.each do |line|
line = line.strip
next if skip?(line)
if line.starts_with?('[') && line.end_with?(']')
section = line[1...-1].strip
parsed[section] ||= {}
next
end
extract_entry_and_populate_parsed(line, parsed, section)
end
parsed
end
def extract_entry_and_populate_parsed(line, parsed, section = nil)
pattern, _separator, owners = line.partition(/(?<!\\)\s+/)
normalized_pattern = normalize_pattern(pattern)
if section
parsed[section][normalized_pattern] = Entry.new(pattern, owners, section)
else
parsed[normalized_pattern] = Entry.new(pattern, owners)
end
end
def skip?(line)
line.blank? || line.starts_with?('#')
end end
def normalize_pattern(pattern) def normalize_pattern(pattern)
......
ee/ @gl-admin
[Documentation]
ee/docs @gl-docs
docs @gl-docs
[Database]
README.md @gl-database
model/db @gl-database
[Documentation]
README.md @gl-docs
...@@ -43,9 +43,49 @@ describe Gitlab::CodeOwners::File do ...@@ -43,9 +43,49 @@ describe Gitlab::CodeOwners::File do
end end
it "passes the call to #get_parsed_sectional_data" do it "passes the call to #get_parsed_sectional_data" do
expect(file).to receive(:get_parsed_sectional_data).and_return({}) expect(file).to receive(:get_parsed_sectional_data)
expect(file.parsed_data).to be_empty file.parsed_data
end
it "populates a hash with a single default section" do
data = file.parsed_data
expect(data.keys.length).to eq(1)
expect(data.keys).to contain_exactly(::Gitlab::CodeOwners::Entry::DEFAULT_SECTION)
end
context "when CODEOWNERS file contains multiple sections" do
using RSpec::Parameterized::TableSyntax
let(:file_content) do
File.read(Rails.root.join("ee", "spec", "fixtures", "sectional_codeowners_example"))
end
it "is a hash sorted by sections without duplicates" do
data = file.parsed_data
expect(data.keys.length).to eq(3)
expect(data.keys).to contain_exactly("codeowners", "Documentation", "Database")
end
where(:section, :patterns, :owners) do
"codeowners" | ["/**/ee/**/*"] | ["@gl-admin"]
"Documentation" | ["/**/README.md", "/**/ee/docs", "/**/docs"] | ["@gl-docs"]
"Database" | ["/**/README.md", "/**/model/db"] | ["@gl-database"]
end
with_them do
it "assigns the correct paths to each section" do
expect(file.parsed_data[section].keys).to contain_exactly(*patterns)
expect(file.parsed_data[section].values.detect { |entry| entry.section != section }).to be_nil
end
it "assigns the correct owners for each entry" do
extracted_owners = file.parsed_data[section].values.collect(&:owner_line).uniq
expect(extracted_owners).to contain_exactly(*owners)
end
end
end end
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment