bibliothecary 6.4.0 → 6.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 35f76a25c41ad5a990e6c6232536f768015703be873a63c852d70369e3ae9295
4
- data.tar.gz: 7faa006c8ff306dc560d57324cf9ad8d5798030aab058bb7d513b3a834c9ecc4
3
+ metadata.gz: 34c770ef3ea9fb2cc8cb2a360871f67c2ad1b7007d92644558df16f975d70a2f
4
+ data.tar.gz: bf68d3358b128c107266c2c3d27b9e78578cf669731d54fb7511aeda7048d76b
5
5
  SHA512:
6
- metadata.gz: ecc552df23a5489aa6b430e2626f48b8600032a74a1a8c8f522c3ef9d9b9e39a7e1646d61651374bd50dc26f75ec5c905e638c29c9c7a7ab9670b5adc8792d57
7
- data.tar.gz: 1a1e7a14eb4e1a75899d3ac319d98367eb9b883d23ea63f312a2405e1076a7d5702fbb35b0755ae864eea2a065fede8ed74749a5a31d7bff31effa835aff60ad
6
+ metadata.gz: 86c784d59fae0d7096d10066dc270017b8eb8acece490d124eef7c64fa31367f50bbc069f56f62b49bb89703b90af30412a3baccc56cce624f885752f28a932d
7
+ data.tar.gz: 53cfeccce209501b909f9b132971ca80226b7b1ea34f20a3a5334c803c5ad53979c536aac10a7696bea82e2a7a96846b44a997da4b020c463e0e941fb9c3a764
@@ -94,16 +94,6 @@ Lint/HandleExceptions:
94
94
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#dont-hide-exceptions'
95
95
  Enabled: true
96
96
 
97
- Lint/InvalidCharacterLiteral:
98
- Description: >-
99
- Checks for invalid character literals with a non-escaped
100
- whitespace character.
101
- Enabled: true
102
-
103
- Lint/LiteralInCondition:
104
- Description: 'Checks of literals used in conditions.'
105
- Enabled: true
106
-
107
97
  Lint/LiteralInInterpolation:
108
98
  Description: 'Checks for literals used in interpolation.'
109
99
  Enabled: true
@@ -157,13 +147,6 @@ Lint/UnderscorePrefixedVariableName:
157
147
  Description: 'Do not use prefix `_` for a variable that is used.'
158
148
  Enabled: true
159
149
 
160
- Lint/UnneededDisable:
161
- Description: >-
162
- Checks for rubocop:disable comments that can be removed.
163
- Note: this cop is not disabled when disabling all cops.
164
- It must be explicitly disabled.
165
- Enabled: true
166
-
167
150
  Lint/UnusedBlockArgument:
168
151
  Description: 'Checks for unused block arguments.'
169
152
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#underscore-unused-vars'
@@ -257,62 +240,6 @@ Metrics/PerceivedComplexity:
257
240
  human reader.
258
241
  Enabled: false
259
242
 
