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 +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
|