Better implementation of 'latest'

- swi file timestamp is unreliable if clock is not set correctly
- extract build timestamp from manifest if available
- extract timestamp-ish string from 'version' file or from swi filename
This commit is contained in:
Carl D. Roth
2016-05-27 13:06:14 -07:00
parent b21007c70a
commit 35db5ffb43

View File

@@ -12,6 +12,9 @@ import subprocess
import shutil
import logging
import tempfile
import re
import json
import zipfile
import onl.install.InstallUtils
MountContext = onl.install.InstallUtils.MountContext
@@ -24,6 +27,98 @@ OnlMountManager = onl.mounts.OnlMountManager
import onl.network
HostInfo = onl.network.HostInfo
SWI_TIMESTAMP_FMT = "%Y-%m-%d.%H:%M"
SWI_TIMESTAMP_RE = re.compile(r"""
[0-9][0-9][0-9][0-9] [-] [0-9][0-9] [-] [0-9][0-9]
[.]
[0-9][0-9] [:] [0-9][0-9]
""", re.VERBOSE)
SWI_FNAME_TIMESTAMP_FMT = "%Y-%m-%d.%H%M"
SWI_FNAME_TIMESTAMP_RE = re.compile(r"""
[0-9][0-9][0-9][0-9] [-] [0-9][0-9] [-] [0-9][0-9]
[.]
[0-9][0-9] [0-9][0-9]
""", re.VERBOSE)
def versionSortKey(vstr):
m = SWI_TIMESTAMP_RE.search(vstr)
if m is not None:
try:
return time.mktime(time.strptime(m.group(0), SWI_TIMESTAMP_FMT))
except ValueError:
pass
m = SWI_FNAME_TIMESTAMP_RE.search(vstr)
if m is not None:
try:
return time.mktime(time.strptime(m.group(0), SWI_FNAME_TIMESTAMP_FMT))
except ValueError:
pass
return None
def manifestSortKey(mdata):
mdata = mdata.get('version', {})
vstr = mdata.get('BUILD_TIMESTAMP', None)
if vstr is not None:
try:
return time.mktime(time.strptime(vstr, SWI_TIMESTAMP_FMT))
except ValueError:
pass
vstr = mdata.get('FNAME_BUILD_TIMESTAMP', None)
if vstr is not None:
try:
return time.mktime(time.strptime(vstr, SWI_FNAME_TIMESTAMP_FMT))
except ValueError:
pass
return None
def swiSortKey(swiPath):
try:
zf = zipfile.ZipFile(swiPath, "r")
except zipfile.BadZipFile:
return os.path.getmtime(swiPath)
try:
fd = zf.open("manifest.json", "r")
except KeyError:
fd = None
if fd is not None:
data = json.load(fd)
fd.close()
else:
data = {}
ts = manifestSortKey(data)
if ts is not None: return ts
try:
fd = zf.open("version", "r")
except KeyError:
fd = None
if fd is not None:
vstr = fd.read()
fd.close()
else:
vstr = ""
ts = versionSortKey(vstr)
if ts is not None: return ts
ts = versionSortKey(swiPath)
if ts is not None: return ts
# maybe the timestamp is embedded into the filename
# else, use the filesytem mtime, which is less reliable
return os.path.getmtime(swiPath)
class Runner(onl.install.InstallUtils.SubprocessMixin):
def __init__(self, log):
@@ -188,7 +283,7 @@ class Runner(onl.install.InstallUtils.SubprocessMixin):
def latest(d):
l = [x for x in os.listdir(d) if x.endswith('.swi')]
l = [os.path.join(d, x) for x in l]
l.sort(key=os.path.getmtime)
l.sort(key=swiSortKey)
return l[-1]
pm = ProcMountsParser()