libyear-bundler 0.5.0 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 8ab149dc302594c069829c10cc93253a4a9165d2
4
- data.tar.gz: 8f6a974c411bc9b72d799b137f715cd7c35260a1
2
+ SHA256:
3
+ metadata.gz: 6605cda8b92cd002e2b1a536a716ba50d8c0df4b550db28f6b0be4760d7734f7
4
+ data.tar.gz: eec844bd3aaf31c95fc29827ca6a33166da392ab799a03b3b3b5269cc5507fe7
5
5
  SHA512:
6
- metadata.gz: 424dad3f3c7ef8e6f42cb406714ec080193ca59f4c3d55b7e38d631d0d0ac97a670e9db076c993a9a1c976e31dd47cbe08f3ccf32dc7466c20379fcdda6d1acd
7
- data.tar.gz: aad230cd11ee0313b1d1bce97fa489b020c92fd15686deb9ecefa4ac96a9a2393cd27aa998edfd9983c66f4dd168c131752aae1d5c53fc4e273d8757c10beec2
6
+ metadata.gz: 555318739eb3506de90e6d21f103fbb8ce2c0bd4225595830465c0aae476a906d55ffcf534e375925146c695348bbca975fe75ef962752bb4d41f474b6308b2d
7
+ data.tar.gz: a1fe20a4d14b170ccc8b10949868cf859382135651ec799bd1c0bfff4c588a5b92e63d7bf347cc0987feb4aa8199966e986b56d797d30828e9b01b3fb64cde72
@@ -11,18 +11,25 @@ module LibyearBundler
11
11
  # Format of `bundle outdated --parseable` (BOP)
12
12
  BOP_FMT = /\A(?<name>[^ ]+) \(newest (?<newest>[^,]+), installed (?<installed>[^,)]+)/
13
13
 
14
- def initialize(gemfile_path)
14
+ def initialize(gemfile_path, release_date_cache)
15
15
  @gemfile_path = gemfile_path
16
+ @release_date_cache = release_date_cache
16
17
  end
17
18
 
18
19
  def execute
19
20
  bundle_outdated.lines.each_with_object([]) do |line, gems|
20
21
  match = BOP_FMT.match(line)
21
22
  next if match.nil?
23
+ if malformed_version_strings?(match)
24
+ warn "Skipping #{match['name']} because of a malformed version string"
25
+ next
26
+ end
27
+
22
28
  gem = ::LibyearBundler::Models::Gem.new(
23
29
  match['name'],
24
30
  match['installed'],
25
- match['newest']
31
+ match['newest'],
32
+ @release_date_cache
26
33
  )
27
34
  gems.push(gem)
28
35
  end
@@ -47,5 +54,12 @@ module LibyearBundler
47
54
  end
48
55
  stdout
49
56
  end
57
+
58
+ # We rely on Gem::Version to handle version strings. If the string is malformed (usually because
59
+ # of a gem installed from git), then we won't be able to determine the dependency's freshness
60
+ def malformed_version_strings?(dependency)
61
+ !Gem::Version.correct?(dependency['installed']) ||
62
+ !Gem::Version.correct?(dependency['newest'])
63
+ end
50
64
  end
51
65
  end
@@ -2,6 +2,7 @@ require "bundler/cli"
2
2
  require "bundler/cli/outdated"
3
3
  require "libyear_bundler/bundle_outdated"
4
4
  require "libyear_bundler/options"
5
+ require "libyear_bundler/release_date_cache"
5
6
  require "libyear_bundler/report"
6
7
  require 'libyear_bundler/models/ruby'
7
8
 
@@ -27,6 +28,12 @@ module LibyearBundler
27
28
  else
28
29
  print report.to_s
29
30
  end
31
+
32
+ # Update cache
33
+ cache_path = @options.cache_path
34
+ if cache_path && release_date_cache
35
+ release_date_cache.save(cache_path)
36
+ end
30
37
  end
31
38
 
32
39
  private
@@ -54,7 +61,15 @@ module LibyearBundler
54
61
  end
55
62
 
56
63
  def bundle_outdated
57
- BundleOutdated.new(@gemfile_path).execute
64
+ BundleOutdated.new(@gemfile_path, release_date_cache).execute
65
+ end
66
+
67
+ def release_date_cache
68
+ @_release_date_cache ||= begin
69
+ path = @options.cache_path
70
+ return if path.nil?
71
+ ReleaseDateCache.load(path)
72
+ end
58
73
  end
59
74
 
60
75
  def report
@@ -63,7 +78,7 @@ module LibyearBundler
63
78
 
64
79
  def ruby
65
80
  lockfile = @gemfile_path + '.lock'
66
- ::LibyearBundler::Models::Ruby.new(lockfile)
81
+ ::LibyearBundler::Models::Ruby.new(lockfile, release_date_cache)
67
82
  end
68
83
 
69
84
  def grand_total
@@ -7,10 +7,39 @@ module LibyearBundler
7
7
  # Logic and information pertaining to the installed and newest versions of
8
8
  # a gem
9
9
  class Gem
10
- def initialize(name, installed_version, newest_version)
10
+ def initialize(name, installed_version, newest_version, release_date_cache)
11
+ unless release_date_cache.nil? || release_date_cache.is_a?(ReleaseDateCache)
12
+ raise TypeError, 'Invalid release_date_cache'
13
+ end
11
14
  @name = name
12
15
  @installed_version = installed_version
13
16
  @newest_version = newest_version
17
+ @release_date_cache = release_date_cache
18
+ end
19
+
20
+ class << self
21
+ def release_date(gem_name, gem_version)
22
+ dep = nil
23
+ begin
24
+ dep = ::Bundler::Dependency.new(gem_name, gem_version)
25
+ rescue ::Gem::Requirement::BadRequirementError => e
26
+ $stderr.puts "Could not find release date for: #{gem_name}"
27
+ $stderr.puts(e)
28
+ $stderr.puts(
29
+ "Maybe you used git in your Gemfile, which libyear doesn't support " \
30
+ "yet. Contributions welcome."
31
+ )
32
+ return nil
33
+ end
34
+ tuples, _errors = ::Gem::SpecFetcher.fetcher.search_for_dependency(dep)
35
+ if tuples.empty?
36
+ $stderr.puts "Could not find release date for: #{gem_name}"
37
+ return nil
38
+ end
39
+ tup, source = tuples.first # Gem::NameTuple
40
+ spec = source.fetch_spec(tup) # raises Gem::RemoteFetcher::FetchError
41
+ spec.date.to_date
42
+ end
14
43
  end
15
44
 
16
45
  def installed_version
@@ -18,7 +47,11 @@ module LibyearBundler
18
47
  end
19
48
 
20
49
  def installed_version_release_date
21
- release_date(name, installed_version)
50
+ if @release_date_cache.nil?
51
+ self.class.release_date(name, installed_version)
52
+ else
53
+ @release_date_cache[name, installed_version]
54
+ end
22
55
  end
23
56
 
24
57
  def installed_version_sequence_index
@@ -45,7 +78,11 @@ module LibyearBundler
45
78
  end
46
79
 
47
80
  def newest_version_release_date
48
- release_date(name, newest_version)
81
+ if @release_date_cache.nil?
82
+ self.class.release_date(name, newest_version)
83
+ else
84
+ @release_date_cache[name, newest_version]
85
+ end
49
86
  end
50
87
 
51
88
  def version_number_delta
@@ -74,31 +111,6 @@ module LibyearBundler
74
111
  parsed_response.map { |version| version['number'] }
75
112
  end
76
113
  end
77
-
78
- # Known issue: Probably performs a network request every time, unless
79
- # there's some kind of caching.
80
- def release_date(gem_name, gem_version)
81
- dep = nil
82
- begin
83
- dep = ::Bundler::Dependency.new(gem_name, gem_version)
84
- rescue ::Gem::Requirement::BadRequirementError => e
85
- $stderr.puts "Could not find release date for: #{gem_name}"
86
- $stderr.puts(e)
87
- $stderr.puts(
88
- "Maybe you used git in your Gemfile, which libyear doesn't support " \
89
- "yet. Contributions welcome."
90
- )
91
- return nil
92
- end
93
- tuples, _errors = ::Gem::SpecFetcher.fetcher.search_for_dependency(dep)
94
- if tuples.empty?
95
- $stderr.puts "Could not find release date for: #{gem_name}"
96
- return nil
97
- end
98
- tup, source = tuples.first # Gem::NameTuple
99
- spec = source.fetch_spec(tup) # raises Gem::RemoteFetcher::FetchError
100
- spec.date.to_date
101
- end
102
114
  end
103
115
  end
104
116
  end
@@ -15,8 +15,78 @@ module LibyearBundler
15
15
  RUBY_VERSION_DATA_URL = "https://raw.githubusercontent.com/ruby/" \
16
16
  "www.ruby-lang.org/master/_data/releases.yml".freeze
17
17
 
18
- def initialize(lockfile)
18
+ def initialize(lockfile, release_date_cache)
19
+ unless release_date_cache.nil? || release_date_cache.is_a?(ReleaseDateCache)
20
+ raise TypeError, 'Invalid release_date_cache'
21
+ end
19
22
  @lockfile = lockfile
23
+ @release_date_cache = release_date_cache
24
+ end
25
+
26
+ class << self
27
+ # We'll only consider non-prerelease versions when analyzing ruby version,
28
+ # which we also implcitly do for gem versions because that's bundler's
29
+ # default behavior
30
+ #
31
+ # @return [Array<String>]
32
+ def all_stable_versions
33
+ all_versions.reject do |version|
34
+ ::Gem::Version.new(version).prerelease?
35
+ end
36
+ end
37
+
38
+ def newest_version
39
+ ::Gem::Version.new(all_stable_versions.first)
40
+ end
41
+
42
+ def newest_version_release_date
43
+ if @release_date_cache.nil?
44
+ release_date(newest_version)
45
+ else
46
+ @release_date_cache[name, newest_version]
47
+ end
48
+ end
49
+
50
+ def newest_version_sequence_index
51
+ all_stable_versions.find_index(newest_version.to_s)
52
+ end
53
+
54
+ def release_date(version_obj)
55
+ version = version_obj.to_s
56
+ v = all_stable_versions.detect { |ver| ver == version }
57
+
58
+ if v.nil?
59
+ raise format('Cannot determine release date for ruby %s', version)
60
+ end
61
+
62
+ # YAML#safe_load provides an already-parsed Date object, so the following
63
+ # is a Date object
64
+ v['date']
65
+ end
66
+
67
+ private
68
+
69
+ # The following URL is the only official, easily-parseable document with
70
+ # Ruby version information that I'm aware of, but is not supported as such
71
+ # (https://github.com/ruby/www.ruby-lang.org/pull/1637#issuecomment-344934173).
72
+ # It's been recommend that ruby-lang.org provide a supported document:
73
+ # https://github.com/ruby/www.ruby-lang.org/pull/1637#issuecomment-344934173
74
+ # TODO: Use supported document with version information if it becomes
75
+ # available.
76
+ #
77
+ # @return [Array<String>]
78
+ def all_versions
79
+ @_all_versions ||= begin
80
+ uri = ::URI.parse(RUBY_VERSION_DATA_URL)
81
+ response = ::Net::HTTP.get_response(uri)
82
+ # The Date object is passed through here due to a bug in
83
+ # YAML#safe_load
84
+ # https://github.com/ruby/psych/issues/262
85
+ ::YAML
86
+ .safe_load(response.body, [Date])
87
+ .map { |release| release['version'] }
88
+ end
89
+ end
20
90
  end
