Automated PaŃkage versions update for tags
Module repos.py
- ReposInfo(), walks mirror using HTTP and builds
all repos map available
- RepoManager(), using repos map builds package versions map
either for specific tags or for all of them
Fixes:
- Progress class clears line remainder on change
Utils:
- Download GZ file into memory
- TGZ file interface, CRU (no deletion)
Change-Id: Ifdb37aa4b68fb25f642b2089cf16cd242ed25a0b
Related-PROD: PROD-28199
diff --git a/cfg_checker/helpers/console_utils.py b/cfg_checker/helpers/console_utils.py
index 5c32506..d1db2a1 100644
--- a/cfg_checker/helpers/console_utils.py
+++ b/cfg_checker/helpers/console_utils.py
@@ -2,6 +2,9 @@
class Progress(object):
+ _strsize = 0
+ _note_size = 0
+
def __init__(self, max_index, bar_size=21):
self.total = max_index
# bar size in symbols
@@ -9,21 +12,35 @@
def write_progress(self, index, note=''):
# calc index and percent values
+ _suffix = ''
+ new_size = len(note)
+ if self._note_size > new_size:
+ _suffix = ' '*(self._note_size - new_size)
_percent = (100 * index) / self.total
_index = (self.bar_size * index) / self.total
# clear the line
sys.stdout.write('\r')
# print new progress
_format = "[{:"+str(self.bar_size-1)+"}] {}/{} ({}%) {}"
- sys.stdout.write(_format.format(
+ _progress_string = _format.format(
'='*_index,
index,
self.total,
_percent,
- note
- ))
+ note + _suffix
+ )
+ sys.stdout.write(_progress_string)
+ # Save new note size and whole string size
+ self._strsize = len(_progress_string)
+ self._note_size = new_size
sys.stdout.flush()
- @staticmethod
- def newline():
+ def clearline(self):
+ sys.stdout.write('\r')
+ sys.stdout.write(' '*self._strsize)
+ sys.stdout.write('\r')
+
+ def end(self):
+ self._note_size = 0
+ self._strsize = 0
sys.stdout.write('\n')
diff --git a/cfg_checker/helpers/tgz.py b/cfg_checker/helpers/tgz.py
new file mode 100644
index 0000000..631125e
--- /dev/null
+++ b/cfg_checker/helpers/tgz.py
@@ -0,0 +1,137 @@
+import os
+import tarfile as tarfile
+import tempfile
+
+from cfg_checker.common import logger_cli
+from cfg_checker.common.exception import ConfigException
+
+
+class TGZFile(object):
+ basefile = None
+
+ def __init__(self, _filepath, label=None):
+ # Check if this filename exists
+ if not os.path.exists(_filepath):
+ # If the archive not exists, create it
+ # simple labelfile for a non-empty archive
+ _labelname = "labelfile"
+ with tempfile.TemporaryFile() as _tempfile:
+ _tempfile.write(label.encode('utf-8'))
+ _tempfile.flush()
+ _tempfile.seek(0)
+ # create tgz
+ with tarfile.open(_filepath, "w:gz") as tgz:
+ _info = tgz.gettarinfo(
+ arcname=_labelname,
+ fileobj=_tempfile
+ )
+ tgz.addfile(_info, fileobj=_tempfile)
+ logger_cli.debug("... created file '{}'".format(_filepath))
+ self.basefile = _filepath
+
+ elif not os.path.isfile(_filepath):
+ # if path exists, and it is not a file
+ raise ConfigException(
+ "Supplied path of '{}' is not a file".format(
+ _filepath
+ )
+ )
+ elif not tarfile.is_tarfile(_filepath):
+ # if file exists, and it is not a tar file
+ raise ConfigException(
+ "Supplied file of '{}' is not a TAR stream".format(
+ _filepath
+ )
+ )
+ else:
+ self.basefile = _filepath
+
+ def get_file(self, name):
+ if self.has_file(name):
+ with tarfile.open(self.basefile, "r:gz") as tgz:
+ _tgzitem = tgz.extractfile(tgz.getmember(name))
+ return _tgzitem.read()
+ else:
+ return None
+
+ def add_file(self, name, buf=None, replace=False):
+ _files = []
+ with tarfile.open(self.basefile) as r:
+ _files = r.getnames()
+ _exists = name in _files
+ if _exists and not replace:
+ # file exists and replace flag is not set
+ return False
+
+ # check if there is work to do
+ if not buf and not os.path.exists(name):
+ # Nothing to do: no buffer or file to add
+ return False
+ elif name in self.list_files() and not replace:
+ # file already there and replace flag not set
+ return False
+
+ _a = "replace" if replace else "add"
+ logger_cli.debug("... about to {} '{}' ({:.2f}MB) -> '{}'".format(
+ _a,
+ name,
+ float(len(buf))/1024/1024,
+ self.basefile
+ ))
+
+ # unzip tar, add file, zip it back
+ _tmpdir = tempfile.mkdtemp()
+ logger_cli.debug("... created tempdir '{}'".format(_tmpdir))
+ # extract them
+ _files = []
+ with tarfile.open(self.basefile) as r:
+ # all names extracted
+ _files = r.getnames()
+ # extract 'em
+ logger_cli.debug("... extracting contents")
+ r.extractall(_tmpdir)
+
+ # create file
+ if buf:
+ _p = os.path.join(_tmpdir, name)
+ logger_cli.debug("... writing new file to '{}'".format(
+ _p
+ ))
+ if not _exists or replace:
+ with open(_p, "w") as w:
+ w.write(buf)
+ if not _exists:
+ _files.append(name)
+ # create the archive
+ logger_cli.debug("... rebuilding archive")
+ with tarfile.open(self.basefile, "w:gz") as tgz:
+ for _file in _files:
+ _p = os.path.join(_tmpdir, _file)
+ tgz.add(_p, arcname=_file)
+ os.remove(_p)
+ os.rmdir(_tmpdir)
+ return True
+
+ def list_files(self):
+ # get names
+ with tarfile.open(self.basefile, "r:gz") as tgz:
+ _names = tgz.getnames()
+ # filter filenames only, skip path
+ if any(['/' in _n for _n in _names]):
+ _n = []
+ for f in _names:
+ if '/' in f:
+ _n.append(f.rsplit('/', 1)[1])
+ else:
+ _n.append(f)
+ return _n
+ else:
+ return _names
+
+ def has_file(self, name):
+ if name in self.list_files():
+ logger_cli.debug("... '{}' has '{}'".format(self.basefile, name))
+ return True
+ else:
+ logger_cli.debug("... '{}' lacks '{}'".format(self.basefile, name))
+ return False
diff --git a/cfg_checker/helpers/zip.py b/cfg_checker/helpers/zip.py
new file mode 100644
index 0000000..b050030
--- /dev/null
+++ b/cfg_checker/helpers/zip.py
@@ -0,0 +1,8 @@
+import os
+import zipfile
+
+
+class ZIPFile(object):
+ def __init__(self, _filepath, label=None):
+
+ return