Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2020-12-21 09:10:07 +00:00
parent 020afca749
commit 081c20deca
9 changed files with 123 additions and 117 deletions

View file

@ -4,6 +4,7 @@ import {
DIFF_FILE_MANUAL_COLLAPSE, DIFF_FILE_MANUAL_COLLAPSE,
DIFF_FILE_AUTOMATIC_COLLAPSE, DIFF_FILE_AUTOMATIC_COLLAPSE,
} from '../constants'; } from '../constants';
import { getDerivedMergeRequestInformation } from './merge_request';
import { uuids } from './uuids'; import { uuids } from './uuids';
function fileSymlinkInformation(file, fileList) { function fileSymlinkInformation(file, fileList) {
@ -34,8 +35,12 @@ function collapsed(file) {
} }
function identifier(file) { function identifier(file) {
const { userOrGroup, project, id } = getDerivedMergeRequestInformation({
endpoint: file.load_collapsed_diff_url,
});
return uuids({ return uuids({
seeds: [file.file_identifier_hash, file.blob?.id], seeds: [userOrGroup, project, id, file.file_identifier_hash, file.blob?.id],
})[0]; })[0];
} }
@ -48,10 +53,10 @@ export function prepareRawDiffFile({ file, allFiles, meta = false }) {
}, },
}; };
// It's possible, but not confirmed, that `content_sha` isn't available sometimes // It's possible, but not confirmed, that `blob.id` isn't available sometimes
// See: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49506#note_464692057 // See: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49506#note_464692057
// We don't want duplicate IDs if that's the case, so we just don't assign an ID // We don't want duplicate IDs if that's the case, so we just don't assign an ID
if (!meta && file.blob?.id) { if (!meta && file.blob?.id && file.load_collapsed_diff_url) {
additionalProperties.id = identifier(file); additionalProperties.id = identifier(file);
} }

View file

@ -1,10 +1,20 @@
const endpointRE = /^(\/?(.+?)\/(.+?)\/-\/merge_requests\/(\d+)).*$/i;
export function getDerivedMergeRequestInformation({ endpoint } = {}) { export function getDerivedMergeRequestInformation({ endpoint } = {}) {
const mrPath = endpoint let mrPath;
?.split('/') let userOrGroup;
.slice(0, -1) let project;
.join('/'); let id;
const matches = endpointRE.exec(endpoint);
if (matches) {
[, mrPath, userOrGroup, project, id] = matches;
}
return { return {
mrPath, mrPath,
userOrGroup,
project,
id,
}; };
} }

View file

@ -26,76 +26,6 @@ module VisibilityLevelHelper
end end
end end
def project_visibility_level_description(level)
case level
when Gitlab::VisibilityLevel::PRIVATE
_("Project access must be granted explicitly to each user. If this project is part of a group, access will be granted to members of the group.")
when Gitlab::VisibilityLevel::INTERNAL
_("The project can be accessed by any logged in user except external users.")
when Gitlab::VisibilityLevel::PUBLIC
_("The project can be accessed without any authentication.")
end
end
def group_visibility_level_description(level)
case level
when Gitlab::VisibilityLevel::PRIVATE
_("The group and its projects can only be viewed by members.")
when Gitlab::VisibilityLevel::INTERNAL
_("The group and any internal projects can be viewed by any logged in user except external users.")
when Gitlab::VisibilityLevel::PUBLIC
_("The group and any public projects can be viewed without any authentication.")
end
end
# Note: these messages closely mirror the form validation strings found in the project
# model and any changes or additons to these may also need to be made there.
def disallowed_project_visibility_level_description(level, project)
level_name = Gitlab::VisibilityLevel.level_name(level).downcase
reasons = []
instructions = []
unless project.visibility_level_allowed_as_fork?(level)
reasons << "the fork source project has lower visibility"
end
unless project.visibility_level_allowed_by_group?(level)
errors = visibility_level_errors_for_group(project.group, level_name)
reasons << errors[:reason]
instructions << errors[:instruction]
end
reasons = reasons.any? ? ' because ' + reasons.to_sentence : ''
"This project cannot be #{level_name}#{reasons}.#{instructions.join}".html_safe
end
# Note: these messages closely mirror the form validation strings found in the group
# model and any changes or additons to these may also need to be made there.
def disallowed_group_visibility_level_description(level, group)
level_name = Gitlab::VisibilityLevel.level_name(level).downcase
reasons = []
instructions = []
unless group.visibility_level_allowed_by_projects?(level)
reasons << "it contains projects with higher visibility"
end
unless group.visibility_level_allowed_by_sub_groups?(level)
reasons << "it contains sub-groups with higher visibility"
end
unless group.visibility_level_allowed_by_parent?(level)
errors = visibility_level_errors_for_group(group.parent, level_name)
reasons << errors[:reason]
instructions << errors[:instruction]
end
reasons = reasons.any? ? ' because ' + reasons.to_sentence : ''
"This group cannot be #{level_name}#{reasons}.#{instructions.join}".html_safe
end
def visibility_icon_description(form_model) def visibility_icon_description(form_model)
if form_model.respond_to?(:visibility_level_allowed_as_fork?) if form_model.respond_to?(:visibility_level_allowed_as_fork?)
project_visibility_icon_description(form_model.visibility_level) project_visibility_icon_description(form_model.visibility_level)
@ -104,14 +34,6 @@ module VisibilityLevelHelper
end end
end end
def group_visibility_icon_description(level)
"#{visibility_level_label(level)} - #{group_visibility_level_description(level)}"
end
def project_visibility_icon_description(level)
"#{visibility_level_label(level)} - #{project_visibility_level_description(level)}"
end
def visibility_level_label(level) def visibility_level_label(level)
# The visibility level can be: # The visibility level can be:
# 'VisibilityLevel|Private', 'VisibilityLevel|Internal', 'VisibilityLevel|Public' # 'VisibilityLevel|Private', 'VisibilityLevel|Internal', 'VisibilityLevel|Public'
@ -203,11 +125,33 @@ module VisibilityLevelHelper
current_level current_level
end end
def visibility_level_errors_for_group(group, level_name) def project_visibility_level_description(level)
group_name = link_to group.name, group_path(group) case level
change_visibility = link_to 'change the visibility', edit_group_path(group) when Gitlab::VisibilityLevel::PRIVATE
_("Project access must be granted explicitly to each user. If this project is part of a group, access will be granted to members of the group.")
when Gitlab::VisibilityLevel::INTERNAL
_("The project can be accessed by any logged in user except external users.")
when Gitlab::VisibilityLevel::PUBLIC
_("The project can be accessed without any authentication.")
end
end
{ reason: "the visibility of #{group_name} is #{group.visibility}", def group_visibility_level_description(level)
instruction: " To make this group #{level_name}, you must first #{change_visibility} of the parent group." } case level
when Gitlab::VisibilityLevel::PRIVATE
_("The group and its projects can only be viewed by members.")
when Gitlab::VisibilityLevel::INTERNAL
_("The group and any internal projects can be viewed by any logged in user except external users.")
when Gitlab::VisibilityLevel::PUBLIC
_("The group and any public projects can be viewed without any authentication.")
end
end
def project_visibility_icon_description(level)
"#{visibility_level_label(level)} - #{project_visibility_level_description(level)}"
end
def group_visibility_icon_description(level)
"#{visibility_level_label(level)} - #{group_visibility_level_description(level)}"
end end
end end

View file

@ -493,6 +493,8 @@ An alternative is the open source community-maintained tool [BFG](https://rtyley
Keep in mind that these tools are faster because they do not provide the same Keep in mind that these tools are faster because they do not provide the same
feature set as `git filter-branch` does, but focus on specific use cases. feature set as `git filter-branch` does, but focus on specific use cases.
Refer [Reduce repository size](../../../user/project/repository/reducing_the_repo_size_using_git.md) page to know more about purging files from repository history & GitLab storage.
## Conclusion ## Conclusion
There are various options of undoing your work with any version control system, but There are various options of undoing your work with any version control system, but

View file

@ -94,6 +94,7 @@ module Gitlab
when :engineering_productivity when :engineering_productivity
return false unless role[/Engineering Productivity/] return false unless role[/Engineering Productivity/]
return true if kind == :reviewer return true if kind == :reviewer
return true if capabilities(project).include?("#{kind} engineering_productivity")
capabilities(project).include?("#{kind} backend") capabilities(project).include?("#{kind} backend")
else else

View file

@ -1,6 +1,8 @@
import { prepareRawDiffFile } from '~/diffs/utils/diff_file'; import { prepareRawDiffFile } from '~/diffs/utils/diff_file';
function getDiffFiles() { function getDiffFiles() {
const loadFull = 'namespace/project/-/merge_requests/12345/diff_for_path?file_identifier=abc';
return [ return [
{ {
blob: { blob: {
@ -8,6 +10,7 @@ function getDiffFiles() {
}, },
file_hash: 'ABC', // This file is just a normal file file_hash: 'ABC', // This file is just a normal file
file_identifier_hash: 'ABC1', file_identifier_hash: 'ABC1',
load_collapsed_diff_url: loadFull,
}, },
{ {
blob: { blob: {
@ -15,6 +18,7 @@ function getDiffFiles() {
}, },
file_hash: 'DEF', // This file replaces a symlink file_hash: 'DEF', // This file replaces a symlink
file_identifier_hash: 'DEF1', file_identifier_hash: 'DEF1',
load_collapsed_diff_url: loadFull,
a_mode: '0', a_mode: '0',
b_mode: '0755', b_mode: '0755',
}, },
@ -24,6 +28,7 @@ function getDiffFiles() {
}, },
file_hash: 'DEF', // This symlink is replaced by a file file_hash: 'DEF', // This symlink is replaced by a file
file_identifier_hash: 'DEF2', file_identifier_hash: 'DEF2',
load_collapsed_diff_url: loadFull,
a_mode: '120000', a_mode: '120000',
b_mode: '0', b_mode: '0',
}, },
@ -33,6 +38,7 @@ function getDiffFiles() {
}, },
file_hash: 'GHI', // This symlink replaces a file file_hash: 'GHI', // This symlink replaces a file
file_identifier_hash: 'GHI1', file_identifier_hash: 'GHI1',
load_collapsed_diff_url: loadFull,
a_mode: '0', a_mode: '0',
b_mode: '120000', b_mode: '120000',
}, },
@ -42,6 +48,7 @@ function getDiffFiles() {
}, },
file_hash: 'GHI', // This file is replaced by a symlink file_hash: 'GHI', // This file is replaced by a symlink
file_identifier_hash: 'GHI2', file_identifier_hash: 'GHI2',
load_collapsed_diff_url: loadFull,
a_mode: '0755', a_mode: '0755',
b_mode: '0', b_mode: '0',
}, },
@ -86,11 +93,11 @@ describe('diff_file utilities', () => {
it.each` it.each`
fileIndex | id fileIndex | id
${0} | ${'8dcd585e-a421-4dab-a04e-6f88c81b7b4c'} ${0} | ${'68296a4f-f1c7-445a-bd0e-6e3b02c4eec0'}
${1} | ${'3f178b78-392b-44a4-bd7d-5d6192208a97'} ${1} | ${'051c9bb8-cdba-4eb7-b8d1-508906e6d8ba'}
${2} | ${'3d9e1354-cddf-4a11-8234-f0413521b2e5'} ${2} | ${'ed3d53d5-5da0-412d-a3c6-7213f84e88d3'}
${3} | ${'460f005b-d29d-43c1-9a08-099a7c7f08de'} ${3} | ${'39d998dc-bc69-4b19-a6af-41e4369c2bd5'}
${4} | ${'d8c89733-6ce1-4455-ae3d-f8aad6ee99f9'} ${4} | ${'7072d115-ce39-423c-8346-9fcad58cd68e'}
`('sets the file id properly { id: $id } on normal diff files', ({ fileIndex, id }) => { `('sets the file id properly { id: $id } on normal diff files', ({ fileIndex, id }) => {
const preppedFile = prepareRawDiffFile({ const preppedFile = prepareRawDiffFile({
file: files[fileIndex], file: files[fileIndex],
@ -122,5 +129,18 @@ describe('diff_file utilities', () => {
expect(preppedFile).not.toHaveProp('id'); expect(preppedFile).not.toHaveProp('id');
}); });
it('does not set the id property if the file is missing a `load_collapsed_diff_url` property', () => {
const fileMissingContentSha = { ...files[0] };
delete fileMissingContentSha.load_collapsed_diff_url;
const preppedFile = prepareRawDiffFile({
file: fileMissingContentSha,
allFiles: files,
});
expect(preppedFile).not.toHaveProp('id');
});
}); });
}); });

