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
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
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