diff options
29 files changed, 246 insertions, 120 deletions
diff --git a/app/assets/javascripts/create_merge_request_dropdown.js b/app/assets/javascripts/create_merge_request_dropdown.js index 108082799ef..f77a5730b77 100644 --- a/app/assets/javascripts/create_merge_request_dropdown.js +++ b/app/assets/javascripts/create_merge_request_dropdown.js @@ -366,7 +366,7 @@ export default class CreateMergeRequestDropdown { removeMessage(target) { const { input, message } = this.getTargetData(target); const inputClasses = ['gl-field-error-outline', 'gl-field-success-outline']; - const messageClasses = ['gl-field-hint', 'gl-field-error-message', 'gl-field-success-message']; + const messageClasses = ['text-muted', 'text-danger', 'text-success']; inputClasses.forEach(cssClass => input.classList.remove(cssClass)); messageClasses.forEach(cssClass => message.classList.remove(cssClass)); @@ -393,7 +393,7 @@ export default class CreateMergeRequestDropdown { this.removeMessage(target); input.classList.add('gl-field-success-outline'); - message.classList.add('gl-field-success-message'); + message.classList.add('text-success'); message.textContent = sprintf(__('%{text} is available'), { text }); message.style.display = 'inline-block'; } @@ -403,7 +403,7 @@ export default class CreateMergeRequestDropdown { const text = target === 'branch' ? __('branch name') : __('source'); this.removeMessage(target); - message.classList.add('gl-field-hint'); + message.classList.add('text-muted'); message.textContent = sprintf(__('Checking %{text} availability…'), { text }); message.style.display = 'inline-block'; } @@ -415,7 +415,7 @@ export default class CreateMergeRequestDropdown { this.removeMessage(target); input.classList.add('gl-field-error-outline'); - message.classList.add('gl-field-error-message'); + message.classList.add('text-danger'); message.textContent = text; message.style.display = 'inline-block'; } diff --git a/app/assets/javascripts/vue_shared/components/expand_button.vue b/app/assets/javascripts/vue_shared/components/expand_button.vue index 0fdea651130..e6e92594b65 100644 --- a/app/assets/javascripts/vue_shared/components/expand_button.vue +++ b/app/assets/javascripts/vue_shared/components/expand_button.vue @@ -1,5 +1,7 @@ <script> import { __ } from '~/locale'; +import Icon from '~/vue_shared/components/icon.vue'; + /** * Port of detail_behavior expand button. * @@ -12,6 +14,9 @@ import { __ } from '~/locale'; */ export default { name: 'ExpandButton', + components: { + Icon, + }, data() { return { isCollapsed: true, @@ -22,6 +27,9 @@ export default { return __('Click to expand text'); }, }, + destroyed() { + this.isCollapsed = true; + }, methods: { onClick() { this.isCollapsed = !this.isCollapsed; @@ -37,7 +45,10 @@ export default { type="button" class="text-expander btn-blank" @click="onClick"> - ... + <icon + :size="12" + name="ellipsis_h" + /> </button> <span v-if="!isCollapsed"> <slot name="expanded"></slot> diff --git a/app/assets/stylesheets/framework/forms.scss b/app/assets/stylesheets/framework/forms.scss index 03520f42997..2b2e6d69e33 100644 --- a/app/assets/stylesheets/framework/forms.scss +++ b/app/assets/stylesheets/framework/forms.scss @@ -201,6 +201,10 @@ label { } .gl-show-field-errors { + .form-control { + height: 34px; + } + .gl-field-success-outline { border: 1px solid $green-600; diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss index dc8842212e0..49226ae8eac 100644 --- a/app/assets/stylesheets/pages/commits.scss +++ b/app/assets/stylesheets/pages/commits.scss @@ -135,10 +135,10 @@ } .text-expander { - display: inline-block; + display: inline-flex; background: $white-light; color: $gl-text-color-secondary; - padding: 0 4px; + padding: 1px $gl-padding-4; cursor: pointer; border: 1px solid $border-gray-dark; border-radius: $border-radius-default; @@ -180,6 +180,11 @@ .commit-content { padding-right: 10px; white-space: normal; + + .commit-title { + display: flex; + align-items: center; + } } .commit-actions { @@ -253,7 +258,6 @@ .generic_commit_status { a, button { - color: $gl-text-color; vertical-align: baseline; } diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index daad829faa2..c405e6d117f 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -407,6 +407,7 @@ module ProjectsHelper @ref || @repository.try(:root_ref) end + # Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/1235 def sanitize_repo_path(project, message) return '' unless message.present? diff --git a/app/models/concerns/redis_cacheable.rb b/app/models/concerns/redis_cacheable.rb index b5425295130..3bdc1330d23 100644 --- a/app/models/concerns/redis_cacheable.rb +++ b/app/models/concerns/redis_cacheable.rb @@ -48,7 +48,7 @@ module RedisCacheable def cast_value_from_cache(attribute, value) if Gitlab.rails5? - self.class.type_for_attribute(attribute).cast(value) + self.class.type_for_attribute(attribute.to_s).cast(value) else self.class.column_for_attribute(attribute).type_cast_from_database(value) end diff --git a/app/models/repository.rb b/app/models/repository.rb index e4202505634..c2f62badbcb 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -154,7 +154,10 @@ class Repository # Returns a list of commits that are not present in any reference def new_commits(newrev) - refs = ::Gitlab::Git::RevList.new(raw, newrev: newrev).new_refs + # Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/1233 + refs = Gitlab::GitalyClient::StorageSettings.allow_disk_access do + ::Gitlab::Git::RevList.new(raw, newrev: newrev).new_refs + end refs.map { |sha| commit(sha.strip) } end diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml index 12b27eb9b66..90e55fd0fb0 100644 --- a/app/views/projects/commits/_commit.html.haml +++ b/app/views/projects/commits/_commit.html.haml @@ -34,7 +34,8 @@ .d-block.d-sm-none = render_commit_status(commit, ref: ref) - if commit.description? - %button.text-expander.d-none.d-sm-inline-block.js-toggle-button{ type: "button" } ... + %button.text-expander.js-toggle-button + = sprite_icon('ellipsis_h', size: 12) .commiter - commit_author_link = commit_author_link(commit, avatar: false, size: 24) diff --git a/app/views/projects/issues/_new_branch.html.haml b/app/views/projects/issues/_new_branch.html.haml index acb1a446ec4..a678cb6f058 100644 --- a/app/views/projects/issues/_new_branch.html.haml +++ b/app/views/projects/issues/_new_branch.html.haml @@ -40,7 +40,7 @@ %label{ for: 'new-branch-name' } = _('Branch name') %input#new-branch-name.js-branch-name.form-control{ type: 'text', placeholder: "#{@issue.to_branch_name}", value: "#{@issue.to_branch_name}" } - %span.js-branch-message.form-text.text-muted + %span.js-branch-message.form-text .form-group %label{ for: 'source-name' } diff --git a/app/views/projects/pipelines/_info.html.haml b/app/views/projects/pipelines/_info.html.haml index aa53fc3ea28..04131a90a57 100644 --- a/app/views/projects/pipelines/_info.html.haml +++ b/app/views/projects/pipelines/_info.html.haml @@ -29,7 +29,7 @@ = link_to @commit.short_id, project_commit_path(@project, @pipeline.sha), class: "commit-sha js-details-short" = link_to("#", class: "js-details-expand d-none d-sm-none d-md-inline") do %span.text-expander - \... + = sprite_icon('ellipsis_h', size: 12) %span.js-details-content.hide = link_to @pipeline.sha, project_commit_path(@project, @pipeline.sha), class: "commit-sha commit-hash-full" = clipboard_button(text: @pipeline.sha, title: "Copy commit SHA to clipboard") diff --git a/changelogs/unreleased/ce-5024-filename-search.yml b/changelogs/unreleased/ce-5024-filename-search.yml new file mode 100644 index 00000000000..a8bf9b1f802 --- /dev/null +++ b/changelogs/unreleased/ce-5024-filename-search.yml @@ -0,0 +1,5 @@ +--- +title: Add filename filtering to code search +merge_request: 19509 +author: +type: added diff --git a/changelogs/unreleased/text-expander-icon-update.yml b/changelogs/unreleased/text-expander-icon-update.yml new file mode 100644 index 00000000000..be9dc98728f --- /dev/null +++ b/changelogs/unreleased/text-expander-icon-update.yml @@ -0,0 +1,5 @@ +--- +title: Updated the icon for expand buttons to ellipsis +merge_request: 18793 +author: Constance Okoghenun +type: changed
\ No newline at end of file diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index 12d09150127..3d3448cb4d6 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -394,6 +394,7 @@ repositories_storages = Settings.repositories.storages.values repository_downloads_path = Settings.gitlab['repository_downloads_path'].to_s.gsub(%r{/$}, '') repository_downloads_full_path = File.expand_path(repository_downloads_path, Settings.gitlab['user_home']) +# Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/1237 Gitlab::GitalyClient::StorageSettings.allow_disk_access do if repository_downloads_path.blank? || repositories_storages.any? { |rs| [repository_downloads_path, repository_downloads_full_path].include?(rs.legacy_disk_path.gsub(%r{/$}, '')) } Settings.gitlab['repository_downloads_path'] = File.join(Settings.shared['path'], 'cache/archive') diff --git a/config/initializers/6_validations.rb b/config/initializers/6_validations.rb index 362a23164ab..ff6865608f0 100644 --- a/config/initializers/6_validations.rb +++ b/config/initializers/6_validations.rb @@ -37,6 +37,7 @@ def validate_storages_config end end +# Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/1237 def validate_storages_paths Gitlab::GitalyClient::StorageSettings.allow_disk_access do Gitlab.config.repositories.storages.each do |name, repository_storage| diff --git a/doc/api/pages_domains.md b/doc/api/pages_domains.md index 20275b902c6..da2ffcfe40a 100644 --- a/doc/api/pages_domains.md +++ b/doc/api/pages_domains.md @@ -122,11 +122,11 @@ POST /projects/:id/pages/domains | `key` | file/string | no | The certificate key in PEM format. | ```bash -curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --form="domain=ssl.domain.example" --form="certificate=@/path/to/cert.pem" --form="key=@/path/to/key.pem" https://gitlab.example.com/api/v4/projects/5/pages/domains +curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --form "domain=ssl.domain.example" --form "certificate=@/path/to/cert.pem" --form "key=@/path/to/key.pem" https://gitlab.example.com/api/v4/projects/5/pages/domains ``` ```bash -curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --form="domain=ssl.domain.example" --form="certificate=$CERT_PEM" --form="key=$KEY_PEM" https://gitlab.example.com/api/v4/projects/5/pages/domains +curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --form "domain=ssl.domain.example" --form "certificate=$CERT_PEM" --form "key=$KEY_PEM" https://gitlab.example.com/api/v4/projects/5/pages/domains ``` ```json @@ -158,11 +158,11 @@ PUT /projects/:id/pages/domains/:domain | `key` | file/string | no | The certificate key in PEM format. | ```bash -curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --form="certificate=@/path/to/cert.pem" --form="key=@/path/to/key.pem" https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example +curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --form "certificate=@/path/to/cert.pem" --form "key=@/path/to/key.pem" https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example ``` ```bash -curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --form="certificate=$CERT_PEM" --form="key=$KEY_PEM" https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example +curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --form "certificate=$CERT_PEM" --form "key=$KEY_PEM" https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example ``` ```json diff --git a/doc/api/search.md b/doc/api/search.md index 107ddaffa6a..9716f682ace 100644 --- a/doc/api/search.md +++ b/doc/api/search.md @@ -776,6 +776,15 @@ Example response: ### Scope: blobs +Filters are available for this scope: +- filename +- path +- extension + +to use a filter simply include it in your query like so: `a query filename:some_name*`. + +You may use wildcards (`*`) to use glob matching. + ```bash curl --request GET --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/6/search?scope=blobs&search=installation ``` diff --git a/doc/user/project/integrations/microsoft_teams.md b/doc/user/project/integrations/microsoft_teams.md index eaad2d5138a..5cf80a298ad 100644 --- a/doc/user/project/integrations/microsoft_teams.md +++ b/doc/user/project/integrations/microsoft_teams.md @@ -2,7 +2,7 @@ ## On Microsoft Teams -To enable Microsoft Teams integration you must create an incoming webhook integration on Microsoft Teams by following the steps described in this [document](https://msdn.microsoft.com/en-us/microsoft-teams/connectors). +To enable Microsoft Teams integration you must create an incoming webhook integration on Microsoft Teams by following the steps described in this [document](https://docs.microsoft.com/en-us/microsoftteams/platform/concepts/connectors#setting-up-a-custom-incoming-webhook). ## On GitLab diff --git a/lib/gitlab/file_finder.rb b/lib/gitlab/file_finder.rb index f42088f980e..af8270c8db8 100644 --- a/lib/gitlab/file_finder.rb +++ b/lib/gitlab/file_finder.rb @@ -14,14 +14,21 @@ module Gitlab end def find(query) - by_content = find_by_content(query) + query = Gitlab::Search::Query.new(query) do + filter :filename, matcher: ->(filter, blob) { blob.filename =~ /#{filter[:regex_value]}$/i } + filter :path, matcher: ->(filter, blob) { blob.filename =~ /#{filter[:regex_value]}/i } + filter :extension, matcher: ->(filter, blob) { blob.filename =~ /\.#{filter[:regex_value]}$/i } + end + + by_content = find_by_content(query.term) already_found = Set.new(by_content.map(&:filename)) - by_filename = find_by_filename(query, except: already_found) + by_filename = find_by_filename(query.term, except: already_found) + + files = (by_content + by_filename) + .sort_by(&:filename) - (by_content + by_filename) - .sort_by(&:filename) - .map { |blob| [blob.filename, blob] } + query.filter_results(files).map { |blob| [blob.filename, blob] } end private diff --git a/lib/gitlab/git/lfs_changes.rb b/lib/gitlab/git/lfs_changes.rb index f3cc388ea41..f0fab1e76a3 100644 --- a/lib/gitlab/git/lfs_changes.rb +++ b/lib/gitlab/git/lfs_changes.rb @@ -7,67 +7,11 @@ module Gitlab end def new_pointers(object_limit: nil, not_in: nil) - @repository.gitaly_migrate(:blob_get_new_lfs_pointers) do |is_enabled| - if is_enabled - @repository.gitaly_blob_client.get_new_lfs_pointers(@newrev, object_limit, not_in) - else - git_new_pointers(object_limit, not_in) - end - end + @repository.gitaly_blob_client.get_new_lfs_pointers(@newrev, object_limit, not_in) end def all_pointers - @repository.gitaly_migrate(:blob_get_all_lfs_pointers) do |is_enabled| - if is_enabled - @repository.gitaly_blob_client.get_all_lfs_pointers(@newrev) - else - git_all_pointers - end - end - end - - private - - def git_new_pointers(object_limit, not_in) - @new_pointers ||= begin - rev_list.new_objects(rev_list_params(not_in: not_in)) do |object_ids| - object_ids = object_ids.take(object_limit) if object_limit - - Gitlab::Git::Blob.batch_lfs_pointers(@repository, object_ids) - end - end - end - - def git_all_pointers - params = {} - if rev_list_supports_new_options? - params[:options] = ["--filter=blob:limit=#{Gitlab::Git::Blob::LFS_POINTER_MAX_SIZE}"] - end - - rev_list.all_objects(rev_list_params(params)) do |object_ids| - Gitlab::Git::Blob.batch_lfs_pointers(@repository, object_ids) - end - end - - def rev_list - Gitlab::Git::RevList.new(@repository, newrev: @newrev) - end - - # We're passing the `--in-commit-order` arg to ensure we don't wait - # for git to traverse all commits before returning pointers. - # This is required in order to improve the performance of LFS integrity check - def rev_list_params(params = {}) - params[:options] ||= [] - params[:options] << "--in-commit-order" if rev_list_supports_new_options? - params[:require_path] = true - - params - end - - def rev_list_supports_new_options? - return @option_supported if defined?(@option_supported) - - @option_supported = Gitlab::Git.version >= Gitlab::VersionInfo.parse('2.16.0') + @repository.gitaly_blob_client.get_all_lfs_pointers(@newrev) end end end diff --git a/lib/gitlab/git/version.rb b/lib/gitlab/git/version.rb index 11184ca3457..1e14e8b652a 100644 --- a/lib/gitlab/git/version.rb +++ b/lib/gitlab/git/version.rb @@ -4,7 +4,7 @@ module Gitlab extend Gitlab::Git::Popen def self.git_version - Gitlab::VersionInfo.parse(popen(%W(#{Gitlab.config.git.bin_path} --version), nil).first) + Gitlab::VersionInfo.parse(Gitaly::Server.all.first.git_binary_version) end end end diff --git a/lib/gitlab/health_checks/fs_shards_check.rb b/lib/gitlab/health_checks/fs_shards_check.rb index fcbf266b80b..050fe7a5173 100644 --- a/lib/gitlab/health_checks/fs_shards_check.rb +++ b/lib/gitlab/health_checks/fs_shards_check.rb @@ -1,5 +1,6 @@ module Gitlab module HealthChecks + # Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/1218 class FsShardsCheck extend BaseAbstractCheck RANDOM_STRING = SecureRandom.hex(1000).freeze diff --git a/lib/gitlab/search/parsed_query.rb b/lib/gitlab/search/parsed_query.rb new file mode 100644 index 00000000000..23595f23f01 --- /dev/null +++ b/lib/gitlab/search/parsed_query.rb @@ -0,0 +1,23 @@ +module Gitlab + module Search + class ParsedQuery + attr_reader :term, :filters + + def initialize(term, filters) + @term = term + @filters = filters + end + + def filter_results(results) + filters = @filters.reject { |filter| filter[:matcher].nil? } + return unless filters + + results.select do |result| + filters.all? do |filter| + filter[:matcher].call(filter, result) + end + end + end + end + end +end diff --git a/lib/gitlab/search/query.rb b/lib/gitlab/search/query.rb new file mode 100644 index 00000000000..8583bce7792 --- /dev/null +++ b/lib/gitlab/search/query.rb @@ -0,0 +1,55 @@ +module Gitlab + module Search + class Query < SimpleDelegator + def initialize(query, filter_opts = {}, &block) + @raw_query = query.dup + @filters = [] + @filter_options = { default_parser: :downcase.to_proc }.merge(filter_opts) + + self.instance_eval(&block) if block_given? + + @query = Gitlab::Search::ParsedQuery.new(*extract_filters) + # set the ParsedQuery as our default delegator thanks to SimpleDelegator + super(@query) + end + + private + + def filter(name, **attributes) + filter = { parser: @filter_options[:default_parser], name: name }.merge(attributes) + + @filters << filter + end + + def filter_options(**options) + @filter_options.merge!(options) + end + + def extract_filters + fragments = [] + + filters = @filters.each_with_object([]) do |filter, parsed_filters| + match = @raw_query.split.find { |part| part =~ /\A#{filter[:name]}:/ } + next unless match + + input = match.split(':')[1..-1].join + next if input.empty? + + filter[:value] = parse_filter(filter, input) + filter[:regex_value] = Regexp.escape(filter[:value]).gsub('\*', '.*?') + fragments << match + + parsed_filters << filter + end + + query = (@raw_query.split - fragments).join(' ') + + [query, filters] + end + + def parse_filter(filter, input) + filter[:parser].call(input) + end + end + end +end diff --git a/lib/gitlab/setup_helper.rb b/lib/gitlab/setup_helper.rb index 4a87f43597e..b2d75aac1d0 100644 --- a/lib/gitlab/setup_helper.rb +++ b/lib/gitlab/setup_helper.rb @@ -24,6 +24,7 @@ module Gitlab address = val['gitaly_address'] end + # https://gitlab.com/gitlab-org/gitaly/issues/1238 Gitlab::GitalyClient::StorageSettings.allow_disk_access do storages << { name: key, path: val.legacy_disk_path } end diff --git a/spec/javascripts/vue_shared/components/expand_button_spec.js b/spec/javascripts/vue_shared/components/expand_button_spec.js index af9693c48fd..98fee9a74a5 100644 --- a/spec/javascripts/vue_shared/components/expand_button_spec.js +++ b/spec/javascripts/vue_shared/components/expand_button_spec.js @@ -19,7 +19,7 @@ describe('expand button', () => { }); it('renders a collpased button', () => { - expect(vm.$el.textContent.trim()).toEqual('...'); + expect(vm.$children[0].iconTestClass).toEqual('ic-ellipsis_h'); }); it('hides expander on click', done => { diff --git a/spec/lib/gitlab/file_finder_spec.rb b/spec/lib/gitlab/file_finder_spec.rb index d6d9e4001a3..b49c5817131 100644 --- a/spec/lib/gitlab/file_finder_spec.rb +++ b/spec/lib/gitlab/file_finder_spec.rb @@ -3,11 +3,29 @@ require 'spec_helper' describe Gitlab::FileFinder do describe '#find' do let(:project) { create(:project, :public, :repository) } + subject { described_class.new(project, project.default_branch) } it_behaves_like 'file finder' do - subject { described_class.new(project, project.default_branch) } let(:expected_file_by_name) { 'files/images/wm.svg' } let(:expected_file_by_content) { 'CHANGELOG' } end + + it 'filters by name' do + results = subject.find('files filename:wm.svg') + + expect(results.count).to eq(1) + end + + it 'filters by path' do + results = subject.find('white path:images') + + expect(results.count).to eq(1) + end + + it 'filters by extension' do + results = subject.find('files extension:svg') + + expect(results.count).to eq(1) + end end end diff --git a/spec/lib/gitlab/git/lfs_changes_spec.rb b/spec/lib/gitlab/git/lfs_changes_spec.rb index d0dd8c6303f..c5e7ab959b2 100644 --- a/spec/lib/gitlab/git/lfs_changes_spec.rb +++ b/spec/lib/gitlab/git/lfs_changes_spec.rb @@ -1,50 +1,19 @@ require 'spec_helper' describe Gitlab::Git::LfsChanges do - let(:project) { create(:project, :repository) } + set(:project) { create(:project, :repository) } let(:newrev) { '54fcc214b94e78d7a41a9a8fe6d87a5e59500e51' } let(:blob_object_id) { '0c304a93cb8430108629bbbcaa27db3343299bc0' } subject { described_class.new(project.repository, newrev) } describe '#new_pointers' do - shared_examples 'new pointers' do - it 'filters new objects to find lfs pointers' do - expect(subject.new_pointers(not_in: []).first.id).to eq(blob_object_id) - end - - it 'limits new_objects using object_limit' do - expect(subject.new_pointers(object_limit: 1)).to eq([]) - end - end - - context 'with gitaly enabled' do - it_behaves_like 'new pointers' + it 'filters new objects to find lfs pointers' do + expect(subject.new_pointers(not_in: []).first.id).to eq(blob_object_id) end - context 'with gitaly disabled', :skip_gitaly_mock do - it_behaves_like 'new pointers' - - it 'uses rev-list to find new objects' do - rev_list = double - allow(Gitlab::Git::RevList).to receive(:new).and_return(rev_list) - - expect(rev_list).to receive(:new_objects).and_return([]) - - subject.new_pointers - end - end - end - - describe '#all_pointers', :skip_gitaly_mock do - it 'uses rev-list to find all objects' do - rev_list = double - allow(Gitlab::Git::RevList).to receive(:new).and_return(rev_list) - allow(rev_list).to receive(:all_objects).and_yield([blob_object_id]) - - expect(Gitlab::Git::Blob).to receive(:batch_lfs_pointers).with(project.repository, [blob_object_id]) - - subject.all_pointers + it 'limits new_objects using object_limit' do + expect(subject.new_pointers(object_limit: 1)).to eq([]) end end end diff --git a/spec/lib/gitlab/search/query_spec.rb b/spec/lib/gitlab/search/query_spec.rb new file mode 100644 index 00000000000..2d00428fffa --- /dev/null +++ b/spec/lib/gitlab/search/query_spec.rb @@ -0,0 +1,39 @@ +require 'spec_helper' + +describe Gitlab::Search::Query do + let(:query) { 'base filter:wow anotherfilter:noway name:maybe other:mmm leftover' } + let(:subject) do + described_class.new(query) do + filter :filter + filter :name, parser: :upcase.to_proc + filter :other + end + end + + it { expect(described_class).to be < SimpleDelegator } + + it 'leaves undefined filters in the main query' do + expect(subject.term).to eq('base anotherfilter:noway leftover') + end + + it 'parses filters' do + expect(subject.filters.count).to eq(3) + expect(subject.filters.map { |f| f[:value] }).to match_array(%w[wow MAYBE mmm]) + end + + context 'with an empty filter' do + let(:query) { 'some bar name: baz' } + + it 'ignores empty filters' do + expect(subject.term).to eq('some bar name: baz') + end + end + + context 'with a pipe' do + let(:query) { 'base | nofilter' } + + it 'does not escape the pipe' do + expect(subject.term).to eq(query) + end + end +end diff --git a/spec/requests/api/search_spec.rb b/spec/requests/api/search_spec.rb index aca4aa40027..f8e468be170 100644 --- a/spec/requests/api/search_spec.rb +++ b/spec/requests/api/search_spec.rb @@ -312,6 +312,30 @@ describe API::Search do end it_behaves_like 'response is correct', schema: 'public_api/v4/blobs', size: 2 + + context 'filters' do + it 'by filename' do + get api("/projects/#{repo_project.id}/search", user), scope: 'blobs', search: 'mon filename:PROCESS.md' + + expect(response).to have_gitlab_http_status(200) + expect(json_response.size).to eq(2) + expect(json_response.first['filename']).to eq('PROCESS.md') + end + + it 'by path' do + get api("/projects/#{repo_project.id}/search", user), scope: 'blobs', search: 'mon path:markdown' + + expect(response).to have_gitlab_http_status(200) + expect(json_response.size).to eq(8) + end + + it 'by extension' do + get api("/projects/#{repo_project.id}/search", user), scope: 'blobs', search: 'mon extension:md' + + expect(response).to have_gitlab_http_status(200) + expect(json_response.size).to eq(11) + end + end end end end |