260
- ##################### Performance #############################
261
-
262
- Performance/Count:
263
- Description: >-
264
- Use `count` instead of `select...size`, `reject...size`,
265
- `select...count`, `reject...count`, `select...length`,
266
- and `reject...length`.
267
- Enabled: true
268
-
269
- Performance/Detect:
270
- Description: >-
271
- Use `detect` instead of `select.first`, `find_all.first`,
272
- `select.last`, and `find_all.last`.
273
- Reference: 'https://github.com/JuanitoFatas/fast-ruby#enumerabledetect-vs-enumerableselectfirst-code'
274
- Enabled: true
275
-
276
- Performance/FlatMap:
277
- Description: >-
278
- Use `Enumerable#flat_map`
279
- instead of `Enumerable#map...Array#flatten(1)`
280
- or `Enumberable#collect..Array#flatten(1)`
281
- Reference: 'https://github.com/JuanitoFatas/fast-ruby#enumerablemaparrayflatten-vs-enumerableflat_map-code'
282
- Enabled: true
283
- EnabledForFlattenWithoutParams: false
284
- # If enabled, this cop will warn about usages of
285
- # `flatten` being called without any parameters.
286
- # This can be dangerous since `flat_map` will only flatten 1 level, and
287
- # `flatten` without any parameters can flatten multiple levels.
288
-
289
- Performance/ReverseEach:
290
- Description: 'Use `reverse_each` instead of `reverse.each`.'
291
- Reference: 'https://github.com/JuanitoFatas/fast-ruby#enumerablereverseeach-vs-enumerablereverse_each-code'
292
- Enabled: true
293
-
294
- Performance/Sample:
295
- Description: >-
296
- Use `sample` instead of `shuffle.first`,
297
- `shuffle.last`, and `shuffle[Fixnum]`.
298
- Reference: 'https://github.com/JuanitoFatas/fast-ruby#arrayshufflefirst-vs-arraysample-code'
299
- Enabled: true
300
-
301
- Performance/Size:
302
- Description: >-
303
- Use `size` instead of `count` for counting
304
- the number of elements in `Array` and `Hash`.
305
- Reference: 'https://github.com/JuanitoFatas/fast-ruby#arraycount-vs-arraysize-code'
306
- Enabled: true
307
-
308
- Performance/StringReplacement:
309
- Description: >-
310
- Use `tr` instead of `gsub` when you are replacing the same
311
- number of characters. Use `delete` instead of `gsub` when
312
- you are deleting characters.
313
- Reference: 'https://github.com/JuanitoFatas/fast-ruby#stringgsub-vs-stringtr-code'
314
- Enabled: true
315
-
316
243
  ##################### Rails ##################################
317
244
 
318
245
  Rails/ActionFilter:
@@ -622,11 +549,11 @@ Style/InitialIndentation:
622
549
  Checks the indentation of the first non-blank non-comment line in a file.
623
550
  Enabled: false
624
551
 
625
- Style/FirstParameterIndentation:
552
+ Layout/IndentFirstParameter:
626
553
  Description: 'Checks the indentation of the first parameter in a method call.'
627
554
  Enabled: false
628
555
 
629
- Style/FlipFlop:
556
+ Lint/FlipFlop:
630
557
  Description: 'Checks for flip flops'
631
558
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-flip-flops'
632
559
  Enabled: false
@@ -680,13 +607,13 @@ Style/IndentationWidth:
680
607
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-indentation'
681
608
  Enabled: false
682
609
 
683
- Style/IndentArray:
610
+ Layout/IndentFirstArrayElement:
684
611
  Description: >-
685
612
  Checks the indentation of the first element in an array
686
613
  literal.
687
614
  Enabled: false
688
615
 
689
- Style/IndentHash:
616
+ Layout/IndentFirstHashElement:
690
617
  Description: 'Checks the indentation of the first key in a hash literal.'
691
618
  Enabled: false
692
619
 
@@ -716,10 +643,11 @@ Style/LineEndConcatenation:
716
643
  line end.
717
644
  Enabled: false
718
645
 
719
- Style/MethodCallParentheses:
646
+ Style/MethodCallWithoutArgsParentheses:
720
647
  Description: 'Do not use parentheses for method calls with no arguments.'
721
- StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-args-no-parens'
722
- Enabled: false
648
+ StyleGuide: '#method-invocation-parens'
649
+ Enabled: true
650
+ IgnoredMethods: []
723
651
 
724
652
  Style/MethodDefParentheses:
725
653
  Description: >-
@@ -816,10 +744,10 @@ Style/OneLineConditional:
816
744
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#ternary-operator'
817
745
  Enabled: false
818
746
 
819
- Style/OpMethod:
747
+ Naming/BinaryOperatorParameterName:
820
748
  Description: 'When defining binary operators, name the argument other.'
821
- StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#other-arg'
822
- Enabled: false
749
+ StyleGuide: '#other-arg'
750
+ Enabled: true
823
751
 
824
752
  Style/OptionalArguments:
825
753
  Description: >-
@@ -1015,7 +943,7 @@ Style/SpaceAroundOperators:
1015
943
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-operators'
1016
944
  Enabled: false
1017
945
 
1018
- Style/SpaceInsideBrackets:
946
+ Layout/SpaceInsideBrackets:
1019
947
  Description: 'No spaces after [ or before ].'
1020
948
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-spaces-braces'
1021
949
  Enabled: false
@@ -1084,10 +1012,14 @@ Style/TrailingCommaInArguments:
1084
1012
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-trailing-params-comma'
1085
1013
  Enabled: false
1086
1014
 
1087
- Style/TrailingCommaInLiteral:
1088
- Description: 'Checks for trailing comma in literals.'
1089
- StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas'
1090
- Enabled: false
1015
+ Style/TrailingCommaInArrayLiteral:
1016
+ Description: 'Checks for trailing comma in array literals.'
1017
+ StyleGuide: '#no-trailing-array-commas'
1018
+ Enabled: true
1019
+
1020
+ Style/TrailingCommaInHashLiteral:
1021
+ Description: 'Checks for trailing comma in hash literals.'
1022
+ Enabled: true
1091
1023
 
1092
1024
  Style/TrailingWhitespace:
1093
1025
  Description: 'Avoid trailing whitespace.'
@@ -4,6 +4,7 @@ require "bibliothecary/configuration"
4
4
  require "bibliothecary/runner"
5
5
  require "bibliothecary/exceptions"
6
6
  require "bibliothecary/file_info"
7
+ require "bibliothecary/related_files_info"
7
8
  require "find"
8
9
 
9
10
  Dir[File.expand_path('../bibliothecary/parsers/*.rb', __FILE__)].each do |file|
@@ -40,6 +41,10 @@ module Bibliothecary
40
41
  runner.package_managers
41
42
  end
42
43
 
44
+ def self.find_manifests(path)
45
+ runner.find_manifests(path)
46
+ end
47
+
43
48
  def self.ignored_dirs
44
49
  configuration.ignored_dirs
45
50
  end
@@ -41,26 +41,24 @@ module Bibliothecary
41
41
  end
42
42
 
43
43
  def parse_file(filename, contents)
44
- mapping.each do |matcher, details|
45
- if mapping_entry_match?(matcher, details, FileInfo.new(nil, filename, contents))
46
- begin
47
- # The `parser` method should raise an exception if the file is malformed,
48
- # should return empty [] if the file is fine but simply doesn't contain
49
- # any dependencies, and should never return nil. At the time of writing
50
- # this comment, some of the parsers return [] or nil to mean an error
51
- # which is confusing to users.
52
- return send(details[:parser], contents)
53
- rescue Exception => e # default is StandardError but C bindings throw Exceptions
54
- # the C xml parser also puts a newline at the end of the message
55
- raise Bibliothecary::FileParsingError.new(e.message.strip, filename)
56
- end
57
- end
58
- end
44
+ details = first_matching_mapping_details(FileInfo.new(nil, filename, contents))
45
+
59
46
  # this can be raised if we don't check match?/match_info?,
60
47
  # OR don't have the file contents when we check them, so
61
48
  # it turns out for example that a .xml file isn't a
62
49
  # manifest after all.
63
- raise Bibliothecary::FileParsingError.new("No parser for this file type", filename)
50
+ raise Bibliothecary::FileParsingError.new("No parser for this file type", filename) unless details[:parser]
51
+
52
+ # The `parser` method should raise an exception if the file is malformed,
53
+ # should return empty [] if the file is fine but simply doesn't contain
54
+ # any dependencies, and should never return nil. At the time of writing
55
+ # this comment, some of the parsers return [] or nil to mean an error
56
+ # which is confusing to users.
57
+ send(details[:parser], contents)
58
+
59
+ rescue Exception => e # default is StandardError but C bindings throw Exceptions
60
+ # the C xml parser also puts a newline at the end of the message
61
+ raise Bibliothecary::FileParsingError.new(e.message.strip, filename)
64
62
  end
65
63
 
66
64
  # this is broken with contents=nil because it can't look at file
@@ -73,9 +71,7 @@ module Bibliothecary
73
71
  end
74
72
 
75
73
  def match_info?(info)
76
- mapping.any? do |matcher, details|
77
- mapping_entry_match?(matcher, details, info)
78
- end
74
+ first_matching_mapping_details(info).any?
79
75
  end
