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
1
Merge Requests
1
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
nexedi
gitlab-ce
Commits
518216c0
Commit
518216c0
authored
Sep 07, 2017
by
Bob Van Landuyt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Merge group hierarchies when parents are shared
parent
530cf2a2
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
199 additions
and
4 deletions
+199
-4
app/controllers/groups_controller.rb
app/controllers/groups_controller.rb
+1
-0
app/finders/group_children_finder.rb
app/finders/group_children_finder.rb
+2
-1
app/finders/group_projects_finder.rb
app/finders/group_projects_finder.rb
+0
-1
app/models/concerns/group_hierarchy.rb
app/models/concerns/group_hierarchy.rb
+45
-2
app/serializers/base_serializer.rb
app/serializers/base_serializer.rb
+3
-0
app/serializers/group_child_serializer.rb
app/serializers/group_child_serializer.rb
+37
-0
spec/models/concerns/group_hierarchy_spec.rb
spec/models/concerns/group_hierarchy_spec.rb
+68
-0
spec/serializers/group_child_serializer_spec.rb
spec/serializers/group_child_serializer_spec.rb
+43
-0
No files found.
app/controllers/groups_controller.rb
View file @
518216c0
...
...
@@ -77,6 +77,7 @@ class GroupsController < Groups::ApplicationController
render
json:
GroupChildSerializer
.
new
(
current_user:
current_user
)
.
with_pagination
(
request
,
response
)
.
hierarchy_base
(
parent
,
open_hierarchy:
filter
[
:filter
].
present
)
.
represent
(
@children
)
end
end
...
...
app/finders/group_children_finder.rb
View file @
518216c0
...
...
@@ -52,7 +52,7 @@ class GroupChildrenFinder
end
def
subgroups_matching_filter
all_subgroups
.
search
(
params
[
:filter
])
all_subgroups
.
search
(
params
[
:filter
])
.
include
(
:parent
)
end
def
subgroups
...
...
@@ -75,6 +75,7 @@ class GroupChildrenFinder
def
projects_matching_filter
ProjectsFinder
.
new
(
current_user:
current_user
).
execute
.
search
(
params
[
:filter
])
.
include
(
:namespace
)
.
where
(
namespace:
all_subgroups
)
end
...
...
app/finders/group_projects_finder.rb
View file @
518216c0
...
...
@@ -34,7 +34,6 @@ class GroupProjectsFinder < ProjectsFinder
else
collection_without_user
end
union
(
projects
)
end
...
...
app/models/concerns/group_hierarchy.rb
View file @
518216c0
module
GroupHierarchy
def
hierarchy
(
hierarchy_base
=
nil
)
@hierarchy
||=
tree_for_child
(
self
,
self
,
hierarchy_base
)
tree_for_child
(
self
,
self
,
hierarchy_base
)
end
def
parent
...
...
@@ -16,7 +16,7 @@ module GroupHierarchy
raise
ArgumentError
.
new
(
'specified base is not part of the tree'
)
end
if
child
.
parent
!=
hierarchy_base
if
child
.
parent
&&
child
.
parent
!=
hierarchy_base
tree_for_child
(
child
.
parent
,
{
child
.
parent
=>
tree
},
hierarchy_base
)
...
...
@@ -24,4 +24,47 @@ module GroupHierarchy
tree
end
end
def
merge_hierarchy
(
other_element
,
hierarchy_base
=
nil
)
GroupHierarchy
.
merge_hierarchies
([
self
,
other_element
],
hierarchy_base
)
end
def
self
.
merge_hierarchies
(
hierarchies
,
hierarchy_base
=
nil
)
hierarchies
=
Array
.
wrap
(
hierarchies
)
return
if
hierarchies
.
empty?
unless
hierarchies
.
all?
{
|
other_base
|
other_base
.
is_a?
(
GroupHierarchy
)
}
raise
ArgumentError
.
new
(
'element is not a hierarchy'
)
end
first_hierarchy
,
*
other_hierarchies
=
hierarchies
merged
=
first_hierarchy
.
hierarchy
(
hierarchy_base
)
other_hierarchies
.
each
do
|
child
|
next_hierarchy
=
child
.
hierarchy
(
hierarchy_base
)
merged
=
merge_values
(
merged
,
next_hierarchy
)
end
merged
end
def
self
.
merge_values
(
first_child
,
second_child
)
# When the first is an array, we need to go over every element to see if
# we can merge deeper.
if
first_child
.
is_a?
(
Array
)
first_child
.
map
do
|
element
|
if
element
.
is_a?
(
Hash
)
&&
element
.
keys
.
any?
{
|
k
|
second_child
.
keys
.
include?
(
k
)
}
element
.
deep_merge
(
second_child
)
{
|
key
,
first
,
second
|
merge_values
(
first
,
second
)
}
else
element
end
end
# If both of them are hashes, we can deep_merge with the same logic
elsif
first_child
.
is_a?
(
Hash
)
&&
second_child
.
is_a?
(
Hash
)
first_child
.
deep_merge
(
second_child
)
{
|
key
,
first
,
second
|
merge_values
(
first
,
second
)
}
# One of them is a root node, we just need to put them next to eachother in an array
else
Array
.
wrap
(
first_child
)
+
Array
.
wrap
(
second_child
)
end
end
end
app/serializers/base_serializer.rb
View file @
518216c0
class
BaseSerializer
attr_reader
:parameters
def
initialize
(
parameters
=
{})
@parameters
=
parameters
@request
=
EntityRequest
.
new
(
parameters
)
end
...
...
app/serializers/group_child_serializer.rb
View file @
518216c0
class
GroupChildSerializer
<
BaseSerializer
include
WithPagination
attr_reader
:hierarchy_root
entity
GroupChildEntity
def
expand_hierarchy
(
hierarchy_root
)
@hierarchy_root
=
hierarchy_root
self
end
def
represent
(
resource
,
opts
=
{},
entity_class
=
nil
)
if
hierarchy_root
.
present?
represent_hierarchies
(
resource
,
opts
)
else
super
(
resource
,
opts
)
end
end
def
represent_hierarchies
(
children
,
opts
)
if
children
.
is_a?
(
GroupHierarchy
)
represent_hierarchy
(
children
.
hierarchy
(
hierarchy_root
),
opts
)
else
children
.
map
{
|
child
|
represent_hierarchy
(
child
.
hierarchy
(
hierarchy_root
),
opts
)
}
end
end
def
represent_hierarchy
(
hierarchy
,
opts
)
serializer
=
self
.
class
.
new
(
parameters
)
result
=
if
hierarchy
.
is_a?
(
Hash
)
parent
=
hierarchy
.
keys
.
first
serializer
.
represent
(
parent
,
opts
)
.
merge
(
children:
[
serializer
.
represent_hierarchy
(
hierarchy
[
parent
],
opts
)])
else
serializer
.
represent
(
hierarchy
,
opts
)
end
result
end
end
spec/models/concerns/group_hierarchy_spec.rb
View file @
518216c0
...
...
@@ -29,6 +29,40 @@ describe GroupHierarchy, :nested_groups do
expect
(
subsub_group
.
parent
).
to
eq
(
subgroup
)
end
end
describe
'#merge_hierarchy'
do
it
'combines hierarchies'
do
other_subgroup
=
create
(
:group
,
parent:
parent
)
expected_hierarchy
=
{
parent
=>
[{
subgroup
=>
subsub_group
},
other_subgroup
]
}
expect
(
subsub_group
.
merge_hierarchy
(
other_subgroup
)).
to
eq
(
expected_hierarchy
)
end
end
describe
'.merge_hierarchies'
do
it
'combines hierarchies until the top'
do
other_subgroup
=
create
(
:group
,
parent:
parent
)
other_subsub_group
=
create
(
:group
,
parent:
subgroup
)
groups
=
[
other_subgroup
,
subsub_group
,
other_subsub_group
]
expected_hierarchy
=
{
parent
=>
[
other_subgroup
,
{
subgroup
=>
[
subsub_group
,
other_subsub_group
]
}]
}
expect
(
described_class
.
merge_hierarchies
(
groups
)).
to
eq
(
expected_hierarchy
)
end
it
'combines upto a given parent'
do
other_subgroup
=
create
(
:group
,
parent:
parent
)
other_subsub_group
=
create
(
:group
,
parent:
subgroup
)
groups
=
[
other_subgroup
,
subsub_group
,
other_subsub_group
]
expected_hierarchy
=
[
other_subgroup
,
{
subgroup
=>
[
subsub_group
,
other_subsub_group
]
}]
expect
(
described_class
.
merge_hierarchies
(
groups
,
parent
)).
to
eq
(
expected_hierarchy
)
end
end
end
context
'for a project'
do
...
...
@@ -57,5 +91,39 @@ describe GroupHierarchy, :nested_groups do
expect
(
project
.
parent
).
to
eq
(
subsub_group
)
end
end
describe
'#merge_hierarchy'
do
it
'combines hierarchies'
do
project
=
create
(
:project
,
namespace:
parent
)
expected_hierarchy
=
{
parent
=>
[{
subgroup
=>
subsub_group
},
project
]
}
expect
(
subsub_group
.
merge_hierarchy
(
project
)).
to
eq
(
expected_hierarchy
)
end
end
describe
'.merge_hierarchies'
do
it
'combines hierarchies until the top'
do
other_project
=
create
(
:project
,
namespace:
parent
)
other_subgroup_project
=
create
(
:project
,
namespace:
subgroup
)
elements
=
[
other_project
,
subsub_group
,
other_subgroup_project
]
expected_hierarchy
=
{
parent
=>
[
other_project
,
{
subgroup
=>
[
subsub_group
,
other_subgroup_project
]
}]
}
expect
(
described_class
.
merge_hierarchies
(
elements
)).
to
eq
(
expected_hierarchy
)
end
it
'combines upto a given parent'
do
other_project
=
create
(
:project
,
namespace:
parent
)
other_subgroup_project
=
create
(
:project
,
namespace:
subgroup
)
elements
=
[
other_project
,
subsub_group
,
other_subgroup_project
]
expected_hierarchy
=
[
other_project
,
{
subgroup
=>
[
subsub_group
,
other_subgroup_project
]
}]
expect
(
described_class
.
merge_hierarchies
(
elements
,
parent
)).
to
eq
(
expected_hierarchy
)
end
end
end
end
spec/serializers/group_child_serializer_spec.rb
0 → 100644
View file @
518216c0
require
'spec_helper'
describe
GroupChildSerializer
do
let
(
:request
)
{
double
(
'request'
)
}
let
(
:user
)
{
create
(
:user
)
}
subject
(
:serializer
)
{
described_class
.
new
(
current_user:
user
)
}
describe
'#represent'
do
context
'for groups'
do
it
'can render a single group'
do
expect
(
serializer
.
represent
(
build
(
:group
))).
to
be_kind_of
(
Hash
)
end
it
'can render a collection of groups'
do
expect
(
serializer
.
represent
(
build_list
(
:group
,
2
))).
to
be_kind_of
(
Array
)
end
end
context
'with a hierarchy'
do
let
(
:parent
)
{
create
(
:group
)
}
subject
(
:serializer
)
do
described_class
.
new
(
current_user:
user
).
expand_hierarchy
(
parent
)
end
it
'expands the subgroups'
do
subgroup
=
create
(
:group
,
parent:
parent
)
subsub_group
=
create
(
:group
,
parent:
subgroup
)
json
=
serializer
.
represent
(
subsub_group
)
subsub_group_json
=
json
[
:children
].
first
expect
(
json
[
:id
]).
to
eq
(
subgroup
.
id
)
expect
(
subsub_group_json
).
not_to
be_nil
expect
(
subsub_group_json
[
:id
]).
to
eq
(
subsub_group
.
id
)
end
it
'can expand multiple trees'
do
end
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