21
91
 
22
92
  def installed_version
@@ -28,13 +98,17 @@ module LibyearBundler
28
98
  end
29
99
 
30
100
  def installed_version_release_date
31
- release_date(installed_version.to_s)
101
+ if @release_date_cache.nil?
102
+ self.class.release_date(installed_version)
103
+ else
104
+ @release_date_cache[name, installed_version]
105
+ end
32
106
  end
33
107
 
34
108
  def libyears
35
109
  ::LibyearBundler::Calculators::Libyear.calculate(
36
- release_date(installed_version.to_s),
37
- release_date(newest_version.to_s)
110
+ installed_version_release_date,
111
+ self.class.newest_version_release_date
38
112
  )
39
113
  end
40
114
 
@@ -42,12 +116,16 @@ module LibyearBundler
42
116
  'ruby'
43
117
  end
44
118
 
119
+ # Simply delegates to class method, but we still need it to conform to
120
+ # the interface expected by `Report#meta_line_summary`.
45
121
  def newest_version
46
- ::Gem::Version.new(all_versions.first['version'])
122
+ self.class.newest_version
47
123
  end
48
124
 
125
+ # Simply delegates to class method, but we still need it to conform to
126
+ # the interface expected by `Report#meta_line_summary`.
49
127
  def newest_version_release_date
50
- release_date(newest_version.to_s)
128
+ self.class.newest_version_release_date
51
129
  end
52
130
 
53
131
  def outdated?
@@ -57,59 +135,35 @@ module LibyearBundler
57
135
  def version_number_delta
58
136
  ::LibyearBundler::Calculators::VersionNumberDelta.calculate(
59
137
  installed_version,
60
- newest_version
138
+ self.class.newest_version
61
139
  )
62
140
  end
63
141
 
64
142
  def version_sequence_delta
65
143
  ::LibyearBundler::Calculators::VersionSequenceDelta.calculate(
66
144
  installed_version_sequence_index,
67
- newest_version_sequence_index
145
+ self.class.newest_version_sequence_index
68
146
  )
69
147
  end
70
148
 
71
149
  private
72
150
 
73
- # We'll only consider non-prerelease versions when determining the
74
- # newest version
75
- #
76
- # The following URL is the only official, easily-parseable document with
77
- # Ruby version information that I'm aware of, but is not supported as such
78
- # (https://github.com/ruby/www.ruby-lang.org/pull/1637#issuecomment-344934173).
79
- # It's been recommend that ruby-lang.org provide a supported document:
80
- # https://github.com/ruby/www.ruby-lang.org/pull/1637#issuecomment-344934173
81
- # TODO: Use supported document with version information if it becomes
82
- # available.
83
- def all_versions
84
- @_all_versions ||= begin
85
- uri = ::URI.parse(RUBY_VERSION_DATA_URL)
86
- response = ::Net::HTTP.get_response(uri)
87
- # The Date object is passed through here due to a bug in
88
- # YAML#safe_load
89
- # https://github.com/ruby/psych/issues/262
90
- ::YAML.safe_load(response.body, [Date]).reject do |version|
91
- ::Gem::Version.new(version['version']).prerelease?
92
- end
93
- end
94
- end
95
-
96
151
  def installed_version_sequence_index
97
- versions_sequence.index(installed_version.to_s)
98
- end
99
-
100
- def newest_version_sequence_index
101
- versions_sequence.index(newest_version.to_s)
102
- end
103
-
104
- def release_date(version)
105
- v = all_versions.detect { |ver| ver['version'] == version }
106
- # YAML#safe_load provides an already-parsed Date object, so the following
107
- # is a Date object
108
- v['date']
152
+ self.class.all_stable_versions.index(installed_version.to_s)
109
153
  end
110
154
 
111
155
  def shell_out_to_ruby
112
- `ruby --version`.split[1]
156
+ # ruby appends a 'p' followed by the patch level number
157
+ # to the version number for stable releases, which returns
158
+ # a false positive using `::Gem::Version#prerelease?`.
159
+ # Understandably, because ruby is not a gem, but we'd like
160
+ # to use `prerelease?`.
161
+ # Pre-releases are appended with 'dev', and so adhere to
162
+ # `::Gem::Version`'s definition of a pre-release.
163
+ # Sources:
164
+ # - https://github.com/ruby/ruby/blob/trunk/version.h#L37
165
+ # - https://ruby-doc.org/stdlib-1.9.3/libdoc/rubygems/rdoc/Version.html
166
+ `ruby --version`.split[1].gsub(/p\d*/, '')
113
167
  end
114
168
 
115
169
  def version_from_bundler
@@ -122,6 +176,8 @@ module LibyearBundler
122
176
  ::Bundler::RubyVersion.from_string(ruby_version_string).gem_version
123
177
  end
124
178
 
179
+ # TODO: this path should probably be relative to `@lockfile` instead
180
+ # TODO: of being relative to the current working directory.
125
181
  def version_from_ruby_version_file
126
182
  return unless ::File.exist?('.ruby-version')
127
183
  ::Gem::Version.new(::File.read('.ruby-version').strip)
@@ -130,10 +186,6 @@ module LibyearBundler
130
186
  def version_from_ruby
131
187
  ::Gem::Version.new(shell_out_to_ruby)
132
188
  end
133
-
134
- def versions_sequence
135
- all_versions.map { |version| version['version'] }
136
- end
137
189
  end
138
190
  end
139
191
  end
@@ -31,6 +31,10 @@ https://github.com/jaredbeck/libyear-bundler/
31
31
  @options.send('versions?=', true)
32
32
  end
33
33
 
34
+ opts.on('--cache=CACHE_PATH', 'Use a cache across runs') do |cache_path|
35
+ @options.cache_path = cache_path
36
+ end
37
+
34
38
  opts.on('--libyears', '[default] Calculate libyears out-of-date') do
35
39
  @options.send('libyears?=', true)
36
40
  end
@@ -0,0 +1,50 @@
1
+ require 'yaml'
2
+
3
+ module LibyearBundler
4
+ # A cache of release dates by name and version, for both gems and rubies.
5
+ class ReleaseDateCache
6
+ # @param data [Hash<String,Date>]
7
+ def initialize(data)
8
+ raise TypeError unless data.is_a?(Hash)
9
+ @data = data
10
+ end
11
+
12
+ def [](name, version)
13
+ key = format('%s-%s', name, version)
14
+ if @data.key?(key)
15
+ @data[key]
16
+ else
17
+ @data[key] = release_date(name, version)
18
+ end
19
+ end
20
+
21
+ class << self
22
+ def load(path)
23
+ if File.exist?(path)
24
+ new(YAML.safe_load(File.read(path), [Date]))
25
+ else
26
+ new({})
27
+ end
28
+ end
29
+ end
30
+
31
+ def save(path)
32
+ content = YAML.dump(@data)
33
+ begin
34
+ File.write(path, content)
35
+ rescue StandardError => e
36
+ warn format('Unable to update cache: %s, %s', path, e.message)
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def release_date(name, version)
43
+ if name == 'ruby'
44
+ Models::Ruby.release_date(version)
45
+ else
46
+ Models::Gem.release_date(name, version)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -17,7 +17,13 @@ module LibyearBundler
17
17
 
18
18
  def to_s
19
19
  to_h[:gems].each { |gem| put_line_summary(gem) }
20
- put_line_summary(@ruby) if @ruby.outdated?
20
+
21
+ begin
22
+ put_line_summary(@ruby) if @ruby.outdated?
23
+ rescue StandardError => e
24
+ warn "Unable to calculate libyears for ruby itself: #{e} (line summary)"
25
+ end
26
+
21
27
  put_summary(to_h)
22
28
  end
23
29
 
@@ -30,7 +36,11 @@ module LibyearBundler
30
36
  }
31
37
  @gems.each { |gem| increment_metrics_summary(gem, summary) }
32
38
 
33
- increment_metrics_summary(@ruby, summary) if @ruby.outdated?
39
+ begin
40
+ increment_metrics_summary(@ruby, summary) if @ruby.outdated?
41
+ rescue StandardError => e
42
+ warn "Unable to calculate libyears for ruby itself: #{e}"
43
+ end
34
44
 
35
45
  summary
36
46
  end
@@ -82,20 +92,23 @@ module LibyearBundler
82
92
 
83
93
  def put_version_delta_summary(sum_major_version, sum_minor_version, sum_patch_version)
84
94
  puts format(
85
- "Major, minor, patch versions behind: %d, %d, %d",
86
- sum_major_version,
87
- sum_minor_version,
88
- sum_patch_version
95
+ "Major, minor, patch versions behind: %<major>d, %<minor>d, %<patch>d",
96
+ major: sum_major_version || 0,
97
+ minor: sum_minor_version || 0,
98
+ patch: sum_patch_version || 0
89
99
  )
90
100
  end
91
101
 
92
102
  def put_sum_seq_delta_summary(sum_seq_delta)
93
- puts format("Total releases behind: %d", sum_seq_delta)
103
+ puts format(
104
+ "Total releases behind: %<seq_delta>d",
105
+ seq_delta: sum_seq_delta || 0
106
+ )
94
107
  end
95
108
 
96
109
  def put_summary(summary)
97
110
  if [:libyears?, :releases?, :versions?].all? { |opt| @options.send(opt) }
98
- put_libyear_summary(summary[:sum_years])
111
+ put_libyear_summary(summary[:sum_libyears])
99
112
  put_sum_seq_delta_summary(summary[:sum_seq_delta])
