After this commit alone it would not work when installed (unless module paths are set in a special way). Next changes will introduce installation to site-packages so no custom PYTHONPATH will be necessary.
192 lines
5.8 KiB
Python
Executable File
192 lines
5.8 KiB
Python
Executable File
#!/usr/bin/python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
import os
|
|
import sys
|
|
import bz2
|
|
import tempfile
|
|
# so that time function with use american locale
|
|
for env in ("LANG", "LC_ALL", "LANGUAGE",):
|
|
os.environ[env] = "en_US.UTF-8"
|
|
|
|
import time
|
|
import calendar
|
|
|
|
from os import path as osp
|
|
_base = osp.dirname(osp.dirname(osp.realpath(__file__)))
|
|
if os.path.isfile(osp.join(_base, "entropy-in-vcs-checkout")):
|
|
sys.path.insert(0, osp.join(_base, "entropy_path_loader"))
|
|
import entropy_path_loader
|
|
del osp
|
|
|
|
from entropy.const import etpConst
|
|
from entropy.client.interfaces import Client
|
|
import entropy.tools
|
|
import entropy.dep
|
|
|
|
|
|
def _print_help():
|
|
sys.stdout.write(
|
|
"entropy-repository-statistics <machine name> <repository id> <branch> <arch> <product> <repository dir> <output file>\n\n")
|
|
|
|
def _handle_stat_lines(entropy_client, target_month, target_year,
|
|
changelog_file):
|
|
|
|
target_year_month = "%s%s" % (target_year, target_month)
|
|
|
|
date_format_string = etpConst['changelog_date_format']
|
|
in_range = False
|
|
commit_lines = []
|
|
date_header = "Date: "
|
|
atom_header = "Name: "
|
|
commit_header = "commit"
|
|
|
|
with open(changelog_file, "r") as changelog_f:
|
|
line = changelog_f.readline()
|
|
commit_line = ""
|
|
do_break = False
|
|
|
|
while line:
|
|
|
|
if line.startswith(date_header):
|
|
# extract date and check it maches this_month
|
|
date_str = line.lstrip(date_header).strip()
|
|
time_obj = time.strptime(date_str, date_format_string)
|
|
if (time_obj.tm_year == target_year) and \
|
|
(time_obj.tm_mon == target_month):
|
|
in_range = True
|
|
elif in_range:
|
|
# left the range, not worth parsing further, we're done
|
|
in_range = False
|
|
do_break = True
|
|
|
|
if in_range and line.startswith(atom_header):
|
|
atom = line.lstrip(atom_header).strip()
|
|
atom = entropy.dep.remove_entropy_revision(atom)
|
|
atom = entropy.dep.remove_tag(atom)
|
|
pkg_key = entropy.dep.dep_getkey(atom)
|
|
split_data = entropy.dep.catpkgsplit(atom)
|
|
if split_data is not None:
|
|
etp_cat, etp_name, ver, rev = split_data
|
|
if rev != "r0":
|
|
ver += "-"+rev
|
|
|
|
if line.startswith(commit_header):
|
|
if in_range:
|
|
commit_lines.append(commit_line)
|
|
commit_line = line
|
|
else:
|
|
commit_line += line
|
|
|
|
if do_break:
|
|
break
|
|
line = changelog_f.readline()
|
|
|
|
return commit_lines
|
|
|
|
def _calculate_stats(target_month, target_year, stat_lines):
|
|
stats = {
|
|
'bumps': len(stat_lines),
|
|
'recompiles': 0,
|
|
'revisions': 0,
|
|
'bumps/day': 0,
|
|
}
|
|
|
|
package_ids = []
|
|
revisions = set()
|
|
for stat_line in stat_lines:
|
|
commit_line = stat_line.split("\n")[0].lstrip("commit").strip()
|
|
revision, package_id, pkg_hash = commit_line.split(";")
|
|
revisions.add(revision)
|
|
package_ids.append(int(package_id))
|
|
|
|
package_ids.sort()
|
|
if package_ids:
|
|
stats['recompiles'] = abs(package_ids[-1] - package_ids[0])
|
|
stats['revisions'] = len(revisions)
|
|
|
|
days_in_month = calendar.monthrange(target_year, target_month)[1]
|
|
stats['bumps/day'] = round(float(stats['bumps']) / days_in_month, 2)
|
|
|
|
return stats
|
|
|
|
def _generate_statistics(entropy_client, machine, repository_id, branch,
|
|
arch, product, repository_dir, output_file):
|
|
|
|
tmp_fd = None
|
|
changelog_file = None
|
|
try:
|
|
tmp_fd, changelog_file = tempfile.mkstemp()
|
|
compressed_changelog_file = os.path.join(repository_dir,
|
|
etpConst['changelog_filename_compressed'])
|
|
|
|
entropy.tools.uncompress_file(compressed_changelog_file,
|
|
changelog_file, bz2.BZ2File)
|
|
|
|
target_month = int(os.getenv("ETP_M", int(time.strftime("%m")) - 1))
|
|
target_year = int(os.getenv("ETP_Y", time.strftime("%Y")))
|
|
if target_month == 0:
|
|
target_month = 12
|
|
target_year -= 1
|
|
stat_lines = _handle_stat_lines(entropy_client,
|
|
target_month, target_year, changelog_file)
|
|
finally:
|
|
if tmp_fd is not None:
|
|
os.close(tmp_fd)
|
|
if changelog_file is not None:
|
|
os.remove(changelog_file)
|
|
|
|
stats = _calculate_stats(target_month, target_year, stat_lines)
|
|
|
|
# header
|
|
header_str = """\
|
|
Sabayon Entropy build server statistics
|
|
Year: %s
|
|
Month: %s
|
|
-------------------------------------------------------------------------------
|
|
Machine: %s
|
|
Repository: %s
|
|
Branch: %s
|
|
Arch: %s
|
|
Product: %s
|
|
-------------------------------------------------------------------------------
|
|
Package bumps: %s
|
|
Recompiles: %s
|
|
Revisions: %s
|
|
Bumps/day: %s
|
|
""" % (target_year, target_month, machine, repository_id, branch, arch, product,
|
|
stats['bumps'], stats['recompiles'], stats['revisions'],
|
|
stats['bumps/day'])
|
|
|
|
with open(output_file, "w") as out_f:
|
|
out_f.write(header_str)
|
|
out_f.write(("="*79) + "\n\n")
|
|
|
|
# changelog
|
|
for line in stat_lines:
|
|
out_f.write(line)
|
|
out_f.flush()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
args = sys.argv[1:]
|
|
if len(args) != 7:
|
|
_print_help()
|
|
raise SystemExit(1)
|
|
|
|
# this expects that:
|
|
# "equo update" is called
|
|
|
|
entropy_client = None
|
|
try:
|
|
entropy_client = Client()
|
|
machine, repository_id, branch, arch, product, \
|
|
repository_dir, output_file = args
|
|
rc = _generate_statistics(entropy_client,
|
|
machine, repository_id, branch, arch, product,
|
|
repository_dir, output_file)
|
|
raise SystemExit(rc)
|
|
finally:
|
|
if entropy_client is not None:
|
|
entropy_client.shutdown()
|