コード例 #1
0
ファイル: jira_manager.py プロジェクト: josh-mckenzie/argus-1
    def display_escalations(self):
        jira_connection_name = pick_value(
            'Select a JIRA Connection to view Escalation type tickets:',
            list(self._jira_connections.keys()))
        jira_connection = self._jira_connections[jira_connection_name]
        jira_issues = JiraUtils.get_issues_by_query(
            jira_connection,
            'type = \'Escalation\' AND resolution = unresolved')
        issue_keys = []
        for issue in jira_issues:
            issue_keys.append(issue.issue_key)

        df = DisplayFilter.default()
        while True:
            print_separator(30)
            print(os.linesep + 'Escalations' + os.linesep)
            print_separator(30)
            clear()
            df.display_and_return_sorted_issues(self, jira_issues)
            i = get_input('[#] Integer to open issue in browser. [q] to quit.')
            if i == 'q':
                break
            try:
                c_input = int(i) - 1
                JiraUtils.open_issue_in_browser(jira_connection.url,
                                                issue_keys[c_input])
            except ValueError:
                print('Bad input. Try again')
                pause()
コード例 #2
0
    def __init__(self, name: str, jira_connection: JiraConnection) -> None:
        self.name = name
        self.jira_connection = jira_connection

        # Collection of filters, keyed by the name of the field they filter on
        self._jira_filters = {}  # type: Dict[str, JiraFilter]

        self._teams = {}  # type: Dict[str, Team]

        self.display_filter = DisplayFilter()
コード例 #3
0
ファイル: jira_manager.py プロジェクト: josh-mckenzie/argus-1
    def search_projects(self):
        """
        Does a one-off ad-hoc search for strings in all cached fields for all cached JiraProjects.
        Keeping at scope of JiraManager as search is a meta-scoped search of all cached JiraProjects independent of JiraConnection
        :return:
        """
        tinput = get_input('Search [o]pen issues only, [c]losed, or [a]ll?')
        substring = get_input('Search for what substring?')
        matches = []
        jira_projects = self.get_all_cached_jira_projects()

        # cache list of seen columns for the query
        columns = {}
        for project in list(jira_projects.values()):
            results = project.get_matching_issues(substring, tinput)
            for r in results:
                matches.append(r)
                for k, v in r.items():
                    # This is going to blast out our ability to filter on reviewer or reviewer 2. For now.
                    if 'custom' not in k:
                        columns[k] = True
        original_list = JiraUtils.sort_custom_jiraissues_by_key(matches)
        display_list = original_list

        df = DisplayFilter.default()
        while True:
            df.display_and_return_sorted_issues(self, display_list)
            print_separator(30)
            cinput = get_input(
                '[#] to open an issue in browser, [c] to clear column filters, [f] to specify a specific field to match on, [q] to return to menu:'
            )
            if str.lower(cinput) == 'f':
                col_name = pick_value('Filter on which column?',
                                      list(columns.keys()), False)
                newlist = []
                for ji in display_list:
                    if col_name in ji:
                        if substring in ji[col_name]:
                            newlist.append(ji)
                display_list = newlist
            elif str.lower(cinput) == 'c':
                display_list = original_list
            elif not str.lower(cinput) == 'q':
                try:
                    jira_issue = display_list[int(cinput) - 1]
                    JiraUtils.open_issue_in_browser(
                        self._jira_connections[
                            jira_issue.jira_connection_name].url,
                        jira_issue.issue_key)
                except ValueError:
                    print('Bad input. Try again.')
            elif str.lower(cinput) == 'q':
                break
コード例 #4
0
ファイル: jira_view.py プロジェクト: ptnapoleon/argus
    def __init__(self, name, jira_connection):
        # type: (str, JiraConnection) -> None
        self.name = name
        self.jira_connection = jira_connection

        # Collection of filters, keyed by the name of the field they filter on
        self._jira_filters = {}  # type: Dict[str, JiraFilter]

        self._teams = {}  # type: Dict[str, Team]

        # TODO: Allow / support customization of display filter on per-view basis in Edit View dialog
        self.display_filter = DisplayFilter()
