Compare commits

..

10 Commits

Author SHA1 Message Date
Cory Bennett 5d863ffed4 Updated Changelog 2015-12-03 12:56:18 -08:00
Cory Bennett 577394b0bd add --quiet command to not print the OK ..
add --saveFile option to print the issue/link to a file on create command
2015-12-03 12:55:14 -08:00
Cory Bennett c1a7e1bbdb fix overrides 2015-12-03 12:21:55 -08:00
Cory Bennett f904f3c089 add abstract request wrapper to allow you to access/process random apis
supported by Jira but not yet supported by go-jira
2015-12-03 11:35:51 -08:00
Cory Bennett e35e518368 Updated Changelog 2015-11-23 17:09:17 -08:00
Cory Bennett 159d142f37 jira edit should not require one arguemnt (allow for --query) 2015-11-23 17:08:40 -08:00
Cory Bennett df84d47552 fix CURVER in case of building from src tar.gz 2015-11-23 14:35:41 -08:00
Cory Bennett fa4ce5647d tweak build 2015-11-23 14:23:29 -08:00
Cory Bennett 713d300a57 Updated Changelog 2015-11-23 14:17:41 -08:00
Cory Bennett c8ae7fc685 [#17] print usage on missing arguments 2015-11-23 14:17:09 -08:00
7 changed files with 156 additions and 36 deletions
+14
View File
@@ -1,5 +1,19 @@
# Changelog # Changelog
## 0.0.17 - 2015-12-03
* add --quiet command to not print the OK .. add --saveFile option to print the issue/link to a file on create command [Cory Bennett] [[c9ac162](https://github.com/Netflix-Skunkworks/go-jira/commit/c9ac162)]
* fix overrides [Cory Bennett] [[eaddfe6](https://github.com/Netflix-Skunkworks/go-jira/commit/eaddfe6)]
* add abstract request wrapper to allow you to access/process random apis supported by Jira but not yet supported by go-jira [Cory Bennett] [[90ef56a](https://github.com/Netflix-Skunkworks/go-jira/commit/90ef56a)]
## 0.0.16 - 2015-11-23
* jira edit should not require one arguemnt (allow for --query) [Cory Bennett] [[a1eb4a1](https://github.com/Netflix-Skunkworks/go-jira/commit/a1eb4a1)]
## 0.0.15 - 2015-11-23
* [[#17](https://github.com/Netflix-Skunkworks/go-jira/issues/17)] print usage on missing arguments [Cory Bennett] [[fd2a2fe](https://github.com/Netflix-Skunkworks/go-jira/commit/fd2a2fe)]
## 0.0.14 - 2015-11-17 ## 0.0.14 - 2015-11-17
* s/enpoint/endpoint/g [Oliver Schrenk] [[c5d251d](https://github.com/Netflix-Skunkworks/go-jira/commit/c5d251d)] * s/enpoint/endpoint/g [Oliver Schrenk] [[c5d251d](https://github.com/Netflix-Skunkworks/go-jira/commit/c5d251d)]
+15 -16
View File
@@ -15,27 +15,33 @@ PLATFORMS= \
DIST=$(shell pwd)/dist DIST=$(shell pwd)/dist
export GOPATH=$(shell pwd) export GOPATH=$(shell pwd)
GOBIN ?= $(shell pwd)/bin
NAME=jira
build: CURVER ?= $(shell [ -d .git ] && git describe --abbrev=0 --tags || grep ^\#\# CHANGELOG.md | awk '{print $$2; exit}')
cd src/github.com/Netflix-Skunkworks/go-jira/jira; \ LDFLAGS:=-X main.buildVersion=$(CURVER)
go get -v
build: src/github.com/Netflix-Skunkworks/go-jira
go build -ldflags "$(LDFLAGS)" -o $(GOBIN)/$(NAME) jira/main.go
src/%:
mkdir -p $(@D)
test -L $@ || ln -sf ../../.. $@
go get -v $*/jira
cross-setup: cross-setup:
for p in $(PLATFORMS); do \ for p in $(PLATFORMS); do \
echo "Building for $$p"; \ echo "Building for $$p"; \
cd $(GOROOT)/src && sudo GOOS=$${p/-*/} GOARCH=$${p/*-/} bash ./make.bash --no-clean; \ cd $(GOROOT)/src && sudo GOROOT_BOOTSTRAP=$(GOROOT) GOOS=$${p/-*/} GOARCH=$${p/*-/} bash ./make.bash --no-clean; \
done done
all: all:
rm -rf $(DIST); \ rm -rf $(DIST); \
mkdir -p $(DIST); \ mkdir -p $(DIST); \
cd src/github.com/Netflix-Skunkworks/go-jira/jira; \
go get -d; \
for p in $(PLATFORMS); do \ for p in $(PLATFORMS); do \
echo "Building for $$p"; \ echo "Building for $$p"; \
GOOS=$${p/-*/} GOARCH=$${p/*-/} go build -v -ldflags -s -o $(DIST)/jira-$$p; \ GOOS=$${p/-*/} GOARCH=$${p/*-/} go build -v -ldflags "$(LDFLAGS) -s" -o $(DIST)/$(NAME)-$$p jira/main.go ; \
done done
fmt: fmt:
gofmt -s -w jira gofmt -s -w jira
@@ -43,11 +49,6 @@ fmt:
install: install:
export GOBIN=~/bin && ${MAKE} build export GOBIN=~/bin && ${MAKE} build
# need gsort on OSX (brew install coreutils) or newer sort on linux
# that supports the -V option for version sorting
SORT=gsort
CURVER ?= $(shell git fetch --tags && git tag | $(SORT) -V | tail -1)
NEWVER ?= $(shell echo $(CURVER) | awk -F. '{print $$1"."$$2"."$$3+1}') NEWVER ?= $(shell echo $(CURVER) | awk -F. '{print $$1"."$$2"."$$3+1}')
TODAY := $(shell date +%Y-%m-%d) TODAY := $(shell date +%Y-%m-%d)
@@ -65,9 +66,7 @@ update-changelog:
tail +2 CHANGELOG.md >> CHANGELOG.md.new; \ tail +2 CHANGELOG.md >> CHANGELOG.md.new; \
mv CHANGELOG.md.new CHANGELOG.md; \ mv CHANGELOG.md.new CHANGELOG.md; \
git commit -m "Updated Changelog" CHANGELOG.md; \ git commit -m "Updated Changelog" CHANGELOG.md; \
perl -pi -e "s/version: $(CURVER)/version: $(NEWVER)/" jira/main.go; \
git commit -m "bump version" jira/main.go; \
git tag $(NEWVER) git tag $(NEWVER)
clean: clean:
rm -rf pkg dist bin && find src \! -path \*/go-jira\* -delete rm -rf pkg dist bin src ./toolkit
+7
View File
@@ -354,6 +354,13 @@ func (c *Cli) Browse(issue string) error {
return nil return nil
} }
func (c *Cli) SaveData(data interface{}) error {
if val, ok := c.opts["saveFile"].(string); ok && val != "" {
yamlWrite(val, data)
}
return nil
}
func (c *Cli) FindIssues() (interface{}, error) { func (c *Cli) FindIssues() (interface{}, error) {
var query string var query string
var ok bool var ok bool
+53 -11
View File
@@ -126,7 +126,9 @@ func (c *Cli) CmdEdit(issue string) error {
if resp.StatusCode == 204 { if resp.StatusCode == 204 {
c.Browse(issueData["key"].(string)) c.Browse(issueData["key"].(string))
fmt.Printf("OK %s %s/browse/%s\n", issueData["key"], c.endpoint, issueData["key"]) if ! c.opts["quiet"].(bool) {
fmt.Printf("OK %s %s/browse/%s\n", issueData["key"], c.endpoint, issueData["key"])
}
return nil return nil
} else { } else {
logBuffer := bytes.NewBuffer(make([]byte, 0)) logBuffer := bytes.NewBuffer(make([]byte, 0))
@@ -260,10 +262,16 @@ func (c *Cli) CmdCreate() error {
if json, err := responseToJson(resp, nil); err != nil { if json, err := responseToJson(resp, nil); err != nil {
return err return err
} else { } else {
key := json.(map[string]interface{})["key"] key := json.(map[string]interface{})["key"].(string)
c.Browse(key.(string)) link := fmt.Sprintf("%s/browse/%s", c.endpoint, key)
fmt.Printf("OK %s %s/browse/%s\n", key, c.endpoint, key) c.Browse(key)
c.SaveData(map[string]string{
"issue": key,
"link": link,
})
if ! c.opts["quiet"].(bool) {
fmt.Printf("OK %s %s\n", key, link)
}
} }
return nil return nil
} else { } else {
@@ -318,7 +326,9 @@ func (c *Cli) CmdBlocks(blocker string, issue string) error {
} }
if resp.StatusCode == 201 { if resp.StatusCode == 201 {
c.Browse(issue) c.Browse(issue)
fmt.Printf("OK %s %s/browse/%s\n", issue, c.endpoint, issue) if ! c.opts["quiet"].(bool) {
fmt.Printf("OK %s %s/browse/%s\n", issue, c.endpoint, issue)
}
} else { } else {
logBuffer := bytes.NewBuffer(make([]byte, 0)) logBuffer := bytes.NewBuffer(make([]byte, 0))
resp.Write(logBuffer) resp.Write(logBuffer)
@@ -359,7 +369,9 @@ func (c *Cli) CmdDups(duplicate string, issue string) error {
} }
if resp.StatusCode == 201 { if resp.StatusCode == 201 {
c.Browse(issue) c.Browse(issue)
fmt.Printf("OK %s %s/browse/%s\n", issue, c.endpoint, issue) if ! c.opts["quiet"].(bool) {
fmt.Printf("OK %s %s/browse/%s\n", issue, c.endpoint, issue)
}
} else { } else {
logBuffer := bytes.NewBuffer(make([]byte, 0)) logBuffer := bytes.NewBuffer(make([]byte, 0))
resp.Write(logBuffer) resp.Write(logBuffer)
@@ -391,7 +403,9 @@ func (c *Cli) CmdWatch(issue string) error {
} }
if resp.StatusCode == 204 { if resp.StatusCode == 204 {
c.Browse(issue) c.Browse(issue)
fmt.Printf("OK %s %s/browse/%s\n", issue, c.endpoint, issue) if ! c.opts["quiet"].(bool) {
fmt.Printf("OK %s %s/browse/%s\n", issue, c.endpoint, issue)
}
} else { } else {
logBuffer := bytes.NewBuffer(make([]byte, 0)) logBuffer := bytes.NewBuffer(make([]byte, 0))
resp.Write(logBuffer) resp.Write(logBuffer)
@@ -445,7 +459,9 @@ func (c *Cli) CmdTransition(issue string, trans string) error {
} }
if resp.StatusCode == 204 { if resp.StatusCode == 204 {
c.Browse(issue) c.Browse(issue)
fmt.Printf("OK %s %s/browse/%s\n", issue, c.endpoint, issue) if ! c.opts["quiet"].(bool) {
fmt.Printf("OK %s %s/browse/%s\n", issue, c.endpoint, issue)
}
} else { } else {
logBuffer := bytes.NewBuffer(make([]byte, 0)) logBuffer := bytes.NewBuffer(make([]byte, 0))
resp.Write(logBuffer) resp.Write(logBuffer)
@@ -496,7 +512,9 @@ func (c *Cli) CmdComment(issue string) error {
if resp.StatusCode == 201 { if resp.StatusCode == 201 {
c.Browse(issue) c.Browse(issue)
fmt.Printf("OK %s %s/browse/%s\n", issue, c.endpoint, issue) if ! c.opts["quiet"].(bool) {
fmt.Printf("OK %s %s/browse/%s\n", issue, c.endpoint, issue)
}
return nil return nil
} else { } else {
logBuffer := bytes.NewBuffer(make([]byte, 0)) logBuffer := bytes.NewBuffer(make([]byte, 0))
@@ -548,7 +566,9 @@ func (c *Cli) CmdAssign(issue string, user string) error {
} }
if resp.StatusCode == 204 { if resp.StatusCode == 204 {
c.Browse(issue) c.Browse(issue)
fmt.Printf("OK %s %s/browse/%s\n", issue, c.endpoint, issue) if ! c.opts["quiet"].(bool) {
fmt.Printf("OK %s %s/browse/%s\n", issue, c.endpoint, issue)
}
} else { } else {
logBuffer := bytes.NewBuffer(make([]byte, 0)) logBuffer := bytes.NewBuffer(make([]byte, 0))
resp.Write(logBuffer) resp.Write(logBuffer)
@@ -585,3 +605,25 @@ func (c *Cli) CmdExportTemplates() error {
} }
return nil return nil
} }
func (c *Cli) CmdRequest(uri, content string) (err error) {
log.Debug("request called")
if ! strings.HasPrefix(uri, "http") {
uri = fmt.Sprintf("%s%s", c.endpoint, uri)
}
method := strings.ToUpper(c.opts["method"].(string))
var data interface{}
if method == "GET" {
data, err = responseToJson(c.get(uri))
} else if method == "POST" {
data, err = responseToJson(c.post(uri, content))
} else if method == "PUT" {
data, err = responseToJson(c.put(uri, content))
}
if err != nil {
return err
}
return runTemplate(c.getTemplate("request"), data, nil)
}
+1
View File
@@ -16,6 +16,7 @@ var all_templates = map[string]string{
"create": default_create_template, "create": default_create_template,
"comment": default_comment_template, "comment": default_comment_template,
"transition": default_transition_template, "transition": default_transition_template,
"request": default_debug_template,
} }
const default_debug_template = "{{ . | toJson}}\n" const default_debug_template = "{{ . | toJson}}\n"
+16
View File
@@ -6,6 +6,7 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"gopkg.in/coryb/yaml.v2"
"github.com/mgutz/ansi" "github.com/mgutz/ansi"
"io" "io"
"io/ioutil" "io/ioutil"
@@ -245,6 +246,21 @@ func jsonWrite(file string, data interface{}) {
enc.Encode(data) enc.Encode(data)
} }
func yamlWrite(file string, data interface{}) {
fh, err := os.OpenFile(file, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
defer fh.Close()
if err != nil {
log.Error("Failed to open %s: %s", file, err)
os.Exit(1)
}
if out, err := yaml.Marshal(data); err != nil {
log.Error("Failed to marshal yaml %v: %s", data, err)
os.Exit(1)
} else {
fh.Write(out)
}
}
func promptYN(prompt string, yes bool) bool { func promptYN(prompt string, yes bool) bool {
reader := bufio.NewReader(os.Stdin) reader := bufio.NewReader(os.Stdin)
if !yes { if !yes {
+50 -9
View File
@@ -13,8 +13,11 @@ import (
"strings" "strings"
) )
var log = logging.MustGetLogger("jira") var (
var format = "%{color}%{time:2006-01-02T15:04:05.000Z07:00} %{level:-5s} [%{shortfile}]%{color:reset} %{message}" log = logging.MustGetLogger("jira")
format = "%{color}%{time:2006-01-02T15:04:05.000Z07:00} %{level:-5s} [%{shortfile}]%{color:reset} %{message}"
buildVersion string
)
func main() { func main() {
logBackend := logging.NewLogBackend(os.Stderr, "", 0) logBackend := logging.NewLogBackend(os.Stderr, "", 0)
@@ -75,6 +78,7 @@ Usage:
jira export-templates [-d DIR] [-t template] jira export-templates [-d DIR] [-t template]
jira (b|browse) ISSUE jira (b|browse) ISSUE
jira login jira login
jira request [-M METHOD] URI [DATA]
jira ISSUE jira ISSUE
General Options: General Options:
@@ -146,6 +150,8 @@ Command Options:
"export-templates": "export-templates", "export-templates": "export-templates",
"browse": "browse", "browse": "browse",
"login": "login", "login": "login",
"req": "request",
"request": "request",
} }
defaults := map[string]interface{}{ defaults := map[string]interface{}{
@@ -154,11 +160,10 @@ Command Options:
"directory": fmt.Sprintf("%s/.jira.d/templates", home), "directory": fmt.Sprintf("%s/.jira.d/templates", home),
"sort": defaultSort, "sort": defaultSort,
"max_results": defaultMaxResults, "max_results": defaultMaxResults,
"method": "GET",
} }
opts := make(map[string]interface{}) opts := make(map[string]interface{})
overrides := make(map[string]string)
setopt := func(name string, value interface{}) { setopt := func(name string, value interface{}) {
opts[name] = value opts[name] = value
} }
@@ -166,7 +171,7 @@ Command Options:
op := optigo.NewDirectAssignParser(map[string]interface{}{ op := optigo.NewDirectAssignParser(map[string]interface{}{
"h|help": usage, "h|help": usage,
"version": func() { "version": func() {
fmt.Println("version: 0.0.14") fmt.Println(fmt.Sprintf("version: %s", buildVersion))
os.Exit(0) os.Exit(0)
}, },
"v|verbose+": func() { "v|verbose+": func() {
@@ -188,11 +193,14 @@ Command Options:
"f|queryfields=s": setopt, "f|queryfields=s": setopt,
"s|sort=s": setopt, "s|sort=s": setopt,
"l|limit|max_results=i": setopt, "l|limit|max_results=i": setopt,
"o|override=s%": &overrides, "o|override=s%": &opts,
"noedit": setopt, "noedit": setopt,
"edit": setopt, "edit": setopt,
"m|comment=s": setopt, "m|comment=s": setopt,
"d|dir|directory=s": setopt, "d|dir|directory=s": setopt,
"M|method=s": setopt,
"S|saveFile=s": setopt,
"Q|quiet": setopt,
}) })
if err := op.ProcessAll(os.Args[1:]); err != nil { if err := op.ProcessAll(os.Args[1:]); err != nil {
@@ -200,7 +208,6 @@ Command Options:
usage(false) usage(false)
} }
args := op.Args args := op.Args
opts["overrides"] = overrides
var command string var command string
if len(args) > 0 { if len(args) > 0 {
@@ -216,7 +223,7 @@ Command Options:
} }
} }
if command == "" { if command == "" && len(args) > 0 {
command = args[0] command = args[0]
args = args[1:] args = args[1:]
} }
@@ -228,7 +235,9 @@ Command Options:
if value, ok := opts["command"].(string); ok { if value, ok := opts["command"].(string); ok {
command = value command = value
} else if _, ok := jiraCommands[command]; !ok || command == "" { } else if _, ok := jiraCommands[command]; !ok || command == "" {
args = append([]string{command}, args...) if command != "" {
args = append([]string{command}, args...)
}
command = "view" command = "view"
} }
@@ -270,6 +279,13 @@ Command Options:
} }
} }
requireArgs := func(count int) {
if len(args) < count {
log.Error("Not enough arguments. %d required, %d provided", count, len(args))
usage(false)
}
}
var err error var err error
switch command { switch command {
case "login": case "login":
@@ -300,8 +316,10 @@ Command Options:
} }
} }
case "editmeta": case "editmeta":
requireArgs(1)
err = c.CmdEditMeta(args[0]) err = c.CmdEditMeta(args[0])
case "transmeta": case "transmeta":
requireArgs(1)
err = c.CmdTransitionMeta(args[0]) err = c.CmdTransitionMeta(args[0])
case "issuelinktypes": case "issuelinktypes":
err = c.CmdIssueLinkTypes() err = c.CmdIssueLinkTypes()
@@ -313,51 +331,74 @@ Command Options:
setEditing(true) setEditing(true)
err = c.CmdCreate() err = c.CmdCreate()
case "transitions": case "transitions":
requireArgs(1)
err = c.CmdTransitions(args[0]) err = c.CmdTransitions(args[0])
case "blocks": case "blocks":
requireArgs(2)
err = c.CmdBlocks(args[0], args[1]) err = c.CmdBlocks(args[0], args[1])
case "dups": case "dups":
requireArgs(2)
if err = c.CmdDups(args[0], args[1]); err == nil { if err = c.CmdDups(args[0], args[1]); err == nil {
opts["resolution"] = "Duplicate" opts["resolution"] = "Duplicate"
err = c.CmdTransition(args[0], "close") err = c.CmdTransition(args[0], "close")
} }
case "watch": case "watch":
requireArgs(1)
err = c.CmdWatch(args[0]) err = c.CmdWatch(args[0])
case "transition": case "transition":
requireArgs(2)
setEditing(true) setEditing(true)
err = c.CmdTransition(args[0], args[1]) err = c.CmdTransition(args[0], args[1])
case "close": case "close":
requireArgs(1)
setEditing(false) setEditing(false)
err = c.CmdTransition(args[0], "close") err = c.CmdTransition(args[0], "close")
case "acknowledge": case "acknowledge":
requireArgs(1)
setEditing(false) setEditing(false)
err = c.CmdTransition(args[0], "acknowledge") err = c.CmdTransition(args[0], "acknowledge")
case "reopen": case "reopen":
requireArgs(1)
setEditing(false) setEditing(false)
err = c.CmdTransition(args[0], "reopen") err = c.CmdTransition(args[0], "reopen")
case "resolve": case "resolve":
requireArgs(1)
setEditing(false) setEditing(false)
err = c.CmdTransition(args[0], "resolve") err = c.CmdTransition(args[0], "resolve")
case "start": case "start":
requireArgs(1)
setEditing(false) setEditing(false)
err = c.CmdTransition(args[0], "start") err = c.CmdTransition(args[0], "start")
case "stop": case "stop":
requireArgs(1)
setEditing(false) setEditing(false)
err = c.CmdTransition(args[0], "stop") err = c.CmdTransition(args[0], "stop")
case "comment": case "comment":
requireArgs(1)
setEditing(true) setEditing(true)
err = c.CmdComment(args[0]) err = c.CmdComment(args[0])
case "take": case "take":
requireArgs(1)
err = c.CmdAssign(args[0], opts["user"].(string)) err = c.CmdAssign(args[0], opts["user"].(string))
case "browse": case "browse":
requireArgs(1)
opts["browse"] = true opts["browse"] = true
err = c.Browse(args[0]) err = c.Browse(args[0])
case "export-templates": case "export-templates":
err = c.CmdExportTemplates() err = c.CmdExportTemplates()
case "assign": case "assign":
requireArgs(2)
err = c.CmdAssign(args[0], args[1]) err = c.CmdAssign(args[0], args[1])
case "view": case "view":
requireArgs(1)
err = c.CmdView(args[0]) err = c.CmdView(args[0])
case "request":
requireArgs(1)
data := ""
if len(args) > 1 {
data = args[1]
}
err = c.CmdRequest(args[0], data)
default: default:
log.Error("Unknown command %s", command) log.Error("Unknown command %s", command)
os.Exit(1) os.Exit(1)