100
113
  put_version_delta_summary(
101
114
  summary[:sum_major_version],
@@ -1,3 +1,3 @@
1
1
  module LibyearBundler
2
- VERSION = "0.5.0".freeze
2
+ VERSION = "0.6.0".freeze
3
3
  end
@@ -12,14 +12,30 @@ Gem::Specification.new do |spec|
12
12
  spec.summary = "A simple measure of dependency freshness"
13
13
  spec.homepage = "https://libyear.com"
14
14
  spec.licenses = ["GPL-3.0"]
15
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
16
- f.match(%r{^(test|spec|features)/})
15
+ spec.files = `git ls-files -z`.split("\x0").select do |f|
16
+ f.start_with?('lib/') ||
17
+ [
18
+ 'bin/libyear-bundler',
19
+ 'libyear-bundler.gemspec',
20
+ 'LICENSE.txt'
21
+ ].include?(f)
17
22
  end
18
23
  spec.bindir = "bin"
19
24
  spec.executables = ["libyear-bundler"]
20
25
  spec.require_paths = ["lib"]
26
+
27
+ # We deliberately support dead rubies, as long as possible. It's important
28
+ # that people with badly out-of-date systems can still measure how bad they
29
+ # are.
21
30
  spec.required_ruby_version = ">= 2.1"
22
- spec.add_dependency "bundler", "~> 1.14"
23
- spec.add_development_dependency "rubocop"
24
- spec.add_development_dependency "rspec"
31
+
32
+ # We will support bundler 1 as long as we can. See `required_ruby_version`
33
+ # above.
34
+ spec.add_dependency "bundler", ">= 1.14", "< 3"
35
+
36
+ spec.add_development_dependency "rspec", "~> 3.9"
37
+
38
+ # rubocop 0.57 drops support for ruby 2.1, so 0.56 is the highest we can
39
+ # use. We're going to support ruby 2.1 as long as possible. See above.
40
+ spec.add_development_dependency "rubocop", "~> 0.56.0"
25
41
  end
metadata CHANGED
@@ -1,57 +1,63 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: libyear-bundler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jared Beck
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-28 00:00:00.000000000 Z
11
+ date: 2021-08-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.14'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '3'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
25
28
  - !ruby/object:Gem::Version
26
29
  version: '1.14'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '3'
27
33
  - !ruby/object:Gem::Dependency
28
- name: rubocop
34
+ name: rspec
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
31
- - - ">="
37
+ - - "~>"
32
38
  - !ruby/object:Gem::Version
33
- version: '0'
39
+ version: '3.9'
34
40
  type: :development
35
41
  prerelease: false
36
42
  version_requirements: !ruby/object:Gem::Requirement
37
43
  requirements:
38
- - - ">="
44
+ - - "~>"
39
45
  - !ruby/object:Gem::Version
40
- version: '0'
46
+ version: '3.9'
41
47
  - !ruby/object:Gem::Dependency
42
- name: rspec
48
+ name: rubocop
43
49
  requirement: !ruby/object:Gem::Requirement
44
50
  requirements:
45
- - - ">="
51
+ - - "~>"
46
52
  - !ruby/object:Gem::Version
47
- version: '0'
53
+ version: 0.56.0
48
54
  type: :development
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
51
57
  requirements:
52
- - - ">="
58
+ - - "~>"
53
59
  - !ruby/object:Gem::Version
54
- version: '0'
60
+ version: 0.56.0
55
61
  description:
56
62
  email:
57
63
  - jared@jaredbeck.com
@@ -60,15 +66,7 @@ executables:
60
66
  extensions: []
61
67
  extra_rdoc_files: []
62
68
  files:
63
- - ".gitignore"
64
- - ".rubocop.yml"
65
- - ".rubocop_todo.yml"
66
- - ".travis.yml"
67
- - CHANGELOG.md
68
- - CONTRIBUTING.md
69
- - Gemfile
70
69
  - LICENSE.txt
71
- - README.md
72
70
  - bin/libyear-bundler
73
71
  - lib/libyear_bundler.rb
74
72
  - lib/libyear_bundler/bundle_outdated.rb
@@ -79,6 +77,7 @@ files:
79
77
  - lib/libyear_bundler/models/gem.rb
80
78
  - lib/libyear_bundler/models/ruby.rb
81
79
  - lib/libyear_bundler/options.rb
80
+ - lib/libyear_bundler/release_date_cache.rb
82
81
  - lib/libyear_bundler/report.rb
83
82
  - lib/libyear_bundler/version.rb
84
83
  - libyear-bundler.gemspec
@@ -102,7 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
102
101
  version: '0'
103
102
  requirements: []
104
103
  rubyforge_project:
105
- rubygems_version: 2.6.13
104
+ rubygems_version: 2.7.6.3
106
105
  signing_key:
107
106
  specification_version: 4
108
107
  summary: A simple measure of dependency freshness
data/.gitignore DELETED
@@ -1,10 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
10
- .ruby-version
data/.rubocop.yml DELETED
@@ -1,30 +0,0 @@
1
- inherit_from: .rubocop_todo.yml
2
-
3
- AllCops:
4
- TargetRubyVersion: 2.1.10
5
-
6
- Metrics/AbcSize:
7
- Max: 27
8
-
9
- Metrics/BlockLength:
10
- Exclude:
11
- - 'spec/**/*'
12
-
13
- Metrics/ModuleLength:
14
- Exclude:
15
- - 'spec/**/*'
16
-
17
- Metrics/LineLength:
18
- Max: 100
19
-
20
- Metrics/MethodLength:
21
- Enabled: false
22
-
23
- Style/IndentArray:
24
- EnforcedStyle: consistent
25
-
26
- Style/MultilineMethodCallIndentation:
27
- EnforcedStyle: indented
28
-
29
- Style/StringLiterals:
30
- Enabled: false
data/.rubocop_todo.yml DELETED
@@ -1,97 +0,0 @@
1
- # This configuration was generated by
2
- # `rubocop --auto-gen-config`
3
- # on 2017-11-29 16:15:16 -0500 using RuboCop version 0.51.0.
4
- # The point is for the user to remove these configuration records
5
- # one by one as the offenses are removed from the code base.
6
- # Note that changes in the inspected code, or installation of new
7
- # versions of RuboCop, may require this file to be generated again.
8
-
9
- # Offense count: 1
10
- # Cop supports --auto-correct.
11
- # Configuration parameters: Include, TreatCommentsAsGroupSeparators.
12
- # Include: **/*.gemspec
13
- Gemspec/OrderedDependencies:
14
- Exclude:
15
- - 'libyear-bundler.gemspec'
16
-
17
- # Offense count: 1
18
- # Cop supports --auto-correct.
19
- # Configuration parameters: EnforcedStyle, SupportedStyles.
20
- # SupportedStyles: leading, trailing
21
- Layout/DotPosition:
22
- Exclude:
23
- - 'spec/calculators/libyear_spec.rb'
24
-
25
- # Offense count: 1
26
- # Cop supports --auto-correct.
27
- Layout/EmptyLines:
28
- Exclude:
29
- - 'lib/libyear_bundler/cli.rb'
30
-
31
- # Offense count: 1
32
- # Cop supports --auto-correct.
33
- # Configuration parameters: EnforcedStyle, SupportedStyles.
34
- # SupportedStyles: auto_detection, squiggly, active_support, powerpack, unindent
35
- Layout/IndentHeredoc:
36
- Exclude:
37
- - 'lib/libyear_bundler/options.rb'
38
-
39
- # Offense count: 3
40
- # Configuration parameters: CountComments, ExcludedMethods.
41
- Metrics/BlockLength:
42
- Max: 40
43
-
44
- # Offense count: 1
45
- Metrics/ClassLength:
46
- Exclude:
47
- - 'lib/libyear_bundler/report.rb'
48
-
49
- # Offense count: 3
50
- # Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts, AllowedAcronyms.
51
- # AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS
52
- Naming/FileName:
53
- Exclude:
54
- - 'spec/gemfiles/Gemfile.bundler-1.14.rb'
55
- - 'spec/gemfiles/Gemfile.bundler-1.15.rb'
56
- - 'spec/gemfiles/Gemfile.bundler-1.16.rb'
57
-
58
- # Offense count: 1
59
- Style/Documentation:
60
- Exclude:
61
- - 'spec/**/*'
62
- - 'test/**/*'
63
-
64
- # Offense count: 1
65
- # Cop supports --auto-correct.
66
- Style/Encoding:
67
- Exclude:
68
- - 'libyear-bundler.gemspec'
69
-
70
- # Offense count: 1
71
- # Cop supports --auto-correct.
72
- Style/MutableConstant:
73
- Exclude:
74
- - 'lib/libyear_bundler/options.rb'
75
-
76
- # Offense count: 9
77
- # Cop supports --auto-correct.
78
- Style/StderrPuts:
79
- Exclude:
80
- - 'lib/libyear_bundler/bundle_outdated.rb'
81
- - 'lib/libyear_bundler/cli.rb'
82
- - 'lib/libyear_bundler/models/gem.rb'
83
-
84
- # Offense count: 2
85
- # Cop supports --auto-correct.
86
- # Configuration parameters: MinSize, SupportedStyles.
87
- # SupportedStyles: percent, brackets
88
- Style/SymbolArray:
89
- EnforcedStyle: brackets
90
-
91
- # Offense count: 1
92
- # Cop supports --auto-correct.
93
- # Configuration parameters: ExactNameMatch, AllowPredicates, AllowDSLWriters, IgnoreClassMethods, Whitelist.
94
- # Whitelist: to_ary, to_a, to_c, to_enum, to_h, to_hash, to_i, to_int, to_io, to_open, to_path, to_proc, to_r, to_regexp, to_str, to_s, to_sym
95
- Style/TrivialAccessors:
96
- Exclude:
97
- - 'lib/libyear_bundler/models/gem.rb'
data/.travis.yml DELETED
@@ -1,11 +0,0 @@
1
- cache: bundler
2
- language: ruby
3
- rvm:
4
- - 2.4.2
5
- - 2.3.5
6
- - 2.2.8
7
- - 2.1.10
8
- script:
9
- - bundle exec rubocop
10
- - bundle exec rspec
11
- sudo: false
data/CHANGELOG.md DELETED
@@ -1,130 +0,0 @@
1
- # libyear
2
-
3
- This project follows [semver 2.0.0][1] and the recommendations
4
- of [keepachangelog.com][2].
5
-
6
- ## Unreleased
7
-
8
- Breaking changes:
9
-
10
- - None
11
-
12
- Added:
13
-
14
- - None
15
-
16
- Fixed:
17
-
18
- - None
19
-
20
- ## 0.5.0 (2017-12-12)
21
-
22
- Breaking changes:
23
-
24
- - None
25
-
26
- Added:
27
-
28
- - [#10](https://github.com/jaredbeck/libyear-bundler/pull/10)
29
- Include Ruby version in metrics calculations
30
-
31
- Fixed:
32
-
33
- - None
34
-
35
- ## 0.4.0 (2017-07-07)
36
-
37
- Breaking changes:
38
-
39
- - None
40
-
41
- Added:
42
-
43
- - [#3](https://github.com/jaredbeck/libyear-bundler/pull/3)
44
- Add --versions and --releases
45
-
46
- Fixed:
47
-
48
- - None
49
-
50
- ## 0.3.0 (2017-03-24)
51
-
52
- Breaking changes:
53
-
54
- - None
55
-
56
- Added:
57
-
58
- - [#1](https://github.com/jaredbeck/libyear-bundler/pull/1)
59
- Add --grand-total option
60
-
61
- Fixed:
62
-
63
- - None
64
-
65
- ## 0.2.0 (2017-03-10)
66
-
67
- Breaking changes:
68
-
69
- - Rename project
70
- - Rename project from libyear-rb to libyear-bundler
71
- - Rename binary from libyear to libyear-bundler
72
- - Discussion: https://github.com/jaredbeck/libyear-rb/issues/1
73
-
74
- Added:
75
-
76
- - None
77
-
78
- Fixed:
79
-
80
- - None
81
-
82
- ## 0.1.3 (2017-03-07)
83
-
84
- Breaking changes:
85
-
86
- - None
87
-
88
- Added:
89
-
90
- - None
91
-
92
- Fixed:
93
-
94
- - Don't crash when Gemfile uses git
95
-
96
- ## 0.1.2 (2017-02-16)
97
-
98
- Breaking changes:
99
-
100
- - None
101
-
102
- Added:
103
-
104
- - None
105
-
106
- Fixed:
107
-
108
- - Better handling of weird sources like rails-assets
109
- - Wider report columns
110
-
111
- ## 0.1.1 (2017-02-14)
112
-
113
- Breaking changes:
114
-
115
- - None
116
-
117
- Added:
118
-
119
- - None
120
-
121
- Fixed:
122
-
123
- - Better handling of error when bundle outdated fails
124
-
125
- ## 0.1.0 (2017-02-13)
126
-
127
- Initial version. Proof of concept.
128
-
129
- [1]: http://semver.org/spec/v2.0.0.html
130
- [2]: http://keepachangelog.com/
data/CONTRIBUTING.md DELETED
@@ -1,24 +0,0 @@
1
- # Contributing Guide
2
-
3
- ## Development
4
-
5
- Pull requests are welcome.
6
-
7
- ```bash
8
- bundle install
9
- bundle exec rspec
10
- ```
11
-
12
- ## Releases
13
-
14
- 1. Set the version in `lib/libyear_bundler/version.rb`
15
- - Follow SEMVER
16
- - Only use integer-dot-integer-dot-integer format, never "pre-releases"
17
- 1. In the changelog,
18
- - Replace "Unreleased" with the date in ISO-8601 format
19
- - Add a new "Unreleased" section
20
- 1. Commit
21
- 1. git tag -a -m "v0.5.0" "v0.5.0" # or whatever number
22
- 1. git push --tags origin master
23
- 1. gem build libyear-bundler.gemspec
24
- 1. gem push libyear-bundler-0.5.0.gem
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in libyear.gemspec
4
- gemspec
data/README.md DELETED
@@ -1,134 +0,0 @@
1
- # Libyear
2
-
3
- A simple measure of dependency freshness for ruby apps.
4
-
5
- Applied to a whole Gemfile, `libyear-bundler` provides a single number for
6
- determining the maintenance burden of an app’s dependencies. It is a simple
7
- measure of the time between the release date of the installed dependency and the
8
- release date of the newest version of the dependency.
9
-
10
- The inspiration for libyear comes from the technical report “Measuring
11
- Dependency Freshness in Software Systems”[1]. Other metrics for determining
12
- dependency freshness outlined in the paper are available in libyear-bundler. See
13
- the Usage section for details.
14
-
15
- # Install
16
-
17
- ```bash
18
- gem install libyear-bundler
19
- ```
20
-
21
- ## Usage
22
-
23
- Run `libyear-bundler` in a directory with a Gemfile. Verbosity is on by default.
24
- For simpler output, see the `--grand-total` option.
25
-
26
- ### Options
27
-
28
- #### `--libyears` (default)
29
- Measures the time between your dependencies' installed and newest versions, in
30
- years.
31
-
32
- ```bash
33
- $ libyear-bundler Gemfile
34
- activesupport 4.2.7.1 2016-08-10 5.1.3 2017-08-03 1.0
35
- i18n 0.8.0 2017-01-31 0.8.6 2017-07-10 0.4
36
- json 1.8.6 2017-01-13 2.1.0 2017-04-18 0.3
37
- minitest 5.10.1 2016-12-02 5.10.3 2017-07-21 0.6
38
- minitest_to_rspec 0.6.0 2015-06-09 0.8.0 2017-01-02 1.6
39
- ruby_parser 3.8.4 2017-01-13 3.10.1 2017-07-21 0.5
40
- sexp_processor 4.8.0 2017-02-01 4.10.0 2017-07-17 0.5
41
- thread_safe 0.3.5 2015-03-11 0.3.6 2017-02-22 2.0
42
- tzinfo 1.2.2 2014-08-08 1.2.3 2017-03-25 2.6
43
- System is 9.4 libyears behind
44
-
45
- ```
46
-
47
- #### `--releases`
48
- Measures the number of releases between your dependencies' installed and newest
49
- versions
50
-
51
- ```bash
52
- $ libyear-bundler Gemfile --releases
53
- activesupport 4.2.7.1 2016-08-10 5.1.3 2017-08-03 37
54
- i18n 0.8.0 2017-01-31 0.8.6 2017-07-10 5
55
- json 1.8.6 2017-01-13 2.1.0 2017-04-18 12
56
- minitest 5.10.1 2016-12-02 5.10.3 2017-07-21 2
57
- minitest_to_rspec 0.6.0 2015-06-09 0.8.0 2017-01-02 5
58
- ruby_parser 3.8.4 2017-01-13 3.10.1 2017-07-21 3
59
- sexp_processor 4.8.0 2017-02-01 4.10.0 2017-07-17 3
60
- thread_safe 0.3.5 2015-03-11 0.3.6 2017-02-22 2
61
- tzinfo 1.2.2 2014-08-08 1.2.3 2017-03-25 1
62
- Total releases behind: 70
63
-
64
- ```
65
-
66
-
67
- #### `--versions`
68
- Measures the number of major, minor, and patch versions between your
69
- dependencies' installed and newest versions
70
-
71
- ```bash
72
- $ libyear-bundler Gemfile --versions
73
- activesupport 4.2.7.1 2016-08-10 5.1.3 2017-08-03 [1, 0, 0]
74
- i18n 0.8.0 2017-01-31 0.8.6 2017-07-10 [0, 0, 6]
75
- json 1.8.6 2017-01-13 2.1.0 2017-04-18 [1, 0, 0]
76
- minitest 5.10.1 2016-12-02 5.10.3 2017-07-21 [0, 0, 2]
77
- minitest_to_rspec 0.6.0 2015-06-09 0.8.0 2017-01-02 [0, 2, 0]
78
- ruby_parser 3.8.4 2017-01-13 3.10.1 2017-07-21 [0, 2, 0]
79
- sexp_processor 4.8.0 2017-02-01 4.10.0 2017-07-17 [0, 2, 0]
80
- thread_safe 0.3.5 2015-03-11 0.3.6 2017-02-22 [0, 0, 1]
81
- tzinfo 1.2.2 2014-08-08 1.2.3 2017-03-25 [0, 0, 1]
82
- Major, minor, patch versions behind: 2, 6, 10
83
-
84
- ```
85
-
86
- #### `--all`
87
- Returns relevant data for each outdated gem, including 'libyears', 'releases',
88
- and 'versions' metrics
89
-
90
- ```bash
91
- $ libyear-bundler Gemfile --all
92
- activesupport 4.2.7.1 2016-08-10 5.1.3 2017-08-03 1.0 37 [1, 0, 0]
93
- i18n 0.8.0 2017-01-31 0.8.6 2017-07-10 0.4 5 [0, 0, 6]
94
- json 1.8.6 2017-01-13 2.1.0 2017-04-18 0.3 12 [1, 0, 0]
95
- minitest 5.10.1 2016-12-02 5.10.3 2017-07-21 0.6 2 [0, 0, 2]
96
- minitest_to_rspec 0.6.0 2015-06-09 0.8.0 2017-01-02 1.6 5 [0, 2, 0]
97
- ruby_parser 3.8.4 2017-01-13 3.10.1 2017-07-21 0.5 3 [0, 2, 0]
98
- sexp_processor 4.8.0 2017-02-01 4.10.0 2017-07-17 0.5 3 [0, 2, 0]
99
- thread_safe 0.3.5 2015-03-11 0.3.6 2017-02-22 2.0 2 [0, 0, 1]
100
- tzinfo 1.2.2 2014-08-08 1.2.3 2017-03-25 2.6 1 [0, 0, 1]
101
- System is 9.4 libyears behind
102
- Total releases behind: 70
103
- Major, minor, patch versions behind: 2, 6, 10
104
- ```
105
-
106
- #### `--grand-total`
107
- With no other options, returns the grand-total of libyears. Used with other
108
- flags, returns the associated grand-total.
109
-
110
- ```bash
111
- $ libyear-bundler Gemfile --grand-total
112
- 9.4
113
-
114
- $ libyear-bundler Gemfile --releases --grand-total
115
- 70
116
-
117
- $ libyear-bundler Gemfile --versions --grand-total
118
- [2, 6, 10]
119
-
120
- $ libyear-bundler Gemfile --all --grand-total
121
- 9.4
122
- 70
123
- [2, 6, 10]
124
- ```
125
-
126
- ## Contributing
127
-
128
- See CONTRIBUTING.md
129
-
130
- ---
131
- [1] J. Cox, E. Bouwers, M. van Eekelen and J. Visser, Measuring Dependency
132
- Freshness in Software Systems. In Proceedings of the 37th International
133
- Conference on Software Engineering (ICSE 2015), May 2015
134
- https://ericbouwers.github.io/papers/icse15.pdf