libyear-bundler 0.5.0 → 0.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
- 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