diff --git a/lib/directory_helper.rb b/lib/directory_helper.rb new file mode 100644 index 000000000..ec8eaccc5 --- /dev/null +++ b/lib/directory_helper.rb @@ -0,0 +1,22 @@ +module DirectoryHelper + + def tmp_directory(prefix) + directory_cache[prefix] ||= begin + f = File.join( Rails.root, 'tmp', Time.now.strftime("#{prefix}%Y%m%d%H%M%S") ) + FileUtils.mkdir_p(f) unless Dir[f].present? + f + end + end + + def remove_tmp_directory(prefix) + tmp_directory_name = directory_cache[prefix] || '' + directory_cache.delete(prefix) + FileUtils.rm_rf(tmp_directory_name) if Dir[tmp_directory_name].present? + end + + private + def directory_cache + @directory_cache ||= {} + end + +end diff --git a/lib/export/json_encoder.rb b/lib/export/json_encoder.rb index bc2e945b5..a27bde341 100644 --- a/lib/export/json_encoder.rb +++ b/lib/export/json_encoder.rb @@ -1,23 +1,18 @@ +require_dependency 'directory_helper' + module Export class SchemaArgumentsError < RuntimeError; end class JsonEncoder + include DirectoryHelper def initialize @table_data = {} end - def tmp_directory - @tmp_directory ||= begin - f = File.join( Rails.root, 'tmp', Time.now.strftime('export%Y%m%d%H%M%S') ) - Dir.mkdir(f) unless Dir[f].present? - f - end - end - def json_output_stream - @json_output_stream ||= File.new( File.join( tmp_directory, 'tables.json' ), 'w+b' ) + @json_output_stream ||= File.new( File.join( tmp_directory('export'), 'tables.json' ), 'w+b' ) end def write_schema_info(args) @@ -59,15 +54,12 @@ module Export :mode => :compat) ) json_output_stream.close - @filenames = [File.join( tmp_directory, 'tables.json' )] + @filenames = [File.join( tmp_directory('export'), 'tables.json' )] end def filenames @filenames ||= [] end - def cleanup_temp - FileUtils.rm_rf(tmp_directory) if Dir[tmp_directory].present? - end end end diff --git a/lib/jobs/exporter.rb b/lib/jobs/exporter.rb index 1ed4d3403..c2546d637 100644 --- a/lib/jobs/exporter.rb +++ b/lib/jobs/exporter.rb @@ -75,7 +75,7 @@ module Jobs if @encoder @encoder.finish create_tar_file - @encoder.cleanup_temp + @encoder.remove_tmp_directory('export') end ensure Export.set_export_is_not_running diff --git a/lib/jobs/importer.rb b/lib/jobs/importer.rb index 01b2bdcb7..4c105ba40 100644 --- a/lib/jobs/importer.rb +++ b/lib/jobs/importer.rb @@ -1,6 +1,7 @@ require_dependency 'import/json_decoder' require_dependency 'import/import' require_dependency 'import/adapter/base' +require_dependency 'directory_helper' (Dir.entries(File.join( Rails.root, 'lib', 'import', 'adapter' )) - ['.', '..', 'base.rb']).each do |f| require_dependency "import/adapter/#{f}" @@ -10,6 +11,7 @@ module Jobs class Importer < Jobs::Base + include DirectoryHelper sidekiq_options retry: false BACKUP_SCHEMA = 'backup' @@ -67,23 +69,15 @@ module Jobs raise Import::FilenameMissingError else extract_files - @decoder = Import::JsonDecoder.new( File.join(tmp_directory, 'tables.json') ) + @decoder = Import::JsonDecoder.new( File.join(tmp_directory('import'), 'tables.json') ) Import.set_import_started Discourse.enable_maintenance_mode end self end - def tmp_directory - @tmp_directory ||= begin - f = File.join( Rails.root, 'tmp', Time.now.strftime('import%Y%m%d%H%M%S') ) - Dir.mkdir(f) unless Dir[f].present? - f - end - end - def extract_files - FileUtils.cd( tmp_directory ) do + FileUtils.cd( tmp_directory('import') ) do `tar xvzf #{@archive_filename} tables.json` end end @@ -248,7 +242,7 @@ module Jobs def finish_import Import.set_import_is_not_running Discourse.disable_maintenance_mode - FileUtils.rm_rf(tmp_directory) if Dir[tmp_directory].present? + remove_tmp_directory('import') if @warnings.size > 0 log "WARNINGS:" diff --git a/spec/components/directory_helper_spec.rb b/spec/components/directory_helper_spec.rb new file mode 100644 index 000000000..a01776423 --- /dev/null +++ b/spec/components/directory_helper_spec.rb @@ -0,0 +1,35 @@ +require 'spec_helper' +require_dependency 'directory_helper' + +describe DirectoryHelper do + class DummyClass + include DirectoryHelper + end + let(:helper) { DummyClass.new } + + before do + helper.tmp_directory('prefix') + helper.tmp_directory('other_prefix') + end + + after do + helper.remove_tmp_directory('prefix') + helper.remove_tmp_directory('other_prefix') + end + + describe '#tmp_directory' do + it 'is memoized by prefix' do + helper.tmp_directory('prefix').should eq(helper.tmp_directory('prefix')) + helper.tmp_directory('prefix').should_not eq(helper.tmp_directory('other_prefix')) + end + end + + describe '#remove_tmp_directory' do + it 'removes the prefixed directory from the filesystem' do + tmp_directory = helper.tmp_directory('prefix') + helper.remove_tmp_directory('prefix') + + Dir[tmp_directory].should_not be_present + end + end +end