Ejemplo n.º 1
0
def format_issue( issue , mode = 0, formatter=None, comments_only=False):
    fields = {}
    global colorfunc
    status_color="blue"
    status_string = get_issue_status ( issue.setdefault("status","1")).lower()
    if status_string in ["resolved","closed"]:
        status_color="green"
    elif status_string in ["open","unassigned","reopened"]:
        status_color="red"

    special_fields = {"status":get_issue_status,"priority":get_issue_priority,"type":get_issue_type}

    if formatter:
        groups = re.compile("(%([\w]+))").findall(formatter)
        ret_str = formatter
        for k, v in groups:
            if v.lower() in special_fields.keys():
                meth = special_fields[v.lower()]
                key=issue[v.lower()]
                mappings = meth(None)
                data = ""
                for item in mappings:
                    if item['id'] == key:
                        data = item['name']
                ret_str = ret_str.replace(k, data)
            else:
                ret_str = ret_str.replace(k, str(issue.setdefault(v.lower(),"")))
        return ret_str

    if mode >= 0:
        # minimal
        fields["issue"] = issue["key"]
        fields["status"] = colorfunc( get_issue_status ( issue["status"] )
                                    , status_color )
        fields["reporter"] = issue.setdefault("reporter","")
        fields["assignee"] = issue.setdefault("assignee","")
        fields["summary"] = issue.setdefault("summary","")
        fields["link"] = colorfunc( "%s/browse/%s" % ( jirabase, issue["key"]), "white",attrs=["underline"])
    if mode >= 1 or comments_only:
        fields["description"] = issue.setdefault("description","")
        fields["priority"] = get_issue_priority( issue.setdefault("priority",""))
        fields["type"] = get_issue_type( issue.setdefault("type","") )
        comments = get_comments ( issue["key"] )
        fields["comments"] = "\n"
        for comment in comments:
            comment_str =  comment["body"].strip()
            fields["comments"] += "%s %s : %s\n" % ( colorfunc(comment["created"], "blue"), colorfunc(comment["author"], "green"), comment_str )
    if comments_only:
        return fields["comments"].strip()
    elif mode < 0:
        url_str = colorfunc("%s/browse/%s" % (jirabase, issue["key"]), "white", attrs=["underline"])
        ret_str = colorfunc(issue["key"],status_color) +" "+ issue.setdefault("summary","") + " " + url_str
        if not color:
            ret_str += " [%s] " % get_issue_status(issue["status"])
        return ret_str
    for k,v in fields.items():
        if not v:
            fields[k] = ""
    return "\n".join( " : ".join((k.ljust(20),v)) for k,v in fields.items() ) + "\n"
Ejemplo n.º 2
0
def issue_header(issue):
    """get a single line string for an issue"""
    return "%s (%s)" % (colorfunc("%s, %s: %s" % (issue.key,
                                                  issue.fields.issuetype.name,
                                                  issue.fields.summary),
                                  None, attrs=['bold', 'underline']),
                        colorfunc("%s, %s" % (issue.fields.status.name,
                                              issue.fields.priority.name),
                                  issue_status_color(issue.fields.status.name),
                                  attrs=['bold']))
Ejemplo n.º 3
0
    def _validate_jira_url():
        jirabase = config('jirabase')

        try:
            urllib2.urlopen('%s/rpc/soap/jirasoapservice-v2?wsdl' % jirabase)
            return Client('%s/rpc/soap/jirasoapservice-v2?wsdl' % jirabase)
        except (socket.gaierror, IOError):
            print colorfunc('invalid url %s. Please provide the correct url for your jira instance' % jirabase, 'red')
            config('jirabase', unset=True)
            return _validate_jira_url()
        except Exception, ex:
            raise ex
Ejemplo n.º 4
0
def main():
    try:
        parser = setup_argparser()
        args = parser.parse_args()
        logging.debug(args)
    except Exception, ex:
        sys.exit(colorfunc(str(ex), 'red'))
Ejemplo n.º 5
0
    def _validate_login(token=None):
        if token:
            try:
                JIRAOBJ.service.getPriorities(token)
                return token
            except WebFault:
                return _validate_login()

        try:
            token = JIRAOBJ.service.login(config('user'), config('password'))
            open(os.path.expanduser('~/.jira-cli/token'), 'w').write(token)
            return token
        except WebFault:
            print colorfunc('username or password incorrect, try again.', 'red')
            config('user', unset=True)
            config('password', unset=True)
            return _validate_login()
