fixed and refactored a few things based on MR feedback
This commit is contained in:
parent
6612ca096a
commit
ce598b0541
11 changed files with 93 additions and 101 deletions
|
@ -5,10 +5,7 @@ module Projects
|
||||||
def execute(options = {})
|
def execute(options = {})
|
||||||
@shared = Gitlab::ImportExport::Shared.new(relative_path: File.join(project.path_with_namespace, 'work'))
|
@shared = Gitlab::ImportExport::Shared.new(relative_path: File.join(project.path_with_namespace, 'work'))
|
||||||
# TODO handle errors
|
# TODO handle errors
|
||||||
save_project_tree
|
save_all if [save_project_tree, bundle_repo, bundle_wiki_repo].all?
|
||||||
bundle_repo
|
|
||||||
bundle_wiki_repo
|
|
||||||
save_all
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -6,7 +6,7 @@ module Gitlab
|
||||||
File.join(storage_path, relative_path)
|
File.join(storage_path, relative_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
def project_atts
|
def project_attributes
|
||||||
%i(name path description issues_enabled wall_enabled merge_requests_enabled wiki_enabled snippets_enabled visibility_level archived)
|
%i(name path description issues_enabled wall_enabled merge_requests_enabled wiki_enabled snippets_enabled visibility_level archived)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,36 +1,31 @@
|
||||||
module Gitlab
|
module Gitlab
|
||||||
module ImportExport
|
module ImportExport
|
||||||
module CommandLineUtil
|
module CommandLineUtil
|
||||||
def tar_cf(archive:, dir:)
|
def tar_czf(archive:, dir:)
|
||||||
tar_with_options(archive: archive, dir: dir, options: 'cf')
|
tar_with_options(archive: archive, dir: dir, options: 'czf')
|
||||||
end
|
end
|
||||||
|
|
||||||
def untar_zxf(archive:, dir:)
|
def untar_zxf(archive:, dir:)
|
||||||
untar_with_options(archive: archive, dir: dir, options: 'zxf')
|
untar_with_options(archive: archive, dir: dir, options: 'zxf')
|
||||||
end
|
end
|
||||||
|
|
||||||
def untar_xf(archive:, dir:)
|
|
||||||
untar_with_options(archive: archive, dir: dir, options: 'xf')
|
|
||||||
end
|
|
||||||
|
|
||||||
def tar_czf(archive:, dir:)
|
|
||||||
tar_with_options(archive: archive, dir: dir, options: 'czf')
|
|
||||||
end
|
|
||||||
|
|
||||||
def git_bundle(git_bin_path: Gitlab.config.git.bin_path, repo_path:, bundle_path:)
|
def git_bundle(git_bin_path: Gitlab.config.git.bin_path, repo_path:, bundle_path:)
|
||||||
cmd = %W(#{git_bin_path} --git-dir=#{repo_path} bundle create #{bundle_path} --all)
|
execute(%W(#{git_bin_path} --git-dir=#{repo_path} bundle create #{bundle_path} --all))
|
||||||
_output, status = Gitlab::Popen.popen(cmd)
|
end
|
||||||
status.zero?
|
|
||||||
|
def git_unbundle(git_bin_path: Gitlab.config.git.bin_path, repo_path:, bundle_path:)
|
||||||
|
execute(%W(#{git_bin_path} clone --bare #{bundle_path} #{repo_path}))
|
||||||
end
|
end
|
||||||
|
|
||||||
def tar_with_options(archive:, dir:, options:)
|
def tar_with_options(archive:, dir:, options:)
|
||||||
cmd = %W(tar -#{options} #{archive} -C #{dir} .)
|
execute(%W(tar -#{options} #{archive} -C #{dir} .))
|
||||||
_output, status = Gitlab::Popen.popen(cmd)
|
|
||||||
status.zero?
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def untar_with_options(archive:, dir:, options:)
|
def untar_with_options(archive:, dir:, options:)
|
||||||
cmd = %W(tar -#{options} #{archive} -C #{dir})
|
execute(%W(tar -#{options} #{archive} -C #{dir}))
|
||||||
|
end
|
||||||
|
|
||||||
|
def execute(cmd)
|
||||||
_output, status = Gitlab::Popen.popen(cmd)
|
_output, status = Gitlab::Popen.popen(cmd)
|
||||||
status.zero?
|
status.zero?
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,22 +1,23 @@
|
||||||
# Class relationships to be included in the project import/export
|
# Model relationships to be included in the project import/export
|
||||||
:project_tree:
|
project_tree:
|
||||||
- :issues:
|
- issues:
|
||||||
- :notes
|
- :notes
|
||||||
- :labels
|
- :labels
|
||||||
- :milestones
|
- :milestones
|
||||||
- :snippets
|
- :snippets
|
||||||
- :releases
|
- :releases
|
||||||
- :events
|
- :events
|
||||||
- :project_members:
|
- project_members:
|
||||||
- :user
|
- :user
|
||||||
- :merge_requests:
|
- merge_requests:
|
||||||
- :merge_request_diff
|
- :merge_request_diff
|
||||||
- :notes
|
- :notes
|
||||||
- :ci_commits:
|
- ci_commits:
|
||||||
- :statuses
|
- :statuses
|
||||||
|
|
||||||
:attributes_only:
|
# Only include the following attributes for the models specified.
|
||||||
:project:
|
included_attributes:
|
||||||
|
project:
|
||||||
- :name
|
- :name
|
||||||
- :path
|
- :path
|
||||||
- :description
|
- :description
|
||||||
|
@ -27,11 +28,12 @@
|
||||||
- :snippets_enabled
|
- :snippets_enabled
|
||||||
- :visibility_level
|
- :visibility_level
|
||||||
- :archived
|
- :archived
|
||||||
:user:
|
user:
|
||||||
- :id
|
- :id
|
||||||
- :email
|
- :email
|
||||||
- :username
|
- :username
|
||||||
|
|
||||||
:attributes_except:
|
# Do not include the following attributes for the models specified.
|
||||||
:snippets:
|
excluded_attributes:
|
||||||
|
snippets:
|
||||||
- :expired_at
|
- :expired_at
|
|
@ -4,7 +4,7 @@ module Gitlab
|
||||||
extend self
|
extend self
|
||||||
|
|
||||||
def project_tree
|
def project_tree
|
||||||
{ only: atts_only[:project], include: build_hash(tree) }
|
{ only: included_attributes[:project], include: build_hash(tree) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def tree
|
def tree
|
||||||
|
@ -14,24 +14,24 @@ module Gitlab
|
||||||
private
|
private
|
||||||
|
|
||||||
def config
|
def config
|
||||||
@config ||= YAML.load_file('lib/gitlab/import_export/import_export.yml')
|
@config ||= YAML.load_file('lib/gitlab/import_export/import_export.yml').with_indifferent_access
|
||||||
end
|
end
|
||||||
|
|
||||||
def atts_only
|
def included_attributes
|
||||||
config[:attributes_only]
|
config[:included_attributes] || {}
|
||||||
end
|
end
|
||||||
|
|
||||||
def atts_except
|
def excluded_attributes
|
||||||
config[:attributes_except]
|
config[:excluded_attributes] || {}
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_hash(array)
|
def build_hash(array)
|
||||||
array.map do |el|
|
array.map do |model_object|
|
||||||
if el.is_a?(Hash)
|
if model_object.is_a?(Hash)
|
||||||
process_include(el)
|
process_include(model_object)
|
||||||
else
|
else
|
||||||
only_except_hash = check_only_and_except(el)
|
only_except_hash = check_only_and_except(model_object)
|
||||||
only_except_hash.empty? ? el : { el => only_except_hash }
|
only_except_hash.empty? ? model_object : { model_object => only_except_hash }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -82,12 +82,12 @@ module Gitlab
|
||||||
|
|
||||||
def check_only(value)
|
def check_only(value)
|
||||||
key = key_from_hash(value)
|
key = key_from_hash(value)
|
||||||
atts_only[key].nil? ? {} : { only: atts_only[key] }
|
included_attributes[key].nil? ? {} : { only: included_attributes[key] }
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_except(value)
|
def check_except(value)
|
||||||
key = key_from_hash(value)
|
key = key_from_hash(value)
|
||||||
atts_except[key].nil? ? {} : { except: atts_except[key] }
|
excluded_attributes[key].nil? ? {} : { except: excluded_attributes[key] }
|
||||||
end
|
end
|
||||||
|
|
||||||
def key_from_hash(value)
|
def key_from_hash(value)
|
||||||
|
|
|
@ -3,19 +3,13 @@ module Gitlab
|
||||||
class ProjectTreeSaver
|
class ProjectTreeSaver
|
||||||
attr_reader :full_path
|
attr_reader :full_path
|
||||||
|
|
||||||
def initialize(project: , shared: )
|
def initialize(project:, shared:)
|
||||||
@project = project
|
@project = project
|
||||||
@export_path = shared.export_path
|
@export_path = shared.export_path
|
||||||
|
@full_path = File.join(@export_path, project_filename)
|
||||||
end
|
end
|
||||||
|
|
||||||
def save
|
def save
|
||||||
@full_path = File.join(@export_path, project_filename)
|
|
||||||
save_to_disk
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def save_to_disk
|
|
||||||
FileUtils.mkdir_p(@export_path)
|
FileUtils.mkdir_p(@export_path)
|
||||||
File.write(full_path, project_json_tree)
|
File.write(full_path, project_json_tree)
|
||||||
true
|
true
|
||||||
|
@ -24,6 +18,8 @@ module Gitlab
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
# TODO remove magic keyword and move it to a shared config
|
# TODO remove magic keyword and move it to a shared config
|
||||||
def project_filename
|
def project_filename
|
||||||
"project.json"
|
"project.json"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
require 'rspec'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe Gitlab::ImportExport::ImportExportReader do
|
describe Gitlab::ImportExport::ImportExportReader do
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ describe Gitlab::ImportExport::ImportExportReader do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should generate hash from project tree config' do
|
it 'should generate hash from project tree config' do
|
||||||
allow(described_class).to receive(:config).and_return(YAML.load_file(test_config))
|
allow(described_class).to receive(:config).and_return(YAML.load_file(test_config).deep_symbolize_keys)
|
||||||
|
|
||||||
expect(described_class.project_tree).to eq(project_tree_hash)
|
expect(described_class.project_tree).to eq(project_tree_hash)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,42 +1,20 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe Gitlab::ImportExport::ProjectTreeSaver, services: true do
|
describe Gitlab::ImportExport::ProjectTreeSaver, services: true do
|
||||||
describe :save do
|
describe 'saves the project tree into a json object' do
|
||||||
|
|
||||||
# TODO refactor this into a setup method
|
|
||||||
|
|
||||||
let(:user) { create(:user) }
|
|
||||||
let(:issue) { create(:issue, assignee: user) }
|
|
||||||
let(:merge_request) { create(:merge_request) }
|
|
||||||
let(:label) { create(:label) }
|
|
||||||
let(:snippet) { create(:project_snippet) }
|
|
||||||
let(:commit_status) { create(:commit_status) }
|
|
||||||
let(:release) { create(:release) }
|
|
||||||
let!(:project) do
|
|
||||||
create(:project,
|
|
||||||
:public,
|
|
||||||
name: 'searchable_project',
|
|
||||||
issues: [issue],
|
|
||||||
merge_requests: [merge_request],
|
|
||||||
labels: [label],
|
|
||||||
snippets: [snippet],
|
|
||||||
releases: [release]
|
|
||||||
)
|
|
||||||
end
|
|
||||||
let!(:ci_commit) { create(:ci_commit, project: project, sha: merge_request.last_commit.id, ref: merge_request.source_branch, statuses: [commit_status]) }
|
|
||||||
let!(:milestone) { create(:milestone, title: "Milestone v1.2", project: project) }
|
|
||||||
let(:export_path) { "#{Dir::tmpdir}/project_tree_saver_spec" }
|
|
||||||
let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: project.path_with_namespace) }
|
let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: project.path_with_namespace) }
|
||||||
let(:project_tree_saver) { Gitlab::ImportExport::ProjectTreeSaver.new(project: project, shared: shared) }
|
let(:project_tree_saver) { described_class.new(project: project, shared: shared) }
|
||||||
let!(:issue_note) { create(:note, note: ":+1: issue", noteable: issue) }
|
let(:export_path) { "#{Dir::tmpdir}/project_tree_saver_spec" }
|
||||||
let!(:merge_request_note) { create(:note, note: ":+1: merge_request", noteable: merge_request) }
|
let(:user) { create(:user) }
|
||||||
|
let(:project) { setup_project }
|
||||||
|
|
||||||
before(:each) do
|
before do
|
||||||
project.team << [user, :master]
|
project.team << [user, :master]
|
||||||
allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path)
|
allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
after(:each) do
|
after do
|
||||||
FileUtils.rm_rf(export_path)
|
FileUtils.rm_rf(export_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -109,6 +87,30 @@ describe Gitlab::ImportExport::ProjectTreeSaver, services: true do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def setup_project
|
||||||
|
issue = create(:issue, assignee: user)
|
||||||
|
merge_request = create(:merge_request)
|
||||||
|
label = create(:label)
|
||||||
|
snippet = create(:project_snippet)
|
||||||
|
commit_status = create(:commit_status)
|
||||||
|
release = create(:release)
|
||||||
|
|
||||||
|
project = create(:project,
|
||||||
|
:public,
|
||||||
|
issues: [issue],
|
||||||
|
merge_requests: [merge_request],
|
||||||
|
labels: [label],
|
||||||
|
snippets: [snippet],
|
||||||
|
releases: [release]
|
||||||
|
)
|
||||||
|
|
||||||
|
create(:ci_commit, project: project, sha: merge_request.last_commit.id, ref: merge_request.source_branch, statuses: [commit_status])
|
||||||
|
create(:milestone, project: project)
|
||||||
|
create(:note, noteable: issue)
|
||||||
|
create(:note, noteable: merge_request)
|
||||||
|
project
|
||||||
|
end
|
||||||
|
|
||||||
def project_json(filename)
|
def project_json(filename)
|
||||||
JSON.parse(IO.read(filename))
|
JSON.parse(IO.read(filename))
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe Gitlab::ImportExport::RepoBundler, services: true do
|
describe Gitlab::ImportExport::RepoBundler, services: true do
|
||||||
describe :bundle do
|
describe 'bundle a project Git repo' do
|
||||||
|
|
||||||
let(:user) { create(:user) }
|
let(:user) { create(:user) }
|
||||||
let!(:project) { create(:project, :public, name: 'searchable_project') }
|
let!(:project) { create(:project, :public, name: 'searchable_project') }
|
||||||
let(:export_path) { "#{Dir::tmpdir}/project_tree_saver_spec" }
|
let(:export_path) { "#{Dir::tmpdir}/project_tree_saver_spec" }
|
||||||
let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: project.path_with_namespace) }
|
let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: project.path_with_namespace) }
|
||||||
let(:bundler) { Gitlab::ImportExport::RepoBundler.new(project: project, shared: shared) }
|
let(:bundler) { described_class.new(project: project, shared: shared) }
|
||||||
|
|
||||||
before(:each) do
|
before do
|
||||||
project.team << [user, :master]
|
project.team << [user, :master]
|
||||||
allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path)
|
allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
after(:each) do
|
after do
|
||||||
FileUtils.rm_rf(export_path)
|
FileUtils.rm_rf(export_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe Gitlab::ImportExport::WikiRepoBundler, services: true do
|
describe Gitlab::ImportExport::WikiRepoBundler, services: true do
|
||||||
describe :bundle do
|
describe 'bundle a wiki Git repo' do
|
||||||
|
|
||||||
let(:user) { create(:user) }
|
let(:user) { create(:user) }
|
||||||
let!(:project) { create(:project, :public, name: 'searchable_project') }
|
let!(:project) { create(:project, :public, name: 'searchable_project') }
|
||||||
let(:export_path) { "#{Dir::tmpdir}/project_tree_saver_spec" }
|
let(:export_path) { "#{Dir::tmpdir}/project_tree_saver_spec" }
|
||||||
let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: project.path_with_namespace) }
|
let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: project.path_with_namespace) }
|
||||||
let(:wiki_bundler) { Gitlab::ImportExport::WikiRepoBundler.new(project: project, shared: shared) }
|
let(:wiki_bundler) { described_class.new(project: project, shared: shared) }
|
||||||
let!(:project_wiki) { ProjectWiki.new(project, user) }
|
let!(:project_wiki) { ProjectWiki.new(project, user) }
|
||||||
|
|
||||||
before(:each) do
|
before do
|
||||||
project.team << [user, :master]
|
project.team << [user, :master]
|
||||||
allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path)
|
allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path)
|
||||||
project_wiki.wiki
|
project_wiki.wiki
|
||||||
project_wiki.create_page("index", "test content")
|
project_wiki.create_page("index", "test content")
|
||||||
end
|
end
|
||||||
|
|
||||||
after(:each) do
|
after do
|
||||||
FileUtils.rm_rf(export_path)
|
FileUtils.rm_rf(export_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
# Class relationships to be included in the project import/export
|
# Class relationships to be included in the project import/export
|
||||||
:project_tree:
|
project_tree:
|
||||||
- :issues
|
- :issues
|
||||||
- :labels
|
- :labels
|
||||||
- :merge_requests:
|
- merge_requests:
|
||||||
- :merge_request_diff
|
- :merge_request_diff
|
||||||
- :merge_request_test
|
- :merge_request_test
|
||||||
- :commit_statuses:
|
- commit_statuses:
|
||||||
- :commit
|
- :commit
|
||||||
|
|
||||||
:attributes_only:
|
included_attributes:
|
||||||
:project:
|
project:
|
||||||
- :name
|
- :name
|
||||||
- :path
|
- :path
|
||||||
:merge_requests:
|
merge_requests:
|
||||||
- :id
|
- :id
|
||||||
|
|
||||||
:attributes_except:
|
excluded_attributes:
|
||||||
:merge_requests:
|
merge_requests:
|
||||||
- :iid
|
- :iid
|
Loading…
Reference in a new issue