Extract artifacts metadata implementation to separate class
This commit is contained in:
parent
df41148662
commit
a7f99b67a0
5 changed files with 139 additions and 23 deletions
|
@ -16,10 +16,7 @@ class Projects::ArtifactsController < Projects::ApplicationController
|
|||
|
||||
def browse
|
||||
return render_404 unless build.artifacts?
|
||||
|
||||
current_path = params[:path] ? "./#{params[:path]}/" : './'
|
||||
paths, metadata = build.artifacts_metadata_for_path(current_path)
|
||||
@path = Gitlab::StringPath.new(current_path, paths, metadata)
|
||||
@path = build.artifacts_metadata_string_path(params[:path] || './')
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -349,24 +349,10 @@ module Ci
|
|||
artifacts? && artifacts_file.path.end_with?('zip') && artifacts_metadata.exists?
|
||||
end
|
||||
|
||||
def artifacts_metadata_for_path(path)
|
||||
return [] unless artifacts_metadata.exists?
|
||||
paths, metadata = [], []
|
||||
|
||||
metadata_path = path.sub(/^\.\//, '')
|
||||
File.open(artifacts_metadata.path) do |file|
|
||||
gzip = Zlib::GzipReader.new(file)
|
||||
gzip.each_line do |line|
|
||||
if line =~ %r{^#{Regexp.escape(metadata_path)}[^/\s]+/?\s}
|
||||
matched_path, matched_meta = line.split(' ')
|
||||
paths << matched_path
|
||||
metadata << JSON.parse(matched_meta)
|
||||
end
|
||||
end
|
||||
gzip.close
|
||||
end
|
||||
|
||||
[paths, metadata]
|
||||
def artifacts_metadata_string_path(path)
|
||||
file = artifacts_metadata.path
|
||||
Gitlab::Ci::Build::Artifacts::Metadata.new(file, path).to_string_path
|
||||
end
|
||||
|
||||
private
|
||||
|
|
57
lib/gitlab/ci/build/artifacts/metadata.rb
Normal file
57
lib/gitlab/ci/build/artifacts/metadata.rb
Normal file
|
@ -0,0 +1,57 @@
|
|||
require 'zlib'
|
||||
require 'json'
|
||||
|
||||
module Gitlab
|
||||
module Ci
|
||||
module Build
|
||||
module Artifacts
|
||||
class Metadata
|
||||
def initialize(file, path)
|
||||
@file = file
|
||||
|
||||
@path = path.sub(/^\.\//, '')
|
||||
@path << '/' unless path.end_with?('/')
|
||||
end
|
||||
|
||||
def exists?
|
||||
File.exists?(@file)
|
||||
end
|
||||
|
||||
def match!
|
||||
raise StandardError, 'Metadata file not found !' unless exists?
|
||||
paths, metadata = [], []
|
||||
|
||||
each do |line|
|
||||
next unless line =~ %r{^#{Regexp.escape(@path)}[^/\s]+/?\s}
|
||||
|
||||
path, meta = line.split(' ')
|
||||
paths.push(path)
|
||||
metadata.push(meta)
|
||||
end
|
||||
|
||||
[paths, metadata.map { |meta| JSON.parse(meta) }]
|
||||
end
|
||||
|
||||
def to_string_path
|
||||
universe, metadata = match!
|
||||
::Gitlab::StringPath.new(@path, universe, metadata)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def each
|
||||
open do |file|
|
||||
gzip = Zlib::GzipReader.new(file)
|
||||
gzip.each_line { |line| yield line }
|
||||
gzip.close
|
||||
end
|
||||
end
|
||||
|
||||
def open
|
||||
File.open(@file) { |file| yield file }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -75,7 +75,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def directories!
|
||||
has_parent? ? directories.prepend(parent) : directories
|
||||
@path =~ %r{^\./[^/]/} ? directories.prepend(parent) : directories
|
||||
end
|
||||
|
||||
def files
|
||||
|
@ -119,7 +119,7 @@ module Gitlab
|
|||
raise ArgumentError, 'Invalid path' if clean_path.start_with?('../')
|
||||
|
||||
prefix = './' unless clean_path =~ %r{^[\.|/]}
|
||||
suffix = '/' if path.end_with?('/') || clean_path =~ /^[\.|\.\.]$/
|
||||
suffix = '/' if path.end_with?('/') || ['.', '..'].include?(clean_path)
|
||||
prefix.to_s + clean_path + suffix.to_s
|
||||
end
|
||||
end
|
||||
|
|
76
spec/lib/gitlab/ci/build/artifacts/metadata_spec.rb
Normal file
76
spec/lib/gitlab/ci/build/artifacts/metadata_spec.rb
Normal file
|
@ -0,0 +1,76 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Gitlab::Ci::Build::Artifacts::Metadata do
|
||||
def metadata(path = '')
|
||||
described_class.new(metadata_file_path, path)
|
||||
end
|
||||
|
||||
let(:metadata_file_path) do
|
||||
Rails.root + 'spec/fixtures/ci_build_artifacts_metadata.gz'
|
||||
end
|
||||
|
||||
context 'metadata file exists' do
|
||||
describe '#exists?' do
|
||||
subject { metadata.exists? }
|
||||
it { is_expected.to be true }
|
||||
end
|
||||
|
||||
describe '#match! ./' do
|
||||
subject { metadata('./').match! }
|
||||
|
||||
it 'matches correct paths' do
|
||||
expect(subject.first).to contain_exactly 'ci_artifacts.txt',
|
||||
'other_artifacts_0.1.2/',
|
||||
'rails_sample.jpg'
|
||||
end
|
||||
|
||||
it 'matches metadata for every path' do
|
||||
expect(subject.last.count).to eq 3
|
||||
end
|
||||
|
||||
it 'return Hashes for each metadata' do
|
||||
expect(subject.last).to all(be_kind_of(Hash))
|
||||
end
|
||||
end
|
||||
|
||||
describe '#match! other_artifacts_0.1.2' do
|
||||
subject { metadata('other_artifacts_0.1.2').match! }
|
||||
|
||||
it 'matches correct paths' do
|
||||
expect(subject.first).
|
||||
to contain_exactly 'other_artifacts_0.1.2/doc_sample.txt',
|
||||
'other_artifacts_0.1.2/another-subdirectory/'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#match! other_artifacts_0.1.2/another-subdirectory' do
|
||||
subject { metadata('other_artifacts_0.1.2/another-subdirectory/').match! }
|
||||
|
||||
it 'matches correct paths' do
|
||||
expect(subject.first).
|
||||
to contain_exactly 'other_artifacts_0.1.2/another-subdirectory/empty_directory/',
|
||||
'other_artifacts_0.1.2/another-subdirectory/banana_sample.gif'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#to_string_path' do
|
||||
subject { metadata('').to_string_path }
|
||||
it { is_expected.to be_an_instance_of(Gitlab::StringPath) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'metadata file does not exist' do
|
||||
let(:metadata_file_path) { '' }
|
||||
|
||||
describe '#exists?' do
|
||||
subject { metadata.exists? }
|
||||
it { is_expected.to be false }
|
||||
end
|
||||
|
||||
describe '#match!' do
|
||||
it 'raises error' do
|
||||
expect { metadata.match! }.to raise_error(StandardError, /Metadata file not found/)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue