cutting_edge 0.0.1 → 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +7 -2
- data/Gemfile.lock +130 -0
- data/LICENSE +68 -81
- data/Procfile +1 -0
- data/README.md +272 -74
- data/Rakefile +0 -5
- data/bin/cutting_edge +60 -45
- data/config.rb +55 -0
- data/cutting_edge.gemspec +33 -4
- data/heroku.config.rb +20 -0
- data/lib/cutting_edge.rb +1 -1
- data/lib/cutting_edge/app.rb +95 -19
- data/lib/cutting_edge/langs.rb +7 -1
- data/lib/cutting_edge/langs/python.rb +5 -1
- data/lib/cutting_edge/langs/ruby.rb +5 -1
- data/lib/cutting_edge/langs/rust.rb +5 -1
- data/lib/cutting_edge/public/images/error.svg +24 -0
- data/lib/cutting_edge/public/images/languages/python.svg +1 -0
- data/lib/cutting_edge/public/images/languages/ruby.svg +1 -0
- data/lib/cutting_edge/public/images/languages/rust.svg +1 -0
- data/lib/cutting_edge/public/images/ok.svg +24 -0
- data/lib/cutting_edge/public/javascript/clipboard.min.js +7 -0
- data/lib/cutting_edge/public/javascript/cuttingedge.js +53 -0
- data/lib/cutting_edge/public/stylesheets/primer.css +22 -0
- data/lib/cutting_edge/repo.rb +124 -18
- data/lib/cutting_edge/templates/_footer.html.erb +3 -0
- data/lib/cutting_edge/templates/_header.html.erb +8 -0
- data/lib/cutting_edge/templates/_overview.html.erb +9 -0
- data/lib/cutting_edge/templates/badge.svg.erb +39 -0
- data/lib/cutting_edge/templates/index.html.erb +62 -0
- data/lib/cutting_edge/templates/info.html.erb +101 -0
- data/lib/cutting_edge/templates/mail.html.erb +163 -0
- data/lib/cutting_edge/workers/badge.rb +33 -11
- data/lib/cutting_edge/workers/dependency.rb +36 -16
- data/lib/cutting_edge/workers/helpers.rb +8 -0
- data/lib/cutting_edge/workers/mail.rb +38 -0
- data/projects.yml +25 -0
- data/spec/app_spec.rb +115 -0
- data/spec/badge_worker_spec.rb +77 -0
- data/spec/dependency_worker_spec.rb +132 -0
- data/spec/email_worker_spec.rb +43 -0
- data/spec/fixtures.rb +180 -0
- data/spec/fixtures/projects.yml +27 -0
- data/spec/langs/python_spec.rb +47 -5
- data/spec/langs/ruby_spec.rb +105 -0
- data/spec/langs/rust_spec.rb +31 -0
- data/spec/repo_spec.rb +52 -0
- data/spec/spec_helper.rb +9 -1
- metadata +43 -15
- data/lib/cutting_edge/badge.rb +0 -46
data/spec/fixtures.rb
ADDED
@@ -0,0 +1,180 @@
|
|
1
|
+
def mock_dependencies(name)
|
2
|
+
{
|
3
|
+
'ok' =>
|
4
|
+
{
|
5
|
+
:locations => {
|
6
|
+
'ok.gemspec' =>
|
7
|
+
{:outdated_major=>[],
|
8
|
+
:outdated_patch=>[],
|
9
|
+
:ok=>
|
10
|
+
[
|
11
|
+
{:name=>'gollum-lib',
|
12
|
+
:required=>'~> 5.0',
|
13
|
+
:latest=>'5.0.3',
|
14
|
+
:type=>:runtime},
|
15
|
+
{:name => 'foobar',
|
16
|
+
:required => '= 1.0',
|
17
|
+
:latest => '1.0',
|
18
|
+
:type => :runtime
|
19
|
+
}
|
20
|
+
],
|
21
|
+
:no_requirement=>[],
|
22
|
+
:unknown=>[]},
|
23
|
+
},
|
24
|
+
:ok=>2,
|
25
|
+
:outdated=>:up_to_date,
|
26
|
+
:outdated_major=>0,
|
27
|
+
:outdated_minor=>0,
|
28
|
+
:outdated_patch=>0,
|
29
|
+
:outdated_total=>0,
|
30
|
+
:unknown=>0,
|
31
|
+
:no_requirement => 0
|
32
|
+
},
|
33
|
+
'gollum' =>
|
34
|
+
{
|
35
|
+
:locations=>
|
36
|
+
{'gollum.gemspec'=>
|
37
|
+
{:outdated_major=>
|
38
|
+
[{:name=>'mustache',
|
39
|
+
:required=>'>= 0.99.5, < 1.0.0',
|
40
|
+
:latest=>'1.1.1',
|
41
|
+
:type=>:runtime,
|
42
|
+
:url=>'https://rubygems.org/gems/mustache'},
|
43
|
+
{:name=>'octicons',
|
44
|
+
:required=>'~> 8.5',
|
45
|
+
:latest=>'9.6.0',
|
46
|
+
:type=>:runtime,
|
47
|
+
:url=>'https://rubygems.org/gems/octicons'}],
|
48
|
+
:outdated_minor=>
|
49
|
+
[{:name=>'kramdown-parser-gfm',
|
50
|
+
:required=>'~> 1.0.0',
|
51
|
+
:latest=>'1.1.0',
|
52
|
+
:type=>:runtime,
|
53
|
+
:url=>'https://rubygems.org/gems/kramdown-parser-gfm'}],
|
54
|
+
:outdated_patch=>[],
|
55
|
+
:ok=>
|
56
|
+
[{:name=>'gollum-lib',
|
57
|
+
:required=>'~> 5.0',
|
58
|
+
:latest=>'5.0.3',
|
59
|
+
:type=>:runtime,
|
60
|
+
:url=>'https://rubygems.org/gems/gollum-lib'},
|
61
|
+
{:name=>'foobar',
|
62
|
+
:required=>'= 1.0',
|
63
|
+
:latest=>'1.0',
|
64
|
+
:type=>:runtime,
|
65
|
+
:url=>'https://rubygems.org/gems/foobar'}],
|
66
|
+
:no_requirement=>[],
|
67
|
+
:unknown=>[]},
|
68
|
+
'Gemfile'=>
|
69
|
+
{:outdated_major=>
|
70
|
+
[{:name=>'rake',
|
71
|
+
:required=>'~> 12.3, >= 12.3.3',
|
72
|
+
:latest=>'13.0.1',
|
73
|
+
:type=>:runtime,
|
74
|
+
:url=>'https://rubygems.org/gems/rake'}],
|
75
|
+
:outdated_minor=>[],
|
76
|
+
:outdated_patch=>[],
|
77
|
+
:ok=>
|
78
|
+
[{:name=>'warbler',
|
79
|
+
:required=>'>= 0',
|
80
|
+
:latest=>'2.0.5',
|
81
|
+
:type=>:runtime,
|
82
|
+
:url=>'https://rubygems.org/gems/warbler'}],
|
83
|
+
:no_requirement=>[],
|
84
|
+
:unknown=>[]}},
|
85
|
+
:ok=>3,
|
86
|
+
:outdated=>:outdated_major,
|
87
|
+
:outdated_major=>3,
|
88
|
+
:outdated_minor=>1,
|
89
|
+
:outdated_patch=>0,
|
90
|
+
:outdated_total=>4,
|
91
|
+
:unknown=>0,
|
92
|
+
:no_requirement => 0
|
93
|
+
},
|
94
|
+
'gollum-updated' =>
|
95
|
+
{
|
96
|
+
:locations =>
|
97
|
+
{'gollum.gemspec'=>
|
98
|
+
{:outdated_major=>
|
99
|
+
[{:name=>'mustache',
|
100
|
+
:required=>'>= 0.99.5, < 1.0.0',
|
101
|
+
:latest=>'2.1.1',
|
102
|
+
:type=>:runtime,
|
103
|
+
:url=>'https://rubygems.org/gems/mustache'},
|
104
|
+
{:name=>'octicons',
|
105
|
+
:required=>'~> 8.5',
|
106
|
+
:latest=>'10.6.0',
|
107
|
+
:type=>:runtime,
|
108
|
+
:url=>'https://rubygems.org/gems/octicons'},
|
109
|
+
{:name=>'kramdown-parser-gfm',
|
110
|
+
:required=>'~> 1.0.0',
|
111
|
+
:latest=>'2.1.0',
|
112
|
+
:type=>:runtime,
|
113
|
+
:url=>'https://rubygems.org/gems/kramdown-parser-gfm'},
|
114
|
+
{:name=>'gollum-lib',
|
115
|
+
:required=>'~> 5.0',
|
116
|
+
:latest=>'6.0.3',
|
117
|
+
:type=>:runtime,
|
118
|
+
:url=>'https://rubygems.org/gems/gollum-lib'},
|
119
|
+
{:name=>'foobar',
|
120
|
+
:required=>'= 1.0',
|
121
|
+
:latest=>'2.0',
|
122
|
+
:type=>:runtime,
|
123
|
+
:url=>'https://rubygems.org/gems/foobar'}],
|
124
|
+
:outdated_minor=>[],
|
125
|
+
:outdated_patch=>[],
|
126
|
+
:ok=>[],
|
127
|
+
:no_requirement=>[],
|
128
|
+
:unknown=>[]},
|
129
|
+
'Gemfile'=>
|
130
|
+
{:outdated_major=>
|
131
|
+
[{:name=>'rake',
|
132
|
+
:required=>'~> 12.3, >= 12.3.3',
|
133
|
+
:latest=>'14.0.1',
|
134
|
+
:type=>:runtime,
|
135
|
+
:url=>'https://rubygems.org/gems/rake'}],
|
136
|
+
:outdated_minor=>[],
|
137
|
+
:outdated_patch=>[],
|
138
|
+
:ok=>
|
139
|
+
[{:name=>'warbler',
|
140
|
+
:required=>'>= 0',
|
141
|
+
:latest=>'3.0.5',
|
142
|
+
:type=>:runtime,
|
143
|
+
:url=>'https://rubygems.org/gems/warbler'}],
|
144
|
+
:no_requirement=>[],
|
145
|
+
:unknown=>[]}},
|
146
|
+
:no_requirement=>0,
|
147
|
+
:ok=>1,
|
148
|
+
:outdated=>:outdated_major,
|
149
|
+
:outdated_major=>6,
|
150
|
+
:outdated_minor=>0,
|
151
|
+
:outdated_patch=>0,
|
152
|
+
:outdated_total=>6,
|
153
|
+
:unknown=>0,
|
154
|
+
:no_requirement => 0
|
155
|
+
}
|
156
|
+
}[name]
|
157
|
+
end
|
158
|
+
|
159
|
+
def mock_dependencies_no_stats(name)
|
160
|
+
stats = DependencyWorker::STATUS_TYPES + [:outdated_total, :outdated]
|
161
|
+
mock_dependencies(name).reject {|k,v| stats.include?(k) }
|
162
|
+
end
|
163
|
+
|
164
|
+
def mock_fetched_requirements(name, location, update_latest = false)
|
165
|
+
dependencies = mock_dependencies(name)[:locations][location]
|
166
|
+
results = []
|
167
|
+
dependencies.each_value do |dependency_type|
|
168
|
+
dependency_type.each do |dependency|
|
169
|
+
gem_dependency = Gem::Dependency.new(dependency[:name], dependency[:required].split(','), dependency[:type])
|
170
|
+
latest_version = Gem::Version.new(dependency[:latest])
|
171
|
+
if update_latest
|
172
|
+
segments = latest_version.segments
|
173
|
+
segments[0] = segments[0] + 1
|
174
|
+
latest_version = Gem::Version.new(segments.join('.'))
|
175
|
+
end
|
176
|
+
results << [gem_dependency, latest_version]
|
177
|
+
end
|
178
|
+
end
|
179
|
+
results
|
180
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Example projects.yml file for CuttingEdge
|
2
|
+
# For more information and options, see: https://github.com/repotag/cutting_edge
|
3
|
+
|
4
|
+
github:
|
5
|
+
repotag:
|
6
|
+
cutting_edge:
|
7
|
+
language: ruby
|
8
|
+
gollum:
|
9
|
+
gollum:
|
10
|
+
language: ruby
|
11
|
+
gollum-lib:
|
12
|
+
locations: [gemspec.rb]
|
13
|
+
dependency_types: [runtime, development]
|
14
|
+
singingwolfboy:
|
15
|
+
flask-dance:
|
16
|
+
language: python
|
17
|
+
email: false
|
18
|
+
rust-lang:
|
19
|
+
crates.io:
|
20
|
+
language: rust
|
21
|
+
gitlab:
|
22
|
+
cthowl01:
|
23
|
+
team-chess-ruby:
|
24
|
+
locations: [Gemfile]
|
25
|
+
gitlab-org:
|
26
|
+
gitlab-foss:
|
27
|
+
hide: mysecret
|
data/spec/langs/python_spec.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
REQUIREMENT_TXT = <<EOF
|
2
|
-
requests>=2.0
|
2
|
+
requests >= 2.0
|
3
3
|
oauthlib
|
4
4
|
requests-oauthlib>=1.0.0 [PDF]
|
5
5
|
-e svn+http://myrepo/svn/MyApp#egg=MyApp
|
@@ -36,12 +36,52 @@ unittest2 = {version = ">=1.0,<3.0", markers="python_version < '2.7.9' or (pytho
|
|
36
36
|
EOF
|
37
37
|
|
38
38
|
describe PythonLang do
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
39
|
+
|
40
|
+
let(:requirements_latest_versions) {
|
41
|
+
{
|
42
|
+
'requests': Gem::Version.new('2.24.0'),
|
43
|
+
'oauthlib': Gem::Version.new('3.1.0'),
|
44
|
+
'requests-oauthlib': Gem::Version.new('1.3.0'),
|
45
|
+
'Flask': Gem::Version.new('1.1.2'),
|
46
|
+
'urlobject': Gem::Version.new('2.4.3'),
|
47
|
+
'six': Gem::Version.new('1.15.0'),
|
48
|
+
}
|
49
|
+
}
|
50
|
+
let(:pipfile_latest_versions) {
|
51
|
+
{
|
52
|
+
'records': Gem::Version.new('0.5.3'),
|
53
|
+
'foo': Gem::Version.new('0.1'),
|
54
|
+
'bar': Gem::Version.new('0.2.1'),
|
55
|
+
'baz': Gem::Version.new('0.2.6'),
|
56
|
+
'pywinusb': Gem::Version.new('0.4.2'),
|
57
|
+
'nose': Gem::Version.new('1.3.7'),
|
58
|
+
'unittest2': Gem::Version.new('1.1.0')
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
it 'expects the default dependency files to be requirements.txt and Pipfile' do
|
63
|
+
expect(PythonLang.locations).to eq ['requirements.txt', 'Pipfile']
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'returns a website for a dependency' do
|
67
|
+
expect(PythonLang.website('foobar')).to eq 'https://pypi.org/project/foobar'
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'fetches latest version' do
|
71
|
+
mock = OpenStruct.new(
|
72
|
+
parse: {'info' => {'version' => '1.0.0'}}
|
73
|
+
)
|
74
|
+
allow_any_instance_of(HTTP::Client).to receive(:get).with('https://pypi.org/pypi/sinatra/json').and_return(mock)
|
75
|
+
expect(Gem::Version).to receive(:new).with('1.0.0').and_call_original
|
76
|
+
PythonLang.latest_version('sinatra')
|
77
|
+
|
78
|
+
allow_any_instance_of(HTTP::Client).to receive(:get).and_raise(HTTP::Error)
|
79
|
+
expect(PythonLang.latest_version('fail')).to be_nil
|
80
|
+
end
|
43
81
|
|
82
|
+
context 'requirements.txt' do
|
44
83
|
it 'parses requirements.txt' do
|
84
|
+
expect(PythonLang).to receive(:latest_version).and_return(*requirements_latest_versions.values)
|
45
85
|
result = PythonLang.parse_file('requirements.txt', REQUIREMENT_TXT)
|
46
86
|
expect(result).to be_a Array
|
47
87
|
expect(result.length).to eq 6
|
@@ -59,6 +99,8 @@ describe PythonLang do
|
|
59
99
|
end
|
60
100
|
|
61
101
|
it 'parses Pipefile' do
|
102
|
+
expect(PythonLang).to receive(:latest_version).and_return(*pipfile_latest_versions.values)
|
103
|
+
|
62
104
|
result = PythonLang.parse_file('Pipfile', PIPFILE)
|
63
105
|
expect(result).to be_a Array
|
64
106
|
|
@@ -0,0 +1,105 @@
|
|
1
|
+
GEMSPEC = <<EOF
|
2
|
+
s.rubygems_version = '1.3.5'
|
3
|
+
s.required_ruby_version = '>= 2.4'
|
4
|
+
|
5
|
+
s.name = 'cutting_edge'
|
6
|
+
s.version = '0.0.1'
|
7
|
+
s.date = '2020-02-19'
|
8
|
+
s.license = 'GPL-3.0-only'
|
9
|
+
|
10
|
+
s.summary = 'Self-hosted dependency monitoring, including shiny badges.'
|
11
|
+
s.description = 'Self-hosted dependency monitoring, including shiny badges.'
|
12
|
+
|
13
|
+
s.authors = ['Dawa Ometto', 'Bart Kamphorst']
|
14
|
+
s.email = 'd.ometto@gmail.com'
|
15
|
+
s.homepage = 'http://github.com/repotag/cutting_edge'
|
16
|
+
|
17
|
+
s.require_paths = %w[lib]
|
18
|
+
|
19
|
+
s.executables = ['cutting_edge']
|
20
|
+
|
21
|
+
s.add_dependency 'gemnasium-parser', '~> 0.1.9'
|
22
|
+
s.add_dependency 'http', '~> 4.3'
|
23
|
+
s.add_dependency 'sucker_punch', '~> 2.1'
|
24
|
+
s.add_dependency 'sinatra', '~> 2.0'
|
25
|
+
s.add_dependency 'moneta', '~> 1.2'
|
26
|
+
s.add_dependency 'rufus-scheduler', '~> 3.6'
|
27
|
+
s.add_dependency 'sinatra-logger', '~> 0.3'
|
28
|
+
s.add_dependency 'toml-rb', '~> 2.0'
|
29
|
+
EOF
|
30
|
+
|
31
|
+
GEMFILE = <<EOF
|
32
|
+
source 'https://rubygems.org'
|
33
|
+
|
34
|
+
gem 'redis', require: false
|
35
|
+
gem 'mail'
|
36
|
+
|
37
|
+
gem 'hashdiff'
|
38
|
+
|
39
|
+
gem 'rspec', '~> 3.9', :group => :development
|
40
|
+
gem 'simplecov', :group => :development
|
41
|
+
|
42
|
+
gem 'coveralls', '~>0.8.23', require: false
|
43
|
+
|
44
|
+
gemspec
|
45
|
+
EOF
|
46
|
+
|
47
|
+
describe RubyLang do
|
48
|
+
let(:gemfile_latest_versions) {
|
49
|
+
{
|
50
|
+
'redis': Gem::Version.new('4.2.2'),
|
51
|
+
'mail': Gem::Version.new('2.7.1'),
|
52
|
+
'hashdiff': Gem::Version.new('1.0.1'),
|
53
|
+
'rspec': Gem::Version.new('3.9.0'),
|
54
|
+
'simplecov': Gem::Version.new('0.19.0'),
|
55
|
+
'coveralls': Gem::Version.new('0.8.23'),
|
56
|
+
}
|
57
|
+
}
|
58
|
+
let(:gemspec_latest_versions) {
|
59
|
+
{
|
60
|
+
'gemnasium-parser': Gem::Version.new('0.1.9'),
|
61
|
+
'http': Gem::Version.new('4.4.1'),
|
62
|
+
'sucker_punch': Gem::Version.new('2.1.2'),
|
63
|
+
'sinatra': Gem::Version.new('2.1.0'),
|
64
|
+
'moneta': Gem::Version.new('1.4.0'),
|
65
|
+
'rufus-scheduler': Gem::Version.new('3.6.0'),
|
66
|
+
'sinatra-logger': Gem::Version.new('0.3.2'),
|
67
|
+
'toml-rb': Gem::Version.new('2.0.1'),
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
71
|
+
it 'expects the default dependency files to be gemspec and Gemfile' do
|
72
|
+
expect(RubyLang.locations('test')).to eq ['test.gemspec', 'Gemfile']
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'returns a website for a dependency' do
|
76
|
+
expect(RubyLang.website('foobar')).to eq 'https://rubygems.org/gems/foobar'
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'fetches latest version' do
|
80
|
+
expect(Gem::SpecFetcher.fetcher).to receive(:spec_for_dependency).and_return([])
|
81
|
+
RubyLang.latest_version('sinatra')
|
82
|
+
|
83
|
+
allow(Gem::SpecFetcher).to receive(:fetcher).and_raise(StandardError)
|
84
|
+
expect(RubyLang.latest_version('fail')).to be_nil
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'parses gemspec' do
|
88
|
+
expect(RubyLang).to receive(:latest_version).and_return(*gemspec_latest_versions.values)
|
89
|
+
results = RubyLang.parse_file('test.gemspec', GEMSPEC)
|
90
|
+
expect(results.length).to eq 8
|
91
|
+
expect(results.last.first).to be_a Bundler::Dependency
|
92
|
+
expect(results.last.first.name).to eq 'toml-rb'
|
93
|
+
expect(results.last.last).to be_a Gem::Version
|
94
|
+
expect(results.last.last.to_s).to eq '2.0.1'
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'parses gemfile' do
|
98
|
+
expect(RubyLang).to receive(:latest_version).and_return(*gemfile_latest_versions.values)
|
99
|
+
results = RubyLang.parse_file('Gemfile', GEMFILE)
|
100
|
+
expect(results.length).to eq 6
|
101
|
+
expect(results.last.first).to be_a Bundler::Dependency
|
102
|
+
expect(results.last.first.name).to eq 'coveralls'
|
103
|
+
expect(results.last.last.to_s).to eq '0.8.23'
|
104
|
+
end
|
105
|
+
end
|
data/spec/langs/rust_spec.rb
CHANGED
@@ -20,11 +20,42 @@ def translate_req(str)
|
|
20
20
|
end
|
21
21
|
|
22
22
|
describe RustLang do
|
23
|
+
let(:rust_latest_versions) {
|
24
|
+
{
|
25
|
+
'log': Gem::Version.new('0.4.11'),
|
26
|
+
'regex': Gem::Version.new('1.3.9'),
|
27
|
+
'termcolor': Gem::Version.new('1.1.0'),
|
28
|
+
'humantime': Gem::Version.new('2.0.1'),
|
29
|
+
'atty': Gem::Version.new('0.2.14'),
|
30
|
+
'uuid': Gem::Version.new('0.8.1'),
|
31
|
+
'tempdir': Gem::Version.new('0.3.7'),
|
32
|
+
'cc': Gem::Version.new('1.0.59'),
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
23
36
|
it 'expects the default dependency files to be Cargo.toml' do
|
24
37
|
expect(RustLang.locations).to eq ['Cargo.toml']
|
25
38
|
end
|
39
|
+
|
40
|
+
it 'returns a website for a dependency' do
|
41
|
+
expect(RustLang.website('foobar')).to eq 'https://crates.io/crates/foobar'
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'fetches latest version' do
|
45
|
+
mock = OpenStruct.new(
|
46
|
+
parse: {'crate' => {'max_version' => '1.0.0'}}
|
47
|
+
)
|
48
|
+
allow_any_instance_of(HTTP::Client).to receive(:get).with('https://crates.io/api/v1/crates/sinatra').and_return(mock)
|
49
|
+
expect(Gem::Version).to receive(:new).with('1.0.0').and_call_original
|
50
|
+
RustLang.latest_version('sinatra')
|
51
|
+
|
52
|
+
allow_any_instance_of(HTTP::Client).to receive(:get).and_raise(HTTP::Error)
|
53
|
+
expect(RustLang.latest_version('fail')).to be_nil
|
54
|
+
end
|
26
55
|
|
27
56
|
it 'parses Cargo.toml' do
|
57
|
+
expect(RustLang).to receive(:latest_version).and_return(*rust_latest_versions.values)
|
58
|
+
|
28
59
|
results = RustLang.parse_file('Cargo.toml', CARGO)
|
29
60
|
expect(results.length).to eq 9
|
30
61
|
|
data/spec/repo_spec.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
describe CuttingEdge::Repository do
|
2
|
+
|
3
|
+
it 'is capable of being hidden' do
|
4
|
+
expect(CuttingEdge::Repository.new(org: 'org', name: 'name').hidden?).to be false
|
5
|
+
hide_token = 'mytoken'
|
6
|
+
repo_with_hide = CuttingEdge::Repository.new(org: 'org', name: 'name', hide: hide_token)
|
7
|
+
expect(repo_with_hide.hidden?).to be true
|
8
|
+
expect(repo_with_hide.hidden_token).to eq hide_token
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'has a headers method' do
|
12
|
+
expect(CuttingEdge::Repository.headers(nil)).to eq ({})
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'GitHub' do
|
16
|
+
it 'has a headers method' do
|
17
|
+
expect(CuttingEdge::GithubRepository.headers(nil)).to eq ({:accept => 'application/vnd.github.v3.raw'})
|
18
|
+
expect(CuttingEdge::GithubRepository.headers('token')).to eq ({:accept => 'application/vnd.github.v3.raw', :authorization => 'token token'})
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'defines a class for GitHub.com' do
|
22
|
+
expect(CuttingEdge::GithubRepository).to_not be_nil
|
23
|
+
github = CuttingEdge::GithubRepository.new(org: 'org', name: 'name')
|
24
|
+
expect(github.source).to eq 'github'
|
25
|
+
expect(github.url_for_file('file')).to eq 'https://api.github.com/repos/org/name/contents/file?ref=master'
|
26
|
+
expect(github.url_for_project).to eq 'https://github.com/org/name'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'dynamic definitions' do
|
31
|
+
|
32
|
+
it 'defines a class for GitLab.com' do
|
33
|
+
expect(CuttingEdge::GitlabRepository).to_not be_nil
|
34
|
+
expect(CuttingEdge::GitlabRepository.headers(nil)).to eq ({})
|
35
|
+
expect(CuttingEdge::GitlabRepository.headers('token')).to eq ({:authorization => 'Bearer token'})
|
36
|
+
gitlab = CuttingEdge::GitlabRepository.new(org: 'org', name: 'name')
|
37
|
+
expect(gitlab.source).to eq 'gitlab'
|
38
|
+
expect(gitlab.url_for_file('file')).to eq 'https://gitlab.com/api/v4/projects/org%2fname/repository/files/file/raw?ref=master'
|
39
|
+
expect(gitlab.url_for_project).to eq 'https://gitlab.com/org/name'
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'dynamically defines providers' do
|
43
|
+
expect(defined?(CuttingEdge::GiteaRepository)).to be_nil
|
44
|
+
define_gitea_server('gitea', 'https://mydependencymonitoring.com')
|
45
|
+
expect(defined?(CuttingEdge::GiteaRepository)).to_not be_nil
|
46
|
+
gitea = CuttingEdge::GiteaRepository.new(org: 'org', name: 'name')
|
47
|
+
expect(gitea.source).to eq 'gitea'
|
48
|
+
expect(gitea.url_for_file('file')).to eq 'https://mydependencymonitoring.com/api/v1/repos/org/name/raw/master/file'
|
49
|
+
expect(gitea.url_for_project).to eq 'https://mydependencymonitoring.com/org/name'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|