コード例 #5
0
    def display_view(self, jira_manager: 'JiraManager') -> None:
        df = DisplayFilter.default()

        working_issues = list(self.get_issues().values())
        while True:
            try:
                issues = df.display_and_return_sorted_issues(
                    jira_manager, working_issues)
                print_separator(60)
                print('[JiraView operations for {}]'.format(self.name))
                input_prompt = (
                    "[f] to manually enter a substring to regex issues in the view\n"
                    "[c] to clear all regex filtering\n"
                    "[#] Integer value to open ticket in browser\n"
                    "[q] to quit\n"
                    ":")
                custom = get_input(input_prompt)
                if custom == 'q':
                    return
                elif custom == 'f':
                    string = get_input('substring to match:', lowered=False)
                    new_issues = []
                    for jira_issue in working_issues:
                        if jira_issue.matches(self.jira_connection, string):
                            new_issues.append(jira_issue)
                    working_issues = new_issues
                elif custom == 'c':
                    working_issues = list(self.get_issues().values())
                elif len(issues) == 0:
                    print(
                        'No matching jira issues found. Skipping attempt to open.'
                    )
                    pause()
                else:
                    try:
                        JiraUtils.open_issue_in_browser(
                            self.jira_connection.url,
                            issues[int(custom) - 1].issue_key)
                    except ValueError:
                        print('Bad input. Try again.')
            except JIRAError as je:
                print('Caught an error: {}'.format(je))
                traceback.print_exc()
                return
コード例 #6
0
ファイル: jira_manager.py プロジェクト: josh-mckenzie/argus-1
 def run_debug(self):
     """
     Used during development to bypass complex menu operations and try out a single new operation outside unit testing
     """
     print_separator(60)
     print('Resolving deps')
     self._resolve_issue_dependencies()
     default_filter = DisplayFilter.default()
     default_filter.open_only = True
     utils.show_dependencies = True
     utils.show_only_open_dependencies = True
     for jira_connection in self.jira_connections():
         if jira_connection.connection_name == 'ds':
             print_separator(30)
             print('Results for connection: {}'.format(jira_connection))
             for issue_list in jira_connection.cached_jira_issues:
                 default_filter.display_and_return_sorted_issues(
                     self, issue_list, 1, None)
     for dep_type in sorted(JiraDependency.unknown_dependencies):
         print('Found unknown dependency: {}'.format(dep_type))
     pause()
コード例 #7
0
ファイル: jira_view.py プロジェクト: ptnapoleon/argus
    def display_view(self, jira_manager):
        # type: (JiraManager) -> None
        df = DisplayFilter.default()

        working_issues = list(self.get_issues().values())
        while True:
            try:
                issues = df.display_and_return_sorted_issues(
                    jira_manager, working_issues)
                print_separator(60)
                print('[JiraView operations for {}]'.format(self.name))
                custom = get_input(
                    '[f] to manually enter a substring to regex issues in the view'
                    + os.linesep + '[c] to clear all regex filtering' +
                    os.linesep +
                    '[#] Integer value to open ticket in browser ' +
                    os.linesep + '[q] to quit' + os.linesep + ':')
                if custom == 'q':
                    return
                elif custom == 'f':
                    string = get_input('substring to match:', lowered=False)
                    new_issues = []
                    for jira_issue in working_issues:
                        if jira_issue.matches(self.jira_connection, string):
                            new_issues.append(jira_issue)
                    working_issues = new_issues
                elif custom == 'c':
                    working_issues = list(self.get_issues().values())
                else:
                    try:
                        JiraUtils.open_issue_in_browser(
                            self.jira_connection.url,
                            issues[int(custom) - 1].issue_key)
                    except ValueError:
                        print('Bad input. Try again.')
            except JIRAError as je:
                print('Caught an error: {}'.format(je))
                traceback.print_exc()
                return
コード例 #8
0
ファイル: jira_manager.py プロジェクト: josh-mckenzie/argus-1
    def report_fix_version(self) -> None:
        """
        Creates a report of all tickets, including dependencies, to the input FixVersion.
        """

        # Only support creating of this on a single JiraConnection, with the assumption that multiple projects on that
        # connection can share a FixVersion, but these won't straddle to exterior Jira instances
        target_connection = self.pick_jira_connection(
            'FixVersion report for which JiraConnection?')
        if target_connection is None:
            return

        open_only = is_yes('Show only unresolved issues?')

        to_match = get_input('Input substring to search fixversions for:',
                             False)
        available_versions = set()
        for jira_project in target_connection.cached_projects:
            for jira_issue in jira_project.jira_issues.values():
                for fix in jira_issue['fixVersions'].split(','):
                    if to_match in fix:
                        available_versions.add(fix)

        report_version = pick_value('Generate report for which FixVersion?',
                                    list(available_versions))
        if report_version is None:
            return

        print('Generating report on: {}'.format(report_version))

        # Now find all "primary root" members on this FixVersion, generate a list of matching, then display w/dependency
        # chains enabled
        matching_issues = set()
        for jira_project in target_connection.cached_projects:
            for jira_issue in jira_project.jira_issues.values():
                if jira_issue.has_fix_version(report_version):
                    if (open_only and jira_issue.is_open) or not open_only:
                        matching_issues.add(jira_issue)

        df = DisplayFilter.default()
        df.open_only = open_only
        df.include_column('fixVersions', 'FixVersion', 10, 2)

        # sort our keys by issuekey
        sorted_results = JiraUtils.sort_custom_jiraissues_by_key(
            list(matching_issues))
        del matching_issues

        issues = df.display_and_return_sorted_issues(self, sorted_results, 1,
                                                     None, True)
        while True:
            choice = get_input(
                '[#] to open an issue in browser, [p] to print report again, [q] to quit report: '
            )
            if choice == 'q':
                break
            elif choice == 'p':
                df.display_and_return_sorted_issues(self, sorted_results, 1,
                                                    None, True)
            try:
                int_choice = int(choice) - 1
                if int_choice < 0 or int_choice > len(issues) - 1:
                    raise ValueError('oops')
                chosen_issue = issues[int_choice]
                if not chosen_issue.is_cached:
                    print(
                        'Cannot open browser for non-cached issue (don\'t know url). Cache offline to inspect {}.'
                        .format(chosen_issue.issue_key))
                else:
                    jira_conn = self._jira_connections[
                        chosen_issue.jira_connection_name]
                    JiraUtils.open_issue_in_browser(jira_conn.url,
                                                    chosen_issue.issue_key)
            except ValueError:
                print('Bad input. Try again.')
