jira

package module
v0.1.13 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 24, 2017 License: Apache-2.0 Imports: 27 Imported by: 0

README

Build Status GoDoc

go-jira

simple command line client for Atlassian's Jira service written in Go

Synopsis

jira ls -p GOJIRA                       # list all unresolved issues for project GOJIRA
jira ls -p GOJIRA -a mothra             # as above also assigned to user mothra
jira ls -p GOJIRA -w mothra             # lists GOJIRA unresolved issues watched by user mothra
jira ls -p GOJIRA -r mothra             # list GOJIRA unresolved issues reported by user mothra
jira ls -t table -p GOJIRA              # list all unresolved issues in pretty table output

jira view GOJIRA-321                    # print Issue using "view" template
jira GOJIRA-321                         # same as above

jira edit GOJIRA-321                    # open up the issue in an editor, when you exit the
                                        # editor the issue will post the updates to the server

# edit the issue, using the overrides on the command line, skip the interactive editor:
jira edit GOJIRA-321 --noedit \
     -o assignee=mothra \
     -o comment="mothra, please take care of this." \
     -o priority=Major

jira create -p GOJIRA                   # create new "Bug" type issue for project GOJIRA
jira create -p GOJIRA -i Task           # create new Task type issue

jira trans close GOJIRA-321             # close issue, with interactive editor to set fields
jira close GOJIRA-321 --edit            # same as above

# close the issue, set the resolution, and skip interactive editor:
jira trans close GOJIRA-321 -o resolution="Won't Fix" --noedit
# same as above
jira close GOJIRA-321 -o resolution="Won't Fix"

jira reopen GOJIRA-321 -m "reopening"  # reopen issue

jira watch GOJIRA-321                   # add self as watcher to the issue

jira comment GOJIRA-321 -m "done yet?"  # add comment to the issue

jira take GOJIRA-321                    # assign issue to self

jira give GOJIRA-321 mothra             # assign issue to user mothra

# create local project config to set defaults
mkdir .jira.d
echo "project: GOJIRA" > .jira.d/config.yml

jira ls                                 # list all unresolved issues for project GOJRIA
jira ls -a mothra                       # as above also assigned to user mothra
jira ls -w mothra                       # lists GOJIRA unresolved issues watched by user mothra
jira ls -r mothra                       # list GOJIRA unresolved issues reported by user mothra
jira ls -t table                        # list all unresolved issues in pretty table output

jira create                             # create new "Bug" type issue for project GOJIRA
jira create -i Task                     # create new Task type issue

# make the table template your default "list" template:
jira export-templates -t table
mv $HOME/.jira.d/templates/table $HOME/.jira.d/templates/list

Download

You can download one of the pre-built binaries for go-jira here.

Build

  • NOTE You will need go-1.4.1 minimum

  • To build the jira binary the current directory just run:

make
  • To install the binary to you ~/bin directory you can run:
make install

Configuration

go-jira uses a configuration hierarchy. When loading the configuration from disk it will recursively look through all parent directories in your current path looking for a .jira.d directory. If your current directory is not a child directory of your homedir, then your homedir will also be inspected for a .jira.d directory. From all of .jira.d directories discovered go-jira will load a config.yml if found. The configuration properties found in a file closests to your current working directory will have precedence. Properties overriden with command line options will have final precedence.

The complicated configuration hierarchy is used because go-jira attempts to be context aware. For example, if you are working on a "foo" project and you cd into your project workspace, wouldn't it be nice if jira ls automatically knew to list only issues related to the "foo" project? Likewise when you cd to the "bar" project then jira ls should only list issues related to "bar" project. You can do this with by creating a configuration under your project workspace at ./.jira.d/config.yml that looks like:

project: foo

You will need to specify your local jira endpoint first, typically in your homedir like:

mkdir ~/.jira.d

cat <<EOM >~/.jira.d/config.yml
endpoint: https://jira.mycompany.com
EOM

Then use jira login to authenticate yourself as $USER. To change your username, use the -u CLI flag or set user: in your config.yml

Dynamic Configuration

If the .jira.d/config.yml file is executable, then go-jira will attempt to execute the file and use the stdout for configuration. You can use this to customize templates or other overrides depending on what type of operation you are running. For example if you would like to use the "table" template when ever you run jira ls, then you can create a template like this:

