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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5e058c01c970e9fde4fdceeabde71c29a623374ef989987d5b5ab10e1e247ca4
4
- data.tar.gz: 58adcd9c3aa9fbf64b1adb7a7f2f68d1d551ee41925ff9f06c03ce9e21298448
3
+ metadata.gz: 613932e8ff35287b6f1cfd47f892ec07842432a48a86de9586daafe7c7fe2e4a
4
+ data.tar.gz: a8d47ebdc3838394b2dae1c86b39f02e0eb59c727fd878e956d849873ff7f1f0
5
5
  SHA512:
6
- metadata.gz: 87d59b8b0d1aa556bf0b2bc7295a617fe5890bb0056437c7728d497468a05df6b57150f13680ac0be0ae9a400d40d02dac05331a5999d59943bcce7821d767f9
7
- data.tar.gz: 38acbd80942af304503ec510b666f2b18ce1de8a728d92254c5fd3acd1393d6eadeb3c8e24aa1de242bc6a7f5243226a446a11e529c03d5e6443adcd571408a6
6
+ metadata.gz: 3919afb9fce45df1d650605e05cd401fd1281f7d17bf4df56e8bc33245df04e70184ed834ba7f09d25cb88f3b6c62448170dfd40d9b38cb3e09b048417aecc4f
7
+ data.tar.gz: 792c5b7483671ea6b0a952ad3736c52046c95bf8b8d030082ff5270a0c0bf9a3af0f6937b02f015c63c32881bd8a9b8d4e0fe97e3ee29d8868299344cd3f7d99
data/.tool-versions CHANGED
@@ -1 +1 @@
1
- ruby 3.0.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] - 2022-01-17
153
+ ## [0.1.0]
34
154
 
35
155
  - Initial release
36
156
 
37
- [unreleased]: https://github.com/MatheusRich/end_of_life/compare/v0.1.0...HEAD
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.1"
8
+ gem "climate_control", "~> 1.0"
9
9
  gem "rake", "~> 13.0"
10
- gem "rspec", "~> 3.0"
11
- gem "simplecov", "~> 0.21.2"
12
- gem "standard", "~> 1.6"
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.2.0)
4
+ end_of_life (0.4.0)
5
+ async
5
6
  dry-monads (~> 1.3)
6
- octokit (~> 4.0)
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.0)
15
- public_suffix (>= 2.0.2, < 5.0)
15
+ addressable (2.8.7)
16
+ public_suffix (>= 2.0.2, < 7.0)
16
17
  ast (2.4.2)
17
- climate_control (1.0.1)
18
- concurrent-ruby (1.1.9)
19
- diff-lcs (1.4.4)
20
- docile (1.4.0)
21
- dry-core (0.7.1)
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
- dry-monads (1.4.0)
39
+ logger
40
+ zeitwerk (~> 2.6)
41
+ dry-monads (1.8.3)
24
42
  concurrent-ruby (~> 1.0)
25
- dry-core (~> 0.7)
26
- faraday (1.9.3)
27
- faraday-em_http (~> 1.0)
28
- faraday-em_synchrony (~> 1.0)
29
- faraday-excon (~> 1.1)
30
- faraday-httpclient (~> 1.0)
31
- faraday-multipart (~> 1.0)
32
- faraday-net_http (~> 1.0)
33
- faraday-net_http_persistent (~> 1.0)
34
- faraday-patron (~> 1.0)
35
- faraday-rack (~> 1.0)
36
- faraday-retry (~> 1.0)
37
- ruby2_keywords (>= 0.0.4)
38
- faraday-em_http (1.0.0)
39
- faraday-em_synchrony (1.0.0)
40
- faraday-excon (1.1.0)
41
- faraday-httpclient (1.0.1)
42
- faraday-multipart (1.0.3)
43
- multipart-post (>= 1.2, < 3)
44
- faraday-net_http (1.0.1)
45
- faraday-net_http_persistent (1.2.0)
46
- faraday-patron (1.0.0)
47
- faraday-rack (1.0.0)
48
- faraday-retry (1.0.3)
49
- multipart-post (2.1.1)
50
- octokit (4.22.0)
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 (4.0.6)
59
- rainbow (3.0.0)
60
- rake (13.0.6)
61
- regexp_parser (2.2.0)
62
- rexml (3.2.5)
63
- rspec (3.10.0)
64
- rspec-core (~> 3.10.0)
65
- rspec-expectations (~> 3.10.0)
66
- rspec-mocks (~> 3.10.0)
67
- rspec-core (3.10.1)
68
- rspec-support (~> 3.10.0)
69
- rspec-expectations (3.10.1)
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.10.0)
72
- rspec-mocks (3.10.2)
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.10.0)
75
- rspec-support (3.10.2)
76
- rubocop (1.24.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.0.0.0)
96
+ parser (>= 3.3.0.2)
79
97
  rainbow (>= 2.2.2, < 4.0)
80
- regexp_parser (>= 1.8, < 3.0)
81
- rexml
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 (>= 1.4.0, < 3.0)
85
- rubocop-ast (1.15.1)
86
- parser (>= 3.0.1.1)
87
- rubocop-performance (1.13.1)
88
- rubocop (>= 1.7.0, < 2.0)
89
- rubocop-ast (>= 0.4.0)
90
- ruby-progressbar (1.11.0)
91
- ruby2_keywords (0.0.5)
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 (> 0.8, < 2.0)
95
- simplecov (0.21.2)
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.12.3)
100
- simplecov_json_formatter (0.1.3)
101
- standard (1.6.0)
102
- rubocop (= 1.24.1)
103
- rubocop-performance (= 1.13.1)
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.1)
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.1.0)
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
- x86_64-darwin-20
123
- x86_64-linux
156
+ ruby
124
157
 