80
76
 
81
77
  def platform_name
@@ -102,64 +98,18 @@ module Bibliothecary
102
98
  end
103
99
  end
104
100
 
105
- def set_related_paths_field(by_dirname_dest, by_dirname_source)
106
- by_dirname_dest.each do |dirname, analyses|
107
- analyses.each do |(info, analysis)|
108
- source_analyses = by_dirname_source[dirname].map { |(info, source_analysis)| info.relative_path }
109
- analysis[:related_paths] = source_analyses.sort
110
- end
111
- end
112
- end
113
-
114
- def add_related_paths(analyses)
115
- analyses.each do |(info, analysis)|
116
- analysis[:related_paths] = []
117
- end
118
-
119
- # associate manifests and lockfiles in the same directory;
120
-
121
- # note that right now we're in the context of a single
122
- # package manager, so manifest and lockfile in the
123
- # same directory is considered proof that they are
124
- # matched.
125
-
126
- by_dirname = {
127
- "manifest" => Hash.new { |h, k| h[k] = [] },
128
- "lockfile" => Hash.new { |h, k| h[k] = [] }
129
- }
130
-
131
- analyses.each do |(info, analysis)|
132
- dirname = File.dirname(info.relative_path)
133
- by_dirname[analysis[:kind]][dirname].push([info, analysis])
134
- end
135
-
136
- by_dirname["manifest"].each do |_, manifests|
137
- # This determine_can_have_lockfile in theory needs the file contents but
138
- # in practice doesn't right now since the only mapping that needs
139
- # file contents is a lockfile and not a manifest so won't reach here.
140
- manifests.delete_if { |(info, manifest)| !determine_can_have_lockfile_from_info(info) }
141
- end
142
-
143
- set_related_paths_field(by_dirname["manifest"], by_dirname["lockfile"])
144
- set_related_paths_field(by_dirname["lockfile"], by_dirname["manifest"])
145
- end
146
-
147
101
  def analyse(folder_path, file_list)
148
102
  analyse_file_info(file_list.map { |full_path| FileInfo.new(folder_path, full_path) })
149
103
  end
150
104
 
151
105
  def analyse_file_info(file_info_list)
152
- analyses = file_info_list.map do |info|
153
- next unless match_info?(info)
154
- [info, analyse_contents_from_info(info)]
155
- end
156
-
157
- # strip the ones we failed to analyse
158
- analyses = analyses.reject { |(info, analysis)| analysis.nil? }
106
+ matching_info = file_info_list
107
+ .select(&method(:match_info?))
159
108
 
160
- add_related_paths(analyses)
161
-
162
- analyses.map { |(info, analysis)| analysis }
109
+ matching_info.map do |info|
110
+ analyse_contents_from_info(info)
111
+ .merge(related_paths: related_paths(info, matching_info))
112
+ end
163
113
  end
164
114
 
165
115
  def analyse_contents(filename, contents)
@@ -182,12 +132,8 @@ module Bibliothecary
182
132
  end
183
133
 
184
134
  def determine_kind_from_info(info)
185
- mapping.each do |matcher, details|
186
- if mapping_entry_match?(matcher, details, info)
187
- return details[:kind]
188
- end
189
- end
190
- return nil
135
+ first_matching_mapping_details(info)
136
+ .fetch(:kind, nil)
191
137
  end
192
138
 
193
139
  # calling this with contents=nil can produce less-informed
@@ -197,12 +143,8 @@ module Bibliothecary
197
143
  end
198
144
 
199
145
  def determine_can_have_lockfile_from_info(info)
200
- mapping.each do |matcher, details|
201
- if mapping_entry_match?(matcher, details, info)
202
- return details.fetch(:can_have_lockfile, true)
203
- end
204
- end
205
- return true
146
+ first_matching_mapping_details(info)
147
+ .fetch(:can_have_lockfile, true)
206
148
  end
207
149
 
208
150
  def parse_ruby_manifest(manifest)
@@ -242,6 +184,31 @@ module Bibliothecary
242
184
  lambda { |path| path.end_with?(filename) }
