diff --git a/app/models/repository.rb b/app/models/repository.rb index 44c6bff6b66..0e1bf11d7c0 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -596,7 +596,7 @@ class Repository cache_method :gitlab_ci_yml def xcode_project? - file_on_head(:xcode_config).present? + file_on_head(:xcode_config, :tree).present? end cache_method :xcode_project? @@ -920,11 +920,21 @@ class Repository end end - def file_on_head(type) - if head = tree(:head) - head.blobs.find do |blob| - Gitlab::FileDetector.type_of(blob.path) == type + def file_on_head(type, object_type = :blob) + return unless head = tree(:head) + + objects = + case object_type + when :blob + head.blobs + when :tree + head.trees + else + raise ArgumentError, "Object type #{object_type} is not supported" end + + objects.find do |object| + Gitlab::FileDetector.type_of(object.path) == type end end diff --git a/lib/gitlab/file_detector.rb b/lib/gitlab/file_detector.rb index 77af7a868d0..49bc9c0b671 100644 --- a/lib/gitlab/file_detector.rb +++ b/lib/gitlab/file_detector.rb @@ -14,7 +14,7 @@ module Gitlab avatar: /\Alogo\.(png|jpg|gif)\z/, issue_template: %r{\A\.gitlab/issue_templates/[^/]+\.md\z}, merge_request_template: %r{\A\.gitlab/merge_request_templates/[^/]+\.md\z}, - xcode_config: %r{\A[^/]*\.(xcodeproj|xcworkspace)\z}, + xcode_config: %r{\A[^/]*\.(xcodeproj|xcworkspace)(/.+)?\z}, # Configuration files gitignore: '.gitignore', diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index ac8d9a32d4e..78d28179e64 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -2021,27 +2021,27 @@ describe Repository do describe '#xcode_project?' do before do - allow(repository).to receive(:tree).with(:head).and_return(double(:tree, blobs: [blob])) + allow(repository).to receive(:tree).with(:head).and_return(double(:tree, trees: [tree])) end - context 'when the root contains a *.xcodeproj file' do - let(:blob) { double(:blob, path: 'Foo.xcodeproj') } + context 'when the root contains a *.xcodeproj directory' do + let(:tree) { double(:tree, path: 'Foo.xcodeproj') } it 'returns true' do expect(repository.xcode_project?).to be_truthy end end - context 'when the root contains a *.xcworkspace file' do - let(:blob) { double(:blob, path: 'Foo.xcworkspace') } + context 'when the root contains a *.xcworkspace directory' do + let(:tree) { double(:tree, path: 'Foo.xcworkspace') } it 'returns true' do expect(repository.xcode_project?).to be_truthy end end - context 'when the root contains no XCode config file' do - let(:blob) { double(:blob, path: 'subdir/Foo.xcworkspace') } + context 'when the root contains no Xcode config directory' do + let(:tree) { double(:tree, path: 'Foo') } it 'returns false' do expect(repository.xcode_project?).to be_falsey