Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wishlist] Produce comparison output into the terminal instead of html #32

Open
yarikoptic opened this issue Jan 26, 2018 · 1 comment

Comments

@yarikoptic
Copy link

html is nice et al, but what I often want is just to get a quick overview on how two things differ. Now for little comparisons it is a multistage procedure requiring running pkgdiff, opening the browser, closing the browser, removing the file. If there was a mode just to print information in the output of running of pkgdiff, it would be great.

E.g. debdiff in Debian world lists files which are present in one package but not in the other, and vise versa. The same could be done by pkgdiff.

@blakev
Copy link

blakev commented Feb 1, 2018

I'm experimenting with pkgdiff for my workflow and needed this too. This is the python code I wrote to extract the information; you can use it if you want.

class Status(IntEnum):
    ADDED = 1
    CHANGED = 0
    MOVED = 3
    REMOVED = 2
    RENAMED = 4
    ERROR = 99


status_cmp = {
    'added': Status.ADDED,
    'changed': Status.CHANGED,
    'moved': Status.MOVED,
    'removed': Status.REMOVED,
    'renamed': Status.RENAMED
}

def run_pkgdiff(path_lo, path_hi, dest=None):
    """Compare two .tar archives and generate a report of their difference.

    Args:
        path_lo (str):
        path_hi (str):
        dest (str):

    Returns:
        str:
    """

    if not check_tar(path_lo) and check_tar(path_hi):
        logger.error('cannot compare non tar archives, %s or %s', path_lo, path_hi)
        return None

    if dest is None:
        dest = tempfile.gettempdir()

    if os.path.isdir(dest):
        dest = os.path.join(dest, 'report.html')

    dest = os.path.abspath(dest)

    command = 'pkgdiff %s %s -hide-unchanged -list-added-removed -quick -report-path %s' % (
        path_lo, path_hi, dest)

    success = _run_process(command, track_output=True, success_statuses=(0, 1,))
    return dest if success else None


def generate_diff(report_path):
    """Generate a list of files to pick/choose for the new distribution."""

    if not report_path or not os.path.exists(report_path):
        logger.error('cannot parse report, %s', report_path)
        return None

    with open(report_path, 'r') as ins_file:
        soup = BeautifulSoup(ins_file, 'lxml')

    logger.debug('created report %s', report_path)

    try:

        headers = list(soup.find_all('h2'))
        # ignore: Test Info, Test Results, Changes in Files . . . Packages
        headers = headers[3:-1]

        for section in headers:
            # each table represents all the file changes of a certain "type"
            table = section.find_next('table')
            rows = iter(table.findChildren('tr'))

            for row in rows:
                # each row is an individual file that changed
                cells = list(row.findChildren('td'))
                if not cells or len(cells) == 0:
                    continue
                # extract the two columns we care about
                filepath, status = cells[:2]

                filepath = os.path.join(filepath.text)
                status = status_cmp.get(status.string.lower(), Status.ERROR)

                # path attribute changes come in pairs of two rows
                if status in (Status.RENAMED, Status.MOVED):
                    row_b = next(rows)
                    dest = row_b.findChildren('td')[0].text
                else:
                    dest = None

                yield filepath, dest, status

    except Exception as e:
        logger.exception(e, exc_info=True)
        logger.error('cannot parse report, possibly invalid')
        raise e

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants