Example #1
0
def main():
    global jira_server
    usage = """\
usage: lp-to-jira-monitor project-id

Examples:
    lp-to-jira-monitor FR
    """
    opt_parser = OptionParser(usage)
    opts, args = opt_parser.parse_args()

    # # Make sure there's at least 1 arguments
    if len(args) < 1:
        opt_parser.print_usage()
        return 1

    jira_project = args[0]

    # 1. Initialize JIRA API
    print("Initialize JIRA API ...")
    api = jira_api()
    jira_server = api.server
    jira = JIRA(api.server, basic_auth=(api.login, api.token))

    # TODO: catch exception if the Launchpad API isn't open
    # 2. Initialize Launchpad API
    print("Initialize Launchpad API ...")
    lp = Launchpad.login_with('foundations', 'production', version='devel')

    try:
        with open(db_json) as fp:
            jira_lp_db = json.load(fp)
        # TODO: check if there's new entry in JIRA that need to be added to the DB
        # refresh_db(jira, lp, jira_project, jira_lp_db)
    except (FileNotFoundError):
        jira_lp_db = build_db(jira, lp, jira_project)

    print("\nFound %s issues" % len(jira_lp_db))
    # Saving DB to disk
    with open(db_json, 'w') as fp:
        json.dump(jira_lp_db, fp, indent=2)

    has_changed = False
    while not has_changed:
        print("Searching for changes %s" % datetime.datetime.now())
        for bug in jira_lp_db:
            try:
                old_date = jira_lp_db[bug]['LAST_CHANGE']
                current_date = "%s" % lp.bugs[int(bug)].date_last_updated
                if current_date != old_date:
                    has_changed = True
                    print("%s has changed since last refresh" % bug)
                    # TODO: compare issues and update JIRA item accordingly
                    # TODO: then replace date in db
                    # TODO: We could think of policy allowing to only update certain field like description, title

            except Exception:
                pass

    return 0
def main(args=None):
    global jira_server

    opt_parser = argparse.ArgumentParser(
            description="Report the status of all active LaunchPad bug "
                        "imported into a JIRA project with lp-to-jira",
            formatter_class=argparse.RawTextHelpFormatter,
            epilog=textwrap.dedent('''\
            Examples:
                lp-to-jira-report FR
                lp-to-jira-report --csv  results.csv  FR
                lp-to-jira-report --json results.json FR
                lp-to-jira-report --html results.html FR
            ''')
        )
    opt_parser.add_argument(
        'project', type=str,
        help="The JIRA project string key")

    opt_parser.add_argument(
        '--csv',
        dest='csv',
        help='export the results of the report into FILE in csv format',
    )
    opt_parser.add_argument(
        '--html',
        dest='html',
        help='export the results of the report into FILE in html format',
    )
    opt_parser.add_argument(
        '--json',
        dest='json',
        help='export the results of the report into FILE in json format',
    )
    opt_parser.add_argument(
        '--sync',
        dest='sync', action='store_true',
        help='Sync JIRA items with corresponding bugs in LP',
    )

    opts = opt_parser.parse_args(args)

    jira_project = opts.project

    # 1. Initialize JIRA API
    api = jira_api()
    jira_server = api.server
    jira = JIRA(api.server, basic_auth=(api.login, api.token))

    # TODO: catch exception if the Launchpad API isn't open
    # 2. Initialize Launchpad API
    # Connect to Launchpad API
    # TODO: catch exception if the Launchpad API isn't open
    snap_home = os.getenv("SNAP_USER_COMMON")
    if snap_home:
        credential_store = UnencryptedFileCredentialStore(
            "{}/.lp_creds".format(snap_home))
    else:
        credential_store = UnencryptedFileCredentialStore(
            os.path.expanduser("~/.lp_creds"))
    lp = Launchpad.login_with(
        'foundations',
        'production',
        version='devel',
        credential_store=credential_store)

    print(
        "Searching for JIRA issues in project %s imported with lp-to-jira..."
        % opts.project,
        flush=True
        )

    # Create a Database of all JIRA issues imported by lp-to-jira
    jira_lp_db = find_issues_in_project(jira, jira_project)
    print("Found %s issues" % len(jira_lp_db))

    # For each issue retrieve latest lp data and sync if required
    merge_lp_data_with_jira_issues(jira, lp, jira_lp_db, opts.sync)

    # Create a table version of the database
    jira_lp_db_table = []
    if jira_lp_db:
        jira_lp_db_table.append(list(jira_lp_db[0].keys()))
        jira_lp_db_table += [list(x.values()) for x in jira_lp_db]
    else:
        return 1

    # Display the content of jira_lp_db based on the output option
    if opts.json:
        with open(opts.json, 'w') as fp:
            json.dump(jira_lp_db, fp, indent=2)
        print("JSON report saved as %s" % opts.json)

    if opts.html:
        print_html_report(jira_lp_db, opts.html)
        print("HTML report saved as %s" % opts.html)

    if opts.csv:
        print_table(jira_lp_db_table, sep=";", limit=1024,
                    align=False, draw_title=False, file=opts.csv)
        print("CSV report saved as %s" % opts.csv)

    if not opts.csv and not opts.html and not opts.json:
        print_table(jira_lp_db_table, sep=" | ", limit=60,
                    align=True, draw_title=True, file="/dev/stdout")

    return 0
Example #3
0
def main(args=None):
    opt_parser = argparse.ArgumentParser(
        description="A script create JIRA issue from Launchpad bugs",
        formatter_class=argparse.RawTextHelpFormatter,
        epilog=textwrap.dedent('''\
        Examples:
            lp-to-jira 3215487 FR
            lp-to-jira -e 3215487 FR
            lp-to-jira -l ubuntu-meeting 3215487 PR
            lp-to-jira -s ubuntu -d 3 IQA
        ''')
    )
    opt_parser.add_argument(
        'bug', type=int,
        # Somewhat hacky way to allow -s option to not require bug id
        # -s (sync) is an optional parameter that doesn't require bug id
        default=0,
        nargs='?',
        help="The Launchpad numeric bug ID")
    opt_parser.add_argument(
        'project', type=str,
        help="The JIRA project string key")
    opt_parser.add_argument(
        '-l',
        '--label',
        dest='label',
        help='Add LABEL to the JIRA issue after creation')
    opt_parser.add_argument(
        '-c',
        '--component',
        dest='component',
        help='Specify COMPONENT to assign the issue to')
    opt_parser.add_argument(
        '-E',
        '--epic',
        dest='epic',
        help='Specify EPIC to link this new issue to')
    opt_parser.add_argument(
        '-e', '--exists',
        dest='exists',
        action='store_true',
        help=textwrap.dedent('''
            Look if the Launchpad Bug has already been imported
            print the JIRA issue ID if found
        ''')
    )
    opt_parser.add_argument(
        '-s', '--sync_project_bugs',
        dest='sync_project_bugs',
        action='store',
        type=str,
        help=textwrap.dedent('''
            Adds all bugs from a specified LP Project to specified Jira board
            if they are not already on the Jira board.
            Use --days to narrow down bugs
            ''')
    )
    opt_parser.add_argument(
        '-d', '--days',
        dest='days',
        action='store',
        type=int,
        help='Only look for LP Bugs in the past n days'
    )
    opt_parser.add_argument(
        '--no-lp-tag',
        dest='no_lp_tag',
        action='store_true',
        help='Do not add tag to LP Bug'
    )

    opts = opt_parser.parse_args(args)

    if (opts.bug == 0 and not opts.sync_project_bugs):
        opt_parser.print_usage()
        print('lp-to-jira: error: the follow argument is required: bug')
        return 1

    # Connect to Launchpad API
    # TODO: catch exception if the Launchpad API isn't open
    snap_home = os.getenv("SNAP_USER_COMMON")
    if snap_home:
        credential_store = UnencryptedFileCredentialStore(
            "{}/.lp_creds".format(snap_home))
    else:
        credential_store = UnencryptedFileCredentialStore(
            os.path.expanduser("~/.lp_creds"))
    lp = Launchpad.login_with(
        'foundations',
        'production',
        version='devel', credential_store=credential_store)

    # Connect to the JIRA API
    try:
        api = jira_api()
    except ValueError:
        return "ERROR: Cannot initialize JIRA API."

    jira = JIRA(api.server, basic_auth=(api.login, api.token))

    if opts.sync_project_bugs:
        tasks_list = get_all_lp_project_bug_tasks(
            lp, opts.sync_project_bugs, opts.days)
        if tasks_list is None:
            return 1

        for bug_task in tasks_list:
            bug = bug_task.bug
            lp_to_jira_bug(lp, jira, bug, opts.project, opts)
        return 0

    bug_number = opts.bug
    project_id = opts.project

    bug = get_lp_bug(lp, bug_number)
    if bug is None:
        return 1

    if opts.exists:
        # We are simply testing if the bug was already in JIRA
        if is_bug_in_jira(jira, bug, project_id):
            return 0
        print("Launchpad Issue {} is not in JIRA project {}".format(
            bug.id, project_id))
        return 1

    # Create the Jira Issue
    lp_to_jira_bug(lp, jira, bug, project_id, opts)

    return 0
Example #4
0
def main():
    usage = """\
usage: lp-to-jira [options] bug-id project-id

Create JIRA entry for a given Launchpad bug ID

options:
    -e, --exists"
                Look if the Launchpad Bug has alreaady been imported
                print the JIRA issue ID if found
    -l, --label LABEL
                Add LABEL to the JIRA issue after creation
    -s SYNC_PROJECT_BUGS, --sync_project_bugs=SYNC_PROJECT_BUGS
                The name of the LP Project. This will bring in every
                bug from your project if you do not also specify days
    -d DAYS, --days=DAYS
                Only look for LP Bugs in the past n days
    --no-lp-tag

Examples:
    lp-to-jira 3215487 FR
    lp-to-jira -e 3215487 FR
    lp-to-jira -l ubuntu-meeting 3215487 PR
    lp-to-jira -s ubuntu -d 3 IQA
        """

    opt_parser = OptionParser(usage)
    opt_parser.add_option(
        '-l',
        '--label',
        dest='label',
    )
    opt_parser.add_option('-e', '--exists', dest='exists', action='store_true')

    opt_parser.add_option(
        '-s',
        '--sync_project_bugs',
        dest='sync_project_bugs',
        action='store',
        type=str,
        help='Adds all bugs from a specified LP Project to specified Jira board'
        ' if they are not already on the Jira board.'
        ' Use --days to narrow down bugs')

    opt_parser.add_option('-d',
                          '--days',
                          dest='days',
                          action='store',
                          type=int,
                          help='Only look for LP Bugs in the past n days')

    opt_parser.add_option('--no-lp-tag',
                          dest='no_lp_tag',
                          action='store_true',
                          help='Do not add tag to LP Bug')

    opts, args = opt_parser.parse_args()

    # Connect to Launchpad API
    # TODO: catch exception if the Launchpad API isn't open
    credential_store = UnencryptedFileCredentialStore(
        os.path.expanduser("~/.lp_creds"))
    lp = Launchpad.login_with('foundations',
                              'production',
                              version='devel',
                              credential_store=credential_store)

    # Connect to the JIRA API
    api = jira_api()
    jira = JIRA(api.server, basic_auth=(api.login, api.token))

    if opts.sync_project_bugs:
        bugs_list = get_all_lp_project_bugs(lp, opts.sync_project_bugs,
                                            opts.days)

        for bug in bugs_list:
            bug_number = bug.bug_link.split('/')[-1]
            bug = get_lp_bug(lp, bug_number)
            lp_to_jira_bug(lp, jira, bug, args[0], opts)
        return 0

    # Make sure there's 2 arguments
    if len(args) < 2:
        opt_parser.print_usage()
        return 1

    bug_number = args[0]
    project_id = args[1]
    bug = get_lp_bug(lp, bug_number)

    if opts.exists:
        # We are simply testing if the bug was already in JIRA
        if is_bug_in_jira(jira, bug, project_id):
            return 0
        print("Launchpad Issue {} is not in JIRA project {}".format(
            bug.id, project_id))
        return 1

    # Create the Jira Issue
    lp_to_jira_bug(lp, jira, bug, project_id, opts)

    return 0
def main():
    global jira_server

    usage = """\
usage: lp-to-jira-report [options] project-id

Report the status of all active LaunchPad bug imported
into a JIRA project with lp-to-jira

options:
    --csv FILE
        export the results of the report into FILE in csv format
    --html FILE
        export the results of the report into FILE in html format
    --json FILE
        export the results of the report into FILE in json format
    default:
        display the report on stdout

Examples:
    lp-to-jira-report FR
    lp-to-jira-report --csv  results.csv  FR
    lp-to-jira-report --json results.json FR
    lp-to-jira-report --html results.html FR
    """
    opt_parser = OptionParser(usage)
    opt_parser.add_option(
        '--csv',
        dest='csv',
    )
    opt_parser.add_option(
        '--html',
        dest='html',
    )
    opt_parser.add_option(
        '--json',
        dest='json',
    )
    opts, args = opt_parser.parse_args()

    # Make sure there's at least 1 arguments
    if len(args) < 1:
        opt_parser.print_usage()
        return 1

    jira_project = args[0]

    # 1. Initialize JIRA API
    print("Initialize JIRA API ...")
    api = jira_api()
    jira_server = api.server
    jira = JIRA(api.server, basic_auth=(api.login, api.token))

    # TODO: catch exception if the Launchpad API isn't open
    # 2. Initialize Launchpad API
    print("Initialize Launchpad API ...")
    lp = Launchpad.login_with('foundations', 'production', version='devel')

    # 3. Create Joint Structure
    # 3.a search for all JIRA issues that starts with LP#
    print("Searching for JIRA issues ...", flush=True)
    # Get JIRA issues in batch of 50
    num_issues = 0
    issue_index = 0
    issue_batch = 50

    while True:
        start_index = issue_index * issue_batch
        request = "project = {} " \
            "AND summary ~ \"LP#\" " \
            "AND status in (BLOCKED, Backlog, \"In Progress\", " \
            "REVIEW,\"Selected for Development\")""".format(jira_project)
        issues = jira.search_issues(request, startAt=start_index)

        if not issues:
            break

        issue_index += 1
        # For each issue in JIRA with LP# in the title
        for issue in issues:
            summary = issue.fields.summary
            if "LP#" in summary:
                num_issues += 1
                print("#", flush=True, end="")

                lpbug_id = get_bug_id(summary)
                lpbug_importance = ""
                lpbug_devel = ""
                lpbug_groovy = ""
                lpbug_focal = ""
                lpbug_bionic = ""
                lpbug_xenial = ""
                lpbug_trusty = ""

                try:
                    lpbug = lp.bugs[int(lpbug_id)]

                    list_pkg = [
                        x.bug_target_name.split()[0] for x in lpbug.bug_tasks
                        if "(Ubuntu)" in x.bug_target_name
                    ]
                    bug_pkg = ", ".join(list_pkg)
                    if len(list_pkg) == 1:
                        lpbug_importance = list(importance_color.keys())[min([
                            list(importance_color.keys()).index(x.importance)
                            for x in lpbug.bug_tasks
                        ])]
                        lpbug_devel = "".join([
                            x.status for x in lpbug.bug_tasks
                            if "(Ubuntu)" in x.bug_target_name
                        ])
                        lpbug_groovy = "".join([
                            x.status for x in lpbug.bug_tasks
                            if "(Ubuntu Groovy)" in x.bug_target_name
                        ])
                        lpbug_focal = "".join([
                            x.status for x in lpbug.bug_tasks
                            if "(Ubuntu Focal)" in x.bug_target_name
                        ])
                        lpbug_bionic = "".join([
                            x.status for x in lpbug.bug_tasks
                            if "(Ubuntu Bionic)" in x.bug_target_name
                        ])
                        lpbug_xenial = "".join([
                            x.status for x in lpbug.bug_tasks
                            if "(Ubuntu Xenial)" in x.bug_target_name
                        ])
                        lpbug_trusty = "".join([
                            x.status for x in lpbug.bug_tasks
                            if "(Ubuntu Trusty)" in x.bug_target_name
                        ])

                    jira_lp_db.append({
                        'JIRA ID': issue.key,
                        'Summary': summary,
                        'Status': issue.fields.status.name,
                        'LaunchPad ID': lpbug_id,
                        'Heat': str(lpbug.heat),
                        'Importance': lpbug_importance,
                        'Packages': bug_pkg,
                        "Devel": lpbug_devel,
                        "Groovy": lpbug_groovy,
                        "Focal": lpbug_focal,
                        "Bionic": lpbug_bionic,
                        "Xenial": lpbug_xenial,
                        "Trusty": lpbug_trusty
                    })

                except Exception:
                    print("\nCouldn't find the Launchpad bug {}".format(
                        lpbug_id))
                    jira_lp_db.append({
                        'JIRA ID': issue.key,
                        'Summary': summary,
                        'Status': issue.fields.status.name,
                        'LaunchPad ID': "N/A",
                        'Heat': "N/A",
                        'Importance': "N/A",
                        'Packages': "N/A",
                        "Devel": "N/A",
                        "Groovy": "N/A",
                        "Focal": "N/A",
                        "Bionic": "N/A",
                        "Xenial": "N/A",
                        "Trusty": "N/A"
                    })

    print("\nFound %s issues" % len(jira_lp_db))

    # Create a table version of the
    jira_lp_db_table = []
    if jira_lp_db:
        jira_lp_db_table.append(list(jira_lp_db[0].keys()))
        jira_lp_db_table += [list(x.values()) for x in jira_lp_db]
    else:
        return 1

    # Display the content of jira_lp_db based on the output option
    if opts.json:
        with open(opts.json, 'w') as fp:
            json.dump(jira_lp_db, fp, indent=2)
        print("JSON report saved as %s" % opts.json)

    if opts.html:
        print_html_report(opts.html)
        print("HTML report saved as %s" % opts.html)

    if opts.csv:
        print_table(jira_lp_db_table,
                    sep=";",
                    limit=1024,
                    align=False,
                    draw_title=False,
                    file=opts.csv)
        print("CSV report saved as %s" % opts.csv)

    if not opts.csv and not opts.html and not opts.json:
        print_table(jira_lp_db_table,
                    sep=" | ",
                    limit=60,
                    align=True,
                    draw_title=True,
                    file="/dev/stdout")

    return 0