Merge branch 'dm-more-dependency-linkers' into 'master'
Autolink package names in more dependency files See merge request !11226
This commit is contained in:
commit
d9835145f9
28 changed files with 1129 additions and 69 deletions
4
changelogs/unreleased/dm-more-dependency-linkers.yml
Normal file
4
changelogs/unreleased/dm-more-dependency-linkers.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Autolink package names in more dependency files
|
||||
merge_request:
|
||||
author:
|
|
@ -1,7 +1,16 @@
|
|||
module Gitlab
|
||||
module DependencyLinker
|
||||
LINKERS = [
|
||||
GemfileLinker
|
||||
GemfileLinker,
|
||||
GemspecLinker,
|
||||
PackageJsonLinker,
|
||||
ComposerJsonLinker,
|
||||
PodfileLinker,
|
||||
PodspecLinker,
|
||||
PodspecJsonLinker,
|
||||
CartfileLinker,
|
||||
GodepsJsonLinker,
|
||||
RequirementsTxtLinker
|
||||
].freeze
|
||||
|
||||
def self.linker(blob_name)
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
module Gitlab
|
||||
module DependencyLinker
|
||||
class BaseLinker
|
||||
URL_REGEX = %r{https?://[^'"]+}.freeze
|
||||
REPO_REGEX = %r{[^/'"]+/[^/'"]+}.freeze
|
||||
|
||||
class_attribute :file_type
|
||||
|
||||
def self.support?(blob_name)
|
||||
|
@ -26,59 +29,20 @@ module Gitlab
|
|||
|
||||
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>}
|
||||
def license_url(name)
|
||||
Licensee::License.find(name)&.url
|
||||
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
|
||||
def github_url(name)
|
||||
"https://github.com/#{name}"
|
||||
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)
|
||||
def link_tag(name, url)
|
||||
%{<a href="#{ERB::Util.html_escape_once(url)}" rel="nofollow noreferrer noopener" target="_blank">#{ERB::Util.html_escape_once(name)}</a>}
|
||||
end
|
||||
|
||||
# Links package names based on regex.
|
||||
|
@ -86,13 +50,13 @@ module Gitlab
|
|||
# Example:
|
||||
# link_regex(/(github:|:github =>)\s*['"](?<name>[^'"]+)['"]/)
|
||||
# # Will link `user/repo` in `github: "user/repo"` or `:github => "user/repo"`
|
||||
def link_regex(regex)
|
||||
def link_regex(regex, &url_proc)
|
||||
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)
|
||||
url = yield(text)
|
||||
url ? link_tag(text, url) : text
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -104,6 +68,19 @@ module Gitlab
|
|||
def highlighted_lines
|
||||
@highlighted_lines ||= highlighted_text.lines
|
||||
end
|
||||
|
||||
def regexp_for_value(value, default: /[^'"]+/)
|
||||
case value
|
||||
when Array
|
||||
Regexp.union(value.map { |v| regexp_for_value(v, default: default) })
|
||||
when String
|
||||
Regexp.escape(value)
|
||||
when Regexp
|
||||
value
|
||||
else
|
||||
default
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
14
lib/gitlab/dependency_linker/cartfile_linker.rb
Normal file
14
lib/gitlab/dependency_linker/cartfile_linker.rb
Normal file
|
@ -0,0 +1,14 @@
|
|||
module Gitlab
|
||||
module DependencyLinker
|
||||
class CartfileLinker < MethodLinker
|
||||
self.file_type = :cartfile
|
||||
|
||||
private
|
||||
|
||||
def link_dependencies
|
||||
link_method_call('github', REPO_REGEX, &method(:github_url))
|
||||
link_method_call(%w[github git binary], URL_REGEX, &:itself)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
10
lib/gitlab/dependency_linker/cocoapods.rb
Normal file
10
lib/gitlab/dependency_linker/cocoapods.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
module Gitlab
|
||||
module DependencyLinker
|
||||
module Cocoapods
|
||||
def package_url(name)
|
||||
package = name.split("/", 2).first
|
||||
"https://cocoapods.org/pods/#{package}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
18
lib/gitlab/dependency_linker/composer_json_linker.rb
Normal file
18
lib/gitlab/dependency_linker/composer_json_linker.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
module Gitlab
|
||||
module DependencyLinker
|
||||
class ComposerJsonLinker < PackageJsonLinker
|
||||
self.file_type = :composer_json
|
||||
|
||||
private
|
||||
|
||||
def link_packages
|
||||
link_packages_at_key("require", &method(:package_url))
|
||||
link_packages_at_key("require-dev", &method(:package_url))
|
||||
end
|
||||
|
||||
def package_url(name)
|
||||
"https://packagist.org/packages/#{name}" if name =~ %r{\A#{REPO_REGEX}\z}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,29 +1,32 @@
|
|||
module Gitlab
|
||||
module DependencyLinker
|
||||
class GemfileLinker < BaseLinker
|
||||
class GemfileLinker < MethodLinker
|
||||
self.file_type = :gemfile
|
||||
|
||||
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}"
|
||||
link_urls
|
||||
link_packages
|
||||
end
|
||||
|
||||
def link_urls
|
||||
# Link `github: "user/repo"` to https://github.com/user/repo
|
||||
link_regex(/(github:|:github\s*=>)\s*['"](?<name>[^'"]+)['"]/, &method(:github_url))
|
||||
|
||||
# Link `git: "https://gitlab.example.com/user/repo"` to https://gitlab.example.com/user/repo
|
||||
link_regex(%r{(git:|:git\s*=>)\s*['"](?<name>https?://[^'"]+)['"]}) { |url| url }
|
||||
link_regex(%r{(git:|:git\s*=>)\s*['"](?<name>#{URL_REGEX})['"]}, &:itself)
|
||||
|
||||
# Link `source "https://rubygems.org"` to https://rubygems.org
|
||||
link_method_call("source", %r{https?://[^'"]+}) { |url| url }
|
||||
link_method_call('source', URL_REGEX, &:itself)
|
||||
end
|
||||
|
||||
def package_url(name)
|
||||
def link_packages
|
||||
# Link `gem "package_name"` to https://rubygems.org/gems/package_name
|
||||
link_method_call('gem') do |name|
|
||||
"https://rubygems.org/gems/#{name}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
18
lib/gitlab/dependency_linker/gemspec_linker.rb
Normal file
18
lib/gitlab/dependency_linker/gemspec_linker.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
module Gitlab
|
||||
module DependencyLinker
|
||||
class GemspecLinker < MethodLinker
|
||||
self.file_type = :gemspec
|
||||
|
||||
private
|
||||
|
||||
def link_dependencies
|
||||
link_method_call('homepage', URL_REGEX, &:itself)
|
||||
link_method_call('license', &method(:license_url))
|
||||
|
||||
link_method_call(%w[name add_dependency add_runtime_dependency add_development_dependency]) do |name|
|
||||
"https://rubygems.org/gems/#{name}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
26
lib/gitlab/dependency_linker/godeps_json_linker.rb
Normal file
26
lib/gitlab/dependency_linker/godeps_json_linker.rb
Normal file
|
@ -0,0 +1,26 @@
|
|||
module Gitlab
|
||||
module DependencyLinker
|
||||
class GodepsJsonLinker < JsonLinker
|
||||
NESTED_REPO_REGEX = %r{([^/]+/)+[^/]+?}.freeze
|
||||
|
||||
self.file_type = :godeps_json
|
||||
|
||||
private
|
||||
|
||||
def link_dependencies
|
||||
link_json('ImportPath') do |path|
|
||||
case path
|
||||
when %r{\A(?<repo>gitlab\.com/#{NESTED_REPO_REGEX})\.git/(?<path>.+)\z},
|
||||
%r{\A(?<repo>git(lab|hub)\.com/#{REPO_REGEX})/(?<path>.+)\z}
|
||||
|
||||
"https://#{$~[:repo]}/tree/master/#{$~[:path]}"
|
||||
when /\Agolang\.org/
|
||||
"https://godoc.org/#{path}"
|
||||
else
|
||||
"https://#{path}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
44
lib/gitlab/dependency_linker/json_linker.rb
Normal file
44
lib/gitlab/dependency_linker/json_linker.rb
Normal file
|
@ -0,0 +1,44 @@
|
|||
module Gitlab
|
||||
module DependencyLinker
|
||||
class JsonLinker < BaseLinker
|
||||
def link
|
||||
return highlighted_text unless json
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Links package names in a JSON key or values.
|
||||
#
|
||||
# Example:
|
||||
# link_json('name')
|
||||
# # Will link `package` in `"name": "package"`
|
||||
#
|
||||
# link_json('name', 'specific_package')
|
||||
# # Will link `specific_package` in `"name": "specific_package"`
|
||||
#
|
||||
# link_json('name', /[^\/]+\/[^\/]+/)
|
||||
# # Will link `user/repo` in `"name": "user/repo"`, but not `"name": "package"`
|
||||
#
|
||||
# link_json('specific_package', '1.0.1', link: :key)
|
||||
# # Will link `specific_package` in `"specific_package": "1.0.1"`
|
||||
def link_json(key, value = nil, link: :value, &url_proc)
|
||||
key = regexp_for_value(key, default: /[^"]+/)
|
||||
value = regexp_for_value(value, default: /[^"]+/)
|
||||
|
||||
if link == :value
|
||||
value = /(?<name>#{value})/
|
||||
else
|
||||
key = /(?<name>#{key})/
|
||||
end
|
||||
|
||||
link_regex(/"#{key}":\s*"#{value}"/, &url_proc)
|
||||
end
|
||||
|
||||
def json
|
||||
@json ||= JSON.parse(plain_text) rescue nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
39
lib/gitlab/dependency_linker/method_linker.rb
Normal file
39
lib/gitlab/dependency_linker/method_linker.rb
Normal file
|
@ -0,0 +1,39 @@
|
|||
module Gitlab
|
||||
module DependencyLinker
|
||||
class MethodLinker < BaseLinker
|
||||
private
|
||||
|
||||
# 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_name, value = nil, &url_proc)
|
||||
method_name = regexp_for_value(method_name)
|
||||
value = regexp_for_value(value)
|
||||
|
||||
regex = %r{
|
||||
#{method_name} # Method name
|
||||
\s* # Whitespace
|
||||
[(=]? # Opening brace or equals sign
|
||||
\s* # Whitespace
|
||||
['"](?<name>#{value})['"] # Package name in quotes
|
||||
}x
|
||||
|
||||
link_regex(regex, &url_proc)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
44
lib/gitlab/dependency_linker/package_json_linker.rb
Normal file
44
lib/gitlab/dependency_linker/package_json_linker.rb
Normal file
|
@ -0,0 +1,44 @@
|
|||
module Gitlab
|
||||
module DependencyLinker
|
||||
class PackageJsonLinker < JsonLinker
|
||||
self.file_type = :package_json
|
||||
|
||||
private
|
||||
|
||||
def link_dependencies
|
||||
link_json('name', json["name"], &method(:package_url))
|
||||
link_json('license', &method(:license_url))
|
||||
link_json(%w[homepage url], URL_REGEX, &:itself)
|
||||
|
||||
link_packages
|
||||
end
|
||||
|
||||
def link_packages
|
||||
link_packages_at_key("dependencies", &method(:package_url))
|
||||
link_packages_at_key("devDependencies", &method(:package_url))
|
||||
end
|
||||
|
||||
def link_packages_at_key(key, &url_proc)
|
||||
dependencies = json[key]
|
||||
return unless dependencies
|
||||
|
||||
dependencies.each do |name, version|
|
||||
link_json(name, version, link: :key, &url_proc)
|
||||
|
||||
link_json(name) do |value|
|
||||
case value
|
||||
when /\A#{URL_REGEX}\z/
|
||||
value
|
||||
when /\A#{REPO_REGEX}\z/
|
||||
github_url(value)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def package_url(name)
|
||||
"https://npmjs.com/package/#{name}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
15
lib/gitlab/dependency_linker/podfile_linker.rb
Normal file
15
lib/gitlab/dependency_linker/podfile_linker.rb
Normal file
|
@ -0,0 +1,15 @@
|
|||
module Gitlab
|
||||
module DependencyLinker
|
||||
class PodfileLinker < GemfileLinker
|
||||
include Cocoapods
|
||||
|
||||
self.file_type = :podfile
|
||||
|
||||
private
|
||||
|
||||
def link_packages
|
||||
link_method_call('pod', &method(:package_url))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
32
lib/gitlab/dependency_linker/podspec_json_linker.rb
Normal file
32
lib/gitlab/dependency_linker/podspec_json_linker.rb
Normal file
|
@ -0,0 +1,32 @@
|
|||
module Gitlab
|
||||
module DependencyLinker
|
||||
class PodspecJsonLinker < JsonLinker
|
||||
include Cocoapods
|
||||
|
||||
self.file_type = :podspec_json
|
||||
|
||||
private
|
||||
|
||||
def link_dependencies
|
||||
link_json('name', json["name"], &method(:package_url))
|
||||
link_json('license', &method(:license_url))
|
||||
link_json(%w[homepage git], URL_REGEX, &:itself)
|
||||
|
||||
link_packages_at_key("dependencies", &method(:package_url))
|
||||
|
||||
json["subspecs"]&.each do |subspec|
|
||||
link_packages_at_key("dependencies", subspec, &method(:package_url))
|
||||
end
|
||||
end
|
||||
|
||||
def link_packages_at_key(key, root = json, &url_proc)
|
||||
dependencies = root[key]
|
||||
return unless dependencies
|
||||
|
||||
dependencies.each do |name, _|
|
||||
link_regex(/"(?<name>#{Regexp.escape(name)})":\s*\[/, &url_proc)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
24
lib/gitlab/dependency_linker/podspec_linker.rb
Normal file
24
lib/gitlab/dependency_linker/podspec_linker.rb
Normal file
|
@ -0,0 +1,24 @@
|
|||
module Gitlab
|
||||
module DependencyLinker
|
||||
class PodspecLinker < MethodLinker
|
||||
include Cocoapods
|
||||
|
||||
STRING_REGEX = /['"](?<name>[^'"]+)['"]/.freeze
|
||||
|
||||
self.file_type = :podspec
|
||||
|
||||
private
|
||||
|
||||
def link_dependencies
|
||||
link_method_call('homepage', URL_REGEX, &:itself)
|
||||
|
||||
link_regex(%r{(git:|:git\s*=>)\s*['"](?<name>#{URL_REGEX})['"]}, &:itself)
|
||||
|
||||
link_method_call('license', &method(:license_url))
|
||||
link_regex(/license\s*=\s*\{\s*(type:|:type\s*=>)\s*#{STRING_REGEX}/, &method(:license_url))
|
||||
|
||||
link_method_call(%w[name dependency], &method(:package_url))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
17
lib/gitlab/dependency_linker/requirements_txt_linker.rb
Normal file
17
lib/gitlab/dependency_linker/requirements_txt_linker.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
module Gitlab
|
||||
module DependencyLinker
|
||||
class RequirementsTxtLinker < BaseLinker
|
||||
self.file_type = :requirements_txt
|
||||
|
||||
private
|
||||
|
||||
def link_dependencies
|
||||
link_regex(/^(?<name>(?![a-z+]+:)[^#.-][^ ><=;\[]+)/) do |name|
|
||||
"https://pypi.python.org/pypi/#{name}"
|
||||
end
|
||||
|
||||
link_regex(%r{^(?<name>https?://[^ ]+)}, &:itself)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
74
spec/lib/gitlab/dependency_linker/cartfile_linker_spec.rb
Normal file
74
spec/lib/gitlab/dependency_linker/cartfile_linker_spec.rb
Normal file
|
@ -0,0 +1,74 @@
|
|||
require 'rails_helper'
|
||||
|
||||
describe Gitlab::DependencyLinker::CartfileLinker, lib: true do
|
||||
describe '.support?' do
|
||||
it 'supports Cartfile' do
|
||||
expect(described_class.support?('Cartfile')).to be_truthy
|
||||
end
|
||||
|
||||
it 'supports Cartfile.private' do
|
||||
expect(described_class.support?('Cartfile.private')).to be_truthy
|
||||
end
|
||||
|
||||
it 'does not support other files' do
|
||||
expect(described_class.support?('test.Cartfile')).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
describe '#link' do
|
||||
let(:file_name) { "Cartfile" }
|
||||
|
||||
let(:file_content) do
|
||||
<<-CONTENT.strip_heredoc
|
||||
# Require version 2.3.1 or later
|
||||
github "ReactiveCocoa/ReactiveCocoa" >= 2.3.1
|
||||
|
||||
# Require version 1.x
|
||||
github "Mantle/Mantle" ~> 1.0 # (1.0 or later, but less than 2.0)
|
||||
|
||||
# Require exactly version 0.4.1
|
||||
github "jspahrsummers/libextobjc" == 0.4.1
|
||||
|
||||
# Use the latest version
|
||||
github "jspahrsummers/xcconfigs"
|
||||
|
||||
# Use the branch
|
||||
github "jspahrsummers/xcconfigs" "branch"
|
||||
|
||||
# Use a project from GitHub Enterprise
|
||||
github "https://enterprise.local/ghe/desktop/git-error-translations"
|
||||
|
||||
# Use a project from any arbitrary server, on the "development" branch
|
||||
git "https://enterprise.local/desktop/git-error-translations2.git" "development"
|
||||
|
||||
# Use a local project
|
||||
git "file:///directory/to/project" "branch"
|
||||
|
||||
# A binary only framework
|
||||
binary "https://my.domain.com/release/MyFramework.json" ~> 2.3
|
||||
CONTENT
|
||||
end
|
||||
|
||||
subject { Gitlab::Highlight.highlight(file_name, file_content) }
|
||||
|
||||
def link(name, url)
|
||||
%{<a href="#{url}" rel="nofollow noreferrer noopener" target="_blank">#{name}</a>}
|
||||
end
|
||||
|
||||
it 'links dependencies' do
|
||||
expect(subject).to include(link('ReactiveCocoa/ReactiveCocoa', 'https://github.com/ReactiveCocoa/ReactiveCocoa'))
|
||||
expect(subject).to include(link('Mantle/Mantle', 'https://github.com/Mantle/Mantle'))
|
||||
expect(subject).to include(link('jspahrsummers/libextobjc', 'https://github.com/jspahrsummers/libextobjc'))
|
||||
expect(subject).to include(link('jspahrsummers/xcconfigs', 'https://github.com/jspahrsummers/xcconfigs'))
|
||||
end
|
||||
|
||||
it 'links Git repos' do
|
||||
expect(subject).to include(link('https://enterprise.local/ghe/desktop/git-error-translations', 'https://enterprise.local/ghe/desktop/git-error-translations'))
|
||||
expect(subject).to include(link('https://enterprise.local/desktop/git-error-translations2.git', 'https://enterprise.local/desktop/git-error-translations2.git'))
|
||||
end
|
||||
|
||||
it 'links binary-only frameworks' do
|
||||
expect(subject).to include(link('https://my.domain.com/release/MyFramework.json', 'https://my.domain.com/release/MyFramework.json'))
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,82 @@
|
|||
require 'rails_helper'
|
||||
|
||||
describe Gitlab::DependencyLinker::ComposerJsonLinker, lib: true do
|
||||
describe '.support?' do
|
||||
it 'supports composer.json' do
|
||||
expect(described_class.support?('composer.json')).to be_truthy
|
||||
end
|
||||
|
||||
it 'does not support other files' do
|
||||
expect(described_class.support?('composer.json.example')).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
describe '#link' do
|
||||
let(:file_name) { "composer.json" }
|
||||
|
||||
let(:file_content) do
|
||||
<<-CONTENT.strip_heredoc
|
||||
{
|
||||
"name": "laravel/laravel",
|
||||
"homepage": "https://laravel.com/",
|
||||
"description": "The Laravel Framework.",
|
||||
"keywords": ["framework", "laravel"],
|
||||
"license": "MIT",
|
||||
"type": "project",
|
||||
"repositories": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/laravel.git"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.5.9",
|
||||
"laravel/framework": "5.2.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"fzaninotto/faker": "~1.4",
|
||||
"mockery/mockery": "0.9.*",
|
||||
"phpunit/phpunit": "~4.0",
|
||||
"symfony/css-selector": "2.8.*|3.0.*",
|
||||
"symfony/dom-crawler": "2.8.*|3.0.*"
|
||||
}
|
||||
}
|
||||
CONTENT
|
||||
end
|
||||
|
||||
subject { Gitlab::Highlight.highlight(file_name, file_content) }
|
||||
|
||||
def link(name, url)
|
||||
%{<a href="#{url}" rel="nofollow noreferrer noopener" target="_blank">#{name}</a>}
|
||||
end
|
||||
|
||||
it 'links the module name' do
|
||||
expect(subject).to include(link('laravel/laravel', 'https://packagist.org/packages/laravel/laravel'))
|
||||
end
|
||||
|
||||
it 'links the homepage' do
|
||||
expect(subject).to include(link('https://laravel.com/', 'https://laravel.com/'))
|
||||
end
|
||||
|
||||
it 'links the repository URL' do
|
||||
expect(subject).to include(link('https://github.com/laravel/laravel.git', 'https://github.com/laravel/laravel.git'))
|
||||
end
|
||||
|
||||
it 'links the license' do
|
||||
expect(subject).to include(link('MIT', 'http://choosealicense.com/licenses/mit/'))
|
||||
end
|
||||
|
||||
it 'links dependencies' do
|
||||
expect(subject).to include(link('laravel/framework', 'https://packagist.org/packages/laravel/framework'))
|
||||
expect(subject).to include(link('fzaninotto/faker', 'https://packagist.org/packages/fzaninotto/faker'))
|
||||
expect(subject).to include(link('mockery/mockery', 'https://packagist.org/packages/mockery/mockery'))
|
||||
expect(subject).to include(link('phpunit/phpunit', 'https://packagist.org/packages/phpunit/phpunit'))
|
||||
expect(subject).to include(link('symfony/css-selector', 'https://packagist.org/packages/symfony/css-selector'))
|
||||
expect(subject).to include(link('symfony/dom-crawler', 'https://packagist.org/packages/symfony/dom-crawler'))
|
||||
end
|
||||
|
||||
it 'does not link core dependencies' do
|
||||
expect(subject).not_to include(link('php', 'https://packagist.org/packages/php'))
|
||||
end
|
||||
end
|
||||
end
|
|
@ -33,7 +33,7 @@ describe Gitlab::DependencyLinker::GemfileLinker, lib: true do
|
|||
subject { Gitlab::Highlight.highlight(file_name, file_content) }
|
||||
|
||||
def link(name, url)
|
||||
%{<a href="#{url}" rel="noopener noreferrer" target="_blank">#{name}</a>}
|
||||
%{<a href="#{url}" rel="nofollow noreferrer noopener" target="_blank">#{name}</a>}
|
||||
end
|
||||
|
||||
it 'links sources' do
|
||||
|
|
66
spec/lib/gitlab/dependency_linker/gemspec_linker_spec.rb
Normal file
66
spec/lib/gitlab/dependency_linker/gemspec_linker_spec.rb
Normal file
|
@ -0,0 +1,66 @@
|
|||
require 'rails_helper'
|
||||
|
||||
describe Gitlab::DependencyLinker::GemspecLinker, lib: true do
|
||||
describe '.support?' do
|
||||
it 'supports *.gemspec' do
|
||||
expect(described_class.support?('gitlab_git.gemspec')).to be_truthy
|
||||
end
|
||||
|
||||
it 'does not support other files' do
|
||||
expect(described_class.support?('.gemspec.example')).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
describe '#link' do
|
||||
let(:file_name) { "gitlab_git.gemspec" }
|
||||
|
||||
let(:file_content) do
|
||||
<<-CONTENT.strip_heredoc
|
||||
Gem::Specification.new do |s|
|
||||
s.name = 'gitlab_git'
|
||||
s.version = `cat VERSION`
|
||||
s.date = Time.now.strftime('%Y-%m-%d')
|
||||
s.summary = "Gitlab::Git library"
|
||||
s.description = "GitLab wrapper around git objects"
|
||||
s.authors = ["Dmitriy Zaporozhets"]
|
||||
s.email = 'dmitriy.zaporozhets@gmail.com'
|
||||
s.license = 'MIT'
|
||||
s.files = `git ls-files lib/`.split('\n') << 'VERSION'
|
||||
s.homepage = 'https://gitlab.com/gitlab-org/gitlab_git'
|
||||
|
||||
s.add_dependency('github-linguist', '~> 4.7.0')
|
||||
s.add_dependency('activesupport', '~> 4.0')
|
||||
s.add_dependency('rugged', '~> 0.24.0')
|
||||
s.add_runtime_dependency('charlock_holmes', '~> 0.7.3')
|
||||
s.add_development_dependency('listen', '~> 3.0.6')
|
||||
end
|
||||
CONTENT
|
||||
end
|
||||
|
||||
subject { Gitlab::Highlight.highlight(file_name, file_content) }
|
||||
|
||||
def link(name, url)
|
||||
%{<a href="#{url}" rel="nofollow noreferrer noopener" target="_blank">#{name}</a>}
|
||||
end
|
||||
|
||||
it 'links the gem name' do
|
||||
expect(subject).to include(link('gitlab_git', 'https://rubygems.org/gems/gitlab_git'))
|
||||
end
|
||||
|
||||
it 'links the license' do
|
||||
expect(subject).to include(link('MIT', 'http://choosealicense.com/licenses/mit/'))
|
||||
end
|
||||
|
||||
it 'links the homepage' do
|
||||
expect(subject).to include(link('https://gitlab.com/gitlab-org/gitlab_git', 'https://gitlab.com/gitlab-org/gitlab_git'))
|
||||
end
|
||||
|
||||
it 'links dependencies' do
|
||||
expect(subject).to include(link('github-linguist', 'https://rubygems.org/gems/github-linguist'))
|
||||
expect(subject).to include(link('activesupport', 'https://rubygems.org/gems/activesupport'))
|
||||
expect(subject).to include(link('rugged', 'https://rubygems.org/gems/rugged'))
|
||||
expect(subject).to include(link('charlock_holmes', 'https://rubygems.org/gems/charlock_holmes'))
|
||||
expect(subject).to include(link('listen', 'https://rubygems.org/gems/listen'))
|
||||
end
|
||||
end
|
||||
end
|
84
spec/lib/gitlab/dependency_linker/godeps_json_linker_spec.rb
Normal file
84
spec/lib/gitlab/dependency_linker/godeps_json_linker_spec.rb
Normal file
|
@ -0,0 +1,84 @@
|
|||
require 'rails_helper'
|
||||
|
||||
describe Gitlab::DependencyLinker::GodepsJsonLinker, lib: true do
|
||||
describe '.support?' do
|
||||
it 'supports Godeps.json' do
|
||||
expect(described_class.support?('Godeps.json')).to be_truthy
|
||||
end
|
||||
|
||||
it 'does not support other files' do
|
||||
expect(described_class.support?('Godeps.json.example')).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
describe '#link' do
|
||||
let(:file_name) { "Godeps.json" }
|
||||
|
||||
let(:file_content) do
|
||||
<<-CONTENT.strip_heredoc
|
||||
{
|
||||
"ImportPath": "gitlab.com/gitlab-org/gitlab-pages",
|
||||
"GoVersion": "go1.5",
|
||||
"Packages": [
|
||||
"./..."
|
||||
],
|
||||
"Deps": [
|
||||
{
|
||||
"ImportPath": "github.com/kardianos/osext",
|
||||
"Rev": "efacde03154693404c65e7aa7d461ac9014acd0c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/stretchr/testify/assert",
|
||||
"Rev": "1297dc01ed0a819ff634c89707081a4df43baf6b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/stretchr/testify/require",
|
||||
"Rev": "1297dc01ed0a819ff634c89707081a4df43baf6b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "gitlab.com/group/project/path",
|
||||
"Rev": "1297dc01ed0a819ff634c89707081a4df43baf6b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "gitlab.com/group/subgroup/project.git/path",
|
||||
"Rev": "1297dc01ed0a819ff634c89707081a4df43baf6b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/crypto/ssh/terminal",
|
||||
"Rev": "1351f936d976c60a0a48d728281922cf63eafb8d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/net/http2",
|
||||
"Rev": "b4e17d61b15679caf2335da776c614169a1b4643"
|
||||
}
|
||||
]
|
||||
}
|
||||
CONTENT
|
||||
end
|
||||
|
||||
subject { Gitlab::Highlight.highlight(file_name, file_content) }
|
||||
|
||||
def link(name, url)
|
||||
%{<a href="#{url}" rel="nofollow noreferrer noopener" target="_blank">#{name}</a>}
|
||||
end
|
||||
|
||||
it 'links the package name' do
|
||||
expect(subject).to include(link('gitlab.com/gitlab-org/gitlab-pages', 'https://gitlab.com/gitlab-org/gitlab-pages'))
|
||||
end
|
||||
|
||||
it 'links GitHub repos' do
|
||||
expect(subject).to include(link('github.com/kardianos/osext', 'https://github.com/kardianos/osext'))
|
||||
expect(subject).to include(link('github.com/stretchr/testify/assert', 'https://github.com/stretchr/testify/tree/master/assert'))
|
||||
expect(subject).to include(link('github.com/stretchr/testify/require', 'https://github.com/stretchr/testify/tree/master/require'))
|
||||
end
|
||||
|
||||
it 'links GitLab projects' do
|
||||
expect(subject).to include(link('gitlab.com/group/project/path', 'https://gitlab.com/group/project/tree/master/path'))
|
||||
expect(subject).to include(link('gitlab.com/group/subgroup/project.git/path', 'https://gitlab.com/group/subgroup/project/tree/master/path'))
|
||||
end
|
||||
|
||||
it 'links Golang packages' do
|
||||
expect(subject).to include(link('golang.org/x/net/http2', 'https://godoc.org/golang.org/x/net/http2'))
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,85 @@
|
|||
require 'rails_helper'
|
||||
|
||||
describe Gitlab::DependencyLinker::PackageJsonLinker, lib: true do
|
||||
describe '.support?' do
|
||||
it 'supports package.json' do
|
||||
expect(described_class.support?('package.json')).to be_truthy
|
||||
end
|
||||
|
||||
it 'does not support other files' do
|
||||
expect(described_class.support?('package.json.example')).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
describe '#link' do
|
||||
let(:file_name) { "package.json" }
|
||||
|
||||
let(:file_content) do
|
||||
<<-CONTENT.strip_heredoc
|
||||
{
|
||||
"name": "module-name",
|
||||
"version": "10.3.1",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/vuejs/vue.git"
|
||||
},
|
||||
"homepage": "https://github.com/vuejs/vue#readme",
|
||||
"dependencies": {
|
||||
"primus": "*",
|
||||
"async": "~0.8.0",
|
||||
"express": "4.2.x",
|
||||
"bigpipe": "bigpipe/pagelet",
|
||||
"plates": "https://github.com/flatiron/plates/tarball/master"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vows": "^0.7.0",
|
||||
"assume": "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0",
|
||||
"pre-commit": "*"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
||||
CONTENT
|
||||
end
|
||||
|
||||
subject { Gitlab::Highlight.highlight(file_name, file_content) }
|
||||
|
||||
def link(name, url)
|
||||
%{<a href="#{url}" rel="nofollow noreferrer noopener" target="_blank">#{name}</a>}
|
||||
end
|
||||
|
||||
it 'links the module name' do
|
||||
expect(subject).to include(link('module-name', 'https://npmjs.com/package/module-name'))
|
||||
end
|
||||
|
||||
it 'links the homepage' do
|
||||
expect(subject).to include(link('https://github.com/vuejs/vue#readme', 'https://github.com/vuejs/vue#readme'))
|
||||
end
|
||||
|
||||
it 'links the repository URL' do
|
||||
expect(subject).to include(link('https://github.com/vuejs/vue.git', 'https://github.com/vuejs/vue.git'))
|
||||
end
|
||||
|
||||
it 'links the license' do
|
||||
expect(subject).to include(link('MIT', 'http://choosealicense.com/licenses/mit/'))
|
||||
end
|
||||
|
||||
it 'links dependencies' do
|
||||
expect(subject).to include(link('primus', 'https://npmjs.com/package/primus'))
|
||||
expect(subject).to include(link('async', 'https://npmjs.com/package/async'))
|
||||
expect(subject).to include(link('express', 'https://npmjs.com/package/express'))
|
||||
expect(subject).to include(link('bigpipe', 'https://npmjs.com/package/bigpipe'))
|
||||
expect(subject).to include(link('plates', 'https://npmjs.com/package/plates'))
|
||||
expect(subject).to include(link('vows', 'https://npmjs.com/package/vows'))
|
||||
expect(subject).to include(link('assume', 'https://npmjs.com/package/assume'))
|
||||
expect(subject).to include(link('pre-commit', 'https://npmjs.com/package/pre-commit'))
|
||||
end
|
||||
|
||||
it 'links GitHub repos' do
|
||||
expect(subject).to include(link('bigpipe/pagelet', 'https://github.com/bigpipe/pagelet'))
|
||||
end
|
||||
|
||||
it 'links Git repos' do
|
||||
expect(subject).to include(link('https://github.com/flatiron/plates/tarball/master', 'https://github.com/flatiron/plates/tarball/master'))
|
||||
end
|
||||
end
|
||||
end
|
53
spec/lib/gitlab/dependency_linker/podfile_linker_spec.rb
Normal file
53
spec/lib/gitlab/dependency_linker/podfile_linker_spec.rb
Normal file
|
@ -0,0 +1,53 @@
|
|||
require 'rails_helper'
|
||||
|
||||
describe Gitlab::DependencyLinker::PodfileLinker, lib: true do
|
||||
describe '.support?' do
|
||||
it 'supports Podfile' do
|
||||
expect(described_class.support?('Podfile')).to be_truthy
|
||||
end
|
||||
|
||||
it 'does not support other files' do
|
||||
expect(described_class.support?('Podfile.lock')).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
describe '#link' do
|
||||
let(:file_name) { "Podfile" }
|
||||
|
||||
let(:file_content) do
|
||||
<<-CONTENT.strip_heredoc
|
||||
source 'https://github.com/artsy/Specs.git'
|
||||
source 'https://github.com/CocoaPods/Specs.git'
|
||||
|
||||
platform :ios, '8.0'
|
||||
use_frameworks!
|
||||
inhibit_all_warnings!
|
||||
|
||||
target 'Artsy' do
|
||||
pod 'AFNetworking', "~> 2.5"
|
||||
pod 'Interstellar/Core', git: 'https://github.com/ashfurrow/Interstellar.git', branch: 'observable-unsubscribe'
|
||||
end
|
||||
CONTENT
|
||||
end
|
||||
|
||||
subject { Gitlab::Highlight.highlight(file_name, file_content) }
|
||||
|
||||
def link(name, url)
|
||||
%{<a href="#{url}" rel="nofollow noreferrer noopener" target="_blank">#{name}</a>}
|
||||
end
|
||||
|
||||
it 'links sources' do
|
||||
expect(subject).to include(link('https://github.com/artsy/Specs.git', 'https://github.com/artsy/Specs.git'))
|
||||
expect(subject).to include(link('https://github.com/CocoaPods/Specs.git', 'https://github.com/CocoaPods/Specs.git'))
|
||||
end
|
||||
|
||||
it 'links packages' do
|
||||
expect(subject).to include(link('AFNetworking', 'https://cocoapods.org/pods/AFNetworking'))
|
||||
expect(subject).to include(link('Interstellar/Core', 'https://cocoapods.org/pods/Interstellar'))
|
||||
end
|
||||
|
||||
it 'links Git repos' do
|
||||
expect(subject).to include(link('https://github.com/ashfurrow/Interstellar.git', 'https://github.com/ashfurrow/Interstellar.git'))
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,96 @@
|
|||
require 'rails_helper'
|
||||
|
||||
describe Gitlab::DependencyLinker::PodspecJsonLinker, lib: true do
|
||||
describe '.support?' do
|
||||
it 'supports *.podspec.json' do
|
||||
expect(described_class.support?('Reachability.podspec.json')).to be_truthy
|
||||
end
|
||||
|
||||
it 'does not support other files' do
|
||||
expect(described_class.support?('.podspec.json.example')).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
describe '#link' do
|
||||
let(:file_name) { "AFNetworking.podspec.json" }
|
||||
|
||||
let(:file_content) do
|
||||
<<-CONTENT.strip_heredoc
|
||||
{
|
||||
"name": "AFNetworking",
|
||||
"version": "2.0.0",
|
||||
"license": "MIT",
|
||||
"summary": "A delightful iOS and OS X networking framework.",
|
||||
"homepage": "https://github.com/AFNetworking/AFNetworking",
|
||||
"authors": {
|
||||
"Mattt Thompson": "m@mattt.me"
|
||||
},
|
||||
"source": {
|
||||
"git": "https://github.com/AFNetworking/AFNetworking.git",
|
||||
"tag": "2.0.0",
|
||||
"submodules": true
|
||||
},
|
||||
"requires_arc": true,
|
||||
"platforms": {
|
||||
"ios": "6.0",
|
||||
"osx": "10.8"
|
||||
},
|
||||
"public_header_files": "AFNetworking/*.h",
|
||||
"subspecs": [
|
||||
{
|
||||
"name": "NSURLConnection",
|
||||
"dependencies": {
|
||||
"AFNetworking/Serialization": [
|
||||
|
||||
],
|
||||
"AFNetworking/Reachability": [
|
||||
|
||||
],
|
||||
"AFNetworking/Security": [
|
||||
|
||||
]
|
||||
},
|
||||
"source_files": [
|
||||
"AFNetworking/AFURLConnectionOperation.{h,m}",
|
||||
"AFNetworking/AFHTTPRequestOperation.{h,m}",
|
||||
"AFNetworking/AFHTTPRequestOperationManager.{h,m}"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
CONTENT
|
||||
end
|
||||
|
||||
subject { Gitlab::Highlight.highlight(file_name, file_content) }
|
||||
|
||||
def link(name, url)
|
||||
%{<a href="#{url}" rel="nofollow noreferrer noopener" target="_blank">#{name}</a>}
|
||||
end
|
||||
|
||||
it 'links the gem name' do
|
||||
expect(subject).to include(link('AFNetworking', 'https://cocoapods.org/pods/AFNetworking'))
|
||||
end
|
||||
|
||||
it 'links the license' do
|
||||
expect(subject).to include(link('MIT', 'http://choosealicense.com/licenses/mit/'))
|
||||
end
|
||||
|
||||
it 'links the homepage' do
|
||||
expect(subject).to include(link('https://github.com/AFNetworking/AFNetworking', 'https://github.com/AFNetworking/AFNetworking'))
|
||||
end
|
||||
|
||||
it 'links the source URL' do
|
||||
expect(subject).to include(link('https://github.com/AFNetworking/AFNetworking.git', 'https://github.com/AFNetworking/AFNetworking.git'))
|
||||
end
|
||||
|
||||
it 'links dependencies' do
|
||||
expect(subject).to include(link('AFNetworking/Serialization', 'https://cocoapods.org/pods/AFNetworking'))
|
||||
expect(subject).to include(link('AFNetworking/Reachability', 'https://cocoapods.org/pods/AFNetworking'))
|
||||
expect(subject).to include(link('AFNetworking/Security', 'https://cocoapods.org/pods/AFNetworking'))
|
||||
end
|
||||
|
||||
it 'does not link subspec names' do
|
||||
expect(subject).not_to include(link('NSURLConnection', 'https://cocoapods.org/pods/NSURLConnection'))
|
||||
end
|
||||
end
|
||||
end
|
69
spec/lib/gitlab/dependency_linker/podspec_linker_spec.rb
Normal file
69
spec/lib/gitlab/dependency_linker/podspec_linker_spec.rb
Normal file
|
@ -0,0 +1,69 @@
|
|||
require 'rails_helper'
|
||||
|
||||
describe Gitlab::DependencyLinker::PodspecLinker, lib: true do
|
||||
describe '.support?' do
|
||||
it 'supports *.podspec' do
|
||||
expect(described_class.support?('Reachability.podspec')).to be_truthy
|
||||
end
|
||||
|
||||
it 'does not support other files' do
|
||||
expect(described_class.support?('.podspec.example')).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
describe '#link' do
|
||||
let(:file_name) { "Reachability.podspec" }
|
||||
|
||||
let(:file_content) do
|
||||
<<-CONTENT.strip_heredoc
|
||||
Pod::Spec.new do |spec|
|
||||
spec.name = 'Reachability'
|
||||
spec.version = '3.1.0'
|
||||
spec.license = { :type => 'GPL-3.0' }
|
||||
spec.license = "MIT"
|
||||
spec.license = { type: 'Apache-2.0' }
|
||||
spec.homepage = 'https://github.com/tonymillion/Reachability'
|
||||
spec.authors = { 'Tony Million' => 'tonymillion@gmail.com' }
|
||||
spec.summary = 'ARC and GCD Compatible Reachability Class for iOS and OS X.'
|
||||
spec.source = { :git => 'https://github.com/tonymillion/Reachability.git', :tag => 'v3.1.0' }
|
||||
spec.source_files = 'Reachability.{h,m}'
|
||||
spec.framework = 'SystemConfiguration'
|
||||
|
||||
spec.dependency 'AFNetworking', '~> 1.0'
|
||||
spec.dependency 'RestKit/CoreData', '~> 0.20.0'
|
||||
spec.ios.dependency 'MBProgressHUD', '~> 0.5'
|
||||
end
|
||||
CONTENT
|
||||
end
|
||||
|
||||
subject { Gitlab::Highlight.highlight(file_name, file_content) }
|
||||
|
||||
def link(name, url)
|
||||
%{<a href="#{url}" rel="nofollow noreferrer noopener" target="_blank">#{name}</a>}
|
||||
end
|
||||
|
||||
it 'links the gem name' do
|
||||
expect(subject).to include(link('Reachability', 'https://cocoapods.org/pods/Reachability'))
|
||||
end
|
||||
|
||||
it 'links the license' do
|
||||
expect(subject).to include(link('GPL-3.0', 'http://choosealicense.com/licenses/gpl-3.0/'))
|
||||
expect(subject).to include(link('MIT', 'http://choosealicense.com/licenses/mit/'))
|
||||
expect(subject).to include(link('Apache-2.0', 'http://choosealicense.com/licenses/apache-2.0/'))
|
||||
end
|
||||
|
||||
it 'links the homepage' do
|
||||
expect(subject).to include(link('https://github.com/tonymillion/Reachability', 'https://github.com/tonymillion/Reachability'))
|
||||
end
|
||||
|
||||
it 'links the source URL' do
|
||||
expect(subject).to include(link('https://github.com/tonymillion/Reachability.git', 'https://github.com/tonymillion/Reachability.git'))
|
||||
end
|
||||
|
||||
it 'links dependencies' do
|
||||
expect(subject).to include(link('AFNetworking', 'https://cocoapods.org/pods/AFNetworking'))
|
||||
expect(subject).to include(link('RestKit/CoreData', 'https://cocoapods.org/pods/RestKit'))
|
||||
expect(subject).to include(link('MBProgressHUD', 'https://cocoapods.org/pods/MBProgressHUD'))
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,87 @@
|
|||
require 'rails_helper'
|
||||
|
||||
describe Gitlab::DependencyLinker::RequirementsTxtLinker, lib: true do
|
||||
describe '.support?' do
|
||||
it 'supports requirements.txt' do
|
||||
expect(described_class.support?('requirements.txt')).to be_truthy
|
||||
end
|
||||
|
||||
it 'supports doc-requirements.txt' do
|
||||
expect(described_class.support?('doc-requirements.txt')).to be_truthy
|
||||
end
|
||||
|
||||
it 'does not support other files' do
|
||||
expect(described_class.support?('requirements')).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
describe '#link' do
|
||||
let(:file_name) { "requirements.txt" }
|
||||
|
||||
let(:file_content) do
|
||||
<<-CONTENT.strip_heredoc
|
||||
#
|
||||
####### example-requirements.txt #######
|
||||
#
|
||||
###### Requirements without Version Specifiers ######
|
||||
nose
|
||||
nose-cov
|
||||
beautifulsoup4
|
||||
#
|
||||
###### Requirements with Version Specifiers ######
|
||||
# See https://www.python.org/dev/peps/pep-0440/#version-specifiers
|
||||
docopt == 0.6.1 # Version Matching. Must be version 0.6.1
|
||||
keyring >= 4.1.1 # Minimum version 4.1.1
|
||||
coverage != 3.5 # Version Exclusion. Anything except version 3.5
|
||||
Mopidy-Dirble ~= 1.1 # Compatible release. Same as >= 1.1, == 1.*
|
||||
#
|
||||
###### Refer to other requirements files ######
|
||||
-r other-requirements.txt
|
||||
#
|
||||
#
|
||||
###### A particular file ######
|
||||
./downloads/numpy-1.9.2-cp34-none-win32.whl
|
||||
http://wxpython.org/Phoenix/snapshot-builds/wxPython_Phoenix-3.0.3.dev1820+49a8884-cp34-none-win_amd64.whl
|
||||
#
|
||||
###### Additional Requirements without Version Specifiers ######
|
||||
# Same as 1st section, just here to show that you can put things in any order.
|
||||
rejected
|
||||
green
|
||||
#
|
||||
|
||||
Jinja2>=2.3
|
||||
Pygments>=1.2
|
||||
Sphinx>=1.3
|
||||
docutils>=0.7
|
||||
markupsafe
|
||||
CONTENT
|
||||
end
|
||||
|
||||
subject { Gitlab::Highlight.highlight(file_name, file_content) }
|
||||
|
||||
def link(name, url)
|
||||
%{<a href="#{url}" rel="nofollow noreferrer noopener" target="_blank">#{name}</a>}
|
||||
end
|
||||
|
||||
it 'links dependencies' do
|
||||
expect(subject).to include(link('nose', 'https://pypi.python.org/pypi/nose'))
|
||||
expect(subject).to include(link('nose-cov', 'https://pypi.python.org/pypi/nose-cov'))
|
||||
expect(subject).to include(link('beautifulsoup4', 'https://pypi.python.org/pypi/beautifulsoup4'))
|
||||
expect(subject).to include(link('docopt', 'https://pypi.python.org/pypi/docopt'))
|
||||
expect(subject).to include(link('keyring', 'https://pypi.python.org/pypi/keyring'))
|
||||
expect(subject).to include(link('coverage', 'https://pypi.python.org/pypi/coverage'))
|
||||
expect(subject).to include(link('Mopidy-Dirble', 'https://pypi.python.org/pypi/Mopidy-Dirble'))
|
||||
expect(subject).to include(link('rejected', 'https://pypi.python.org/pypi/rejected'))
|
||||
expect(subject).to include(link('green', 'https://pypi.python.org/pypi/green'))
|
||||
expect(subject).to include(link('Jinja2', 'https://pypi.python.org/pypi/Jinja2'))
|
||||
expect(subject).to include(link('Pygments', 'https://pypi.python.org/pypi/Pygments'))
|
||||
expect(subject).to include(link('Sphinx', 'https://pypi.python.org/pypi/Sphinx'))
|
||||
expect(subject).to include(link('docutils', 'https://pypi.python.org/pypi/docutils'))
|
||||
expect(subject).to include(link('markupsafe', 'https://pypi.python.org/pypi/markupsafe'))
|
||||
end
|
||||
|
||||
it 'links URLs' do
|
||||
expect(subject).to include(link('http://wxpython.org/Phoenix/snapshot-builds/wxPython_Phoenix-3.0.3.dev1820+49a8884-cp34-none-win_amd64.whl', 'http://wxpython.org/Phoenix/snapshot-builds/wxPython_Phoenix-3.0.3.dev1820+49a8884-cp34-none-win_amd64.whl'))
|
||||
end
|
||||
end
|
||||
end
|
|
@ -9,5 +9,77 @@ describe Gitlab::DependencyLinker, lib: true do
|
|||
|
||||
described_class.link(blob_name, nil, nil)
|
||||
end
|
||||
|
||||
it 'links using GemspecLinker' do
|
||||
blob_name = 'gitlab_git.gemspec'
|
||||
|
||||
expect(described_class::GemspecLinker).to receive(:link)
|
||||
|
||||
described_class.link(blob_name, nil, nil)
|
||||
end
|
||||
|
||||
it 'links using PackageJsonLinker' do
|
||||
blob_name = 'package.json'
|
||||
|
||||
expect(described_class::PackageJsonLinker).to receive(:link)
|
||||
|
||||
described_class.link(blob_name, nil, nil)
|
||||
end
|
||||
|
||||
it 'links using ComposerJsonLinker' do
|
||||
blob_name = 'composer.json'
|
||||
|
||||
expect(described_class::ComposerJsonLinker).to receive(:link)
|
||||
|
||||
described_class.link(blob_name, nil, nil)
|
||||
end
|
||||
|
||||
it 'links using PodfileLinker' do
|
||||
blob_name = 'Podfile'
|
||||
|
||||
expect(described_class::PodfileLinker).to receive(:link)
|
||||
|
||||
described_class.link(blob_name, nil, nil)
|
||||
end
|
||||
|
||||
it 'links using PodspecLinker' do
|
||||
blob_name = 'Reachability.podspec'
|
||||
|
||||
expect(described_class::PodspecLinker).to receive(:link)
|
||||
|
||||
described_class.link(blob_name, nil, nil)
|
||||
end
|
||||
|
||||
it 'links using PodspecJsonLinker' do
|
||||
blob_name = 'AFNetworking.podspec.json'
|
||||
|
||||
expect(described_class::PodspecJsonLinker).to receive(:link)
|
||||
|
||||
described_class.link(blob_name, nil, nil)
|
||||
end
|
||||
|
||||
it 'links using CartfileLinker' do
|
||||
blob_name = 'Cartfile'
|
||||
|
||||
expect(described_class::CartfileLinker).to receive(:link)
|
||||
|
||||
described_class.link(blob_name, nil, nil)
|
||||
end
|
||||
|
||||
it 'links using GodepsJsonLinker' do
|
||||
blob_name = 'Godeps.json'
|
||||
|
||||
expect(described_class::GodepsJsonLinker).to receive(:link)
|
||||
|
||||
described_class.link(blob_name, nil, nil)
|
||||
end
|
||||
|
||||
it 'links using RequirementsTxtLinker' do
|
||||
blob_name = 'requirements.txt'
|
||||
|
||||
expect(described_class::RequirementsTxtLinker).to receive(:link)
|
||||
|
||||
described_class.link(blob_name, nil, nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -59,8 +59,6 @@ describe Gitlab::Highlight, lib: true do
|
|||
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
|
||||
|
|
Loading…
Reference in a new issue