summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/gitlab/string_path.rb26
-rw-r--r--spec/lib/gitlab/string_path_spec.rb24
2 files changed, 41 insertions, 9 deletions
diff --git a/lib/gitlab/string_path.rb b/lib/gitlab/string_path.rb
index a2dc63db2f2..d165829132a 100644
--- a/lib/gitlab/string_path.rb
+++ b/lib/gitlab/string_path.rb
@@ -1,6 +1,6 @@
module Gitlab
##
- # Class that represents a path to a file or directory
+ # Class that represents a simplified path to a file or directory
#
# This is IO-operations safe class, that does similar job to
# Ruby's Pathname but without the risk of accessing filesystem.
@@ -10,8 +10,9 @@ module Gitlab
attr_reader :path, :universe
def initialize(path, universe)
- @path = path
- @universe = universe
+ @path = prepare(path)
+ @universe = universe.map { |entry| prepare(entry) }
+ @universe.unshift('./') unless @universe.include?('./')
end
def to_s
@@ -43,6 +44,15 @@ module Gitlab
new(@path.sub(basename, ''))
end
+ def basename
+ name = @path.split(::File::SEPARATOR).last
+ directory? ? name + ::File::SEPARATOR : name
+ end
+
+ def has_descendants?
+ descendants.any?
+ end
+
def descendants
return [] unless directory?
children = @universe.select { |entry| entry =~ /^#{@path}.+/ }
@@ -63,11 +73,6 @@ module Gitlab
children.select { |child| child.file? }
end
- def basename
- name = @path.split(::File::SEPARATOR).last
- directory? ? name + ::File::SEPARATOR : name
- end
-
def ==(other)
@path == other.path && @universe == other.universe
end
@@ -77,5 +82,10 @@ module Gitlab
def new(path)
self.class.new(path, @universe)
end
+
+ def prepare(path)
+ return path if path =~ %r{^(/|\.|\.\.)}
+ path.dup.prepend('./')
+ end
end
end
diff --git a/spec/lib/gitlab/string_path_spec.rb b/spec/lib/gitlab/string_path_spec.rb
index 7818e340726..7ee69c7d3cb 100644
--- a/spec/lib/gitlab/string_path_spec.rb
+++ b/spec/lib/gitlab/string_path_spec.rb
@@ -11,6 +11,7 @@ describe Gitlab::StringPath do
'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
@@ -30,6 +31,7 @@ describe Gitlab::StringPath do
it { is_expected.to_not be_relative }
it { is_expected.to be_file }
it { is_expected.to_not have_parent }
+ it { is_expected.to_not have_descendants }
describe '#basename' do
subject { |example| path(example).basename }
@@ -43,7 +45,7 @@ describe Gitlab::StringPath do
it { is_expected.to be_directory }
it { is_expected.to be_relative }
- it { is_expected.to_not have_parent }
+ it { is_expected.to have_parent }
end
describe 'path/dir_1/', path: 'path/dir_1/' do
@@ -100,4 +102,24 @@ describe Gitlab::StringPath do
it { is_expected.to contain_exactly string_path('path/dir_1/subdir/') }
end
end
+
+ describe './', path: './' do
+ subject { |example| path(example) }
+
+ it { is_expected.to_not have_parent }
+ it { is_expected.to have_descendants }
+
+ describe '#descendants' do
+ subject { |example| path(example).descendants }
+
+ it { expect(subject.count).to eq universe.count - 1 }
+ it { is_expected.to_not include string_path('./') }
+ end
+
+ describe '#children' do
+ subject { |example| path(example).children }
+
+ it { expect(subject.count).to eq 3 }
+ end
+ end
end