Skip to content
Snippets Groups Projects
Commit d50bc7a8 authored by Jakub Ružička's avatar Jakub Ružička
Browse files

report: new command to generate version report

* new template module provides rendering of templates using jinja2
parent 9f827729
No related merge requests found
......@@ -5,6 +5,7 @@ cache_base_path = Path.home() / '.cache' / 'cznicinfo'
nv_cache_path = cache_base_path / 'nv'
nv_config_cache_path = nv_cache_path / 'config'
nv_versions_cache_path = nv_cache_path / 'versions'
report_cache_path = cache_base_path / 'report'
def ensure_cache_dirs():
......
"""
Generate report of various project(s) versions
Usage: cznicinfo report [-h] [-c] [-f] [-o <dir>] [<project>...]
Arguments:
<project> project(s) to generate report for (default: ALL)
Options:
-o <dir>, --outdir <dir> generate report into this directory
-c, --cached don't check versions, use cached data instead
-f, --force use force - delete outdir if it exists
-h, --help show command help
"""
from docopt import docopt
import os
from pathlib import Path
import shutil
from cznicinfo import cache
from cznicinfo import exception
from cznicinfo import infocore
from cznicinfo import infoquery
from cznicinfo import log
from cznicinfo import nv
from cznicinfo import template
def run_command(*args, **kwargs):
cargs = docopt(__doc__)
info = infocore.get_info()
if cargs['<project>']:
projs, not_found = infoquery.get_projects_by_name(
info, cargs['<project>'])
if not_found:
nf_str = ", ".join(not_found)
log.warn("following projects were not found: %s", nf_str)
else:
# all projects by default
projs = info.get('projects')
if not cargs['--cached']:
log.info("checking latest versions...")
for proj in projs:
nv.save_nv_config(proj)
nv.run_nv_check(proj)
if cargs['--outdir']:
outdir = Path(cargs['--outdir'])
if outdir.exists():
if cargs['--force']:
log.verbose("removing existing report dir with --force: %s",
outdir)
shutil.rmtree(outdir)
else:
msg = "selected --outdir exists (override with -f/--force)"
raise exception.OutputExists(msg=msg)
else:
outdir = cache.report_cache_path
if outdir.exists():
# cached report dir can be overwritten without force
shutil.rmtree(outdir)
log.info("generating version report...")
os.makedirs(outdir)
index = gen_versions_report(projs, outdir)
print("report index: %s" % index)
return 0
def gen_versions_report(projects, out_dir):
out_dir = Path(out_dir)
for proj in projects:
proj['versions'] = nv.load_versions_by_distro(proj)
vars = {
'projects': projects,
}
index = template.render_template('report/index.html', out_dir, vars)
template.copy_template('report/style.css', out_dir)
return index
......@@ -63,6 +63,11 @@ class InvalidFormat(CZNICInfoException):
exit_code = 18
class OutputExists(CZNICInfoException):
msg_fmt = "Output exists: %(out)s"
exit_code = 30
class HTTPRequestFailed(CZNICInfoException):
msg_fmt = "HTTP request failed with code %(code)s: %(request)s"
exit_code = 44
......
......@@ -39,12 +39,48 @@ def load_nv_versions(project, postfix='new'):
return json.load(verfile.open())
def load_versions_by_distro(project):
versions = load_nv_versions(project)
return versions_by_distro(project, versions)
def versions_by_distro(project, versions):
distros = infocore.get_supported_distros()
nv_versions = load_nv_versions(project)
versions = []
dpkgs = project.get('distro-pkgs', [])
for dpkg in dpkgs:
dpkg_distro = dpkg.get('distro')
if dpkg_distro not in distros:
msg = "distro info not available for: %s"
log.warn(msg, dpkg_distro)
continue
distro = distros[dpkg_distro]
distro_name = distro['name']
distro_vers = []
for release in distro.get('releases', []):
distro_version = release['version']
distro_id = nvid(distro_name, distro_version)
ver = nv_versions.get(distro_id)
dv = {'distro_version': distro_version}
dv['version'] = ver or 'N/A'
distro_vers.append(dv)
versions.append({
'distro': distro_name,
'versions': distro_vers,
})
return versions
def get_nv_entry(project, distro, release):
pkg_name = project['short-name']
distro_name = distro['name']
distro_version = str(release['version'])
distro_id = nvid("%s-%s" % (distro_name, distro_version))
nv_source = distro['nv_source']
distro_id = nvid(distro_name, distro_version)
e = "[%s]\n" % distro_id
e += 'source = "%s"\n' % nv_source
e += '%s = "%s"\n' % (nv_source, pkg_name)
......@@ -62,5 +98,6 @@ def get_nv_head(name):
old=old_path, new=new_path))
def nvid(s):
return re.sub(r'\W+', '-', s.lower())
def nvid(distro, version):
dv = "%s-%s" % (distro, version)
return re.sub(r'\W+', '-', dv.lower())
import jinja2
from pathlib import Path
import shutil
def get_template_path(template_fn, module_path=None):
if module_path:
path = module_path
else:
import cznicinfo
path = Path(cznicinfo.__file__).parent / 'templates'
return path / template_fn
def render_template(template_path, out_dir, vars):
src = get_template_path(template_path)
dst = out_dir / src.name
with src.open('r') as srcf:
t = jinja2.Template(srcf.read())
with dst.open('w') as dstf:
dstf.write(t.render(**vars) + '\n')
return dst
def copy_template(template_path, out_dir):
src = get_template_path(template_path)
dst = out_dir / src.name
shutil.copyfile(src, dst)
return dst
<html lang="en">
<head>
<title>CZ.NIC info: packaging versions report</title>
<meta charset="utf-8"/>
<link href="style.css" rel="stylesheet" type="text/css"/>
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet"/>
</head>
<body>
<h1>cznicinfo report</h1>
{% for proj in projects %}
<h2>{{ proj['full-name'] }}</h2>
{% for distro in proj['versions'] %}
<h3>{{ distro['distro'] }}</h3>
{% for ver in distro['versions'] %}
<div class="ver">
<h4>{{ ver['distro_version'] }}</h4>
<div>{{ ver['version'] }}</div>
</div>
{% endfor %}
{% endfor %}
{% endfor %}
</tr>
</table
</body>
h1, h2, h3, h4, h5 {
clear: both;
margin: 1ex 0ex 0ex 0ex;
}
.ver {
float: left;
display: block;
padding: 0.5ex 1ex;
}
.ver h4 {
margin: 0;
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment