libyear-bundler 0.4.0 → 0.5.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
  SHA1:
3
- metadata.gz: 2bc00352e31430c9a27e420073d5284a343a840a
4
- data.tar.gz: 10d60b3b473df24f7a7a6140a22d4ed8bfe7f8a8
3
+ metadata.gz: 8ab149dc302594c069829c10cc93253a4a9165d2
4
+ data.tar.gz: 8f6a974c411bc9b72d799b137f715cd7c35260a1
5
5
  SHA512:
6
- metadata.gz: ec414ad1bb5b06517e6fa39fd7ebf1265a8ea42c36f1a9bf225d16bac46fcb61df3f97506725204bd3563b5425f02e28ff5e847bbfbdf8fcc0eaf1a06373be92
7
- data.tar.gz: 0e3f53fc0fa0a497abd545e4e91eaa1d82e399d54401cf982393c6db3ff3b28c248a20f4e9d68e8b08d68d3f27e6b4daff1e88ac9bb7e5e82c240eb00d8d2ca9
6
+ metadata.gz: 424dad3f3c7ef8e6f42cb406714ec080193ca59f4c3d55b7e38d631d0d0ac97a670e9db076c993a9a1c976e31dd47cbe08f3ccf32dc7466c20379fcdda6d1acd
7
+ data.tar.gz: aad230cd11ee0313b1d1bce97fa489b020c92fd15686deb9ecefa4ac96a9a2393cd27aa998edfd9983c66f4dd168c131752aae1d5c53fc4e273d8757c10beec2
data/.rubocop.yml CHANGED
@@ -1,11 +1,30 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
3
+ AllCops:
4
+ TargetRubyVersion: 2.1.10
5
+
1
6
  Metrics/AbcSize:
2
7
  Max: 27
3
8
 
9
+ Metrics/BlockLength:
10
+ Exclude:
11
+ - 'spec/**/*'
12
+
13
+ Metrics/ModuleLength:
14
+ Exclude:
15
+ - 'spec/**/*'
16
+
4
17
  Metrics/LineLength:
5
18
  Max: 100
6
19
 
7
20
  Metrics/MethodLength:
8
21
  Enabled: false
9
22
 
23
+ Style/IndentArray:
24
+ EnforcedStyle: consistent
25
+
26
+ Style/MultilineMethodCallIndentation:
27
+ EnforcedStyle: indented
28
+
10
29
  Style/StringLiterals:
11
30
  Enabled: false
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,97 @@
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 ADDED
@@ -0,0 +1,11 @@
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 CHANGED
@@ -17,6 +17,21 @@ Fixed:
17
17
 
18
18
  - None
19
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
+
20
35
  ## 0.4.0 (2017-07-07)
21
36
 
22
37
  Breaking changes:
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,24 @@
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/README.md CHANGED
@@ -2,29 +2,133 @@
2
2
 
3
3
  A simple measure of dependency freshness for ruby apps.
4
4
 
5
- A libyear (library year) is a measure of how old a software dependency is.
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.
6
9
 
7
- If your system has two dependencies, the first one year old, the second three,
8
- then your system is four libyears out-of-date.
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.
9
14
 
10
- A dependency is one year old when the version you are using is one year older
11
- than its latest version.
15
+ # Install
16
+
17
+ ```bash
18
+ gem install libyear-bundler
19
+ ```
12
20
 
13
21
  ## Usage
14
22
 
15
- Early access. Output and usage subject to change.
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
16
44
 
17
45
  ```
18
- gem install libyear-bundler
19
- libyear-bundler Gemfile
20
- activesupport 4.2.7.1 2016-08-10 5.0.1 2016-12-21 0.4
21
- json 1.8.6 2017-01-13 2.0.3 2017-01-12 0.0
22
- minitest_to_rspec 0.6.0 2015-06-09 0.8.0 2017-01-02 1.6
23
- System is 1.9 libyears behind
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
+
24
64
  ```
25
65
 
26
- ## Development
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
27
83
 