View file

@ -2,16 +2,28 @@ import { getDerivedMergeRequestInformation } from '~/diffs/utils/merge_request';
import { diffMetadata } from '../mock_data/diff_metadata'; import { diffMetadata } from '../mock_data/diff_metadata';
describe('Merge Request utilities', () => { describe('Merge Request utilities', () => {
const derivedMrInfo = {
mrPath: '/gitlab-org/gitlab-test/-/merge_requests/4',
userOrGroup: 'gitlab-org',
project: 'gitlab-test',
id: '4',
};
const unparseableEndpoint = {
mrPath: undefined,
userOrGroup: undefined,
project: undefined,
id: undefined,
};
describe('getDerivedMergeRequestInformation', () => { describe('getDerivedMergeRequestInformation', () => {
const endpoint = `${diffMetadata.latest_version_path}.json?searchParam=irrelevant`; const endpoint = `${diffMetadata.latest_version_path}.json?searchParam=irrelevant`;
const mrPath = diffMetadata.latest_version_path.replace(/\/diffs$/, '');
it.each` it.each`
argument | response argument | response
${{ endpoint }} | ${{ mrPath }} ${{ endpoint }} | ${derivedMrInfo}
${{}} | ${{ mrPath: undefined }} ${{}} | ${unparseableEndpoint}
${{ endpoint: undefined }} | ${{ mrPath: undefined }} ${{ endpoint: undefined }} | ${unparseableEndpoint}
${{ endpoint: null }} | ${{ mrPath: undefined }} ${{ endpoint: null }} | ${unparseableEndpoint}
`('generates the correct derived results based on $argument', ({ argument, response }) => { `('generates the correct derived results based on $argument', ({ argument, response }) => {
expect(getDerivedMergeRequestInformation(argument)).toStrictEqual(response); expect(getDerivedMergeRequestInformation(argument)).toStrictEqual(response);
}); });

View file

@ -35,29 +35,33 @@ RSpec.describe VisibilityLevelHelper do
describe 'visibility_level_description' do describe 'visibility_level_description' do
context 'used with a Project' do context 'used with a Project' do
it 'delegates projects to #project_visibility_level_description' do let(:descriptions) do
expect(visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, project)) [
.to match /project/i visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, project),
visibility_level_description(Gitlab::VisibilityLevel::INTERNAL, project),
visibility_level_description(Gitlab::VisibilityLevel::PUBLIC, project)
]
end
it 'returns different project related descriptions depending on visibility level' do
expect(descriptions.uniq.size).to eq(descriptions.size)
expect(descriptions).to all match /project/i
end end
end end
context 'used with a Group' do context 'used with a Group' do
it 'delegates groups to #group_visibility_level_description' do let(:descriptions) do
expect(visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, group)) [
.to match /group/i visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, group),
visibility_level_description(Gitlab::VisibilityLevel::INTERNAL, group),
visibility_level_description(Gitlab::VisibilityLevel::PUBLIC, group)
]
end end
end
end
describe "#project_visibility_level_description" do it 'returns different group related descriptions depending on visibility level' do
it "describes private projects" do expect(descriptions.uniq.size).to eq(descriptions.size)
expect(project_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE)) expect(descriptions).to all match /group/i
.to eq _('Project access must be granted explicitly to each user. If this project is part of a group, access will be granted to members of the group.') end
end
it "describes public projects" do
expect(project_visibility_level_description(Gitlab::VisibilityLevel::PUBLIC))
.to eq _('The project can be accessed without any authentication.')
end end
end end

View file

@ -121,6 +121,14 @@ RSpec.describe Gitlab::Danger::Teammate do
end end
end end
context 'when capabilities include maintainer engineering productivity' do
let(:capabilities) { ['maintainer engineering_productivity'] }
it '#maintainer? returns true' do
expect(subject.maintainer?(project, :engineering_productivity, labels)).to be_truthy
end
end
context 'when capabilities include trainee_maintainer backend' do context 'when capabilities include trainee_maintainer backend' do
let(:capabilities) { ['trainee_maintainer backend'] } let(:capabilities) { ['trainee_maintainer backend'] }