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: Improve version checking for cvdupdate package #67

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
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
6 changes: 3 additions & 3 deletions cvdupdate/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,16 @@

import logging
import os
from pathlib import Path
import sys
from pathlib import Path

import click
import coloredlogs
import importlib.metadata
from http.server import HTTPServer
from RangeHTTPServer import RangeRequestHandler

from cvdupdate import auto_updater
import pkg_resources
from cvdupdate.cvdupdate import CVDUpdate

logging.basicConfig()
Expand All @@ -58,7 +58,7 @@
+ __doc__ + "\n"
+ Fore.GREEN
+ _description + "\n"
+ f"\nVersion {pkg_resources.get_distribution('cvdupdate').version}\n"
+ f"\nVersion {importlib.metadata.version('cvdupdate')}\n"
+ Style.RESET_ALL
+ _copyright,
)
Expand Down
69 changes: 37 additions & 32 deletions cvdupdate/cvdupdate.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,27 @@
limitations under the License.
"""

from pathlib import Path
import copy
import datetime
from enum import Enum
import http.client as http_client
import json
import logging
import os
import platform
import pkg_resources
import re
import subprocess
import sys
import time
from typing import *
import uuid
import http.client as http_client
from enum import Enum
from pathlib import Path
from typing import *

from dns import resolver
import importlib.metadata
import requests
from requests import status_codes
from dns import resolver
from packaging import version
from requests import status_codes # Often redundant if you're already using `requests.*`

class CvdStatus(Enum):
NO_UPDATE = 0
Expand Down Expand Up @@ -117,7 +118,7 @@ def __init__(
db_dir: path where databases will be downloaded.
verbose: Enable DEBUG-level logs and other verbose messages.
"""
self.version = pkg_resources.get_distribution('cvdupdate').version
self.version = importlib.metadata.version('cvdupdate')
self.verbose = verbose
self._read_config(
config,
Expand Down Expand Up @@ -897,33 +898,37 @@ def _get_cvd_version_from_file(self, path: Path) -> int:

def pypi_update_check(self):
def check(name):
'''
Check if there's a newer version of the cvdupdate package.
From https://stackoverflow.com/questions/58648739/how-to-check-if-python-package-is-latest-version-programmatically
'''
self.logger.debug(f'Checking for a newer version of cvdupdate.')
"""Checks if a newer version of the specified module is available on PyPI."""
self.logger.debug(f'Checking for a newer version of {name}.')
try:
current_version_str = importlib.metadata.version(name)
current_version = version.parse(current_version_str)

result = subprocess.run([sys.executable, '-m', 'pip', 'install', '{}==random'.format('cvdupdate')], stdout=subprocess.DEVNULL, stderr=subprocess.PIPE)
latest_version = result.stderr.decode("utf-8")
latest_version = latest_version[latest_version.find('(from versions:')+15:]
latest_version = latest_version[:latest_version.find(')')]
latest_version = latest_version.replace(' ','').split(',')[-1].strip()
response = requests.get(f"https://pypi.org/pypi/{name}/json") # Get package info
response.raise_for_status() # Raise an exception for bad status codes (4xx or 5xx)
latest_version_str = response.json()["info"]["version"]
latest_version = version.parse(latest_version_str)

result = subprocess.run([sys.executable, '-m', 'pip', 'show', '{}'.format('cvdupdate')], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
current_version = result.stdout.decode("utf-8")
current_version = current_version[current_version.find('Version:')+8:]
current_version = current_version[:current_version.find('\n')].replace(' ','').strip()
if latest_version > current_version:
self.logger.warning(f'You are running {name} version: {current_version}.')
self.logger.warning(f'There is a newer version on PyPI: {latest_version}. Please update!')
return False # Newer version available

if 'ERROR' in latest_version:
self.logger.debug(f"Version check didn't work, didn't get back a list of package versions.")
return True
elif latest_version == current_version:
self.logger.debug(f'cvdupdate is up-to-date: {current_version}.')
return True
else:
self.logger.warning(f'You are running cvdupdate version: {current_version}.')
self.logger.warning(f'There is a newer version on PyPI: {latest_version}. Please update!')
return False
else:
self.logger.debug(f'{name} is up-to-date: {current_version}.')
return True # No newer version

except requests.exceptions.RequestException as e:
self.logger.debug(f"Version check failed: {e}") # Log the error
return True # Assume up-to-date on error

except importlib.metadata.PackageNotFoundError:
self.logger.error(f"Package {name} not found locally.")
return True # Assuming not found means no update possible

except Exception as e: # Catch other potential errors (json parsing etc.)
self.logger.debug(f"Version check failed: {e}")
return True # Assume up-to-date on error

return check('cvdupdate')

Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"dnspython>=2.1.0",
"rangehttpserver",
"setuptools",
"packaging",
],
classifiers=[
"Programming Language :: Python :: 3",
Expand Down