summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/models/repository.rb67
-rw-r--r--app/services/files/multi_service.rb15
-rw-r--r--db/fixtures/development/22_labeled_issues_seed.rb112
-rw-r--r--lib/gitlab/git/index.rb12
-rw-r--r--lib/gitlab/git/repository.rb36
-rw-r--r--spec/migrations/migrate_gcp_clusters_to_new_clusters_architectures_spec.rb32
-rw-r--r--spec/models/repository_spec.rb46
-rw-r--r--spec/services/files/multi_service_spec.rb4
8 files changed, 86 insertions, 238 deletions
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 7b8f5794a87..9c879e2006b 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -783,34 +783,30 @@ class Repository
end
def create_dir(user, path, **options)
- options[:user] = user
options[:actions] = [{ action: :create_dir, file_path: path }]
- multi_action(**options)
+ multi_action(user, **options)
end
def create_file(user, path, content, **options)
- options[:user] = user
options[:actions] = [{ action: :create, file_path: path, content: content }]
- multi_action(**options)
+ multi_action(user, **options)
end
def update_file(user, path, content, **options)
previous_path = options.delete(:previous_path)
action = previous_path && previous_path != path ? :move : :update
- options[:user] = user
options[:actions] = [{ action: action, file_path: path, previous_path: previous_path, content: content }]
- multi_action(**options)
+ multi_action(user, **options)
end
def delete_file(user, path, **options)
- options[:user] = user
options[:actions] = [{ action: :delete, file_path: path }]
- multi_action(**options)
+ multi_action(user, **options)
end
def with_cache_hooks
@@ -824,59 +820,14 @@ class Repository
result.newrev
end
- def with_branch(user, *args)
- with_cache_hooks do
- Gitlab::Git::OperationService.new(user, raw_repository).with_branch(*args) do |start_commit|
- yield start_commit
- end
- end
- end
-
- # rubocop:disable Metrics/ParameterLists
- def multi_action(
- user:, branch_name:, message:, actions:,
- author_email: nil, author_name: nil,
- start_branch_name: nil, start_project: project)
-
- with_branch(
- user,
- branch_name,
- start_branch_name: start_branch_name,
- start_repository: start_project.repository.raw_repository) do |start_commit|
-
- index = Gitlab::Git::Index.new(raw_repository)
-
- if start_commit
- index.read_tree(start_commit.rugged_commit.tree)
- parents = [start_commit.sha]
- else
- parents = []
- end
+ def multi_action(user, **options)
+ start_project = options.delete(:start_project)
- actions.each do |options|
- index.public_send(options.delete(:action), options) # rubocop:disable GitlabSecurity/PublicSend
- end
-
- options = {
- tree: index.write_tree,
- message: message,
- parents: parents
- }
- options.merge!(get_committer_and_author(user, email: author_email, name: author_name))
-
- create_commit(options)
+ if start_project
+ options[:start_repository] = start_project.repository.raw_repository
end
- end
- # rubocop:enable Metrics/ParameterLists
- def get_committer_and_author(user, email: nil, name: nil)
- committer = user_to_committer(user)
- author = Gitlab::Git.committer_hash(email: email, name: name) || committer
-
- {
- author: author,
- committer: committer
- }
+ with_cache_hooks { raw.multi_action(user, **options) }
end
def can_be_merged?(source_sha, target_branch)
diff --git a/app/services/files/multi_service.rb b/app/services/files/multi_service.rb
index 98a3e83c130..a03c59f569d 100644
--- a/app/services/files/multi_service.rb
+++ b/app/services/files/multi_service.rb
@@ -4,7 +4,7 @@ module Files
def create_commit!
repository.multi_action(
- user: current_user,
+ current_user,
message: @commit_message,
branch_name: @branch_name,
actions: params[:actions],
@@ -13,6 +13,8 @@ module Files
start_project: @start_project,
start_branch_name: @start_branch
)
+ rescue ArgumentError => e
+ raise_error(e)
end
private
@@ -20,16 +22,7 @@ module Files
def validate!
super
- params[:actions].each do |action|
- validate_action!(action)
- validate_file_status!(action)
- end
- end
-
- def validate_action!(action)
- unless Gitlab::Git::Index::ACTIONS.include?(action[:action].to_s)
- raise_error("Unknown action '#{action[:action]}'")
- end
+ params[:actions].each { |action| validate_file_status!(action) }
end
def validate_file_status!(action)
diff --git a/db/fixtures/development/22_labeled_issues_seed.rb b/db/fixtures/development/22_labeled_issues_seed.rb
deleted file mode 100644
index 3e4485c7a73..00000000000
--- a/db/fixtures/development/22_labeled_issues_seed.rb
+++ /dev/null
@@ -1,112 +0,0 @@
-# Creates a project with labeled issues for a user.
-# Run this single seed file using: rake db:seed_fu FILTER=labeled USER_ID=74.
-# If an USER_ID is not provided it will use the last created user.
-require './spec/support/sidekiq'
-
-class Gitlab::Seeder::LabeledIssues
- include ::Gitlab::Utils
-
- def initialize(user)
- @user = user
- end
-
- def seed!
- Sidekiq::Testing.inline! do
- group = create_group
- puts '.'
-
- create_projects(group)
- puts '.'
-
- create_labels(group)
- puts '.'
-
- create_issues(group)
- puts '.'
- end
-
- print '.'
- end
-
- private
-
- def create_group
- group_name = "group_of_#{@user.name}#{SecureRandom.hex(4)}"
-
- group = Group.new(
- name: group_name,
- path: group_name,
- description: FFaker::Lorem.sentence
- )
-
- group.save
-
- group.add_owner(@user)
-
- group
- end
-
- def create_projects(group)
- 5.times do
- project_name = "project_#{SecureRandom.hex(6)}"
- params = {
- namespace_id: group.id,
- name: project_name,
- description: FFaker::Lorem.sentence,
- visibility_level: Gitlab::VisibilityLevel.values.sample
- }
-
- Projects::CreateService.new(@user, params).execute
- end
- end
-
- def create_labels(group)
- group.projects.each do |project|
- 5.times do
- label_title = FFaker::Vehicle.model
- Labels::CreateService.new(title: label_title).execute(project: project)
- end
- end
-
- 10.times do
- label_title = FFaker::Product.brand
- Labels::CreateService.new(title: label_title).execute(group: group)
- end
- end
-
- def create_issues(group)
- # Get only group labels
- group_labels =
- LabelsFinder.new(@user, group_id: group.id).execute.where.not(group_id: nil)
-
- group.projects.each do |project|
- label_ids = project.labels.pluck(:id).sample(5)
- label_ids.push(*group.labels.sample(4))
-
- 50.times do
- issue_params = {
- title: FFaker::Lorem.sentence(6),
- description: FFaker::Lorem.sentence,
- state: 'opened',
- label_ids: label_ids
-
- }
-
- Issues::CreateService.new(project, @user, issue_params).execute if project.project_feature.present?
- end
- end
- end
-end
-
-Gitlab::Seeder.quiet do
- user_id = ENV['USER_ID']
-
- user =
- if user_id.present?
- User.find(user_id)
- else
- User.last
- end
-
- Gitlab::Seeder::LabeledIssues.new(user).seed!
-end
diff --git a/lib/gitlab/git/index.rb b/lib/gitlab/git/index.rb
index db532600d1b..d94082a3e30 100644
--- a/lib/gitlab/git/index.rb
+++ b/lib/gitlab/git/index.rb
@@ -10,6 +10,7 @@ module Gitlab
DEFAULT_MODE = 0o100644
ACTIONS = %w(create create_dir update move delete).freeze
+ ACTION_OPTIONS = %i(file_path previous_path content encoding).freeze
attr_reader :repository, :raw_index
@@ -20,6 +21,11 @@ module Gitlab
delegate :read_tree, :get, to: :raw_index
+ def apply(action, options)
+ validate_action!(action)
+ public_send(action, options.slice(*ACTION_OPTIONS)) # rubocop:disable GitlabSecurity/PublicSend
+ end
+
def write_tree
raw_index.write_tree(repository.rugged)
end
@@ -140,6 +146,12 @@ module Gitlab
rescue Rugged::IndexError => e
raise IndexError, e.message
end
+
+ def validate_action!(action)
+ unless ACTIONS.include?(action.to_s)
+ raise ArgumentError, "Unknown action '#{action}'"
+ end
+ end
end
end
end
diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb
index e8b1788e140..84105501d1e 100644
--- a/lib/gitlab/git/repository.rb
+++ b/lib/gitlab/git/repository.rb
@@ -1300,6 +1300,42 @@ module Gitlab
success || gitlab_projects_error
end
+ # rubocop:disable Metrics/ParameterLists
+ def multi_action(
+ user, branch_name:, message:, actions:,
+ author_email: nil, author_name: nil,
+ start_branch_name: nil, start_repository: self)
+
+ OperationService.new(user, self).with_branch(
+ branch_name,
+ start_branch_name: start_branch_name,
+ start_repository: start_repository
+ ) do |start_commit|
+ index = Gitlab::Git::Index.new(self)
+ parents = []
+
+ if start_commit
+ index.read_tree(start_commit.rugged_commit.tree)
+ parents = [start_commit.sha]
+ end
+
+ actions.each { |opts| index.apply(opts.delete(:action), opts) }
+
+ committer = user_to_committer(user)
+ author = Gitlab::Git.committer_hash(email: author_email, name: author_name) || committer
+ options = {
+ tree: index.write_tree,
+ message: message,
+ parents: parents,
+ author: author,
+ committer: committer
+ }
+
+ create_commit(options)
+ end
+ end
+ # rubocop:enable Metrics/ParameterLists
+
def gitaly_repository
Gitlab::GitalyClient::Util.repository(@storage, @relative_path, @gl_repository)
end
diff --git a/spec/migrations/migrate_gcp_clusters_to_new_clusters_architectures_spec.rb b/spec/migrations/migrate_gcp_clusters_to_new_clusters_architectures_spec.rb
index 57ee2adaaff..c81ec887ded 100644
--- a/spec/migrations/migrate_gcp_clusters_to_new_clusters_architectures_spec.rb
+++ b/spec/migrations/migrate_gcp_clusters_to_new_clusters_architectures_spec.rb
@@ -33,7 +33,7 @@ describe MigrateGcpClustersToNewClustersArchitectures, :migration do
let(:encrypted_gcp_token) { "'encrypted_gcp_token'" }
let(:encrypted_gcp_token_iv) { "'encrypted_gcp_token_iv'" }
- let(:cluster) { Clusters::Cluster.last }
+ let(:cluster) { described_class::Cluster.last }
let(:cluster_id) { cluster.id }
before do
@@ -46,12 +46,12 @@ describe MigrateGcpClustersToNewClustersArchitectures, :migration do
it 'correctly migrate to new clusters architectures' do
migrate!
- expect(Clusters::Cluster.count).to eq(1)
- expect(Clusters::Project.count).to eq(1)
- expect(Clusters::Providers::Gcp.count).to eq(1)
- expect(Clusters::Platforms::Kubernetes.count).to eq(1)
+ expect(described_class::Cluster.count).to eq(1)
+ expect(described_class::ClustersProject.count).to eq(1)
+ expect(described_class::ProvidersGcp.count).to eq(1)
+ expect(described_class::PlatformsKubernetes.count).to eq(1)
- expect(cluster.user).to eq(user)
+ expect(cluster.user_id).to eq(user.id)
expect(cluster.enabled).to be_truthy
expect(cluster.name).to eq(gcp_cluster_name.delete!("'"))
expect(cluster.provider_type).to eq('gcp')
@@ -59,7 +59,7 @@ describe MigrateGcpClustersToNewClustersArchitectures, :migration do
expect(cluster.project_ids).to include(project.id)
- expect(cluster.provider_gcp.cluster).to eq(cluster)
+ expect(cluster.provider_gcp.cluster_id).to eq(cluster.id)
expect(cluster.provider_gcp.status).to eq(status)
expect(cluster.provider_gcp.status_reason).to eq(tr(status_reason))
expect(cluster.provider_gcp.gcp_project_id).to eq(tr(gcp_project_id))
@@ -71,7 +71,7 @@ describe MigrateGcpClustersToNewClustersArchitectures, :migration do
expect(cluster.provider_gcp.encrypted_access_token).to eq(tr(encrypted_gcp_token))
expect(cluster.provider_gcp.encrypted_access_token_iv).to eq(tr(encrypted_gcp_token_iv))
- expect(cluster.platform_kubernetes.cluster).to eq(cluster)
+ expect(cluster.platform_kubernetes.cluster_id).to eq(cluster.id)
expect(cluster.platform_kubernetes.api_url).to be_nil
expect(cluster.platform_kubernetes.ca_cert).to be_nil
expect(cluster.platform_kubernetes.namespace).to eq(tr(project_namespace))
@@ -109,7 +109,7 @@ describe MigrateGcpClustersToNewClustersArchitectures, :migration do
let(:encrypted_gcp_token) { "'encrypted_gcp_token'" }
let(:encrypted_gcp_token_iv) { "'encrypted_gcp_token_iv'" }
- let(:cluster) { Clusters::Cluster.last }
+ let(:cluster) { described_class::Cluster.last }
let(:cluster_id) { cluster.id }
before do
@@ -122,12 +122,12 @@ describe MigrateGcpClustersToNewClustersArchitectures, :migration do
it 'correctly migrate to new clusters architectures' do
migrate!
- expect(Clusters::Cluster.count).to eq(1)
- expect(Clusters::Project.count).to eq(1)
- expect(Clusters::Providers::Gcp.count).to eq(1)
- expect(Clusters::Platforms::Kubernetes.count).to eq(1)
+ expect(described_class::Cluster.count).to eq(1)
+ expect(described_class::ClustersProject.count).to eq(1)
+ expect(described_class::ProvidersGcp.count).to eq(1)
+ expect(described_class::PlatformsKubernetes.count).to eq(1)
- expect(cluster.user).to eq(user)
+ expect(cluster.user_id).to eq(user.id)
expect(cluster.enabled).to be_truthy
expect(cluster.name).to eq(tr(gcp_cluster_name))
expect(cluster.provider_type).to eq('gcp')
@@ -135,7 +135,7 @@ describe MigrateGcpClustersToNewClustersArchitectures, :migration do
expect(cluster.project_ids).to include(project.id)
- expect(cluster.provider_gcp.cluster).to eq(cluster)
+ expect(cluster.provider_gcp.cluster_id).to eq(cluster.id)
expect(cluster.provider_gcp.status).to eq(status)
expect(cluster.provider_gcp.status_reason).to eq(tr(status_reason))
expect(cluster.provider_gcp.gcp_project_id).to eq(tr(gcp_project_id))
@@ -147,7 +147,7 @@ describe MigrateGcpClustersToNewClustersArchitectures, :migration do
expect(cluster.provider_gcp.encrypted_access_token).to eq(tr(encrypted_gcp_token))
expect(cluster.provider_gcp.encrypted_access_token_iv).to eq(tr(encrypted_gcp_token_iv))
- expect(cluster.platform_kubernetes.cluster).to eq(cluster)
+ expect(cluster.platform_kubernetes.cluster_id).to eq(cluster.id)
expect(cluster.platform_kubernetes.api_url).to eq('https://' + tr(endpoint))
expect(cluster.platform_kubernetes.ca_cert).to eq(tr(ca_cert))
expect(cluster.platform_kubernetes.namespace).to eq(tr(project_namespace))
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index 48a75c9885b..c0db2c1b386 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -582,38 +582,6 @@ describe Repository do
end
end
- describe '#get_committer_and_author' do
- it 'returns the committer and author data' do
- options = repository.get_committer_and_author(user)
- expect(options[:committer][:email]).to eq(user.email)
- expect(options[:author][:email]).to eq(user.email)
- end
-
- context 'when the email/name are given' do
- it 'returns an object containing the email/name' do
- options = repository.get_committer_and_author(user, email: author_email, name: author_name)
- expect(options[:author][:email]).to eq(author_email)
- expect(options[:author][:name]).to eq(author_name)
- end
- end
-
- context 'when the email is given but the name is not' do
- it 'returns the committer as the author' do
- options = repository.get_committer_and_author(user, email: author_email)
- expect(options[:author][:email]).to eq(user.email)
- expect(options[:author][:name]).to eq(user.name)
- end
- end
-
- context 'when the name is given but the email is not' do
- it 'returns nil' do
- options = repository.get_committer_and_author(user, name: author_name)
- expect(options[:author][:email]).to eq(user.email)
- expect(options[:author][:name]).to eq(user.name)
- end
- end
- end
-
describe "search_files_by_content" do
let(:results) { repository.search_files_by_content('feature', 'master') }
subject { results }
@@ -1112,16 +1080,16 @@ describe Repository do
allow_any_instance_of(Gitlab::Git::Hook).to receive(:trigger).and_return([true, ''])
end
- it 'expires branch cache' do
- expect(repository).not_to receive(:expire_exists_cache)
- expect(repository).not_to receive(:expire_root_ref_cache)
- expect(repository).not_to receive(:expire_emptiness_caches)
- expect(repository).to receive(:expire_branches_cache)
-
- repository.with_branch(user, 'new-feature') do
+ subject do
+ Gitlab::Git::OperationService.new(git_user, repository.raw_repository).with_branch('new-feature') do
new_rev
end
end
+
+ it 'returns branch_created as true' do
+ expect(subject).not_to be_repo_created
+ expect(subject).to be_branch_created
+ end
end
context 'when repository is empty' do
diff --git a/spec/services/files/multi_service_spec.rb b/spec/services/files/multi_service_spec.rb
index 2b79609930c..b9971776b33 100644
--- a/spec/services/files/multi_service_spec.rb
+++ b/spec/services/files/multi_service_spec.rb
@@ -41,7 +41,7 @@ describe Files::MultiService do
describe '#execute' do
context 'with a valid action' do
- it 'returns a hash with the :success status ' do
+ it 'returns a hash with the :success status' do
results = subject.execute
expect(results[:status]).to eq(:success)
@@ -51,7 +51,7 @@ describe Files::MultiService do
context 'with an invalid action' do
let(:action) { 'rename' }
- it 'returns a hash with the :error status ' do
+ it 'returns a hash with the :error status' do
results = subject.execute
expect(results[:status]).to eq(:error)