Commit c975e1d9 authored by Nick Thomas's avatar Nick Thomas

Merge branch '217829-extract-the-code-owner-validation-logic-from-diffcheck' into 'master'

Extract the code owner validation logic from DiffCheck

Closes #217829

See merge request gitlab-org/gitlab!32225
parents d27fb038 7ae1b165
...@@ -36,25 +36,10 @@ module EE ...@@ -36,25 +36,10 @@ module EE
def validate_code_owners def validate_code_owners
lambda do |paths| lambda do |paths|
loader = ::Gitlab::CodeOwners::Loader.new(project, branch_name, paths) validator = ::Gitlab::CodeOwners::Validator.new(project, branch_name, paths)
return if loader.entries.blank? validator.execute
assemble_error_msg_for_codeowner_matches(loader)
end
end end
def assemble_error_msg_for_codeowner_matches(loader)
matched_rules = loader.entries.collect { |e| "- #{e.pattern}" }
code_owner_path = project.repository.code_owners_blob(ref: branch_name).path || "CODEOWNERS"
msg = "Pushes to protected branches that contain changes to files that\n" \
"match patterns defined in `#{code_owner_path}` are disabled for\n" \
"this project. Please submit these changes via a merge request.\n\n" \
"The following pattern(s) from `#{code_owner_path}` were matched:\n" \
"#{matched_rules.join('\n')}\n"
updated_from_web? ? msg.tr("\n", " ") : msg
end end
def validate_path_locks? def validate_path_locks?
......
# frozen_string_literal: true
module Gitlab
module CodeOwners
class Validator
def initialize(project, branch_name, paths)
@project = project
@branch_name = branch_name
@paths = Array(paths)
end
def execute
return if loader.entries.blank?
assemble_error_msg_for_codeowner_matches
end
private
def assemble_error_msg_for_codeowner_matches
"Pushes to protected branches that contain changes to files that\n" \
"match patterns defined in `#{code_owner_path}` are disabled for\n" \
"this project. Please submit these changes via a merge request.\n\n" \
"The following pattern(s) from `#{code_owner_path}` were matched:\n" \
"#{matched_rules.join('\n')}\n"
end
def matched_rules
loader.entries.collect { |e| "- #{e.pattern}" }
end
def code_owner_path
@project.repository.code_owners_blob(ref: @branch_name).path || "CODEOWNERS"
end
def loader
@loader ||= ::Gitlab::CodeOwners::Loader.new(@project, @branch_name, @paths)
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::CodeOwners::Validator do
include FakeBlobHelpers
let_it_be(:group) { create(:group) }
let_it_be(:project) { create(:project, namespace: group) }
let(:codeowner_content) do
<<~CODEOWNERS
docs/* @documentation-owner
docs/CODEOWNERS @owner-1 owner2@gitlab.org @owner-3 @documentation-owner
spec/* @test-owner @test-group @test-group/nested-group
CODEOWNERS
end
let!(:owner_1) { create(:user, username: 'owner-1') }
let!(:email_owner) { create(:user, username: 'owner-2') }
let!(:owner_3) { create(:user, username: 'owner-3') }
let!(:documentation_owner) { create(:user, username: 'documentation-owner') }
let!(:test_owner) { create(:user, username: 'test-owner') }
let(:codeowner_blob) { fake_blob(path: 'CODEOWNERS', data: codeowner_content) }
let(:paths) { 'docs/CODEOWNERS' }
subject(:validator) { described_class.new(project, 'with-codeowners', paths) }
before do
project.add_developer(owner_1)
project.add_developer(email_owner)
project.add_developer(documentation_owner)
project.add_developer(test_owner)
create(:email, user: email_owner, email: 'owner2@gitlab.org')
allow(project.repository).to receive(:code_owners_blob).and_return(codeowner_blob)
end
describe "#execute" do
context "when paths match entries in the codeowners file" do
it "returns an error message" do
expect(subject.execute).to include("Pushes to protected branches")
end
end
context "when paths do not match entries in the codeowners file" do
let(:paths) { "not/a/matching/path" }
it "returns nil" do
expect(subject.execute).to be_nil
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