Compare commits

..

33 Commits

Author SHA1 Message Date
Mike Pountney c442e2c98d Add test for findClosestParentPath to check for figtree regression
I inadvertently 'upgraded' to coryb/figtree v1.0.0, and it caused an
error in findCLosestParentPath, due to figtree.FindParentPaths having
a different function signature in v1.0.0

No idea why a regular compile isn't picking this up - but when
explicitly testing like this, we get the error detailed in #277:

```
Mikes-MBP:jira mike$ go test ./...
?       github.com/go-jira/jira [no test files]
jiracli/util.go:29:34: too many arguments in call to figtree.FindParentPaths
        have (string, string, string)
        want (string)
jiracli/util.go:29:34: too many arguments in call to figtree.FindParentPaths
        have (string, string, string)
        want (string)
FAIL    github.com/go-jira/jira/jiracli [build failed]
ok      github.com/go-jira/jira/jiradata        (cached)
Mikes-MBP:jira mike$
```
2019-09-15 21:47:49 -07:00
Mike Pountney 27f57b2bbe Switch over to using github.com/go-jira/jira, from gopkg.in
There should be no reason to use gopkg.in versioned imports now that
we're using go modules. I think, IANAE.

gopkg.in kind of gets in the way of modules, as it only pulls over
tagged releases from github.com -- this then means that you need to use
go modules 'replace' syntax in the go.mod to use a non-versioned commit
or branch. This is feasible, but kind of ugly.

go modules defaults to pulling the latest version, so the default
behavior is the same as when pulling go-jira.v1 from gopkg.in.
2019-09-14 21:31:11 -07:00
coryb 71aaa88b13 Merge pull request #276 from go-jira/fix_228
Fixes #228: make ':' gpg files temporary to fix go mod
2019-09-13 22:13:01 -07:00
Mike Pountney 52a577ea48 Fixes #228: make ':' gpg files temporary to fix go mod 2019-09-13 21:38:25 -07:00
coryb b8e73a5cb0 Merge pull request #266 from mbethke/fix-multiline-worklog-comment
Fix worklog template for multiline comments
2019-07-05 11:43:48 -07:00
Matthias Bethke 43e07f1197 fix worklog template to allow multiline comments 2019-07-05 09:07:09 +02:00
coryb 957696bed8 Merge pull request #263 from kojustin/master
Allow reading password from stdin
2019-06-05 14:24:50 -07:00
Justin Ko 225e1dcc05 Allow reading password from stdin
Allow reading password from stdin in `jira login`. This is useful for
combining the jira tool with other command-line utilities.
2019-06-05 14:08:09 -07:00
Cory Bennett f1390760b4 add CODEOWNERS file 2019-05-28 17:31:23 -07:00
Daniel Martí 31c113d1ba all: unindent some code 2019-05-28 11:01:51 +01:00
Daniel Martí 9bcdcc128f don't use ReadAll when decoding JSON
An empty stream isn't valid JSON, so we shouldn't silently ignore it.
2019-05-27 13:09:31 +01:00
Daniel Martí 098d963881 README: trim down the content
This README is huge; the document shouldn't take more than two or three
screens. If we need more docs, they should be linked to and live
elsewhere.

For now, start by removing unnecessary sections. Gitter has been
completely unused since 2017, so remove it. The table of contents also
takes a lot of vertical space, when we don't want to have that much
content to begin with.

Tips on forking are also unnecessary, since that's the same for all Go
projects. Moreover, this is out of date now that the project is a Go
module.

Remove the help output, as that can be obtained extremely easily by just
running 'jira -h'.

Finally, remove the v0-v1 changes, as v0 was last released over three
years ago. It's extremely unlikely that anyone still has to upgrade from
the older version.
2019-05-27 13:08:36 +01:00
Daniel Martí 9b9186f7d4 start making staticcheck happier 2019-05-27 10:49:15 +01:00
Daniel Martí f125ef3fa9 all: convert to a Go module
And remove vendor/, as it's now unnecessary. go.sum ensures that
dependencies aren't tampered with, and proxy.golang.org keeps copies of
all the archives.
2019-05-26 23:40:16 +01:00
coryb 5cc009af4c Merge pull request #253 from mvdan/module
t: rename to _t to fix module support
2019-05-26 14:41:18 -07:00
Daniel Martí d237e86cda t: rename to _t to fix module support
The following two files contain characters which aren't valid in source
files within a Go module:

	t/.password-store/GoJira/api-token:gojira@corybennett.org.gpg
	t/.password-store/GoJira/api-token:mothra@corybennett.org.gpg

The directory only contains test scripts, so it doesn't need to be
included in the module. The simplest way to do that is to start the
directory with an underscore.

Fixes #228.
2019-05-26 22:34:24 +01:00
Daniel Martí 664c5cad24 CI: test on Go 1.12.x, cleanup
We can also use the apt addon to install packages. We also don't need
fast_finish, since we don't use allow_failures anywhere.

Finally, the 'go get' line was pointless, as all dependencies are
vendored, and 'go test' will catch build failures.
2019-05-26 21:34:53 +01:00
Cory Bennett 36c99ce040 make automatic pagination on search optional, fix tests 2019-05-25 17:06:03 -07:00
coryb 58a300422b Merge pull request #240 from jgraglia/patch-1
API Token auth requires "user" config
2019-05-25 15:34:25 -07:00
coryb eb90676bbc Merge pull request #219 from kerhac/master
docs: update pass documentation with password-name
2019-05-25 15:33:39 -07:00
coryb d54a549d24 Merge pull request #236 from CodeLingoBot/rewrite
Fix function comments based on best practices from Effective Go
2019-05-25 14:12:06 -07:00
Cory Bennett 3d00c294f4 add test for --limit 2019-05-25 14:10:18 -07:00
Cory Bennett 181bd74f1b prefer defer resp.Body.Close to avoid leaks on subsequent errors 2019-05-25 14:09:48 -07:00
Cory Bennett f6809e32f4 version bump 2019-05-25 14:09:12 -07:00
Cory Bennett cbcac1755a Updated Changelog 2019-05-25 14:09:12 -07:00
coryb 890b9aa724 Merge pull request #245 from justmiles/211
add pagination to search (closes #211)
2019-05-25 14:08:09 -07:00
Miles Maddox 76dd1d8982 add pagination to search 2019-04-21 07:33:17 -05:00
Julien Graglia 271289a3c9 API Token auth requires "user" config
API Token authentication requires the `user ` to be defined in the config
2019-03-26 09:49:29 +01:00
Julian Swagemakers d8189f0a01 docs: update pass documentation with password-name
This will update the README.md to include setting the configuration
option password-name when using pass.
2019-03-13 07:48:50 +01:00
CodeLingo Bot 23ac11872b Fix function comments based on best practices from Effective Go
Signed-off-by: CodeLingo Bot <bot@codelingo.io>
2019-02-28 21:20:03 +00:00
coryb 514c1491c7 Merge pull request #220 from ejsuncy/master
docs: Fix grammar typos (#1)
2018-11-29 19:52:02 -08:00
Dan Bunker 9258d4df15 Fix grammar typos (#1) 2018-11-29 11:20:55 -07:00
Cory Bennett ee69afadd0 [#201] update required library, failing to populate cookiejar from cookies file 2018-08-04 14:20:03 -07:00
568 changed files with 635 additions and 216115 deletions
+2
View File
@@ -0,0 +1,2 @@
# one of these users must approve the PR before merging
* @coryb @mvdan @vanniktech @mikepea
+10 -8
View File
@@ -1,10 +1,12 @@
jira
schemas/*.json
t/.gnupg/random_seed
t/issue.props
t/attach.props
t/garbage.bin
t/attach1.txt
t/binary.out
t/foobar.bin
dist
/_t/.gnupg/random_seed
/_t/issue.props
/_t/attach.props
/_t/garbage.bin
/_t/attach1.txt
/_t/binary.out
/_t/foobar.bin
/_t/.password-store/GoJira/api-token:gojira@corybennett.org.gpg
/_t/.password-store/GoJira/api-token:mothra@corybennett.org.gpg
dist
+11 -11
View File
@@ -1,19 +1,19 @@
sudo: true
before_install:
- sudo apt-get update && sudo apt-get install -y pass gnupg
addons:
apt:
packages:
- pass
- gnupg
language: go
go_import_path: gopkg.in/Netflix-Skunkworks/go-jira.v1
go:
- 1.9
matrix:
fast_finish: true
go:
- 1.12.x
env:
- GO111MODULE=on
script:
- go get -t -v ./...
- go test ./...
- go vet -composites=false ./...
- make
- make prove 2>&1
+4
View File
@@ -1,5 +1,9 @@
# Changelog
## 1.0.20 - 2018-08-04
* [[#201](https://github.com/Netflix-Skunkworks/go-jira/issues/201)] update required library, failing to populate cookiejar from cookies file [Cory Bennett] [[ee69afa](https://github.com/Netflix-Skunkworks/go-jira/commit/ee69afa)]
## 1.0.19 - 2018-08-02
* [[#199](https://github.com/Netflix-Skunkworks/go-jira/issues/199)] [[#198](https://github.com/Netflix-Skunkworks/go-jira/issues/198)] update http client library, fix issues with internal login retries [Cory Bennett] [[0cba806](https://github.com/Netflix-Skunkworks/go-jira/commit/0cba806)]
Generated
-193
View File
@@ -1,193 +0,0 @@
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
branch = "master"
name = "github.com/alecthomas/template"
packages = [
".",
"parse"
]
revision = "a0175ee3bccc567396460bf5acd36800cb10c49c"
[[projects]]
branch = "master"
name = "github.com/alecthomas/units"
packages = ["."]
revision = "2efee857e7cfd4f3d0138cc3cbb1b4966962b93a"
[[projects]]
branch = "master"
name = "github.com/cheekybits/genny"
packages = ["generic"]
revision = "c546fedd85a9b2291805f7a2933a3564cbdda989"
source = "github.com/coryb/genny"
[[projects]]
branch = "master"
name = "github.com/coryb/figtree"
packages = ["."]
revision = "071d1ef303dfb7738166ba62aac71e5ee10ce218"
[[projects]]
branch = "master"
name = "github.com/coryb/kingpeon"
packages = ["."]
revision = "9a669f143f2e7454e80064c47365d139420a3fff"
[[projects]]
branch = "master"
name = "github.com/coryb/oreo"
packages = ["."]
revision = "efd7a2135270bc44f64af39446c7226057e6953d"
[[projects]]
name = "github.com/davecgh/go-spew"
packages = ["spew"]
revision = "346938d642f2ec3594ed81d874461961cd0faa76"
version = "v1.1.0"
[[projects]]
branch = "master"
name = "github.com/fatih/camelcase"
packages = ["."]
revision = "44e46d280b43ec1531bb25252440e34f1b800b65"
[[projects]]
branch = "master"
name = "github.com/guelfey/go.dbus"
packages = ["."]
revision = "f6a3a2366cc39b8479cadc499d3c735fb10fbdda"
[[projects]]
branch = "master"
name = "github.com/jinzhu/copier"
packages = ["."]
revision = "7e38e58719c33e0d44d585c4ab477a30f8cb82dd"
[[projects]]
branch = "master"
name = "github.com/kballard/go-shellquote"
packages = ["."]
revision = "95032a82bc518f77982ea72343cc1ade730072f0"
[[projects]]
name = "github.com/mattn/go-colorable"
packages = ["."]
revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072"
version = "v0.0.9"
[[projects]]
name = "github.com/mattn/go-isatty"
packages = ["."]
revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39"
version = "v0.0.3"
[[projects]]
branch = "master"
name = "github.com/mgutz/ansi"
packages = ["."]
revision = "9520e82c474b0a04dd04f8a40959027271bab992"
[[projects]]
branch = "master"
name = "github.com/pkg/browser"
packages = ["."]
revision = "c90ca0c84f15f81c982e32665bffd8d7aac8f097"
[[projects]]
name = "github.com/pkg/errors"
packages = ["."]
revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
version = "v0.8.0"
[[projects]]
name = "github.com/pmezard/go-difflib"
packages = ["difflib"]
revision = "792786c7400a136282c1664665ae0a8db921c6c2"
version = "v1.0.0"
[[projects]]
name = "github.com/stretchr/testify"
packages = ["assert"]
revision = "f35b8ab0b5a2cef36673838d662e249dd9c94686"
version = "v1.2.2"
[[projects]]
name = "github.com/theckman/go-flock"
packages = ["."]
revision = "b139a2487364247d91814e4a7c7b8fdc69e342b2"
version = "v0.4.0"
[[projects]]
branch = "master"
name = "github.com/tidwall/gjson"
packages = ["."]
revision = "ba784d767ac7d937cf2439f237e50ec04a381c8b"
[[projects]]
branch = "master"
name = "github.com/tidwall/match"
packages = ["."]
revision = "1731857f09b1f38450e2c12409748407822dc6be"
[[projects]]
branch = "master"
name = "github.com/tmc/keyring"
packages = ["."]
revision = "839169085ae146fc7a34bcb34dfd7ab216d23991"
[[projects]]
branch = "master"
name = "golang.org/x/crypto"
packages = ["ssh/terminal"]
revision = "c126467f60eb25f8f27e5a981f32a87e3965053f"
[[projects]]
name = "golang.org/x/net"
packages = ["proxy"]
revision = "01c190206fbdffa42f334f4b2bf2220f50e64920"
[[projects]]
branch = "master"
name = "golang.org/x/sys"
packages = [
"unix",
"windows"
]
revision = "bd9dbc187b6e1dacfdd2722a87e83093c2d7bd6e"
[[projects]]
name = "gopkg.in/AlecAivazis/survey.v1"
packages = [
".",
"core",
"terminal"
]
revision = "17861e192dc11fd2f5081df1932c94cce262fa1e"
version = "v1.6.1"
[[projects]]
name = "gopkg.in/alecthomas/kingpin.v2"
packages = ["."]
revision = "947dcec5ba9c011838740e680966fd7087a71d0d"
version = "v2.2.6"
[[projects]]
branch = "v2"
name = "gopkg.in/coryb/yaml.v2"
packages = ["."]
revision = "0e40e46f7153ceb79ebbfdd075233d57f9611bd1"
[[projects]]
name = "gopkg.in/op/go-logging.v1"
packages = ["."]
revision = "b2cb9fa56473e98db8caba80237377e83fe44db5"
version = "v1"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "e087b3c5e03a82796f3bbc9d67c366dd794718c12f9ef9252e6172a6344c4fd7"
solver-name = "gps-cdcl"
solver-version = 1
-90
View File
@@ -1,90 +0,0 @@
# Gopkg.toml example
#
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
# for detailed Gopkg.toml documentation.
#
# required = ["github.com/user/thing/cmd/thing"]
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
#
# [[constraint]]
# name = "github.com/user/project"
# version = "1.0.0"
#
# [[constraint]]
# name = "github.com/user/project2"
# branch = "dev"
# source = "github.com/myfork/project2"
#
# [[override]]
# name = "github.com/x/y"
# version = "2.4.0"
[prune]
go-tests = true
unused-packages = true
non-go = true
[[constraint]]
name = "github.com/coryb/figtree"
branch = "master"
[[constraint]]
name = "github.com/coryb/kingpeon"
branch = "master"
[[constraint]]
name = "github.com/coryb/oreo"
branch = "master"
[[constraint]]
name = "github.com/jinzhu/copier"
branch = "master"
[[constraint]]
name = "github.com/kballard/go-shellquote"
branch = "master"
[[constraint]]
name = "github.com/mgutz/ansi"
branch = "master"
[[constraint]]
name = "github.com/pkg/browser"
branch = "master"
[[constraint]]
name = "github.com/pkg/errors"
version = "0.8.0"
[[constraint]]
name = "github.com/tmc/keyring"
branch = "master"
[[constraint]]
name = "golang.org/x/crypto"
branch = "master"
[[constraint]]
name = "gopkg.in/AlecAivazis/survey.v1"
version = "1.3.1"
[[constraint]]
name = "gopkg.in/alecthomas/kingpin.v2"
version = "2.2.5"
[[constraint]]
name = "gopkg.in/coryb/yaml.v2"
branch = "v2"
[[constraint]]
name = "gopkg.in/op/go-logging.v1"
version = "1.0.0"
[[constraint]]
branch = "master"
name = "github.com/tidwall/gjson"
[[constraint]]
name = "golang.org/x/net"
revision = "01c190206fbdffa42f334f4b2bf2220f50e64920"
+12 -4
View File
@@ -80,12 +80,20 @@ release:
version:
@echo $(CURVER)
clean:
clean: clean-password-store
rm -rf ./$(NAME)
prove:
chmod -R g-rwx,o-rwx $(CWD)/t/.gnupg
OSHT_VERBOSE=1 prove -v
clean-password-store:
rm -f "$(CWD)/_t/.password-store/GoJira/api-token:gojira@corybennett.org.gpg"
rm -f "$(CWD)/_t/.password-store/GoJira/api-token:mothra@corybennett.org.gpg"
test-password-store:
ln -s "$(CWD)/_t/.password-store/GoJira/api-token__gojira@corybennett.org.gpg" "$(CWD)/_t/.password-store/GoJira/api-token:gojira@corybennett.org.gpg"
ln -s "$(CWD)/_t/.password-store/GoJira/api-token__mothra@corybennett.org.gpg" "$(CWD)/_t/.password-store/GoJira/api-token:mothra@corybennett.org.gpg"
prove: test-password-store
chmod -R g-rwx,o-rwx $(CWD)/_t/.gnupg
OSHT_VERBOSE=1 prove -v _t/*.t
generate:
cd schemas && ./fetch-schemas.py
+28 -197
View File
@@ -1,72 +1,33 @@
[![Join the chat at https://gitter.im/go-jira-cli/help](https://badges.gitter.im/go-jira-cli/help.svg)](https://gitter.im/go-jira-cli/help?utm_source=badge&utm_medium=badge&utm_content=badge)
[![Build Status](https://travis-ci.org/Netflix-Skunkworks/go-jira.svg?branch=master)](https://travis-ci.org/Netflix-Skunkworks/go-jira)
[![GoDoc](https://godoc.org/gopkg.in/Netflix-Skunkworks/go-jira.v1?status.svg)](https://godoc.org/gopkg.in/Netflix-Skunkworks/go-jira.v1)
[![Build Status](https://travis-ci.org/go-jira/jira/go-jira.svg?branch=master)](https://travis-ci.org/go-jira/jira)
[![GoDoc](https://godoc.org/github.com/go-jira/jira?status.svg)](https://godoc.org/github.com/go-jira/jira)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
### Table of Contents
* [Summary](#go-jira)
* [Install](#install)
* [Download](#download)
* [Build](#build)
* [Usage](#usage)
* [TAB completion](#setting-up-tab-completion)
* [v1 vs v0 changes](#v1-vs-v0-changes)
* [<strong>Golang library import</strong>](#golang-library-import)
* [<strong>Configs per command</strong>](#configs-per-command)
* [<strong>Custom Commands</strong>](#custom-commands)
* [<strong>Incompatible command changes</strong>](#incompatible-command-changes)
* [<strong>Login process change</strong>](#login-process-change)
* [Configuration](#configuration)
* [Dynamic Configuration](#dynamic-configuration)
* [Custom Commands](#custom-commands-1)
* [Commands](#commands)
* [Options](#options)
* [Arguments](#arguments)
* [Script Template](#script-template)
* [Examples](#examples)
* [Editing](#editing)
* [Templates](#templates)
* [Writing/Editing Templates](#writingediting-templates)
* [Authentication](#authentication)
* [user vs login](#user-vs-login)
* [keyring password source](#keyring-password-source)
* [pass password source](#pass-password-source)
# go-jira
simple command line client for Atlassian's Jira service written in Go
Simple command line client for Atlassian's Jira service written in Go.
## Install
### Download
You can download one of the pre-built binaries for **go-jira** [here](https://github.com/Netflix-Skunkworks/go-jira/releases).
You can download one of the pre-built binaries for **go-jira** [here](https://github.com/go-jira/jira/releases).
### Build
You can build and install the official repository with [Go](https://golang.org/dl/):
```
go get gopkg.in/Netflix-Skunkworks/go-jira.v1/cmd/jira
```
This will checkout this repository into `$GOPATH/src/gopkg.in/Netflix-Skunkworks/go-jira.v1`, build, and install it.
go get github.com/go-jira/jira/cmd/jira
Because golang likes fully qualified import paths, forking and contributing can be a bit tricky.
This will checkout this repository into `$GOPATH/src/github.com/go-jira/jira/`, build, and install it.
If you want to tinker or hack on go-jira, the [easiest way to do so](http://code.openark.org/blog/development/forking-golang-repositories-on-github-and-managing-the-import-path) is to fork the repository and clone directly into the official path like this:
`git clone https://github.com/YOUR_USER_NAME_HERE/go-jira $GOPATH/src/gopkg.in/Netflix-Skunkworks/go-jira.v1`
From within that source dir you can build and install modifications from within that directory like:
`go install ./...`
It should then be available in $GOPATH/bin/jira
## Usage
#### Setting up TAB completion
Since go-jira is build with the "kingpin" golang command line library we supports bash/zsh shell completion automatically:
Since go-jira is built with the "kingpin" golang command line library we support bash/zsh shell completion automatically:
* <https://github.com/alecthomas/kingpin/tree/v2.2.5#bashzsh-shell-completion>
@@ -76,153 +37,6 @@ For example, in bash, adding something along the lines of:
to your bashrc, or .profile (assuming go-jira binary is already in your path) will cause jira to offer tab completion behavior.
```
usage: jira [<flags>] <command> [<args> ...]
Jira Command Line Interface
Global flags:
--help Show context-sensitive help (also try --help-long and --help-man).
-v, --verbose ... Increase verbosity for debugging
-e, --endpoint=ENDPOINT Base URI to use for Jira
-k, --insecure Disable TLS certificate verification
-Q, --quiet Suppress output to console
--unixproxy=UNIXPROXY Path for a unix-socket proxy
--socksproxy=SOCKSPROXY Address for a socks proxy
-u, --user=USER user name used within the Jira service
--login=LOGIN login name that corresponds to the user used for authentication
Commands:
help: Show help.
version: Prints version
acknowledge: Transition issue to acknowledge state
assign: Assign user to issue
attach create: Attach file to issue
attach get: Fetch attachment
attach list: Prints attachment details for issue
attach remove: Delete attachment
backlog: Transition issue to Backlog state
block: Mark issues as blocker
browse: Open issue in browser
close: Transition issue to close state
comment: Add comment to issue
component add: Add component
components: Show components for a project
create: Create issue
createmeta: View 'create' metadata
done: Transition issue to Done state
dup: Mark issues as duplicate
edit: Edit issue details
editmeta: View 'edit' metadata
epic add: Add issues to Epic
epic create: Create Epic
epic list: Prints list of issues for an epic with optional search criteria
epic remove: Remove issues from Epic
export-templates: Export templates for customizations
fields: Prints all fields, both System and Custom
in-progress: Transition issue to Progress state
issuelink: Link two issues
issuelinktypes: Show the issue link types
issuetypes: Show issue types for a project
labels add: Add labels to an issue
labels remove: Remove labels from an issue
labels set: Set labels on an issue
list: Prints list of issues for given search criteria
login: Attempt to login into jira server
logout: Deactivate session with Jira server
rank: Mark issues as blocker
reopen: Transition issue to reopen state
request: Open issue in requestr
resolve: Transition issue to resolve state
start: Transition issue to start state
stop: Transition issue to stop state
subtask: Subtask issue
take: Assign issue to yourself
todo: Transition issue to To Do state
transition: Transition issue to given state
transitions: List valid issue transitions
transmeta: List valid issue transitions
unassign: Unassign an issue
unexport-templates: Remove unmodified exported templates
view: Prints issue details
vote: Vote up/down an issue
watch: Add/Remove watcher to issue
worklog add: Add a worklog to an issue
worklog list: Prints the worklog data for given issue
session: Attempt to login into jira server
```
## v1 vs v0 changes
###### **Golang library import**
For the new version of go-jira you should use:
```
import "gopkg.in/Netflix-Skunkworks/go-jira.v1"
```
If you have code that depends on the old apis, you can still use them with this import:
```
import "gopkg.in/Netflix-Skunkworks/go-jira.v0"
```
###### **Configs per command**
Instead of requiring a executable template to get configs for a given command now you can create a config to be applied to a command. So if you want to use `template: table` by default for your `jira list` you can now do:
```
$ cat $HOME/.jira.d/list.yml
template: table
```
Where previously you needed something like:
```
# cat $HOME/.jira.d/config.yml
#!/bin/sh
case $JIRA_OPERATION in
list)
echo "template: table";;
esac
```
###### **Custom Commands**
Now you can create your own custom commands to do common operations with jira. Please see the details **Custom Commands** section below for more details. If you want to create a command `jira mine` that lists all the issues assigned to you now you can modify your `.jira.d/config.yml` file to add a `custom-commands` section like this:
```yaml
custom-commands:
- name: mine
help: display issues assigned to me
script: |-
{{jira}} list --query "resolution = unresolved and assignee=currentuser() ORDER BY created"
```
Then the next time you run `jira help` you will see your usage:
```
$ jira mine --help
usage: jira mine
display issues assigned to me
Flags:
--help Show context-sensitive help (also try --help-long and --help-man).
-v, --verbose ... Increase verbosity for debugging
-e, --endpoint=ENDPOINT Base URI to use for Jira
-u, --user=USER Login name used for authentication with Jira service
--unixproxy=UNIXPROXY Path for a unix-socket proxy
-k, --insecure Disable TLS certificate verification
```
###### **Incompatible command changes**
Unfortunately during the rewrite between v0 and v1 there were some necessary changes that broke backwards compatibility with existing commands. Specifically the `dups`, `blocks`, `add worklog` and `add|remove|set labels` commands have had the command word swapped around:
* `jira DUPLICATE dups ISSUE` => `jira dup DUPLICATE ISSUE`
* `jira BLOCKER blocks ISSUE` => `jira block BLOCKER ISSUE`
* `jira add worklog` => `jira worklog add`
* `jira add labels` => `jira labels add`
* `jira remove labels` => `jira labels remove`
* `jira set labels` => `jira labels set`
###### **Login process change**
We have, once again, changed how login happens for Jira. When authenticating against Atlassian Cloud Jira [API Tokens are now required](https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-basic-auth-and-cookie-based-auth/). Please read [the Authentication section](#authentication) below for more information.
If you use a privately hosted Jira service, you can chose to use the API Token method or continue using the session login api. Please read [the Authentication section](#authentication) below for more information.
Previously `jira` used attempt to get a `JSESSION` cookies by authenticating with the webservice standard GUI login process. This has been especially problematic as users need to authenticate with various credential providers (google auth, etc). We now attempt to authenticate via the [session login api](https://docs.atlassian.com/jira/REST/cloud/#auth/1/session-login). This may be problematic for users if admins have locked down the session-login api, so we might have to bring back the error-prone Basic-Auth approach. For users that are unable to authenticate via `jira` hopefully someone in your organization can provide me with details on a process for you to authenticate and we can try to update `jira`.
## 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 **&lt;command&gt;.yml** file (ie for `jira list` it will load `.jira.d/list.yml`) then it will merge in any properties from the **config.yml** if found. The configuration properties found in a file closest to your current working directory will have precedence. Properties overridden with command line options will have final precedence.
@@ -446,7 +260,7 @@ hard-coded templates with `jira export-templates` which will write them to **~/.
#### 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](https://golang.org/pkg/text/template/), and there is a good primer document [here](https://gohugo.io/templates/go-templates/). `go-jira` also provides a few extra helper functions to make it a bit easier to format the data, those functions are defined [here](https://github.com/Netflix-Skunkworks/go-jira/blob/master/jiracli/templates.go#L64).
First the basic templating functionality is defined by the Go language 'text/template' library. The library reference documentation can be found [here](https://golang.org/pkg/text/template/), and there is a good primer document [here](https://gohugo.io/templates/go-templates/). `go-jira` also provides a few extra helper functions to make it a bit easier to format the data, those functions are defined [here](https://github.com/go-jira/jira/blob/master/jiracli/templates.go#L64).
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 example to find out what is available to the "view" templates, you can use:
```
@@ -462,6 +276,8 @@ jira list -t debug
For Atlassian Cloud hosted Jira [API Tokens are now required](https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-basic-auth-and-cookie-based-auth/). You will automatically be prompted for an API Token if your jira endpoint ends in `.atlassian.net`. If you are using a private Jira service, you can force `jira` to use an api-token by setting the `authentication-method: api-token` property in your `$HOME/.jira.d/config.yml` file. The API Token needs to be presented to the Jira service on every request, so it is recommended to store this API Token security within your OS's keyring, or using the `pass` service as documented below so that it can be programmatically accessed via `jira` and not prompt you every time. For a less-secure option you can also provide the API token via a `JIRA_API_TOKEN` environment variable. If you are unable to use an api-token for an Atlassian Cloud hosted Jira then you can still force `jira` to use the old session based authentication (until it the hosted system stops accepting it) by setting `authentication-method: session`.
The API Token authentication requires both the token and the email of the user. The email mut be set in the `user:` in your config.yml. Failure to provide the `user` will result in a 401 error.
If your Jira service still allows you to use the Session based authentication method then `jira` will prompt for a password automatically when get a response header from the Jira service that indicates you do not have an active session (ie the `X-Ausername` header is set to `anonymous`). Then after authentication we cache the `cloud.session.token` cookie returned by the service [session login api](https://docs.atlassian.com/jira/REST/cloud/#auth/1/session-login) and reuse that on subsequent requests. Typically this cookie will be valid for several hours (depending on the service configuration). To automatically securely store your password for easy reuse by jira You can enable a `password-source` via `.jira.d/config.yml` with possible values of `keyring` or `pass`.
#### User vs Login
@@ -473,7 +289,7 @@ login: person@example.com
You can also override these values on the command line with `jira --user person --login person@example.com`. The `login` value will be used only for authentication purposes, the `user` value will be used when a user name is required for any Jira service API calls.
#### keyring password source
#### `keyring` password source
On OSX and Linux there are a few keyring providers that `go-jira` can use (via this [golang module](https://github.com/tmc/keyring)). To integrate `go-jira` with a supported keyring just add this configuration to `$HOME/.jira.d/config.yml`:
```yaml
password-source: keyring
@@ -484,6 +300,7 @@ After setting this and issuing a `jira login`, your credentials will be stored i
An alternative to the keyring password source is the `pass` tool (documentation [here](https://www.passwordstore.org/)). 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`:
```yaml
password-source: pass
password-name: jira.example.com/myuser
```
This assumes you have already setup `pass` correctly on your system. Specifically you will need to have created a gpg key like this:
@@ -507,6 +324,12 @@ Then initialize the `pass` tool to use the correct key:
$ pass init "Go Jira <gojira@example.com>"
```
Now insert your password with the name you configured.
```
$ pass insert jira.example.com/myuser
```
You probably want to setup gpg-agent so that you don't 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`
```bash
if [ -f $HOME/.gpg-agent-info ]; then
@@ -532,3 +355,11 @@ if [ -n "${GPG_AGENT_INFO}" ]; then
fi
export GPG_TTY=$(tty)
```
#### `stdin` password source
When `password-source` is set to `stdin`, the `jira login` command will read from stdin until EOF, and the bytes read will be the used as the password. This is useful if you have some other programmatic method for fetching passwords. For example, if `password-generator` creates a one-time password and prints it to stdout, you could use it like this.
```bash
$ ./password-generator | jira login --endpoint=https://my.jira.endpoint.com --user=USERNAME
```
View File
View File
View File
+13 -1
View File
@@ -4,7 +4,7 @@ cd $(dirname $0)
jira="../jira"
. env.sh
PLAN 94
PLAN 98
# reset login
RUNS $jira logout
@@ -567,3 +567,15 @@ labels: better-label, more-label
description: |
blocks
EOF
###############################################################################
## List 102 closed issues, should be more than 100 (max page size), verify pagination
###############################################################################
RUNS $jira ls -q "project = 'BASIC' AND status = 'Done'" --limit 102
IS $(wc -l <$OSHT_STDOUT) -eq 102
###############################################################################
## List 1 issue, verify we dont get full page
###############################################################################
RUNS $jira ls -q "project = 'BASIC' AND status = 'Done'" --limit 1
IS $(wc -l <$OSHT_STDOUT) -eq 1
+1 -1
View File
@@ -62,7 +62,7 @@ DIFF <<EOF
+------------+------------------------------+------------+--------------+--------------+
| id | filename | bytes | user | created |
+------------+------------------------------+------------+--------------+--------------+
| $(printf %10s $attach1) | README.md | 1238 | gojira | a minute |
| $(printf %10s $attach1) | README.md | 1239 | gojira | a minute |
| $(printf %10s $attach2) | garbage.bin | 1048576 | gojira | a minute |
| $(printf %10s $attach3) | foobar.bin | 1048576 | gojira | a minute |
+------------+------------------------------+------------+--------------+--------------+
View File
View File
View File
View File
View File
View File
+1 -1
View File
@@ -9,7 +9,7 @@ From the top level of the project you can run:
# this creates a local "jira" binary
make
# this runs the integration tests in the "t" directory
# this runs the integration tests in the "_t" directory
prove
```
View File
+4 -2
View File
@@ -1,7 +1,9 @@
package jira
import (
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata"
"encoding/json"
"github.com/go-jira/jira/jiradata"
)
// https://docs.atlassian.com/jira/REST/cloud/#api/2/attachment-getAttachment
@@ -19,7 +21,7 @@ func GetAttachment(ua HttpClient, endpoint string, id string) (*jiradata.Attachm
if resp.StatusCode == 200 {
results := &jiradata.Attachment{}
return results, readJSON(resp.Body, results)
return results, json.NewDecoder(resp.Body).Decode(results)
}
return nil, responseError(resp)
}
+2 -2
View File
@@ -7,8 +7,8 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracmd"
"github.com/go-jira/jira/jiracli"
"github.com/go-jira/jira/jiracmd"
"gopkg.in/op/go-logging.v1"
)
+2 -2
View File
@@ -4,7 +4,7 @@ import (
"bytes"
"encoding/json"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata"
"github.com/go-jira/jira/jiradata"
)
type ComponentProvider interface {
@@ -31,7 +31,7 @@ func CreateComponent(ua HttpClient, endpoint string, cp ComponentProvider) (*jir
if resp.StatusCode == 201 {
results := &jiradata.Component{}
return results, readJSON(resp.Body, results)
return results, json.NewDecoder(resp.Body).Decode(results)
}
return nil, responseError(resp)
}
+2 -2
View File
@@ -9,7 +9,7 @@ import (
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata"
"github.com/go-jira/jira/jiradata"
)
// https://docs.atlassian.com/jira-software/REST/latest/#agile/1.0/epic-getIssuesForEpic
@@ -53,7 +53,7 @@ func EpicSearch(ua HttpClient, endpoint string, epic string, sp SearchProvider)
if resp.StatusCode == 200 {
results := &jiradata.SearchResults{}
return results, readJSON(resp.Body, results)
return results, json.NewDecoder(resp.Body).Decode(results)
}
return nil, responseError(resp)
}
+3 -2
View File
@@ -1,14 +1,15 @@
package jira
import (
"encoding/json"
"net/http"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata"
"github.com/go-jira/jira/jiradata"
)
func responseError(resp *http.Response) error {
results := &jiradata.ErrorCollection{}
if err := readJSON(resp.Body, results); err != nil {
if err := json.NewDecoder(resp.Body).Decode(results); err != nil {
results.Status = resp.StatusCode
results.ErrorMessages = append(results.ErrorMessages, err.Error())
}
+4 -2
View File
@@ -1,7 +1,9 @@
package jira
import (
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata"
"encoding/json"
"github.com/go-jira/jira/jiradata"
)
// https://docs.atlassian.com/jira/REST/cloud/#api/2/field-getFields
@@ -18,7 +20,7 @@ func GetFields(ua HttpClient, endpoint string) ([]jiradata.Field, error) {
defer resp.Body.Close()
if resp.StatusCode == 200 {
results := []jiradata.Field{}
return results, readJSON(resp.Body, &results)
return results, json.NewDecoder(resp.Body).Decode(&results)
}
return nil, responseError(resp)
}
+41
View File
@@ -0,0 +1,41 @@
module github.com/go-jira/jira
go 1.12
require (
github.com/Netflix/go-expect v0.0.0-20180928190340-9d1f4485533b // indirect
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc // indirect
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf // indirect
github.com/cheekybits/genny v1.0.0 // indirect
github.com/coryb/figtree v0.0.0-20180728224503-071d1ef303df
github.com/coryb/kingpeon v0.0.0-20180107011214-9a669f143f2e
github.com/coryb/oreo v0.0.0-20180804211640-3e1b88fc08f1
github.com/davecgh/go-spew v1.1.0 // indirect
github.com/fatih/camelcase v1.0.0 // indirect
github.com/guelfey/go.dbus v0.0.0-20131113121618-f6a3a2366cc3 // indirect
github.com/hinshun/vt10x v0.0.0-20180809195222-d55458df857c // indirect
github.com/jinzhu/copier v0.0.0-20180308034124-7e38e58719c3
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
github.com/kr/pretty v0.1.0 // indirect
github.com/kr/pty v1.1.4 // indirect
github.com/mattn/go-colorable v0.0.9 // indirect
github.com/mattn/go-isatty v0.0.3 // indirect
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b
github.com/pkg/browser v0.0.0-20170505125900-c90ca0c84f15
github.com/pkg/errors v0.8.0
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/testify v1.2.2
github.com/theckman/go-flock v0.4.0 // indirect
github.com/tidwall/gjson v0.0.0-20180711011033-ba784d767ac7
github.com/tidwall/match v1.0.0 // indirect
github.com/tmc/keyring v0.0.0-20171121202319-839169085ae1
golang.org/x/crypto v0.0.0-20180723164146-c126467f60eb
golang.org/x/net v0.0.0-20171102191033-01c190206fbd
golang.org/x/sys v0.0.0-20180727230415-bd9dbc187b6e // indirect
gopkg.in/AlecAivazis/survey.v1 v1.6.1
gopkg.in/alecthomas/kingpin.v2 v2.2.6
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
gopkg.in/coryb/yaml.v2 v2.0.0-20180616071044-0e40e46f7153
gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473
gopkg.in/yaml.v2 v2.2.2 // indirect
)
+74
View File
@@ -0,0 +1,74 @@
github.com/Netflix/go-expect v0.0.0-20180928190340-9d1f4485533b h1:sSQK05nvxs4UkgCJaxihteu+r+6ela3dNMm7NVmsS3c=
github.com/Netflix/go-expect v0.0.0-20180928190340-9d1f4485533b/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE=
github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ=
github.com/coryb/figtree v0.0.0-20180728224503-071d1ef303df h1:cS4Z9Nlv8J4UqFbLp9ltZypgenm2p3Jeg0yqLfpH2pc=
github.com/coryb/figtree v0.0.0-20180728224503-071d1ef303df/go.mod h1:uAkZUEGm6dROpxfy+8vXLs7JrLCI4O+gQyKAuISxI/g=
github.com/coryb/kingpeon v0.0.0-20180107011214-9a669f143f2e h1:tGmk9Tuyz7fKuBq/d3nFJvVWRvc48MEBKQC4uYV3wb0=
github.com/coryb/kingpeon v0.0.0-20180107011214-9a669f143f2e/go.mod h1:gBc0uEH6swbOMoR7VkVuW7w5fGvZu/KHeSgxBR4Ta7Q=
github.com/coryb/oreo v0.0.0-20180804211640-3e1b88fc08f1 h1:Hh0qSvmvoAGL8VxvEoUv9UuUf9XlKcQtSxAMTz1kqfE=
github.com/coryb/oreo v0.0.0-20180804211640-3e1b88fc08f1/go.mod h1:l/wuS2rM8ostk0aApWje8tsZNWJPOc2TVr85B0n3e6M=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8=
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
github.com/guelfey/go.dbus v0.0.0-20131113121618-f6a3a2366cc3 h1:fngCxKbvZdctIsWj2hYijhAt4iK0JXSSA78B36xP0yI=
github.com/guelfey/go.dbus v0.0.0-20131113121618-f6a3a2366cc3/go.mod h1:0CNX5Cvi77WEH8llpfZ/ieuqyceb1cnO5//b5zzsnF8=
github.com/hinshun/vt10x v0.0.0-20180809195222-d55458df857c h1:kp3AxgXgDOmIJFR7bIwqFhwJ2qWar8tEQSE5XXhCfVk=
github.com/hinshun/vt10x v0.0.0-20180809195222-d55458df857c/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A=
github.com/jinzhu/copier v0.0.0-20180308034124-7e38e58719c3 h1:sHsPfNMAG70QAvKbddQ0uScZCHQoZsT5NykGRCeeeIs=
github.com/jinzhu/copier v0.0.0-20180308034124-7e38e58719c3/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.4 h1:5Myjjh3JY/NaAi4IsUbHADytDyl1VE1Y9PXDlL+P/VQ=
github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.3 h1:ns/ykhmWi7G9O+8a448SecJU3nSMBXJfqQkl0upE1jI=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/pkg/browser v0.0.0-20170505125900-c90ca0c84f15 h1:mrI+6Ae64Wjt+uahGe5we/sPS1sXjvfT3YjtawAVgps=
github.com/pkg/browser v0.0.0-20170505125900-c90ca0c84f15/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/theckman/go-flock v0.4.0 h1:bcqNkS4RTQBGWybG7IBimUMxnLz53Qes1+D4QaOhzJc=
github.com/theckman/go-flock v0.4.0/go.mod h1:kjuth3y9VJ2aNlkNEO99G/8lp9fMIKaGyBmh84IBheM=
github.com/tidwall/gjson v0.0.0-20180711011033-ba784d767ac7 h1:PW7TzL8BOpYMcUYSv4qWDoH1Y5iRzVABteynvfF7pwE=
github.com/tidwall/gjson v0.0.0-20180711011033-ba784d767ac7/go.mod h1:c/nTNbUr0E0OrXEhq1pwa8iEgc2DOt4ZZqAt1HtCkPA=
github.com/tidwall/match v1.0.0 h1:Ym1EcFkp+UQ4ptxfWlW+iMdq5cPH5nEuGzdf/Pb7VmI=
github.com/tidwall/match v1.0.0/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
github.com/tmc/keyring v0.0.0-20171121202319-839169085ae1 h1:+gXfyhy0t28Guz+vFztBg45yIquB2bNtiFvbItzJtUc=
github.com/tmc/keyring v0.0.0-20171121202319-839169085ae1/go.mod h1:gsa3jftQ3xia55nzIN4lXLYzDcWdxjojdKoz+N0St2Y=
golang.org/x/crypto v0.0.0-20180723164146-c126467f60eb h1:Ah9YqXLj6fEgeKqcmBuLCbAsrF3ScD7dJ/bYM0C6tXI=
golang.org/x/crypto v0.0.0-20180723164146-c126467f60eb/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/net v0.0.0-20171102191033-01c190206fbd h1:CLQSRrSDQMOMkogMxky7XOkERftMegAnxjT2re4E66M=
golang.org/x/net v0.0.0-20171102191033-01c190206fbd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/sys v0.0.0-20180727230415-bd9dbc187b6e h1:3dQ4fR8k5KugjVKO0oqSd1odxuk2yaE2CIfxWP2WarQ=
golang.org/x/sys v0.0.0-20180727230415-bd9dbc187b6e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
gopkg.in/AlecAivazis/survey.v1 v1.6.1 h1:HyWkjKGBpzhNxrpaKRLDqoa4L1f4cMVBNU4bnVmU8Mw=
gopkg.in/AlecAivazis/survey.v1 v1.6.1/go.mod h1:2Ehl7OqkBl3Xb8VmC4oFW2bItAhnUfzIjrOzwRxCrOU=
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/coryb/yaml.v2 v2.0.0-20180616071044-0e40e46f7153 h1:3KfEubBNUdXqlEXuMz13dXy4cYK2AvuPhp8fKTYuPdU=
gopkg.in/coryb/yaml.v2 v2.0.0-20180616071044-0e40e46f7153/go.mod h1:Vth2iKfSejHZ3p6akgWO0iSjuuiu6mNCEgzcYUCnumw=
gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 h1:6D+BvnJ/j6e222UW8s2qTSe3wGBtvo0MbVQG/c5k8RE=
gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473/go.mod h1:N1eN2tsCx0Ydtgjl4cqmbRCsY4/+z4cYDeqwZTk6zog=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+30 -29
View File
@@ -11,7 +11,7 @@ import (
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata"
"github.com/go-jira/jira/jiradata"
)
type IssueQueryProvider interface {
@@ -69,7 +69,7 @@ func GetIssue(ua HttpClient, endpoint string, issue string, iqg IssueQueryProvid
if resp.StatusCode == 200 {
results := &jiradata.Issue{}
return results, readJSON(resp.Body, results)
return results, json.NewDecoder(resp.Body).Decode(results)
}
return nil, responseError(resp)
}
@@ -95,15 +95,13 @@ func GetIssueWorklog(ua HttpClient, endpoint string, issue string) (*jiradata.Wo
if resp.StatusCode == 200 {
results := &jiradata.WorklogWithPagination{}
err := readJSON(resp.Body, results)
err := json.NewDecoder(resp.Body).Decode(results)
if err != nil {
return nil, err
}
startAt = startAt + maxResults
total = results.Total
for _, worklog := range results.Worklogs {
worklogs = append(worklogs, worklog)
}
worklogs = append(worklogs, results.Worklogs...)
} else {
return nil, responseError(resp)
}
@@ -135,7 +133,7 @@ func AddIssueWorklog(ua HttpClient, endpoint string, issue string, wp WorklogPro
if resp.StatusCode == 201 {
results := &jiradata.Worklog{}
return results, readJSON(resp.Body, results)
return results, json.NewDecoder(resp.Body).Decode(results)
}
return nil, responseError(resp)
}
@@ -155,7 +153,7 @@ func GetIssueEditMeta(ua HttpClient, endpoint string, issue string) (*jiradata.E
if resp.StatusCode == 200 {
results := &jiradata.EditMeta{}
return results, readJSON(resp.Body, results)
return results, json.NewDecoder(resp.Body).Decode(results)
}
return nil, responseError(resp)
}
@@ -208,7 +206,7 @@ func CreateIssue(ua HttpClient, endpoint string, iup IssueUpdateProvider) (*jira
if resp.StatusCode == 201 {
results := &jiradata.IssueCreateResponse{}
return results, readJSON(resp.Body, results)
return results, json.NewDecoder(resp.Body).Decode(results)
}
return nil, responseError(resp)
}
@@ -229,7 +227,7 @@ func GetIssueCreateMetaProject(ua HttpClient, endpoint string, projectKey string
if resp.StatusCode == 200 {
results := &jiradata.CreateMeta{}
err = readJSON(resp.Body, results)
err = json.NewDecoder(resp.Body).Decode(results)
if err != nil {
return nil, err
}
@@ -238,7 +236,7 @@ func GetIssueCreateMetaProject(ua HttpClient, endpoint string, projectKey string
return project, nil
}
}
return nil, fmt.Errorf("Project %s not found", projectKey)
return nil, fmt.Errorf("project %s not found", projectKey)
}
return nil, responseError(resp)
}
@@ -257,24 +255,24 @@ func GetIssueCreateMetaIssueType(ua HttpClient, endpoint string, projectKey, iss
}
defer resp.Body.Close()
if resp.StatusCode == 200 {
results := &jiradata.CreateMeta{}
err = readJSON(resp.Body, results)
if err != nil {
return nil, err
if resp.StatusCode != 200 {
return nil, responseError(resp)
}
results := &jiradata.CreateMeta{}
if err := json.NewDecoder(resp.Body).Decode(results); err != nil {
return nil, err
}
for _, project := range results.Projects {
if project.Key != projectKey {
continue
}
for _, project := range results.Projects {
if project.Key == projectKey {
for _, issueType := range project.IssueTypes {
if issueType.Name == issueTypeName {
return issueType, nil
}
}
for _, issueType := range project.IssueTypes {
if issueType.Name == issueTypeName {
return issueType, nil
}
}
return nil, fmt.Errorf("Project %s and IssueType %s not found", projectKey, issueTypeName)
}
return nil, responseError(resp)
return nil, fmt.Errorf("project %s and IssueType %s not found", projectKey, issueTypeName)
}
type LinkIssueProvider interface {
@@ -321,7 +319,7 @@ func GetIssueTransitions(ua HttpClient, endpoint string, issue string) (*jiradat
if resp.StatusCode == 200 {
results := &jiradata.TransitionsMeta{}
return results, readJSON(resp.Body, results)
return results, json.NewDecoder(resp.Body).Decode(results)
}
return nil, responseError(resp)
}
@@ -369,7 +367,7 @@ func GetIssueLinkTypes(ua HttpClient, endpoint string) (*jiradata.IssueLinkTypes
}{
IssueLinkTypes: jiradata.IssueLinkTypes{},
}
return &results.IssueLinkTypes, readJSON(resp.Body, &results)
return &results.IssueLinkTypes, json.NewDecoder(resp.Body).Decode(&results)
}
return nil, responseError(resp)
}
@@ -503,7 +501,7 @@ func IssueAddComment(ua HttpClient, endpoint string, issue string, cp CommentPro
if resp.StatusCode == 201 {
results := jiradata.Comment{}
return &results, readJSON(resp.Body, &results)
return &results, json.NewDecoder(resp.Body).Decode(&results)
}
return nil, responseError(resp)
}
@@ -563,6 +561,9 @@ func IssueAttachFile(ua HttpClient, endpoint string, issue, filename string, con
}
uri, err := url.Parse(URLJoin(endpoint, "rest/api/2/issue", issue, "attachments"))
if err != nil {
return nil, err
}
req := oreo.RequestBuilder(uri).WithMethod("POST").WithHeader(
"X-Atlassian-Token", "no-check",
).WithHeader(
@@ -578,7 +579,7 @@ func IssueAttachFile(ua HttpClient, endpoint string, issue, filename string, con
if resp.StatusCode == 200 {
results := jiradata.ListOfAttachment{}
return &results, readJSON(resp.Body, &results)
return &results, json.NewDecoder(resp.Body).Decode(&results)
}
return nil, responseError(resp)
}
+1 -4
View File
@@ -2,12 +2,9 @@ package jira
import (
"github.com/coryb/oreo"
logging "gopkg.in/op/go-logging.v1"
)
var log = logging.MustGetLogger("jira")
const VERSION = "1.0.19"
const VERSION = "1.0.20"
type Jira struct {
Endpoint string `json:"endpoint,omitempty" yaml:"endpoint,omitempty"`
+69 -68
View File
@@ -150,43 +150,39 @@ func register(app *kingpin.Application, o *oreo.Client, fig *figtree.FigTree) {
app.Flag("user", "user name used within the Jira service").Short('u').SetValue(&globals.User)
app.Flag("login", "login name that corresponds to the user used for authentication").SetValue(&globals.Login)
o = o.WithPreCallback(
func(req *http.Request) (*http.Request, error) {
if globals.AuthMethod() == "api-token" {
// need to set basic auth header with user@domain:api-token
token := globals.GetPass()
authHeader := fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", globals.Login.Value, token))))
req.Header.Add("Authorization", authHeader)
}
return req, nil
},
)
o = o.WithPreCallback(func(req *http.Request) (*http.Request, error) {
if globals.AuthMethod() == "api-token" {
// need to set basic auth header with user@domain:api-token
token := globals.GetPass()
authHeader := fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", globals.Login.Value, token))))
req.Header.Add("Authorization", authHeader)
}
return req, nil
})
o = o.WithPostCallback(
func(req *http.Request, resp *http.Response) (*http.Response, error) {
if globals.AuthMethod() == "session" {
authUser := resp.Header.Get("X-Ausername")
if authUser == "" || authUser == "anonymous" {
// preserve the --quiet value, we need to temporarily disable it so
// the normal login output is surpressed
defer func(quiet bool) {
globals.Quiet.Value = quiet
}(globals.Quiet.Value)
globals.Quiet.Value = true
o = o.WithPostCallback(func(req *http.Request, resp *http.Response) (*http.Response, error) {
if globals.AuthMethod() == "session" {
authUser := resp.Header.Get("X-Ausername")
if authUser == "" || authUser == "anonymous" {
// preserve the --quiet value, we need to temporarily disable it so
// the normal login output is surpressed
defer func(quiet bool) {
globals.Quiet.Value = quiet
}(globals.Quiet.Value)
globals.Quiet.Value = true
// we are not logged in, so force login now by running the "login" command
app.Parse([]string{"login"})
// we are not logged in, so force login now by running the "login" command
app.Parse([]string{"login"})
// rerun the original request
return o.Do(req)
}
} else if globals.AuthMethod() == "api-token" && resp.StatusCode == 401 {
globals.SetPass("")
// rerun the original request
return o.Do(req)
}
return resp, nil
},
)
} else if globals.AuthMethod() == "api-token" && resp.StatusCode == 401 {
globals.SetPass("")
return o.Do(req)
}
return resp, nil
})
for _, command := range globalCommandRegistry {
copy := command
@@ -238,14 +234,12 @@ func register(app *kingpin.Application, o *oreo.Client, fig *figtree.FigTree) {
copy.Entry.UsageFunc(fig, cmd)
}
cmd.Action(
func(_ *kingpin.ParseContext) error {
if logging.GetLevel("") > logging.DEBUG {
o = o.WithTrace(true)
}
return copy.Entry.ExecuteFunc(o, &globals)
},
)
cmd.Action(func(_ *kingpin.ParseContext) error {
if logging.GetLevel("") > logging.DEBUG {
o = o.WithTrace(true)
}
return copy.Entry.ExecuteFunc(o, &globals)
})
}
}
@@ -321,38 +315,45 @@ func (o *CommonOptions) editFile(fileName string) (changes bool, err error) {
}
// now we just need to diff the files to see if there are any changes
var oldHandle, newHandle *os.File
var oldStat, newStat os.FileInfo
if oldHandle, err = os.Open(tmpFileNameOrig); err == nil {
if newHandle, err = os.Open(fileName); err == nil {
if oldStat, err = oldHandle.Stat(); err == nil {
if newStat, err = newHandle.Stat(); err == nil {
// different sizes, so must have changes
if oldStat.Size() != newStat.Size() {
return true, err
}
oldBuf, newBuf := make([]byte, 1024), make([]byte, 1024)
var oldCount, newCount int
// loop though 1024 bytes at a time comparing the buffers for changes
for err != io.EOF {
oldCount, _ = oldHandle.Read(oldBuf)
newCount, err = newHandle.Read(newBuf)
if oldCount != newCount {
return true, nil
}
if bytes.Compare(oldBuf[:oldCount], newBuf[:newCount]) != 0 {
return true, nil
}
}
return false, nil
}
}
f1, err := os.Open(tmpFileNameOrig)
if err != nil {
return false, err
}
f2, err := os.Open(fileName)
if err != nil {
return false, err
}
stat1, err := f1.Stat()
if err != nil {
return false, err
}
stat2, err := f2.Stat()
if err != nil {
return false, err
}
// different sizes, so must have changes
if stat1.Size() != stat2.Size() {
return true, nil
}
p1, p2 := make([]byte, 1024), make([]byte, 1024)
var n1, n2 int
// loop though 1024 bytes at a time comparing the buffers for changes
for err != io.EOF {
n1, _ = f1.Read(p1)
n2, err = f2.Read(p2)
if n1 != n2 {
return true, nil
}
if !bytes.Equal(p1[:n1], p2[:n2]) {
return true, nil
}
}
return false, err
return false, nil
}
var EditLoopAbort = fmt.Errorf("Edit Loop aborted by request")
var EditLoopAbort = fmt.Errorf("edit Loop aborted by request")
func EditLoop(opts *CommonOptions, input interface{}, output interface{}, submit func() error) error {
tmpFile, err := tmpTemplate(opts.Template.Value, input)
+8 -1
View File
@@ -3,12 +3,13 @@ package jiracli
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"os/exec"
"strings"
"github.com/go-jira/jira/jiradata"
"gopkg.in/AlecAivazis/survey.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata"
)
func (o *GlobalOptions) ProvideAuthParams() *jiradata.AuthParams {
@@ -57,6 +58,12 @@ func (o *GlobalOptions) GetPass() string {
passwd = strings.TrimSpace(buf.String())
}
}
} else if o.PasswordSource.Value == "stdin" {
allBytes, err := ioutil.ReadAll(os.Stdin)
if err != nil {
panic(fmt.Sprintf("unable to read bytes from stdin: %s", err))
}
passwd = string(allBytes)
} else {
log.Warningf("Unknown password-source: %s", o.PasswordSource)
}
+4 -3
View File
@@ -44,7 +44,8 @@ func getTemplate(name string) (string, error) {
b, err := findTemplate(name)
if err != nil {
return "", err
} else if b != nil {
}
if b != nil {
return string(b), nil
}
if s, ok := AllTemplates[name]; ok {
@@ -119,7 +120,7 @@ func TemplateProcessor() *template.Template {
}
},
"indent": func(spaces int, content string) string {
indent := make([]rune, spaces+1, spaces+1)
indent := make([]rune, spaces+1)
indent[0] = '\n'
for i := 1; i < spaces+1; i++ {
indent[i] = ' '
@@ -546,7 +547,7 @@ transition:
const defaultWorklogTemplate = `{{/* worklog template */ -}}
# issue: {{ .issue }}
comment: |~
{{ or .comment "" }}
{{ or .comment "" | indent 2 }}
timeSpent: {{ or .timeSpent "" }}
started: {{ or .started "" }}
`
+7 -8
View File
@@ -11,7 +11,7 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/kingpeon"
"github.com/coryb/oreo"
jira "gopkg.in/Netflix-Skunkworks/go-jira.v1"
jira "github.com/go-jira/jira"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
@@ -187,13 +187,12 @@ func ParseCommandLine(app *kingpin.Application, args []string) {
if _, ok := err.(*Error); ok {
log.Errorf("%s", err)
panic(Exit{Code: 1})
} else {
ctx, _ := app.ParseContext(os.Args[1:])
if ctx != nil {
app.UsageForContext(ctx)
}
log.Errorf("Invalid Usage: %s", err)
panic(Exit{Code: 1})
}
ctx, _ := app.ParseContext(os.Args[1:])
if ctx != nil {
app.UsageForContext(ctx)
}
log.Errorf("Invalid Usage: %s", err)
panic(Exit{Code: 1})
}
}
+2 -3
View File
@@ -1,7 +1,6 @@
package jiracli
import (
"errors"
"fmt"
"io"
"io/ioutil"
@@ -31,7 +30,7 @@ func findClosestParentPath(fileName string) (string, error) {
if len(paths) > 0 {
return paths[len(paths)-1], nil
}
return "", errors.New(fmt.Sprintf("%s not found in parent directory hierarchy", fileName))
return "", fmt.Errorf("%s not found in parent directory hierarchy", fileName)
}
func tmpYml(tmpFilePrefix string) (*os.File, error) {
@@ -86,7 +85,7 @@ func fuzzyAge(start string) (string, error) {
if err != nil {
return "", err
}
delta := time.Now().Sub(t)
delta := time.Since(t)
if delta.Minutes() < 2 {
return "a minute", nil
} else if dm := delta.Minutes(); dm < 45 {
+71
View File
@@ -0,0 +1,71 @@
package jiracli
import (
"io/ioutil"
"os"
"path/filepath"
"testing"
)
func realPath(path string) string {
cpath, err := filepath.EvalSymlinks(path)
if err != nil {
log.Fatal(err)
}
return cpath
}
func comparePaths(p1 string, p2 string) bool {
if realPath(p1) == realPath(p2) {
return true
}
return false
}
func TestFindClosestParentPath(t *testing.T) {
dir, err := ioutil.TempDir("", "testFindParentPath")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(dir)
origDir, err := os.Getwd()
if err != nil {
log.Fatal(err)
}
defer os.Chdir(origDir)
t1 := filepath.Join(dir, "/.test1")
t2 := filepath.Join(t1, "/.test2")
t3 := filepath.Join(t2, "/.test1")
err = os.MkdirAll(t3, os.ModePerm)
if err != nil {
log.Fatal(err)
}
os.Chdir(t3)
path1, err := findClosestParentPath(".test1")
if err != nil {
t.Errorf("findClosestParentPath should not have errored: %s", err)
}
if ok := comparePaths(path1, t3); !ok {
t.Errorf("%s != %s", path1, t3)
}
path2, err := findClosestParentPath(".test2")
if err != nil {
t.Errorf("findClosestParentPath should not have errored: %s", err)
}
if ok := comparePaths(path2, t2); !ok {
t.Errorf("%s != %s", path2, t2)
}
path3, err := findClosestParentPath(".test3")
if err.Error() != ".test3 not found in parent directory hierarchy" {
t.Errorf("incorrect error from findClosestParentPath: %s", err)
}
if path3 != "" {
t.Errorf("path3 should be empty, but is not: %s", path3)
}
}
+2 -2
View File
@@ -5,8 +5,8 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
+2 -2
View File
@@ -9,8 +9,8 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
jira "gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
jira "github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
kingpin "gopkg.in/alecthomas/kingpin.v2"
yaml "gopkg.in/coryb/yaml.v2"
)
+2 -2
View File
@@ -7,8 +7,8 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
jira "gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
jira "github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
+3 -3
View File
@@ -5,9 +5,9 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata"
"github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
"github.com/go-jira/jira/jiradata"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
+2 -2
View File
@@ -5,8 +5,8 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
jira "gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
jira "github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
+3 -3
View File
@@ -6,9 +6,9 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata"
"github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
"github.com/go-jira/jira/jiradata"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
+2 -2
View File
@@ -3,9 +3,9 @@ package jiracmd
import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
jira "github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
"github.com/pkg/browser"
jira "gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
+3 -3
View File
@@ -6,9 +6,9 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata"
"github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
"github.com/go-jira/jira/jiradata"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
+4 -5
View File
@@ -6,9 +6,9 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata"
"github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
"github.com/go-jira/jira/jiradata"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
@@ -52,9 +52,8 @@ func CmdComponentAddUsage(cmd *kingpin.CmdClause, opts *ComponentAddOptions) err
func CmdComponentAdd(o *oreo.Client, globals *jiracli.GlobalOptions, opts *ComponentAddOptions) error {
var err error
component := &jiradata.Component{}
var resp *jiradata.Component
err = jiracli.EditLoop(&opts.CommonOptions, &opts.Component, component, func() error {
resp, err = jira.CreateComponent(o, globals.Endpoint.Value, component)
_, err = jira.CreateComponent(o, globals.Endpoint.Value, component)
return err
})
if err != nil {
+2 -2
View File
@@ -6,8 +6,8 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
+3 -3
View File
@@ -7,9 +7,9 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata"
"github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
"github.com/go-jira/jira/jiradata"
kingpin "gopkg.in/alecthomas/kingpin.v2"
yaml "gopkg.in/coryb/yaml.v2"
)
+2 -2
View File
@@ -3,8 +3,8 @@ package jiracmd
import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
+27 -26
View File
@@ -6,9 +6,9 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata"
"github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
"github.com/go-jira/jira/jiradata"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
@@ -60,7 +60,7 @@ func CmdDupUsage(cmd *kingpin.CmdClause, opts *DupOptions) error {
return nil
}
// CmdDups will update the given issue as being a duplicate by the given dup issue
// CmdDup will update the given issue as being a duplicate by the given dup issue
// and will attempt to resolve the dup issue
func CmdDup(o *oreo.Client, globals *jiracli.GlobalOptions, opts *DupOptions) error {
if err := jira.LinkIssues(o, globals.Endpoint.Value, &opts.LinkIssueRequest); err != nil {
@@ -76,30 +76,31 @@ func CmdDup(o *oreo.Client, globals *jiracli.GlobalOptions, opts *DupOptions) er
}
for _, trans := range []string{"close", "done", "cancel", "start", "stop"} {
transMeta := meta.Transitions.Find(trans)
if transMeta != nil {
issueUpdate := jiradata.IssueUpdate{
Transition: transMeta,
}
resolution := defaultResolution(transMeta)
if resolution != "" {
issueUpdate.Fields = map[string]interface{}{
"resolution": map[string]interface{}{
"name": resolution,
},
}
}
if err = jira.TransitionIssue(o, globals.Endpoint.Value, opts.InwardIssue.Key, &issueUpdate); err != nil {
return err
}
if trans != "start" {
break
}
// if we are here then we must be stopping, so need to reset the meta
meta, err = jira.GetIssueTransitions(o, globals.Endpoint.Value, opts.InwardIssue.Key)
if err != nil {
return err
if transMeta == nil {
continue
}
issueUpdate := jiradata.IssueUpdate{
Transition: transMeta,
}
resolution := defaultResolution(transMeta)
if resolution != "" {
issueUpdate.Fields = map[string]interface{}{
"resolution": map[string]interface{}{
"name": resolution,
},
}
}
if err = jira.TransitionIssue(o, globals.Endpoint.Value, opts.InwardIssue.Key, &issueUpdate); err != nil {
return err
}
if trans != "start" {
break
}
// if we are here then we must be stopping, so need to reset the meta
meta, err = jira.GetIssueTransitions(o, globals.Endpoint.Value, opts.InwardIssue.Key)
if err != nil {
return err
}
}
if !globals.Quiet.Value {
+16 -18
View File
@@ -5,10 +5,10 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
"github.com/go-jira/jira/jiradata"
"gopkg.in/AlecAivazis/survey.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
@@ -124,22 +124,20 @@ func CmdEdit(o *oreo.Client, globals *jiracli.GlobalOptions, opts *EditOptions)
err = jiracli.EditLoop(&opts.CommonOptions, &input, &issueUpdate, func() error {
return jira.EditIssue(o, globals.Endpoint.Value, issueData.Key, &issueUpdate)
})
if err == jiracli.EditLoopAbort {
if len(results.Issues) > i+1 {
var answer bool
survey.AskOne(
&survey.Confirm{
Message: fmt.Sprintf("Continue to edit next issue %s?", results.Issues[i+1].Key),
Default: true,
},
&answer,
nil,
)
if answer {
continue
}
panic(jiracli.Exit{1})
if err == jiracli.EditLoopAbort && len(results.Issues) > i+1 {
var answer bool
survey.AskOne(
&survey.Confirm{
Message: fmt.Sprintf("Continue to edit next issue %s?", results.Issues[i+1].Key),
Default: true,
},
&answer,
nil,
)
if answer {
continue
}
panic(jiracli.Exit{1})
}
if err != nil {
return err
+3 -3
View File
@@ -3,8 +3,8 @@ package jiracmd
import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
@@ -41,7 +41,7 @@ func CmdEditMetaUsage(cmd *kingpin.CmdClause, opts *EditMetaOptions) error {
return nil
}
// EditMeta will get issue edit metadata and send to "editmeta" template
// CmdEditMeta will get issue edit metadata and send to "editmeta" template
func CmdEditMeta(o *oreo.Client, globals *jiracli.GlobalOptions, opts *EditMetaOptions) error {
editMeta, err := jira.GetIssueEditMeta(o, globals.Endpoint.Value, opts.Issue)
if err != nil {
+3 -3
View File
@@ -6,9 +6,9 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata"
"github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
"github.com/go-jira/jira/jiradata"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
+1 -1
View File
@@ -4,7 +4,7 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"github.com/go-jira/jira/jiracli"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
+2 -2
View File
@@ -3,8 +3,8 @@ package jiracmd
import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
+3 -3
View File
@@ -6,9 +6,9 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata"
"github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
"github.com/go-jira/jira/jiradata"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
+1 -1
View File
@@ -7,7 +7,7 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"github.com/go-jira/jira/jiracli"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
+2 -2
View File
@@ -3,8 +3,8 @@ package jiracmd
import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
+4 -4
View File
@@ -6,9 +6,9 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata"
"github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
"github.com/go-jira/jira/jiradata"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
@@ -54,7 +54,7 @@ func CmdIssueLinkUsage(cmd *kingpin.CmdClause, opts *IssueLinkOptions) error {
return nil
}
// CmdBlock will update the given issue as being a duplicate by the given dup issue
// CmdIssueLink will update the given issue as being a duplicate by the given dup issue
// and will attempt to resolve the dup issue
func CmdIssueLink(o *oreo.Client, globals *jiracli.GlobalOptions, opts *IssueLinkOptions) error {
if err := jira.LinkIssues(o, globals.Endpoint.Value, &opts.LinkIssueRequest); err != nil {
+2 -2
View File
@@ -3,8 +3,8 @@ package jiracmd
import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
+2 -2
View File
@@ -6,8 +6,8 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
+4 -4
View File
@@ -6,9 +6,9 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata"
"github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
"github.com/go-jira/jira/jiradata"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
@@ -39,7 +39,7 @@ func CmdLabelsAddUsage(cmd *kingpin.CmdClause, opts *LabelsAddOptions) error {
return nil
}
// CmdLabels will add labels on a given issue
// CmdLabelsAdd will add labels on a given issue
func CmdLabelsAdd(o *oreo.Client, globals *jiracli.GlobalOptions, opts *LabelsAddOptions) error {
ops := jiradata.FieldOperations{}
for _, label := range opts.Labels {
+4 -4
View File
@@ -6,9 +6,9 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata"
"github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
"github.com/go-jira/jira/jiradata"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
@@ -39,7 +39,7 @@ func CmdLabelsRemoveUsage(cmd *kingpin.CmdClause, opts *LabelsRemoveOptions) err
return nil
}
// CmdLabels will remove labels on a given issue
// CmdLabelsRemove will remove labels on a given issue
func CmdLabelsRemove(o *oreo.Client, globals *jiracli.GlobalOptions, opts *LabelsRemoveOptions) error {
ops := jiradata.FieldOperations{}
for _, label := range opts.Labels {
+4 -4
View File
@@ -6,9 +6,9 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata"
"github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
"github.com/go-jira/jira/jiradata"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
@@ -39,7 +39,7 @@ func CmdLabelsSetUsage(cmd *kingpin.CmdClause, opts *LabelsSetOptions) error {
return nil
}
// CmdLabels will set labels on a given issue
// CmdLabelsSet will set labels on a given issue
func CmdLabelsSet(o *oreo.Client, globals *jiracli.GlobalOptions, opts *LabelsSetOptions) error {
issueUpdate := jiradata.IssueUpdate{
Update: jiradata.FieldOperationsMap{
+3 -6
View File
@@ -5,8 +5,8 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
@@ -30,9 +30,6 @@ func CmdListRegistry() *jiracli.CommandRegistryEntry {
return CmdListUsage(cmd, &opts, fig)
},
func(o *oreo.Client, globals *jiracli.GlobalOptions) error {
if opts.MaxResults == 0 {
opts.MaxResults = 500
}
if opts.QueryFields == "" {
opts.QueryFields = "assignee,created,priority,reporter,status,summary,updated,issuetype"
}
@@ -72,7 +69,7 @@ func CmdListUsage(cmd *kingpin.CmdClause, opts *ListOptions, fig *figtree.FigTre
// List will query jira and send data to "list" template
func CmdList(o *oreo.Client, globals *jiracli.GlobalOptions, opts *ListOptions) error {
data, err := jira.Search(o, globals.Endpoint.Value, opts)
data, err := jira.Search(o, globals.Endpoint.Value, opts, jira.WithAutoPagination())
if err != nil {
return err
}
+2 -2
View File
@@ -6,9 +6,9 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
"github.com/mgutz/ansi"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
+2 -2
View File
@@ -6,11 +6,11 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
"github.com/mgutz/ansi"
"golang.org/x/crypto/ssh/terminal"
survey "gopkg.in/AlecAivazis/survey.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
+3 -3
View File
@@ -6,9 +6,9 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata"
"github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
"github.com/go-jira/jira/jiradata"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
+1 -1
View File
@@ -1,6 +1,6 @@
package jiracmd
import "gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
import "github.com/go-jira/jira/jiracli"
func RegisterAllCommands() {
jiracli.RegisterCommand(jiracli.CommandRegistry{Command: "acknowledge", Entry: CmdTransitionRegistry("acknowledge"), Aliases: []string{"ack"}})
+3 -16
View File
@@ -3,14 +3,13 @@ package jiracmd
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/url"
"strings"
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"github.com/go-jira/jira/jiracli"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
@@ -75,21 +74,9 @@ func CmdRequest(o *oreo.Client, globals *jiracli.GlobalOptions, opts *RequestOpt
}
defer resp.Body.Close()
content, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
if len(content) == 0 {
if !globals.Quiet.Value {
fmt.Println("No content in response")
}
return nil
}
var data interface{}
err = json.Unmarshal(content, &data)
if err != nil {
return fmt.Errorf("JSON Parse Error: %s from %q", err, content)
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
return fmt.Errorf("JSON Parse Error: %v", err)
}
return opts.PrintTemplate(&data)
}
+2 -2
View File
@@ -5,8 +5,8 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
kingpin "gopkg.in/alecthomas/kingpin.v2"
yaml "gopkg.in/coryb/yaml.v2"
)
+3 -3
View File
@@ -6,9 +6,9 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata"
"github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
"github.com/go-jira/jira/jiradata"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
+1 -1
View File
@@ -3,7 +3,7 @@ package jiracmd
import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"github.com/go-jira/jira/jiracli"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
+11 -13
View File
@@ -7,9 +7,9 @@ import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata"
"github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
"github.com/go-jira/jira/jiradata"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
@@ -110,15 +110,13 @@ func CmdTransition(o *oreo.Client, globals *jiracli.GlobalOptions, opts *Transit
}
// need to default the Resolution, usually Fixed works but sometime need Done
if opts.Resolution == "" {
if resField, ok := transMeta.Fields["resolution"]; ok {
for _, allowedValueRaw := range resField.AllowedValues {
if allowedValue, ok := allowedValueRaw.(map[string]interface{}); ok {
if allowedValue["name"] == "Fixed" {
opts.Resolution = "Fixed"
} else if allowedValue["name"] == "Done" {
opts.Resolution = "Done"
}
if resField, ok := transMeta.Fields["resolution"]; ok && opts.Resolution == "" {
for _, allowedValueRaw := range resField.AllowedValues {
if allowedValue, ok := allowedValueRaw.(map[string]interface{}); ok {
if allowedValue["name"] == "Fixed" {
opts.Resolution = "Fixed"
} else if allowedValue["name"] == "Done" {
opts.Resolution = "Done"
}
}
}
@@ -129,7 +127,7 @@ func CmdTransition(o *oreo.Client, globals *jiracli.GlobalOptions, opts *Transit
*jiradata.Issue `yaml:",inline"`
// Yes, Meta and Transition are redundant, but this is for backwards compatibility
// with old templates
Meta *jiradata.Transition `yaml:"meta,omitempty" json:"meta,omitemtpy"`
Meta *jiradata.Transition `yaml:"meta,omitempty" json:"meta,omitempty"`
Transition *jiradata.Transition `yaml:"transition,omitempty" json:"transition,omitempty"`
Overrides map[string]string `yaml:"overrides,omitempty" json:"overrides,omitempty"`
}
+2 -2
View File
@@ -3,8 +3,8 @@ package jiracmd
import (
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiracli"
"github.com/go-jira/jira"
"github.com/go-jira/jira/jiracli"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)

Some files were not shown because too many files have changed in this diff Show More