bibliothecary 4.0.4 → 5.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 +4 -4
- data/.codeclimate.yml +25 -0
- data/.github/CONTRIBUTING.md +165 -0
- data/.github/ISSUE_TEMPLATE.md +18 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +10 -0
- data/.rubocop.yml +1156 -0
- data/.travis.yml +4 -1
- data/Gemfile +5 -0
- data/README.md +7 -1
- data/bibliothecary.gemspec +1 -1
- data/lib/bibliothecary.rb +16 -2
- data/lib/bibliothecary/analyser.rb +28 -4
- data/lib/bibliothecary/parsers/bower.rb +7 -10
- data/lib/bibliothecary/parsers/cargo.rb +9 -31
- data/lib/bibliothecary/parsers/carthage.rb +13 -34
- data/lib/bibliothecary/parsers/clojars.rb +4 -7
- data/lib/bibliothecary/parsers/cocoapods.rb +19 -30
- data/lib/bibliothecary/parsers/cpan.rb +10 -15
- data/lib/bibliothecary/parsers/cran.rb +7 -10
- data/lib/bibliothecary/parsers/dub.rb +7 -12
- data/lib/bibliothecary/parsers/elm.rb +7 -47
- data/lib/bibliothecary/parsers/go.rb +47 -52
- data/lib/bibliothecary/parsers/hex.rb +5 -14
- data/lib/bibliothecary/parsers/julia.rb +4 -7
- data/lib/bibliothecary/parsers/maven.rb +12 -18
- data/lib/bibliothecary/parsers/meteor.rb +6 -9
- data/lib/bibliothecary/parsers/npm.rb +15 -14
- data/lib/bibliothecary/parsers/nuget.rb +18 -28
- data/lib/bibliothecary/parsers/packagist.rb +9 -14
- data/lib/bibliothecary/parsers/pub.rb +9 -14
- data/lib/bibliothecary/parsers/pypi.rb +8 -10
- data/lib/bibliothecary/parsers/rubygems.rb +16 -23
- data/lib/bibliothecary/parsers/shard.rb +9 -14
- data/lib/bibliothecary/parsers/swift_pm.rb +4 -7
- data/lib/bibliothecary/version.rb +1 -1
- data/lib/sdl_parser.rb +0 -4
- metadata +9 -5
- data/CONTRIBUTING.md +0 -10
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
# Bibliothecary
|
2
2
|
|
3
|
-
Dependency manifest parsing
|
3
|
+
Dependency manifest parsing library for https://libraries.io
|
4
|
+
|
5
|
+
[](https://travis-ci.org/librariesio/bibliothecary)
|
6
|
+
[](https://codeclimate.com/github/librariesio/bibliothecary)
|
7
|
+
[](https://codeclimate.com/github/librariesio/bibliothecary)
|
8
|
+
[](https://codeclimate.com/github/librariesio/bibliothecary/issues)
|
9
|
+
[](https://github.com/librariesio/bibliothecary/blob/master/LICENSE.txt)
|
4
10
|
|
5
11
|
## Installation
|
6
12
|
|
data/bibliothecary.gemspec
CHANGED
@@ -26,6 +26,6 @@ Gem::Specification.new do |spec|
|
|
26
26
|
spec.add_dependency "sdl4r"
|
27
27
|
|
28
28
|
spec.add_development_dependency "bundler", "~> 1.11"
|
29
|
-
spec.add_development_dependency "rake", "~>
|
29
|
+
spec.add_development_dependency "rake", "~> 12.0"
|
30
30
|
spec.add_development_dependency "rspec", "~> 3.0"
|
31
31
|
end
|
data/lib/bibliothecary.rb
CHANGED
@@ -8,15 +8,29 @@ end
|
|
8
8
|
module Bibliothecary
|
9
9
|
def self.analyse(path)
|
10
10
|
cmd = `find #{path} -type f | grep -vE "#{ignored_files}"`
|
11
|
-
file_list = cmd.split("\n")
|
11
|
+
file_list = cmd.split("\n").sort
|
12
12
|
package_managers.map{|pm| pm.analyse(path, file_list) }.flatten.compact
|
13
13
|
end
|
14
14
|
|
15
|
+
def self.analyse_file(file_path, contents)
|
16
|
+
package_managers.map do |pm|
|
17
|
+
pm.analyse_contents(file_path, contents)
|
18
|
+
end.flatten.uniq.compact
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.identify_manifests(file_list)
|
22
|
+
package_managers.map do |pm|
|
23
|
+
file_list.select do |file_path|
|
24
|
+
pm.match?(file_path)
|
25
|
+
end
|
26
|
+
end.flatten.uniq.compact
|
27
|
+
end
|
28
|
+
|
15
29
|
def self.package_managers
|
16
30
|
Bibliothecary::Parsers.constants.map{|c| Bibliothecary::Parsers.const_get(c) }.sort_by{|c| c.to_s.downcase }
|
17
31
|
end
|
18
32
|
|
19
33
|
def self.ignored_files
|
20
|
-
['.git', 'node_modules', 'bower_components'].join('|')
|
34
|
+
['.git', 'node_modules', 'bower_components', 'spec/fixtures', 'vendor/bundle'].join('|')
|
21
35
|
end
|
22
36
|
end
|
@@ -4,6 +4,19 @@ module Bibliothecary
|
|
4
4
|
base.extend(ClassMethods)
|
5
5
|
end
|
6
6
|
module ClassMethods
|
7
|
+
def parse_file(filename, contents)
|
8
|
+
mapping.each do |regex, method_name|
|
9
|
+
if filename.match(regex)
|
10
|
+
return send(method_name, contents)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
return []
|
14
|
+
end
|
15
|
+
|
16
|
+
def match?(filename)
|
17
|
+
mapping.keys.any?{|regex| filename.match(regex) }
|
18
|
+
end
|
19
|
+
|
7
20
|
def platform_name
|
8
21
|
self.name.to_s.split('::').last.downcase
|
9
22
|
end
|
@@ -11,17 +24,18 @@ module Bibliothecary
|
|
11
24
|
def analyse(folder_path, file_list)
|
12
25
|
file_list.map do |path|
|
13
26
|
filename = path.gsub(folder_path, '').gsub(/^\//, '')
|
14
|
-
|
27
|
+
contents = File.open(path).read
|
28
|
+
analyse_contents(filename, contents)
|
15
29
|
end.compact
|
16
30
|
end
|
17
31
|
|
18
|
-
def
|
32
|
+
def analyse_contents(filename, contents)
|
19
33
|
begin
|
20
|
-
dependencies =
|
34
|
+
dependencies = parse_file(filename, contents)
|
21
35
|
if dependencies.any?
|
22
36
|
{
|
23
37
|
platform: platform_name,
|
24
|
-
path:
|
38
|
+
path: filename,
|
25
39
|
dependencies: dependencies
|
26
40
|
}
|
27
41
|
else
|
@@ -31,6 +45,16 @@ module Bibliothecary
|
|
31
45
|
nil
|
32
46
|
end
|
33
47
|
end
|
48
|
+
|
49
|
+
def parse_ruby_manifest(manifest)
|
50
|
+
manifest.dependencies.inject([]) do |deps, dep|
|
51
|
+
deps.push({
|
52
|
+
name: dep.name,
|
53
|
+
requirement: dep.requirement.to_s,
|
54
|
+
type: dep.type
|
55
|
+
})
|
56
|
+
end.uniq
|
57
|
+
end
|
34
58
|
end
|
35
59
|
end
|
36
60
|
end
|
@@ -5,19 +5,16 @@ module Bibliothecary
|
|
5
5
|
class Bower
|
6
6
|
include Bibliothecary::Analyser
|
7
7
|
|
8
|
-
def self.
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
parse_manifest(json)
|
13
|
-
else
|
14
|
-
[]
|
15
|
-
end
|
8
|
+
def self.mapping
|
9
|
+
{
|
10
|
+
/^bower\.json$/ => :parse_manifest
|
11
|
+
}
|
16
12
|
end
|
17
13
|
|
18
14
|
def self.parse_manifest(manifest)
|
19
|
-
|
20
|
-
map_dependencies(
|
15
|
+
json = JSON.parse(manifest)
|
16
|
+
map_dependencies(json, 'dependencies', 'runtime') +
|
17
|
+
map_dependencies(json, 'devDependencies', 'development')
|
21
18
|
end
|
22
19
|
|
23
20
|
def self.map_dependencies(hash, key, type)
|
@@ -5,21 +5,15 @@ module Bibliothecary
|
|
5
5
|
class Cargo
|
6
6
|
include Bibliothecary::Analyser
|
7
7
|
|
8
|
-
def self.
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
elsif filename.match(/Cargo\.lock$/)
|
14
|
-
file_contents = File.open(path).read
|
15
|
-
toml = TOML.parse(file_contents)
|
16
|
-
parse_lockfile(toml)
|
17
|
-
else
|
18
|
-
[]
|
19
|
-
end
|
8
|
+
def self.mapping
|
9
|
+
{
|
10
|
+
/Cargo\.toml$/ => :parse_manifest,
|
11
|
+
/Cargo\.lock$/ => :parse_lockfile
|
12
|
+
}
|
20
13
|
end
|
21
14
|
|
22
|
-
def self.parse_manifest(
|
15
|
+
def self.parse_manifest(file_contents)
|
16
|
+
manifest = TOML.parse(file_contents)
|
23
17
|
manifest.fetch('dependencies', []).map do |name, requirement|
|
24
18
|
if requirement.respond_to?(:fetch)
|
25
19
|
requirement = requirement['version'] or next
|
@@ -33,24 +27,8 @@ module Bibliothecary
|
|
33
27
|
.compact
|
34
28
|
end
|
35
29
|
|
36
|
-
def self.
|
37
|
-
|
38
|
-
return unless paths.any?
|
39
|
-
|
40
|
-
paths.map do |path|
|
41
|
-
manifest = TOML.load_file(path)
|
42
|
-
|
43
|
-
{
|
44
|
-
platform: PLATFORM_NAME,
|
45
|
-
path: path,
|
46
|
-
dependencies: parse_lockfile(manifest)
|
47
|
-
}
|
48
|
-
end
|
49
|
-
rescue
|
50
|
-
[]
|
51
|
-
end
|
52
|
-
|
53
|
-
def self.parse_lockfile(manifest)
|
30
|
+
def self.parse_lockfile(file_contents)
|
31
|
+
manifest = TOML.parse(file_contents)
|
54
32
|
manifest.fetch('package',[]).map do |dependency|
|
55
33
|
next if not dependency['source'] or not dependency['source'].start_with?('registry+')
|
56
34
|
{
|
@@ -3,49 +3,28 @@ module Bibliothecary
|
|
3
3
|
class Carthage
|
4
4
|
include Bibliothecary::Analyser
|
5
5
|
|
6
|
-
def self.
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
parse_cartfile_private(file_contents)
|
13
|
-
elsif filename.match(/^Cartfile\.resolved$/)
|
14
|
-
file_contents = File.open(path).read
|
15
|
-
parse_cartfile_resolved(file_contents)
|
16
|
-
else
|
17
|
-
[]
|
18
|
-
end
|
6
|
+
def self.mapping
|
7
|
+
{
|
8
|
+
/^Cartfile$/ => :parse_cartfile,
|
9
|
+
/^Cartfile\.private$/ => :parse_cartfile_private,
|
10
|
+
/^Cartfile\.resolved$/ => :parse_cartfile_resolved
|
11
|
+
}
|
19
12
|
end
|
20
13
|
|
21
14
|
def self.parse_cartfile(manifest)
|
22
|
-
|
23
|
-
json = JSON.parse(response.body)
|
24
|
-
|
25
|
-
json.map do |dependency|
|
26
|
-
{
|
27
|
-
name: dependency['name'],
|
28
|
-
version: dependency['version'],
|
29
|
-
type: dependency["type"]
|
30
|
-
}
|
31
|
-
end
|
15
|
+
map_dependencies(manifest, 'cartfile')
|
32
16
|
end
|
33
17
|
|
34
18
|
def self.parse_cartfile_private(manifest)
|
35
|
-
|
36
|
-
json = JSON.parse(response.body)
|
37
|
-
|
38
|
-
json.map do |dependency|
|
39
|
-
{
|
40
|
-
name: dependency['name'],
|
41
|
-
version: dependency['version'],
|
42
|
-
type: dependency["type"]
|
43
|
-
}
|
44
|
-
end
|
19
|
+
map_dependencies(manifest, 'cartfile.private')
|
45
20
|
end
|
46
21
|
|
47
22
|
def self.parse_cartfile_resolved(manifest)
|
48
|
-
|
23
|
+
map_dependencies(manifest, 'cartfile.resolved')
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.map_dependencies(manifest, path)
|
27
|
+
response = Typhoeus.post("https://carthageparser.herokuapp.com/#{path}", params: {body: manifest})
|
49
28
|
json = JSON.parse(response.body)
|
50
29
|
|
51
30
|
json.map do |dependency|
|
@@ -6,13 +6,10 @@ module Bibliothecary
|
|
6
6
|
class Clojars
|
7
7
|
include Bibliothecary::Analyser
|
8
8
|
|
9
|
-
def self.
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
else
|
14
|
-
[]
|
15
|
-
end
|
9
|
+
def self.mapping
|
10
|
+
{
|
11
|
+
/^project\.clj$/ => :parse_manifest
|
12
|
+
}
|
16
13
|
end
|
17
14
|
|
18
15
|
def self.parse_manifest(manifest)
|
@@ -9,29 +9,17 @@ module Bibliothecary
|
|
9
9
|
NAME_VERSION = '(?! )(.*?)(?: \(([^-]*)(?:-(.*))?\))?'.freeze
|
10
10
|
NAME_VERSION_4 = /^ {4}#{NAME_VERSION}$/
|
11
11
|
|
12
|
-
def self.
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
manifest = Gemnasium::Parser.send(:podspec, file_contents)
|
20
|
-
parse_manifest(manifest)
|
21
|
-
elsif filename.match(/^Podfile\.lock$/)
|
22
|
-
file_contents = File.open(path).read
|
23
|
-
manifest = YAML.load file_contents
|
24
|
-
parse_podfile_lock(manifest)
|
25
|
-
elsif filename.match(/^[A-Za-z0-9_-]+\.podspec.json$/)
|
26
|
-
file_contents = File.open(path).read
|
27
|
-
json = JSON.parse(file_contents)
|
28
|
-
parse_json_manifest(json)
|
29
|
-
else
|
30
|
-
[]
|
31
|
-
end
|
12
|
+
def self.mapping
|
13
|
+
{
|
14
|
+
/^Podfile$/ => :parse_podfile,
|
15
|
+
/^[A-Za-z0-9_-]+\.podspec$/ => :parse_podspec,
|
16
|
+
/^Podfile\.lock$/ => :parse_podfile_lock,
|
17
|
+
/^[A-Za-z0-9_-]+\.podspec.json$/ => :parse_json_manifest
|
18
|
+
}
|
32
19
|
end
|
33
20
|
|
34
|
-
def self.parse_podfile_lock(
|
21
|
+
def self.parse_podfile_lock(file_contents)
|
22
|
+
manifest = YAML.load file_contents
|
35
23
|
manifest['PODS'].map do |row|
|
36
24
|
pod = row.is_a?(String) ? row : row.keys.first
|
37
25
|
match = pod.match(/(.+?)\s\((.+?)\)/i)
|
@@ -43,17 +31,18 @@ module Bibliothecary
|
|
43
31
|
end.compact
|
44
32
|
end
|
45
33
|
|
46
|
-
def self.
|
47
|
-
manifest.
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
34
|
+
def self.parse_podspec(file_contents)
|
35
|
+
manifest = Gemnasium::Parser.send(:podspec, file_contents)
|
36
|
+
parse_ruby_manifest(manifest)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.parse_podfile(file_contents)
|
40
|
+
manifest = Gemnasium::Parser.send(:podfile, file_contents)
|
41
|
+
parse_ruby_manifest(manifest)
|
54
42
|
end
|
55
43
|
|
56
|
-
def self.parse_json_manifest(
|
44
|
+
def self.parse_json_manifest(file_contents)
|
45
|
+
manifest = JSON.parse(file_contents)
|
57
46
|
manifest['dependencies'].inject([]) do |deps, dep|
|
58
47
|
deps.push({
|
59
48
|
name: dep[0],
|
@@ -6,27 +6,22 @@ module Bibliothecary
|
|
6
6
|
class CPAN
|
7
7
|
include Bibliothecary::Analyser
|
8
8
|
|
9
|
-
def self.
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
elsif filename.match(/^META\.yml$/i)
|
15
|
-
file_contents = File.open(path).read
|
16
|
-
yaml = YAML.load file_contents
|
17
|
-
parse_yaml_manifest(yaml)
|
18
|
-
else
|
19
|
-
[]
|
20
|
-
end
|
9
|
+
def self.mapping
|
10
|
+
{
|
11
|
+
/^META\.json$/i => :parse_json_manifest,
|
12
|
+
/^META\.yml$/i => :parse_yaml_manifest
|
13
|
+
}
|
21
14
|
end
|
22
15
|
|
23
|
-
def self.parse_json_manifest(
|
24
|
-
manifest
|
16
|
+
def self.parse_json_manifest(file_contents)
|
17
|
+
manifest = JSON.parse file_contents
|
18
|
+
manifest['prereqs'].map do |_group, deps|
|
25
19
|
map_dependencies(deps, 'requires', 'runtime')
|
26
20
|
end.flatten
|
27
21
|
end
|
28
22
|
|
29
|
-
def self.parse_yaml_manifest(
|
23
|
+
def self.parse_yaml_manifest(file_contents)
|
24
|
+
manifest = YAML.load file_contents
|
30
25
|
map_dependencies(manifest, 'requires', 'runtime')
|
31
26
|
end
|
32
27
|
|
@@ -7,17 +7,14 @@ module Bibliothecary
|
|
7
7
|
|
8
8
|
REQUIRE_REGEXP = /([a-zA-Z0-9\-_\.]+)\s?\(?([><=\s\d\.,]+)?\)?/
|
9
9
|
|
10
|
-
def self.
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
parse_description(control)
|
15
|
-
else
|
16
|
-
[]
|
17
|
-
end
|
10
|
+
def self.mapping
|
11
|
+
{
|
12
|
+
/^DESCRIPTION$/i => :parse_description
|
13
|
+
}
|
18
14
|
end
|
19
15
|
|
20
|
-
def self.parse_description(
|
16
|
+
def self.parse_description(file_contents)
|
17
|
+
manifest = DebControl::ControlFileBase.parse(file_contents)
|
21
18
|
parse_section(manifest, 'Depends') +
|
22
19
|
parse_section(manifest, 'Imports') +
|
23
20
|
parse_section(manifest, 'Suggests') +
|
@@ -26,7 +23,7 @@ module Bibliothecary
|
|
26
23
|
|
27
24
|
def self.parse_section(manifest, name)
|
28
25
|
return [] unless manifest.first[name]
|
29
|
-
deps = manifest.first[name].
|
26
|
+
deps = manifest.first[name].delete("\n").split(',').map(&:strip)
|
30
27
|
deps.map do |dependency|
|
31
28
|
dep = dependency.match(REQUIRE_REGEXP)
|
32
29
|
{
|
@@ -6,20 +6,15 @@ module Bibliothecary
|
|
6
6
|
class Dub
|
7
7
|
include Bibliothecary::Analyser
|
8
8
|
|
9
|
-
def self.
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
elsif filename.match(/^dub\.sdl$/)
|
15
|
-
file_contents = File.open(path).read
|
16
|
-
parse_sdl_manifest(file_contents)
|
17
|
-
else
|
18
|
-
[]
|
19
|
-
end
|
9
|
+
def self.mapping
|
10
|
+
{
|
11
|
+
/^dub\.json$/ => :parse_manifest,
|
12
|
+
/^dub\.sdl$/ => :parse_sdl_manifest
|
13
|
+
}
|
20
14
|
end
|
21
15
|
|
22
|
-
def self.parse_manifest(
|
16
|
+
def self.parse_manifest(file_contents)
|
17
|
+
manifest = JSON.parse(file_contents)
|
23
18
|
map_dependencies(manifest, 'dependencies', 'runtime')
|
24
19
|
end
|
25
20
|
|