libyear-bundler 0.4.0 → 0.5.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 +4 -4
- data/.rubocop.yml +19 -0
- data/.rubocop_todo.yml +97 -0
- data/.travis.yml +11 -0
- data/CHANGELOG.md +15 -0
- data/CONTRIBUTING.md +24 -0
- data/README.md +118 -14
- data/lib/libyear_bundler/{query.rb → bundle_outdated.rb} +9 -21
- data/lib/libyear_bundler/calculators/libyear.rb +18 -45
- data/lib/libyear_bundler/calculators/version_number_delta.rb +38 -36
- data/lib/libyear_bundler/calculators/version_sequence_delta.rb +9 -16
- data/lib/libyear_bundler/cli.rb +20 -33
- data/lib/libyear_bundler/models/gem.rb +104 -0
- data/lib/libyear_bundler/models/ruby.rb +139 -0
- data/lib/libyear_bundler/options.rb +63 -0
- data/lib/libyear_bundler/report.rb +73 -53
- data/lib/libyear_bundler/version.rb +1 -1
- data/libyear-bundler.gemspec +1 -0
- metadata +24 -5
- data/asd +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8ab149dc302594c069829c10cc93253a4a9165d2
|
4
|
+
data.tar.gz: 8f6a974c411bc9b72d799b137f715cd7c35260a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
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
|
-
|
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
|
-
|
8
|
-
|
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
|
-
|
11
|
-
|
15
|
+
# Install
|
16
|
+
|
17
|
+
```bash
|
18
|
+
gem install libyear-bundler
|
19
|
+
```
|
12
20
|
|
13
21
|
## Usage
|
14
22
|
|
15
|
-
|
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
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
14
|
+
def initialize(gemfile_path)
|
14
15
|
@gemfile_path = gemfile_path
|
15
|
-
@argv = argv
|
16
16
|
end
|
17
17
|
|
18
18
|
def execute
|
19
|
-
|
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
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
class
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
class
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
-
|
22
|
+
private
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
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
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
def version_delta(newest_version, installed_version)
|
31
|
+
delta = newest_version - installed_version
|
32
|
+
delta < 0 ? 0 : delta
|
33
|
+
end
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
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
|
data/lib/libyear_bundler/cli.rb
CHANGED
@@ -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
|
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 @
|
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
|
59
|
-
|
56
|
+
def bundle_outdated
|
57
|
+
BundleOutdated.new(@gemfile_path).execute
|
60
58
|
end
|
61
59
|
|
62
60
|
def report
|
63
|
-
@_report ||= Report.new(
|
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
|
76
|
-
|
77
|
-
|
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
|
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
|
80
|
+
elsif @options.releases?
|
94
81
|
releases_grand_total
|
95
|
-
elsif
|
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[:
|
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
|
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
|
9
|
-
|
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|
|
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
|
-
|
29
|
+
sum_libyears: 0.0
|
24
30
|
}
|
25
|
-
@gems.
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
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
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
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
|
68
|
+
def meta_line_summary(gem_or_ruby)
|
67
69
|
format(
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
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(
|
78
|
-
puts format("System is %.1f libyears behind",
|
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
|
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
|
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
|
111
|
+
elsif @options.releases?
|
110
112
|
put_sum_seq_delta_summary(summary[:sum_seq_delta])
|
111
|
-
|
112
|
-
put_libyear_summary(summary[:
|
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
|
data/libyear-bundler.gemspec
CHANGED
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
|
+
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-
|
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/
|
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.
|
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
|