bibliothecary 11.0.1 → 12.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +2 -1
  3. data/.rubocop.yml +10 -2
  4. data/.ruby-version +1 -1
  5. data/CHANGELOG.md +24 -0
  6. data/Gemfile +16 -1
  7. data/Rakefile +2 -0
  8. data/bibliothecary.gemspec +11 -14
  9. data/bin/bibliothecary +2 -1
  10. data/bin/console +1 -0
  11. data/lib/bibliothecary/analyser/analysis.rb +13 -8
  12. data/lib/bibliothecary/analyser/determinations.rb +2 -0
  13. data/lib/bibliothecary/analyser/matchers.rb +17 -17
  14. data/lib/bibliothecary/analyser.rb +11 -8
  15. data/lib/bibliothecary/cli.rb +3 -1
  16. data/lib/bibliothecary/configuration.rb +3 -11
  17. data/lib/bibliothecary/dependency.rb +17 -15
  18. data/lib/bibliothecary/exceptions.rb +6 -2
  19. data/lib/bibliothecary/file_info.rb +9 -11
  20. data/lib/bibliothecary/multi_parsers/bundler_like_manifest.rb +13 -10
  21. data/lib/bibliothecary/multi_parsers/cyclonedx.rb +10 -8
  22. data/lib/bibliothecary/multi_parsers/dependencies_csv.rb +11 -4
  23. data/lib/bibliothecary/multi_parsers/json_runtime.rb +5 -2
  24. data/lib/bibliothecary/multi_parsers/spdx.rb +24 -19
  25. data/lib/bibliothecary/parsers/bower.rb +5 -3
  26. data/lib/bibliothecary/parsers/cargo.rb +10 -4
  27. data/lib/bibliothecary/parsers/cocoapods.rb +15 -11
  28. data/lib/bibliothecary/parsers/conda.rb +56 -33
  29. data/lib/bibliothecary/parsers/cpan.rb +6 -4
  30. data/lib/bibliothecary/parsers/cran.rb +10 -6
  31. data/lib/bibliothecary/parsers/dub.rb +4 -2
  32. data/lib/bibliothecary/parsers/elm.rb +4 -1
  33. data/lib/bibliothecary/parsers/go.rb +51 -43
  34. data/lib/bibliothecary/parsers/haxelib.rb +2 -1
  35. data/lib/bibliothecary/parsers/julia.rb +5 -1
  36. data/lib/bibliothecary/parsers/maven.rb +93 -77
  37. data/lib/bibliothecary/parsers/meteor.rb +2 -0
  38. data/lib/bibliothecary/parsers/npm.rb +97 -34
  39. data/lib/bibliothecary/parsers/nuget.rb +37 -28
  40. data/lib/bibliothecary/parsers/packagist.rb +21 -11
  41. data/lib/bibliothecary/parsers/pub.rb +4 -2
  42. data/lib/bibliothecary/parsers/pypi.rb +48 -37
  43. data/lib/bibliothecary/parsers/rubygems.rb +16 -12
  44. data/lib/bibliothecary/parsers/shard.rb +10 -7
  45. data/lib/bibliothecary/purl_util.rb +2 -4
  46. data/lib/bibliothecary/related_files_info.rb +7 -8
  47. data/lib/bibliothecary/runner/multi_manifest_filter.rb +5 -4
  48. data/lib/bibliothecary/runner.rb +12 -10
  49. data/lib/bibliothecary/version.rb +3 -1
  50. data/lib/bibliothecary.rb +7 -4
  51. data/lib/sdl_parser.rb +11 -6
  52. metadata +18 -120
  53. data/lib/bibliothecary/parsers/carthage.rb +0 -52
  54. data/lib/bibliothecary/parsers/clojars.rb +0 -38
  55. data/lib/bibliothecary/parsers/hackage.rb +0 -53
  56. data/lib/bibliothecary/parsers/hex.rb +0 -54
  57. data/lib/bibliothecary/parsers/swift_pm.rb +0 -35
@@ -1,13 +1,16 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Bibliothecary
2
4
  module MultiParsers
3
5
  # Provide JSON Runtime Manifest parsing
4
6
  module JSONRuntime
5
- def parse_json_runtime_manifest(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
6
- JSON.parse(file_contents).fetch("dependencies",[]).map do |name, requirement|
7
+ def parse_json_runtime_manifest(file_contents, options: {})
8
+ JSON.parse(file_contents).fetch("dependencies", []).map do |name, requirement|
7
9
  Dependency.new(
8
10
  name: name,
9
11
  requirement: requirement,
10
12
  type: "runtime",
13
+ source: options.fetch(:filename, nil)
11
14
  )
12
15
  end
13
16
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # packageurl-ruby uses pattern-matching (https://docs.ruby-lang.org/en/2.7.0/NEWS.html#label-Pattern+matching)
2
4
  # which warns a whole bunch in Ruby 2.7 as being an experimental feature, but has
3
5
  # been accepted in Ruby 3.0 (https://rubyreferences.github.io/rubychanges/3.0.html#pattern-matching).
@@ -43,7 +45,7 @@ module Bibliothecary
43
45
 
44
46
  def parse_spdx_tag_value(file_contents, options: {})
45
47
  entries = try_cache(options, options[:filename]) do
46
- parse_spdx_tag_value_file_contents(file_contents)
48
+ parse_spdx_tag_value_file_contents(file_contents, options.fetch(:filename, nil))
47
49
  end
48
50
 
49
51
  raise NoEntries if entries.empty?
@@ -51,7 +53,7 @@ module Bibliothecary
51
53
  entries[platform_name.to_sym]
52
54
  end
53
55
 
54
- def parse_spdx_tag_value_file_contents(file_contents)
56
+ def parse_spdx_tag_value_file_contents(file_contents, source = nil)
55
57
  entries = {}
56
58
  spdx_name = spdx_version = platform = purl_name = purl_version = nil
57
59
 
@@ -65,13 +67,14 @@ module Bibliothecary
65
67
  # Per the spec:
66
68
  # > A new package Information section is denoted by the package name (7.1) field.
67
69
  add_entry(entries: entries, platform: platform, purl_name: purl_name,
68
- spdx_name: spdx_name, purl_version: purl_version, spdx_version: spdx_version)
70
+ spdx_name: spdx_name, purl_version: purl_version, spdx_version: spdx_version,
71
+ source: source)
69
72
 
70
73
  # reset for this new package
71
74
  spdx_name = spdx_version = platform = purl_name = purl_version = nil
72
75
 
73
76
  # capture the new package's name
74
- spdx_package_name = match[1]
77
+ spdx_name = match[1]
75
78
  elsif (match = stripped_line.match(PACKAGE_VERSION_REGEXP))
76
79
  spdx_version = match[1]
77
80
  elsif (match = stripped_line.match(PURL_REGEXP))
@@ -83,7 +86,8 @@ module Bibliothecary
83
86
  end
84
87
 
85
88
  add_entry(entries: entries, platform: platform, purl_name: purl_name,
86
- spdx_name: spdx_name, purl_version: purl_version, spdx_version: spdx_version)
89
+ spdx_name: spdx_name, purl_version: purl_version, spdx_version: spdx_version,
90
+ source: source)
87
91
 
88
92
  entries
89
93
  end
@@ -95,7 +99,7 @@ module Bibliothecary
95
99
 
96
100
  def parse_spdx_json(file_contents, options: {})
97
101
  entries = try_cache(options, options[:filename]) do
98
- parse_spdx_json_file_contents(file_contents)
102
+ parse_spdx_json_file_contents(file_contents, options.fetch(:filename, nil))
99
103
  end
100
104
 
101
105
  raise NoEntries if entries.empty?
@@ -103,7 +107,7 @@ module Bibliothecary
103
107
  entries[platform_name.to_sym]
104
108
  end
105
109
 