28
84
  ```
29
- ruby -I lib bin/libyear-bundler spec/fixtures/01/Gemfile
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
30
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
@@ -3,41 +3,29 @@ require "open3"
3
3
  require 'libyear_bundler/calculators/libyear'
4
4
  require 'libyear_bundler/calculators/version_number_delta'
5
5
  require 'libyear_bundler/calculators/version_sequence_delta'
6
+ require 'libyear_bundler/models/gem'
6
7
 
7
8
  module LibyearBundler
8
9
  # Responsible for getting all the data that goes into the `Report`.
9
- class Query
10
+ class BundleOutdated
10
11
  # Format of `bundle outdated --parseable` (BOP)
11
12
  BOP_FMT = /\A(?<name>[^ ]+) \(newest (?<newest>[^,]+), installed (?<installed>[^,)]+)/
12
13
 
13
- def initialize(gemfile_path, argv)
14
+ def initialize(gemfile_path)
14
15
  @gemfile_path = gemfile_path
15
- @argv = argv
16
16
  end
17
17
 
18
18
  def execute
19
- gems = []
20
- bundle_outdated.lines.each do |line|
19
+ bundle_outdated.lines.each_with_object([]) do |line, gems|
21
20
  match = BOP_FMT.match(line)
22
21
  next if match.nil?
23
- gems.push(
24
- installed: { version: match["installed"] },
25
- name: match["name"],
26
- newest: { version: match["newest"] }
22
+ gem = ::LibyearBundler::Models::Gem.new(
23
+ match['name'],
24
+ match['installed'],
25
+ match['newest']
27
26
  )
27
+ gems.push(gem)
28
28
  end
29
- gems.each do |gem|
30
- if @argv.include?("--versions") || @argv.include?("--all")
31
- gem[:version_number_delta] = ::Calculators::VersionNumberDelta.calculate(gem)
32
- end
33
-
34
- if @argv.include?("--releases") || @argv.include?("--all")
35
- gem[:version_sequence_delta] = ::Calculators::VersionSequenceDelta.calculate(gem)
36
- end
37
-
38
- gem[:libyears] = ::Calculators::Libyear.calculate(gem)
39
- end
40
- gems
41
29
  end
42
30
 
43
31
  private
@@ -1,49 +1,22 @@
1
- module Calculators
2
- # A libyear is the difference in time between releases of the newest and
3
- # installed versions of the gem in years
4
- class Libyear
5
- class << self
6
- def calculate(gem)
7
- di = release_date(gem[:name], gem[:installed][:version])
8
- dn = release_date(gem[:name], gem[:newest][:version])
9
- gem[:installed][:date] = di
10
- gem[:newest][:date] = dn
11
- if di.nil? || dn.nil? || dn <= di
12
- # Known issue: Backports and maintenance releases of older minor versions.
13
- # Example: json 1.8.6 (2017-01-13) was released *after* 2.0.3 (2017-01-12)
14
- years = 0.0
15
- else
16
- days = (dn - di).to_f
17
- years = days / 365.0
1
+ module LibyearBundler
2
+ module Calculators
3
+ # A libyear is the difference in time between releases of the newest and
4
+ # installed versions of the gem in years
5
+ class Libyear
6
+ class << self
7
+ def calculate(installed_version_release_date, newest_version_release_date)
8
+ di = installed_version_release_date
9
+ dn = newest_version_release_date
10
+ if di.nil? || dn.nil? || dn <= di
11
+ # Known issue: Backports and maintenance releases of older minor versions.
12
+ # Example: json 1.8.6 (2017-01-13) was released *after* 2.0.3 (2017-01-12)
13
+ years = 0.0
14
+ else
15
+ days = (dn - di).to_f
16
+ years = days / 365.0
17
+ end
18
+ years
18
19
  end
19
- years
20
- end
21
-
22
- private
23
-
24
- # Known issue: Probably performs a network request every time, unless
25
- # there's some kind of caching.
26
- def release_date(gem_name, gem_version)
27
- dep = nil
28
- begin
29
- dep = ::Bundler::Dependency.new(gem_name, gem_version)
30
- rescue ::Gem::Requirement::BadRequirementError => e
31
- $stderr.puts "Could not find release date for: #{gem_name}"
32
- $stderr.puts(e)
33
- $stderr.puts(
34
- "Maybe you used git in your Gemfile, which libyear doesn't support " \
35
- "yet. Contributions welcome."
36
- )
37
- return nil
38
- end
39
- tuples, _errors = ::Gem::SpecFetcher.fetcher.search_for_dependency(dep)
40
- if tuples.empty?
41
- $stderr.puts "Could not find release date for: #{gem_name}"
42
- return nil
43
- end
44
- tup, source = tuples.first # Gem::NameTuple
45
- spec = source.fetch_spec(tup) # raises Gem::RemoteFetcher::FetchError
46
- spec.date.to_date
47
20
  end
48
21
  end
49
22
  end
@@ -1,43 +1,45 @@
1
- module Calculators
2
- # The version number delta is the absolute difference between the highest-
3
- # order version number of the installed and newest releases
4
- class VersionNumberDelta
5
- class << self
6
- def calculate(gem)
7
- newest_version_tuple = version_tuple(gem[:newest][:version].split('.'))
8
- installed_version_tuple = version_tuple(gem[:installed][:version].split('.'))
9
- major_version_delta = version_delta(
10
- newest_version_tuple.major, installed_version_tuple.major
11
- )
12
- minor_version_delta = version_delta(
13
- newest_version_tuple.minor, installed_version_tuple.minor
14
- )
15
- patch_version_delta = version_delta(
16
- newest_version_tuple.patch, installed_version_tuple.patch
17
- )
18
- highest_order([major_version_delta, minor_version_delta, patch_version_delta])
19
- end
1
+ module LibyearBundler
2
+ module Calculators
3
+ # The version number delta is the absolute difference between the highest-
4
+ # order version number of the installed and newest releases
5
+ class VersionNumberDelta
6
+ class << self
7
+ def calculate(installed_version, newest_version)
8
+ installed_version_tuple = version_tuple(installed_version.to_s.split('.'))
9
+ newest_version_tuple = version_tuple(newest_version.to_s.split('.'))
10
+ major_version_delta = version_delta(
11
+ newest_version_tuple.major, installed_version_tuple.major
12
+ )
13
+ minor_version_delta = version_delta(
14
+ newest_version_tuple.minor, installed_version_tuple.minor
15
+ )
16
+ patch_version_delta = version_delta(
17
+ newest_version_tuple.patch, installed_version_tuple.patch
18
+ )
19
+ highest_order([major_version_delta, minor_version_delta, patch_version_delta])
20
+ end
20
21
 
21
- private
22
+ private
22
23
 
23
- def highest_order(arr)
24
- arr[1] = arr[2] = 0 if arr[0] > 0
25
- arr[2] = 0 if arr[1] > 0
26
- arr
27
- end
24
+ def highest_order(arr)
25
+ arr[1] = arr[2] = 0 if arr[0] > 0
26
+ arr[2] = 0 if arr[1] > 0
27
+ arr
28
+ end
28
29
 
29
- def version_delta(newest_version, installed_version)
30
- delta = newest_version - installed_version
31
- delta < 0 ? 0 : delta
32
- end
30
+ def version_delta(newest_version, installed_version)
31
+ delta = newest_version - installed_version
32
+ delta < 0 ? 0 : delta
33
+ end
33
34
 
34
- def version_tuple(version_array)
35
- version_struct = Struct.new(:major, :minor, :patch)
36
- version_struct.new(
37
- version_array[0].to_i,
38
- version_array[1].to_i,
39
- version_array[2].to_i
40
- )
35
+ def version_tuple(version_array)
36
+ version_struct = Struct.new(:major, :minor, :patch)
37
+ version_struct.new(
38
+ version_array[0].to_i,
39
+ version_array[1].to_i,
40
+ version_array[2].to_i
41
+ )
42
+ end
41
43
  end
42
44
  end
43
45
  end
@@ -1,19 +1,12 @@
1
- require 'net/http'
2
- require 'uri'
3
- require 'json'
4
-
5
- module Calculators
6
- # The version sequence delta is the number of releases between the newest and
7
- # installed versions of the gem
8
- class VersionSequenceDelta
9
- class << self
10
- def calculate(gem)
11
- uri = URI.parse("https://rubygems.org/api/v1/versions/#{gem[:name]}.json")
12
- response = Net::HTTP.get_response(uri)
13
- versions = JSON.parse(response.body).map { |version| version["number"] }
14
- newest_seq = versions.index(gem[:newest][:version])
15
- installed_seq = versions.index(gem[:installed][:version])
16
- installed_seq - newest_seq
1
+ module LibyearBundler
2
+ module Calculators
3
+ # The version sequence delta is the number of releases between the newest and
4
+ # installed versions of the gem
5
+ class VersionSequenceDelta
6
+ class << self
7
+ def calculate(installed_seq_index, newest_seq_index)
8
+ installed_seq_index - newest_seq_index
9
+ end
17
10
  end
18
11
  end
19
12
  end
@@ -1,30 +1,28 @@
1
1
  require "bundler/cli"
2
2
  require "bundler/cli/outdated"
3
+ require "libyear_bundler/bundle_outdated"
4
+ require "libyear_bundler/options"
3
5
  require "libyear_bundler/report"
4
- require "libyear_bundler/query"
6
+ require 'libyear_bundler/models/ruby'
5
7
 
6
8
  module LibyearBundler
7
9
  # The `libyear-bundler` command line program
8
10
  class CLI
9
- OPTIONS = %w[
10
- --all
11
- --grand-total
12
- --libyears
13
- --releases
14
- --versions
15
- ].freeze
16
-
17
11
  E_BUNDLE_OUTDATED_FAILED = 1
18
12
  E_NO_GEMFILE = 2
13
+ E_INVALID_CLI_ARG = 3
19
14
 
20
15
  def initialize(argv)
16
+ @options = ::LibyearBundler::Options.new(argv).parse
17
+ # Command line flags are removed form `argv` in `Options` by
18
+ # `OptionParser`, leaving non-flag command line arguments,
19
+ # such as a Gemfile path
21
20
  @argv = argv
22
21
  @gemfile_path = load_gemfile_path
23
- validate_arguments
24
22
  end
25
23
 
26
24
  def run
27
- if @argv.include?("--grand-total")
25
+ if @options.grand_total?
28
26
  grand_total
29
27
  else
30
28
  print report.to_s
@@ -51,32 +49,21 @@ module LibyearBundler
51
49
  '' # `bundle outdated` will default to local Gemfile
52
50
  else
53
51
  $stderr.puts "Gemfile not found"
54
- exit
52
+ exit E_NO_GEMFILE
55
53
  end
56
54
  end
57
55
 
58
- def query
59
- Query.new(@gemfile_path, @argv).execute
56
+ def bundle_outdated
57
+ BundleOutdated.new(@gemfile_path).execute
60
58
  end
61
59
 
62
60
  def report
63
- @_report ||= Report.new(query)
64
- end
65
-
66
- def unexpected_options
67
- @_unexpected_options ||= begin
68
- options = @argv.select { |arg| arg.start_with?("--") }
69
- options.each_with_object([]) do |arg, memo|
70
- memo << arg unless OPTIONS.include?(arg)
71
- end
72
- end
61
+ @_report ||= Report.new(bundle_outdated, ruby, @options)
73
62
  end
74
63
 
75
- def validate_arguments
76
- return if unexpected_options.empty?
77
- puts "Unexpected args: #{unexpected_options.join(', ')}"
78
- puts "Allowed args: #{OPTIONS.join(', ')}"
79
- exit E_NO_GEMFILE
64
+ def ruby
65
+ lockfile = @gemfile_path + '.lock'
66
+ ::LibyearBundler::Models::Ruby.new(lockfile)
80
67
  end
81
68
 
82
69
  def grand_total
@@ -84,15 +71,15 @@ module LibyearBundler
84
71
  end
85
72
 
86
73
  def calculate_grand_total
87
- if report.to_h.key?(:sum_seq_delta) && report.to_h.key?(:sum_major_version)
74
+ if [:libyears?, :releases?, :versions?].all? { |opt| @options[opt] }
88
75
  [
89
76
  libyears_grand_total,
90
77
  releases_grand_total,
91
78
  versions_grand_total
92
79
  ].join("\n")
93
- elsif report.to_h.key?(:sum_seq_delta)
80
+ elsif @options.releases?
94
81
  releases_grand_total
95
- elsif report.to_h.key?(:sum_major_version)
82
+ elsif @options.versions?
96
83
  versions_grand_total
97
84
  else
98
85
  libyears_grand_total
@@ -100,7 +87,7 @@ module LibyearBundler
100
87
  end
101
88
 
102
89
  def libyears_grand_total
103
- report.to_h[:sum_years].truncate(1)
90
+ report.to_h[:sum_libyears].truncate(1)
104
91
  end
105
92
 
106
93
  def releases_grand_total
@@ -0,0 +1,104 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+ require 'json'
4
+
5
+ module LibyearBundler
6
+ module Models
7
+ # Logic and information pertaining to the installed and newest versions of
8
+ # a gem
9
+ class Gem
10
+ def initialize(name, installed_version, newest_version)
11
+ @name = name
12
+ @installed_version = installed_version
13
+ @newest_version = newest_version
14
+ end
15
+
16
+ def installed_version
17
+ ::Gem::Version.new(@installed_version)
18
+ end
19
+
20
+ def installed_version_release_date
21
+ release_date(name, installed_version)
22
+ end
23
+
24
+ def installed_version_sequence_index
25
+ versions_sequence.index(installed_version.to_s)
26
+ end
27
+
28
+ def libyears
29
+ ::LibyearBundler::Calculators::Libyear.calculate(
30
+ installed_version_release_date,
31
+ newest_version_release_date
32
+ )
33
+ end
34
+
35
+ def name
36
+ @name
37
+ end
38
+
39
+ def newest_version
40
+ ::Gem::Version.new(@newest_version)
41
+ end
42
+
43
+ def newest_version_sequence_index
44
+ versions_sequence.index(newest_version.to_s)
45
+ end
46
+
47
+ def newest_version_release_date
48
+ release_date(name, newest_version)
49
+ end
50
+
51
+ def version_number_delta
52
+ ::LibyearBundler::Calculators::VersionNumberDelta.calculate(
53
+ installed_version,
54
+ newest_version
55
+ )
56
+ end
57
+
58
+ def version_sequence_delta
59
+ ::LibyearBundler::Calculators::VersionSequenceDelta.calculate(
60
+ installed_version_sequence_index,
61
+ newest_version_sequence_index
62
+ )
63
+ end
64
+
65
+ private
66
+
67
+ # docs: http://guides.rubygems.org/rubygems-org-api/#gem-version-methods
68
+ # Versions are returned ordered by version number, descending
69
+ def versions_sequence
70
+ @_versions_sequence ||= begin
71
+ uri = URI.parse("https://rubygems.org/api/v1/versions/#{name}.json")
72
+ response = Net::HTTP.get_response(uri)
73
+ parsed_response = JSON.parse(response.body)
74
+ parsed_response.map { |version| version['number'] }
75
+ end
76
+ 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
+ end
103
+ end
104
+ end
@@ -0,0 +1,139 @@
1
+ require 'bundler/lockfile_parser'
2
+ require 'bundler/ruby_version'
3
+ require 'date'
4
+ require 'net/http'
5
+ require 'yaml'
6
+
7
+ require 'libyear_bundler/calculators/libyear'
8
+ require 'libyear_bundler/calculators/version_number_delta'
9
+ require 'libyear_bundler/calculators/version_sequence_delta'
10
+
11
+ module LibyearBundler
12
+ module Models
13
+ # Logic and information pertaining to the installed and newest Ruby versions
14
+ class Ruby
15
+ RUBY_VERSION_DATA_URL = "https://raw.githubusercontent.com/ruby/" \
16
+ "www.ruby-lang.org/master/_data/releases.yml".freeze
17
+
18
+ def initialize(lockfile)
19
+ @lockfile = lockfile
20
+ end
21
+
22
+ def installed_version
23
+ @_installed_version ||= begin
24
+ version_from_bundler ||
25
+ version_from_ruby_version_file ||
26
+ version_from_ruby
27
+ end
28
+ end
29
+
30
+ def installed_version_release_date
31
+ release_date(installed_version.to_s)
32
+ end
33
+
34
+ def libyears
35
+ ::LibyearBundler::Calculators::Libyear.calculate(
36
+ release_date(installed_version.to_s),
37
+ release_date(newest_version.to_s)
38
+ )
39
+ end
40
+
41
+ def name
42
+ 'ruby'
43
+ end
44
+
45
+ def newest_version
46
+ ::Gem::Version.new(all_versions.first['version'])
47
+ end
48
+
49
+ def newest_version_release_date
50
+ release_date(newest_version.to_s)
51
+ end
52
+
53
+ def outdated?
54
+ installed_version < newest_version
55
+ end
56
+
57
+ def version_number_delta
58
+ ::LibyearBundler::Calculators::VersionNumberDelta.calculate(
59
+ installed_version,
60
+ newest_version
61
+ )
62
+ end
63
+
64
+ def version_sequence_delta
65
+ ::LibyearBundler::Calculators::VersionSequenceDelta.calculate(
66
+ installed_version_sequence_index,
67
+ newest_version_sequence_index
68
+ )
69
+ end
70
+
71
+ private
72
+
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
+ 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']
109
+ end
110
+
111
+ def shell_out_to_ruby
112
+ `ruby --version`.split[1]
113
+ end
114
+
115
+ def version_from_bundler
116
+ return unless File.exist?(@lockfile)
117
+ ruby_version_string = ::Bundler::LockfileParser
118
+ .new(@lockfile)
119
+ .ruby_version
120
+ return if ruby_version_string.nil?
121
+
122
+ ::Bundler::RubyVersion.from_string(ruby_version_string).gem_version
123
+ end
124
+
125
+ def version_from_ruby_version_file
126
+ return unless ::File.exist?('.ruby-version')
127
+ ::Gem::Version.new(::File.read('.ruby-version').strip)
128
+ end
129
+
130
+ def version_from_ruby
131
+ ::Gem::Version.new(shell_out_to_ruby)
132
+ end
133
+
134
+ def versions_sequence
135
+ all_versions.map { |version| version['version'] }
136
+ end
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,63 @@
1
+ require 'optparse'
2
+ require 'libyear_bundler/version'
3
+ require "libyear_bundler/cli"
4
+ require 'ostruct'
5
+
6
+ module LibyearBundler
7
+ # Uses OptionParser from Ruby's stdlib to hand command-line arguments
8
+ class Options
9
+ BANNER = <<-BANNER.freeze
10
+ Usage: libyear-bundler [Gemfile ...] [options]
11
+ https://github.com/jaredbeck/libyear-bundler/
12
+ BANNER
13
+
14
+ def initialize(argv)
15
+ @argv = argv
16
+ @options = ::OpenStruct.new
17
+ @optparser = OptionParser.new do |opts|
18
+ opts.banner = BANNER
19
+ opts.program_name = 'libyear-bundler'
20
+ opts.version = ::LibyearBundler::VERSION
21
+ @options.send('libyears?=', true)
22
+
23
+ opts.on_head('-h', '--help', 'Prints this help') do
24
+ puts opts
25
+ exit
26
+ end
27
+
28
+ opts.on('--all', 'Calculate all metrics') do
29
+ @options.send('libyears?=', true)
30
+ @options.send('releases?=', true)
31
+ @options.send('versions?=', true)
32
+ end
33
+
34
+ opts.on('--libyears', '[default] Calculate libyears out-of-date') do
35
+ @options.send('libyears?=', true)
36
+ end
37
+
38
+ opts.on('--releases', 'Calculate number of releases out-of-date') do
39
+ @options.send('libyears?=', false)
40
+ @options.send('releases?=', true)
41
+ end
42
+
43
+ opts.on('--versions', 'Calculate major, minor, and patch versions out-of-date') do
44
+ @options.send('libyears?=', false)
45
+ @options.send('versions?=', true)
46
+ end
47
+
48
+ opts.on('--grand-total', 'Return value for given metric(s)') do
49
+ @options.send('grand_total?=', true)
50
+ end
51
+ end
52
+ end
53
+
54
+ def parse
55
+ @optparser.parse!(@argv)
56
+ @options
57
+ rescue OptionParser::InvalidOption => e
58
+ warn e
59
+ warn @optparser.help
60
+ exit ::LibyearBundler::CLI::E_INVALID_CLI_ARG
61
+ end
62
+ end
63
+ end
@@ -1,17 +1,23 @@
1
1
  module LibyearBundler
2
- # Responsible presenting data from the `Query`. Should only be concerned
3
- # with presentation, nothing else.
2
+ # Responsible presenting data from the `::LibyearBundler::Models`. Should only
3
+ # be concerned with presentation, nothing else.
4
4
  class Report
5
+ FMT_LIBYEARS_COLUMN = "%10.1f".freeze
5
6
  FMT_RELEASES_COLUMN = "%10d".freeze
6
7
  FMT_VERSIONS_COLUMN = "%15s".freeze
8
+ FMT_SUMMARY_COLUMNS = "%30s%15s%15s%15s%15s".freeze
7
9
 
8
- # `gems` - Array of hashes.
9
- def initialize(gems)
10
+ # `gems` - Array of `::LibyearBundler::Models::Gem` instances
11
+ # `options` - Instance of `::LibyearBundler::Options`
12
+ def initialize(gems, ruby, options)
10
13
  @gems = gems
14
+ @ruby = ruby
15
+ @options = options
11
16
  end
12
17
 
13
18
  def to_s
14
- to_h[:gems].each { |gem| put_gem_summary(gem) }
19
+ to_h[:gems].each { |gem| put_line_summary(gem) }
20
+ put_line_summary(@ruby) if @ruby.outdated?
15
21
  put_summary(to_h)
16
22
  end
17
23
 
@@ -20,62 +26,58 @@ module LibyearBundler
20
26
  begin
21
27
  summary = {
22
28
  gems: @gems,
23
- sum_years: 0.0
29
+ sum_libyears: 0.0
24
30
  }
25
- @gems.each_with_object(summary) do |gem, memo|
26
- memo[:sum_years] += gem[:libyears]
27
-
28
- if gem.key?(:version_number_delta)
29
- memo[:sum_major_version] ||= 0
30
- memo[:sum_major_version] += gem[:version_number_delta][0]
31
- memo[:sum_minor_version] ||= 0
32
- memo[:sum_minor_version] += gem[:version_number_delta][1]
33
- memo[:sum_patch_version] ||= 0
34
- memo[:sum_patch_version] += gem[:version_number_delta][2]
35
- end
36
-
37
- if gem.key?(:version_sequence_delta)
38
- memo[:sum_seq_delta] ||= 0
39
- memo[:sum_seq_delta] += gem[:version_sequence_delta]
40
- end
41
- end
31
+ @gems.each { |gem| increment_metrics_summary(gem, summary) }
32
+
33
+ increment_metrics_summary(@ruby, summary) if @ruby.outdated?
34
+
35
+ summary
42
36
  end
43
37
  end
44
38
 
45
39
  private
46
40
 
47
- def put_gem_summary(gem)
48
- meta = meta_gem_summary(gem)
49
- libyear = format("%10.1f", gem[:libyears])
50
-
51
- if gem.key?(:version_sequence_delta) && gem.key?(:version_number_delta)
52
- releases = format(FMT_RELEASES_COLUMN, gem[:version_sequence_delta])
53
- versions = format(FMT_VERSIONS_COLUMN, gem[:version_number_delta])
54
- puts meta << libyear << releases << versions
55
- elsif gem.key?(:version_sequence_delta)
56
- releases = format(FMT_RELEASES_COLUMN, gem[:version_sequence_delta])
57
- puts meta << releases
58
- elsif gem.key?(:version_number_delta)
59
- versions = format(FMT_VERSIONS_COLUMN, gem[:version_number_delta])
60
- puts meta << versions
61
- else
62
- puts meta << libyear
41
+ def increment_metrics_summary(model, summary)
42
+ increment_libyears(model, summary) if @options.libyears?
43
+ increment_version_deltas(model, summary) if @options.versions?
44
+ increment_seq_deltas(model, summary) if @options.releases?
45
+ end
46
+
47
+ def put_line_summary(gem_or_ruby)
48
+ meta = meta_line_summary(gem_or_ruby)
49
+
50
+ if @options.releases?
51
+ releases = format(FMT_RELEASES_COLUMN, gem_or_ruby.version_sequence_delta)
52
+ meta << releases
53
+ end
54
+
55
+ if @options.versions?
56
+ versions = format(FMT_VERSIONS_COLUMN, gem_or_ruby.version_number_delta)
57
+ meta << versions
58
+ end
59
+
60
+ if @options.libyears?
61
+ libyears = format(FMT_LIBYEARS_COLUMN, gem_or_ruby.libyears)
62
+ meta << libyears
63
63
  end
64
+
65
+ puts meta
64
66
  end
65
67
 
66
- def meta_gem_summary(gem)
68
+ def meta_line_summary(gem_or_ruby)
67
69
  format(
68
- "%30s%15s%15s%15s%15s",
69
- gem[:name],
70
- gem[:installed][:version],
71
- gem[:installed][:date],
72
- gem[:newest][:version],
73
- gem[:newest][:date]
70
+ FMT_SUMMARY_COLUMNS,
71
+ gem_or_ruby.name,
72
+ gem_or_ruby.installed_version.to_s,
73
+ gem_or_ruby.installed_version_release_date,
74
+ gem_or_ruby.newest_version.to_s,
75
+ gem_or_ruby.newest_version_release_date
74
76
  )
75
77
  end
76
78
 
77
- def put_libyear_summary(sum_years)
78
- puts format("System is %.1f libyears behind", sum_years)
79
+ def put_libyear_summary(sum_libyears)
80
+ puts format("System is %.1f libyears behind", sum_libyears)
79
81
  end
80
82
 
81
83
  def put_version_delta_summary(sum_major_version, sum_minor_version, sum_patch_version)
@@ -92,7 +94,7 @@ module LibyearBundler
92
94
  end
93
95
 
94
96
  def put_summary(summary)
95
- if summary.key?(:sum_seq_delta) && summary.key?(:sum_major_version)
97
+ if [:libyears?, :releases?, :versions?].all? { |opt| @options.send(opt) }
96
98
  put_libyear_summary(summary[:sum_years])
97
99
  put_sum_seq_delta_summary(summary[:sum_seq_delta])
98
100
  put_version_delta_summary(
@@ -100,17 +102,35 @@ module LibyearBundler
100
102
  summary[:sum_minor_version],
101
103
  summary[:sum_patch_version]
102
104
  )
103
- elsif summary.key?(:sum_major_version)
105
+ elsif @options.versions?
104
106
  put_version_delta_summary(
105
107
  summary[:sum_major_version],
106
108
  summary[:sum_minor_version],
107
109
  summary[:sum_patch_version]
108
110
  )
109
- elsif summary.key?(:sum_seq_delta)
111
+ elsif @options.releases?
110
112
  put_sum_seq_delta_summary(summary[:sum_seq_delta])
111
- else
112
- put_libyear_summary(summary[:sum_years])
113
+ elsif @options.libyears?
114
+ put_libyear_summary(summary[:sum_libyears])
113
115
  end
114
116
  end
117
+
118
+ def increment_libyears(model, memo)
119
+ memo[:sum_libyears] += model.libyears
120
+ end
121
+
122
+ def increment_seq_deltas(model, memo)
123
+ memo[:sum_seq_delta] ||= 0
124
+ memo[:sum_seq_delta] += model.version_sequence_delta
125
+ end
126
+
127
+ def increment_version_deltas(model, memo)
128
+ memo[:sum_major_version] ||= 0
129
+ memo[:sum_major_version] += model.version_number_delta[0]
130
+ memo[:sum_minor_version] ||= 0
131
+ memo[:sum_minor_version] += model.version_number_delta[1]
132
+ memo[:sum_patch_version] ||= 0
133
+ memo[:sum_patch_version] += model.version_number_delta[2]
134
+ end
115
135
  end
116
136
  end
@@ -1,3 +1,3 @@
1
1
  module LibyearBundler
2
- VERSION = "0.4.0".freeze
2
+ VERSION = "0.5.0".freeze
3
3
  end
@@ -21,4 +21,5 @@ Gem::Specification.new do |spec|
21
21
  spec.required_ruby_version = ">= 2.1"
22
22
  spec.add_dependency "bundler", "~> 1.14"
23
23
  spec.add_development_dependency "rubocop"
24
+ spec.add_development_dependency "rspec"
24
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: libyear-bundler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.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-07-07 00:00:00.000000000 Z
11
+ date: 2017-12-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  description:
42
56
  email:
43
57
  - jared@jaredbeck.com
@@ -48,18 +62,23 @@ extra_rdoc_files: []
48
62
  files:
49
63
  - ".gitignore"
50
64
  - ".rubocop.yml"
65
+ - ".rubocop_todo.yml"
66
+ - ".travis.yml"
51
67
  - CHANGELOG.md
68
+ - CONTRIBUTING.md
52
69
  - Gemfile
53
70
  - LICENSE.txt
54
71
  - README.md
55
- - asd
56
72
  - bin/libyear-bundler
57
73
  - lib/libyear_bundler.rb
74
+ - lib/libyear_bundler/bundle_outdated.rb
58
75
  - lib/libyear_bundler/calculators/libyear.rb
59
76
  - lib/libyear_bundler/calculators/version_number_delta.rb
60
77
  - lib/libyear_bundler/calculators/version_sequence_delta.rb
61
78
  - lib/libyear_bundler/cli.rb
62
- - lib/libyear_bundler/query.rb
79
+ - lib/libyear_bundler/models/gem.rb
80
+ - lib/libyear_bundler/models/ruby.rb
81
+ - lib/libyear_bundler/options.rb
63
82
  - lib/libyear_bundler/report.rb
64
83
  - lib/libyear_bundler/version.rb
65
84
  - libyear-bundler.gemspec
@@ -83,7 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
102
  version: '0'
84
103
  requirements: []
85
104
  rubyforge_project:
86
- rubygems_version: 2.6.12
105
+ rubygems_version: 2.6.13
87
106
  signing_key:
88
107
  specification_version: 4
89
108
  summary: A simple measure of dependency freshness
data/asd DELETED
File without changes