end_of_life 0.2.0 → 0.4.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/.tool-versions +1 -1
- data/CHANGELOG.md +124 -2
- data/Gemfile +7 -4
- data/Gemfile.lock +122 -86
- data/README.md +26 -7
- data/Rakefile +2 -1
- data/end_of_life.gemspec +4 -3
- data/lib/end_of_life/cli.rb +79 -0
- data/lib/end_of_life/options.rb +59 -0
- data/lib/end_of_life/repository.rb +44 -25
- data/lib/end_of_life/ruby_version.rb +37 -12
- data/lib/end_of_life/version.rb +1 -1
- data/lib/end_of_life.json +96 -11
- data/lib/end_of_life.rb +5 -101
- metadata +29 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 613932e8ff35287b6f1cfd47f892ec07842432a48a86de9586daafe7c7fe2e4a
|
4
|
+
data.tar.gz: a8d47ebdc3838394b2dae1c86b39f02e0eb59c727fd878e956d849873ff7f1f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3919afb9fce45df1d650605e05cd401fd1281f7d17bf4df56e8bc33245df04e70184ed834ba7f09d25cb88f3b6c62448170dfd40d9b38cb3e09b048417aecc4f
|
7
|
+
data.tar.gz: 792c5b7483671ea6b0a952ad3736c52046c95bf8b8d030082ff5270a0c0bf9a3af0f6937b02f015c63c32881bd8a9b8d4e0fe97e3ee29d8868299344cd3f7d99
|
data/.tool-versions
CHANGED
@@ -1 +1 @@
|
|
1
|
-
ruby 3.
|
1
|
+
ruby 3.4.2
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,123 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.4.0] - 2025-05-23
|
4
|
+
|
5
|
+
- Skip archived repos (by default)
|
6
|
+
|
7
|
+
It's possible to include them with the `--include-archived` flag.
|
8
|
+
|
9
|
+
- Sort repositories by most recently updated
|
10
|
+
|
11
|
+
These are likely the ones one cares more about.
|
12
|
+
|
13
|
+
- Require Ruby >= 3.2.0
|
14
|
+
|
15
|
+
## [0.3.0]
|
16
|
+
|
17
|
+
### Added
|
18
|
+
|
19
|
+
- Allow excluding repositories from search. Due to a [limitation] on GitHub's API,
|
20
|
+
it's only possible to exclude up to five words.
|
21
|
+
|
22
|
+
```sh
|
23
|
+
$ end_of_life --exclude=repo1,repo2
|
24
|
+
```
|
25
|
+
|
26
|
+
[limitation]: https://docs.github.com/en/search-github/getting-started-with-searching-on-github/troubleshooting-search-queries#limitations-on-query-length
|
27
|
+
|
28
|
+
- Allow specifying the repo visibility on search:
|
29
|
+
|
30
|
+
```sh
|
31
|
+
$ end_of_life --public-only
|
32
|
+
# or
|
33
|
+
$ end_of_life --private-only
|
34
|
+
```
|
35
|
+
|
36
|
+
- Allow searching repositories inside organizations
|
37
|
+
|
38
|
+
```sh
|
39
|
+
$ end_of_life --org org1
|
40
|
+
|
41
|
+
# It's also possible to search on multiple organizations
|
42
|
+
$ end_of_life --org org1,org2
|
43
|
+
```
|
44
|
+
|
45
|
+
- Fetch EOL Ruby versions from endoflife.date API. This ensures we always use up-to-date data but keep the embedded JSON as a fallback.
|
46
|
+
|
47
|
+
- Allow users to specify the maximum number of days away a version can be from EOL. It defaults to 0.
|
48
|
+
|
49
|
+
```sh
|
50
|
+
$ end_of_life --max-eol-days-away 90
|
51
|
+
```
|
52
|
+
|
53
|
+
- Add search methods to RubyVersion
|
54
|
+
|
55
|
+
It's possible to query all EOL versions, or the latest one at any given time.
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
EndOfLife::RubyVersion.eol_versions_at(Date.today)
|
59
|
+
# =>
|
60
|
+
# [#<EndOfLife::RubyVersion:0x00007f9b1300d858
|
61
|
+
# @eol_date=#<Date: 2021-03-31 ((2459305j,0s,0n),+0s,2299161j)>,
|
62
|
+
# @version=Gem::Version.new("2.5.9")>,
|
63
|
+
# #<EndOfLife::RubyVersion:0x00007f9b1300cea8
|
64
|
+
# @eol_date=#<Date: 2020-03-31 ((2458940j,0s,0n),+0s,2299161j)>,
|
65
|
+
# @version=Gem::Version.new("2.4.10")>,
|
66
|
+
# #<EndOfLife::RubyVersion:0x00007f9b1300cb10
|
67
|
+
# @eol_date=#<Date: 2019-03-31 ((2458574j,0s,0n),+0s,2299161j)>,
|
68
|
+
# @version=Gem::Version.new("2.3.8")>,
|
69
|
+
# #<EndOfLife::RubyVersion:0x00007f9b1300c5e8
|
70
|
+
# @eol_date=#<Date: 2018-03-31 ((2458209j,0s,0n),+0s,2299161j)>,
|
71
|
+
# @version=Gem::Version.new("2.2.10")>,
|
72
|
+
# #<EndOfLife::RubyVersion:0x00007f9b1300c020
|
73
|
+
# @eol_date=#<Date: 2017-03-31 ((2457844j,0s,0n),+0s,2299161j)>,
|
74
|
+
# @version=Gem::Version.new("2.1.10")>,
|
75
|
+
# #<EndOfLife::RubyVersion:0x00007f9b112efbb8
|
76
|
+
# @eol_date=#<Date: 2016-02-24 ((2457443j,0s,0n),+0s,2299161j)>,
|
77
|
+
# @version=Gem::Version.new("2.0.0.pre.p648")>,
|
78
|
+
# #<EndOfLife::RubyVersion:0x00007f9b112ef028
|
79
|
+
# @eol_date=#<Date: 2015-02-23 ((2457077j,0s,0n),+0s,2299161j)>,
|
80
|
+
# @version=Gem::Version.new("1.9.3.pre.p551")>]
|
81
|
+
|
82
|
+
EndOfLife::RubyVersion.latest_eol # returns today's latest EOL version
|
83
|
+
# =>
|
84
|
+
# #<EndOfLife::RubyVersion:0x00007f9b1300d858
|
85
|
+
# @eol_date=#<Date: 2021-03-31 ((2459305j,0s,0n),+0s,2299161j)>,
|
86
|
+
# @version=Gem::Version.new("2.5.9")>
|
87
|
+
|
88
|
+
# returns the latest EOL version at a given date
|
89
|
+
EndOfLife::RubyVersion.latest_eol(at: Date.parse("2024-03-31"))
|
90
|
+
# =>
|
91
|
+
# #<EndOfLife::RubyVersion:0x00007f9b1300e7d0
|
92
|
+
# @eol_date=#<Date: 2024-03-31 ((2460401j,0s,0n),+0s,2299161j)>,
|
93
|
+
# @version=Gem::Version.new("3.0.3")>
|
94
|
+
|
95
|
+
EndOfLife::RubyVersion.new("3.0.0").eol?
|
96
|
+
# => false
|
97
|
+
|
98
|
+
EndOfLife::RubyVersion.new("3.0.0").eol?(at: Date.parse("2024-03-31"))
|
99
|
+
# => true
|
100
|
+
```
|
101
|
+
|
102
|
+
- Using the methods above, we can check whether a Repository is using EOL Ruby versions.
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
# repo with Ruby 3.0 (which is not EOL today)
|
106
|
+
repo.eol_ruby?
|
107
|
+
# => false
|
108
|
+
|
109
|
+
repo.eol_ruby?(at: Date.parse("2024.04.04"))
|
110
|
+
# => true
|
111
|
+
```
|
112
|
+
|
113
|
+
### Changed
|
114
|
+
|
115
|
+
- `EndOfLife::RubyVersion::EOL` constant was removed in favor of `EndOfLife::RubyVersion.latest_eol` method.
|
116
|
+
|
117
|
+
---
|
118
|
+
|
119
|
+
## [0.2.0]
|
120
|
+
|
3
121
|
### Added
|
4
122
|
|
5
123
|
- Allow searching a specific repository.
|
@@ -24,15 +142,19 @@ $ end_of_life --user=matz # searches on matz's repositories
|
|
24
142
|
|
25
143
|
### Changed
|
26
144
|
|
145
|
+
- Remove the 100 repo limit on GitHub API [#13](https://github.com/MatheusRich/end_of_life/pull/13)
|
146
|
+
|
27
147
|
- Exit with -1 if EOL repos are present.
|
28
148
|
|
29
149
|
- Upgrade `octokit` to v4.22, which fixes [a Faraday warning], so we can remove the dependency on the `warning` gem.
|
30
150
|
|
31
151
|
[a faraday warning]: https://github.com/octokit/octokit.rb/pull/1359
|
32
152
|
|
33
|
-
## [0.1.0]
|
153
|
+
## [0.1.0]
|
34
154
|
|
35
155
|
- Initial release
|
36
156
|
|
37
|
-
[unreleased]: https://github.com/MatheusRich/end_of_life/compare/v0.
|
157
|
+
[unreleased]: https://github.com/MatheusRich/end_of_life/compare/v0.3.0...HEAD
|
158
|
+
[0.3.0]: https://github.com/MatheusRich/end_of_life/releases/tag/v0.3.0
|
159
|
+
[0.2.0]: https://github.com/MatheusRich/end_of_life/releases/tag/v0.2.0
|
38
160
|
[0.1.0]: https://github.com/MatheusRich/end_of_life/releases/tag/v0.1.0
|
data/Gemfile
CHANGED
@@ -5,8 +5,11 @@ source "https://rubygems.org"
|
|
5
5
|
# Specify your gem's dependencies in end_of_life.gemspec
|
6
6
|
gemspec
|
7
7
|
|
8
|
-
gem "climate_control", "~> 1.0
|
8
|
+
gem "climate_control", "~> 1.0"
|
9
9
|
gem "rake", "~> 13.0"
|
10
|
-
gem "rspec", "~> 3.
|
11
|
-
gem "
|
12
|
-
gem "
|
10
|
+
gem "rspec", "~> 3.10"
|
11
|
+
gem "rspec-mocks", "~> 3.10"
|
12
|
+
gem "simplecov", "~> 0.22.0"
|
13
|
+
gem "standard", "~> 1.26"
|
14
|
+
gem "vcr", "~> 6.0"
|
15
|
+
gem "webmock", "~> 3.13"
|
data/Gemfile.lock
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
end_of_life (0.
|
4
|
+
end_of_life (0.4.0)
|
5
|
+
async
|
5
6
|
dry-monads (~> 1.3)
|
6
|
-
octokit (~>
|
7
|
+
octokit (~> 9.0)
|
7
8
|
pastel (~> 0.8.0)
|
8
9
|
tty-spinner (~> 0.9.0)
|
9
10
|
tty-table (~> 0.12.0)
|
@@ -11,124 +12,159 @@ PATH
|
|
11
12
|
GEM
|
12
13
|
remote: https://rubygems.org/
|
13
14
|
specs:
|
14
|
-
addressable (2.8.
|
15
|
-
public_suffix (>= 2.0.2, <
|
15
|
+
addressable (2.8.7)
|
16
|
+
public_suffix (>= 2.0.2, < 7.0)
|
16
17
|
ast (2.4.2)
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
async (2.24.0)
|
19
|
+
console (~> 1.29)
|
20
|
+
fiber-annotation
|
21
|
+
io-event (~> 1.9)
|
22
|
+
metrics (~> 0.12)
|
23
|
+
traces (~> 0.15)
|
24
|
+
base64 (0.2.0)
|
25
|
+
bigdecimal (3.1.9)
|
26
|
+
climate_control (1.2.0)
|
27
|
+
concurrent-ruby (1.3.5)
|
28
|
+
console (1.30.2)
|
29
|
+
fiber-annotation
|
30
|
+
fiber-local (~> 1.1)
|
31
|
+
json
|
32
|
+
crack (1.0.0)
|
33
|
+
bigdecimal
|
34
|
+
rexml
|
35
|
+
diff-lcs (1.5.1)
|
36
|
+
docile (1.4.1)
|
37
|
+
dry-core (1.1.0)
|
22
38
|
concurrent-ruby (~> 1.0)
|
23
|
-
|
39
|
+
logger
|
40
|
+
zeitwerk (~> 2.6)
|
41
|
+
dry-monads (1.8.3)
|
24
42
|
concurrent-ruby (~> 1.0)
|
25
|
-
dry-core (~>
|
26
|
-
|
27
|
-
|
28
|
-
faraday-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
faraday (>= 0.9)
|
52
|
-
sawyer (~> 0.8.0, >= 0.5.3)
|
53
|
-
parallel (1.21.0)
|
54
|
-
parser (3.1.0.0)
|
43
|
+
dry-core (~> 1.1)
|
44
|
+
zeitwerk (~> 2.6)
|
45
|
+
faraday (2.13.1)
|
46
|
+
faraday-net_http (>= 2.0, < 3.5)
|
47
|
+
json
|
48
|
+
logger
|
49
|
+
faraday-net_http (3.4.0)
|
50
|
+
net-http (>= 0.5.0)
|
51
|
+
fiber-annotation (0.2.0)
|
52
|
+
fiber-local (1.1.0)
|
53
|
+
fiber-storage
|
54
|
+
fiber-storage (1.0.1)
|
55
|
+
hashdiff (1.1.2)
|
56
|
+
io-event (1.10.1)
|
57
|
+
json (2.9.1)
|
58
|
+
language_server-protocol (3.17.0.3)
|
59
|
+
lint_roller (1.1.0)
|
60
|
+
logger (1.7.0)
|
61
|
+
metrics (0.12.2)
|
62
|
+
net-http (0.6.0)
|
63
|
+
uri
|
64
|
+
octokit (9.2.0)
|
65
|
+
faraday (>= 1, < 3)
|
66
|
+
sawyer (~> 0.9)
|
67
|
+
parallel (1.26.3)
|
68
|
+
parser (3.3.6.0)
|
55
69
|
ast (~> 2.4.1)
|
70
|
+
racc
|
56
71
|
pastel (0.8.0)
|
57
72
|
tty-color (~> 0.5)
|
58
|
-
public_suffix (
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
rspec-
|
66
|
-
rspec-
|
67
|
-
|
68
|
-
|
69
|
-
|
73
|
+
public_suffix (6.0.1)
|
74
|
+
racc (1.8.1)
|
75
|
+
rainbow (3.1.1)
|
76
|
+
rake (13.2.1)
|
77
|
+
regexp_parser (2.10.0)
|
78
|
+
rexml (3.4.0)
|
79
|
+
rspec (3.13.0)
|
80
|
+
rspec-core (~> 3.13.0)
|
81
|
+
rspec-expectations (~> 3.13.0)
|
82
|
+
rspec-mocks (~> 3.13.0)
|
83
|
+
rspec-core (3.13.2)
|
84
|
+
rspec-support (~> 3.13.0)
|
85
|
+
rspec-expectations (3.13.3)
|
70
86
|
diff-lcs (>= 1.2.0, < 2.0)
|
71
|
-
rspec-support (~> 3.
|
72
|
-
rspec-mocks (3.
|
87
|
+
rspec-support (~> 3.13.0)
|
88
|
+
rspec-mocks (3.13.2)
|
73
89
|
diff-lcs (>= 1.2.0, < 2.0)
|
74
|
-
rspec-support (~> 3.
|
75
|
-
rspec-support (3.
|
76
|
-
rubocop (1.
|
90
|
+
rspec-support (~> 3.13.0)
|
91
|
+
rspec-support (3.13.2)
|
92
|
+
rubocop (1.69.2)
|
93
|
+
json (~> 2.3)
|
94
|
+
language_server-protocol (>= 3.17.0)
|
77
95
|
parallel (~> 1.10)
|
78
|
-
parser (>= 3.
|
96
|
+
parser (>= 3.3.0.2)
|
79
97
|
rainbow (>= 2.2.2, < 4.0)
|
80
|
-
regexp_parser (>=
|
81
|
-
|
82
|
-
rubocop-ast (>= 1.15.1, < 2.0)
|
98
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
99
|
+
rubocop-ast (>= 1.36.2, < 2.0)
|
83
100
|
ruby-progressbar (~> 1.7)
|
84
|
-
unicode-display_width (>=
|
85
|
-
rubocop-ast (1.
|
86
|
-
parser (>= 3.
|
87
|
-
rubocop-performance (1.
|
88
|
-
rubocop (>= 1.
|
89
|
-
rubocop-ast (>=
|
90
|
-
ruby-progressbar (1.
|
91
|
-
|
92
|
-
sawyer (0.8.2)
|
101
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
102
|
+
rubocop-ast (1.37.0)
|
103
|
+
parser (>= 3.3.1.0)
|
104
|
+
rubocop-performance (1.23.0)
|
105
|
+
rubocop (>= 1.48.1, < 2.0)
|
106
|
+
rubocop-ast (>= 1.31.1, < 2.0)
|
107
|
+
ruby-progressbar (1.13.0)
|
108
|
+
sawyer (0.9.2)
|
93
109
|
addressable (>= 2.3.5)
|
94
|
-
faraday (
|
95
|
-
simplecov (0.
|
110
|
+
faraday (>= 0.17.3, < 3)
|
111
|
+
simplecov (0.22.0)
|
96
112
|
docile (~> 1.1)
|
97
113
|
simplecov-html (~> 0.11)
|
98
114
|
simplecov_json_formatter (~> 0.1)
|
99
|
-
simplecov-html (0.
|
100
|
-
simplecov_json_formatter (0.1.
|
101
|
-
standard (1.
|
102
|
-
|
103
|
-
|
115
|
+
simplecov-html (0.13.1)
|
116
|
+
simplecov_json_formatter (0.1.4)
|
117
|
+
standard (1.43.0)
|
118
|
+
language_server-protocol (~> 3.17.0.2)
|
119
|
+
lint_roller (~> 1.0)
|
120
|
+
rubocop (~> 1.69.1)
|
121
|
+
standard-custom (~> 1.0.0)
|
122
|
+
standard-performance (~> 1.6)
|
123
|
+
standard-custom (1.0.2)
|
124
|
+
lint_roller (~> 1.0)
|
125
|
+
rubocop (~> 1.50)
|
126
|
+
standard-performance (1.6.0)
|
127
|
+
lint_roller (~> 1.1)
|
128
|
+
rubocop-performance (~> 1.23.0)
|
104
129
|
strings (0.2.1)
|
105
130
|
strings-ansi (~> 0.2)
|
106
131
|
unicode-display_width (>= 1.5, < 3.0)
|
107
132
|
unicode_utils (~> 1.4)
|
108
133
|
strings-ansi (0.2.0)
|
134
|
+
traces (0.15.2)
|
109
135
|
tty-color (0.6.0)
|
110
136
|
tty-cursor (0.7.1)
|
111
|
-
tty-screen (0.8.
|
137
|
+
tty-screen (0.8.2)
|
112
138
|
tty-spinner (0.9.3)
|
113
139
|
tty-cursor (~> 0.7)
|
114
140
|
tty-table (0.12.0)
|
115
141
|
pastel (~> 0.8)
|
116
142
|
strings (~> 0.2.0)
|
117
143
|
tty-screen (~> 0.8)
|
118
|
-
unicode-display_width (2.
|
144
|
+
unicode-display_width (2.6.0)
|
119
145
|
unicode_utils (1.4.0)
|
146
|
+
uri (1.0.3)
|
147
|
+
vcr (6.3.1)
|
148
|
+
base64
|
149
|
+
webmock (3.24.0)
|
150
|
+
addressable (>= 2.8.0)
|
151
|
+
crack (>= 0.3.2)
|
152
|
+
hashdiff (>= 0.4.0, < 2.0.0)
|
153
|
+
zeitwerk (2.7.3)
|
120
154
|
|
121
155
|
PLATFORMS
|
122
|
-
|
123
|
-
x86_64-linux
|
156
|
+
ruby
|
124
157
|
|
125
158
|
DEPENDENCIES
|
126
|
-
climate_control (~> 1.0
|
159
|
+
climate_control (~> 1.0)
|
127
160
|
end_of_life!
|
128
161
|
rake (~> 13.0)
|
129
|
-
rspec (~> 3.
|
130
|
-
|
131
|
-
|
162
|
+
rspec (~> 3.10)
|
163
|
+
rspec-mocks (~> 3.10)
|
164
|
+
simplecov (~> 0.22.0)
|
165
|
+
standard (~> 1.26)
|
166
|
+
vcr (~> 6.0)
|
167
|
+
webmock (~> 3.13)
|
132
168
|
|
133
169
|
BUNDLED WITH
|
134
|
-
2.3.
|
170
|
+
2.3.9
|
data/README.md
CHANGED
@@ -12,19 +12,20 @@ gem install end_of_life
|
|
12
12
|
|
13
13
|
## Usage
|
14
14
|
|
15
|
-
1. Set up a [GitHub access token];
|
15
|
+
1. Set up a [GitHub access token][] (we recommend using a read-only token);
|
16
16
|
|
17
|
-
[
|
17
|
+
[github access token]: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token#creating-a-token
|
18
18
|
|
19
19
|
2. Export the `GITHUB_TOKEN` environment variable or set it when calling `end_of_life`;
|
20
20
|
|
21
21
|
3. Use the `end_of_life` command to list the repositories:
|
22
|
+
|
22
23
|
```sh
|
23
24
|
$ GITHUB_TOKEN=something end_of_life # if your platform supports symlinks, you can use the `eol` command instead
|
24
25
|
[✔] Fetching repositories...
|
25
26
|
[✔] Searching for EOL Ruby in repositories...
|
26
27
|
|
27
|
-
Found 2 repositories using EOL Ruby (<= 2.
|
28
|
+
Found 2 repositories using EOL Ruby (<= 2.7.8):
|
28
29
|
┌───┬──────────────────────────────────────────────┬──────────────┐
|
29
30
|
│ │ Repository │ Ruby version │
|
30
31
|
├───┼──────────────────────────────────────────────┼──────────────┤
|
@@ -33,15 +34,33 @@ Found 2 repositories using EOL Ruby (<= 2.5.9):
|
|
33
34
|
└───┴──────────────────────────────────────────────┴──────────────┘
|
34
35
|
```
|
35
36
|
|
36
|
-
|
37
|
+
### Options
|
38
|
+
|
39
|
+
There are some options to help you filter down the results:
|
40
|
+
|
41
|
+
```
|
42
|
+
Usage: end_of_life [options]
|
43
|
+
--exclude=NAME,NAME2 Exclude repositories containing a certain word in its name. You can specify up to five words.
|
44
|
+
--public-only Searches only public repostories
|
45
|
+
--private-only Searches only private repostories
|
46
|
+
--repo, --repository=USER/REPO Searches a specific repostory
|
47
|
+
--org, --organization=ORG,ORG2 Searches within specific organizations
|
48
|
+
-u, --user=NAME Sets the user used on the repository search
|
49
|
+
--max-eol-days-away NUMBER Sets the maximum number of days away a version can be from EOL. It defaults to 0.
|
50
|
+
--include-archived Includes archived repositories on the search
|
51
|
+
-v, --version Displays end_of_life version
|
52
|
+
-h, --help Displays this help
|
53
|
+
```
|
54
|
+
|
55
|
+
## How it works
|
37
56
|
|
38
57
|
This gem fetches all your GitHub repositories that contain Ruby code, then
|
39
58
|
searches for files that may have a Ruby version. Currently, those files are:
|
40
59
|
`.ruby-version`, `Gemfile`, `Gemfile.lock`, and `.tool-version`. We parse these
|
41
60
|
files and extract the minimum Ruby version used in the repository.
|
42
61
|
|
43
|
-
The EOL Ruby version is
|
44
|
-
|
62
|
+
The EOL Ruby version is provided by https://endoflife.date/, with a file
|
63
|
+
[fallback].
|
45
64
|
|
46
65
|
> **IMPORTANT:** To parse Gemfiles, we need to execute the code inside it. **Be
|
47
66
|
> careful** because this may be a security risk. We plan to add a secure parser
|
@@ -49,7 +68,7 @@ https://endoflife.date/. We plan to fetch their API endpoint in the future.
|
|
49
68
|
|
50
69
|
Some other limitations are listed on the [issues page].
|
51
70
|
|
52
|
-
[
|
71
|
+
[fallback]: ./lib/end_of_life.json
|
53
72
|
[issues page]: https://github.com/MatheusRich/end_of_life/issues
|
54
73
|
|
55
74
|
## Development
|
data/Rakefile
CHANGED
data/end_of_life.gemspec
CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
|
|
13
13
|
"unmaintained, Ruby versions."
|
14
14
|
spec.homepage = "https://github.com/MatheusRich/end_of_life"
|
15
15
|
spec.license = "MIT"
|
16
|
-
spec.required_ruby_version = ">= 2.
|
16
|
+
spec.required_ruby_version = ">= 3.2.0"
|
17
17
|
|
18
18
|
# spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'"
|
19
19
|
|
@@ -32,9 +32,10 @@ Gem::Specification.new do |spec|
|
|
32
32
|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
33
33
|
spec.require_paths = ["lib"]
|
34
34
|
|
35
|
-
spec.add_dependency "
|
36
|
-
spec.add_dependency "pastel", "~> 0.8.0"
|
35
|
+
spec.add_dependency "async"
|
37
36
|
spec.add_dependency "dry-monads", "~> 1.3"
|
37
|
+
spec.add_dependency "octokit", "~> 9.0"
|
38
|
+
spec.add_dependency "pastel", "~> 0.8.0"
|
38
39
|
spec.add_dependency "tty-spinner", "~> 0.9.0"
|
39
40
|
spec.add_dependency "tty-table", "~> 0.12.0"
|
40
41
|
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module EndOfLife
|
2
|
+
class CLI
|
3
|
+
include TerminalHelper
|
4
|
+
|
5
|
+
def call(argv)
|
6
|
+
parse_options(argv)
|
7
|
+
.then { |options| execute_command(options) }
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def execute_command(options)
|
13
|
+
case options[:command]
|
14
|
+
when :help
|
15
|
+
puts options[:parser]
|
16
|
+
when :version
|
17
|
+
puts "end_of_life v#{EndOfLife::VERSION}"
|
18
|
+
when :print_error
|
19
|
+
puts error_msg(options[:error])
|
20
|
+
exit(-1)
|
21
|
+
else
|
22
|
+
check_eol_ruby_on_repositories(options)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def check_eol_ruby_on_repositories(options)
|
27
|
+
fetch_repositories(options)
|
28
|
+
.fmap { |repositories| filter_repositories_with_end_of_life(repositories, max_eol_date: options[:max_eol_date]) }
|
29
|
+
.fmap { |repositories| print_diagnose_for(repositories, max_eol_date: options[:max_eol_date]) }
|
30
|
+
.or { |error| puts "\n#{error_msg(error)}" }
|
31
|
+
end
|
32
|
+
|
33
|
+
def parse_options(argv)
|
34
|
+
Options.from(argv)
|
35
|
+
end
|
36
|
+
|
37
|
+
def fetch_repositories(options)
|
38
|
+
with_loading_spinner("Fetching repositories...") do |spinner|
|
39
|
+
result = Repository.fetch(options)
|
40
|
+
|
41
|
+
spinner.error if result.failure?
|
42
|
+
|
43
|
+
result
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def filter_repositories_with_end_of_life(repositories, max_eol_date:)
|
48
|
+
with_loading_spinner("Searching for EOL Ruby in repositories...") do
|
49
|
+
Sync do
|
50
|
+
repositories
|
51
|
+
.tap { |repos| repos.map { |repo| Async { repo.ruby_version } }.map(&:wait) }
|
52
|
+
.filter { |repo| repo.eol_ruby?(at: max_eol_date) }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def print_diagnose_for(repositories, max_eol_date:)
|
58
|
+
puts
|
59
|
+
|
60
|
+
if repositories.empty?
|
61
|
+
puts "No repositories using EOL Ruby."
|
62
|
+
return
|
63
|
+
end
|
64
|
+
|
65
|
+
puts "Found #{repositories.size} repositories using EOL Ruby (<= #{RubyVersion.latest_eol(at: max_eol_date)}):"
|
66
|
+
puts end_of_life_table(repositories)
|
67
|
+
exit(-1)
|
68
|
+
end
|
69
|
+
|
70
|
+
def end_of_life_table(repositories)
|
71
|
+
headers = ["", "Repository", "Ruby version"]
|
72
|
+
rows = repositories.map.with_index(1) do |repo, i|
|
73
|
+
[i, repo.url, repo.ruby_version]
|
74
|
+
end
|
75
|
+
|
76
|
+
table(headers, rows)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require "optparse"
|
2
|
+
|
3
|
+
module EndOfLife
|
4
|
+
module Options
|
5
|
+
def self.from(argv)
|
6
|
+
options = {max_eol_date: Date.today, skip_archived: true}
|
7
|
+
|
8
|
+
OptionParser.new do |opts|
|
9
|
+
options[:parser] = opts
|
10
|
+
|
11
|
+
opts.banner = "Usage: end_of_life [options]"
|
12
|
+
|
13
|
+
opts.on("--exclude=NAME,NAME2", Array, "Exclude repositories containing a certain word in its name. You can specify up to five words.") do |excludes|
|
14
|
+
options[:excludes] = excludes.first(5)
|
15
|
+
end
|
16
|
+
|
17
|
+
opts.on("--public-only", "Searches only public repostories") do
|
18
|
+
options[:visibility] = :public
|
19
|
+
end
|
20
|
+
|
21
|
+
opts.on("--private-only", "Searches only private repostories") do
|
22
|
+
options[:visibility] = :private
|
23
|
+
end
|
24
|
+
|
25
|
+
opts.on("--repo=USER/REPO", "--repository=USER/REPO", "Searches a specific repostory") do |repository|
|
26
|
+
options[:repository] = repository
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on("--org=ORG,ORG2...", "--organization=ORG,ORG2", Array, "Searches within specific organizations") do |organizations|
|
30
|
+
options[:organizations] = organizations
|
31
|
+
end
|
32
|
+
|
33
|
+
opts.on("-u NAME", "--user=NAME", "Sets the user used on the repository search") do |user|
|
34
|
+
options[:user] = user
|
35
|
+
end
|
36
|
+
|
37
|
+
opts.on("--max-eol-days-away NUMBER", "Sets the maximum number of days away a version can be from EOL. It defaults to 0.") do |days|
|
38
|
+
options[:max_eol_date] = Date.today + days.to_i.abs
|
39
|
+
end
|
40
|
+
|
41
|
+
opts.on("--include-archived", "Includes archived repositories on the search") do
|
42
|
+
options[:skip_archived] = false
|
43
|
+
end
|
44
|
+
|
45
|
+
opts.on("-v", "--version", "Displays end_of_life version") do
|
46
|
+
options[:command] = :version
|
47
|
+
end
|
48
|
+
|
49
|
+
opts.on("-h", "--help", "Displays this help") do
|
50
|
+
options[:command] = :help
|
51
|
+
end
|
52
|
+
end.parse!(argv)
|
53
|
+
|
54
|
+
options
|
55
|
+
rescue OptionParser::ParseError => e
|
56
|
+
{command: :print_error, error: e}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -1,20 +1,20 @@
|
|
1
|
-
require "dry-monads"
|
2
|
-
|
3
1
|
module EndOfLife
|
4
2
|
class Repository
|
5
3
|
class << self
|
6
4
|
include Dry::Monads[:result, :maybe]
|
7
5
|
|
8
|
-
def fetch(
|
6
|
+
def fetch(options)
|
9
7
|
github_client.bind do |github|
|
10
|
-
|
11
|
-
|
8
|
+
github.auto_paginate = true
|
9
|
+
options[:user] ||= github.user.login
|
12
10
|
|
13
|
-
|
14
|
-
|
11
|
+
query = search_query_for(options)
|
12
|
+
items = github.search_repositories(query, {sort: :updated}).items
|
15
13
|
|
16
14
|
Success(
|
17
|
-
|
15
|
+
items.filter_map do |repo|
|
16
|
+
next if repo.archived && options[:skip_archived]
|
17
|
+
|
18
18
|
Repository.new(
|
19
19
|
full_name: repo.full_name,
|
20
20
|
url: repo.html_url,
|
@@ -29,24 +29,36 @@ module EndOfLife
|
|
29
29
|
|
30
30
|
def github_client
|
31
31
|
Maybe(ENV["GITHUB_TOKEN"])
|
32
|
-
.to_result
|
33
32
|
.fmap { |token| Octokit::Client.new(access_token: token) }
|
34
33
|
.or { Failure("Please set GITHUB_TOKEN environment variable") }
|
35
34
|
end
|
36
35
|
|
37
|
-
def search_query_for(
|
38
|
-
query = "language
|
39
|
-
|
40
|
-
|
36
|
+
def search_query_for(options)
|
37
|
+
query = "language:ruby"
|
38
|
+
|
39
|
+
query += if options[:repository]
|
40
|
+
" repo:#{options[:repository]}"
|
41
|
+
elsif options[:organizations]
|
42
|
+
options[:organizations].map { |org| " org:#{org}" }.join
|
41
43
|
else
|
42
|
-
" user:#{user}"
|
44
|
+
" user:#{options[:user]}"
|
45
|
+
end
|
46
|
+
|
47
|
+
if options[:visibility]
|
48
|
+
query += " is:#{options[:visibility]}"
|
49
|
+
end
|
50
|
+
|
51
|
+
if options[:excludes]
|
52
|
+
words_to_exclude = options[:excludes].map { |word| "NOT #{word} " }.join
|
53
|
+
|
54
|
+
query += " #{words_to_exclude} in:name"
|
43
55
|
end
|
44
56
|
|
45
57
|
query
|
46
58
|
end
|
47
59
|
end
|
48
60
|
|
49
|
-
|
61
|
+
attr_reader :full_name, :url
|
50
62
|
|
51
63
|
def initialize(full_name:, url:, github_client:)
|
52
64
|
@full_name = full_name
|
@@ -54,8 +66,8 @@ module EndOfLife
|
|
54
66
|
@github_client = github_client
|
55
67
|
end
|
56
68
|
|
57
|
-
def eol_ruby?
|
58
|
-
ruby_version&.eol?
|
69
|
+
def eol_ruby?(at: Date.today)
|
70
|
+
ruby_version&.eol?(at: at)
|
59
71
|
end
|
60
72
|
|
61
73
|
def ruby_version
|
@@ -69,15 +81,22 @@ module EndOfLife
|
|
69
81
|
def ruby_versions
|
70
82
|
return @ruby_versions if defined?(@ruby_versions)
|
71
83
|
|
72
|
-
@ruby_versions =
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
fetch_file("Gemfile.lock"),
|
77
|
-
fetch_file(".tool-versions")
|
78
|
-
].compact
|
84
|
+
@ruby_versions = fetch_ruby_version_files.filter_map { |file|
|
85
|
+
parse_version_file(file)
|
86
|
+
}
|
87
|
+
end
|
79
88
|
|
80
|
-
|
89
|
+
POSSIBLE_RUBY_VERSION_FILES = [
|
90
|
+
".ruby-version",
|
91
|
+
"Gemfile.lock",
|
92
|
+
"Gemfile",
|
93
|
+
".tool-versions"
|
94
|
+
]
|
95
|
+
def fetch_ruby_version_files
|
96
|
+
Sync do
|
97
|
+
POSSIBLE_RUBY_VERSION_FILES
|
98
|
+
.map { |file_path| Async { fetch_file(file_path) } }
|
99
|
+
.filter_map(&:wait)
|
81
100
|
end
|
82
101
|
end
|
83
102
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require "net/http"
|
1
2
|
require "rubygems"
|
2
3
|
require_relative "ruby_version/parser"
|
3
4
|
|
@@ -5,28 +6,52 @@ module EndOfLife
|
|
5
6
|
class RubyVersion
|
6
7
|
include Comparable
|
7
8
|
|
8
|
-
|
9
|
+
class << self
|
10
|
+
include Dry::Monads[:try]
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
.map { |version| Gem::Version.new(version[:latest]) }
|
14
|
-
.max
|
12
|
+
def from_file(file_name:, content:, parser: Parser)
|
13
|
+
parser.parse_file(file_name: file_name, content: content)
|
14
|
+
end
|
15
15
|
|
16
|
-
|
17
|
-
|
16
|
+
def eol_versions_at(date)
|
17
|
+
all_versions.filter { |version| version.eol_date <= date }
|
18
|
+
end
|
19
|
+
|
20
|
+
def latest_eol(at: Date.today)
|
21
|
+
eol_versions_at(at).max
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
EOL_API_URL = "https://endoflife.date/api/ruby.json"
|
27
|
+
DB_PATH = File.join(__dir__, "../end_of_life.json")
|
28
|
+
|
29
|
+
def all_versions
|
30
|
+
@all_versions ||= (fetch_end_of_life_api || load_file_fallback)
|
31
|
+
.then { |json| JSON.parse(json, symbolize_names: true) }
|
32
|
+
.map { |version| new(version[:latest], eol_date: Date.parse(version[:eol])) }
|
33
|
+
end
|
34
|
+
|
35
|
+
def fetch_end_of_life_api
|
36
|
+
Try { Net::HTTP.get URI(EOL_API_URL) }.value_or(nil)
|
37
|
+
end
|
38
|
+
|
39
|
+
def load_file_fallback
|
40
|
+
File.read(DB_PATH)
|
41
|
+
end
|
18
42
|
end
|
19
43
|
|
20
|
-
|
44
|
+
attr_reader :version, :eol_date
|
21
45
|
|
22
|
-
def initialize(version_string)
|
46
|
+
def initialize(version_string, eol_date: nil)
|
23
47
|
@version = Gem::Version.new(version_string)
|
48
|
+
@eol_date = eol_date
|
24
49
|
|
25
50
|
freeze
|
26
51
|
end
|
27
52
|
|
28
|
-
def eol?
|
29
|
-
|
53
|
+
def eol?(at: Date.today)
|
54
|
+
self <= RubyVersion.latest_eol(at: at)
|
30
55
|
end
|
31
56
|
|
32
57
|
def <=>(other)
|
data/lib/end_of_life/version.rb
CHANGED
data/lib/end_of_life.json
CHANGED
@@ -1,13 +1,98 @@
|
|
1
1
|
[
|
2
|
-
{
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
{
|
11
|
-
|
12
|
-
|
2
|
+
{
|
3
|
+
"cycle": "3.2",
|
4
|
+
"eol": "2026-03-31",
|
5
|
+
"latest": "3.2.2",
|
6
|
+
"latestReleaseDate": "2023-03-30",
|
7
|
+
"releaseDate": "2022-12-25",
|
8
|
+
"lts": false
|
9
|
+
},
|
10
|
+
{
|
11
|
+
"cycle": "3.1",
|
12
|
+
"eol": "2025-03-31",
|
13
|
+
"latest": "3.1.4",
|
14
|
+
"latestReleaseDate": "2023-03-30",
|
15
|
+
"releaseDate": "2021-12-25",
|
16
|
+
"lts": false
|
17
|
+
},
|
18
|
+
{
|
19
|
+
"cycle": "3.0",
|
20
|
+
"eol": "2024-03-31",
|
21
|
+
"latest": "3.0.6",
|
22
|
+
"latestReleaseDate": "2023-03-30",
|
23
|
+
"releaseDate": "2020-12-25",
|
24
|
+
"lts": false
|
25
|
+
},
|
26
|
+
{
|
27
|
+
"cycle": "2.7",
|
28
|
+
"eol": "2023-03-31",
|
29
|
+
"latest": "2.7.8",
|
30
|
+
"latestReleaseDate": "2023-03-30",
|
31
|
+
"releaseDate": "2019-12-25",
|
32
|
+
"lts": false
|
33
|
+
},
|
34
|
+
{
|
35
|
+
"cycle": "2.6",
|
36
|
+
"eol": "2022-03-31",
|
37
|
+
"latest": "2.6.10",
|
38
|
+
"latestReleaseDate": "2022-04-12",
|
39
|
+
"releaseDate": "2018-12-25",
|
40
|
+
"lts": false
|
41
|
+
},
|
42
|
+
{
|
43
|
+
"cycle": "2.5",
|
44
|
+
"eol": "2021-03-31",
|
45
|
+
"latest": "2.5.9",
|
46
|
+
"latestReleaseDate": "2021-04-05",
|
47
|
+
"releaseDate": "2017-12-25",
|
48
|
+
"lts": false
|
49
|
+
},
|
50
|
+
{
|
51
|
+
"cycle": "2.4",
|
52
|
+
"eol": "2020-03-31",
|
53
|
+
"latest": "2.4.10",
|
54
|
+
"latestReleaseDate": "2020-03-31",
|
55
|
+
"releaseDate": "2016-12-23",
|
56
|
+
"lts": false
|
57
|
+
},
|
58
|
+
{
|
59
|
+
"cycle": "2.3",
|
60
|
+
"eol": "2019-03-31",
|
61
|
+
"latest": "2.3.8",
|
62
|
+
"latestReleaseDate": "2018-10-17",
|
63
|
+
"releaseDate": "2015-12-24",
|
64
|
+
"lts": false
|
65
|
+
},
|
66
|
+
{
|
67
|
+
"cycle": "2.2",
|
68
|
+
"eol": "2018-03-31",
|
69
|
+
"latest": "2.2.10",
|
70
|
+
"latestReleaseDate": "2018-03-28",
|
71
|
+
"releaseDate": "2014-12-25",
|
72
|
+
"lts": false
|
73
|
+
},
|
74
|
+
{
|
75
|
+
"cycle": "2.1",
|
76
|
+
"eol": "2017-03-31",
|
77
|
+
"latest": "2.1.10",
|
78
|
+
"latestReleaseDate": "2016-03-31",
|
79
|
+
"releaseDate": "2013-12-25",
|
80
|
+
"lts": false
|
81
|
+
},
|
82
|
+
{
|
83
|
+
"cycle": "2.0.0",
|
84
|
+
"eol": "2016-02-24",
|
85
|
+
"latest": "2.0.0p648",
|
86
|
+
"latestReleaseDate": "2015-12-16",
|
87
|
+
"releaseDate": "2013-02-24",
|
88
|
+
"lts": false
|
89
|
+
},
|
90
|
+
{
|
91
|
+
"cycle": "1.9.3",
|
92
|
+
"eol": "2015-02-23",
|
93
|
+
"latest": "1.9.3p551",
|
94
|
+
"latestReleaseDate": "2014-11-13",
|
95
|
+
"releaseDate": "2011-10-30",
|
96
|
+
"lts": false
|
97
|
+
}
|
13
98
|
]
|
data/lib/end_of_life.rb
CHANGED
@@ -1,113 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "async"
|
4
|
+
require "dry-monads"
|
3
5
|
require "json"
|
6
|
+
require "base64"
|
4
7
|
require "octokit"
|
5
|
-
|
8
|
+
require_relative "end_of_life/options"
|
6
9
|
require_relative "end_of_life/repository"
|
7
10
|
require_relative "end_of_life/ruby_version"
|
8
11
|
require_relative "end_of_life/terminal_helper"
|
9
12
|
require_relative "end_of_life/version"
|
13
|
+
require_relative "end_of_life/cli"
|
10
14
|
|
11
15
|
module EndOfLife
|
12
16
|
extend TerminalHelper
|
13
|
-
|
14
|
-
class CLI
|
15
|
-
include TerminalHelper
|
16
|
-
|
17
|
-
def call(argv)
|
18
|
-
parse_options(argv)
|
19
|
-
.then { |options| execute_command(options) }
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
def execute_command(options)
|
25
|
-
case options[:command]
|
26
|
-
when :help
|
27
|
-
puts options[:parser]
|
28
|
-
when :version
|
29
|
-
puts "end_of_life v#{EndOfLife::VERSION}"
|
30
|
-
when :print_error
|
31
|
-
puts error_msg(options[:error])
|
32
|
-
exit(-1)
|
33
|
-
else
|
34
|
-
check_eol_ruby_on_repositories(options)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def check_eol_ruby_on_repositories(options)
|
39
|
-
fetch_repositories(user: options[:user], repository: options[:repository])
|
40
|
-
.fmap { |repositories| filter_repositories_with_end_of_life(repositories) }
|
41
|
-
.fmap { |repositories| print_diagnose_for(repositories) }
|
42
|
-
.or { |error| puts "\n#{error_msg(error)}" }
|
43
|
-
end
|
44
|
-
|
45
|
-
def parse_options(argv)
|
46
|
-
options = {}
|
47
|
-
|
48
|
-
OptionParser.new do |opts|
|
49
|
-
options[:parser] = opts
|
50
|
-
|
51
|
-
opts.banner = "Usage: end_of_life [options]"
|
52
|
-
|
53
|
-
opts.on("--repo=USER/REPO", "--repository=USER/REPO", "Searches a specific repostory") do |repository|
|
54
|
-
options[:repository] = repository
|
55
|
-
end
|
56
|
-
|
57
|
-
opts.on("-u NAME", "--user=NAME", "Sets the user used on the repository search") do |user|
|
58
|
-
options[:user] = user
|
59
|
-
end
|
60
|
-
|
61
|
-
opts.on("-v", "--version", "Displays end_of_life version") do
|
62
|
-
options[:command] = :version
|
63
|
-
end
|
64
|
-
|
65
|
-
opts.on("-h", "--help", "Displays this help") do
|
66
|
-
options[:command] = :help
|
67
|
-
end
|
68
|
-
end.parse!(argv)
|
69
|
-
|
70
|
-
options
|
71
|
-
rescue OptionParser::ParseError => e
|
72
|
-
{command: :print_error, error: e}
|
73
|
-
end
|
74
|
-
|
75
|
-
def fetch_repositories(user:, repository:)
|
76
|
-
with_loading_spinner("Fetching repositories...") do |spinner|
|
77
|
-
result = Repository.fetch(language: "ruby", user: user, repository: repository)
|
78
|
-
|
79
|
-
spinner.error if result.failure?
|
80
|
-
|
81
|
-
result
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
def filter_repositories_with_end_of_life(repositories)
|
86
|
-
with_loading_spinner("Searching for EOL Ruby in repositories...") do
|
87
|
-
repositories.filter { |repo| repo.eol_ruby? }
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
def print_diagnose_for(repositories)
|
92
|
-
puts
|
93
|
-
|
94
|
-
if repositories.empty?
|
95
|
-
puts "No repositories using EOL Ruby."
|
96
|
-
return
|
97
|
-
end
|
98
|
-
|
99
|
-
puts "Found #{repositories.size} repositories using EOL Ruby (<= #{RubyVersion::EOL}):"
|
100
|
-
puts end_of_life_table(repositories)
|
101
|
-
exit(-1)
|
102
|
-
end
|
103
|
-
|
104
|
-
def end_of_life_table(repositories)
|
105
|
-
headers = ["", "Repository", "Ruby version"]
|
106
|
-
rows = repositories.map.with_index(1) do |repo, i|
|
107
|
-
[i, repo.url, repo.ruby_version]
|
108
|
-
end
|
109
|
-
|
110
|
-
table(headers, rows)
|
111
|
-
end
|
112
|
-
end
|
113
17
|
end
|
metadata
CHANGED
@@ -1,57 +1,70 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: end_of_life
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matheus Richard
|
8
|
-
autorequire:
|
9
8
|
bindir: exe
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 2025-05-23 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
13
|
+
name: async
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - ">="
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '0'
|
19
|
+
type: :runtime
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - ">="
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '0'
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: dry-monads
|
15
28
|
requirement: !ruby/object:Gem::Requirement
|
16
29
|
requirements:
|
17
30
|
- - "~>"
|
18
31
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
32
|
+
version: '1.3'
|
20
33
|
type: :runtime
|
21
34
|
prerelease: false
|
22
35
|
version_requirements: !ruby/object:Gem::Requirement
|
23
36
|
requirements:
|
24
37
|
- - "~>"
|
25
38
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
39
|
+
version: '1.3'
|
27
40
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
41
|
+
name: octokit
|
29
42
|
requirement: !ruby/object:Gem::Requirement
|
30
43
|
requirements:
|
31
44
|
- - "~>"
|
32
45
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
46
|
+
version: '9.0'
|
34
47
|
type: :runtime
|
35
48
|
prerelease: false
|
36
49
|
version_requirements: !ruby/object:Gem::Requirement
|
37
50
|
requirements:
|
38
51
|
- - "~>"
|
39
52
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
53
|
+
version: '9.0'
|
41
54
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
55
|
+
name: pastel
|
43
56
|
requirement: !ruby/object:Gem::Requirement
|
44
57
|
requirements:
|
45
58
|
- - "~>"
|
46
59
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
60
|
+
version: 0.8.0
|
48
61
|
type: :runtime
|
49
62
|
prerelease: false
|
50
63
|
version_requirements: !ruby/object:Gem::Requirement
|
51
64
|
requirements:
|
52
65
|
- - "~>"
|
53
66
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
67
|
+
version: 0.8.0
|
55
68
|
- !ruby/object:Gem::Dependency
|
56
69
|
name: tty-spinner
|
57
70
|
requirement: !ruby/object:Gem::Requirement
|
@@ -107,6 +120,8 @@ files:
|
|
107
120
|
- exe/eol
|
108
121
|
- lib/end_of_life.json
|
109
122
|
- lib/end_of_life.rb
|
123
|
+
- lib/end_of_life/cli.rb
|
124
|
+
- lib/end_of_life/options.rb
|
110
125
|
- lib/end_of_life/repository.rb
|
111
126
|
- lib/end_of_life/ruby_version.rb
|
112
127
|
- lib/end_of_life/ruby_version/parser.rb
|
@@ -119,7 +134,6 @@ metadata:
|
|
119
134
|
homepage_uri: https://github.com/MatheusRich/end_of_life
|
120
135
|
source_code_uri: https://github.com/MatheusRich/end_of_life
|
121
136
|
changelog_uri: https://github.com/MatheusRich/end_of_life/blob/main/CHANGELOG.md
|
122
|
-
post_install_message:
|
123
137
|
rdoc_options: []
|
124
138
|
require_paths:
|
125
139
|
- lib
|
@@ -127,15 +141,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
127
141
|
requirements:
|
128
142
|
- - ">="
|
129
143
|
- !ruby/object:Gem::Version
|
130
|
-
version: 2.
|
144
|
+
version: 3.2.0
|
131
145
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
146
|
requirements:
|
133
147
|
- - ">="
|
134
148
|
- !ruby/object:Gem::Version
|
135
149
|
version: '0'
|
136
150
|
requirements: []
|
137
|
-
rubygems_version: 3.2
|
138
|
-
signing_key:
|
151
|
+
rubygems_version: 3.6.2
|
139
152
|
specification_version: 4
|
140
153
|
summary: Lists repositories using end-of-life Ruby versions.
|
141
154
|
test_files: []
|