Commit 1ca9784e authored by Douwe Maan's avatar Douwe Maan

Merge branch 'id-groups-in-codeowners' into 'master'

Backport for EE's "Allow adding groups to CODEOWNERS file"

See merge request gitlab-org/gitlab-ce!29533
parents 97b2a3cc ae7041d4
...@@ -63,6 +63,8 @@ class Group < Namespace ...@@ -63,6 +63,8 @@ class Group < Namespace
after_save :update_two_factor_requirement after_save :update_two_factor_requirement
after_update :path_changed_hook, if: :saved_change_to_path? after_update :path_changed_hook, if: :saved_change_to_path?
scope :with_users, -> { includes(:users) }
class << self class << self
def sort_by_attribute(method) def sort_by_attribute(method)
if method == 'storage_size_desc' if method == 'storage_size_desc'
......
# Code Owners **[STARTER]** # Code Owners **[STARTER]**
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/6916) > - [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/6916)
in [GitLab Starter](https://about.gitlab.com/pricing/) 11.3. in [GitLab Starter](https://about.gitlab.com/pricing/) 11.3.
> - [Support for group namespaces](https://gitlab.com/gitlab-org/gitlab-ce/issues/53182) added in GitLab Starter 12.1.
You can use a `CODEOWNERS` file to specify users that are responsible You can use a `CODEOWNERS` file to specify users or
for certain files in a repository. [shared groups](members/share_project_with_groups.md)
that are responsible for certain files in a repository.
You can choose and add the `CODEOWNERS` file in three places: You can choose and add the `CODEOWNERS` file in three places:
...@@ -25,7 +27,8 @@ the given file. ...@@ -25,7 +27,8 @@ the given file.
Files can be specified using the same kind of patterns you would use Files can be specified using the same kind of patterns you would use
in the `.gitignore` file followed by the `@username` or email of one in the `.gitignore` file followed by the `@username` or email of one
or more users that should be owners of the file. or more users or by the `@name` of one or more groups that should
be owners of the file.
The order in which the paths are defined is significant: the last The order in which the paths are defined is significant: the last
pattern that matches a given path will be used to find the code pattern that matches a given path will be used to find the code
...@@ -63,6 +66,10 @@ CODEOWNERS @multiple @owners @tab-separated ...@@ -63,6 +66,10 @@ CODEOWNERS @multiple @owners @tab-separated
# owner for the LICENSE file # owner for the LICENSE file
LICENSE @legal this_does_not_match janedoe@gitlab.com LICENSE @legal this_does_not_match janedoe@gitlab.com
# Group names can be used to match groups and nested groups to specify
# them as owners for a file
README @group @group/with-nested/subgroup
# Ending a path in a `/` will specify the code owners for every file # Ending a path in a `/` will specify the code owners for every file
# nested in that directory, on any level # nested in that directory, on any level
/docs/ @all-docs /docs/ @all-docs
......
# frozen_string_literal: true
# This class extracts all users found in a piece of text by the username or the
# email address
module Gitlab
class UserExtractor
# Not using `Devise.email_regexp` to filter out any chars that an email
# does not end with and not pinning the email to a start of end of a string.
EMAIL_REGEXP = /(?<email>([^@\s]+@[^@\s]+(?<!\W)))/.freeze
USERNAME_REGEXP = User.reference_pattern
def initialize(text)
# EE passes an Array to `text` in a few places, so we want to support both
# here.
@text = Array(text).join(' ')
end
def users
return User.none unless @text.present?
return User.none if references.empty?
@users ||= User.from_union(union_relations)
end
def usernames
matches[:usernames]
end
def emails
matches[:emails]
end
def references
@references ||= matches.values.flatten
end
def matches
@matches ||= {
emails: @text.scan(EMAIL_REGEXP).flatten.uniq,
usernames: @text.scan(USERNAME_REGEXP).flatten.uniq
}
end
private
def union_relations
relations = []
relations << User.by_any_email(emails) if emails.any?
relations << User.by_username(usernames) if usernames.any?
relations
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::UserExtractor do
let(:text) do
<<~TXT
This is a long texth that mentions some users.
@user-1, @user-2 and user@gitlab.org take a walk in the park.
There they meet @user-4 that was out with other-user@gitlab.org.
@user-1 thought it was late, so went home straight away
TXT
end
subject(:extractor) { described_class.new(text) }
describe '#users' do
it 'returns an empty relation when nil was passed' do
extractor = described_class.new(nil)
expect(extractor.users).to be_empty
expect(extractor.users).to be_a(ActiveRecord::Relation)
end
it 'returns the user case insensitive for usernames' do
user = create(:user, username: "USER-4")
expect(extractor.users).to include(user)
end
it 'returns users by primary email' do
user = create(:user, email: 'user@gitlab.org')
expect(extractor.users).to include(user)
end
it 'returns users by secondary email' do
user = create(:email, email: 'other-user@gitlab.org').user
expect(extractor.users).to include(user)
end
context 'input as array of strings' do
it 'is treated as one string' do
extractor = described_class.new(text.lines)
user_1 = create(:user, username: "USER-1")
user_4 = create(:user, username: "USER-4")
user_email = create(:user, email: 'user@gitlab.org')
expect(extractor.users).to contain_exactly(user_1, user_4, user_email)
end
end
end
describe '#matches' do
it 'includes all mentioned email adresses' do
expect(extractor.matches[:emails]).to contain_exactly('user@gitlab.org', 'other-user@gitlab.org')
end
it 'includes all mentioned usernames' do
expect(extractor.matches[:usernames]).to contain_exactly('user-1', 'user-2', 'user-4')
end
context 'input has no matching e-mail or usernames' do
it 'returns an empty list of users' do
extractor = described_class.new('My test')
expect(extractor.users).to be_empty
end
end
end
describe '#references' do
it 'includes all user-references once' do
expect(extractor.references).to contain_exactly('user-1', 'user-2', 'user@gitlab.org', 'user-4', 'other-user@gitlab.org')
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