From acfa0b69d5370749cee9768bf79b58daf6d916a4 Mon Sep 17 00:00:00 2001 From: James Lopez <james@jameslopez.es> Date: Thu, 7 Apr 2016 13:19:57 +0200 Subject: [PATCH] continuing to refactor config, added spec and fixed a few problems --- .../projects/import_export/import_export.yml | 2 +- .../import_export/import_export_reader.rb | 51 ++++++++++++++++--- .../import_export_reader_spec.rb | 24 +++++++++ spec/support/import_export/import_export.yml | 20 ++++++++ 4 files changed, 89 insertions(+), 8 deletions(-) create mode 100644 spec/services/projects/import_export/import_export_reader_spec.rb create mode 100644 spec/support/import_export/import_export.yml diff --git a/app/services/projects/import_export/import_export.yml b/app/services/projects/import_export/import_export.yml index d02ec5df2ff..40fd98b8092 100644 --- a/app/services/projects/import_export/import_export.yml +++ b/app/services/projects/import_export/import_export.yml @@ -1,4 +1,4 @@ -# Class relationships to be included in the import/export +# Class relationships to be included in the project import/export :project_tree: - :issues - :labels diff --git a/app/services/projects/import_export/import_export_reader.rb b/app/services/projects/import_export/import_export_reader.rb index af8c8c3c251..77a1abb851b 100644 --- a/app/services/projects/import_export/import_export_reader.rb +++ b/app/services/projects/import_export/import_export_reader.rb @@ -7,6 +7,8 @@ module Projects { only: atts_only[:project], include: build_hash(tree) } end + private + def config @config ||= YAML.load_file('app/services/projects/import_export/import_export.yml') end @@ -27,21 +29,56 @@ module Projects array.map { |el| el.is_a?(Hash) ? process_include(el) : el } end - def process_include(hash) - included_classes_hash = {} + def process_include(hash, included_classes_hash = {}) hash.values.flatten.each do |value| - value = value.is_a?(Hash) ? process_include(hash) : value - new_hash = { :include => value } - new_hash.merge!(check_only(value)) - included_classes_hash[hash.keys.first] = new_hash + current_key, value = process_current_class(hash, included_classes_hash, value) + if included_classes_hash[current_key] + add_class(current_key, included_classes_hash, value) + else + add_new_class(current_key, included_classes_hash, value) + end end included_classes_hash end + def process_current_class(hash, included_classes_hash, value) + value = value.is_a?(Hash) ? process_include(hash, included_classes_hash) : value + current_key = hash.keys.first + current_key_only = check_only_and_except(current_key) + included_classes_hash[current_key] ||= current_key_only unless current_key_only.empty? + return current_key, value + end + + def add_new_class(current_key, included_classes_hash, value) + new_hash = { :include => value } + new_hash.merge!(check_only_and_except(value)) + included_classes_hash[current_key] = new_hash + end + + def add_class(current_key, included_classes_hash, value) + check_only_hash = check_only_and_except(value) + value = { value => check_only_hash } unless check_only_hash.empty? + old_values = included_classes_hash[current_key][:include] + included_classes_hash[current_key][:include] = ([old_values] + [value]).compact.flatten + end + + def check_only_and_except(value) + check_only(value).merge(check_except(value)) + end + def check_only(value) - key = value.is_a?(Hash) ? value.keys.first : value + key = key_from_hash(value) atts_only[key].nil? ? {} : { only: atts_only[key] } end + + def check_except(value) + key = key_from_hash(value) + atts_except[key].nil? ? {} : { except: atts_except[key] } + end + + def key_from_hash(value) + value.is_a?(Hash) ? value.keys.first : value + end end end end \ No newline at end of file diff --git a/spec/services/projects/import_export/import_export_reader_spec.rb b/spec/services/projects/import_export/import_export_reader_spec.rb new file mode 100644 index 00000000000..73e043e52ce --- /dev/null +++ b/spec/services/projects/import_export/import_export_reader_spec.rb @@ -0,0 +1,24 @@ +require 'rspec' + +describe Projects::ImportExport::ImportExportReader do + + let(:test_config) { 'spec/support/import_export/import_export.yml' } + let(:project_tree_hash) do + { + :only => [:name, :path], + :include => [:issues, :labels, + { :merge_requests => { + :only => [:id], + :except => [:iid], + :include => [:merge_request_diff, :merge_request_test] + } }, + { :commit_statuses => { :include => :commit } }] + } + end + + it 'should generate hash from project tree config' do + allow(described_class).to receive(:config).and_return(YAML.load_file(test_config)) + + expect(described_class.project_tree).to eq(project_tree_hash) + end +end \ No newline at end of file diff --git a/spec/support/import_export/import_export.yml b/spec/support/import_export/import_export.yml new file mode 100644 index 00000000000..e6985d6413c --- /dev/null +++ b/spec/support/import_export/import_export.yml @@ -0,0 +1,20 @@ +# Class relationships to be included in the project import/export +:project_tree: + - :issues + - :labels + - :merge_requests: + - :merge_request_diff + - :merge_request_test + - :commit_statuses: + - :commit + +:attributes_only: + :project: + - :name + - :path + :merge_requests: + - :id + +:attributes_except: + :merge_requests: + - :iid \ No newline at end of file -- GitLab