#!/bin/sh

echo "endpoint: https://jira.mycompany.com"
echo "editor: emacs -nw"

case $JIRA_OPERATION in 
    list)
      echo "template: table";;
esac

Or if you always set the same overrides when you create an issue for your project you can do something like this:

#!/bin/sh
echo "project: GOJIRA"

case $JIRA_OPERATION in
    create)
        echo "assignee: $USER"
        echo "watchers: mothra"
        ;;
esac
Editing

When you run command like jira edit it will open up your favorite editor with the templatized output so you can quickly edit. When the editor closes go-jira will submit the completed form. The order which go-jira attempts to determine your prefered editor is:

  • editor property in any config.yml file
  • JIRA_EDITOR environment variable
  • EDITOR environment variable
  • vim
Templates

go-jira has the ability to customize most output (and editor input) via templates. There are default templates available for all operations, which may or may not work for your actual jira implementation. Jira is endlessly customizable, so it is hard to provide default templates that will work for all issue types.

When running a command like jira edit it will look through the current directory hierarchy trying to find a file that matches .jira.d/templates/edit, if found it will use that file as the template, otherwise it will use the default edit template hard-coded into go-jira. You can export the default hard-coded templates with jira export-templates which will write them to ~/.jira.d/templates/.

Writing/Editing Templates

First the basic templating functionality is defined by the Go language 'text/template' library. The library reference documentation can be found here, and there is a good primer document here. go-jira also provides a few extra helper functions to make it a bit easlier to format the data, those functions are defined here.

Knowing what data and fields are available to any given template is not obvious. The easiest approach to determine what is available is to use the debug template on any given operation. For eample to find out what is available to the "view" templates, you can use:

jira view GOJIRA-321 -t debug

This will print out the data in JSON format that is available to the template. You can do this for any other operation, like "list":

jira list -t debug

Figuring out what is available to input templates (like for the create operation) is a bit more tricky, but similar. To find the data available for a create template you can run:

jira create --dryrun -t debug --editor /bin/cat

This will attempt to fetch metadata for your default project (you can provide any options that you would normally specify for the create operation). It uses the --dryrun option to prevent any actual updates being sent to Jira. The -t debug is like before to cause the input to be serialized to JSON and printed for your inspection. Finally the --editor /bin/cat will cause go-jira to just print the template rather than open up an editor and wait for you to edit/save it.

Authentication

By default go-jira will prompt for a password automatically when we receive an 403 http response. Then after authentication we cache the JSESSSION cookie returned by the service and reuse that on subsequent requests. Typically this cookie will be valid for several hours (depending on the service configuration). Many deployments of Jira (like the cloud services on atlassian.net) have "websudo" enabled which will prevent the cookie based authentcation from working. On these deployments you have a few options with go-jira. You can enable a password-source via .jira.d/config.yml with possible values of keyring or pass.

keyring password source

Note: Version 0.1.9 required. On OSX and Linux there are a few keyring providers that go-jira can use (via this golang module). To integrate go-jira with a supported keyring just add this configuration to $HOME/.jira.d/config.yml:

password-source: keyring

After setting this and issuing a jira login, your credentials will be stored in your platform's backend (e.g. Keychain for Mac OS X) automatically. Subsequent operations, like a jira ls, should "just work" from there.

pass password source

Note: Version 0.1.9 required. An alternative to the keyring password source is the pass tool (documentation here). This uses gpg to encrypt/decrypt passwords on demand and by using gpg-agent you can cache the gpg credentials for a period of time so you will not be prompted repeatedly for decrypting the passwords. The advantage over the keyring integration is that pass can be used on more platforms than OSX and Linux, although it does require more setup. To use pass for password storage and retrieval via go-jira just add this configuration to $HOME/.jira.d/config.yml:

password-source: pass

This assumes you have already setup pass correctly on your system. Specifically you will need to have created a gpg key like this:

$ gpg --gen-key

Then you will need the GPG Key ID you want associated with pass. First list the available keys:

$ gpg --list-keys
/home/gojira/.gnupg/pubring.gpg
-------------------------------------------------
pub   2048R/A307D709 2016-12-18
uid                  Go Jira <gojira@example.com>
sub   2048R/F9A047B8 2016-12-18

Then initialize the pass tool to use the correct key:

$ pass init "Go Jira <gojira@example.com>"

You probably want to setup gpg-agent so that you dont have to type in your gpg passphrase all the time. You can get gpg-agent to automatically start by adding something like this to your $HOME/.bashrc

if [ -f $HOME/.gpg-agent-info ]; then
    . $HOME/.gpg-agent-info
    export GPG_AGENT_INFO
fi
# verify sock file from GPG_AGENT_INFO is actually present
if [ ! -S "${GPG_AGENT_INFO%%:*}" ]; then
    # set passphrase cache so I only have to type my passphrase once a day
    eval $(gpg-agent --default-cache-ttl 604800 --daemon --write-env-file $HOME/.gpg-agent-info)
fi
export GPG_TTY=$(tty)

Usage

Usage:
  jira (ls|list) <Query Options> 
  jira view ISSUE
  jira edit [--noedit] <Edit Options> [ISSUE | <Query Options>]
  jira create [--noedit] [-p PROJECT] <Create Options>
  jira DUPLICATE dups ISSUE
  jira BLOCKER blocks ISSUE
  jira watch ISSUE [-w WATCHER]
  jira (trans|transition) TRANSITION ISSUE [--noedit] <Edit Options>
  jira ack ISSUE [--edit] <Edit Options>
  jira close ISSUE [--edit] <Edit Options>
  jira resolve ISSUE [--edit] <Edit Options>
  jira reopen ISSUE [--edit] <Edit Options>
  jira start ISSUE [--edit] <Edit Options>
  jira stop ISSUE [--edit] <Edit Options>
  jira comment ISSUE [--noedit] <Edit Options>
  jira take ISSUE
  jira (assign|give) ISSUE ASSIGNEE
  jira fields
  jira issuelinktypes
  jira transmeta ISSUE
  jira editmeta ISSUE
  jira issuetypes [-p PROJECT] 
  jira createmeta [-p PROJECT] [-i ISSUETYPE] 
  jira transitions ISSUE
  jira export-templates [-d DIR] [-t template]
  jira (b|browse) ISSUE
  jira login
  jira ISSUE

General Options:
  -b --browse         Open your browser to the Jira issue
  -e --endpoint=URI   URI to use for jira
  -h --help           Show this usage
  -t --template=FILE  Template file to use for output/editing
  -u --user=USER      Username to use for authentication (default: $USER)
  -v --verbose        Increase output logging

Query Options:
  -a --assignee=USER        Username assigned the issue
  -c --component=COMPONENT  Component to Search for
  -f --queryfields=FIELDS   Fields that are used in "list" template: (default: summary,created,updated,priority,status,reporter,assignee)
  -i --issuetype=ISSUETYPE  The Issue Type
  -l --limit=VAL            Maximum number of results to return in query (default: 500)
  -p --project=PROJECT      Project to Search for
  -q --query=JQL            Jira Query Language expression for the search
  -r --reporter=USER        Reporter to search for
  -s --sort=ORDER           For list operations, sort issues (default: priority asc, created)
  -w --watcher=USER         Watcher to add to issue (default: $USER)
                            or Watcher to search for

Edit Options:
  -m --comment=COMMENT      Comment message for transition
  -o --override=KEY=VAL     Set custom key/value pairs

Create Options:
  -i --issuetype=ISSUETYPE  Jira Issue Type (default: Bug)
  -m --comment=COMMENT      Comment message for transition
  -o --override=KEY=VAL     Set custom key/value pairs

Command Options:
  -d --directory=DIR        Directory to export templates to (default: $HOME/.jira.d/templates)

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (

	// VERSION is the go-jira library version
	VERSION string
)

Functions

func FindClosestParentPath

func FindClosestParentPath(fileName string) (string, error)

FindClosestParentPath finds the path that matches the given fileName path that is closest to the current working directory

func FindParentPaths

func FindParentPaths(fileName string) []string

FindParentPaths will find all available paths from the current path up to the root that matches the given fileName path

func RunTemplate

func RunTemplate(templateContent string, data interface{}, out io.Writer) error

RunTemplate will run the give templateContent as a golang text/template and pass the provided data to the template execution. It will write the output to the provided "out" writer.