Ejemplo n.º 6
0
def issue_format(issue, show_desc=False, show_comments=False):
    """return a dict with fields which describe the issue"""
    fields = OrderedDict()
    if hasattr(issue.fields, "parent"):
        fields['parent'] = "%s" % (issue.fields.parent.key)
    if show_desc:
        fields['description'] = "\n%s" % (issue.fields.description)
    fields['created'] = "%s, by %s" % (dtstr2dt(issue.fields.created),
                                       issue.fields.reporter.name)
    if hasattr(issue.fields.assignee, 'name'):
        fields['assignee'] = issue.fields.assignee.name
    fields['updated'] = dtstr2dt(issue.fields.updated)
    if hasattr(issue.fields, 'versions') and issue.fields.fixVersions:
        fields['versions'] = ", ".join([x.name
                                        for x in issue.fields.fixVersions])
    if hasattr(issue.fields, 'components') and issue.fields.components:
        fields['components'] = ", ".join([x.name
                                          for x in issue.fields.components])
    if hasattr(issue.fields, 'labels') and issue.fields.labels:
        fields['labels'] = ", ".join(issue.fields.labels)
    if hasattr(issue.fields, 'attachment') and issue.fields.attachment:
        fields['attachment'] = ", ".join([x.filename
                                          for x in issue.fields.attachment])
    if hasattr(issue.fields, 'issuelinks') and issue.fields.issuelinks:
        link_list = list()
        # inward issue: the issue to link from
        # outward issue: the issue to link to
        for link in issue.fields.issuelinks:
            if 'outwardIssue' in link.raw:
                link_list.append(link.raw['outwardIssue'])
            elif 'inwardIssue' in link.raw:
                link_list.append(link.raw['inwardIssue'])
        fields['issuelinks'] = ", ".join([x['key'] for x in link_list])
    if show_comments:
        if hasattr(issue.fields, 'comment'):
            formatted_issues = ["%s\n%s" % (colorfunc("%s, %s" % (dtstr2dt(x.updated), x.updateAuthor.name), None, attrs=['reverse']), x.body) for x in issue.fields.comment.comments]
            fields['comments'] = "%s\n%s" % (len(issue.fields.comment.comments), "\n\n".join(formatted_issues))
        else:
            fields['comments'] = "0"
    else:
        # show only the number of comments
        if hasattr(issue.fields, 'comment') and issue.fields.comment.comments:
            fields['comments'] = "%s" % (len(issue.fields.comment.comments))
    transitions = jira.transitions(issue)
    fields['trans'] = ", ".join([x['name'] + "(" + x['id'] + ")"
                                 for x in transitions])

    # print(dir(issue.fields))
    # add empty strings if field not available
    for k, v in fields.items():
        if not v:
            fields[k] = ""
    return fields
Ejemplo n.º 7
0
 def _login(u,p):
     username,password = u,p
     if not u:
         sys.stderr.write("enter username:"******"enter password:"******"username or password incorrect, try again.", "red")
         return _login(None,None)
Ejemplo n.º 8
0
 def _validate_jira_url(url=None):
     global jiraobj, token, jirabase
     if not url:
         jirabase = raw_input("base url for your jira instance (e.g http://issues.apache.org/jira):")
     else:
         jirabase = url
     try:
         jiraobj = xmlrpclib.ServerProxy("%s/rpc/xmlrpc" % jirabase )
         # lame ping method
         jiraobj.getIssueTypes()
     except (xml.parsers.expat.ExpatError, xmlrpclib.ProtocolError,socket.gaierror, IOError),  e:
         print >> colorfunc("invalid url %s. Please provide the correct url for your jira installation" % jirabase, "red")
         return _validate_jira_url()
Ejemplo n.º 9
0
 def _validate_jira_url(url=None):
     global jiraobj, token, jirabase
     if not url:
         jirabase = raw_input("base url for your jira instance (e.g http://issues.apache.org/jira):")
     else:
         jirabase = url
     try:
         urllib2.urlopen('%s/rpc/soap/jirasoapservice-v2?wsdl' % jirabase)
         jiraobj = Client('%s/rpc/soap/jirasoapservice-v2?wsdl' % jirabase)
         # lame ping method
         jiraobj.service.getIssueTypes()
     except (socket.gaierror, IOError):
         print >> sys.stderr, colorfunc("invalid url %s. Please provide the correct url for your jira installation" % jirabase, "red")
         return _validate_jira_url()
     except WebFault,e:
         open(os.path.expanduser("~/.jira-cli/config"),"w").write(jirabase)
Ejemplo n.º 10
0
def filter_list_print(filter_list):
    """print a list of filters"""
    for f in filter_list:
        # header
        print("%s" % (colorfunc("%s, %s" % (f.id, f.name),
                                None, attrs=['bold', 'underline'])))
        # fields to show for the filter
        fields = OrderedDict()
        fields['Url'] = f.viewUrl
        fields['description'] = getattr(f, 'description', '')
        fields['owner'] = f.owner.name
        fields['jql'] = f.jql
        # add empty strings if field not available
        for k, v in fields.items():
            if not v:
                fields[k] = ""
        print("\n".join(" : ".join((k.ljust(20), v))
              for k, v in fields.items()) + "\n")
Ejemplo n.º 11
0
def print_error(msg, severity=CRITICAL):
    color = 'red' if severity == CRITICAL else 'yellow'
    sys.stderr.write(colorfunc(msg, color) + "\n")
Ejemplo n.º 12
0
def command_progress(args):
    '''entry point for 'progress' subcommand '''

    def find_by_attr(list, attr, value):
        return next((x for x in list if x[attr].lower() == value), None)

    if not args.issue:
        raise Exception('issue id must be provided')

    available_actions = get_actions(args.issue)
    available_actions_names = [action.name.lower() for action in available_actions]

    if args.actions:
        for idx, action in enumerate(available_actions, start=1):
            print '%d. %s: "%s"' % (idx, colorfunc(action.id, 'green'), action.name)

    if args.start:
        if any(map(lambda a: a in available_actions_names, ['start progress', 'in progress >>'])):
            action = None
            for a in ['start progress', 'in progress >>']:
                action = find_by_attr(available_actions, 'name', a)
                if action:
                    break
            print format_issue(progress(args.issue, action), 0, args.format)
        else:
            sys.exit('unable to start progress on "%s", available actions are: "%s"' % (args.issue,
                     available_actions_names))

    if args.stop:
        if 'stop progress' in available_actions_names:
            print format_issue(progress(args.issue, find_by_attr(available_actions, 'name', 'stop progress')), 0,
                               args.format)
        else:
            sys.exit('unable to stop progress on "%s", available actions are: "%s"' % (args.issue,
                     available_actions_names))

    if args.toggle:
        if 'start progress' in available_actions_names:
            print format_issue(progress(args.issue, find_by_attr(available_actions, 'name', 'start progress')), 0,
                               args.format)
        elif 'stop progress' in available_actions_names:
            print format_issue(progress(args.issue, find_by_attr(available_actions, 'name', 'stop progress')), 0,
                               args.format)
        else:
            sys.exit('unable to toggle progress on "%s", available actions are: "%s"' % (args.issue,
                     available_actions_names))

    if args.transist:
        if args.transist.lower() in available_actions_names:
            print format_issue(progress(args.issue, find_by_attr(available_actions, 'name', args.transist.lower())), 0,
                               args.format)
            available_actions = get_actions(args.issue)
            available_actions_names = [action.name.lower() for action in available_actions]
            print 'available actions from this state are:'
            for idx, action in enumerate(available_actions, start=1):
                print '%d. %s: "%s"' % (idx, colorfunc(action.id, 'green'), action.name)
        else:
            sys.exit('unable to perform transition "%s" on "%s", available actions are: "%s"' % (args.transist,
                     args.issue, available_actions_names))

    if args.close:
        if 'close issue' in available_actions_names:
            print format_issue(progress(args.issue, find_by_attr(available_actions, 'name', 'close issue')), 0,
                               args.format)
        else:
            sys.exit('unable to close "%s", available actions are: "%s"' % (args.issue, available_actions_names))
