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
Boxiang Sun
gitlab-ce
Commits
ddbe676d
Commit
ddbe676d
authored
Sep 08, 2016
by
Thomas Balthazar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add a /wip slash command
It toggles the 'WIP' prefix in the MR title.
parent
bcb2699f
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
196 additions
and
16 deletions
+196
-16
CHANGELOG
CHANGELOG
+1
-0
app/controllers/projects/merge_requests_controller.rb
app/controllers/projects/merge_requests_controller.rb
+1
-1
app/models/merge_request.rb
app/models/merge_request.rb
+20
-4
app/services/merge_requests/base_service.rb
app/services/merge_requests/base_service.rb
+5
-4
app/services/merge_requests/update_service.rb
app/services/merge_requests/update_service.rb
+14
-1
app/services/slash_commands/interpret_service.rb
app/services/slash_commands/interpret_service.rb
+12
-0
doc/user/project/slash_commands.md
doc/user/project/slash_commands.md
+2
-1
spec/controllers/projects/merge_requests_controller_spec.rb
spec/controllers/projects/merge_requests_controller_spec.rb
+14
-0
spec/features/issues/user_uses_slash_commands_spec.rb
spec/features/issues/user_uses_slash_commands_spec.rb
+10
-0
spec/features/merge_requests/user_uses_slash_commands_spec.rb
.../features/merge_requests/user_uses_slash_commands_spec.rb
+50
-5
spec/models/merge_request_spec.rb
spec/models/merge_request_spec.rb
+40
-0
spec/services/slash_commands/interpret_service_spec.rb
spec/services/slash_commands/interpret_service_spec.rb
+27
-0
No files found.
CHANGELOG
View file @
ddbe676d
...
@@ -6,6 +6,7 @@ v 8.13.0 (unreleased)
...
@@ -6,6 +6,7 @@ v 8.13.0 (unreleased)
- Fix centering of custom header logos (Ashley Dumaine)
- Fix centering of custom header logos (Ashley Dumaine)
- AbstractReferenceFilter caches project_refs on RequestStore when active
- AbstractReferenceFilter caches project_refs on RequestStore when active
- Replaced the check sign to arrow in the show build view. !6501
- Replaced the check sign to arrow in the show build view. !6501
- Add a /wip slash command to toggle the Work In Progress status of a merge request. !6259 (tbalthazar)
- Speed-up group milestones show page
- Speed-up group milestones show page
- Log LDAP lookup errors and don't swallow unrelated exceptions. !6103 (Markus Koller)
- Log LDAP lookup errors and don't swallow unrelated exceptions. !6103 (Markus Koller)
- Add more tests for calendar contribution (ClemMakesApps)
- Add more tests for calendar contribution (ClemMakesApps)
...
...
app/controllers/projects/merge_requests_controller.rb
View file @
ddbe676d
...
@@ -276,7 +276,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
...
@@ -276,7 +276,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end
end
def
remove_wip
def
remove_wip
MergeRequests
::
UpdateService
.
new
(
project
,
current_user
,
title:
@merge_request
.
wipless_title
).
execute
(
@merge_request
)
MergeRequests
::
UpdateService
.
new
(
project
,
current_user
,
wip_event:
'unwip'
).
execute
(
@merge_request
)
redirect_to
namespace_project_merge_request_path
(
@project
.
namespace
,
@project
,
@merge_request
),
redirect_to
namespace_project_merge_request_path
(
@project
.
namespace
,
@project
,
@merge_request
),
notice:
"The merge request can now be merged."
notice:
"The merge request can now be merged."
...
...
app/models/merge_request.rb
View file @
ddbe676d
...
@@ -155,6 +155,20 @@ class MergeRequest < ActiveRecord::Base
...
@@ -155,6 +155,20 @@ class MergeRequest < ActiveRecord::Base
where
(
"merge_requests.id IN (
#{
union
.
to_sql
}
)"
)
where
(
"merge_requests.id IN (
#{
union
.
to_sql
}
)"
)
end
end
WIP_REGEX
=
/\A\s*(\[WIP\]\s*|WIP:\s*|WIP\s+)+\s*/i
.
freeze
def
self
.
work_in_progress?
(
title
)
!!
(
title
=~
WIP_REGEX
)
end
def
self
.
wipless_title
(
title
)
title
.
sub
(
WIP_REGEX
,
""
)
end
def
self
.
wip_title
(
title
)
work_in_progress?
(
title
)
?
title
:
"WIP:
#{
title
}
"
end
def
to_reference
(
from_project
=
nil
)
def
to_reference
(
from_project
=
nil
)
reference
=
"
#{
self
.
class
.
reference_prefix
}#{
iid
}
"
reference
=
"
#{
self
.
class
.
reference_prefix
}#{
iid
}
"
...
@@ -389,14 +403,16 @@ class MergeRequest < ActiveRecord::Base
...
@@ -389,14 +403,16 @@ class MergeRequest < ActiveRecord::Base
@closed_event
||=
target_project
.
events
.
where
(
target_id:
self
.
id
,
target_type:
"MergeRequest"
,
action:
Event
::
CLOSED
).
last
@closed_event
||=
target_project
.
events
.
where
(
target_id:
self
.
id
,
target_type:
"MergeRequest"
,
action:
Event
::
CLOSED
).
last
end
end
WIP_REGEX
=
/\A\s*(\[WIP\]\s*|WIP:\s*|WIP\s+)+\s*/i
.
freeze
def
work_in_progress?
def
work_in_progress?
!!
(
title
=~
WIP_REGEX
)
self
.
class
.
work_in_progress?
(
title
)
end
end
def
wipless_title
def
wipless_title
self
.
title
.
sub
(
WIP_REGEX
,
""
)
self
.
class
.
wipless_title
(
self
.
title
)
end
def
wip_title
self
.
class
.
wip_title
(
self
.
title
)
end
end
def
mergeable?
(
skip_ci_check:
false
)
def
mergeable?
(
skip_ci_check:
false
)
...
...
app/services/merge_requests/base_service.rb
View file @
ddbe676d
...
@@ -5,16 +5,17 @@ module MergeRequests
...
@@ -5,16 +5,17 @@ module MergeRequests
end
end
def
create_title_change_note
(
issuable
,
old_title
)
def
create_title_change_note
(
issuable
,
old_title
)
removed_wip
=
old_title
=~
MergeRequest
::
WIP_REGEX
&&
!
issuable
.
work_in_progress?
removed_wip
=
MergeRequest
.
work_in_progress?
(
old_title
)
&&
!
issuable
.
work_in_progress?
added_wip
=
old_title
!~
MergeRequest
::
WIP_REGEX
&&
issuable
.
work_in_progress?
added_wip
=
!
MergeRequest
.
work_in_progress?
(
old_title
)
&&
issuable
.
work_in_progress?
changed_title
=
MergeRequest
.
wipless_title
(
old_title
)
!=
issuable
.
wipless_title
if
removed_wip
if
removed_wip
SystemNoteService
.
remove_merge_request_wip
(
issuable
,
issuable
.
project
,
current_user
)
SystemNoteService
.
remove_merge_request_wip
(
issuable
,
issuable
.
project
,
current_user
)
elsif
added_wip
elsif
added_wip
SystemNoteService
.
add_merge_request_wip
(
issuable
,
issuable
.
project
,
current_user
)
SystemNoteService
.
add_merge_request_wip
(
issuable
,
issuable
.
project
,
current_user
)
else
super
end
end
super
if
changed_title
end
end
def
hook_data
(
merge_request
,
action
,
oldrev
=
nil
)
def
hook_data
(
merge_request
,
action
,
oldrev
=
nil
)
...
...
app/services/merge_requests/update_service.rb
View file @
ddbe676d
...
@@ -16,7 +16,7 @@ module MergeRequests
...
@@ -16,7 +16,7 @@ module MergeRequests
end
end
merge_request
.
merge_params
[
'force_remove_source_branch'
]
=
params
.
delete
(
:force_remove_source_branch
)
merge_request
.
merge_params
[
'force_remove_source_branch'
]
=
params
.
delete
(
:force_remove_source_branch
)
handle_wip_event
(
merge_request
)
update
(
merge_request
)
update
(
merge_request
)
end
end
...
@@ -81,5 +81,18 @@ module MergeRequests
...
@@ -81,5 +81,18 @@ module MergeRequests
def
after_update
(
issuable
)
def
after_update
(
issuable
)
issuable
.
cache_merge_request_closes_issues!
(
current_user
)
issuable
.
cache_merge_request_closes_issues!
(
current_user
)
end
end
private
def
handle_wip_event
(
merge_request
)
if
wip_event
=
params
.
delete
(
:wip_event
)
# We update the title that is provided in the params or we use the mr title
title
=
params
[
:title
]
||
merge_request
.
title
params
[
:title
]
=
case
wip_event
when
'wip'
then
MergeRequest
.
wip_title
(
title
)
when
'unwip'
then
MergeRequest
.
wipless_title
(
title
)
end
end
end
end
end
end
end
app/services/slash_commands/interpret_service.rb
View file @
ddbe676d
...
@@ -214,6 +214,18 @@ module SlashCommands
...
@@ -214,6 +214,18 @@ module SlashCommands
@updates
[
:due_date
]
=
nil
@updates
[
:due_date
]
=
nil
end
end
desc
do
"Toggle the Work In Progress status"
end
condition
do
issuable
.
persisted?
&&
issuable
.
respond_to?
(
:work_in_progress?
)
&&
current_user
.
can?
(
:"update_
#{
issuable
.
to_ability_name
}
"
,
issuable
)
end
command
:wip
do
@updates
[
:wip_event
]
=
issuable
.
work_in_progress?
?
'unwip'
:
'wip'
end
# This is a dummy command, so that it appears in the autocomplete commands
# This is a dummy command, so that it appears in the autocomplete commands
desc
'CC'
desc
'CC'
params
'@user'
params
'@user'
...
...
doc/user/project/slash_commands.md
View file @
ddbe676d
...
@@ -27,4 +27,5 @@ do.
...
@@ -27,4 +27,5 @@ do.
|
`/subscribe`
| Subscribe |
|
`/subscribe`
| Subscribe |
|
`/unsubscribe`
| Unsubscribe |
|
`/unsubscribe`
| Unsubscribe |
|
<code>
/due
<
in 2 days
|
this Friday
|
December 31st
>
</code>
| Set due date |
|
<code>
/due
<
in 2 days
|
this Friday
|
December 31st
>
</code>
| Set due date |
|
`/remove_due_date`
| Remove due date |
|
`/remove_due_date`
| Remove due date |
|
`/wip`
| Toggle the Work In Progress status |
spec/controllers/projects/merge_requests_controller_spec.rb
View file @
ddbe676d
...
@@ -644,6 +644,20 @@ describe Projects::MergeRequestsController do
...
@@ -644,6 +644,20 @@ describe Projects::MergeRequestsController do
end
end
end
end
context
'POST remove_wip'
do
it
'removes the wip status'
do
merge_request
.
title
=
merge_request
.
wip_title
merge_request
.
save
post
:remove_wip
,
namespace_id:
merge_request
.
project
.
namespace
.
to_param
,
project_id:
merge_request
.
project
.
to_param
,
id:
merge_request
.
iid
expect
(
merge_request
.
reload
.
title
).
to
eq
(
merge_request
.
wipless_title
)
end
end
context
'POST resolve_conflicts'
do
context
'POST resolve_conflicts'
do
let
(
:json_response
)
{
JSON
.
parse
(
response
.
body
)
}
let
(
:json_response
)
{
JSON
.
parse
(
response
.
body
)
}
let!
(
:original_head_sha
)
{
merge_request_with_conflicts
.
diff_head_sha
}
let!
(
:original_head_sha
)
{
merge_request_with_conflicts
.
diff_head_sha
}
...
...
spec/features/issues/user_uses_slash_commands_spec.rb
View file @
ddbe676d
...
@@ -99,5 +99,15 @@ feature 'Issues > User uses slash commands', feature: true, js: true do
...
@@ -99,5 +99,15 @@ feature 'Issues > User uses slash commands', feature: true, js: true do
end
end
end
end
end
end
describe
'toggling the WIP prefix from the title from note'
do
let
(
:issue
)
{
create
(
:issue
,
project:
project
)
}
it
'does not recognize the command nor create a note'
do
write_note
(
"/wip"
)
expect
(
page
).
not_to
have_content
'/wip'
end
end
end
end
end
end
spec/features/merge_requests/user_uses_slash_commands_spec.rb
View file @
ddbe676d
...
@@ -14,21 +14,66 @@ feature 'Merge Requests > User uses slash commands', feature: true, js: true do
...
@@ -14,21 +14,66 @@ feature 'Merge Requests > User uses slash commands', feature: true, js: true do
let
(
:new_url_opts
)
{
{
merge_request:
{
source_branch:
'feature'
}
}
}
let
(
:new_url_opts
)
{
{
merge_request:
{
source_branch:
'feature'
}
}
}
end
end
describe
'
adding a due date from note
'
do
describe
'
merge-request-only commands
'
do
before
do
before
do
project
.
team
<<
[
user
,
:master
]
project
.
team
<<
[
user
,
:master
]
login_with
(
user
)
login_with
(
user
)
visit
namespace_project_merge_request_path
(
project
.
namespace
,
project
,
merge_request
)
visit
namespace_project_merge_request_path
(
project
.
namespace
,
project
,
merge_request
)
end
end
after
do
after
do
wait_for_ajax
wait_for_ajax
end
end
it
'does not recognize the command nor create a note'
do
describe
'toggling the WIP prefix in the title from note'
do
write_note
(
"/due 2016-08-28"
)
context
'when the current user can toggle the WIP prefix'
do
it
'adds the WIP: prefix to the title'
do
write_note
(
"/wip"
)
expect
(
page
).
not_to
have_content
'/wip'
expect
(
page
).
to
have_content
'Your commands have been executed!'
expect
(
merge_request
.
reload
.
work_in_progress?
).
to
eq
true
end
it
'removes the WIP: prefix from the title'
do
merge_request
.
title
=
merge_request
.
wip_title
merge_request
.
save
write_note
(
"/wip"
)
expect
(
page
).
not_to
have_content
'/wip'
expect
(
page
).
to
have_content
'Your commands have been executed!'
expect
(
merge_request
.
reload
.
work_in_progress?
).
to
eq
false
end
end
context
'when the current user cannot toggle the WIP prefix'
do
let
(
:guest
)
{
create
(
:user
)
}
before
do
project
.
team
<<
[
guest
,
:guest
]
logout
login_with
(
guest
)
visit
namespace_project_merge_request_path
(
project
.
namespace
,
project
,
merge_request
)
end
it
'does not change the WIP prefix'
do
write_note
(
"/wip"
)
expect
(
page
).
not_to
have_content
'/wip'
expect
(
page
).
not_to
have_content
'Your commands have been executed!'
expect
(
merge_request
.
reload
.
work_in_progress?
).
to
eq
false
end
end
end
describe
'adding a due date from note'
do
it
'does not recognize the command nor create a note'
do
write_note
(
'/due 2016-08-28'
)
expect
(
page
).
not_to
have_content
'/due 2016-08-28'
expect
(
page
).
not_to
have_content
'/due 2016-08-28'
end
end
end
end
end
end
end
spec/models/merge_request_spec.rb
View file @
ddbe676d
...
@@ -287,6 +287,46 @@ describe MergeRequest, models: true do
...
@@ -287,6 +287,46 @@ describe MergeRequest, models: true do
end
end
end
end
describe
"#wipless_title"
do
[
'WIP '
,
'WIP:'
,
'WIP: '
,
'[WIP]'
,
'[WIP] '
,
' [WIP] WIP [WIP] WIP: WIP '
].
each
do
|
wip_prefix
|
it
"removes the '
#{
wip_prefix
}
' prefix"
do
wipless_title
=
subject
.
title
subject
.
title
=
"
#{
wip_prefix
}#{
subject
.
title
}
"
expect
(
subject
.
wipless_title
).
to
eq
wipless_title
end
it
"is satisfies the #work_in_progress? method"
do
subject
.
title
=
"
#{
wip_prefix
}#{
subject
.
title
}
"
subject
.
title
=
subject
.
wipless_title
expect
(
subject
.
work_in_progress?
).
to
eq
false
end
end
end
describe
"#wip_title"
do
it
"adds the WIP: prefix to the title"
do
wip_title
=
"WIP:
#{
subject
.
title
}
"
expect
(
subject
.
wip_title
).
to
eq
wip_title
end
it
"does not add the WIP: prefix multiple times"
do
wip_title
=
"WIP:
#{
subject
.
title
}
"
subject
.
title
=
subject
.
wip_title
subject
.
title
=
subject
.
wip_title
expect
(
subject
.
wip_title
).
to
eq
wip_title
end
it
"is satisfies the #work_in_progress? method"
do
subject
.
title
=
subject
.
wip_title
expect
(
subject
.
work_in_progress?
).
to
eq
true
end
end
describe
'#can_remove_source_branch?'
do
describe
'#can_remove_source_branch?'
do
let
(
:user
)
{
create
(
:user
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:user2
)
{
create
(
:user
)
}
let
(
:user2
)
{
create
(
:user
)
}
...
...
spec/services/slash_commands/interpret_service_spec.rb
View file @
ddbe676d
...
@@ -165,6 +165,23 @@ describe SlashCommands::InterpretService, services: true do
...
@@ -165,6 +165,23 @@ describe SlashCommands::InterpretService, services: true do
end
end
end
end
shared_examples
'wip command'
do
it
'returns wip_event: "wip" if content contains /wip'
do
_
,
updates
=
service
.
execute
(
content
,
issuable
)
expect
(
updates
).
to
eq
(
wip_event:
'wip'
)
end
end
shared_examples
'unwip command'
do
it
'returns wip_event: "unwip" if content contains /wip'
do
issuable
.
update
(
title:
issuable
.
wip_title
)
_
,
updates
=
service
.
execute
(
content
,
issuable
)
expect
(
updates
).
to
eq
(
wip_event:
'unwip'
)
end
end
shared_examples
'empty command'
do
shared_examples
'empty command'
do
it
'populates {} if content contains an unsupported command'
do
it
'populates {} if content contains an unsupported command'
do
_
,
updates
=
service
.
execute
(
content
,
issuable
)
_
,
updates
=
service
.
execute
(
content
,
issuable
)
...
@@ -376,6 +393,16 @@ describe SlashCommands::InterpretService, services: true do
...
@@ -376,6 +393,16 @@ describe SlashCommands::InterpretService, services: true do
let
(
:issuable
)
{
issue
}
let
(
:issuable
)
{
issue
}
end
end
it_behaves_like
'wip command'
do
let
(
:content
)
{
'/wip'
}
let
(
:issuable
)
{
merge_request
}
end
it_behaves_like
'unwip command'
do
let
(
:content
)
{
'/wip'
}
let
(
:issuable
)
{
merge_request
}
end
it_behaves_like
'empty command'
do
it_behaves_like
'empty command'
do
let
(
:content
)
{
'/remove_due_date'
}
let
(
:content
)
{
'/remove_due_date'
}
let
(
:issuable
)
{
merge_request
}
let
(
:issuable
)
{
merge_request
}
...
...
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