Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Jérome Perrin
gitlab-ce
Commits
50d2eae8
Commit
50d2eae8
authored
Jan 09, 2014
by
Dmitriy Zaporozhets
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'refactor/search_context' of /home/git/repositories/gitlab/gitlabhq
parents
cb589d23
a9d7efa1
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
137 additions
and
128 deletions
+137
-128
app/assets/stylesheets/generic/nav.scss
app/assets/stylesheets/generic/nav.scss
+1
-4
app/contexts/search/global_context.rb
app/contexts/search/global_context.rb
+40
-0
app/contexts/search/project_context.rb
app/contexts/search/project_context.rb
+37
-0
app/contexts/search_context.rb
app/contexts/search_context.rb
+0
-42
app/controllers/search_controller.rb
app/controllers/search_controller.rb
+8
-28
app/views/search/_filter.html.haml
app/views/search/_filter.html.haml
+2
-2
app/views/search/_global_results.html.haml
app/views/search/_global_results.html.haml
+3
-3
app/views/search/_project_results.html.haml
app/views/search/_project_results.html.haml
+6
-6
app/views/search/_results.html.haml
app/views/search/_results.html.haml
+8
-4
spec/contexts/search_context_spec.rb
spec/contexts/search_context_spec.rb
+32
-21
spec/controllers/search_controller_spec.rb
spec/controllers/search_controller_spec.rb
+0
-18
No files found.
app/assets/stylesheets/generic/nav.scss
View file @
50d2eae8
...
@@ -7,12 +7,9 @@
...
@@ -7,12 +7,9 @@
background
:
$primary_color
;
background
:
$primary_color
;
}
}
>
li
>
a
{
@include
border-radius
(
0
);
}
&
.nav-stacked
{
&
.nav-stacked
{
>
li
>
a
{
>
li
>
a
{
@include
border-radius
(
0
);
border-left
:
4px
solid
#EEE
;
border-left
:
4px
solid
#EEE
;
padding
:
12px
;
padding
:
12px
;
color
:
#777
;
color
:
#777
;
...
...
app/contexts/search/global_context.rb
0 → 100644
View file @
50d2eae8
module
Search
class
GlobalContext
attr_accessor
:current_user
,
:params
def
initialize
(
user
,
params
)
@current_user
,
@params
=
user
,
params
.
dup
end
def
execute
query
=
params
[
:search
]
query
=
Shellwords
.
shellescape
(
query
)
if
query
.
present?
return
result
unless
query
.
present?
authorized_projects_ids
=
[]
authorized_projects_ids
+=
current_user
.
authorized_projects
.
pluck
(
:id
)
if
current_user
authorized_projects_ids
+=
Project
.
public_or_internal_only
(
current_user
).
pluck
(
:id
)
group
=
Group
.
find_by_id
(
params
[
:group_id
])
if
params
[
:group_id
].
present?
projects
=
Project
.
where
(
id:
authorized_projects_ids
)
projects
=
projects
.
where
(
namespace_id:
group
.
id
)
if
group
projects
=
projects
.
search
(
query
)
project_ids
=
projects
.
pluck
(
:id
)
result
[
:projects
]
=
projects
.
limit
(
20
)
result
[
:merge_requests
]
=
MergeRequest
.
in_projects
(
project_ids
).
search
(
query
).
order
(
'updated_at DESC'
).
limit
(
20
)
result
[
:issues
]
=
Issue
.
where
(
project_id:
project_ids
).
search
(
query
).
order
(
'updated_at DESC'
).
limit
(
20
)
result
[
:total_results
]
=
%w(projects issues merge_requests)
.
sum
{
|
items
|
result
[
items
.
to_sym
].
size
}
result
end
def
result
@result
||=
{
projects:
[],
merge_requests:
[],
issues:
[],
total_results:
0
,
}
end
end
end
app/contexts/search/project_context.rb
0 → 100644
View file @
50d2eae8
module
Search
class
ProjectContext
attr_accessor
:project
,
:current_user
,
:params
def
initialize
(
project
,
user
,
params
)
@project
,
@current_user
,
@params
=
project
,
user
,
params
.
dup
end
def
execute
query
=
params
[
:search
]
query
=
Shellwords
.
shellescape
(
query
)
if
query
.
present?
return
result
unless
query
.
present?
if
params
[
:search_code
].
present?
blobs
=
project
.
repository
.
search_files
(
query
,
params
[
:repository_ref
])
unless
project
.
empty_repo?
blobs
=
Kaminari
.
paginate_array
(
blobs
).
page
(
params
[
:page
]).
per
(
20
)
result
[
:blobs
]
=
blobs
result
[
:total_results
]
=
blobs
.
total_count
else
result
[
:merge_requests
]
=
project
.
merge_requests
.
search
(
query
).
order
(
'updated_at DESC'
).
limit
(
20
)
result
[
:issues
]
=
project
.
issues
.
search
(
query
).
order
(
'updated_at DESC'
).
limit
(
20
)
result
[
:total_results
]
=
%w(issues merge_requests)
.
sum
{
|
items
|
result
[
items
.
to_sym
].
size
}
end
result
end
def
result
@result
||=
{
merge_requests:
[],
issues:
[],
blobs:
[],
total_results:
0
,
}
end
end
end
app/contexts/search_context.rb
deleted
100644 → 0
View file @
cb589d23
class
SearchContext
attr_accessor
:project_ids
,
:current_user
,
:params
def
initialize
(
project_ids
,
user
,
params
)
@project_ids
,
@current_user
,
@params
=
project_ids
,
user
,
params
.
dup
end
def
execute
query
=
params
[
:search
]
query
=
Shellwords
.
shellescape
(
query
)
if
query
.
present?
return
result
unless
query
.
present?
visibility_levels
=
@current_user
?
[
Gitlab
::
VisibilityLevel
::
INTERNAL
,
Gitlab
::
VisibilityLevel
::
PUBLIC
]
:
[
Gitlab
::
VisibilityLevel
::
PUBLIC
]
result
[
:projects
]
=
Project
.
where
(
"projects.id in (?) OR projects.visibility_level in (?)"
,
project_ids
,
visibility_levels
).
search
(
query
).
limit
(
20
)
# Search inside single project
single_project_search
(
Project
.
where
(
id:
project_ids
),
query
)
result
end
def
single_project_search
(
projects
,
query
)
project
=
projects
.
first
if
projects
.
length
==
1
if
params
[
:search_code
].
present?
result
[
:blobs
]
=
project
.
repository
.
search_files
(
query
,
params
[
:repository_ref
])
unless
project
.
empty_repo?
else
result
[
:merge_requests
]
=
MergeRequest
.
in_projects
(
project_ids
).
search
(
query
).
order
(
'updated_at DESC'
).
limit
(
20
)
result
[
:issues
]
=
Issue
.
where
(
project_id:
project_ids
).
search
(
query
).
order
(
'updated_at DESC'
).
limit
(
20
)
result
[
:wiki_pages
]
=
[]
end
end
def
result
@result
||=
{
projects:
[],
merge_requests:
[],
issues:
[],
wiki_pages:
[],
blobs:
[]
}
end
end
app/controllers/search_controller.rb
View file @
50d2eae8
class
SearchController
<
ApplicationController
class
SearchController
<
ApplicationController
def
show
def
show
project_id
=
params
[
:project_id
]
@project
=
Project
.
find_by_id
(
params
[
:project_id
])
if
params
[
:project_id
].
present?
group_id
=
params
[
:group_id
]
@group
=
Group
.
find_by_id
(
params
[
:group_id
])
if
params
[
:group_id
].
present?
project_ids
=
find_project_ids
(
group_id
,
project_id
)
if
@project
return
access_denied!
unless
can?
(
current_user
,
:download_code
,
@project
)
result
=
SearchContext
.
new
(
project_ids
,
current_user
,
params
).
execute
@search_results
=
Search
::
ProjectContext
.
new
(
@project
,
current_user
,
params
).
execute
else
@projects
=
result
[
:projects
]
@search_results
=
Search
::
GlobalContext
.
new
(
current_user
,
params
).
execute
@merge_requests
=
result
[
:merge_requests
]
@issues
=
result
[
:issues
]
@wiki_pages
=
result
[
:wiki_pages
]
@blobs
=
Kaminari
.
paginate_array
(
result
[
:blobs
]).
page
(
params
[
:page
]).
per
(
20
)
@total_results
=
@projects
.
count
+
@merge_requests
.
count
+
@issues
.
count
+
@wiki_pages
.
count
+
@blobs
.
total_count
end
private
def
find_project_ids
(
group_id
,
project_id
)
project_ids
=
current_user
.
authorized_projects
.
map
(
&
:id
)
if
group_id
.
present?
@group
=
Group
.
find
(
group_id
)
group_project_ids
=
@group
.
projects
.
map
(
&
:id
)
project_ids
.
select!
{
|
id
|
group_project_ids
.
include?
(
id
)
}
elsif
project_id
.
present?
@project
=
Project
.
find
(
project_id
)
project_ids
=
@project
.
public?
?
[
@project
.
id
]
:
project_ids
.
select
{
|
id
|
id
==
project_id
.
to_i
}
end
end
project_ids
end
end
end
end
app/views/search/_filter.html.haml
View file @
50d2eae8
...
@@ -9,7 +9,7 @@
...
@@ -9,7 +9,7 @@
%b
.caret
%b
.caret
%ul
.dropdown-menu
%ul
.dropdown-menu
%li
%li
=
link_to
search_path
(
group_id:
nil
)
do
=
link_to
search_path
(
group_id:
nil
,
search:
params
[
:search
]
)
do
Any
Any
-
current_user
.
authorized_groups
.
sort_by
(
&
:name
).
each
do
|
group
|
-
current_user
.
authorized_groups
.
sort_by
(
&
:name
).
each
do
|
group
|
%li
%li
...
@@ -27,7 +27,7 @@
...
@@ -27,7 +27,7 @@
%b
.caret
%b
.caret
%ul
.dropdown-menu
%ul
.dropdown-menu
%li
%li
=
link_to
search_path
(
project_id:
nil
)
do
=
link_to
search_path
(
project_id:
nil
,
search:
params
[
:search
]
)
do
Any
Any
-
current_user
.
authorized_projects
.
sort_by
(
&
:name_with_namespace
).
each
do
|
project
|
-
current_user
.
authorized_projects
.
sort_by
(
&
:name_with_namespace
).
each
do
|
project
|
%li
%li
...
...
app/views/search/_global_results.html.haml
View file @
50d2eae8
.search_results
.search_results
%ul
.bordered-list
%ul
.bordered-list
=
render
partial:
"search/results/project"
,
collection:
@
projects
=
render
partial:
"search/results/project"
,
collection:
@
search_results
[
:projects
]
=
render
partial:
"search/results/merge_request"
,
collection:
@
merge_requests
=
render
partial:
"search/results/merge_request"
,
collection:
@
search_results
[
:merge_requests
]
=
render
partial:
"search/results/issue"
,
collection:
@
issues
=
render
partial:
"search/results/issue"
,
collection:
@
search_results
[
:issues
]
app/views/search/_project_results.html.haml
View file @
50d2eae8
%ul
.nav.nav-
pills
%ul
.nav.nav-
tabs.append-bottom-10
%li
{
class:
(
"active"
if
params
[
:search_code
].
present?
)}
%li
{
class:
(
"active"
if
params
[
:search_code
].
present?
)}
=
link_to
search_path
(
params
.
merge
(
search_code:
true
))
do
=
link_to
search_path
(
params
.
merge
(
search_code:
true
))
do
Repository Code
Repository Code
%li
{
class:
(
"active"
if
params
[
:search_code
].
blank?
)}
%li
{
class:
(
"active"
if
params
[
:search_code
].
blank?
)}
=
link_to
search_path
(
params
.
merge
(
search_code:
nil
))
do
=
link_to
search_path
(
params
.
merge
(
search_code:
nil
))
do
Everything else
Issues and Merge requests
.search_results
.search_results
-
if
params
[
:search_code
].
present?
-
if
params
[
:search_code
].
present?
.blob-results
.blob-results
=
render
partial:
"search/results/blob"
,
collection:
@
blobs
=
render
partial:
"search/results/blob"
,
collection:
@
search_results
[
:blobs
]
=
paginate
@
blobs
,
theme:
'gitlab'
=
paginate
@
search_results
[
:blobs
]
,
theme:
'gitlab'
-
else
-
else
%ul
.bordered-list
%ul
.bordered-list
=
render
partial:
"search/results/merge_request"
,
collection:
@
merge_requests
=
render
partial:
"search/results/merge_request"
,
collection:
@
search_results
[
:merge_requests
]
=
render
partial:
"search/results/issue"
,
collection:
@
issues
=
render
partial:
"search/results/issue"
,
collection:
@
search_results
[
:issues
]
app/views/search/_results.html.haml
View file @
50d2eae8
%fieldset
%h4
%legend
#{
@search_results
[
:total_results
]
}
results found
Search results
-
if
@project
%span
.cgray
(
#{
@total_results
}
)
for
#{
link_to
@project
.
name_with_namespace
,
@project
}
-
elsif
@group
for
#{
link_to
@group
.
name
,
@group
}
%hr
-
if
@project
-
if
@project
=
render
"project_results"
=
render
"project_results"
...
...
spec/contexts/search_context_spec.rb
View file @
50d2eae8
require
'spec_helper'
require
'spec_helper'
describe
SearchContext
do
describe
'Search::GlobalContext'
do
let
(
:found_namespace
)
{
create
(
:namespace
,
name:
'searchable namespace'
,
path
:'another_thing'
)
}
let
(
:found_namespace
)
{
create
(
:namespace
,
name:
'searchable namespace'
,
path
:'another_thing'
)
}
let
(
:user
)
{
create
(
:user
,
namespace:
found_namespace
)
}
let
(
:user
)
{
create
(
:user
,
namespace:
found_namespace
)
}
let!
(
:found_project
)
{
create
(
:project
,
name:
'searchable_project'
,
creator_id:
user
.
id
,
namespace:
found_namespace
,
visibility_level:
Gitlab
::
VisibilityLevel
::
PRIVATE
)
}
let!
(
:found_project
)
{
create
(
:project
,
name:
'searchable_project'
,
creator_id:
user
.
id
,
namespace:
found_namespace
,
visibility_level:
Gitlab
::
VisibilityLevel
::
PRIVATE
)
}
let
(
:unfound_namespace
)
{
create
(
:namespace
,
name:
'unfound namespace'
,
path:
'yet_something_else'
)
}
let
(
:unfound_namespace
)
{
create
(
:namespace
,
name:
'unfound namespace'
,
path:
'yet_something_else'
)
}
let!
(
:unfound_project
)
{
create
(
:project
,
name:
'unfound_project'
,
creator_id:
user
.
id
,
namespace:
unfound_namespace
,
visibility_level:
Gitlab
::
VisibilityLevel
::
PRIVATE
)
}
let!
(
:unfound_project
)
{
create
(
:project
,
name:
'unfound_project'
,
creator_id:
user
.
id
,
namespace:
unfound_namespace
,
visibility_level:
Gitlab
::
VisibilityLevel
::
PRIVATE
)
}
let
(
:internal_namespace
)
{
create
(
:namespace
,
path:
'something_internal'
,
name:
'searchable internal namespace'
)
}
let
(
:internal_namespace
)
{
create
(
:namespace
,
path:
'something_internal'
,
name:
'searchable internal namespace'
)
}
let
(
:internal_user
)
{
create
(
:user
,
namespace:
internal_namespace
)
}
let
(
:internal_user
)
{
create
(
:user
,
namespace:
internal_namespace
)
}
let!
(
:internal_project
)
{
create
(
:project
,
name:
'searchable_internal_project'
,
creator_id:
internal_user
.
id
,
namespace:
internal_namespace
,
visibility_level:
Gitlab
::
VisibilityLevel
::
INTERNAL
)
}
let!
(
:internal_project
)
{
create
(
:project
,
name:
'searchable_internal_project'
,
creator_id:
internal_user
.
id
,
namespace:
internal_namespace
,
visibility_level:
Gitlab
::
VisibilityLevel
::
INTERNAL
)
}
let
(
:public_namespace
)
{
create
(
:namespace
,
path:
'something_public'
,
name:
'searchable public namespace'
)
}
let
(
:public_namespace
)
{
create
(
:namespace
,
path:
'something_public'
,
name:
'searchable public namespace'
)
}
let
(
:public_user
)
{
create
(
:user
,
namespace:
public_namespace
)
}
let
(
:public_user
)
{
create
(
:user
,
namespace:
public_namespace
)
}
let!
(
:public_project
)
{
create
(
:project
,
name:
'searchable_public_project'
,
creator_id:
public_user
.
id
,
namespace:
public_namespace
,
visibility_level:
Gitlab
::
VisibilityLevel
::
PUBLIC
)
}
let!
(
:public_project
)
{
create
(
:project
,
name:
'searchable_public_project'
,
creator_id:
public_user
.
id
,
namespace:
public_namespace
,
visibility_level:
Gitlab
::
VisibilityLevel
::
PUBLIC
)
}
describe
'#execute'
do
describe
'#execute'
do
it
'public projects should be searchable'
do
context
'unauthenticated'
do
context
=
SearchContext
.
new
([
found_project
.
id
],
nil
,
{
search_code:
false
,
search:
"searchable"
})
it
'should return public projects only'
do
results
=
context
.
execute
context
=
Search
::
GlobalContext
.
new
(
nil
,
search:
"searchable"
)
results
[
:projects
].
should
==
[
found_project
,
public_project
]
results
=
context
.
execute
results
[
:projects
].
should
have
(
1
).
items
results
[
:projects
].
should
include
(
public_project
)
end
end
end
it
'internal projects should be searchable'
do
context
'authenticated'
do
context
=
SearchContext
.
new
([
found_project
.
id
],
user
,
{
search_code:
false
,
search:
"searchable"
})
it
'should return public, internal and private projects'
do
results
=
context
.
execute
context
=
Search
::
GlobalContext
.
new
(
user
,
search:
"searchable"
)
# can't seem to rely on the return order, so check this way
results
=
context
.
execute
#subject { results[:projects] }
results
[
:projects
].
should
have
(
3
).
items
results
[
:projects
].
should
have
(
3
).
items
results
[
:projects
].
should
include
(
public_project
)
results
[
:projects
].
should
include
(
found_project
)
results
[
:projects
].
should
include
(
found_project
)
results
[
:projects
].
should
include
(
internal_project
)
results
[
:projects
].
should
include
(
internal_project
)
results
[
:projects
].
should
include
(
public_project
)
end
end
it
'should return only public & internal projects'
do
context
=
Search
::
GlobalContext
.
new
(
internal_user
,
search:
"searchable"
)
results
=
context
.
execute
results
[
:projects
].
should
have
(
2
).
items
results
[
:projects
].
should
include
(
internal_project
)
results
[
:projects
].
should
include
(
public_project
)
end
it
'namespace name should be searchable'
do
it
'namespace name should be searchable'
do
context
=
SearchContext
.
new
([
found_project
.
id
],
user
,
{
search_code:
false
,
search:
"searchable namespace"
})
context
=
Search
::
GlobalContext
.
new
(
user
,
search:
"searchable namespace"
)
results
=
context
.
execute
results
=
context
.
execute
results
[
:projects
].
should
==
[
found_project
]
results
[
:projects
].
should
==
[
found_project
]
end
end
end
end
end
end
end
spec/controllers/search_controller_spec.rb
deleted
100644 → 0
View file @
cb589d23
require
'spec_helper'
describe
SearchController
do
let
(
:project
)
{
create
(
:project
,
public:
true
)
}
let
(
:user
)
{
create
(
:user
)
}
before
do
sign_in
(
user
)
end
describe
'#find_project_ids'
do
it
'should include public projects ids when searching within a single project'
do
project_ids
=
controller
.
send
(
:find_project_ids
,
nil
,
project
.
id
)
project_ids
.
size
.
should
==
1
project_ids
[
0
].
should
==
project
.
id
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment