#!/usr/bin/env python3

# Report significant differences in the buildhistory repository since a specific revision
#
# Copyright (C) 2013 Intel Corporation
# Author: Paul Eggleton <paul.eggleton@linux.intel.com>

import sys
import os
import argparse
from distutils.version import LooseVersion

# Ensure PythonGit is installed (buildhistory_analysis needs it)
try:
    import git
except ImportError:
    print("Please install GitPython (python3-git) 0.3.4 or later in order to use this script")
    sys.exit(1)

def get_args_parser():
    description = "Reports significant differences in the buildhistory repository."

    parser = argparse.ArgumentParser(description=description,
                                     usage="""
    %(prog)s [options] [from-revision [to-revision]]
    (if not specified, from-revision defaults to build-minus-1, and to-revision defaults to HEAD)""")

    parser.add_argument('-p', '--buildhistory-dir',
                        action='store',
                        dest='buildhistory_dir',
                        default='buildhistory/',
                        help="Specify path to buildhistory directory (defaults to buildhistory/ under cwd)")
    parser.add_argument('-v', '--report-version',
                        action='store_true',
                        dest='report_ver',
                        default=False,
                        help="Report changes in PKGE/PKGV/PKGR even when the values are still the default (PE/PV/PR)")
    parser.add_argument('-a', '--report-all',
                        action='store_true',
                        dest='report_all',
                        default='False',
                        help="Report all changes, not just the default significant ones")
    parser.add_argument('-s', '---signatures',
                        action='store_true',
                        dest='sigs',
                        default=False,
                        help="Report list of signatures differing instead of output")
    parser.add_argument('-S', '--signatures-with-diff',
                        action='store_true',
                        dest='sigsdiff',
                        default=False,
                        help="Report on actual signature differences instead of output (requires signature data to have been generated, either by running the actual tasks or using bitbake -S)")
    parser.add_argument('-e', '--exclude-path',
                        action='append',
                        help="Exclude path from the output")
    parser.add_argument('revisions',
                        default = ['build-minus-1', 'HEAD'],
                        nargs='*',
                        help=argparse.SUPPRESS)
    return parser

def main():

    parser = get_args_parser()
    args = parser.parse_args()

    if LooseVersion(git.__version__) < '0.3.1':
        sys.stderr.write("Version of GitPython is too old, please install GitPython (python-git) 0.3.1 or later in order to use this script\n")
        sys.exit(1)

    if len(args.revisions) > 2:
        sys.stderr.write('Invalid argument(s) specified: %s\n\n' % ' '.join(args.revisions[2:]))
        parser.print_help()

        sys.exit(1)
    if not os.path.exists(args.buildhistory_dir):
        if args.buildhistory_dir == 'buildhistory/':
            cwd = os.getcwd()
            if os.path.basename(cwd) == 'buildhistory':
                args.buildhistory_dir = cwd

    if not os.path.exists(args.buildhistory_dir):
        sys.stderr.write('Buildhistory directory "%s" does not exist\n\n' % args.buildhistory_dir)
        parser.print_help()
        sys.exit(1)

    scripts_path = os.path.abspath(os.path.dirname(os.path.abspath(sys.argv[0])))
    lib_path = scripts_path + '/lib'
    sys.path = sys.path + [lib_path]

    import scriptpath

    # Set path to OE lib dir so we can import the buildhistory_analysis module
    scriptpath.add_oe_lib_path()
    # Set path to bitbake lib dir so the buildhistory_analysis module can load bb.utils
    bitbakepath = scriptpath.add_bitbake_lib_path()

    if not bitbakepath:
        sys.stderr.write("Unable to find bitbake by searching parent directory of this script or PATH\n")
        sys.exit(1)

    if len(args.revisions) == 1:
        if '..'  in args.revisions[0]:
            fromrev, torev = args.revisions[0].split('..')
        else:
            fromrev, torev = args.revisions[0], 'HEAD'
    elif len(args.revisions) == 2:
        fromrev, torev = args.revisions

    from oe.buildhistory_analysis import process_changes

    import gitdb

    try:
        changes = process_changes(args.buildhistory_dir, fromrev, torev,
                                  args.report_all, args.report_ver, args.sigs,
                                  args.sigsdiff, args.exclude_path)
    except gitdb.exc.BadObject as e:
        if not args.revisions:
            sys.stderr.write("Unable to find previous build revision in buildhistory repository\n\n")
            parser.print_help()
        else:
            sys.stderr.write('Specified git revision "%s" is not valid\n' % e.args[0])
        sys.exit(1)

    for chg in changes:
        out = str(chg)
        if out:
            print(out)

    sys.exit(0)

if __name__ == "__main__":
    main()