243
185
  end
244
186
  end
187
+
188
+ private
189
+
190
+ def related_paths(info, infos)
191
+ return [] unless determine_can_have_lockfile_from_info(info)
192
+
193
+ kind = determine_kind_from_info(info)
194
+ relate_to_kind = first_matching_mapping_details(info)
195
+ .fetch(:related_to, %w(manifest lockfile).reject { |k| k == kind })
196
+ dirname = File.dirname(info.relative_path)
197
+
198
+ infos
199
+ .reject { |i| i == info }
200
+ .select { |i| relate_to_kind.include?(determine_kind_from_info(i)) }
201
+ .select { |i| File.dirname(i.relative_path) == dirname }
202
+ .select(&method(:determine_can_have_lockfile_from_info))
203
+ .map(&:relative_path)
204
+ .sort
205
+ end
206
+
207
+ def first_matching_mapping_details(info)
208
+ mapping
209
+ .find { |matcher, details| mapping_entry_match?(matcher, details, info) }
210
+ &.last || {}
211
+ end
245
212
  end
246
213
  end
247
214
  end
@@ -41,7 +41,7 @@ module Bibliothecary
41
41
  match_filename("Gopkg.lock") => {
42
42
  kind: 'lockfile',
43
43
  parser: :parse_dep_lockfile
44
- },
44
+ }
45
45
  }
46
46
  end
47
47
 
@@ -15,7 +15,7 @@ module Bibliothecary
15
15
  match_extension("cabal.config") => {
16
16
  kind: 'lockfile',
17
17
  parser: :parse_cabal_config
18
- },
18
+ }
19
19
  }
20
20
  end
21
21
 
@@ -53,7 +53,7 @@ module Bibliothecary
53
53
  doc = Ox.parse file_contents
54
54
  root = doc&.locate("ivy-report")&.first
55
55
  return !root.nil?
56
- rescue Exception => e
56
+ rescue Exception => e # rubocop:disable Lint/RescueException
57
57
  # We rescue exception here since native libs can throw a non-StandardError
58
58
  # We don't want to throw errors during the matching phase, only during
59
59
  # parsing after we match.
@@ -111,18 +111,17 @@ module Bibliothecary
111
111
 
112
112
  def self.parse_pom_manifest(file_contents)
113
113
  manifest = Ox.parse file_contents
114
- if manifest.respond_to?('project')
115
- xml = manifest.project
116
- else
117
- xml = manifest
118
- end
119
- return [] unless xml.respond_to?('dependencies')
120
- xml.dependencies.locate('dependency').map do |dependency|
121
- {
122
- name: "#{extract_pom_dep_info(xml, dependency, 'groupId')}:#{extract_pom_dep_info(xml, dependency, 'artifactId')}",
123
- requirement: extract_pom_dep_info(xml, dependency, 'version'),
124
- type: extract_pom_dep_info(xml, dependency, 'scope') || 'runtime'
125
- }
114
+ xml = manifest.respond_to?('project') ? manifest.project : manifest
115
+ [].tap do |deps|
116
+ ['dependencies/dependency', 'dependencyManagement/dependencies/dependency'].each do |deps_xpath|
117
+ xml.locate(deps_xpath).each do |dep|
118
+ deps.push({
119
+ name: "#{extract_pom_dep_info(xml, dep, 'groupId')}:#{extract_pom_dep_info(xml, dep, 'artifactId')}",
120
+ requirement: extract_pom_dep_info(xml, dep, 'version'),
121
+ type: extract_pom_dep_info(xml, dep, 'scope') || 'runtime'
122
+ })
123
+ end
124
+ end
126
125
  end
127
126
  end
128
127
 
@@ -148,6 +147,7 @@ module Bibliothecary
148
147
  value = field.nodes.first
149
148
  match = value.match(/^\$\{(.+)\}/)
150
149
  if match
150
+ return value unless xml.respond_to? 'properties'
151
151
  prop_field = xml.properties.locate(match[1]).first
152
152
  if prop_field
153
153
  return prop_field.nodes.first
@@ -12,16 +12,18 @@ module Bibliothecary
12
12
  {
13
13
  match_filenames("Gemfile", "gems.rb") => {
14
14
  kind: 'manifest',
15
- parser: :parse_gemfile
15
+ parser: :parse_gemfile,
16
+ related_to: [ 'manifest', 'lockfile' ]
16
17
  },
17
18
  match_extension(".gemspec") => {
18
19
  kind: 'manifest',
19
20
  parser: :parse_gemspec,
20
- can_have_lockfile: false
21
+ related_to: [ 'manifest', 'lockfile' ]
21
22
  },
22
23
  match_filenames("Gemfile.lock", "gems.locked") => {
23
24
  kind: 'lockfile',
24
- parser: :parse_gemfile_lock
25
+ parser: :parse_gemfile_lock,
26
+ related_to: [ 'manifest', 'lockfile' ]
25
27
  }
26
28
  }
27
29
  end
@@ -49,8 +51,6 @@ module Bibliothecary
49
51
  manifest = Gemnasium::Parser.send(:gemspec, file_contents)
50
52
  parse_ruby_manifest(manifest)
51
53
  end
52
-
53
-
54
54
  end
55
55
  end
56
56
  end
@@ -0,0 +1,28 @@
1
+ module Bibliothecary
2
+ class RelatedFilesInfo
3
+ attr_reader :path
4
+ attr_reader :platform
5
+ attr_reader :manifests
6
+ attr_reader :lockfiles
7
+
8
+ def self.create_from_file_infos(file_infos)
9
+ returns = []
10
+ paths = file_infos.group_by { |info| File.dirname(info.relative_path) }
11
+ paths.values.each do |path|
12
+ same_pm = path.group_by { |info| info.package_manager}
13
+ same_pm.values.each do |value|
14
+ returns.append(RelatedFilesInfo.new(value))
15
+ end
16
+ end
17
+ returns
18
+ end
19
+
20
+ def initialize(file_infos)
21
+ package_manager = file_infos.first.package_manager
22
+ @platform = package_manager.platform_name
23
+ @path = Pathname.new(File.dirname(file_infos.first.relative_path)).cleanpath.to_path
24
+ @manifests = file_infos.select { |info| package_manager.determine_kind_from_info(info) == "manifest" }.map { |info| File.basename(info.relative_path) }
25
+ @lockfiles = file_infos.select { |info| package_manager.determine_kind_from_info(info) == "lockfile" }.map { |info| File.basename(info.relative_path) }
26
+ end
27
+ end
28
+ end
@@ -61,6 +61,10 @@ module Bibliothecary
61
61
  file_list
62
62
  end
63
63
 
64
+ def find_manifests(path)
65
+ RelatedFilesInfo.create_from_file_infos(load_file_info_list(path).reject { |info| info.package_manager.nil? })
66
+ end
67
+
64
68
  def analyse_file(file_path, contents)
65
69
  package_managers.select { |pm| pm.match?(file_path, contents) }.map do |pm|
66
70
  pm.analyse_contents(file_path, contents)
@@ -1,3 +1,3 @@
1
1
  module Bibliothecary
2
- VERSION = "6.4.0"
2
+ VERSION = "6.6.0"
3
3
  end
@@ -12,7 +12,7 @@ class SdlParser
12
12
  deps.push({
13
13
  name: dep.value,
14
14
  requirement: dep.attribute('version') || ">= 0",
15
- type: type,
15
+ type: type
16
16
  })
17
17
  end.uniq
18
18
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bibliothecary
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.4.0
4
+ version: 6.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Nesbitt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-04-03 00:00:00.000000000 Z
11
+ date: 2019-05-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: toml-rb
@@ -250,6 +250,7 @@ files:
250
250
  - lib/bibliothecary/parsers/rubygems.rb
251
251
  - lib/bibliothecary/parsers/shard.rb
252
252
  - lib/bibliothecary/parsers/swift_pm.rb
253
+ - lib/bibliothecary/related_files_info.rb
253
254
  - lib/bibliothecary/runner.rb
254
255
  - lib/bibliothecary/version.rb
255
256
  - lib/sdl_parser.rb