summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouwe Maan <douwe@selenight.nl>2016-07-10 18:58:55 -0500
committerDouwe Maan <douwe@selenight.nl>2016-07-10 20:52:09 -0500
commitb1de9d82b9435436a9c44862b350b2b343ea827f (patch)
treef65dde93cdeac877e80acaa869e032285682192f
parent66857f43599d809f93b0e328cd92acf6711268f5 (diff)
downloadgitlab-ce-b1de9d82b9435436a9c44862b350b2b343ea827f.tar.gz
Autolink packages in requirements.txt
-rw-r--r--lib/gitlab/dependency_linker.rb1
-rw-r--r--lib/gitlab/dependency_linker/requirements_txt_linker.rb19
-rw-r--r--spec/lib/gitlab/dependency_linker/requirements_txt_linker_spec.rb83
-rw-r--r--spec/lib/gitlab/dependency_linker_spec.rb8
4 files changed, 111 insertions, 0 deletions
diff --git a/lib/gitlab/dependency_linker.rb b/lib/gitlab/dependency_linker.rb
index 37923dcc017..57fc3c6e0e5 100644
--- a/lib/gitlab/dependency_linker.rb
+++ b/lib/gitlab/dependency_linker.rb
@@ -10,6 +10,7 @@ module Gitlab
PodspecJsonLinker,
CartfileLinker,
GodepsJsonLinker,
+ RequirementsTxtLinker
]
def self.link(blob_name, plain_text, highlighted_text)
diff --git a/lib/gitlab/dependency_linker/requirements_txt_linker.rb b/lib/gitlab/dependency_linker/requirements_txt_linker.rb
new file mode 100644
index 00000000000..92fcb8177ea
--- /dev/null
+++ b/lib/gitlab/dependency_linker/requirements_txt_linker.rb
@@ -0,0 +1,19 @@
+module Gitlab
+ module DependencyLinker
+ class RequirementsTxtLinker < BaseLinker
+ def self.support?(blob_name)
+ blob_name.end_with?('requirements.txt')
+ end
+
+ private
+
+ def link_dependencies
+ link_regex(/(?<name>^(?![a-z+]+:)[^#.-][^ ><=;\[]+)/)
+ end
+
+ def package_url(name)
+ "https://pypi.python.org/pypi/#{name}"
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/dependency_linker/requirements_txt_linker_spec.rb b/spec/lib/gitlab/dependency_linker/requirements_txt_linker_spec.rb
new file mode 100644
index 00000000000..a334bb38db1
--- /dev/null
+++ b/spec/lib/gitlab/dependency_linker/requirements_txt_linker_spec.rb
@@ -0,0 +1,83 @@
+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, nowrap: false) }
+
+ def link(name, url)
+ %{<a href="#{url}" rel="nofollow noreferrer" 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
+ end
+end
diff --git a/spec/lib/gitlab/dependency_linker_spec.rb b/spec/lib/gitlab/dependency_linker_spec.rb
index 15a8bf6a426..3d1cfbcfbf7 100644
--- a/spec/lib/gitlab/dependency_linker_spec.rb
+++ b/spec/lib/gitlab/dependency_linker_spec.rb
@@ -73,5 +73,13 @@ describe Gitlab::DependencyLinker, lib: true do
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