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
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
gitlab-ce
Commits
4cb1cc2b
Commit
4cb1cc2b
authored
Apr 06, 2015
by
Robert Speicher
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make CommitRange and Snippets cross-referable
parent
d520fe07
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
96 additions
and
67 deletions
+96
-67
lib/gitlab/markdown/snippet_reference_filter.rb
lib/gitlab/markdown/snippet_reference_filter.rb
+14
-12
spec/lib/gitlab/markdown/commit_range_reference_filter_spec.rb
...lib/gitlab/markdown/commit_range_reference_filter_spec.rb
+23
-22
spec/lib/gitlab/markdown/commit_reference_filter_spec.rb
spec/lib/gitlab/markdown/commit_reference_filter_spec.rb
+3
-4
spec/lib/gitlab/markdown/snippet_reference_filter_spec.rb
spec/lib/gitlab/markdown/snippet_reference_filter_spec.rb
+56
-29
No files found.
lib/gitlab/markdown/snippet_reference_filter.rb
View file @
4cb1cc2b
...
@@ -7,11 +7,14 @@ module Gitlab
...
@@ -7,11 +7,14 @@ module Gitlab
# snippets that do not exist are ignored.
# snippets that do not exist are ignored.
#
#
# Context options:
# Context options:
# :project (required) - Current project.
# :project (required) - Current project, ignored when reference is
# cross-project.
# :reference_class - Custom CSS class added to reference links.
# :reference_class - Custom CSS class added to reference links.
# :only_path - Generate path-only links.
# :only_path - Generate path-only links.
#
#
class
SnippetReferenceFilter
<
HTML
::
Pipeline
::
Filter
class
SnippetReferenceFilter
<
HTML
::
Pipeline
::
Filter
include
CrossProjectReference
# Public: Find `$123` snippet references in text
# Public: Find `$123` snippet references in text
#
#
# SnippetReferenceFilter.references_in(text) do |match, snippet|
# SnippetReferenceFilter.references_in(text) do |match, snippet|
...
@@ -20,17 +23,20 @@ module Gitlab
...
@@ -20,17 +23,20 @@ module Gitlab
#
#
# text - String text to search.
# text - String text to search.
#
#
# Yields the String match and the Integer snippet ID.
# Yields the String match, the Integer snippet ID, and an optional String
# of the external project reference.
#
#
# Returns a String replaced with the return of the block.
# Returns a String replaced with the return of the block.
def
self
.
references_in
(
text
)
def
self
.
references_in
(
text
)
text
.
gsub
(
SNIPPET_PATTERN
)
do
|
match
|
text
.
gsub
(
SNIPPET_PATTERN
)
do
|
match
|
yield
match
,
$~
[
:snippet
].
to_i
yield
match
,
$~
[
:snippet
].
to_i
,
$~
[
:project
]
end
end
end
end
# Pattern used to extract `$123` snippet references from text
# Pattern used to extract `$123` snippet references from text
SNIPPET_PATTERN
=
/\$(?<snippet>\d+)/
#
# This pattern supports cross-project references.
SNIPPET_PATTERN
=
/
#{
PROJECT_PATTERN
}
?\$(?<snippet>\d+)/
# Don't look for references in text nodes that are children of these
# Don't look for references in text nodes that are children of these
# elements.
# elements.
...
@@ -40,7 +46,7 @@ module Gitlab
...
@@ -40,7 +46,7 @@ module Gitlab
doc
.
search
(
'text()'
).
each
do
|
node
|
doc
.
search
(
'text()'
).
each
do
|
node
|
content
=
node
.
to_html
content
=
node
.
to_html
next
if
project
.
nil?
next
if
context
[
:project
]
.
nil?
next
unless
content
.
match
(
SNIPPET_PATTERN
)
next
unless
content
.
match
(
SNIPPET_PATTERN
)
next
if
has_ancestor?
(
node
,
IGNORE_PARENTS
)
next
if
has_ancestor?
(
node
,
IGNORE_PARENTS
)
...
@@ -66,9 +72,9 @@ module Gitlab
...
@@ -66,9 +72,9 @@ module Gitlab
# Returns a String with `$123` references replaced with links. All links
# Returns a String with `$123` references replaced with links. All links
# have `gfm` and `gfm-snippet` class names attached for styling.
# have `gfm` and `gfm-snippet` class names attached for styling.
def
snippet_link_filter
(
text
)
def
snippet_link_filter
(
text
)
project
=
context
[
:project
]
self
.
class
.
references_in
(
text
)
do
|
match
,
id
,
project_ref
|
project
=
self
.
project_from_ref
(
project_ref
)
self
.
class
.
references_in
(
text
)
do
|
match
,
id
|
if
snippet
=
project
.
snippets
.
find_by
(
id:
id
)
if
snippet
=
project
.
snippets
.
find_by
(
id:
id
)
title
=
"Snippet:
#{
snippet
.
title
}
"
title
=
"Snippet:
#{
snippet
.
title
}
"
klass
=
"gfm gfm-snippet
#{
context
[
:reference_class
]
}
"
.
strip
klass
=
"gfm gfm-snippet
#{
context
[
:reference_class
]
}
"
.
strip
...
@@ -77,17 +83,13 @@ module Gitlab
...
@@ -77,17 +83,13 @@ module Gitlab
%(<a href="#{url}"
%(<a href="#{url}"
title="#{title}"
title="#{title}"
class="#{klass}">$#{id}</a>)
class="#{klass}">
#{project_ref}
$#{id}</a>)
else
else
match
match
end
end
end
end
end
end
def
project
context
[
:project
]
end
def
url_for_snippet
(
snippet
,
project
)
def
url_for_snippet
(
snippet
,
project
)
h
=
Rails
.
application
.
routes
.
url_helpers
h
=
Rails
.
application
.
routes
.
url_helpers
h
.
namespace_project_snippet_url
(
project
.
namespace
,
project
,
snippet
,
h
.
namespace_project_snippet_url
(
project
.
namespace
,
project
,
snippet
,
...
...
spec/lib/gitlab/markdown/commit_range_reference_filter_spec.rb
View file @
4cb1cc2b
...
@@ -51,7 +51,7 @@ module Gitlab::Markdown
...
@@ -51,7 +51,7 @@ module Gitlab::Markdown
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
Regexp
.
escape
(
reference
)
}
<\/a>\.\)/
)
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
Regexp
.
escape
(
reference
)
}
<\/a>\.\)/
)
end
end
it
'ignores invalid
issue
IDs'
do
it
'ignores invalid
commit
IDs'
do
exp
=
act
=
"See
#{
commit1
.
id
.
reverse
}
...
#{
commit2
.
id
}
"
exp
=
act
=
"See
#{
commit1
.
id
.
reverse
}
...
#{
commit2
.
id
}
"
expect
(
project
).
to
receive
(
:valid_repo?
).
and_return
(
true
)
expect
(
project
).
to
receive
(
:valid_repo?
).
and_return
(
true
)
...
@@ -83,31 +83,32 @@ module Gitlab::Markdown
...
@@ -83,31 +83,32 @@ module Gitlab::Markdown
end
end
end
end
# TODO (rspeicher): Remove or re-enable
context
'cross-project reference'
do
# context 'cross-project reference' do
let
(
:namespace
)
{
create
(
:namespace
,
name:
'cross-reference'
)
}
# let(:namespace) { create(:namespace, name: 'cross-reference') }
let
(
:project2
)
{
create
(
:project
,
namespace:
namespace
)
}
# let(:project2) { create(:project, namespace: namespace) }
let
(
:commit1
)
{
project
.
repository
.
commit
}
# let(:commit1) { project.repository.commit }
let
(
:commit2
)
{
project
.
repository
.
commit
(
"HEAD~2"
)
}
# let(:commit2) { project.repository.commit("HEAD~2") }
let
(
:reference
)
{
"
#{
project2
.
path_with_namespace
}
@
#{
commit1
.
id
}
...
#{
commit2
.
id
}
"
}
# let(:reference) { "#{project2.path_with_namespace}@#{commit.id}" }
#
it 'links to a valid reference' do
it
'links to a valid reference'
do
#
doc = filter("See #{reference}")
doc
=
filter
(
"See
#{
reference
}
"
)
#
expect(doc.css('a').first.attr('href')).
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)).
# to eq urls.namespace_project_commit_url(project2.namespace, project2, commit
.id)
to
eq
urls
.
namespace_project_compare_url
(
project2
.
namespace
,
project2
,
from:
commit1
.
id
,
to:
commit2
.
id
)
#
end
end
#
it 'links with adjacent text' do
it
'links with adjacent text'
do
#
doc = filter("Fixed (#{reference}.)")
doc
=
filter
(
"Fixed (
#{
reference
}
.)"
)
#
expect(doc.to_html).to match(/\(<a.+>#{Regexp.escape(reference)}<\/a>\.\)/)
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
Regexp
.
escape
(
reference
)
}
<\/a>\.\)/
)
#
end
end
# it 'ignores invalid issue IDs on the referenced project' do
it
'ignores invalid commit IDs on the referenced project'
do
# exp = act = "Fixed #{project2.path_with_namespace}##{commit.id.reverse}"
exp
=
act
=
"Fixed
#{
project2
.
path_with_namespace
}
#
#{
commit1
.
id
.
reverse
}
...
#{
commit2
.
id
}
"
expect
(
filter
(
act
).
to_html
).
to
eq
exp
# expect(filter(act).to_html).to eq exp
exp
=
act
=
"Fixed
#{
project2
.
path_with_namespace
}
#
#{
commit1
.
id
}
...
#{
commit2
.
id
.
reverse
}
"
# end
expect
(
filter
(
act
).
to_html
).
to
eq
exp
# end
end
end
end
end
end
end
spec/lib/gitlab/markdown/commit_reference_filter_spec.rb
View file @
4cb1cc2b
...
@@ -38,7 +38,7 @@ module Gitlab::Markdown
...
@@ -38,7 +38,7 @@ module Gitlab::Markdown
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
Regexp
.
escape
(
reference
)
}
<\/a>\.\)/
)
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
Regexp
.
escape
(
reference
)
}
<\/a>\.\)/
)
end
end
it
'ignores invalid
issue
IDs'
do
it
'ignores invalid
commit
IDs'
do
exp
=
act
=
"See
#{
reference
.
reverse
}
"
exp
=
act
=
"See
#{
reference
.
reverse
}
"
expect
(
project
).
to
receive
(
:valid_repo?
).
and_return
(
true
)
expect
(
project
).
to
receive
(
:valid_repo?
).
and_return
(
true
)
...
@@ -88,9 +88,8 @@ module Gitlab::Markdown
...
@@ -88,9 +88,8 @@ module Gitlab::Markdown
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
Regexp
.
escape
(
reference
)
}
<\/a>\.\)/
)
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
Regexp
.
escape
(
reference
)
}
<\/a>\.\)/
)
end
end
it
'ignores invalid issue IDs on the referenced project'
do
it
'ignores invalid commit IDs on the referenced project'
do
exp
=
act
=
"Fixed
#{
project2
.
path_with_namespace
}
#
#{
commit
.
id
.
reverse
}
"
exp
=
act
=
"Committed
#{
project2
.
path_with_namespace
}
#
#{
commit
.
id
.
reverse
}
"
expect
(
filter
(
act
).
to_html
).
to
eq
exp
expect
(
filter
(
act
).
to_html
).
to
eq
exp
end
end
end
end
...
...
spec/lib/gitlab/markdown/snippet_reference_filter_spec.rb
View file @
4cb1cc2b
...
@@ -20,45 +20,72 @@ module Gitlab::Markdown
...
@@ -20,45 +20,72 @@ module Gitlab::Markdown
end
end
end
end
it
'links to a valid reference'
do
context
'internal reference'
do
doc
=
filter
(
"See
#{
reference
}
"
)
it
'links to a valid reference'
do
doc
=
filter
(
"See
#{
reference
}
"
)
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)).
to
eq
urls
.
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)).
to
eq
urls
.
namespace_project_snippet_url
(
project
.
namespace
,
project
,
snippet
)
namespace_project_snippet_url
(
project
.
namespace
,
project
,
snippet
)
end
end
it
'links with adjacent text'
do
it
'links with adjacent text'
do
doc
=
filter
(
"Snippet (
#{
reference
}
.)"
)
doc
=
filter
(
"Snippet (
#{
reference
}
.)"
)
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
Regexp
.
escape
(
reference
)
}
<\/a>\.\)/
)
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
Regexp
.
escape
(
reference
)
}
<\/a>\.\)/
)
end
end
it
'ignores invalid snippet IDs'
do
it
'ignores invalid snippet IDs'
do
exp
=
act
=
"Snippet $
#{
snippet
.
id
+
1
}
"
exp
=
act
=
"Snippet $
#{
snippet
.
id
+
1
}
"
expect
(
filter
(
act
).
to_html
).
to
eq
exp
expect
(
filter
(
act
).
to_html
).
to
eq
exp
end
end
it
'includes a title attribute'
do
it
'includes a title attribute'
do
doc
=
filter
(
"Snippet
#{
reference
}
"
)
doc
=
filter
(
"Snippet
#{
reference
}
"
)
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'title'
)).
to
eq
"Snippet:
#{
snippet
.
title
}
"
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'title'
)).
to
eq
"Snippet:
#{
snippet
.
title
}
"
end
end
it
'includes default classes'
do
it
'includes default classes'
do
doc
=
filter
(
"Snippet
#{
reference
}
"
)
doc
=
filter
(
"Snippet
#{
reference
}
"
)
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'class'
)).
to
eq
'gfm gfm-snippet'
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'class'
)).
to
eq
'gfm gfm-snippet'
end
end
it
'includes an optional custom class'
do
it
'includes an optional custom class'
do
doc
=
filter
(
"Snippet
#{
reference
}
"
,
reference_class:
'custom'
)
doc
=
filter
(
"Snippet
#{
reference
}
"
,
reference_class:
'custom'
)
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'class'
)).
to
include
'custom'
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'class'
)).
to
include
'custom'
end
it
'supports an :only_path context'
do
doc
=
filter
(
"Snippet
#{
reference
}
"
,
only_path:
true
)
link
=
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)
expect
(
link
).
not_to
match
%r(https?://)
expect
(
link
).
to
eq
urls
.
namespace_project_snippet_url
(
project
.
namespace
,
project
,
snippet
,
only_path:
true
)
end
end
end
it
'supports an :only_path context'
do
context
'cross-project reference'
do
doc
=
filter
(
"Snippet
#{
reference
}
"
,
only_path:
true
)
let
(
:namespace
)
{
create
(
:namespace
,
name:
'cross-reference'
)
}
link
=
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)
let
(
:project2
)
{
create
(
:empty_project
,
namespace:
namespace
)
}
let
(
:snippet
)
{
create
(
:project_snippet
,
project:
project2
)
}
let
(
:reference
)
{
"
#{
project2
.
path_with_namespace
}
$
#{
snippet
.
id
}
"
}
it
'links to a valid reference'
do
doc
=
filter
(
"See
#{
reference
}
"
)
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)).
to
eq
urls
.
namespace_project_snippet_url
(
project2
.
namespace
,
project2
,
snippet
)
end
expect
(
link
).
not_to
match
%r(https?://)
it
'links with adjacent text'
do
expect
(
link
).
to
eq
urls
.
namespace_project_snippet_url
(
project
.
namespace
,
project
,
snippet
,
only_path:
true
)
doc
=
filter
(
"See (
#{
reference
}
.)"
)
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
Regexp
.
escape
(
reference
)
}
<\/a>\.\)/
)
end
it
'ignores invalid snippet IDs on the referenced project'
do
exp
=
act
=
"See
#{
project2
.
path_with_namespace
}
$
#{
snippet
.
id
+
1
}
"
expect
(
filter
(
act
).
to_html
).
to
eq
exp
end
end
end
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