Ejemplo n.º 13
0
def command_list(args):
    ''' entry point for 'list' subcommand '''

    if not any([
        args.filters,
        args.prios,
        args.statuses,
        args.types,
        args.search,
        args.jqlsearch,
        args.filter,
        args.project,
    ]):
        if not args.issue:
            raise Exception('issue id must be provided')
        for issue in args.issue:
            issue_id = get_issue(issue)
            mode = (0 if not args.verbose else 1)
            mode = (-1 if args.oneline else mode)
            print format_issue(issue_id, mode, args.format, args.commentsonly)

    if args.filters:
        for idx, filt in enumerate(get_filters(), start=1):
            print '%d. %s: %s (Owner: %s)' % (idx, colorfunc(filt.id, 'green'), filt.name, colorfunc(filt.author, 'blue'
                                              ))

    if args.types:
        for idx, typ in enumerate(get_issue_type(None), start=1):
            print '%d. %s: %s' % (idx, colorfunc(typ['name'], 'green'), typ['description'])

    if args.statuses:
        for idx, status in enumerate(get_issue_status(None), start=1):
            print '%d. %s: %s' % (idx, colorfunc(status['name'], 'green'), status['description'])

    if args.prios:
        for idx, prio in enumerate(get_issue_priority(None), start=1):
            print '%d. %s: %s' % (idx, colorfunc(prio['name'], 'green'), prio['description'])

    if args.project:
        for idx, comp in enumerate(get_components(args.project), start=1):
            print '%d. %s: %s' % (idx, colorfunc(comp['id'], 'green'), comp['name'])

    if args.search:
        issues = search_issues(args.search)
        for issue in issues:
            mode = (0 if not args.verbose else 1)
            mode = (-1 if args.oneline else mode)
            print format_issue(issue, mode, args.format)

    if args.jqlsearch:
        issues = search_issues_jql(args.jqlsearch)
        mode = (0 if not args.verbose else 1)
        mode = (-1 if args.oneline else mode)
        for issue in issues:
            print format_issue(issue, mode, args.format)

    if args.filter:
        for filt in args.filter:
            issues = get_issues_by_filter(get_filter_by_name(filt))
            for issue in issues:
                mode = (0 if not args.verbose else 1)
                mode = (-1 if args.oneline else mode)
                print format_issue(issue, mode, args.format, args.commentsonly)
Ejemplo n.º 14
0
def format_issue(issue, mode=0, formatter=None, comments_only=False):
    ''' formatting output for a issue according the different modes '''

    # @TODO rework 'mode' to use args too
    # @TODO better formatting for "multiline" fields

    fields = {}
    status_string = get_issue_status(issue.status).lower()
    status_color = 'blue'
    if status_string in ['resolved', 'closed']:
        status_color = 'green'
    elif status_string in ['open', 'unassigned', 'reopened']:
        status_color = 'red'

    special_fields = {'status': get_issue_status, 'priority': get_issue_priority, 'type': get_issue_type}

    if formatter:
        groups = re.compile('(\$([\w]+))').findall(formatter)
        ret_str = formatter
        for key, value in groups:

            if value.lower() in special_fields.keys():
                issue_id = issue[value.lower()]
                meth = special_fields[value.lower()]
                mappings = meth(None)
                data = ''
                for item in mappings:
                    if item['id'] == issue_id:
                        data = item['name']
                ret_str = ret_str.replace(key, data)
            else:
                ret_str = ret_str.replace(key, str(getattr(issue, value)))
        return ret_str

    if mode >= 0:
        fields['issue'] = issue['key']
        fields['status'] = colorfunc(get_issue_status(issue['status']), status_color)
        fields['reporter'] = issue.reporter
        fields['assignee'] = issue.assignee
        fields['summary'] = issue.summary
        fields['link'] = colorfunc('%s/browse/%s' % (config('jirabase'), issue['key']), 'white', attrs=['underline'])
    if mode >= 1 or comments_only:
        fields['description'] = issue.description.strip()
        fields['priority'] = get_issue_priority(issue.priority)
        fields['type'] = get_issue_type(issue.type)
        fields['components'] = ', '.join([component.name for component in issue.components])
        comments = get_comments(issue['key'])
        fields['comments'] = ''
        for comment in comments:
            comment_body = comment['body'].strip()
            fields['comments'] += '\n' + 20 * ' ' + ': %s %s - "%s"' % (colorfunc(comment['created'], 'blue'),
                    colorfunc(comment['author'], 'green'), comment_body)
    if comments_only:
        return fields['comments'].strip()
    elif mode < 0:
        url_str = colorfunc('%s/browse/%s' % (config('jirabase'), issue['key']), 'white', attrs=['underline'])
        if CONFIG['color']:
            ret_str = colorfunc(issue['key'], status_color)
        else:
            ret_str = issue['key'] + ' [%s] ' % get_issue_status(issue['status'])
        ret_str += ' ' + issue.summary + ' ' + url_str
        return ret_str.encode('utf-8')
    for key, value in fields.items():
        if not value:
            fields[key] = ''
    return '\n'.join(': '.join((k.ljust(20), v.encode('utf-8'))) for (k, v) in fields.items()) + '\n'
Ejemplo n.º 15
0
def main():
    """
    """
    example_usage = """
------------------------------------------------------------------------------------------
view jira: jira-cli BE-193
view multiple jiras: jira-cli XYZ-123 ZZZ-123 ABC-123
add a comment: jira-cli -j BE-193 -c "i am sam"
create a new issue: jira-cli -n bug -p BE -t "i am sam" "and this is my long description
ending
here"
------------------------------------------------------------------------------------------
"""
    parser = optparse.OptionParser()
    parser.usage = example_usage
    parser.add_option("-c",
                      "--comment",
                      dest="comment",
                      help="comment on a jira",
                      action="store_true")
    parser.add_option("",
                      "--comments-only",
                      dest="commentsonly",
                      help="show only the comments for a jira",
                      action="store_true")
    parser.add_option("-j", "--jira-id", dest="jira_id", help="issue id")
    parser.add_option(
        "",
        "--filter",
        dest="filter",
        help=
        "filter(s) to use for listing jiras. use a comma to separate multiple filters"
    )
    parser.add_option("-n",
                      "--new",
                      dest="issue_type",
                      help="create a new issue with given title")
    parser.add_option("",
                      "--priority",
                      dest="issue_priority",
                      help="priority of new issue",
                      default="minor")
    parser.add_option("-t",
                      "--title",
                      dest="issue_title",
                      help="new issue title")
    parser.add_option("-p",
                      "--project",
                      dest="jira_project",
                      help="the jira project to act on")
    parser.add_option("",
                      "--oneline",
                      dest="oneline",
                      help="print only one line of info",
                      action="store_true")
    parser.add_option("",
                      "--list-jira-types",
                      dest="listtypes",
                      help="print out the different jira 'types'",
                      action="store_true")
    parser.add_option("",
                      "--list-filters",
                      dest="listfilters",
                      help="print out the different jira filters available",
                      action="store_true")
    parser.add_option("-v",
                      dest="verbose",
                      action="store_true",
                      help="print extra information")
    parser.add_option("-s", "--search", dest="search", help="search criteria")
    parser.add_option("",
                      "--search-jql",
                      dest="search_jql",
                      help="JQL expression")
    parser.add_option("-f",
                      "--format",
                      dest="format",
                      default=None,
                      help="""format for outputting information.
    allowed tokens: %status,%priority,%updated,%votes,%components,%project,%reporter,%created,%fixVersions,%summary,%environment,%assignee,%key,%affectsVersions,%type.
    examples: "%priority,%reporter","(%key) %priority, reported by %reporter"
    """)
    parser.add_option("",
                      "--user",
                      dest="username",
                      help="username to login as",
                      default=None)
    parser.add_option("",
                      "--password",
                      dest="password",
                      help="passowrd",
                      default=None)

    opts, args = parser.parse_args()
    check_auth(opts.username, opts.password)
    try:
        if opts.listfilters:
            idx = 1
            for f in get_filters():
                print("%d. %s (Owner: %s)" %
                      (idx, f["name"], colorfunc(f["author"], "green")))
                idx += 1
        elif opts.listtypes:
            print("Priorities:")
            for el in get_issue_priority(None):
                print(el["name"], ":", el["description"])
            print()
            print("Issue Types:")
            for el in get_issue_type(None):
                print(el["name"], ":", el["description"])
        else:

            if opts.issue_type:
                project = opts.jira_project
                if args:
                    description = " ".join(args)
                else:
                    description = default_editor_text
                print(
                    format_issue(
                        dict(
                            create_issue(project, opts.issue_type,
                                         opts.issue_title, description,
                                         opts.issue_priority)), 0,
                        opts.format))
            elif opts.comment:
                if not opts.jira_id:
                    parser.error("specify the jira to comment on")
                print(
                    add_comment(
                        opts.jira_id,
                        " ".join(args) if args else default_editor_text))
            elif opts.search or opts.search_jql:
                project = opts.jira_project
                if (project is None):
                    issues = search_issues(
                        opts.search) if opts.search else search_issues_jql(
                            opts.search_jql)
                else:
                    jira_max_int = pow(2, 31) - 1
                    issues = search_issues_with_project(
                        project, opts.search, jira_max_int)
                for issue in issues:
                    mode = 0 if not opts.verbose else 1
                    mode = -1 if opts.oneline else mode
                    print(format_issue(dict(issue), mode, opts.format))
            else:
                # otherwise we're just showing the jira.
                # maybe by filter
                if opts.filter:
                    for f in opts.filter.split(","):
                        issues = get_issues_from_filter(f)
                        for issue in issues:
                            mode = 0 if not opts.verbose else 1
                            mode = -1 if opts.oneline else mode
                            print(
                                format_issue(dict(issue), mode, opts.format,
                                             opts.commentsonly))
                else:
                    if not (opts.jira_id or args):
                        parser.error("jira id must be provided")
                    if args:
                        for arg in args:
                            issue = get_jira(arg)
                            mode = 0 if not opts.verbose else 1
                            mode = -1 if opts.oneline else mode
                            print(
                                format_issue(dict(issue), mode, opts.format,
                                             opts.commentsonly))
                    if opts.jira_id:
                        issue = get_jira(opts.jira_id)
                        print(
                            format_issue(dict(issue),
                                         0 if not opts.verbose else 1,
                                         opts.format))
    except Exception as e:
        parser.error(colorfunc(str(e), "red"))