106
- def parse_spdx_json_file_contents(file_contents)
110
+ def parse_spdx_json_file_contents(file_contents, source = nil)
107
111
  entries = {}
108
112
  manifest = JSON.parse(file_contents)
109
113
 
@@ -111,33 +115,34 @@ module Bibliothecary
111
115
  spdx_name = package["name"]
112
116
  spdx_version = package["versionInfo"]
113
117
 
114
- first_purl_string = package.dig("externalRefs")&.find { |ref| ref["referenceType"] == "purl" }&.dig("referenceLocator")
118
+ first_purl_string = package["externalRefs"]&.find { |ref| ref["referenceType"] == "purl" }&.dig("referenceLocator")
115
119
  purl = first_purl_string && PackageURL.parse(first_purl_string)
116
120
  platform = PurlUtil::PURL_TYPE_MAPPING[purl&.type]
117
121
  purl_name = PurlUtil.full_name(purl)
118
122
  purl_version = purl&.version
119
123
 
120
124
  add_entry(entries: entries, platform: platform, purl_name: purl_name,
121
- spdx_name: spdx_name, purl_version: purl_version, spdx_version: spdx_version)
125
+ spdx_name: spdx_name, purl_version: purl_version, spdx_version: spdx_version,
126
+ source: source)
122
127
  end
123
128
 
124
129
  entries
125
130
  end
126
131
 
127
- def add_entry(entries:, platform:, purl_name:, spdx_name:, purl_version:, spdx_version:)
132
+ def add_entry(entries:, platform:, purl_name:, spdx_name:, purl_version:, spdx_version:, source: nil)
128
133
  package_name = purl_name || spdx_name
129
134
  package_version = purl_version || spdx_version
130
135
 
131
- if platform && package_name && package_version
132
- entries[platform.to_sym] ||= []
133
- entries[platform.to_sym] << Dependency.new(
134
- name: package_name,
135
- requirement: package_version,
136
- type: "lockfile"
137
- )
138
- end
139
- end
136
+ return unless platform && package_name && package_version
140
137
 
138
+ entries[platform.to_sym] ||= []
139
+ entries[platform.to_sym] << Dependency.new(
140
+ name: package_name,
141
+ requirement: package_version,
142
+ type: "lockfile",
143
+ source: source
144
+ )
145
+ end
141
146
  end
142
147
  end
143
148
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "json"
2
4
 
3
5
  module Bibliothecary
@@ -16,10 +18,10 @@ module Bibliothecary
16
18
 
17
19
  add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
18
20
 
