Commit 6b0a43af authored by Grzegorz Bizon's avatar Grzegorz Bizon

Improve readability of artifacts browser `Entry` related code

parent 154b8ceb
...@@ -18,17 +18,17 @@ class Projects::ArtifactsController < Projects::ApplicationController ...@@ -18,17 +18,17 @@ class Projects::ArtifactsController < Projects::ApplicationController
return render_404 unless build.artifacts? return render_404 unless build.artifacts?
directory = params[:path] ? "#{params[:path]}/" : '' directory = params[:path] ? "#{params[:path]}/" : ''
@path = build.artifacts_metadata_path(directory) @entry = build.artifacts_metadata_entry(directory)
return render_404 unless @path.exists? return render_404 unless @entry.exists?
end end
def file def file
file_path = build.artifacts_metadata_path(params[:path]) entry = build.artifacts_metadata_entry(params[:path])
if file_path.exists? if entry.exists?
render json: { archive: build.artifacts_file.path, render json: { archive: build.artifacts_file.path,
path: Base64.encode64(file_path.path) } entry: Base64.encode64(entry.path) }
else else
render json: {}, status: 404 render json: {}, status: 404
end end
......
...@@ -347,8 +347,8 @@ module Ci ...@@ -347,8 +347,8 @@ module Ci
artifacts? && artifacts_metadata.exists? artifacts? && artifacts_metadata.exists?
end end
def artifacts_metadata_path(path) def artifacts_metadata_entry(path)
Gitlab::Ci::Build::Artifacts::Metadata.new(artifacts_metadata.path, path).to_path Gitlab::Ci::Build::Artifacts::Metadata.new(artifacts_metadata.path, path).to_entry
end end
private private
......
- page_title "#{@build.name} (##{@build.id})", 'Build artifacts' - page_title 'Artifacts', "#{@build.name} (##{@build.id})", 'Builds'
- header_title project_title(@project, "Build artifacts", namespace_project_build_path(@project.namespace, @project, @build)) = render 'projects/builds/header_title'
#tree-holder.tree-holder #tree-holder.tree-holder
.gray-content-block.top-block.clearfix .gray-content-block.top-block.clearfix
.pull-right .pull-right
= link_to download_namespace_project_build_artifacts_path(@project.namespace, @project, @build), = link_to download_namespace_project_build_artifacts_path(@project.namespace, @project, @build),
class: 'btn btn-default', method: :get do class: 'btn btn-default' do
= icon('download') = icon('download')
Download artifacts archive Download artifacts archive
...@@ -17,8 +17,8 @@ ...@@ -17,8 +17,8 @@
%th Name %th Name
%th Size %th Size
%th Download %th Download
= render partial: 'tree_directory', collection: @path.directories!, as: :directory = render partial: 'tree_directory', collection: @entry.directories(parent: true), as: :directory
= render partial: 'tree_file', collection: @path.files, as: :file = render partial: 'tree_file', collection: @entry.files, as: :file
- if @path.children.empty? - if @entry.empty?
.center Empty .center Empty
...@@ -84,6 +84,6 @@ class Spinach::Features::ProjectBuilds < Spinach::FeatureSteps ...@@ -84,6 +84,6 @@ class Spinach::Features::ProjectBuilds < Spinach::FeatureSteps
# this will be accelerated by Workhorse # this will be accelerated by Workhorse
response_json = JSON.parse(page.body, symbolize_names: true) response_json = JSON.parse(page.body, symbolize_names: true)
expect(response_json[:archive]).to end_with('build_artifacts.zip') expect(response_json[:archive]).to end_with('build_artifacts.zip')
expect(response_json[:path]).to eq Base64.encode64('ci_artifacts.txt') expect(response_json[:entry]).to eq Base64.encode64('ci_artifacts.txt')
end end
end end
...@@ -34,8 +34,9 @@ module Gitlab ...@@ -34,8 +34,9 @@ module Gitlab
end end
end end
def to_path def to_entry
Path.new(@path, *match!) entires, metadata = match!
Entry.new(@path, entires, metadata)
end end
private private
......
...@@ -2,7 +2,7 @@ module Gitlab ...@@ -2,7 +2,7 @@ module Gitlab
module Ci::Build::Artifacts module Ci::Build::Artifacts
class Metadata class Metadata
## ##
# Class that represents a simplified path to a file or # Class that represents an entry (path and metadata) to a file or
# directory in GitLab CI Build Artifacts binary file / archive # directory in GitLab CI Build Artifacts binary file / archive
# #
# This is IO-operations safe class, that does similar job to # This is IO-operations safe class, that does similar job to
...@@ -10,13 +10,13 @@ module Gitlab ...@@ -10,13 +10,13 @@ module Gitlab
# #
# This class is working only with UTF-8 encoded paths. # This class is working only with UTF-8 encoded paths.
# #
class Path class Entry
attr_reader :path, :universe attr_reader :path, :entires
attr_accessor :name attr_accessor :name
def initialize(path, universe, metadata = []) def initialize(path, entires, metadata = [])
@path = path.force_encoding('UTF-8') @path = path.force_encoding('UTF-8')
@universe = universe @entires = entires
@metadata = metadata @metadata = metadata
if path.include?("\0") if path.include?("\0")
...@@ -46,11 +46,11 @@ module Gitlab ...@@ -46,11 +46,11 @@ module Gitlab
end end
def basename def basename
(directory? && !blank_node?) ? name + ::File::SEPARATOR : name (directory? && !blank_node?) ? name + '/' : name
end end
def name def name
@name || @path.split(::File::SEPARATOR).last.to_s @name || @path.split('/').last.to_s
end end
def children def children
...@@ -58,20 +58,17 @@ module Gitlab ...@@ -58,20 +58,17 @@ module Gitlab
return @children if @children return @children if @children
child_pattern = %r{^#{Regexp.escape(@path)}[^/]+/?$} child_pattern = %r{^#{Regexp.escape(@path)}[^/]+/?$}
@children = select { |entry| entry =~ child_pattern } @children = select_entires { |entry| entry =~ child_pattern }
end end
def directories def directories(opts = {})
return [] unless directory? return [] unless directory?
children.select(&:directory?) dirs = children.select(&:directory?)
end return dirs unless has_parent? && opts[:parent]
def directories!
return directories unless has_parent?
dotted_parent = parent dotted_parent = parent
dotted_parent.name = '..' dotted_parent.name = '..'
directories.prepend(dotted_parent) dirs.prepend(dotted_parent)
end end
def files def files
...@@ -80,7 +77,7 @@ module Gitlab ...@@ -80,7 +77,7 @@ module Gitlab
end end
def metadata def metadata
@index ||= @universe.index(@path) @index ||= @entires.index(@path)
@metadata[@index] || {} @metadata[@index] || {}
end end
...@@ -88,12 +85,16 @@ module Gitlab ...@@ -88,12 +85,16 @@ module Gitlab
@path.count('/') + (file? ? 1 : 0) @path.count('/') + (file? ? 1 : 0)
end end
def blank_node?
@path.empty? # "" is considered to be './'
end
def exists? def exists?
blank_node? || @universe.include?(@path) blank_node? || @entires.include?(@path)
end end
def blank_node? def empty?
@path.empty? # "" is considered to be './' children.empty?
end end
def to_s def to_s
...@@ -101,7 +102,7 @@ module Gitlab ...@@ -101,7 +102,7 @@ module Gitlab
end end
def ==(other) def ==(other)
@path == other.path && @universe == other.universe @path == other.path && @entires == other.entires
end end
def inspect def inspect
...@@ -111,11 +112,11 @@ module Gitlab ...@@ -111,11 +112,11 @@ module Gitlab
private private
def new(path) def new(path)
self.class.new(path, @universe, @metadata) self.class.new(path, @entires, @metadata)
end end
def select def select_entires
selected = @universe.select { |entry| yield entry } selected = @entires.select { |entry| yield entry }
selected.map { |path| new(path) } selected.map { |path| new(path) }
end end
end end
......
require 'spec_helper' require 'spec_helper'
describe Gitlab::Ci::Build::Artifacts::Metadata::Path do describe Gitlab::Ci::Build::Artifacts::Metadata::Entry do
let(:universe) do let(:entries) do
['path/', ['path/',
'path/dir_1/', 'path/dir_1/',
'path/dir_1/file_1', 'path/dir_1/file_1',
...@@ -21,7 +21,7 @@ describe Gitlab::Ci::Build::Artifacts::Metadata::Path do ...@@ -21,7 +21,7 @@ describe Gitlab::Ci::Build::Artifacts::Metadata::Path do
end end
def string_path(string_path) def string_path(string_path)
described_class.new(string_path, universe) described_class.new(string_path, entries)
end end
describe '/file/with/absolute_path', path: '/file/with/absolute_path' do describe '/file/with/absolute_path', path: '/file/with/absolute_path' do
...@@ -79,21 +79,38 @@ describe Gitlab::Ci::Build::Artifacts::Metadata::Path do ...@@ -79,21 +79,38 @@ describe Gitlab::Ci::Build::Artifacts::Metadata::Path do
end end
describe '#directories' do describe '#directories' do
subject { |example| path(example).directories } context 'without options' do
subject { |example| path(example).directories }
it { is_expected.to all(be_directory) } it { is_expected.to all(be_directory) }
it { is_expected.to all(be_an_instance_of described_class) } 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 string_path('path/dir_1/subdir/') }
end end
describe '#directories!' do context 'with option parent: true' do
subject { |example| path(example).directories! } subject { |example| path(example).directories(parent: true) }
it { is_expected.to all(be_directory) } it { is_expected.to all(be_directory) }
it { is_expected.to all(be_an_instance_of described_class) } it { is_expected.to all(be_an_instance_of described_class) }
it do it do
is_expected.to contain_exactly string_path('path/dir_1/subdir/'), is_expected.to contain_exactly string_path('path/dir_1/subdir/'),
string_path('path/') string_path('path/')
end
end
describe '#nodes' do
subject { |example| path(example).nodes }
it { is_expected.to eq 2 }
end
describe '#exists?' do
subject { |example| path(example).exists? }
it { is_expected.to be true }
end
describe '#empty?' do
subject { |example| path(example).empty? }
it { is_expected.to be false }
end end
end end
end end
...@@ -106,20 +123,37 @@ describe Gitlab::Ci::Build::Artifacts::Metadata::Path do ...@@ -106,20 +123,37 @@ describe Gitlab::Ci::Build::Artifacts::Metadata::Path do
subject { |example| path(example).children } subject { |example| path(example).children }
it { expect(subject.count).to eq 3 } it { expect(subject.count).to eq 3 }
end end
end
describe 'path/dir_1/subdir/subfile', path: 'path/dir_1/subdir/subfile' do
describe '#nodes' do
subject { |example| path(example).nodes }
it { is_expected.to eq 4 }
end
end end
describe '#nodes', path: 'test' do describe 'non-existent/', path: 'non-existent/' do
subject { |example| path(example).nodes } describe '#empty?' do
it { is_expected.to eq 1 } subject { |example| path(example).empty? }
it { is_expected.to be true }
end
describe '#exists?' do
subject { |example| path(example).exists? }
it { is_expected.to be false }
end
end end
describe '#nodes', path: 'test/' do describe 'another_directory/', path: 'another_directory/' do
subject { |example| path(example).nodes } describe '#empty?' do
it { is_expected.to eq 1 } subject { |example| path(example).empty? }
it { is_expected.to be true }
end
end end
describe '#metadata' do describe '#metadata' do
let(:universe) do let(:entries) do
['path/', 'path/file1', 'path/file2'] ['path/', 'path/file1', 'path/file2']
end end
...@@ -128,21 +162,9 @@ describe Gitlab::Ci::Build::Artifacts::Metadata::Path do ...@@ -128,21 +162,9 @@ describe Gitlab::Ci::Build::Artifacts::Metadata::Path do
end end
subject do subject do
described_class.new('path/file1', universe, metadata).metadata[:name] described_class.new('path/file1', entries, metadata).metadata[:name]
end end
it { is_expected.to eq '/path/file1' } it { is_expected.to eq '/path/file1' }
end end
describe '#exists?', path: 'another_file' do
subject { |example| path(example).exists? }
it { is_expected.to be true }
end
describe '#exists?', path: './non_existent/' do
let(:universe) { ['./something'] }
subject { |example| path(example).exists? }
it { is_expected.to be false }
end
end end
...@@ -51,9 +51,9 @@ describe Gitlab::Ci::Build::Artifacts::Metadata do ...@@ -51,9 +51,9 @@ describe Gitlab::Ci::Build::Artifacts::Metadata do
end end
end end
describe '#to_path' do describe '#to_entry' do
subject { metadata('').to_path } subject { metadata('').to_entry }
it { is_expected.to be_an_instance_of(Gitlab::Ci::Build::Artifacts::Metadata::Path) } it { is_expected.to be_an_instance_of(Gitlab::Ci::Build::Artifacts::Metadata::Entry) }
end end
describe '#full_version' do describe '#full_version' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment