diff --git a/lib/gitlab/ci/build/artifacts/metadata.rb b/lib/gitlab/ci/build/artifacts/metadata.rb index 94821c0eae0f02870d638409db4501f11ac406b8..25ecf27d4e6cccdbfbbb1836ec09c78578629618 100644 --- a/lib/gitlab/ci/build/artifacts/metadata.rb +++ b/lib/gitlab/ci/build/artifacts/metadata.rb @@ -37,14 +37,14 @@ module Gitlab end def to_entry - entries, metadata = find_entries! - Entry.new(@path, entries, metadata) + entries = find_entries! + Entry.new(@path, entries) end private def match_entries(gz) - paths, metadata = [], [] + entries = {} match_pattern = %r{^#{Regexp.escape(@path)}[^/]*/?$} until gz.eof? do @@ -56,14 +56,13 @@ module Gitlab next unless path =~ match_pattern next if path =~ INVALID_PATH_PATTERN - paths.push(path) - metadata.push(JSON.parse(meta, symbolize_names: true)) + entries.store(path, JSON.parse(meta, symbolize_names: true)) rescue JSON::ParserError, Encoding::CompatibilityError next end end - [paths, metadata] + entries end def read_version diff --git a/lib/gitlab/ci/build/artifacts/metadata/entry.rb b/lib/gitlab/ci/build/artifacts/metadata/entry.rb index 12bb1bf0346e7409a30026b5bd899b936f2bb76b..4dae02ce4f799970e605d96e33e28948eb9648db 100644 --- a/lib/gitlab/ci/build/artifacts/metadata/entry.rb +++ b/lib/gitlab/ci/build/artifacts/metadata/entry.rb @@ -14,10 +14,9 @@ module Gitlab attr_reader :path, :entries attr_accessor :name - def initialize(path, entries, metadata = []) - @path = path.force_encoding('UTF-8') + def initialize(path, entries) + @path = path.dup.force_encoding('UTF-8') @entries = entries - @metadata = metadata if path.include?("\0") raise ArgumentError, 'Path contains zero byte character!' @@ -42,7 +41,7 @@ module Gitlab def parent return nil unless has_parent? - new_entry(@path.chomp(basename)) + self.class.new(@path.chomp(basename), @entries) end def basename @@ -77,8 +76,7 @@ module Gitlab end def metadata - @index ||= @entries.index(@path) - @metadata[@index] || {} + @entries[@path] || {} end def nodes @@ -111,13 +109,9 @@ module Gitlab private - def new_entry(path) - self.class.new(path, @entries, @metadata) - end - def select_entries - selected = @entries.select { |entry| yield entry } - selected.map { |path| new_entry(path) } + selected = @entries.select { |entry, _metadata| yield entry } + selected.map { |path, _metadata| self.class.new(path, @entries) } end end end diff --git a/spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb b/spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb index a728227f87c0f03f77591bac6e33e42213f5a4c7..41257103eadbae0377580ab449a1547b18923c52 100644 --- a/spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb +++ b/spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb @@ -2,26 +2,26 @@ require 'spec_helper' describe Gitlab::Ci::Build::Artifacts::Metadata::Entry do let(:entries) do - ['path/', - 'path/dir_1/', - 'path/dir_1/file_1', - 'path/dir_1/file_b', - 'path/dir_1/subdir/', - 'path/dir_1/subdir/subfile', - 'path/second_dir', - 'path/second_dir/dir_3/file_2', - 'path/second_dir/dir_3/file_3', - 'another_directory/', - 'another_file', - '/file/with/absolute_path'] + { 'path/' => {}, + 'path/dir_1/' => {}, + 'path/dir_1/file_1' => {}, + 'path/dir_1/file_b' => {}, + 'path/dir_1/subdir/' => {}, + 'path/dir_1/subdir/subfile' => {}, + 'path/second_dir' => {}, + 'path/second_dir/dir_3/file_2' => {}, + 'path/second_dir/dir_3/file_3'=> {}, + 'another_directory/'=> {}, + 'another_file' => {}, + '/file/with/absolute_path' => {} } end def path(example) - string_path(example.metadata[:path]) + entry(example.metadata[:path]) end - def string_path(string_path) - described_class.new(string_path, entries) + def entry(path) + described_class.new(path, entries) end describe '/file/with/absolute_path', path: '/file/with/absolute_path' do @@ -53,7 +53,7 @@ describe Gitlab::Ci::Build::Artifacts::Metadata::Entry do describe '#parent' do subject { |example| path(example).parent } - it { is_expected.to eq string_path('path/') } + it { is_expected.to eq entry('path/') } end describe '#children' do @@ -61,9 +61,9 @@ describe Gitlab::Ci::Build::Artifacts::Metadata::Entry do it { is_expected.to all(be_an_instance_of described_class) } it do - is_expected.to contain_exactly string_path('path/dir_1/file_1'), - string_path('path/dir_1/file_b'), - string_path('path/dir_1/subdir/') + is_expected.to contain_exactly entry('path/dir_1/file_1'), + entry('path/dir_1/file_b'), + entry('path/dir_1/subdir/') end end @@ -73,8 +73,8 @@ describe Gitlab::Ci::Build::Artifacts::Metadata::Entry do it { is_expected.to all(be_file) } it { is_expected.to all(be_an_instance_of described_class) } it do - is_expected.to contain_exactly string_path('path/dir_1/file_1'), - string_path('path/dir_1/file_b') + is_expected.to contain_exactly entry('path/dir_1/file_1'), + entry('path/dir_1/file_b') end end @@ -84,7 +84,7 @@ describe Gitlab::Ci::Build::Artifacts::Metadata::Entry do it { is_expected.to all(be_directory) } it { is_expected.to all(be_an_instance_of described_class) } - it { is_expected.to contain_exactly string_path('path/dir_1/subdir/') } + it { is_expected.to contain_exactly entry('path/dir_1/subdir/') } end context 'with option parent: true' do @@ -93,8 +93,8 @@ describe Gitlab::Ci::Build::Artifacts::Metadata::Entry do it { is_expected.to all(be_directory) } it { is_expected.to all(be_an_instance_of described_class) } it do - is_expected.to contain_exactly string_path('path/dir_1/subdir/'), - string_path('path/') + is_expected.to contain_exactly entry('path/dir_1/subdir/'), + entry('path/') end end @@ -154,15 +154,13 @@ describe Gitlab::Ci::Build::Artifacts::Metadata::Entry do describe '#metadata' do let(:entries) do - ['path/', 'path/file1', 'path/file2'] - end - - let(:metadata) do - [{ name: '/path/' }, { name: '/path/file1' }, { name: '/path/file2' }] + { 'path/' => { name: '/path/' }, + 'path/file1' => { name: '/path/file1' }, + 'path/file2' => { name: '/path/file2' } } end subject do - described_class.new('path/file1', entries, metadata).metadata[:name] + described_class.new('path/file1', entries).metadata[:name] end it { is_expected.to eq '/path/file1' } diff --git a/spec/lib/gitlab/ci/build/artifacts/metadata_spec.rb b/spec/lib/gitlab/ci/build/artifacts/metadata_spec.rb index 8560493f5b5b4bc325dcf334b0d2cb945ffc26de..828eedfa7b03c923c8faafd2656c4818424d2568 100644 --- a/spec/lib/gitlab/ci/build/artifacts/metadata_spec.rb +++ b/spec/lib/gitlab/ci/build/artifacts/metadata_spec.rb @@ -14,18 +14,18 @@ describe Gitlab::Ci::Build::Artifacts::Metadata do subject { metadata('').find_entries! } it 'matches correct paths' do - expect(subject.first).to contain_exactly 'ci_artifacts.txt', - 'other_artifacts_0.1.2/', - 'rails_sample.jpg', - 'tests_encoding/' + expect(subject.keys).to contain_exactly 'ci_artifacts.txt', + 'other_artifacts_0.1.2/', + 'rails_sample.jpg', + 'tests_encoding/' end it 'matches metadata for every path' do - expect(subject.last.count).to eq 4 + expect(subject.keys.count).to eq 4 end it 'return Hashes for each metadata' do - expect(subject.last).to all(be_kind_of(Hash)) + expect(subject.values).to all(be_kind_of(Hash)) end end @@ -33,7 +33,7 @@ describe Gitlab::Ci::Build::Artifacts::Metadata do subject { metadata('other_artifacts_0.1.2/').find_entries! } it 'matches correct paths' do - expect(subject.first). + expect(subject.keys). to contain_exactly 'other_artifacts_0.1.2/', 'other_artifacts_0.1.2/doc_sample.txt', 'other_artifacts_0.1.2/another-subdirectory/' @@ -44,7 +44,7 @@ describe Gitlab::Ci::Build::Artifacts::Metadata do subject { metadata('other_artifacts_0.1.2/another-subdirectory/').find_entries! } it 'matches correct paths' do - expect(subject.first). + expect(subject.keys). to contain_exactly 'other_artifacts_0.1.2/another-subdirectory/', 'other_artifacts_0.1.2/another-subdirectory/empty_directory/', 'other_artifacts_0.1.2/another-subdirectory/banana_sample.gif'