19
- def self.parse_manifest(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
21
+ def self.parse_manifest(file_contents, options: {})
20
22
  json = JSON.parse(file_contents)
21
- map_dependencies(json, "dependencies", "runtime") +
22
- map_dependencies(json, "devDependencies", "development")
23
+ map_dependencies(json, "dependencies", "runtime", options.fetch(:filename, nil)) +
24
+ map_dependencies(json, "devDependencies", "development", options.fetch(:filename, nil))
23
25
  end
24
26
  end
25
27
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Bibliothecary
2
4
  module Parsers
3
5
  class Cargo
@@ -20,7 +22,7 @@ module Bibliothecary
20
22
  add_multi_parser(Bibliothecary::MultiParsers::Spdx)
21
23
  add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
22
24
 
23
- def self.parse_manifest(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
25
+ def self.parse_manifest(file_contents, options: {})
24
26
  manifest = Tomlrb.parse(file_contents)
25
27
 
26
28
  parsed_dependencies = []
@@ -30,10 +32,12 @@ module Bibliothecary
30
32
  if requirement.respond_to?(:fetch)
31
33
  requirement = requirement["version"] or next
32
34
  end
35
+
33
36
  Dependency.new(
34
37
  name: name,
35
38
  requirement: requirement,
36
39
  type: index.zero? ? "runtime" : "development",
40
+ source: options.fetch(:filename, nil)
37
41
  )
38
42
  end
39
43
  end
@@ -41,14 +45,16 @@ module Bibliothecary
41
45
  parsed_dependencies.flatten.compact
42
46
  end
43
47
 
44
- def self.parse_lockfile(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
48
+ def self.parse_lockfile(file_contents, options: {})
45
49
  manifest = Tomlrb.parse(file_contents)
46
- manifest.fetch("package",[]).map do |dependency|
47
- next if not dependency["source"] or not dependency["source"].start_with?("registry+")
50
+ manifest.fetch("package", []).map do |dependency|
51
+ next if !(dependency["source"]) || !dependency["source"].start_with?("registry+")
52
+
48
53
  Dependency.new(
49
54
  name: dependency["name"],
50
55
  requirement: dependency["version"],
51
56
  type: "runtime",
57
+ source: options.fetch(:filename, nil)
52
58
  )
53
59
  end
54
60
  .compact
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "gemnasium/parser"
2
4
  require "yaml"
3
5
 
@@ -7,7 +9,7 @@ module Bibliothecary
7
9
  include Bibliothecary::Analyser
8
10
  extend Bibliothecary::MultiParsers::BundlerLikeManifest
9
11
 
10
- NAME_VERSION = '(?! )(.*?)(?: \(([^-]*)(?:-(.*))?\))?'.freeze
12
+ NAME_VERSION = '(?! )(.*?)(?: \(([^-]*)(?:-(.*))?\))?'
11
13
  NAME_VERSION_4 = /^ {4}#{NAME_VERSION}$/
12
14
 
13
15
  def self.mapping
@@ -35,7 +37,7 @@ module Bibliothecary
35
37
 
36
38
  add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
37
39
 
38
- def self.parse_podfile_lock(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
40
+ def self.parse_podfile_lock(file_contents, options: {})
39
41
  manifest = YAML.load file_contents
40
42
  manifest["PODS"].map do |row|
41
43
  pod = row.is_a?(String) ? row : row.keys.first
@@ -44,28 +46,30 @@ module Bibliothecary
44
46
  name: match[1].split("/").first,
45
47
  requirement: match[2],
46
48
  type: "runtime",
49
+ source: options.fetch(:filename, nil)
47
50
  )
48
51
  end.compact
49
52
  end
50
53
 
51
- def self.parse_podspec(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
54
+ def self.parse_podspec(file_contents, options: {})
52
55
  manifest = Gemnasium::Parser.send(:podspec, file_contents)
53
- parse_ruby_manifest(manifest)
56
+ parse_ruby_manifest(manifest, options.fetch(:filename, nil))
54
57
  end
55
58
 
56
- def self.parse_podfile(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
59
+ def self.parse_podfile(file_contents, options: {})
57
60
  manifest = Gemnasium::Parser.send(:podfile, file_contents)
58
- parse_ruby_manifest(manifest)
61
+ parse_ruby_manifest(manifest, options.fetch(:filename, nil))
59
62
  end
60
63
 
61
- def self.parse_json_manifest(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
64
+ def self.parse_json_manifest(file_contents, options: {})
62
65
  manifest = JSON.parse(file_contents)
63
66
  manifest["dependencies"].inject([]) do |deps, dep|
64
67
  deps.push(Dependency.new(
65
- name: dep[0],
66
- requirement: dep[1],
67
- type: "runtime",
68
- ))
68
+ name: dep[0],
69
+ requirement: dep[1],
70
+ type: "runtime",
71
+ source: options.fetch(:filename, nil)
72
+ ))
69
73
  end.uniq
70
74
  end
71
75
  end
@@ -1,4 +1,6 @@
1
- require "json"
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
2
4
 
3
5
  module Bibliothecary
4
6
  module Parsers
@@ -15,14 +17,6 @@ module Bibliothecary
15
17
  parser: :parse_conda,
16
18
  kind: "manifest",
17
19
  },
18
- match_filename("environment.yml.lock") => {
19
- parser: :parse_conda_lockfile,
20
- kind: "lockfile",
21
- },
22
- match_filename("environment.yaml.lock") => {
23
- parser: :parse_conda_lockfile,
24
- kind: "lockfile",
25
- },
26
20
  }
27
21
  end
28
22
 
@@ -30,35 +24,64 @@ module Bibliothecary
30
24
  add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
31
25
  add_multi_parser(Bibliothecary::MultiParsers::Spdx)
32
26
 
33
- def self.parse_conda(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
34
- parse_conda_with_kind(file_contents, "manifest")
35
- end
27
+ def self.parse_conda(file_contents, options: {})
28
+ manifest = YAML.load(file_contents)
29
+ deps = manifest["dependencies"]
30
+ deps.map do |dep|
31
+ next unless dep.is_a? String # only deal with strings to skip parsing pip stuff
36
32
 
37
- def self.parse_conda_lockfile(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
38
- parse_conda_with_kind(file_contents, "lockfile")
33
+ parsed = parse_name_requirement_from_matchspec(dep)
34
+ Dependency.new(**parsed, type: "runtime", source: options.fetch(:filename, nil))
35
+ end.compact
39
36
  end
40
37
 
41
- def self.parse_conda_with_kind(info, kind)
42
- dependencies = call_conda_parser_web(info, kind)[kind.to_sym]
43
- dependencies.map { |dep_kv| Dependency.new(**dep_kv.merge(type: "runtime")) }
44
- end
38
+ def self.parse_name_requirement_from_matchspec(matchspec)
39
+ # simplified version of the implementation in conda to handle what we care about
40
+ # https://github.com/conda/conda/blob/main/conda/models/match_spec.py#L598
41
+ # (channel(/subdir):(namespace):)name(version(build))[key1=value1,key2=value2]
42
+ return if matchspec.end_with?("@")
45
43
 
46
- private_class_method def self.call_conda_parser_web(file_contents, kind)
47
- host = Bibliothecary.configuration.conda_parser_host
48
- response = Typhoeus.post(
49
- "#{host}/parse",
50
- headers: {
51
- ContentType: "multipart/form-data",
52
- },
53
- body: {
54
- file: file_contents,
55
- # Unfortunately we do not get the filename in the mapping parsers, so hardcoding the file name depending on the kind
56
- filename: kind == "manifest" ? "environment.yml" : "environment.yml.lock",
57
- }
58
- )
59
- raise Bibliothecary::RemoteParsingError.new("Http Error #{response.response_code} when contacting: #{host}/parse", response.response_code) unless response.success?
44
+ # strip off comments and optional features
45
+ matchspec = matchspec.split("#", 2).first
46
+ matchspec = matchspec.split(" if ", 2).first
47
+
48
+ # strip off brackets
49
+ matchspec = matchspec.match(/^(.*)(?:\[(.*)\])?$/)[1]
60
50
 
61
- JSON.parse(response.body, symbolize_names: true)
51
+ # strip off any parens
52
+ matchspec = matchspec.match(/^(.*)(?:(\(.*\)))?$/)[1]
53
+
54
+ # deal with channel and namespace, I wish there was rsplit in ruby
55
+ split = matchspec.reverse.split(":", 2)
56
+ matchspec = split.last.reverse
57
+
58
+ # split the name from the version/build combo
59
+ matches = matchspec.match(/([^ =<>!~]+)?([><!=~ ].+)?/)
60
+ name = matches[1]
61
+ version_build = matches[2]
62
+
63
+ version = nil
64
+ if matches && matches[2]
65
+ version_build = matches[2]
66
+ # and now deal with getting the version from version/build
67
+ matches = version_build.match(/((?:.+?)[^><!,|]?)(?:(?<![=!|,<>~])(?:[ =])([^-=,|<>~]+?))?$/)
68
+ version = if matches
69
+ matches[1].strip
70
+ else
71
+ version_build.strip
72
+ end
73
+ end
74
+ # if it's an exact requirement, lose the =
75
+ if version&.start_with?("==")
76
+ version = version[2..]
77
+ elsif version&.start_with?("=")
78
+ version = version[1..]
79
+ end
80
+
81
+ {
82
+ name: name,
83
+ requirement: version || "", # NOTE: this ignores build info
84
+ }
62
85
  end
63
86
  end
64
87
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "yaml"
2
4
  require "json"
3
5
 
@@ -21,16 +23,16 @@ module Bibliothecary
21
23
 
22
24
  add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
23
25
 
24
- def self.parse_json_manifest(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
26
+ def self.parse_json_manifest(file_contents, options: {})
25
27
  manifest = JSON.parse file_contents
26
28
  manifest["prereqs"].map do |_group, deps|
27
- map_dependencies(deps, "requires", "runtime")
29
+ map_dependencies(deps, "requires", "runtime", options.fetch(:filename, nil))
28
30
  end.flatten
29
31
  end
30
32
 
31
- def self.parse_yaml_manifest(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
33
+ def self.parse_yaml_manifest(file_contents, options: {})
32
34
  manifest = YAML.load file_contents
33
- map_dependencies(manifest, "requires", "runtime")
35
+ map_dependencies(manifest, "requires", "runtime", options.fetch(:filename, nil))
34
36
  end
35
37
  end
36
38
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "deb_control"
2
4
 
3
5
  module Bibliothecary
@@ -20,16 +22,17 @@ module Bibliothecary
20
22
  add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
21
23
  add_multi_parser(Bibliothecary::MultiParsers::Spdx)
22
24
 
23
- def self.parse_description(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
25
+ def self.parse_description(file_contents, options: {})
24
26
  manifest = DebControl::ControlFileBase.parse(file_contents)
25
- parse_section(manifest, "Depends") +
26
- parse_section(manifest, "Imports") +
27
- parse_section(manifest, "Suggests") +
28
- parse_section(manifest, "Enhances")
27
+ parse_section(manifest, "Depends", options.fetch(:filename, nil)) +
28
+ parse_section(manifest, "Imports", options.fetch(:filename, nil)) +
29
+ parse_section(manifest, "Suggests", options.fetch(:filename, nil)) +
30
+ parse_section(manifest, "Enhances", options.fetch(:filename, nil))
29
31
  end
30
32
 
31
- def self.parse_section(manifest, name)
33
+ def self.parse_section(manifest, name, source = nil)
32
34
  return [] unless manifest.first[name]
35
+
33
36
  deps = manifest.first[name].delete("\n").split(",").map(&:strip)
34
37
  deps.map do |dependency|
35
38
  dep = dependency.match(REQUIRE_REGEXP)
@@ -37,6 +40,7 @@ module Bibliothecary
37
40
  name: dep[1],
38
41
  requirement: dep[2],
39
42
  type: name.downcase,
43
+ source: source
40
44
  )
41
45
  end
42
46
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "json"
2
4
  require "sdl_parser"
3
5
 
@@ -22,8 +24,8 @@ module Bibliothecary
22
24
 
23
25
  add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
24
26
 
25
- def self.parse_sdl_manifest(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
26
- SdlParser.new(:runtime, file_contents).dependencies
27
+ def self.parse_sdl_manifest(file_contents, options: {})
28
+ SdlParser.new(:runtime, file_contents, options.fetch(:filename, nil)).dependencies
27
29
  end
28
30
  end
29
31
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "json"
2
4
 
3
5
  module Bibliothecary
@@ -21,13 +23,14 @@ module Bibliothecary
21
23
 
22
24
  add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
23
25
 
24
- def self.parse_json_lock(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
26
+ def self.parse_json_lock(file_contents, options: {})
25
27
  manifest = JSON.parse file_contents
26
28
  manifest.map do |name, requirement|
27
29
  Dependency.new(
28
30
  name: name,
29
31
  requirement: requirement,
30
32
  type: "runtime",
33
+ source: options.fetch(:filename, nil)
31
34
  )
32
35
  end
33
36
  end