Commit 7f57fe5034f6fdfbdd4e29745b50e7bfa1576bf5
Committed by
Dmitriy Zaporozhets
1 parent
4353babe
Exists in
master
and in
4 other branches
Implemented code search feature
Showing
11 changed files
with
98 additions
and
7 deletions
Show diff stats
.travis.yml
Gemfile
... | ... | @@ -23,7 +23,7 @@ gem 'omniauth-github' |
23 | 23 | |
24 | 24 | # Extracting information from a git repository |
25 | 25 | # We cannot use original git since some bugs |
26 | -gem "grit", '~> 2.5.0', git: 'https://github.com/gitlabhq/grit.git', ref: '42297cdcee16284d2e4eff23d41377f52fc28b9d' | |
26 | +gem "grit", '~> 2.5.0', git: 'https://github.com/gitlabhq/grit.git' | |
27 | 27 | gem 'gitlab_git', '~> 1.0.6' |
28 | 28 | |
29 | 29 | # Ruby/Rack Git Smart-HTTP Server Handler | ... | ... |
Gemfile.lock
... | ... | @@ -8,8 +8,7 @@ GIT |
8 | 8 | |
9 | 9 | GIT |
10 | 10 | remote: https://github.com/gitlabhq/grit.git |
11 | - revision: 42297cdcee16284d2e4eff23d41377f52fc28b9d | |
12 | - ref: 42297cdcee16284d2e4eff23d41377f52fc28b9d | |
11 | + revision: e873bb84ac3c4f8249311490d6a7c6ac9127625f | |
13 | 12 | specs: |
14 | 13 | grit (2.5.0) |
15 | 14 | diff-lcs (~> 1.1) | ... | ... |
app/contexts/search_context.rb
... | ... | @@ -10,7 +10,11 @@ class SearchContext |
10 | 10 | |
11 | 11 | return result unless query.present? |
12 | 12 | |
13 | - result[:projects] = Project.where(id: project_ids).search(query).limit(10) | |
13 | + projects = Project.where(id: project_ids) | |
14 | + result[:projects] = projects.search(query).limit(10) | |
15 | + if projects.length == 1 | |
16 | + result[:snippets] = projects.first.files(query, params[:branch_ref]) | |
17 | + end | |
14 | 18 | result[:merge_requests] = MergeRequest.where(project_id: project_ids).search(query).limit(10) |
15 | 19 | result[:issues] = Issue.where(project_id: project_ids).search(query).limit(10) |
16 | 20 | result[:wiki_pages] = [] |
... | ... | @@ -22,7 +26,8 @@ class SearchContext |
22 | 26 | projects: [], |
23 | 27 | merge_requests: [], |
24 | 28 | issues: [], |
25 | - wiki_pages: [] | |
29 | + wiki_pages: [], | |
30 | + snippets: [] | |
26 | 31 | } |
27 | 32 | end |
28 | 33 | end | ... | ... |
app/controllers/search_controller.rb
app/models/project.rb
... | ... | @@ -411,4 +411,15 @@ class Project < ActiveRecord::Base |
411 | 411 | !(forked_project_link.nil? || forked_project_link.forked_from_project.nil?) |
412 | 412 | end |
413 | 413 | |
414 | + def files(query, treeish) | |
415 | + snippets = [] | |
416 | + tree = treeish.present? ? treeish : default_branch | |
417 | + if repository && !tree.nil? | |
418 | + greps = repository.repo.grep(query, 3, tree) | |
419 | + greps.each do |g| | |
420 | + snippets << Gitlab::BlobSnippet.new(self, tree, g.content, g.startline, g.filename) | |
421 | + end | |
422 | + end | |
423 | + snippets | |
424 | + end | |
414 | 425 | end | ... | ... |
app/views/layouts/_search.html.haml
... | ... | @@ -3,4 +3,13 @@ |
3 | 3 | = text_field_tag "search", nil, placeholder: "Search", class: "search-input" |
4 | 4 | = hidden_field_tag :group_id, @group.try(:id) |
5 | 5 | = hidden_field_tag :project_id, @project.try(:id) |
6 | - .search-autocomplete-json.hide{:'data-autocomplete-opts' => search_autocomplete_source } | |
6 | + - if @ref | |
7 | + - @branch_ref = @ref | |
8 | + - else | |
9 | + - @branch_ref = @project.try(:default_branch) | |
10 | + - if @branch_ref.blank? | |
11 | + - @branch_ref = 'master' | |
12 | + = hidden_field_tag :branch_ref, @branch_ref | |
13 | + - if ENV['RAILS_ENV'] == 'test' | |
14 | + = submit_tag 'Go' | |
15 | + .search-autocomplete-json.hide{:'data-autocomplete-opts' => search_autocomplete_source } | |
7 | 16 | \ No newline at end of file | ... | ... |
app/views/search/_result.html.haml
... | ... | @@ -32,6 +32,15 @@ |
32 | 32 | %strong.term |
33 | 33 | = truncate wiki_page.title, length: 50 |
34 | 34 | %span.light (#{wiki_page.project.name_with_namespace}) |
35 | + - @snippets.each do |snippet| | |
36 | + %li | |
37 | + code: | |
38 | + = link_to project_blob_path(snippet.project, tree_join(snippet.tree, snippet.filename), :anchor => "L" + snippet.startline.to_s) do | |
39 | + %strong.term | |
40 | + = snippet.filename | |
41 | + .file_content.code | |
42 | + %div{class: user_color_scheme_class} | |
43 | + = raw snippet.colorize( formatter: :gitlab, options: { first_line_number: snippet.startline } ) | |
35 | 44 | |
36 | 45 | :javascript |
37 | 46 | $(function() { | ... | ... |
... | ... | @@ -0,0 +1,9 @@ |
1 | +Feature: Project Search code | |
2 | + Background: | |
3 | + Given I sign in as a user | |
4 | + And I own project "Shop" | |
5 | + Given I visit project source page | |
6 | + | |
7 | + Scenario: Search for term "Welcome to Gitlab" | |
8 | + When I search for term "Welcome to Gitlab" | |
9 | + Then I should see files from repository containing "Welcome to Gitlab" | ... | ... |
... | ... | @@ -0,0 +1,16 @@ |
1 | +class ProjectSearchCode < Spinach::FeatureSteps | |
2 | + include SharedAuthentication | |
3 | + include SharedProject | |
4 | + include SharedPaths | |
5 | + | |
6 | + When 'I search for term "Welcome to Gitlab"' do | |
7 | + fill_in "search", with: "Welcome to Gitlab" | |
8 | + click_button "Go" | |
9 | + end | |
10 | + | |
11 | + Then 'I should see files from repository containing "Welcome to Gitlab"' do | |
12 | + page.should have_content "Welcome to Gitlab" | |
13 | + page.should have_content "GitLab is a free project and repository management application" | |
14 | + end | |
15 | + | |
16 | +end | ... | ... |
... | ... | @@ -0,0 +1,32 @@ |
1 | +module Gitlab | |
2 | + class BlobSnippet | |
3 | + include Linguist::BlobHelper | |
4 | + | |
5 | + attr_accessor :project | |
6 | + attr_accessor :tree | |
7 | + attr_accessor :lines | |
8 | + attr_accessor :filename | |
9 | + attr_accessor :startline | |
10 | + | |
11 | + def initialize(project, tree, lines, startline, filename) | |
12 | + @project, @tree, @lines, @startline, @filename = project, tree, lines, startline, filename | |
13 | + end | |
14 | + | |
15 | + def data | |
16 | + lines.join("\n") | |
17 | + end | |
18 | + | |
19 | + def name | |
20 | + filename | |
21 | + end | |
22 | + | |
23 | + def size | |
24 | + data.length | |
25 | + end | |
26 | + | |
27 | + def mode | |
28 | + nil | |
29 | + end | |
30 | + | |
31 | + end | |
32 | +end | |
0 | 33 | \ No newline at end of file | ... | ... |