コード例 #9
0
ファイル: jira_manager.py プロジェクト: josh-mckenzie/argus-1
    def __init__(self, team_manager):
        """
        Recreates any JiraConnections and JiraViews based on saved data in conf/jira.cfg
        """
        # Holds connected Jira objects to be queried by JiraViews
        self._jira_connections = {}  # type: Dict[str, JiraConnection]

        # JiraViews, caching filters for different ways to view Jira Data. Implicit 1:1 JiraConnection to JiraView
        self.jira_views = {}  # type: Dict[str, JiraView]

        self.jira_dashboards = {}  # type: Dict[str, JiraDashboard]

        # Used during JiraDependency resolution to notify user of missing JiraProjects
        self.missing_project_counts = {}  # type: Dict[str, int]

        self._display_filter = DisplayFilter.default()

        if os.path.exists(jira_conf_file):
            config_parser = configparser.RawConfigParser()
            config_parser.read(jira_conf_file)

            connection_names = []
            if config_parser.has_section(
                    'JiraManager') and config_parser.has_option(
                        'JiraManager', 'Connections'):
                connection_names = config_parser.get('JiraManager',
                                                     'Connections').split(',')

            # JiraConnections are the root of our container hierarchy
            for connection_name in connection_names:
                if connection_name == '':
                    pass
                try:
                    jira_connection = JiraConnection.from_file(connection_name)
                    # If we had an error on init we obviously cannot add this
                    if jira_connection is None:
                        continue
                    self._jira_connections[
                        jira_connection.connection_name] = jira_connection
                except ConfigError as ce:
                    print('ConfigError with project {}: {}'.format(
                        connection_name, ce))

            # Construct JiraViews so they can be used during JiraDashboard creation.
            view_names = []
            if config_parser.has_option('JiraManager', 'Views'):
                view_names = config_parser.get('JiraManager',
                                               'Views').split(',')

            for name in view_names:
                try:
                    jv = JiraView.from_file(self, name, team_manager)
                    self.jira_views[jv.name] = jv
                except ConfigError as ce:
                    print('ConfigError with jira view {}: {}'.format(name, ce))

            if config_parser.has_section('Dashboards'):
                for dash in config_parser.options('Dashboards'):
                    dash_views = {}
                    for view in view_names:
                        if view not in self.jira_views:
                            print(
                                'Found dashboard {} with invalid view: {}. Skipping init: manually remove from config.'
                                .format(dash, view))
                            break
                        dash_views[view] = self.jira_views[view]
                    self.jira_dashboards[dash] = JiraDashboard(
                        dash, dash_views)

        if len(self._jira_connections) == 0:
            print_separator(30)
            print(
                'No JIRA Connections found. Prompting to add first connection.'
            )
            self.add_connection()

        # Initialize JiraProjects from locally cached files
        for file_name in os.listdir(jira_project_dir):
            full_path = os.path.join(jira_project_dir, file_name)
            print(
                'Processing locally cached JiraProject: {}'.format(full_path))
            # Init based on matching the name of this connection and .cfg
            print_separator(30)
            try:
                new_jira_project = JiraProject.from_file(full_path, self)
                if new_jira_project is None:
                    print('Error initializing from {}. Skipping'.format(
                        full_path))
                    break
                if new_jira_project.jira_connection is None:
                    add = get_input(
                        'Did not find JiraConnection for JiraProject: {}. Would you like to add one now? (y/n)'
                    )
                    if add == 'y':
                        new_jira_connection = self.add_connection(
                            'Name the connection (reference url: {}):'.format(
                                new_jira_project.url))
                        new_jira_connection.save_config()
                        new_jira_project.jira_connection = new_jira_connection
                    else:
                        print(
                            'Did not add JiraConnection, so cannot link and use JiraProject.'
                        )
                        continue
                print('Updating with new data from JIRA instance')
                new_jira_project.refresh()
                new_jira_project.jira_connection.add_and_link_jira_project(
                    new_jira_project)
            except (configparser.NoSectionError, ConfigError) as e:
                print(
                    'WARNING! Encountered error initializing JiraProject from file {}: {}'
                    .format(full_path, e))
                print(
                    'This JiraProject will not be initialized. Remove it manually from disk in conf/jira/projects and data/jira/'
                )

        if os.path.exists('conf/custom_params.cfg'):
            config_parser = configparser.RawConfigParser()
            config_parser.read('conf/custom_params.cfg')
            custom_projects = config_parser.get('CUSTOM_PROJECTS',
                                                'project_names').split(',')

            for project_name in custom_projects:
                argus_debug(
                    'Processing immutable config for custom project: {}'.
                    format(project_name))
                # Find the JiraConnection w/matching URL, if any
                url = config_parser.get(project_name, 'url').rstrip('/')

                jira_project = self.maybe_get_cached_jira_project(
                    url, project_name)
                if jira_project is not None:
                    # Don't need to cache since already done on ctor for JiraProject
                    argus_debug('Project already initialized. Skipping.')
                    continue

                # Didn't find the JiraProject, so we need to build one, cache, and link.
                custom_fields = {}
                field_names = config_parser.get(project_name,
                                                'custom_fields').split(',')
                for field in field_names:
                    custom_fields[field] = config_parser.get(
                        project_name, field)

                parent_jira_connection = None
                for jira_connection in list(self._jira_connections.values()):
                    if jira_connection.url == url:
                        parent_jira_connection = jira_connection
                        break

                # Create a JiraConnection for this JiraProject if we do not yet have one
                if parent_jira_connection is None:
                    print(
                        'WARNING! Did not find JiraConnection for project: {}, attempting to match url: {}'
                        .format(project_name, url))
                    print('Known JiraConnections and their urls:')
                    for jira_connection in list(
                            self._jira_connections.values()):
                        print('   {}: {}'.format(
                            jira_connection.connection_name,
                            jira_connection.url))
                    if is_yes('Would you like to add one now?'):
                        parent_jira_connection = self.add_connection(
                            'Name the connection (reference url: {}):'.format(
                                url))
                    else:
                        print(
                            'JiraProject data and config will not be added nor cached. Either add it manually or restart Argus and reply y'
                        )
                        break

                new_jira_project = JiraProject(parent_jira_connection,
                                               project_name, url,
                                               custom_fields)
                new_jira_project.refresh()
                parent_jira_connection.add_and_link_jira_project(
                    new_jira_project)
        print('Resolving dependencies between JiraIssues')
        self._resolve_issue_dependencies()
        print('JiraManager initialization complete.')
コード例 #10
0
    def __init__(self):
        parser = optparse.OptionParser(
            description=DESCRIPTION,
            usage='Usage: %prog [options] [host [port]]',
            version='argus ' + __version__)
        parser.add_option(
            '-p',
            '--password',
            help=
            'provide local password on command-line rather than being prompted'
        )
        parser.add_option('-d',
                          '--dashboard',
                          help='name of dashboard to auto-execute into')
        parser.add_option(
            '-j',
            '--jenkins_report',
            help=
            'TODO:#106 execute and print a jenkins report, exiting upon completion',
            default=False,
            action='store_true')
        parser.add_option(
            '-n',
            '--jenkins_project_name',
            help='Name of consistent root of project names in Jenkins')
        parser.add_option(
            '-b',
            '--jenkins_branch',
            help='TODO:#107 Used with -j, specify branch to run reports against'
        )
        parser.add_option(
            '-t',
            '--jenkins_type',
            help=
            'TODO:#108 Used with -j, specify type of test [u]nit test, or [d]test to report against'
        )
        # parser.add_option('-c', '--triage_csv', help='Specifies local file containing [link, key, summary, assignee, reviewer, status, prio, repro, scope, component] triage file to update against live JIRA data')
        # parser.add_option('-o', '--triage_out', help='Output file name for updated triage data. If not provided, prints to stdout.')
        parser.add_option(
            '-u',
            '--unit_test',
            help=
            'Unit testing mode, does not connect servers, saves config changes to test/ folder',
            action='store_true',
            dest='unit_test')
        parser.add_option(
            '-v',
            '--verbose',
            help='Log verbose debug output to console and argus.log',
            action='store_true',
            dest='verbose')

        optvalues = optparse.Values()
        (options, arguments) = parser.parse_args(sys.argv[1:],
                                                 values=optvalues)

        signal.signal(signal.SIGINT, self.signal_handler)

        if hasattr(options, 'verbose'):
            utils.debug = True
            utils.argus_log = open('argus.log', 'w')

        Config.init_argus()

        # determine if this is a first run, prompt differently pending that
        msg = None
        if hasattr(options, 'password'):
            Config.MenuPass = options.password
        else:
            msg = 'Enter Argus Password (local JIRA credentials will be encrypted with this):'

        while Config.MenuPass == '':
            Config.MenuPass = getpass(msg)

        if hasattr(options, 'unit_test'):
            if os.path.exists('test'):
                shutil.rmtree('test')
            os.mkdir('test')
            os.mkdir(os.path.join('test', 'conf'))
            os.mkdir(os.path.join('test', 'data'))
            utils.unit_test = True

            # Run one-off test on time utils
            # now = time_converter.current_time()
            # print('Now is: {}'.format(now))
            #
            # four_weeks_ago = time_converter.since_now('-4w')
            # print('Four weeks ago is: {}'.format(four_weeks_ago))
            #
            # one_m_two_days_ago = time_converter.since_now('-1m -2d')
            # print('One M 2 D ago is: {}'.format(one_m_two_days_ago))
            # exit(-1)

        try:
            self._team_manager = TeamManager.from_file()
        except ConfigError as ce:
            print('ConfigError: {}. Initializing empty JiraManager'.format(ce))
            self._team_manager = TeamManager()
        self._jira_manager = JiraManager(self._team_manager)
        self._jenkins_manager = JenkinsManager(self)

        if hasattr(options, 'triage_csv'):
            jira_connections = {}
            for jira_connection in self._jira_manager.jira_connections():
                jira_connections[
                    jira_connection.connection_name] = jira_connection
            tu = TriageUpdate(
                jira_connections,
                self._jira_manager.get_all_cached_jira_projects())
            triage_out = options.triage_out if hasattr(options,
                                                       'triage_out') else None
            tu.process(options.triage_csv, triage_out)

        if hasattr(options, 'dashboard'):
            user_key = optvalues.__dict__['dashboard']
            dash_keys = list(self._jira_manager.jira_dashboards.keys())

            if user_key in dash_keys:
                self._jira_manager.jira_dashboards[user_key].display_dashboard(
                    self._jira_manager.jira_views)
            else:
                print('Oops... Error with dashboard name {}'.format(user_key))
                print('Possible dashboard names : {}'.format(
                    ','.join(dash_keys)))
                print('Starting Argus normally...')

        if hasattr(options, 'verbose'):
            utils.debug = True
            utils.argus_log = open('argus.log', 'w')

        self._display_filter = DisplayFilter()

        self.main_menu = [
            MenuOption('d',
                       'Dashboards',
                       self.go_to_dashboards_menu,
                       pause=False),
            MenuOption('v',
                       'Jira Views',
                       self.go_to_jira_views_menu,
                       pause=False),
            MenuOption('p',
                       'JiraProject Queries',
                       self.go_to_projects_menu,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption('t',
                       'Run a Team-Based Report',
                       self._run_team_report,
                       pause=False),
            MenuOption('e',
                       'View Escalations',
                       self._jira_manager.display_escalations,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption('r',
                       'Generate a Pre-Determined Report',
                       self.go_to_reports_menu,
                       pause=False),
            MenuOption('m',
                       'Team Management',
                       self.go_to_teams_menu,
                       pause=False),
            MenuOption('c',
                       'Jira Connections',
                       self.go_to_jira_connections_menu,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption('j',
                       'Jenkins Menu',
                       self.go_to_jenkins_menu,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption('o',
                       'Change Options',
                       self.go_to_options_menu,
                       pause=False),
            MenuOption('x', 'Debug', self._jira_manager.run_debug,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption('h', 'Help', self._display_readme, pause=False),
            MenuOption.quit_program()
        ]

        self.dashboards_menu = [
            MenuOption('l', 'List all available dashboards',
                       self._jira_manager.list_dashboards),
            MenuOption('d', 'Display a dashboard\'s results',
                       self._jira_manager.display_dashboard),
            MenuOption('c', 'Create a dashboard',
                       self._jira_manager.add_dashboard),
            MenuOption('e', 'Edit a dashboard',
                       self._jira_manager.edit_dashboard),
            MenuOption('r', 'Remove a dashboard',
                       self._jira_manager.remove_dashboard),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_main_menu)
        ]

        self.jira_views_menu = [
            MenuOption('l', 'List all defined JiraViews',
                       self._jira_manager.list_all_jira_views),
            MenuOption('d', 'Display a JiraView\'s results',
                       self._jira_manager.display_view),
            MenuOption('a', 'Add a JiraView', self._add_view),
            MenuOption('e', 'Edit a JiraView', self._edit_view),
            MenuOption('r', 'Remove a JiraView',
                       self._jira_manager.remove_view),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_main_menu)
        ]

        self.reports_menu = [
            MenuOption(
                'f',
                'FixVersion report (release). Query all tickets with a specified FixVersion',
                self._jira_manager.report_fix_version),
            MenuOption('s',
                       'Add a single-user multi-JIRA open ticket dashboard',
                       self._add_multi_jira_dashboard),
            MenuOption('l', 'Add a label-based cross-cutting view',
                       self._jira_manager.add_label_view),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_main_menu)
        ]

        self.team_menu = [
            MenuOption('l', 'List all defined Teams',
                       self._team_manager.list_teams),
            MenuOption('a', 'Add a new team', self._add_team),
            MenuOption('e', 'Edit an existing team', self._edit_team),
            MenuOption('r', 'Remove a team', self._remove_team),
            MenuOption(
                'x',
                'Link a team member to two accounts across JiraConnections',
                self.add_linked_member),
            MenuOption('d', 'Delete a cross-Jira link',
                       self._team_manager.remove_linked_member),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_main_menu)
        ]

        self.jira_connections_menu = [
            MenuOption('a', 'Add a JIRA connection',
                       self._jira_manager.add_connection),
            MenuOption('r', 'Remove a JIRA connection and all related views',
                       self._jira_manager.remove_connection),
            MenuOption(
                'c',
                'Cache offline ticket data for a JiraProject on a connection',
                self._jira_manager.cache_new_jira_project_data),
            MenuOption(
                'd',
                'Delete offline cached ticket data for a JiraProject on a connection',
                self._jira_manager.delete_cached_jira_project),
            MenuOption('l', 'List all configured Jiraconnections',
                       self._jira_manager.list_jira_connections),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_main_menu)
        ]

        self.jenkins_menu = [
            MenuOption('r',
                       'Reports Manager',
                       self.go_to_jenkins_reports_manager_menu,
                       pause=False),
            MenuOption('c',
                       'Connections Manager',
                       self.go_to_jenkins_connections_manager_menu,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_main_menu)
        ]

        self.jenkins_reports_manager_menu = [
            MenuOption('o',
                       'Open custom report',
                       self._jenkins_manager.select_active_report,
                       pause=False),
            MenuOption('a',
                       'Add a custom report',
                       self._jenkins_manager.add_custom_report,
                       pause=False),
            MenuOption('r',
                       'Remove a custom report',
                       self._jenkins_manager.remove_custom_report,
                       pause=False),
            MenuOption('l', 'List custom reports',
                       self._jenkins_manager.list_custom_reports),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_jenkins_menu)
        ]

        self.jenkins_report_menu = [
            MenuOption('v', 'View report',
                       self._jenkins_manager.view_custom_report),
            MenuOption('a',
                       'Add a job',
                       self._jenkins_manager.add_custom_report_job,
                       pause=False),
            MenuOption('r',
                       'Remove a job',
                       self._jenkins_manager.remove_custom_report_job,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(
                self.go_to_jenkins_reports_manager_menu)
        ]

        self.jenkins_connections_manager_menu = [
            MenuOption('o',
                       'Open connection',
                       self._jenkins_manager.select_active_connection,
                       pause=False),
            MenuOption('a',
                       'Add a connection',
                       self._jenkins_manager.add_connection,
                       pause=False),
            MenuOption('r',
                       'Remove a connection',
                       self._jenkins_manager.remove_connection,
                       pause=False),
            MenuOption('l', 'List connections',
                       self._jenkins_manager.list_connections),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_jenkins_menu)
        ]

        self.jenkins_connection_menu = [
            MenuOption('v',
                       'View cached jobs',
                       self._jenkins_manager.view_cached_jobs,
                       pause=False),
            MenuOption('d',
                       'Download jobs to cache',
                       self._jenkins_manager.download_jobs,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption('l', 'List saved views',
                       self._jenkins_manager.list_views),
            MenuOption('a',
                       'Add a view',
                       self._jenkins_manager.add_view,
                       pause=False),
            MenuOption('r',
                       'Remove a view',
                       self._jenkins_manager.remove_view,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(
                self.go_to_jenkins_connections_manager_menu)
        ]

        self.options_menu = [
            MenuOption('p', 'Change Argus password', self._change_password),
            MenuOption('b', 'Change browser', self._change_browser),
            MenuOption('v', 'Toggle Verbose/Debug', self._change_debug),
            MenuOption('d', 'Toggle Display dependencies',
                       self._change_show_dependencies),
            MenuOption('o', 'Toggle show open dependencies only',
                       self._change_dependency_type),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_main_menu)
        ]

        self.projects_menu = [
            MenuOption('l',
                       'List locally cached projects',
                       self._jira_manager.list_projects,
                       pause=True),
            MenuOption('s',
                       'Search locally cached JiraIssues for a string',
                       self._jira_manager.search_projects,
                       pause=False),
            MenuOption('a',
                       'Add new JiraProject offline cache',
                       self._jira_manager.cache_new_jira_project_data,
                       pause=True),
            MenuOption(
                'd',
                'Delete offline cached ticket data for a JiraProject on a connection',
                self._jira_manager.delete_cached_jira_project),
            MenuOption('u',
                       'Update all locally cached project JIRA data',
                       self._jira_manager.update_cached_jira_project_data,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_main_menu)
        ]

        self.active_menu = None
        self.menu_header = None
        self.go_to_main_menu()

        self._load_config()

        # let user read startup info
        pause()
コード例 #11
0
    def display_member_issues(self, jira_manager, report_filter):
        # type: (JiraManager, ReportFilter) -> List[JiraIssue]
        """
        Prints details for tickets by category. This method is always executed in the context of having a relevant
        ReportFilter in use for the display. Can use a no-op all-inclusive ReportFilter if you want to report all issues
        for this MemberIssuesByStatus.
        :param: jira_manager: Needed for display of 'pretty names' of custom columns by DisplayFilter
        :param: report_filter: Used to determine which issues to display
        :return: Sorted list of keys printed in this report
        """
        print('[Detailed report for {}]'.format(self.primary_name))
        # TODO: Allow configuration of format for DisplayFilter
        df = DisplayFilter.team_details()

        idx = 1
        issues_displayed = []

        # Use a scratch array so we don't print a summary for something we don't have details for
        scratch = [x for x in self.assigned if report_filter.contains_issue(x)]
        if len(scratch) > 0:
            print('\n[ASSIGNED]')
            sorted_issues = df.display_and_return_sorted_issues(jira_manager, scratch, idx)
            idx += len(sorted_issues)
            for jira_issue in sorted_issues:
                issues_displayed.append(jira_issue)

        scratch = [x for x in self.reviewer if report_filter.contains_issue(x)]
        if len(scratch) > 0:
            print('\n[REVIEWER]')
            sorted_issues = df.display_and_return_sorted_issues(jira_manager, scratch, idx)
            idx += len(sorted_issues)
            for jira_issue in sorted_issues:
                issues_displayed.append(jira_issue)

        closed_test = []
        closed_non_test = []
        for jira_issue in [x for x in self.closed if report_filter.contains_issue(x)]:
            # Note: designation of tickets as being 'test' related is via a label, not a component or issuetype
            if jira_issue.matches_label('test', False):
                closed_test.append(jira_issue)
                issues_displayed.append(jira_issue)
            else:
                closed_non_test.append(jira_issue)
                issues_displayed.append(jira_issue)

        if len(closed_test) > 0:
            print('\n[CLOSED TEST]')
            printed = df.display_and_return_sorted_issues(jira_manager, closed_test, idx)
            idx += len(printed)

        if len(closed_non_test) > 0:
            print('\n[CLOSED NON-TEST]')
            printed = df.display_and_return_sorted_issues(jira_manager, closed_non_test, idx)
            idx += len(printed)

        scratch = [x for x in self.reviewed if report_filter.contains_issue(x)]
        if len(scratch) > 0:
            print('\n[REVIEWED]')
            printed = df.display_and_return_sorted_issues(jira_manager, scratch, idx)
            idx += len(printed)
            for jira_issue in printed:
                issues_displayed.append(jira_issue)

        return issues_displayed