Ejemplo n.º 16
0
def print_error(msg, severity=CRITICAL):
    color = 'red' if severity == CRITICAL else 'yellow'
    sys.stderr.write(colorfunc(msg, color) + "\n")
Ejemplo n.º 17
0
def issue_format(jira_obj,
                 issue,
                 show_desc=False,
                 show_comments=False,
                 show_trans=False):
    """return a dict with fields which describe the issue"""
    fields = OrderedDict()
    if hasattr(issue.fields, "parent"):
        fields['parent'] = "%s" % (issue.fields.parent.key)
    if show_desc:
        fields['description'] = "\n%s" % (issue.fields.description)
    fields['created'] = "%s, by %s" % (dtstr2dt(
        issue.fields.created), issue.fields.reporter.name)
    if hasattr(issue.fields.assignee, 'name'):
        fields['assignee'] = issue.fields.assignee.name
    fields['updated'] = dtstr2dt(issue.fields.updated)
    if hasattr(issue.fields, 'versions') and len(issue.fields.fixVersions) > 0:
        fields['versions'] = ", ".join(
            map(lambda x: x.name, issue.fields.fixVersions))
    if hasattr(issue.fields, 'components') and \
       len(issue.fields.components) > 0:
        fields['components'] = ", ".join(
            map(lambda x: x.name, issue.fields.components))
    if hasattr(issue.fields, 'labels') and len(issue.fields.labels) > 0:
        fields['labels'] = ", ".join(map(lambda x: x, issue.fields.labels))
    if hasattr(issue.fields, 'attachment') and \
       len(issue.fields.attachment) > 0:
        fields['attachment'] = ", ".join(
            map(lambda x: x.filename, issue.fields.attachment))
    if hasattr(issue.fields, 'issuelinks') and \
       len(issue.fields.issuelinks) > 0:
        link_list = list()
        # inward issue: the issue to link from
        # outward issue: the issue to link to
        for link in issue.fields.issuelinks:
            if 'outwardIssue' in link.raw:
                link_list.append(link.raw['outwardIssue'])
            elif 'inwardIssue' in link.raw:
                link_list.append(link.raw['inwardIssue'])
        fields['issuelinks'] = ", ".join(map(lambda x: x['key'], link_list))
    if show_comments:
        if hasattr(issue.fields, 'comment'):
            fields['comments'] = "%s\n%s" % (len(
                issue.fields.comment.comments), "\n\n".join(
                    map(
                        lambda x: "%s\n%s" %
                        (colorfunc("%s, %s" %
                                   (dtstr2dt(x.updated), x.updateAuthor.name),
                                   None,
                                   attrs=['reverse']), x.body),
                        issue.fields.comment.comments)))  # noqa
        else:
            fields['comments'] = "0"
    else:
        # show only the number of comments
        if hasattr(issue.fields, 'comment') and \
           len(issue.fields.comment.comments) > 0:
            fields['comments'] = "%s" % (len(issue.fields.comment.comments))

    if show_trans:
        transitions = jira_obj.transitions(issue)
        fields['trans'] = ", ".join(
            map(lambda x: x['name'] + "(" + x['id'] + ")", transitions))

    # print(dir(issue.fields))
    # add empty strings if field not available
    for k, v in fields.items():
        if not v:
            fields[k] = ""
    return fields
