librariesio-gem-parser 1.0.0
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 +7 -0
- data/.gitignore +18 -0
- data/.travis.yml +4 -0
- data/CHANGELOG.md +19 -0
- data/Gemfile +3 -0
- data/LICENSE +22 -0
- data/README.md +55 -0
- data/Rakefile +9 -0
- data/lib/gemnasium/parser.rb +35 -0
- data/lib/gemnasium/parser/configuration.rb +11 -0
- data/lib/gemnasium/parser/gemfile.rb +109 -0
- data/lib/gemnasium/parser/gemspec.rb +38 -0
- data/lib/gemnasium/parser/patterns.rb +69 -0
- data/lib/gemnasium/parser/podfile.rb +91 -0
- data/lib/gemnasium/parser/podspec.rb +38 -0
- data/librariesio-gem-parser.gemspec +20 -0
- data/spec/gemnasium/parser/gemfile_spec.rb +294 -0
- data/spec/gemnasium/parser/gemspec_spec.rb +159 -0
- data/spec/gemnasium/parser/podfile_spec.rb +239 -0
- data/spec/gemnasium/parser/podspec_spec.rb +150 -0
- data/spec/gemnasium/parser_spec.rb +34 -0
- data/spec/spec_helper.rb +1 -0
- metadata +111 -0
@@ -0,0 +1,38 @@
|
|
1
|
+
module Gemnasium
|
2
|
+
module Parser
|
3
|
+
class Podspec
|
4
|
+
attr_reader :content
|
5
|
+
|
6
|
+
def initialize(content)
|
7
|
+
@content = content
|
8
|
+
end
|
9
|
+
|
10
|
+
def dependencies
|
11
|
+
@dependencies ||= [].tap do |deps|
|
12
|
+
runtime_matches.each do |match|
|
13
|
+
dep = dependency(match)
|
14
|
+
deps << dep
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def runtime_matches
|
21
|
+
@runtime_matches ||= matches(Patterns::ADD_POD_DEPENDENCY_CALL)
|
22
|
+
end
|
23
|
+
|
24
|
+
def matches(pattern)
|
25
|
+
[].tap{|m| content.scan(pattern){ m << Regexp.last_match } }
|
26
|
+
end
|
27
|
+
|
28
|
+
def dependency(match)
|
29
|
+
name, reqs = match["name"], [match["req1"], match["req2"]].compact
|
30
|
+
type = :runtime
|
31
|
+
Bundler::Dependency.new(name, reqs, "type" => type).tap do |dep|
|
32
|
+
line = content.slice(0, match.begin(0)).count("\n") + 1
|
33
|
+
dep.instance_variable_set(:@line, line)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
Gem::Specification.new do |gem|
|
4
|
+
gem.name = "librariesio-gem-parser"
|
5
|
+
gem.version = "1.0.0"
|
6
|
+
|
7
|
+
gem.authors = "Andrew Nesbitt"
|
8
|
+
gem.email = "andrewnez@gmail.com"
|
9
|
+
gem.description = "Fork of gemnasium-parser"
|
10
|
+
gem.summary = gem.description
|
11
|
+
gem.homepage = "https://github.com/librariesio/gemnasium-parser"
|
12
|
+
|
13
|
+
gem.add_development_dependency "bundler", "~> 1.0"
|
14
|
+
gem.add_development_dependency "rake", ">= 0.8.7"
|
15
|
+
gem.add_development_dependency "rspec", "~> 2.4"
|
16
|
+
|
17
|
+
gem.files = `git ls-files`.split($\)
|
18
|
+
gem.test_files = gem.files.grep(/^spec\//)
|
19
|
+
gem.require_paths = ["lib"]
|
20
|
+
end
|
@@ -0,0 +1,294 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Gemnasium::Parser::Gemfile do
|
4
|
+
def content(string)
|
5
|
+
@content ||= begin
|
6
|
+
indent = string.scan(/^[ \t]*(?=\S)/)
|
7
|
+
n = indent ? indent.size : 0
|
8
|
+
string.gsub(/^[ \t]{#{n}}/, "")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def gemfile
|
13
|
+
@gemfile ||= Gemnasium::Parser::Gemfile.new(@content)
|
14
|
+
end
|
15
|
+
|
16
|
+
def dependencies
|
17
|
+
@dependencies ||= gemfile.dependencies
|
18
|
+
end
|
19
|
+
|
20
|
+
def dependency
|
21
|
+
dependencies.size.should == 1
|
22
|
+
dependencies.first
|
23
|
+
end
|
24
|
+
|
25
|
+
def reset
|
26
|
+
@content = @gemfile = @dependencies = nil
|
27
|
+
end
|
28
|
+
|
29
|
+
it "parses double quotes" do
|
30
|
+
content(%(gem "rake", ">= 0.8.7"))
|
31
|
+
dependency.name.should == "rake"
|
32
|
+
dependency.requirement.as_list.should == [">= 0.8.7"]
|
33
|
+
end
|
34
|
+
|
35
|
+
it "parses single quotes" do
|
36
|
+
content(%(gem 'rake', '>= 0.8.7'))
|
37
|
+
dependency.name.should == "rake"
|
38
|
+
dependency.requirement.as_list.should == [">= 0.8.7"]
|
39
|
+
end
|
40
|
+
|
41
|
+
it "ignores mixed quotes" do
|
42
|
+
content(%(gem "rake', ">= 0.8.7"))
|
43
|
+
dependencies.size.should == 0
|
44
|
+
end
|
45
|
+
|
46
|
+
it "parses gems with a period in the name" do
|
47
|
+
content(%(gem "pygment.rb", ">= 0.8.7"))
|
48
|
+
dependency.name.should == "pygment.rb"
|
49
|
+
dependency.requirement.as_list.should == [">= 0.8.7"]
|
50
|
+
end
|
51
|
+
|
52
|
+
it "parses non-requirement gems" do
|
53
|
+
content(%(gem "rake"))
|
54
|
+
dependency.name.should == "rake"
|
55
|
+
dependency.requirement.as_list.should == [">= 0"]
|
56
|
+
end
|
57
|
+
|
58
|
+
it "parses multi-requirement gems" do
|
59
|
+
content(%(gem "rake", ">= 0.8.7", "<= 0.9.2"))
|
60
|
+
dependency.name.should == "rake"
|
61
|
+
dependency.requirement.as_list.should == ["<= 0.9.2", ">= 0.8.7"]
|
62
|
+
end
|
63
|
+
|
64
|
+
it "parses gems with options" do
|
65
|
+
content(%(gem "rake", ">= 0.8.7", :require => false))
|
66
|
+
dependency.name.should == "rake"
|
67
|
+
dependency.requirement.as_list.should == [">= 0.8.7"]
|
68
|
+
end
|
69
|
+
|
70
|
+
it "listens for gemspecs" do
|
71
|
+
content(%(gemspec))
|
72
|
+
gemfile.should be_gemspec
|
73
|
+
gemfile.gemspec.should == "*.gemspec"
|
74
|
+
reset
|
75
|
+
content(%(gem "rake"))
|
76
|
+
gemfile.should_not be_gemspec
|
77
|
+
gemfile.gemspec.should be_nil
|
78
|
+
end
|
79
|
+
|
80
|
+
it "parses gemspecs with a name option" do
|
81
|
+
content(%(gemspec :name => "gemnasium-parser"))
|
82
|
+
gemfile.gemspec.should == "gemnasium-parser.gemspec"
|
83
|
+
end
|
84
|
+
|
85
|
+
it "parses gemspecs with a path option" do
|
86
|
+
content(%(gemspec :path => "lib/gemnasium"))
|
87
|
+
gemfile.gemspec.should == "lib/gemnasium/*.gemspec"
|
88
|
+
end
|
89
|
+
|
90
|
+
it "parses gemspecs with name and path options" do
|
91
|
+
content(%(gemspec :name => "parser", :path => "lib/gemnasium"))
|
92
|
+
gemfile.gemspec.should == "lib/gemnasium/parser.gemspec"
|
93
|
+
end
|
94
|
+
|
95
|
+
it "parses gemspecs with parentheses" do
|
96
|
+
content(%(gemspec(:name => "gemnasium-parser")))
|
97
|
+
gemfile.should be_gemspec
|
98
|
+
end
|
99
|
+
|
100
|
+
it "parses gems of a type" do
|
101
|
+
content(%(gem "rake"))
|
102
|
+
dependency.type.should == :runtime
|
103
|
+
reset
|
104
|
+
content(%(gem "rake", :type => :development))
|
105
|
+
dependency.type.should == :development
|
106
|
+
end
|
107
|
+
|
108
|
+
it "parses gems of a group" do
|
109
|
+
content(%(gem "rake"))
|
110
|
+
dependency.groups.should == [:default]
|
111
|
+
reset
|
112
|
+
content(%(gem "rake", :group => :development))
|
113
|
+
dependency.groups.should == [:development]
|
114
|
+
end
|
115
|
+
|
116
|
+
it "parses gems of multiple groups" do
|
117
|
+
content(%(gem "rake", :group => [:development, :test]))
|
118
|
+
dependency.groups.should == [:development, :test]
|
119
|
+
end
|
120
|
+
|
121
|
+
it "recognizes :groups" do
|
122
|
+
content(%(gem "rake", :groups => [:development, :test]))
|
123
|
+
dependency.groups.should == [:development, :test]
|
124
|
+
end
|
125
|
+
|
126
|
+
it "parses gems in a group" do
|
127
|
+
content(<<-EOF)
|
128
|
+
gem "rake"
|
129
|
+
group :production do
|
130
|
+
gem "pg"
|
131
|
+
end
|
132
|
+
group :development do
|
133
|
+
gem "sqlite3"
|
134
|
+
end
|
135
|
+
EOF
|
136
|
+
dependencies[0].groups.should == [:default]
|
137
|
+
dependencies[1].groups.should == [:production]
|
138
|
+
dependencies[2].groups.should == [:development]
|
139
|
+
end
|
140
|
+
|
141
|
+
it "parses gems in a group with parentheses" do
|
142
|
+
content(<<-EOF)
|
143
|
+
group(:production) do
|
144
|
+
gem "pg"
|
145
|
+
end
|
146
|
+
EOF
|
147
|
+
dependency.groups.should == [:production]
|
148
|
+
end
|
149
|
+
|
150
|
+
it "parses gems in multiple groups" do
|
151
|
+
content(<<-EOF)
|
152
|
+
group :development, :test do
|
153
|
+
gem "sqlite3"
|
154
|
+
end
|
155
|
+
EOF
|
156
|
+
dependency.groups.should == [:development, :test]
|
157
|
+
end
|
158
|
+
|
159
|
+
it "parses multiple gems in a group" do
|
160
|
+
content(<<-EOF)
|
161
|
+
group :development do
|
162
|
+
gem "rake"
|
163
|
+
gem "sqlite3"
|
164
|
+
end
|
165
|
+
EOF
|
166
|
+
dependencies[0].groups.should == [:development]
|
167
|
+
dependencies[1].groups.should == [:development]
|
168
|
+
end
|
169
|
+
|
170
|
+
it "parses multiple gems in multiple groups" do
|
171
|
+
content(<<-EOF)
|
172
|
+
group :development, :test do
|
173
|
+
gem "rake"
|
174
|
+
gem "sqlite3"
|
175
|
+
end
|
176
|
+
EOF
|
177
|
+
dependencies[0].groups.should == [:development, :test]
|
178
|
+
dependencies[1].groups.should == [:development, :test]
|
179
|
+
end
|
180
|
+
|
181
|
+
it "ignores h4x" do
|
182
|
+
path = File.expand_path("../h4x.txt", __FILE__)
|
183
|
+
content(%(gem "h4x", :require => "\#{`touch #{path}`}"))
|
184
|
+
dependencies.size.should == 0
|
185
|
+
begin
|
186
|
+
File.should_not exist(path)
|
187
|
+
ensure
|
188
|
+
FileUtils.rm_f(path)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
it "ignores gems with a git option" do
|
193
|
+
content(%(gem "rails", :git => "https://github.com/rails/rails.git"))
|
194
|
+
dependencies.size.should == 1
|
195
|
+
end
|
196
|
+
|
197
|
+
it "ignores gems with a github option" do
|
198
|
+
content(%(gem "rails", :github => "rails/rails"))
|
199
|
+
dependencies.size.should == 1
|
200
|
+
end
|
201
|
+
|
202
|
+
it "ignores gems with a path option" do
|
203
|
+
content(%(gem "rails", :path => "vendor/rails"))
|
204
|
+
dependencies.size.should == 1
|
205
|
+
end
|
206
|
+
|
207
|
+
it "ignores gems in a git block" do
|
208
|
+
content(<<-EOF)
|
209
|
+
git "https://github.com/rails/rails.git" do
|
210
|
+
gem "rails"
|
211
|
+
end
|
212
|
+
EOF
|
213
|
+
dependencies.size.should == 1
|
214
|
+
end
|
215
|
+
|
216
|
+
it "ignores gems in a git block with parentheses" do
|
217
|
+
content(<<-EOF)
|
218
|
+
git("https://github.com/rails/rails.git") do
|
219
|
+
gem "rails"
|
220
|
+
end
|
221
|
+
EOF
|
222
|
+
dependencies.size.should == 1
|
223
|
+
end
|
224
|
+
|
225
|
+
it "ignores gems in a path block" do
|
226
|
+
content(<<-EOF)
|
227
|
+
path "vendor/rails" do
|
228
|
+
gem "rails"
|
229
|
+
end
|
230
|
+
EOF
|
231
|
+
dependencies.size.should == 1
|
232
|
+
end
|
233
|
+
|
234
|
+
it "ignores gems in a path block with parentheses" do
|
235
|
+
content(<<-EOF)
|
236
|
+
path("vendor/rails") do
|
237
|
+
gem "rails"
|
238
|
+
end
|
239
|
+
EOF
|
240
|
+
dependencies.size.should == 1
|
241
|
+
end
|
242
|
+
|
243
|
+
it "records dependency line numbers" do
|
244
|
+
content(<<-EOF)
|
245
|
+
gem "rake"
|
246
|
+
|
247
|
+
gem "rails"
|
248
|
+
EOF
|
249
|
+
dependencies[0].instance_variable_get(:@line).should == 1
|
250
|
+
dependencies[1].instance_variable_get(:@line).should == 3
|
251
|
+
end
|
252
|
+
|
253
|
+
it "maps groups to types" do
|
254
|
+
content(<<-EOF)
|
255
|
+
gem "rake"
|
256
|
+
gem "pg", :group => :production
|
257
|
+
gem "mysql2", :group => :staging
|
258
|
+
gem "sqlite3", :group => :development
|
259
|
+
EOF
|
260
|
+
dependencies[0].type.should == :runtime
|
261
|
+
dependencies[1].type.should == :runtime
|
262
|
+
dependencies[2].type.should == :development
|
263
|
+
dependencies[3].type.should == :development
|
264
|
+
reset
|
265
|
+
Gemnasium::Parser.runtime_groups << :staging
|
266
|
+
content(<<-EOF)
|
267
|
+
gem "rake"
|
268
|
+
gem "pg", :group => :production
|
269
|
+
gem "mysql2", :group => :staging
|
270
|
+
gem "sqlite3", :group => :development
|
271
|
+
EOF
|
272
|
+
dependencies[0].type.should == :runtime
|
273
|
+
dependencies[1].type.should == :runtime
|
274
|
+
dependencies[2].type.should == :runtime
|
275
|
+
dependencies[3].type.should == :development
|
276
|
+
end
|
277
|
+
|
278
|
+
it "parses parentheses" do
|
279
|
+
content(%(gem("rake", ">= 0.8.7")))
|
280
|
+
dependency.name.should == "rake"
|
281
|
+
dependency.requirement.as_list.should == [">= 0.8.7"]
|
282
|
+
end
|
283
|
+
|
284
|
+
it "parses gems followed by inline comments" do
|
285
|
+
content(%(gem "rake", ">= 0.8.7" # Comment))
|
286
|
+
dependency.name.should == "rake"
|
287
|
+
dependency.requirement.as_list.should == [">= 0.8.7"]
|
288
|
+
end
|
289
|
+
|
290
|
+
it "parses oddly quoted gems" do
|
291
|
+
content(%(gem %q<rake>))
|
292
|
+
dependency.name.should == "rake"
|
293
|
+
end
|
294
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Gemnasium::Parser::Gemspec do
|
4
|
+
def content(string)
|
5
|
+
@content ||= begin
|
6
|
+
indent = string.scan(/^[ \t]*(?=\S)/)
|
7
|
+
n = indent ? indent.size : 0
|
8
|
+
string.gsub(/^[ \t]{#{n}}/, "")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def gemspec
|
13
|
+
@gemspec ||= Gemnasium::Parser::Gemspec.new(@content)
|
14
|
+
end
|
15
|
+
|
16
|
+
def dependencies
|
17
|
+
@dependencies ||= gemspec.dependencies
|
18
|
+
end
|
19
|
+
|
20
|
+
def dependency
|
21
|
+
dependencies.size.should == 1
|
22
|
+
dependencies.first
|
23
|
+
end
|
24
|
+
|
25
|
+
def reset
|
26
|
+
@content = @gemspec = @dependencies = nil
|
27
|
+
end
|
28
|
+
|
29
|
+
it "parses double quotes" do
|
30
|
+
content(<<-EOF)
|
31
|
+
Gem::Specification.new do |gem|
|
32
|
+
gem.add_dependency "rake", ">= 0.8.7"
|
33
|
+
end
|
34
|
+
EOF
|
35
|
+
dependency.name.should == "rake"
|
36
|
+
dependency.requirement.as_list.should == [">= 0.8.7"]
|
37
|
+
end
|
38
|
+
|
39
|
+
it "parses single quotes" do
|
40
|
+
content(<<-EOF)
|
41
|
+
Gem::Specification.new do |gem|
|
42
|
+
gem.add_dependency 'rake', '>= 0.8.7'
|
43
|
+
end
|
44
|
+
EOF
|
45
|
+
dependency.name.should == "rake"
|
46
|
+
dependency.requirement.as_list.should == [">= 0.8.7"]
|
47
|
+
end
|
48
|
+
|
49
|
+
it "ignores mixed quotes" do
|
50
|
+
content(<<-EOF)
|
51
|
+
Gem::Specification.new do |gem|
|
52
|
+
gem.add_dependency "rake', ">= 0.8.7"
|
53
|
+
end
|
54
|
+
EOF
|
55
|
+
dependencies.size.should == 0
|
56
|
+
end
|
57
|
+
|
58
|
+
it "parses gems with a period in the name" do
|
59
|
+
content(<<-EOF)
|
60
|
+
Gem::Specification.new do |gem|
|
61
|
+
gem.add_dependency "pygment.rb", ">= 0.8.7"
|
62
|
+
end
|
63
|
+
EOF
|
64
|
+
dependency.name.should == "pygment.rb"
|
65
|
+
dependency.requirement.as_list.should == [">= 0.8.7"]
|
66
|
+
end
|
67
|
+
|
68
|
+
it "parses non-requirement gems" do
|
69
|
+
content(<<-EOF)
|
70
|
+
Gem::Specification.new do |gem|
|
71
|
+
gem.add_dependency "rake"
|
72
|
+
end
|
73
|
+
EOF
|
74
|
+
dependency.name.should == "rake"
|
75
|
+
dependency.requirement.as_list.should == [">= 0"]
|
76
|
+
end
|
77
|
+
|
78
|
+
it "parses multi-requirement gems" do
|
79
|
+
content(<<-EOF)
|
80
|
+
Gem::Specification.new do |gem|
|
81
|
+
gem.add_dependency "rake", ">= 0.8.7", "<= 0.9.2"
|
82
|
+
end
|
83
|
+
EOF
|
84
|
+
dependency.name.should == "rake"
|
85
|
+
dependency.requirement.as_list.should == ["<= 0.9.2", ">= 0.8.7"]
|
86
|
+
end
|
87
|
+
|
88
|
+
it "parses single-element array requirement gems" do
|
89
|
+
content(<<-EOF)
|
90
|
+
Gem::Specification.new do |gem|
|
91
|
+
gem.add_dependency "rake", [">= 0.8.7"]
|
92
|
+
end
|
93
|
+
EOF
|
94
|
+
dependency.name.should == "rake"
|
95
|
+
dependency.requirement.as_list.should == [">= 0.8.7"]
|
96
|
+
end
|
97
|
+
|
98
|
+
it "parses multi-element array requirement gems" do
|
99
|
+
content(<<-EOF)
|
100
|
+
Gem::Specification.new do |gem|
|
101
|
+
gem.add_dependency "rake", [">= 0.8.7", "<= 0.9.2"]
|
102
|
+
end
|
103
|
+
EOF
|
104
|
+
dependency.name.should == "rake"
|
105
|
+
dependency.requirement.as_list.should == ["<= 0.9.2", ">= 0.8.7"]
|
106
|
+
end
|
107
|
+
|
108
|
+
it "parses runtime gems" do
|
109
|
+
content(<<-EOF)
|
110
|
+
Gem::Specification.new do |gem|
|
111
|
+
gem.add_dependency "rake"
|
112
|
+
gem.add_runtime_dependency "rails"
|
113
|
+
end
|
114
|
+
EOF
|
115
|
+
dependencies[0].type.should == :runtime
|
116
|
+
dependencies[1].type.should == :runtime
|
117
|
+
end
|
118
|
+
|
119
|
+
it "parses dependency gems" do
|
120
|
+
content(<<-EOF)
|
121
|
+
Gem::Specification.new do |gem|
|
122
|
+
gem.add_development_dependency "rake"
|
123
|
+
end
|
124
|
+
EOF
|
125
|
+
dependency.type.should == :development
|
126
|
+
end
|
127
|
+
|
128
|
+
it "records dependency line numbers" do
|
129
|
+
content(<<-EOF)
|
130
|
+
Gem::Specification.new do |gem|
|
131
|
+
gem.add_dependency "rake"
|
132
|
+
|
133
|
+
gem.add_dependency "rails"
|
134
|
+
end
|
135
|
+
EOF
|
136
|
+
dependencies[0].instance_variable_get(:@line).should == 2
|
137
|
+
dependencies[1].instance_variable_get(:@line).should == 4
|
138
|
+
end
|
139
|
+
|
140
|
+
it "parses parentheses" do
|
141
|
+
content(<<-EOF)
|
142
|
+
Gem::Specification.new do |gem|
|
143
|
+
gem.add_dependency("rake", ">= 0.8.7")
|
144
|
+
end
|
145
|
+
EOF
|
146
|
+
dependency.name.should == "rake"
|
147
|
+
dependency.requirement.as_list.should == [">= 0.8.7"]
|
148
|
+
end
|
149
|
+
|
150
|
+
it "parses gems followed by inline comments" do
|
151
|
+
content(<<-EOF)
|
152
|
+
Gem::Specification.new do |gem|
|
153
|
+
gem.add_dependency "rake", ">= 0.8.7" # Comment
|
154
|
+
end
|
155
|
+
EOF
|
156
|
+
dependency.name.should == "rake"
|
157
|
+
dependency.requirement.as_list.should == [">= 0.8.7"]
|
158
|
+
end
|
159
|
+
end
|