Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: validate barcalendar project versions dates from eol #453

Merged
merged 2 commits into from
Nov 15, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions barcalendar.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,87 @@
import re
import time

import atexit
import logging
UsamaSadiq marked this conversation as resolved.
Show resolved Hide resolved
import requests
import yaml

def setup_custom_logging():
"""
Creating a custom logger to flush all Warning logs at the end of the script
UsamaSadiq marked this conversation as resolved.
Show resolved Hide resolved
to avoid breaking the console script being generated by the script
"""
class DelayedLogHandler(logging.Handler):
def __init__(self):
super().__init__()
self.log_messages = []

def emit(self, record):
self.log_messages.append(record)

def _flush_log_messages(handler):
for message in handler.log_messages:
print(message)
UsamaSadiq marked this conversation as resolved.
Show resolved Hide resolved

# Create a custom log handler
custom_log_handler = DelayedLogHandler()
custom_log_handler.setLevel(logging.WARNING)

# Create custom logger and attach custom_handler to it
eol_logger = logging.getLogger("eol_logger")
eol_logger.addHandler(custom_log_handler)

# Register a function to flush log messages at exit
atexit.register(_flush_log_messages, custom_log_handler)

# Return custom logger to use in the script
return eol_logger

def validate_version_date(project, version, year, month, check_start=False):
"""
Validates the end-of-life(EOL) or release date for a project version.
Returns the correct EOL/releaseDate in case of a conflict with api value.

Parameters:
project (str): The name of the project.
version (str): The version of the project.
year (int): The year of the EOL/release date.
month (int): The month of the EOL/release date.
check_start (bool): Boolean flag to check either EOL or release date

Returns:
tuple: A tuple representing the validated EOL/release date (year, month)
"""
try:
response = requests.get(
url=f"https://endoflife.date/api/{project}/{version}.json",
headers={'Accept': 'application/json'}
)

if response.status_code != 200:
eol_logger.error(f"Project not Found: {project}/{version} not found on endoflife.date")
return (year, month)

version_info = response.json()
if check_start:
eol_year, eol_month, _ = version_info['releaseDate'].split("-")
date_type = "releaseDate"
else:
if version_info['eol'] == False:
eol_logger.warning(f"No EOL found for {project} {version}")
return (year, month)
eol_year, eol_month, _ = version_info['eol'].split("-")
date_type = "eol"

if (year, month) == (int(eol_year), int(eol_month)):
return (year, month)
else:
eol_logger.warning(f"Invalid EOL: Update {project} {version} {date_type} to {eol_year}/{eol_month} instead")
UsamaSadiq marked this conversation as resolved.
Show resolved Hide resolved
return (int(eol_year), int(eol_month))
except requests.exceptions.RequestException as e:
eol_logger.error(f"API request failed with an exception: {str(e)}")
return (year, month)

def css_to_rgb(hex):
assert hex[0] == "#"
return [int(h, 16)/255 for h in [hex[1:3], hex[3:5], hex[5:7]]]
Expand Down Expand Up @@ -312,6 +390,7 @@ def parse_version_name(line):
return version_name.capitalize()
raise ValueError(f"Couldn't get version name from {line!r}")

eol_logger = setup_custom_logging()
# ==== Editable content ====

# Global Options
Expand Down Expand Up @@ -420,6 +499,7 @@ def parse_version_name(line):
('4.2', 2023, 4, True, "Django 4.2 work is being tracked in https://github.com/openedx/platform-roadmap/issues/269"),
]
for name, year, month, lts, *more in django_releases:
year, month = validate_version_date("Django", name, year, month, check_start=True)
if LTS_ONLY and not lts:
continue
length = 3*12 if lts else 16
Expand Down Expand Up @@ -449,6 +529,7 @@ def parse_version_name(line):
('3.12', 2023, 10, 2028, 10), # https://peps.python.org/pep-0693/
]
for name, syear, smonth, eyear, emonth in python_releases:
eyear, emonth = validate_version_date("Python", name, eyear, emonth)
cal.bar(
f"Python {name}",
start=(syear, smonth),
Expand Down Expand Up @@ -477,6 +558,7 @@ def parse_version_name(line):
nick = ubuntu_nicks.get(name, '')
if nick:
nick = f" {nick}"
year, month = validate_version_date("Ubuntu", name, 2000+year, month, check_start=True)
cal.bar(
f"Ubuntu {name}{nick}",
(2000+year, month),
Expand All @@ -500,6 +582,7 @@ def parse_version_name(line):
('18.x', 2022, 4, 2025, 4),
]
for name, syear, smonth, eyear, emonth in node_releases:
eyear, emonth = validate_version_date("NodeJS", name, eyear, emonth)
cal.bar(
f"Node {name}",
start=(syear, smonth),
Expand All @@ -523,6 +606,7 @@ def parse_version_name(line):
('4.4', 2020, 7, 2024, 2),
]
for name, syear, smonth, eyear, emonth in mongo_releases:
eyear, emonth = validate_version_date("mongo", name, eyear, emonth)
cal.bar(
f"Mongo {name}",
start=(syear, smonth),
Expand All @@ -542,6 +626,7 @@ def parse_version_name(line):
('8.1', 2023, 6, 2024, 9), # Not sure of the real support dates.
]
for name, syear, smonth, eyear, emonth in mysql_releases:
eyear, emonth = validate_version_date("MySQL", name, eyear, emonth)
cal.bar(
f"MySQL {name}",
start=(syear, smonth),
Expand All @@ -568,6 +653,7 @@ def parse_version_name(line):
('7.17', 2022, 2, 2023, 8),
]
for name, syear, smonth, eyear, emonth in es_releases:
eyear, emonth = validate_version_date("ElasticSearch", name, eyear, emonth)
cal.bar(
f"Elasticsearch {name}",
start=(syear, smonth),
Expand All @@ -588,6 +674,7 @@ def parse_version_name(line):
('7.0', 2022, 4, 2025, 4),
]
for name, syear, smonth, eyear, emonth in redis_releases:
eyear, emonth = validate_version_date("Redis", name, eyear, emonth)
cal.bar(
f"Redis {name}",
start=(syear, smonth),
Expand All @@ -611,6 +698,7 @@ def parse_version_name(line):
('3.1', 2021, 12, 2025, 3),
]
for name, syear, smonth, eyear, emonth, *more in ruby_releases:
eyear, emonth = validate_version_date("Ruby", name, eyear, emonth)
cal.bar(
f"Ruby {name}",
start=(syear, smonth),
Expand Down