Ejemplo n.º 18
0
def main():
    """
    """
    example_usage = """
------------------------------------------------------------------------------------------
view jira: jira-cli BE-193
view multiple jiras: jira-cli XYZ-123 ZZZ-123 ABC-123
add a comment: jira-cli -j BE-193 -c "i am sam"
create a new issue: jira-cli -n bug -p BE -t "i am sam" "and this is my long description
ending
here"
------------------------------------------------------------------------------------------
"""
    parser = optparse.OptionParser()
    parser.usage = example_usage
    parser.add_option("-c", "--comment", dest="comment", help="comment on a jira", action="store_true")
    parser.add_option("", "--comments-only", dest="commentsonly", help="show only the comments for a jira",
                      action="store_true")
    parser.add_option("-j", "--jira-id", dest="jira_id", help="issue id")
    parser.add_option("", "--filter", dest="filter",
                      help="filter(s) to use for listing jiras. use a comma to separate multiple filters")
    parser.add_option("-n", "--new", dest="issue_type", help="create a new issue with given title")
    parser.add_option("", "--priority", dest="issue_priority", help="priority of new issue", default="minor")
    parser.add_option("-t", "--title", dest="issue_title", help="new issue title")
    parser.add_option("-p", "--project", dest="jira_project", help="the jira project to act on")
    parser.add_option("", "--oneline", dest="oneline", help="print only one line of info", action="store_true")
    parser.add_option("", "--list-jira-types", dest="listtypes", help="print out the different jira 'types'",
                      action="store_true")
    parser.add_option("", "--list-filters", dest="listfilters", help="print out the different jira filters available",
                      action="store_true")
    parser.add_option("-v", dest="verbose", action="store_true", help="print extra information")
    parser.add_option("-s", "--search", dest="search", help="search criteria")
    parser.add_option("", "--search-jql", dest="search_jql", help="JQL expression")
    parser.add_option("-f", "--format", dest="format", default=None, help="""format for outputting information.
    allowed tokens: %status,%priority,%updated,%votes,%components,%project,%reporter,%created,%fixVersions,%summary,%environment,%assignee,%key,%affectsVersions,%type.
    examples: "%priority,%reporter","(%key) %priority, reported by %reporter"
    """)
    parser.add_option("","--user",dest="username", help="username to login as" , default=None)
    parser.add_option("","--password",dest="password", help="passowrd", default = None )

    opts, args = parser.parse_args()
    check_auth(opts.username, opts.password)
    try:
        if opts.listfilters:
            idx=1
            for f in get_filters():
                print "%d. %s (Owner: %s)" % (idx,  f["name"], colorfunc(f["author"],"green"))
                idx+=1
        elif opts.listtypes:
            print "Priorities:"
            for el in  get_issue_priority(None):
                print el["name"], ":", el["description"]
            print
            print "Issue Types:"
            for el in  get_issue_type(None):
                print el["name"], ":", el["description"]
        else:

            if opts.issue_type:
                project = opts.jira_project
                if args:
                    description = " ".join(args)
                else:
                    description = default_editor_text
                print format_issue ( dict(create_issue ( project, opts.issue_type, opts.issue_title,  description, opts.issue_priority) ), 0, opts.format)
            elif opts.comment:
                if not opts.jira_id:
                    parser.error("specify the jira to comment on")
                print add_comment(opts.jira_id, " ".join(args) if args else default_editor_text)
            elif opts.search or opts.search_jql:
                project = opts.jira_project
                if (project is None):
                    issues = search_issues ( opts.search ) if opts.search else search_issues_jql(opts.search_jql)
                else:
                    jira_max_int = pow(2,31)-1
                    issues = search_issues_with_project( project, opts.search, jira_max_int)
                for issue in issues:
                    mode = 0 if not opts.verbose else 1
                    mode = -1 if opts.oneline else mode
                    print format_issue( dict(issue), mode, opts.format )
            else:
                # otherwise we're just showing the jira.
                # maybe by filter
                if opts.filter:
                    for f in opts.filter.split(","):
                        issues = get_issues_from_filter(f)
                        for issue in issues:
                            mode = 0 if not opts.verbose else 1
                            mode = -1 if opts.oneline else mode
                            print format_issue( dict(issue), mode , opts.format, opts.commentsonly)
                else:
                    if not (opts.jira_id or args):
                        parser.error("jira id must be provided")
                    if args:
                        for arg in args:
                            issue = get_jira(arg)
                            mode = 0 if not opts.verbose else 1
                            mode = -1 if opts.oneline else mode
                            print format_issue( dict(issue), mode , opts.format, opts.commentsonly)
                    if opts.jira_id:
                        issue = get_jira(opts.jira_id)
                        print format_issue( dict(issue), 0  if not opts.verbose else 1, opts.format)
    except Exception, e:
        parser.error(colorfunc(str(e), "red"))
Ejemplo n.º 19
0
def format_issue(issue, mode=0, formatter=None, comments_only=False):
    fields = {}
    global colorfunc
    status_color = "blue"
    status_string = get_issue_status(issue.setdefault("status", "1")).lower()
    if status_string in ["resolved", "closed"]:
        status_color = "green"
    elif status_string in ["open", "unassigned", "reopened"]:
        status_color = "red"

    special_fields = {
        "status": get_issue_status,
        "priority": get_issue_priority,
        "type": get_issue_type
    }

    if formatter:
        groups = re.compile("(%([\w]+))").findall(formatter)
        ret_str = formatter
        for k, v in groups:
            if v.lower() in special_fields.keys():
                meth = special_fields[v.lower()]
                key = issue[v.lower()]
                mappings = meth(None)
                data = ""
                for item in mappings:
                    if item['id'] == key:
                        data = item['name']
                ret_str = ret_str.replace(k, data)
            else:
                ret_str = ret_str.replace(k,
                                          str(issue.setdefault(v.lower(), "")))
        return ret_str

    if mode >= 0:
        # minimal
        fields["issue"] = issue["key"]
        fields["status"] = colorfunc(get_issue_status(issue["status"]),
                                     status_color)
        fields["reporter"] = issue.setdefault("reporter", "")
        fields["assignee"] = issue.setdefault("assignee", "")
        fields["summary"] = issue.setdefault("summary", "")
        fields["link"] = colorfunc("%s/browse/%s" % (jirabase, issue["key"]),
                                   "white",
                                   attrs=["underline"])
    if mode >= 1 or comments_only:
        fields["description"] = issue.setdefault("description", "")
        fields["priority"] = get_issue_priority(
            issue.setdefault("priority", ""))
        fields["type"] = get_issue_type(issue.setdefault("type", ""))
        comments = get_comments(issue["key"])
        fields["comments"] = "\n"
        for comment in comments:
            comment_str = comment["body"].strip()
            fields["comments"] += "%s %s : %s\n" % (colorfunc(
                comment["created"],
                "blue"), colorfunc(comment["author"], "green"), comment_str)
    if comments_only:
        return fields["comments"].strip()
    elif mode < 0:
        url_str = colorfunc("%s/browse/%s" % (jirabase, issue["key"]),
                            "white",
                            attrs=["underline"])
        ret_str = colorfunc(issue["key"],
                            status_color) + " " + issue.setdefault(
                                "summary", "") + " " + url_str
        if not color:
            ret_str += " [%s] " % get_issue_status(issue["status"])
        return ret_str
    for k, v in fields.items():
        if not v:
            fields[k] = ""
    return "\n".join(" : ".join((k.ljust(20), v))
                     for k, v in fields.items()) + "\n"