aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rwxr-xr-xdlpcvp.py94
2 files changed, 79 insertions, 17 deletions
diff --git a/.gitignore b/.gitignore
index 5b478e6..0697a1c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
__pycache__/
*.log
+dlpcvp-log*.txt
+*.db
diff --git a/dlpcvp.py b/dlpcvp.py
index bab5ee9..8e117ab 100755
--- a/dlpcvp.py
+++ b/dlpcvp.py
@@ -7,10 +7,11 @@ import json
import logging
import os
import os.path
-# import sqlite3
+import sqlite3
import sys
import tempfile
import urllib.request
+from distutils.version import LooseVersion
from urllib.error import HTTPError
from urllib.request import Request, urlopen
from typing import Iterable, Optional, Tuple
@@ -30,7 +31,7 @@ config = configparser.ConfigParser()
config.read(ConfigRC)
logging.basicConfig(format='%(levelname)s:%(funcName)s:%(message)s',
- level=logging.DEBUG)
+ stream=sys.stdout, level=logging.DEBUG)
log = logging.getLogger()
# or HTTPPasswordMgrWithPriorAuth ?
@@ -43,6 +44,15 @@ handler = urllib.request.HTTPBasicAuthHandler(password_mgr)
opener = urllib.request.build_opener(handler)
urllib.request.install_opener(opener)
+TB_EXISTS = """SELECT name FROM sqlite_master
+ WHERE type='table' AND name='etags'
+ """
+TB_CREATE = """CREATE TABLE etags
+ (pkg text NOT NULL,
+ suse_name_etag text, suse_spec_etag text, pypi_etag text)
+ """
+TB_CREATE_IDX = "CREATE UNIQUE INDEX etags_names ON etags(pkg)"
+
def get_version_from_pypi(name: str, etag: str = None) -> Tuple[str, str, str]:
"""
@@ -61,6 +71,7 @@ def get_version_from_pypi(name: str, etag: str = None) -> Tuple[str, str, str]:
except HTTPError as ex:
if ex.getcode() == 404:
log.error(f'Cannot find {name} on PyPI')
+ return None
else:
raise
@@ -87,7 +98,7 @@ def suse_packages(proj: str) -> Iterable[str]:
raise
-def parse_spec_in_dev_null(spec, pkg, e_fn, e_spcf):
+def parse_spec_in_dev_null(spec_file, pkg, e_fn, e_spcf):
# rpm library generates awful lot of nonsensical goo on
# stderr
with open(os.devnull, 'wb') as nullf:
@@ -96,12 +107,12 @@ def parse_spec_in_dev_null(spec, pkg, e_fn, e_spcf):
sys.stderr = nullf
sys.stdout = nullf
try:
- spc = rpm.spec(spec)
+ spc = rpm.spec(spec_file)
except Exception:
log.error("Cannot parse {}".format(pkg))
else:
try:
- return spc.packages[0].header['Version'].decode(), \
+ return pkg, spc.packages[0].header['Version'].decode(), \
e_fn, e_spcf
except IndexError:
pass
@@ -110,6 +121,27 @@ def parse_spec_in_dev_null(spec, pkg, e_fn, e_spcf):
sys.stdout = old_stdout
+def get_etags(con, pkg):
+ cur = con.execute("SELECT * FROM etags WHERE pkg=?", (pkg,))
+ ret = cur.fetchone()
+ if ret is None:
+ return None, None, None, None
+ else:
+ return ret
+
+
+def update_etags(con, pkg, e_suse_name, e_suse_spec, e_pypi):
+ if con.execute("SELECT * FROM etags WHERE pkg=?", (pkg,)).fetchone():
+ con.execute('''UPDATE etags
+ SET suse_name_etag=?, suse_spec_etag=?, pypi_etag=?
+ WHERE pkg=?''', (e_suse_name, e_suse_spec, e_pypi, pkg))
+ else:
+ con.execute('''INSERT INTO etags
+ (pkg, suse_name_etag, suse_spec_etag, pypi_etag)
+ VALUES (?, ?, ?, ?)''', (pkg, e_suse_name, e_suse_spec, e_pypi))
+ con.commit()
+
+
def package_version(proj: str, pkg_name: str,
etag_fn: str = None, etag_spcf: str = None) \
-> Optional[Tuple[str, str, str]]:
@@ -136,6 +168,7 @@ def package_version(proj: str, pkg_name: str,
except HTTPError as ex:
if ex.getcode() == 404:
log.error(f'Cannot accquire version of {pkg_name} in {proj}')
+ return
else:
raise
@@ -174,18 +207,45 @@ def package_version(proj: str, pkg_name: str,
def main(prj):
- for pkg in suse_packages(prj):
- log.debug(f'pkg = {pkg}')
- if pkg.startswith('python-'):
- pypi_name = pkg[CUTCHARS:]
- pypi_ver = get_version_from_pypi(pypi_name)
- suse_ver = package_version(prj, pkg)
- # FIXME We should somehow react to the situation, not just
- # ignore it.
- if suse_ver is not None:
- print(f"{pkg} {suse_ver} {pypi_ver}")
- else:
- print(f'Is {pkg} on PyPI?')
+ db_name = os.path.split(os.path.basename(sys.argv[0]))[0] + ".db"
+ with sqlite3.connect(db_name) as conn:
+ if not conn.execute(TB_EXISTS).fetchone():
+ conn.execute(TB_CREATE)
+ conn.execute(TB_CREATE_IDX)
+
+ for pkg in suse_packages(prj):
+ log.debug(f'pkg = {pkg}')
+ if pkg.startswith('python-'):
+ pypi_name = pkg[CUTCHARS:]
+ _, et_suse_name, et_suse_spec, et_pypi = get_etags(conn, pkg)
+
+ try:
+ suse_ver_tup = package_version(prj, pkg,
+ et_suse_name, et_suse_spec)
+ if suse_ver_tup is None:
+ raise RuntimeError('not in OBS')
+
+ pypi_ver_tup = get_version_from_pypi(pypi_name, et_pypi)
+ if pypi_ver_tup is None:
+ raise RuntimeError('not in PyPI')
+
+ update_etags(conn, pkg,
+ suse_ver_tup[1], suse_ver_tup[2],
+ pypi_ver_tup[2])
+ except RuntimeError as ex:
+ log.warning(f'Package {pkg} cannot be found: {ex}')
+ continue
+
+ log.debug(f"{pkg} {suse_ver_tup} {pypi_ver_tup}")
+
+ pypi_ver = LooseVersion(pypi_ver_tup[1])
+ suse_ver = LooseVersion(suse_ver_tup[1])
+
+ if pypi_ver > suse_ver:
+ print(
+ f'We need to upgrade {pkg} ({suse_ver} -> {pypi_ver})')
+ else:
+ print(f'Is {pkg} on PyPI?')
if __name__ == '__main__':