end_of_life 0.4.1 → 0.5.1
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 +13 -1
- data/Gemfile +1 -1
- data/Gemfile.lock +44 -33
- data/README.md +23 -14
- data/end_of_life.gemspec +7 -3
- data/lib/end_of_life/api.rb +17 -0
- data/lib/end_of_life/cli.rb +7 -58
- data/lib/end_of_life/helpers/silent_bundler.rb +18 -0
- data/lib/end_of_life/{terminal_helper.rb → helpers/terminal.rb} +1 -1
- data/lib/end_of_life/in_memory_file.rb +3 -0
- data/lib/end_of_life/options.rb +18 -14
- data/lib/end_of_life/parsers/gemfile.rb +31 -0
- data/lib/end_of_life/parsers/gemfile_lock.rb +16 -0
- data/lib/end_of_life/parsers/ruby_version.rb +11 -0
- data/lib/end_of_life/parsers/tool_versions.rb +23 -0
- data/lib/end_of_life/product/registry.rb +23 -0
- data/lib/end_of_life/product/release.rb +30 -0
- data/lib/end_of_life/product.rb +32 -0
- data/lib/end_of_life/report.rb +35 -0
- data/lib/end_of_life/repository/search/query.rb +31 -0
- data/lib/end_of_life/repository/search.rb +45 -0
- data/lib/end_of_life/repository.rb +17 -81
- data/lib/end_of_life/scanner.rb +41 -0
- data/lib/end_of_life/version.rb +1 -1
- data/lib/end_of_life/version_detector.rb +27 -0
- data/lib/end_of_life/version_detectors/rails.rb +26 -0
- data/lib/end_of_life/version_detectors/ruby.rb +35 -0
- data/lib/end_of_life/version_detectors.rb +17 -0
- data/lib/end_of_life.rb +10 -7
- metadata +60 -10
- data/lib/end_of_life/ruby_version/parser.rb +0 -96
- data/lib/end_of_life/ruby_version.rb +0 -69
- data/lib/end_of_life.json +0 -98
@@ -1,96 +0,0 @@
|
|
1
|
-
require "bundler"
|
2
|
-
require "tempfile"
|
3
|
-
|
4
|
-
module EndOfLife
|
5
|
-
class RubyVersion
|
6
|
-
module Parser
|
7
|
-
extend self
|
8
|
-
|
9
|
-
def parse_file(file_name:, content:)
|
10
|
-
return if content.strip.empty?
|
11
|
-
|
12
|
-
version = if file_name == ".ruby-version"
|
13
|
-
parse_ruby_version_file(content)
|
14
|
-
elsif file_name == "Gemfile.lock"
|
15
|
-
parse_gemfile_lock_file(content)
|
16
|
-
elsif file_name == "Gemfile"
|
17
|
-
parse_gemfile_file(content)
|
18
|
-
elsif file_name == ".tool-versions"
|
19
|
-
parse_tool_versions_file(content)
|
20
|
-
else
|
21
|
-
raise ArgumentError, "Unsupported file #{file_name}"
|
22
|
-
end
|
23
|
-
|
24
|
-
# Gem::Version is pretty forgiving and will accept empty strings
|
25
|
-
# as valid versions. This is a catch-all to ensure we don't return
|
26
|
-
# a version 0, which always takes precedence over any other version
|
27
|
-
# when comparing.
|
28
|
-
return if version&.zero?
|
29
|
-
|
30
|
-
version
|
31
|
-
end
|
32
|
-
|
33
|
-
private
|
34
|
-
|
35
|
-
def parse_ruby_version_file(file_content)
|
36
|
-
string_version = file_content.strip.delete_prefix("ruby-")
|
37
|
-
|
38
|
-
RubyVersion.new(string_version)
|
39
|
-
end
|
40
|
-
|
41
|
-
def parse_gemfile_lock_file(file_content)
|
42
|
-
with_silent_bundler do
|
43
|
-
gemfile_lock_version = Bundler::LockfileParser.new(file_content).ruby_version
|
44
|
-
return if gemfile_lock_version.nil?
|
45
|
-
|
46
|
-
RubyVersion.new(gemfile_lock_version.delete_prefix("ruby "))
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def parse_gemfile_file(file_content)
|
51
|
-
with_temp_gemfile(file_content) do |temp_gemfile|
|
52
|
-
gemfile_version = temp_gemfile.ruby_version&.gem_version
|
53
|
-
return if gemfile_version.nil?
|
54
|
-
|
55
|
-
RubyVersion.new(gemfile_version)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def parse_tool_versions_file(file_content)
|
60
|
-
file_content
|
61
|
-
.split("\n")
|
62
|
-
.filter_map do |line|
|
63
|
-
tool, version = line.strip.split
|
64
|
-
|
65
|
-
tool == "ruby" && RubyVersion.new(version)
|
66
|
-
end
|
67
|
-
.first
|
68
|
-
end
|
69
|
-
|
70
|
-
def with_silent_bundler
|
71
|
-
previous_ui = Bundler.ui
|
72
|
-
Bundler.ui = Bundler::UI::Silent.new
|
73
|
-
|
74
|
-
yield
|
75
|
-
ensure
|
76
|
-
Bundler.ui = previous_ui
|
77
|
-
end
|
78
|
-
|
79
|
-
def with_temp_gemfile(contents)
|
80
|
-
# Bundler requires a file to parse, so we need to create a temporary file
|
81
|
-
Tempfile.create("tempGemfile") do |tempfile|
|
82
|
-
tempfile.write(contents)
|
83
|
-
tempfile.rewind
|
84
|
-
gemfile = with_silent_bundler do
|
85
|
-
# This is security problem, since it runs the code inside the file
|
86
|
-
Bundler::Definition.build(tempfile.path, nil, {})
|
87
|
-
end
|
88
|
-
|
89
|
-
yield(gemfile)
|
90
|
-
rescue Bundler::BundlerError
|
91
|
-
nil
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
@@ -1,69 +0,0 @@
|
|
1
|
-
require "net/http"
|
2
|
-
require "rubygems"
|
3
|
-
require_relative "ruby_version/parser"
|
4
|
-
|
5
|
-
module EndOfLife
|
6
|
-
class RubyVersion
|
7
|
-
include Comparable
|
8
|
-
|
9
|
-
ZERO = Gem::Version.new("0")
|
10
|
-
|
11
|
-
class << self
|
12
|
-
include Dry::Monads[:try]
|
13
|
-
|
14
|
-
def from_file(file_name:, content:, parser: Parser)
|
15
|
-
parser.parse_file(file_name: file_name, content: content)
|
16
|
-
end
|
17
|
-
|
18
|
-
def eol_versions_at(date)
|
19
|
-
all_versions.filter { |version| version.eol_date <= date }
|
20
|
-
end
|
21
|
-
|
22
|
-
def latest_eol(at: Date.today)
|
23
|
-
eol_versions_at(at).max
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
EOL_API_URL = "https://endoflife.date/api/ruby.json"
|
29
|
-
DB_PATH = File.join(__dir__, "../end_of_life.json")
|
30
|
-
|
31
|
-
def all_versions
|
32
|
-
@all_versions ||= (fetch_end_of_life_api || load_file_fallback)
|
33
|
-
.then { |json| JSON.parse(json, symbolize_names: true) }
|
34
|
-
.map { |version| new(version[:latest], eol_date: Date.parse(version[:eol])) }
|
35
|
-
end
|
36
|
-
|
37
|
-
def fetch_end_of_life_api
|
38
|
-
Try { Net::HTTP.get URI(EOL_API_URL) }.value_or(nil)
|
39
|
-
end
|
40
|
-
|
41
|
-
def load_file_fallback
|
42
|
-
File.read(DB_PATH)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
attr_reader :version, :eol_date
|
47
|
-
|
48
|
-
def initialize(version_string, eol_date: nil)
|
49
|
-
@version = Gem::Version.new(version_string)
|
50
|
-
@eol_date = eol_date
|
51
|
-
|
52
|
-
freeze
|
53
|
-
end
|
54
|
-
|
55
|
-
def eol?(at: Date.today)
|
56
|
-
self <= RubyVersion.latest_eol(at: at)
|
57
|
-
end
|
58
|
-
|
59
|
-
def <=>(other)
|
60
|
-
@version <=> other.version
|
61
|
-
end
|
62
|
-
|
63
|
-
def zero? = @version == ZERO
|
64
|
-
|
65
|
-
def to_s
|
66
|
-
@version.to_s
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
data/lib/end_of_life.json
DELETED
@@ -1,98 +0,0 @@
|
|
1
|
-
[
|
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
|
-
}
|
98
|
-
]
|