#!/usr/bin/python
"""
SYNOPSIS
        ./merge-package-lists NEW-PARTIAL OLD-FULL

DESCRIPTION
        Updates the list of binary package artifacts in OLD-FULL to add or
        modify an packages in NEW-PARTIAL, then writes this list to both files.
        Safe to run more than once (the 2nd run will do nothing).

        The header comments are updated to be those from NEW-PARTIAL, as the
        idea is that a full rebuild from that tree would result in the same set
        of binary package content.
"""
import logging
import re
import os.path
import sys


class PackageList:

    pkg_re = re.compile(r'([0-9a-f]+)  (\S+)-([^-]+-[^-]+)\.([^.]+)\.rpm')

    def __init__(self, filepath):
        self.path = filepath
        self.header = []
        self.packages = {}
        if not os.path.exists(filepath):
            logging.warning("No file '%s', ignoring.", filepath)
            return
        with open(filepath) as fh:
            for line in fh:
                if line[0] == '#':
                    self.header.append(line)
                else:
                    m = self.pkg_re.match(line)
                    if m:
                        (checksum, name, version, arch) = m.groups()
                        self.packages[name] = line
                    else:
                        raise Exception("Malformed line: " + line)


def name_for_sorting(name):
    """Return package name mangled so it sorts the way eg-buildpkg sorts"""
    return name.replace('-', '').replace('.', '')

def main():
    logging.basicConfig(level=logging.DEBUG)

    new_partial = PackageList(sys.argv[1])
    old_full = PackageList(sys.argv[2])

    all_pkgs = sorted(set(new_partial.packages.keys() + old_full.packages.keys()), key=name_for_sorting)
    logging.debug("Merging new entries from '%s' with old '%s'", new_partial.path, old_full.path)
    out = sys.stdout
    for line in new_partial.header:
        out.write(line)
    for name in all_pkgs:
        if name in new_partial.packages:
            out.write(new_partial.packages[name])
        else:
            out.write(old_full.packages[name])

if __name__ == '__main__':
    main()
