summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Lopez <james@jameslopez.es>2018-07-10 11:40:39 +0200
committerJames Lopez <james@jameslopez.es>2018-07-10 11:40:39 +0200
commit4c7b120acf503e087d935fce2fe5af3f77d00d1e (patch)
treef4c3742103acbf262d3539d301f8adbd3f612399
parent0ed8f3490e037d451841ec0e6fe226b9e62e8466 (diff)
downloadgitlab-ce-4c7b120acf503e087d935fce2fe5af3f77d00d1e.tar.gz
add upload manager and spec
-rw-r--r--lib/gitlab/import_export/uploads_manager.rb62
-rw-r--r--spec/lib/gitlab/import_export/uploads_manager_spec.rb40
2 files changed, 102 insertions, 0 deletions
diff --git a/lib/gitlab/import_export/uploads_manager.rb b/lib/gitlab/import_export/uploads_manager.rb
new file mode 100644
index 00000000000..b229ab12291
--- /dev/null
+++ b/lib/gitlab/import_export/uploads_manager.rb
@@ -0,0 +1,62 @@
+module Gitlab
+ module ImportExport
+ class UploadsManager
+ include Gitlab::ImportExport::CommandLineUtil
+
+ def initialize(project:, shared:, relative_export_path: 'uploads', from: nil)
+ @project = project
+ @shared = shared
+ @relative_export_path = relative_export_path
+ @from = from || default_uploads_path
+ end
+
+ def copy
+ copy_files(@from, uploads_export_path) if File.directory?(@from)
+
+ copy_from_object_storage
+ end
+
+ private
+
+ def copy_from_object_storage
+ return unless Gitlab::ImportExport.object_storage?
+ return if uploads.empty?
+
+ mkdir_p(uploads_export_path)
+
+ uploads.each do |upload_model|
+ next unless upload_model.file
+ next if upload_model.upload.local? # Already copied
+
+ download_and_copy(upload_model)
+ end
+ end
+
+ def default_uploads_path
+ FileUploader.absolute_base_dir(@project)
+ end
+
+ def uploads_export_path
+ @uploads_export_path ||= File.join(@shared.export_path, @relative_export_path)
+ end
+
+ def uploads
+ @uploads ||= begin
+ if @relative_export_path == 'avatar'
+ [@project.avatar].compact
+ else
+ (@project.uploads - [@project.avatar&.upload]).map(&:build_uploader)
+ end
+ end
+ end
+
+ def download_and_copy(upload)
+ upload_path = File.join(uploads_export_path, upload.filename)
+
+ File.open(upload_path, 'w') do |file|
+ IO.copy_stream(URI.parse(upload.file.url).open, file)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/import_export/uploads_manager_spec.rb b/spec/lib/gitlab/import_export/uploads_manager_spec.rb
new file mode 100644
index 00000000000..dcb065fef24
--- /dev/null
+++ b/spec/lib/gitlab/import_export/uploads_manager_spec.rb
@@ -0,0 +1,40 @@
+require 'spec_helper'
+
+describe Gitlab::ImportExport::UploadsManager do
+ let(:shared) { project.import_export_shared }
+ let(:export_path) { "#{Dir.tmpdir}/project_tree_saver_spec" }
+ let(:project) { create(:project) }
+
+ subject(:manager) { described_class.new(project: project, shared: shared) }
+
+ before do
+ allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path)
+ FileUtils.mkdir_p(shared.export_path)
+ end
+
+ after do
+ FileUtils.rm_rf(shared.export_path)
+ end
+
+ describe '#copy' do
+ context 'when the project has uploads locally stored' do
+ let(:upload) { create(:upload) }
+
+ before do
+ project.uploads << upload
+ end
+
+ it 'does not cause errors' do
+ manager.copy
+
+ expect(shared.errors).to be_empty
+ end
+
+ it 'copies the file in the correct location when there is an upload' do
+ manager.copy
+
+ expect(File).to exist("#{shared.export_path}/uploads/#{File.basename(upload.path)}")
+ end
+ end
+ end
+end