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
b1012d98
Commit
b1012d98
authored
Jul 10, 2016
by
Douwe Maan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Autolink package names in Gemfile
parent
3f6d91c5
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
263 additions
and
10 deletions
+263
-10
lib/gitlab/dependency_linker.rb
lib/gitlab/dependency_linker.rb
+18
-0
lib/gitlab/dependency_linker/base_linker.rb
lib/gitlab/dependency_linker/base_linker.rb
+103
-0
lib/gitlab/dependency_linker/gemfile_linker.rb
lib/gitlab/dependency_linker/gemfile_linker.rb
+28
-0
lib/gitlab/highlight.rb
lib/gitlab/highlight.rb
+27
-10
spec/lib/gitlab/dependency_linker/gemfile_linker_spec.rb
spec/lib/gitlab/dependency_linker/gemfile_linker_spec.rb
+63
-0
spec/lib/gitlab/dependency_linker_spec.rb
spec/lib/gitlab/dependency_linker_spec.rb
+13
-0
spec/lib/gitlab/highlight_spec.rb
spec/lib/gitlab/highlight_spec.rb
+11
-0
No files found.
lib/gitlab/dependency_linker.rb
0 → 100644
View file @
b1012d98
module
Gitlab
module
DependencyLinker
LINKERS
=
[
GemfileLinker
,
].
freeze
def
self
.
linker
(
blob_name
)
LINKERS
.
find
{
|
linker
|
linker
.
support?
(
blob_name
)
}
end
def
self
.
link
(
blob_name
,
plain_text
,
highlighted_text
)
linker
=
linker
(
blob_name
)
return
highlighted_text
unless
linker
linker
.
link
(
plain_text
,
highlighted_text
)
end
end
end
lib/gitlab/dependency_linker/base_linker.rb
0 → 100644
View file @
b1012d98
module
Gitlab
module
DependencyLinker
class
BaseLinker
def
self
.
link
(
plain_text
,
highlighted_text
)
new
(
plain_text
,
highlighted_text
).
link
end
attr_accessor
:plain_text
,
:highlighted_text
def
initialize
(
plain_text
,
highlighted_text
)
@plain_text
=
plain_text
@highlighted_text
=
highlighted_text
end
def
link
link_dependencies
highlighted_lines
.
join
.
html_safe
end
private
def
package_url
(
name
)
raise
NotImplementedError
end
def
link_dependencies
raise
NotImplementedError
end
def
package_link
(
name
,
url
=
package_url
(
name
))
return
name
unless
url
%{<a href="#{ERB::Util.html_escape_once(url)}" rel="noopener noreferrer" target="_blank">#{ERB::Util.html_escape_once(name)}</a>}
end
# Links package names in a method call or assignment string argument.
#
# Example:
# link_method_call("gem")
# # Will link `package` in `gem "package"`, `gem("package")` and `gem = "package"`
#
# link_method_call("gem", "specific_package")
# # Will link `specific_package` in `gem "specific_package"`
#
# link_method_call("github", /[^\/]+\/[^\/]+/)
# # Will link `user/repo` in `github "user/repo"`, but not `github "package"`
#
# link_method_call(%w[add_dependency add_development_dependency])
# # Will link `spec.add_dependency "package"` and `spec.add_development_dependency "package"`
#
# link_method_call("name")
# # Will link `package` in `self.name = "package"`
def
link_method_call
(
method_names
,
value
=
nil
,
&
url_proc
)
value
=
case
value
when
String
Regexp
.
escape
(
value
)
when
nil
/[^'"]+/
else
value
end
method_names
=
Array
(
method_names
).
map
{
|
name
|
Regexp
.
escape
(
name
)
}
regex
=
%r{
#{
Regexp
.
union
(
method_names
)
}
# Method name
\s
* # Whitespace
[(=]? # Opening brace or equals sign
\s
* # Whitespace
['"](?<name>
#{
value
}
)['"] # Package name in quotes
}x
link_regex
(
regex
,
&
url_proc
)
end
# Links package names based on regex.
#
# Example:
# link_regex(/(github:|:github =>)\s*['"](?<name>[^'"]+)['"]/)
# # Will link `user/repo` in `github: "user/repo"` or `:github => "user/repo"`
def
link_regex
(
regex
)
highlighted_lines
.
map!
.
with_index
do
|
rich_line
,
i
|
marker
=
StringRegexMarker
.
new
(
plain_lines
[
i
],
rich_line
.
html_safe
)
marker
.
mark
(
regex
,
group: :name
)
do
|
text
,
left
:,
right
:|
url
=
block_given?
?
yield
(
text
)
:
package_url
(
text
)
package_link
(
text
,
url
)
end
end
end
def
plain_lines
@plain_lines
||=
plain_text
.
lines
end
def
highlighted_lines
@highlighted_lines
||=
highlighted_text
.
lines
end
end
end
end
lib/gitlab/dependency_linker/gemfile_linker.rb
0 → 100644
View file @
b1012d98
module
Gitlab
module
DependencyLinker
class
GemfileLinker
<
BaseLinker
def
self
.
support?
(
blob_name
)
blob_name
==
'Gemfile'
||
blob_name
==
'gems.rb'
end
private
def
link_dependencies
# Link `gem "package_name"` to https://rubygems.org/gems/package_name
link_method_call
(
"gem"
)
# Link `github: "user/repo"` to https://github.com/user/repo
link_regex
(
/(github:|:github\s*=>)\s*['"](?<name>[^'"]+)['"]/
)
do
|
name
|
"https://github.com/
#{
name
}
"
end
# Link `source "https://rubygems.org"` to https://rubygems.org
link_method_call
(
"source"
,
%r{https?://[^'"]+}
)
{
|
url
|
url
}
end
def
package_url
(
name
)
"https://rubygems.org/gems/
#{
name
}
"
end
end
end
end
lib/gitlab/highlight.rb
View file @
b1012d98
...
...
@@ -13,6 +13,8 @@ module Gitlab
highlight
(
file_name
,
blob
.
data
,
repository:
repository
).
lines
.
map!
(
&
:html_safe
)
end
attr_reader
:blob_name
def
initialize
(
blob_name
,
blob_content
,
repository:
nil
)
@formatter
=
Rouge
::
Formatters
::
HTMLGitlab
@repository
=
repository
...
...
@@ -21,16 +23,9 @@ module Gitlab
end
def
highlight
(
text
,
continue:
true
,
plain:
false
)
if
plain
hl_lexer
=
Rouge
::
Lexers
::
PlainText
continue
=
false
else
hl_lexer
=
self
.
lexer
end
@formatter
.
format
(
hl_lexer
.
lex
(
text
,
continue:
continue
),
tag:
hl_lexer
.
tag
).
html_safe
rescue
@formatter
.
format
(
Rouge
::
Lexers
::
PlainText
.
lex
(
text
)).
html_safe
highlighted_text
=
highlight_text
(
text
,
continue:
continue
,
plain:
plain
)
highlighted_text
=
link_dependencies
(
text
,
highlighted_text
)
if
blob_name
highlighted_text
end
def
lexer
...
...
@@ -50,5 +45,27 @@ module Gitlab
Rouge
::
Lexer
.
find_fancy
(
language_name
)
end
def
highlight_text
(
text
,
continue:
true
,
plain:
false
)
if
plain
highlight_plain
(
text
)
else
highlight_rich
(
text
,
continue:
continue
)
end
end
def
highlight_plain
(
text
)
@formatter
.
format
(
Rouge
::
Lexers
::
PlainText
.
lex
(
text
)).
html_safe
end
def
highlight_rich
(
text
,
continue:
true
)
@formatter
.
format
(
lexer
.
lex
(
text
,
continue:
continue
),
tag:
lexer
.
tag
).
html_safe
rescue
highlight_plain
(
text
)
end
def
link_dependencies
(
text
,
highlighted_text
)
Gitlab
::
DependencyLinker
.
link
(
blob_name
,
text
,
highlighted_text
)
end
end
end
spec/lib/gitlab/dependency_linker/gemfile_linker_spec.rb
0 → 100644
View file @
b1012d98
require
'rails_helper'
describe
Gitlab
::
DependencyLinker
::
GemfileLinker
,
lib:
true
do
describe
'.support?'
do
it
'supports Gemfile'
do
expect
(
described_class
.
support?
(
'Gemfile'
)).
to
be_truthy
end
it
'supports gems.rb'
do
expect
(
described_class
.
support?
(
'gems.rb'
)).
to
be_truthy
end
it
'does not support other files'
do
expect
(
described_class
.
support?
(
'Gemfile.lock'
)).
to
be_falsey
end
end
describe
'#link'
do
let
(
:file_name
)
{
'Gemfile'
}
let
(
:file_content
)
do
<<-
CONTENT
.
strip_heredoc
source 'https://rubygems.org'
gem "rails", '4.2.6', github: "rails/rails"
gem 'rails-deprecated_sanitizer', '~> 1.0.3'
# Responders respond_to and respond_with
gem 'responders', '~> 2.0', :github => 'rails/responders'
# Specify a sprockets version due to increased performance
# See https://gitlab.com/gitlab-org/gitlab-ce/issues/6069
gem 'sprockets', '~> 3.6.0'
# Default values for AR models
gem 'default_value_for', '~> 3.0.0'
CONTENT
end
subject
{
Gitlab
::
Highlight
.
highlight
(
file_name
,
file_content
)
}
def
link
(
name
,
url
)
%{<a href="#{url}" rel="noopener noreferrer" target="_blank">#{name}</a>}
end
it
'links sources'
do
expect
(
subject
).
to
include
(
link
(
'https://rubygems.org'
,
'https://rubygems.org'
))
end
it
'links dependencies'
do
expect
(
subject
).
to
include
(
link
(
'rails'
,
'https://rubygems.org/gems/rails'
))
expect
(
subject
).
to
include
(
link
(
'rails-deprecated_sanitizer'
,
'https://rubygems.org/gems/rails-deprecated_sanitizer'
))
expect
(
subject
).
to
include
(
link
(
'responders'
,
'https://rubygems.org/gems/responders'
))
expect
(
subject
).
to
include
(
link
(
'sprockets'
,
'https://rubygems.org/gems/sprockets'
))
expect
(
subject
).
to
include
(
link
(
'default_value_for'
,
'https://rubygems.org/gems/default_value_for'
))
end
it
'links GitHub repos'
do
expect
(
subject
).
to
include
(
link
(
'rails/rails'
,
'https://github.com/rails/rails'
))
expect
(
subject
).
to
include
(
link
(
'rails/responders'
,
'https://github.com/rails/responders'
))
end
end
end
spec/lib/gitlab/dependency_linker_spec.rb
0 → 100644
View file @
b1012d98
require
'rails_helper'
describe
Gitlab
::
DependencyLinker
,
lib:
true
do
describe
'.link'
do
it
'links using GemfileLinker'
do
blob_name
=
'Gemfile'
expect
(
described_class
::
GemfileLinker
).
to
receive
(
:link
)
described_class
.
link
(
blob_name
,
nil
,
nil
)
end
end
end
spec/lib/gitlab/highlight_spec.rb
View file @
b1012d98
...
...
@@ -57,4 +57,15 @@ describe Gitlab::Highlight, lib: true do
end
end
end
describe
'#highlight'
do
subject
{
described_class
.
highlight
(
file_name
,
file_content
,
nowrap:
false
)
}
it
'links dependencies via DependencyLinker'
do
expect
(
Gitlab
::
DependencyLinker
).
to
receive
(
:link
).
with
(
'file.name'
,
'Contents'
,
anything
).
and_call_original
described_class
.
highlight
(
'file.name'
,
'Contents'
)
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