Types

type Cli

type Cli struct {
	// contains filtered or unexported fields
}

Cli is go-jira client object

func New

func New(opts map[string]interface{}) *Cli

New creates go-jira client object

func (*Cli) Browse

func (c *Cli) Browse(issue string) error

Browse will open up your default browser to the provided issue

func (*Cli) CmdAssign

func (c *Cli) CmdAssign(issue string, user string) error

CmdAssign will assign the given user to be the owner of the given issue

func (*Cli) CmdBlocks

func (c *Cli) CmdBlocks(blocker string, issue string) error

CmdBlocks will update the given issue as being "blocked" by the given blocker

func (*Cli) CmdComment

func (c *Cli) CmdComment(issue string) error

CmdComment will open up editor with "comment" template and submit YAML output to jira

func (*Cli) CmdComponent added in v0.1.0

func (c *Cli) CmdComponent(action string, project string, name string, desc string, lead string) error

CmdComponent will add a new component to given project

func (*Cli) CmdComponents added in v0.1.0

func (c *Cli) CmdComponents(project string) error

CmdComponents sends component data for given project and sends to the "components" template

func (*Cli) CmdCreate

func (c *Cli) CmdCreate() error

CmdCreate sends the create-metadata to the "create" template for editing, then will parse the edited document as YAML and submit the document to jira.

func (*Cli) CmdCreateMeta

func (c *Cli) CmdCreateMeta() error

CmdCreateMeta sends the 'create' metadata for the given project & issuetype and sends it to the 'createmeta' template

func (*Cli) CmdDups

func (c *Cli) CmdDups(duplicate string, issue string) error

CmdDups will update the given issue as being a duplicate by the given dup issue and will attempt to resolve the dup issue

func (*Cli) CmdEdit

func (c *Cli) CmdEdit(issue string) error

CmdEdit will populate "edit" template with issue data and issue "editmeta" data. Then will parse yaml template and submit data to jira.

func (*Cli) CmdEditMeta

func (c *Cli) CmdEditMeta(issue string) error

CmdEditMeta will send issue 'edit' metadata to the "editmeta" template

func (*Cli) CmdExportTemplates

func (c *Cli) CmdExportTemplates() error

CmdExportTemplates will export the default templates to the template directory.

func (*Cli) CmdFields

func (c *Cli) CmdFields() error

CmdFields will send data from /rest/api/2/field API to "fields" template

func (c *Cli) CmdIssueLink(inwardIssue string, issueLinkTypeName string, outwardIssue string) error

CmdIssueLink is a generic function for adding a link type to an issue

func (*Cli) CmdIssueLinkTypes

func (c *Cli) CmdIssueLinkTypes() error

CmdIssueLinkTypes will send the issue link type data to the "issuelinktypes" template.

func (*Cli) CmdIssueTypes

func (c *Cli) CmdIssueTypes() error

CmdIssueTypes will send issue 'create' metadata to the 'issuetypes'

func (*Cli) CmdLabels

func (c *Cli) CmdLabels(action string, issue string, labels []string) error

CmdLabels will add, remove or set labels on a given issue

func (*Cli) CmdList

func (c *Cli) CmdList() error

CmdList will query jira and send data to "list" template

func (*Cli) CmdLogin

func (c *Cli) CmdLogin() error

CmdLogin will attempt to login into jira server

func (*Cli) CmdLogout added in v0.1.4

func (c *Cli) CmdLogout() error

CmdLogout will close any active sessions

func (*Cli) CmdRankAfter added in v0.1.8

func (c *Cli) CmdRankAfter(issue, after string) error

CmdRankAfter rank issue after target issue

func (*Cli) CmdRankBefore added in v0.1.8

func (c *Cli) CmdRankBefore(issue, before string) error

CmdRankBefore rank issue before target issue

func (*Cli) CmdRequest

func (c *Cli) CmdRequest(uri, content string) (err error)

CmdRequest will use the given uri to make a request and potentially send provided content.

func (*Cli) CmdSubtask added in v0.1.11

func (c *Cli) CmdSubtask(issue string) error

CmdSubtask sends the create-metadata to the "subtask" template for editing, then will parse the edited document as YAML and submit the document to jira.

func (*Cli) CmdTransition