125
158
  DEPENDENCIES
126
- climate_control (~> 1.0.1)
159
+ climate_control (~> 1.0)
127
160
  end_of_life!
128
161
  rake (~> 13.0)
129
- rspec (~> 3.0)
130
- simplecov (~> 0.21.2)
131
- standard (~> 1.6)
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.4
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
- [GitHub access token]: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token#creating-a-token
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.5.9):
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
- ## How it works?
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 defined statically in [this JSON file] provided by
44
- https://endoflife.date/. We plan to fetch their API endpoint in the future.
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
- [this json file]: ./lib/end_of_life.json
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
@@ -2,7 +2,8 @@
2
2
 
3
3
  require "bundler/gem_tasks"
4
4
  require "rspec/core/rake_task"
5
+ require "standard/rake"
5
6
 
6
7
  RSpec::Core::RakeTask.new(:spec)
7
8
 
8
- task default: :spec
9
+ task default: [:spec, :standard]
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.7.0"
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 "octokit", "~> 4.0"
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(language:, user:, repository: nil)
6
+ def fetch(options)
9
7
  github_client.bind do |github|
10
- user ||= github.user.login
11
- query = search_query_for(language: language, user: user, repository: repository)
8
+ github.auto_paginate = true
9
+ options[:user] ||= github.user.login
12
10
 
13
- response = github.search_repositories(query, per_page: 100)
14
- warn "Incomplete results: we only search 100 repos at a time" if response.incomplete_results
11
+ query = search_query_for(options)
12
+ items = github.search_repositories(query, {sort: :updated}).items
15
13
 
16
14
  Success(
17
- response.items.map do |repo|
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(language:, user:, repository:)
38
- query = "language:#{language}"
39
- query += if repository
40
- " repo:#{repository}"
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
- attr :full_name, :url
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 = begin
73
- ruby_version_files = [
74
- fetch_file(".ruby-version"),
75
- fetch_file("Gemfile"),
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
- ruby_version_files.filter_map { |file| parse_version_file(file) }
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
- DB_PATH = File.join(__dir__, "../end_of_life.json")
9
+ class << self
10
+ include Dry::Monads[:try]
9
11
 
10
- EOL = File.read(DB_PATH)
11
- .then { |json| JSON.parse(json, symbolize_names: true) }
12
- .filter { |version| Date.parse(version[:eol]) <= Date.today }
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
- def self.from_file(file_name:, content:, parser: Parser)
17
- parser.parse_file(file_name: file_name, content: content)
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
- attr :version
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
- @version <= EOL
53
+ def eol?(at: Date.today)
54
+ self <= RubyVersion.latest_eol(at: at)
30
55
  end
31
56
 
32
57
  def <=>(other)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module EndOfLife
4
- VERSION = "0.2.0"
4
+ VERSION = "0.4.0"
5
5
  end
data/lib/end_of_life.json CHANGED
@@ -1,13 +1,98 @@
1
1
  [
2
- {"cycle": "3.1", "release": "2021-12-25", "eol": "2025-12-25", "latest": "3.1.0"},
3
- {"cycle": "3.0", "release": "2020-12-25", "eol": "2024-03-31", "latest": "3.0.3"},
4
- {"cycle": "2.7", "release": "2019-12-25", "eol": "2023-03-31", "latest": "2.7.5"},
5
- {"cycle": "2.6", "release": "2018-12-25", "eol": "2022-03-31", "latest": "2.6.9"},
6
- {"cycle": "2.5", "release": "2017-12-25", "eol": "2021-03-31", "latest": "2.5.9"},
7
- {"cycle": "2.4", "release": "2016-12-25", "eol": "2020-03-31", "latest": "2.4.10"},
8
- {"cycle": "2.3", "release": "2015-12-25", "eol": "2019-03-31", "latest": "2.3.8"},
9
- {"cycle": "2.2", "release": "2014-12-25", "eol": "2018-03-31", "latest": "2.2.10"},
10
- {"cycle": "2.1", "release": "2013-12-25", "eol": "2017-03-31", "latest": "2.1.10"},
11
- {"cycle": "2.0.0", "release": "2013-02-24", "eol": "2016-02-24", "latest": "2.0.0-p648"},
12
- {"cycle": "1.9.3", "release": "2011-10-31", "eol": "2015-02-23", "latest": "1.9.3-p551"}
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
- require "optparse"
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.2.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: 2022-01-26 00:00:00.000000000 Z
10
+ date: 2025-05-23 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
- name: octokit
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: '4.0'
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: '4.0'
39
+ version: '1.3'
27
40
  - !ruby/object:Gem::Dependency
28
- name: pastel
41
+ name: octokit
29
42
  requirement: !ruby/object:Gem::Requirement
30
43
  requirements:
31
44
  - - "~>"
32
45
  - !ruby/object:Gem::Version
33
- version: 0.8.0
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: 0.8.0
53
+ version: '9.0'
41
54
  - !ruby/object:Gem::Dependency
42
- name: dry-monads
55
+ name: pastel
43
56
  requirement: !ruby/object:Gem::Requirement
44
57
  requirements:
45
58
  - - "~>"
46
59
  - !ruby/object:Gem::Version
47
- version: '1.3'
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: '1.3'
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.7.0
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.32
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: []