func (c *Cli) CmdTransition(issue string, trans string) error

CmdTransition will move state of the given issue to the given transtion

func (*Cli) CmdTransitionMeta

func (c *Cli) CmdTransitionMeta(issue string) error

CmdTransitionMeta will send available transition metadata to the "transmeta" template

func (*Cli) CmdTransitions

func (c *Cli) CmdTransitions(issue string) error

CmdTransitions sends valid transtions for given issue to the "transitions" template

func (*Cli) CmdView

func (c *Cli) CmdView(issue string) error

CmdView will get issue data and send to "view" template

func (*Cli) CmdVote added in v0.1.0

func (c *Cli) CmdVote(issue string, up bool) error

CmdVote will add or remove a vote on an issue

func (*Cli) CmdWatch

func (c *Cli) CmdWatch(issue string, watcher string, remove bool) error

CmdWatch will add the given watcher to the issue (or remove the watcher given the 'remove' flag)

func (*Cli) CmdWorklog added in v0.1.6

func (c *Cli) CmdWorklog(action string, issue string) error

CmdWorklog will attempt to add (action=add) a worklog to the given issue. It will spawn the editor (unless --noedit isused) and post edited YAML content as JSON to the worklog endpoint

func (*Cli) CmdWorklogs added in v0.1.6

func (c *Cli) CmdWorklogs(issue string) error

CmdWorklogs will get worklog data for given issue and sent to the "worklogs" template

func (*Cli) FindIssues

func (c *Cli) FindIssues() (interface{}, error)

FindIssues will return a list of issues that match the given options. If the "query" option is undefined it will generate a JQL query using any/all of the provide options: project, component, assignee, issuetype, watcher, reporter, sort Further it will restrict the fields being extracted from the jira response with the 'queryfields' option

func (*Cli) GetOptBool added in v0.1.0

func (c *Cli) GetOptBool(optName string, dflt bool) bool

GetOptBool will extract the boolean value from the Client object options otherwise return the provided default\

func (*Cli) GetOptString added in v0.1.0

func (c *Cli) GetOptString(optName string, dflt string) string

GetOptString will extract the string from the Cli object options otherwise return the provided default

func (*Cli) GetPass added in v0.1.10

func (c *Cli) GetPass(user string) string

func (*Cli) GetTemplate

func (c *Cli) GetTemplate(name string) string

GetTemplate will return the text/template for the given command name

func (*Cli) RankIssue added in v0.1.8

func (c *Cli) RankIssue(issue, target string, order RankOrder) error

RankIssue will modify issue to have rank before or after the target issue

func (*Cli) SaveData

func (c *Cli) SaveData(data interface{}) error

SaveData will write out the yaml formated --saveFile file with provided data

func (*Cli) SetPass added in v0.1.10

func (c *Cli) SetPass(user, passwd string) error

func (*Cli) ValidTransitions added in v0.1.4

func (c *Cli) ValidTransitions(issue string) (jiradata.Transitions, error)

ValidTransitions will return a list of valid transitions for given issue.

func (*Cli) ViewIssue

func (c *Cli) ViewIssue(issue string) (interface{}, error)

ViewIssue will return the details for the given issue id

func (*Cli) ViewIssueWorkLogs added in v0.1.6

func (c *Cli) ViewIssueWorkLogs(issue string) (interface{}, error)

ViewIssueWorkLogs gets the worklog data for the given issue

type NoChangesFound

type NoChangesFound struct{}

NoChangesFound is an error returned from when editing templates and no modifications were made while editing

func (NoChangesFound) Error

func (f NoChangesFound) Error() string

type RankOrder added in v0.1.8

type RankOrder int

RankOrder type used to specify before/after ranking arguments to RankIssue

const (
	// RANKBEFORE should be used to rank issue before the target issue
	RANKBEFORE RankOrder = iota
	// RANKAFTER should be used to rank issue after the target issue
	RANKAFTER RankOrder = iota
)

type Transport added in v0.1.8

type Transport struct {
	// contains filtered or unexported fields
}

func NewUnixProxyTransport added in v0.1.8

func NewUnixProxyTransport(path string) *Transport

func UnixProxy added in v0.1.8

func UnixProxy(path string) *Transport

func (*Transport) RoundTrip added in v0.1.8

func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL