Compare commits

...

29 Commits

Author SHA1 Message Date
Cory Bennett e841270b83 version bump 2017-09-13 12:31:16 -07:00
Cory Bennett 2ededeeaf7 Updated Changelog 2017-09-13 12:31:16 -07:00
Cory Bennett 00cba793ad tweaks for templates in named queries to work better 2017-09-13 12:17:59 -07:00
Cory Bennett fb43753c31 [#99] add support for named queries to be stored in configs 2017-09-13 11:12:58 -07:00
Cory Bennett 5085a14494 add license badge 2017-09-13 00:15:09 -07:00
Cory Bennett 5da04c1f86 [#98] add --status option for JQL filter on status with list command 2017-09-13 00:12:20 -07:00
Cory Bennett 052e038d73 version bump 2017-09-11 00:16:10 -07:00
Cory Bennett a7f1323f34 Updated Changelog 2017-09-11 00:16:10 -07:00
Cory Bennett 8d27b736ca track *.lock 2017-09-11 00:16:01 -07:00
Cory Bennett c3c008e53d running dep prune 2017-09-11 00:11:56 -07:00
Cory Bennett 608e586d1c use --gjq for GJson Query to filter json response data, remove --jq option 2017-09-10 22:48:40 -07:00
Cory Bennett 2c552ac530 fix field tag syntax 2017-09-09 19:13:58 -07:00
Cory Bennett 1d269183c3 add --jq option to run a json query against Jira service response json 2017-09-09 19:02:23 -07:00
Cory Bennett e0e1e5b941 use {{jira}} in custom-command docs 2017-09-09 17:44:56 -07:00
Cory Bennett 941824d7f8 add '{{jira}}' template macro to refer to path of currently running jira command 2017-09-09 17:40:26 -07:00
Cory Bennett c585244f3e add basic tests for custom-commands 2017-09-09 17:20:57 -07:00
Cory Bennett 29b95a52cb version bump 2017-09-08 18:54:34 -07:00
Cory Bennett f556375242 Updated Changelog 2017-09-08 18:54:34 -07:00
Cory Bennett 86b963bdb5 update deps for kingpeon update
use os.exec instead of syscall.exec for windows
2017-09-08 18:53:21 -07:00
Cory Bennett 036ebb4bf7 make custom-commands example copy/pasteable 2017-09-07 08:39:37 -07:00
Cory Bennett 7d481fe965 version bump 2017-09-06 23:23:47 -07:00
Cory Bennett 4709bbbe38 Updated Changelog 2017-09-06 23:23:47 -07:00
Cory Bennett 1c79a80389 add COLUMNS back in for jira ls --template table testing 2017-09-06 23:07:48 -07:00
Cory Bennett 6a879959be fix perms for test .gnupg directory 2017-09-06 22:34:15 -07:00
Cory Bennett d46f9495e7 assume tests always run in jira cloud 2017-09-06 22:30:59 -07:00
Cory Bennett e6faee1573 [#66] add --started option to jira worklog add to change the start time for worklog 2017-09-06 22:30:15 -07:00
Cory Bennett c4be59cae3 [#45] automatically add comment to issue even if transition does not support comment updates during transtion 2017-09-06 21:28:57 -07:00
Cory Bennett 9cc91f7108 use xgo tool rather than docker image directly 2017-09-06 12:29:06 -07:00
Cory Bennett da8ee59ebb version bump 2017-09-06 12:07:51 -07:00
529 changed files with 6007 additions and 69884 deletions
+1
View File
@@ -2,3 +2,4 @@ jira
schemas/*.json
t/.gnupg/random_seed
t/issue.props
dist
+11
View File
@@ -0,0 +1,11 @@
config:
stop: true
password-source: pass
endpoint: https://go-jira.atlassian.net
user: admin
queries:
todo: |
resolution = unresolved {{if .project}}AND project = '{{.project}}'{{end}} AND status = 'To Do'
open: |
resolution = unresolved {{if .project}}AND project = '{{.project}}'{{end}} AND status = 'Open'
+21
View File
@@ -1,5 +1,26 @@
# Changelog
## 1.0.6 - 2017-09-13
* tweaks for templates in named queries to work better [Cory Bennett] [[00cba79](https://github.com/Netflix-Skunkworks/go-jira/commit/00cba79)]
* [[#99](https://github.com/Netflix-Skunkworks/go-jira/issues/99)] add support for named queries to be stored in configs [Cory Bennett] [[fb43753](https://github.com/Netflix-Skunkworks/go-jira/commit/fb43753)]
* [[#98](https://github.com/Netflix-Skunkworks/go-jira/issues/98)] add `--status` option for JQL filter on status with `list` command [Cory Bennett] [[5da04c1](https://github.com/Netflix-Skunkworks/go-jira/commit/5da04c1)]
## 1.0.5 - 2017-09-11
* use --gjq for GJson Query to filter json response data [Cory Bennett] [[608e586](https://github.com/Netflix-Skunkworks/go-jira/commit/608e586)]
* fix field tag syntax [Cory Bennett] [[2c552ac](https://github.com/Netflix-Skunkworks/go-jira/commit/2c552ac)]
* add '{{jira}}' template macro to refer to path of currently running jira command [Cory Bennett] [[941824d](https://github.com/Netflix-Skunkworks/go-jira/commit/941824d)]
## 1.0.4 - 2017-09-08
* update deps for kingpeon update use os.exec instead of syscall.exec for windows [Cory Bennett] [[86b963b](https://github.com/Netflix-Skunkworks/go-jira/commit/86b963b)]
## 1.0.3 - 2017-09-06
* [[#66](https://github.com/Netflix-Skunkworks/go-jira/issues/66)] add --started option to `jira worklog add` to change the start time for worklog [Cory Bennett] [[e6faee1](https://github.com/Netflix-Skunkworks/go-jira/commit/e6faee1)]
* [[#45](https://github.com/Netflix-Skunkworks/go-jira/issues/45)] automatically add comment to issue even if transition does not support comment updates during transtion [Cory Bennett] [[c4be59c](https://github.com/Netflix-Skunkworks/go-jira/commit/c4be59c)]
## 1.0.2 - 2017-09-06
* update dependencies [Cory Bennett] [[aa876cd](https://github.com/Netflix-Skunkworks/go-jira/commit/aa876cd)]
Generated
+165
View File
@@ -0,0 +1,165 @@
# 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 = "9127e812e1e9e501ce899a18121d316ecb52e4ba"
[[projects]]
branch = "master"
name = "github.com/coryb/figtree"
packages = ["."]
revision = "c7d8fbf1d7746b5864b8262fabffec813b5a43fa"
[[projects]]
branch = "master"
name = "github.com/coryb/kingpeon"
packages = ["."]
revision = "64b561ae2d0f895b94719c486bed798f4236a4b3"
[[projects]]
branch = "master"
name = "github.com/coryb/oreo"
packages = ["."]
revision = "95687d61c95ee1522c1140e2af59b0c1846abfc1"
[[projects]]
branch = "master"
name = "github.com/fatih/camelcase"
packages = ["."]
revision = "f6a740d52f961c60348ebb109adde9f4635d7540"
[[projects]]
branch = "master"
name = "github.com/guelfey/go.dbus"
packages = ["."]
revision = "f6a3a2366cc39b8479cadc499d3c735fb10fbdda"
[[projects]]
branch = "master"
name = "github.com/jinzhu/copier"
packages = ["."]
revision = "32e0d0db1dcd4373fb9eb0f9d727b1fe1a723e54"
[[projects]]
branch = "master"
name = "github.com/kballard/go-shellquote"
packages = ["."]
revision = "cd60e84ee657ff3dc51de0b4f55dd299a3e136f2"
[[projects]]
branch = "master"
name = "github.com/mattn/go-colorable"
packages = ["."]
revision = "ad5389df28cdac544c99bd7b9161a0b5b6ca9d1b"
[[projects]]
name = "github.com/mattn/go-isatty"
packages = ["."]
revision = "fc9e8d8ef48496124e79ae0df75490096eccf6fe"
version = "v0.0.2"
[[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]]
branch = "master"
name = "github.com/sethgrid/pester"
packages = ["."]
revision = "a86a2d88f4dc3c7dbf3a6a6bbbfb095690b834b6"
[[projects]]
branch = "master"
name = "github.com/theckman/go-flock"
packages = ["."]
revision = "6de226b0d5f040ed85b88c82c381709b98277f3d"
[[projects]]
branch = "master"
name = "github.com/tidwall/gjson"
packages = ["."]
revision = "be96719f990978a867f52c48f29d43f6b591da28"
[[projects]]
branch = "master"
name = "github.com/tidwall/match"
packages = ["."]
revision = "173748da739a410c5b0b813b956f89ff94730b4c"
[[projects]]
branch = "master"
name = "github.com/tmc/keyring"
packages = ["."]
revision = "06e6283d50adc5f8fcdb3cdf33ee1244d4400ae1"
[[projects]]
branch = "master"
name = "golang.org/x/crypto"
packages = ["ssh/terminal"]
revision = "9ba3862cf6a5452ae579de98f9364dd2e544844c"
[[projects]]
branch = "master"
name = "golang.org/x/sys"
packages = ["unix","windows"]
revision = "a5054c7c1385fd50d9394475365355a87a7873ec"
[[projects]]
name = "gopkg.in/AlecAivazis/survey.v1"
packages = [".","core","terminal"]
revision = "9d910423e24aa6d7c7950160658c295e0734c7e0"
version = "1.3.1"
[[projects]]
name = "gopkg.in/alecthomas/kingpin.v2"
packages = ["."]
revision = "1087e65c9441605df944fb12c33f0fe7072d18ca"
version = "v2.2.5"
[[projects]]
branch = "v2"
name = "gopkg.in/coryb/yaml.v2"
packages = ["."]
revision = "fb7cb9628c6e3bdd76c29fb91798d51a09832470"
[[projects]]
name = "gopkg.in/op/go-logging.v1"
packages = ["."]
revision = "b2cb9fa56473e98db8caba80237377e83fe44db5"
version = "v1"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "1f4b97fcf898a5ef03af5e222686a09328b393e71797d21bf0c37b74d1e74a8e"
solver-name = "gps-cdcl"
solver-version = 1
+75
View File
@@ -0,0 +1,75 @@
# 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"
[[constraint]]
name = "github.com/coryb/figtree"
[[constraint]]
name = "github.com/coryb/kingpeon"
[[constraint]]
name = "github.com/coryb/oreo"
[[constraint]]
name = "github.com/jinzhu/copier"
[[constraint]]
name = "github.com/kballard/go-shellquote"
[[constraint]]
name = "github.com/mgutz/ansi"
[[constraint]]
name = "github.com/pkg/browser"
[[constraint]]
name = "github.com/pkg/errors"
version = "0.8.0"
[[constraint]]
name = "github.com/savaki/jq"
[[constraint]]
name = "github.com/tmc/keyring"
[[constraint]]
name = "golang.org/x/crypto"
[[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"
[[constraint]]
name = "gopkg.in/op/go-logging.v1"
version = "1.0.0"
[[constraint]]
branch = "master"
name = "github.com/tidwall/gjson"
+6 -25
View File
@@ -1,19 +1,3 @@
PLATFORMS= \
freebsd/amd64 \
linux/386 \
linux/amd64 \
windows/386 \
windows/amd64 \
darwin/amd64 \
$(NULL)
# freebsd-386 \
# freebsd-arm \
# linux-arm \
# openbsd-386 \
# openbsd-amd64 \
# darwin-386
NAME=jira
OS=$(shell uname -s)
@@ -53,11 +37,11 @@ lint:
@golint ./jiradata
@golint ./cmd/jira
all:
docker pull karalabe/xgo-latest
all:
go get -u github.com/karalabe/xgo
rm -rf dist
mkdir -p dist
docker run --rm -e EXT_GOPATH=/gopath -v $$(pwd):/gopath/src/gopkg.in/Netflix-Skunkworks/go-jira.v1 -e TARGETS="$(PLATFORMS)" -v $$(pwd)/dist:/build karalabe/xgo-latest gopkg.in/Netflix-Skunkworks/go-jira.v1/cmd/jira
xgo --targets="freebsd/amd64,linux/386,linux/amd64,windows/386,windows/amd64,darwin/amd64" -dest ./dist -ldflags="-w -s" ./cmd/jira
install:
${MAKE} GOBIN=$$HOME/bin build
@@ -66,7 +50,7 @@ NEWVER ?= $(shell echo $(CURVER) | awk -F. '{print $$1"."$$2"."$$3+1}')
TODAY := $(shell date +%Y-%m-%d)
changes:
@git log --pretty=format:"* %s [%cn] [%h]" --no-merges ^v$(CURVER) HEAD *.go jiracli/*.go jiradata/*.go jiracmd/*.go cmd/*/*.go | grep -vE 'gofmt|go fmt'
@git log --pretty=format:"* %s [%cn] [%h]" --no-merges ^v$(CURVER) HEAD *.go jiracli/*.go jiradata/*.go jiracmd/*.go cmd/*/*.go *.lock | grep -vE 'gofmt|go fmt|version bump'
update-changelog:
@echo "# Changelog" > CHANGELOG.md.new; \
@@ -83,6 +67,7 @@ update-changelog:
release:
git commit -m "Updated Changelog" CHANGELOG.md; \
git commit -m "version bump" jira.go
git tag v$(NEWVER)
git push --tags
@@ -92,12 +77,8 @@ version:
clean:
rm -rf ./$(NAME)
export GNUPGHOME=$(CWD)/t/.gnupg
export PASSWORD_STORE_DIR=$(CWD)/t/.password-store
export JIRACLOUD=1
prove:
chmod -R g-rwx,o-rwx $(GNUPGHOME)
chmod -R g-rwx,o-rwx $(CWD)/t/.gnupg
OSHT_VERBOSE=1 prove -v
generate:
+7 -5
View File
@@ -1,7 +1,7 @@
[![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.png)](https://godoc.org/gopkg.in/Netflix-Skunkworks/go-jira.v1)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
# go-jira
simple command line client for Atlassian's Jira service written in Go
@@ -56,7 +56,7 @@ custom-commands:
- name: mine
help: display issues assigned to me
script: |-
jira list --query "resolution = unresolved and assignee=currentuser() ORDER BY created"
{{jira}} list --query "resolution = unresolved and assignee=currentuser() ORDER BY created"
```
Then the next time you run `jira help` you will see your usage:
```
@@ -267,25 +267,27 @@ custom-commands:
* `jira mine` for listing issues assigned to you
```
custom-commands:
- name: mine
help: display issues assigned to me
script: |-
if [ -n "$JIRA_PROJECT" ]; then
# if `project: ...` configured just list the issues for current project
jira list --template table --query "resolution = unresolved and assignee=currentuser() and project = $JIRA_PROJECT ORDER BY priority asc, created"
{{jira}} list --template table --query "resolution = unresolved and assignee=currentuser() and project = $JIRA_PROJECT ORDER BY priority asc, created"
else
# otherwise list issues for all project
jira list --template table --query "resolution = unresolved and assignee=currentuser() ORDER BY priority asc, created"
{{jira}} list --template table --query "resolution = unresolved and assignee=currentuser() ORDER BY priority asc, created"
fi
```
* `jira sprint` for listing issues in your current sprint
```
custom-commands:
- name: sprint
help: display issues for active sprint
script: |-
if [ -n "$JIRA_PROJECT" ]; then
# if `project: ...` configured just list the issues for current project
jira list --template table --query "sprint in openSprints() and type != epic and resolution = unresolved and project=$JIRA_PROJECT ORDER BY rank asc, created"
{{jira}} list --template table --query "sprint in openSprints() and type != epic and resolution = unresolved and project=$JIRA_PROJECT ORDER BY rank asc, created"
else
# otherwise list issues for all project
echo "\"project: ...\" configuration missing from .jira.d/config.yml"
+16 -1
View File
@@ -3,10 +3,13 @@ package main
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"regexp"
"runtime"
"runtime/debug"
"strconv"
"syscall"
"github.com/coryb/figtree"
"github.com/coryb/kingpeon"
@@ -307,9 +310,21 @@ func main() {
}
if len(data.CustomCommands) > 0 {
runner := syscall.Exec
if runtime.GOOS == "windows" {
runner = func(binary string, cmd []string, env []string) error {
command := exec.Command(binary, cmd[1:]...)
command.Stdin = os.Stdin
command.Stdout = os.Stdout
command.Stderr = os.Stderr
command.Env = env
return command.Run()
}
}
tmp := map[string]interface{}{}
fig.LoadAllConfigs("config.yml", &tmp)
kingpeon.RegisterDynamicCommands(app, data.CustomCommands, jiracli.TemplateProcessor())
kingpeon.RegisterDynamicCommandsWithRunner(runner, app, data.CustomCommands, jiracli.TemplateProcessor())
}
app.Terminate(func(status int) {
Generated
-64
View File
@@ -1,64 +0,0 @@
hash: 4c3ae9c9421b17aae9987ea9566cac7d0a789750bb77c8d235b7be163aec8cae
updated: 2017-09-06T11:32:06.307462177-07:00
imports:
- name: github.com/alecthomas/template
version: a0175ee3bccc567396460bf5acd36800cb10c49c
subpackages:
- parse
- name: github.com/alecthomas/units
version: 2efee857e7cfd4f3d0138cc3cbb1b4966962b93a
- name: github.com/cheekybits/genny
version: 9127e812e1e9e501ce899a18121d316ecb52e4ba
subpackages:
- generic
- name: github.com/coryb/figtree
version: 48d3afc6118a0c353dc7d41ff77a3e0b75e14c07
- name: github.com/coryb/kingpeon
version: 3ca9749293339b932167921f92ce7a55207ad34e
- name: github.com/coryb/oreo
version: 95687d61c95ee1522c1140e2af59b0c1846abfc1
- name: github.com/fatih/camelcase
version: f6a740d52f961c60348ebb109adde9f4635d7540
- name: github.com/guelfey/go.dbus
version: f6a3a2366cc39b8479cadc499d3c735fb10fbdda
- name: github.com/jinzhu/copier
version: 32e0d0db1dcd4373fb9eb0f9d727b1fe1a723e54
- name: github.com/kballard/go-shellquote
version: cd60e84ee657ff3dc51de0b4f55dd299a3e136f2
- name: github.com/mattn/go-colorable
version: ad5389df28cdac544c99bd7b9161a0b5b6ca9d1b
- name: github.com/mattn/go-isatty
version: fc9e8d8ef48496124e79ae0df75490096eccf6fe
- name: github.com/mgutz/ansi
version: 9520e82c474b0a04dd04f8a40959027271bab992
- name: github.com/pkg/browser
version: c90ca0c84f15f81c982e32665bffd8d7aac8f097
- name: github.com/pkg/errors
version: 645ef00459ed84a119197bfb8d8205042c6df63d
- name: github.com/sethgrid/pester
version: a86a2d88f4dc3c7dbf3a6a6bbbfb095690b834b6
- name: github.com/theckman/go-flock
version: 6de226b0d5f040ed85b88c82c381709b98277f3d
- name: github.com/tmc/keyring
version: 06e6283d50adc5f8fcdb3cdf33ee1244d4400ae1
- name: golang.org/x/crypto
version: 81e90905daefcd6fd217b62423c0908922eadb30
subpackages:
- ssh/terminal
- name: golang.org/x/sys
version: 9aade4d3a3b7e6d876cd3823ad20ec45fc035402
subpackages:
- unix
- windows
- name: gopkg.in/AlecAivazis/survey.v1
version: 9d910423e24aa6d7c7950160658c295e0734c7e0
subpackages:
- core
- terminal
- name: gopkg.in/alecthomas/kingpin.v2
version: 1087e65c9441605df944fb12c33f0fe7072d18ca
- name: gopkg.in/coryb/yaml.v2
version: fb7cb9628c6e3bdd76c29fb91798d51a09832470
- name: gopkg.in/op/go-logging.v1
version: b2cb9fa56473e98db8caba80237377e83fe44db5
testImports: []
-22
View File
@@ -1,22 +0,0 @@
package: gopkg.in/Netflix-Skunkworks/go-jira.v1
import:
- package: github.com/coryb/figtree
- package: github.com/coryb/kingpeon
- package: github.com/coryb/oreo
- package: github.com/jinzhu/copier
- package: github.com/kballard/go-shellquote
- package: github.com/mgutz/ansi
- package: github.com/pkg/browser
- package: github.com/pkg/errors
version: ^0.8.0
- package: github.com/tmc/keyring
- package: golang.org/x/crypto
subpackages:
- ssh/terminal
- package: gopkg.in/AlecAivazis/survey.v1
version: ^1.3.1
- package: gopkg.in/alecthomas/kingpin.v2
version: ^2.2.5
- package: gopkg.in/coryb/yaml.v2
- package: gopkg.in/op/go-logging.v1
version: ^1.0.0
+1 -1
View File
@@ -7,7 +7,7 @@ import (
var log = logging.MustGetLogger("jira")
const VERSION = "1.0.1"
const VERSION = "1.0.6"
type Jira struct {
Endpoint string `json:"endpoint,omitempty" yaml:"endpoint,omitempty"`
+18
View File
@@ -16,6 +16,7 @@ import (
"github.com/coryb/oreo"
"github.com/jinzhu/copier"
shellquote "github.com/kballard/go-shellquote"
"github.com/tidwall/gjson"
"gopkg.in/AlecAivazis/survey.v1"
kingpin "gopkg.in/alecthomas/kingpin.v2"
yaml "gopkg.in/coryb/yaml.v2"
@@ -40,6 +41,7 @@ type GlobalOptions struct {
type CommonOptions struct {
Browse figtree.BoolOption `yaml:"browse,omitempty" json:"browse,omitempty"`
Editor figtree.StringOption `yaml:"editor,omitempty" json:"editor,omitempty"`
GJsonQuery figtree.StringOption `yaml:"gjq,omitempty" json:"gjq,omitempty"`
SkipEditing figtree.BoolOption `yaml:"noedit,omitempty" json:"noedit,omitempty"`
Template figtree.StringOption `yaml:"template,omitempty" json:"template,omitempty"`
}
@@ -169,6 +171,22 @@ func TemplateUsage(cmd *kingpin.CmdClause, opts *CommonOptions) {
cmd.Flag("template", "Template to use for output").Short('t').SetValue(&opts.Template)
}
func GJsonQueryUsage(cmd *kingpin.CmdClause, opts *CommonOptions) {
cmd.Flag("gjq", "GJSON Query to filter output, see https://goo.gl/iaYwJ5").SetValue(&opts.GJsonQuery)
}
func (o *CommonOptions) PrintTemplate(data interface{}) error {
if o.GJsonQuery.Value != "" {
buf := bytes.NewBufferString("")
RunTemplate("json", data, buf)
results := gjson.GetBytes(buf.Bytes(), o.GJsonQuery.Value)
_, err := os.Stdout.Write([]byte(results.String()))
os.Stdout.Write([]byte{'\n'})
return err
}
return RunTemplate(o.Template.Value, data, nil)
}
func (o *CommonOptions) editFile(fileName string) (changes bool, err error) {
var editor string
for _, ed := range []string{o.Editor.Value, os.Getenv("JIRA_EDITOR"), os.Getenv("EDITOR"), "vim"} {
+70 -34
View File
@@ -13,9 +13,11 @@ import (
"strings"
"text/template"
yaml "gopkg.in/coryb/yaml.v2"
"github.com/coryb/figtree"
"github.com/mgutz/ansi"
"golang.org/x/crypto/ssh/terminal"
yaml "gopkg.in/coryb/yaml.v2"
)
func findTemplate(name string) ([]byte, error) {
@@ -60,6 +62,9 @@ func tmpTemplate(templateName string, data interface{}) (string, error) {
func TemplateProcessor() *template.Template {
funcs := map[string]interface{}{
"jira": func() string {
return os.Args[0]
},
"toJson": func(content interface{}) (string, error) {
bytes, err := json.MarshalIndent(content, "", " ")
if err != nil {
@@ -154,6 +159,48 @@ func TemplateProcessor() *template.Template {
return template.New("gojira").Funcs(funcs)
}
func ConfigTemplate(fig *figtree.FigTree, template, command string, opts interface{}) (string, error) {
tmp, err := translateOptions(opts)
if err != nil {
return "", err
}
fig.LoadAllConfigs(command+".yml", tmp)
fig.LoadAllConfigs("config.yml", tmp)
tmpl, err := TemplateProcessor().Parse(template)
if err != nil {
return "", err
}
buf := bytes.NewBufferString("")
if err := tmpl.Execute(buf, &tmp); err != nil {
return "", err
}
return buf.String(), nil
}
func translateOptions(opts interface{}) (interface{}, error) {
// HACK HACK HACK: convert data formats to json for backwards compatibilty with templates
jsonData, err := json.Marshal(opts)
if err != nil {
return nil, err
}
defer func(mapType, iface reflect.Type) {
yaml.DefaultMapType = mapType
yaml.IfaceType = iface
}(yaml.DefaultMapType, yaml.IfaceType)
yaml.DefaultMapType = reflect.TypeOf(map[string]interface{}{})
yaml.IfaceType = yaml.DefaultMapType.Elem()
var rawData map[string]interface{}
if err := yaml.Unmarshal(jsonData, &rawData); err != nil {
return nil, err
}
return &rawData, nil
}
func RunTemplate(templateName string, data interface{}, out io.Writer) error {
templateContent, err := getTemplate(templateName)
@@ -165,22 +212,9 @@ func RunTemplate(templateName string, data interface{}, out io.Writer) error {
out = os.Stdout
}
// HACK HACK HACK: convert data formats to json for backwards compatibilty with templates
var rawData interface{}
if jsonData, err := json.Marshal(data); err != nil {
rawData, err := translateOptions(data)
if err != nil {
return err
} else {
defer func(mapType, iface reflect.Type) {
yaml.DefaultMapType = mapType
yaml.IfaceType = iface
}(yaml.DefaultMapType, yaml.IfaceType)
yaml.DefaultMapType = reflect.TypeOf(map[string]interface{}{})
yaml.IfaceType = yaml.DefaultMapType.Elem()
if err := yaml.Unmarshal(jsonData, &rawData); err != nil {
return err
}
}
tmpl, err := TemplateProcessor().Parse(templateContent)
@@ -194,25 +228,26 @@ func RunTemplate(templateName string, data interface{}, out io.Writer) error {
}
var AllTemplates = map[string]string{
"component-add": defaultComponentAddTemplate,
"debug": defaultDebugTemplate,
"fields": defaultDebugTemplate,
"editmeta": defaultDebugTemplate,
"transmeta": defaultDebugTemplate,
"createmeta": defaultDebugTemplate,
"issuelinktypes": defaultDebugTemplate,
"list": defaultListTemplate,
"table": defaultTableTemplate,
"view": defaultViewTemplate,
"edit": defaultEditTemplate,
"transitions": defaultTransitionsTemplate,
"components": defaultComponentsTemplate,
"issuetypes": defaultIssuetypesTemplate,
"create": defaultCreateTemplate,
"subtask": defaultSubtaskTemplate,
"comment": defaultCommentTemplate,
"transition": defaultTransitionTemplate,
"component-add": defaultComponentAddTemplate,
"components": defaultComponentsTemplate,
"create": defaultCreateTemplate,
"createmeta": defaultDebugTemplate,
"debug": defaultDebugTemplate,
"edit": defaultEditTemplate,
"editmeta": defaultDebugTemplate,
"fields": defaultDebugTemplate,
"issuelinktypes": defaultDebugTemplate,
"issuetypes": defaultIssuetypesTemplate,
"json": defaultDebugTemplate,
"list": defaultListTemplate,
"request": defaultDebugTemplate,
"subtask": defaultSubtaskTemplate,
"table": defaultTableTemplate,
"transition": defaultTransitionTemplate,
"transitions": defaultTransitionsTemplate,
"transmeta": defaultDebugTemplate,
"view": defaultViewTemplate,
"worklog": defaultWorklogTemplate,
"worklogs": defaultWorklogsTemplate,
}
@@ -449,12 +484,13 @@ const defaultWorklogTemplate = `{{/* worklog template */ -}}
comment: |~
{{ or .comment "" }}
timeSpent: {{ or .timeSpent "" }}
started:
started: {{ or .started "" }}
`
const defaultWorklogsTemplate = `{{/* worklogs template */ -}}
{{ range .worklogs }}- # {{.author.name}}, {{.created | age}} ago
comment: {{ or .comment "" }}
started: {{ .started }}
timeSpent: {{ .timeSpent }}
{{end}}`
+2 -1
View File
@@ -37,6 +37,7 @@ func CmdComponentsRegistry() *jiracli.CommandRegistryEntry {
func CmdComponentsUsage(cmd *kingpin.CmdClause, opts *ComponentsOptions) error {
jiracli.TemplateUsage(cmd, &opts.CommonOptions)
jiracli.GJsonQueryUsage(cmd, &opts.CommonOptions)
cmd.Flag("project", "project to list components").Short('p').StringVar(&opts.Project)
return nil
@@ -51,5 +52,5 @@ func CmdComponents(o *oreo.Client, globals *jiracli.GlobalOptions, opts *Compone
if err != nil {
return err
}
return jiracli.RunTemplate(opts.Template.Value, data, nil)
return opts.PrintTemplate(data)
}
+2 -1
View File
@@ -35,6 +35,7 @@ func CmdCreateMetaRegistry() *jiracli.CommandRegistryEntry {
func CmdCreateMetaUsage(cmd *kingpin.CmdClause, opts *CreateMetaOptions) error {
jiracli.TemplateUsage(cmd, &opts.CommonOptions)
jiracli.GJsonQueryUsage(cmd, &opts.CommonOptions)
cmd.Flag("project", "project to fetch create metadata").Short('p').StringVar(&opts.Project)
cmd.Flag("issuetype", "issuetype in project to fetch create metadata").Short('i').StringVar(&opts.IssueType)
return nil
@@ -49,5 +50,5 @@ func CmdCreateMeta(o *oreo.Client, globals *jiracli.GlobalOptions, opts *CreateM
if err != nil {
return err
}
return jiracli.RunTemplate(opts.Template.Value, createMeta, nil)
return opts.PrintTemplate(createMeta)
}
+12 -2
View File
@@ -18,6 +18,7 @@ type EditOptions struct {
jira.SearchOptions `yaml:",inline" json:",inline" figtree:",inline"`
Overrides map[string]string `yaml:"overrides,omitempty" json:"overrides,omitempty"`
Issue string `yaml:"issue,omitempty" json:"issue,omitempty"`
Queries map[string]string `yaml:"queries,omitempty" json:"queries,omitempty"`
}
func CmdEditRegistry() *jiracli.CommandRegistryEntry {
@@ -32,7 +33,7 @@ func CmdEditRegistry() *jiracli.CommandRegistryEntry {
"Edit issue details",
func(fig *figtree.FigTree, cmd *kingpin.CmdClause) error {
jiracli.LoadConfigs(cmd, fig, &opts)
return CmdEditUsage(cmd, &opts)
return CmdEditUsage(cmd, &opts, fig)
},
func(o *oreo.Client, globals *jiracli.GlobalOptions) error {
return CmdEdit(o, globals, &opts)
@@ -40,11 +41,20 @@ func CmdEditRegistry() *jiracli.CommandRegistryEntry {
}
}
func CmdEditUsage(cmd *kingpin.CmdClause, opts *EditOptions) error {
func CmdEditUsage(cmd *kingpin.CmdClause, opts *EditOptions, fig *figtree.FigTree) error {
jiracli.BrowseUsage(cmd, &opts.CommonOptions)
jiracli.EditorUsage(cmd, &opts.CommonOptions)
jiracli.TemplateUsage(cmd, &opts.CommonOptions)
cmd.Flag("noedit", "Disable opening the editor").SetValue(&opts.SkipEditing)
cmd.Flag("named-query", "The name of a query in the `queries` configuration").Short('n').PreAction(func(ctx *kingpin.ParseContext) error {
name := jiracli.FlagValue(ctx, "named-query")
if query, ok := opts.Queries[name]; ok && query != "" {
var err error
opts.Query, err = jiracli.ConfigTemplate(fig, query, cmd.FullCommand(), opts)
return err
}
return fmt.Errorf("A valid named-query %q not found in `queries` configuration", name)
}).String()
cmd.Flag("query", "Jira Query Language (JQL) expression for the search to edit multiple issues").Short('q').StringVar(&opts.Query)
cmd.Flag("comment", "Comment message for issue").Short('m').PreAction(func(ctx *kingpin.ParseContext) error {
opts.Overrides["comment"] = jiracli.FlagValue(ctx, "comment")
+2 -1
View File
@@ -36,6 +36,7 @@ func CmdEditMetaRegistry() *jiracli.CommandRegistryEntry {
func CmdEditMetaUsage(cmd *kingpin.CmdClause, opts *EditMetaOptions) error {
jiracli.BrowseUsage(cmd, &opts.CommonOptions)
jiracli.TemplateUsage(cmd, &opts.CommonOptions)
jiracli.GJsonQueryUsage(cmd, &opts.CommonOptions)
cmd.Arg("ISSUE", "edit metadata for issue id").Required().StringVar(&opts.Issue)
return nil
}
@@ -46,7 +47,7 @@ func CmdEditMeta(o *oreo.Client, globals *jiracli.GlobalOptions, opts *EditMetaO
if err != nil {
return err
}
if err := jiracli.RunTemplate(opts.Template.Value, editMeta, nil); err != nil {
if err := opts.PrintTemplate(editMeta); err != nil {
return err
}
if opts.Browse.Value {
+2 -1
View File
@@ -17,6 +17,7 @@ func CmdFieldsRegistry() *jiracli.CommandRegistryEntry {
func(fig *figtree.FigTree, cmd *kingpin.CmdClause) error {
jiracli.LoadConfigs(cmd, fig, &opts)
jiracli.TemplateUsage(cmd, &opts)
jiracli.GJsonQueryUsage(cmd, &opts)
return nil
},
func(o *oreo.Client, globals *jiracli.GlobalOptions) error {
@@ -31,5 +32,5 @@ func CmdFields(o *oreo.Client, globals *jiracli.GlobalOptions, opts *jiracli.Com
if err != nil {
return err
}
return jiracli.RunTemplate(opts.Template.Value, data, nil)
return opts.PrintTemplate(data)
}
+2 -1
View File
@@ -27,6 +27,7 @@ func CmdIssueLinkTypesRegistry() *jiracli.CommandRegistryEntry {
func CmdIssueLinkTypesUsage(cmd *kingpin.CmdClause, opts *jiracli.CommonOptions) error {
jiracli.TemplateUsage(cmd, opts)
jiracli.GJsonQueryUsage(cmd, opts)
return nil
}
@@ -36,5 +37,5 @@ func CmdIssueLinkTypes(o *oreo.Client, globals *jiracli.GlobalOptions, opts *jir
if err != nil {
return err
}
return jiracli.RunTemplate(opts.Template.Value, data, nil)
return opts.PrintTemplate(data)
}
+2 -1
View File
@@ -37,6 +37,7 @@ func CmdIssueTypesRegistry() *jiracli.CommandRegistryEntry {
func CmdIssueTypesUsage(cmd *kingpin.CmdClause, opts *IssueTypesOptions) error {
jiracli.TemplateUsage(cmd, &opts.CommonOptions)
jiracli.GJsonQueryUsage(cmd, &opts.CommonOptions)
cmd.Flag("project", "project to list issueTypes").Short('p').StringVar(&opts.Project)
return nil
@@ -51,5 +52,5 @@ func CmdIssueTypes(o *oreo.Client, globals *jiracli.GlobalOptions, opts *IssueTy
if err != nil {
return err
}
return jiracli.RunTemplate(opts.Template.Value, data, nil)
return opts.PrintTemplate(data)
}
+17 -3
View File
@@ -1,6 +1,8 @@
package jiracmd
import (
"fmt"
"github.com/coryb/figtree"
"github.com/coryb/oreo"
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
@@ -11,6 +13,7 @@ import (
type ListOptions struct {
jiracli.CommonOptions `yaml:",inline" json:",inline" figtree:",inline"`
jira.SearchOptions `yaml:",inline" json:",inline" figtree:",inline"`
Queries map[string]string `yaml:"queries,omitempty" json:"queries,omitempty"`
}
func CmdListRegistry() *jiracli.CommandRegistryEntry {
@@ -33,7 +36,7 @@ func CmdListRegistry() *jiracli.CommandRegistryEntry {
if opts.Sort == "" {
opts.Sort = "priority asc, key"
}
return CmdListUsage(cmd, &opts)
return CmdListUsage(cmd, &opts, fig)
},
func(o *oreo.Client, globals *jiracli.GlobalOptions) error {
return CmdList(o, globals, &opts)
@@ -41,16 +44,27 @@ func CmdListRegistry() *jiracli.CommandRegistryEntry {
}
}
func CmdListUsage(cmd *kingpin.CmdClause, opts *ListOptions) error {
func CmdListUsage(cmd *kingpin.CmdClause, opts *ListOptions, fig *figtree.FigTree) error {
jiracli.TemplateUsage(cmd, &opts.CommonOptions)
jiracli.GJsonQueryUsage(cmd, &opts.CommonOptions)
cmd.Flag("assignee", "User assigned the issue").Short('a').StringVar(&opts.Assignee)
cmd.Flag("component", "Component to search for").Short('c').StringVar(&opts.Component)
cmd.Flag("issuetype", "Issue type to search for").Short('i').StringVar(&opts.IssueType)
cmd.Flag("limit", "Maximum number of results to return in search").Short('l').IntVar(&opts.MaxResults)
cmd.Flag("project", "Project to search for").Short('p').StringVar(&opts.Project)
cmd.Flag("named-query", "The name of a query in the `queries` configuration").Short('n').PreAction(func(ctx *kingpin.ParseContext) error {
name := jiracli.FlagValue(ctx, "named-query")
if query, ok := opts.Queries[name]; ok && query != "" {
var err error
opts.Query, err = jiracli.ConfigTemplate(fig, query, cmd.FullCommand(), opts)
return err
}
return fmt.Errorf("A valid named-query %q not found in `queries` configuration", name)
}).String()
cmd.Flag("query", "Jira Query Language (JQL) expression for the search").Short('q').StringVar(&opts.Query)
cmd.Flag("queryfields", "Fields that are used in \"list\" template").Short('f').StringVar(&opts.QueryFields)
cmd.Flag("reporter", "Reporter to search for").Short('r').StringVar(&opts.Reporter)
cmd.Flag("status", "Filter on issue status").Short('S').StringVar(&opts.Status)
cmd.Flag("sort", "Sort order to return").Short('s').StringVar(&opts.Sort)
cmd.Flag("watcher", "Watcher to search for").Short('w').StringVar(&opts.Watcher)
return nil
@@ -62,5 +76,5 @@ func CmdList(o *oreo.Client, globals *jiracli.GlobalOptions, opts *ListOptions)
if err != nil {
return err
}
return jiracli.RunTemplate(opts.Template.Value, data, nil)
return opts.PrintTemplate(data)
}
+3 -1
View File
@@ -35,6 +35,8 @@ func CmdRequestRegistry() *jiracli.CommandRegistryEntry {
if opts.Method == "" {
opts.Method = "GET"
}
jiracli.TemplateUsage(cmd, &opts.CommonOptions)
jiracli.GJsonQueryUsage(cmd, &opts.CommonOptions)
return CmdRequestUsage(cmd, &opts)
},
func(o *oreo.Client, globals *jiracli.GlobalOptions) error {
@@ -89,5 +91,5 @@ func CmdRequest(o *oreo.Client, globals *jiracli.GlobalOptions, opts *RequestOpt
return fmt.Errorf("JSON Parse Error: %s from %q", err, content)
}
return jiracli.RunTemplate(opts.Template.Value, &data, nil)
return opts.PrintTemplate(&data)
}
+9
View File
@@ -133,6 +133,15 @@ func CmdTransition(o *oreo.Client, globals *jiracli.GlobalOptions, opts *Transit
Overrides map[string]string `yaml:"overrides,omitempty" json:"overrides,omitempty"`
}
if _, ok := transMeta.Fields["comment"]; !ok && opts.Overrides["comment"] != "" {
comment := jiradata.Comment{
Body: opts.Overrides["comment"],
}
if _, err := jira.IssueAddComment(o, globals.Endpoint.Value, opts.Issue, &comment); err != nil {
return err
}
}
issueUpdate := jiradata.IssueUpdate{}
input := templateInput{
Issue: issueData,
+2 -1
View File
@@ -35,6 +35,7 @@ func CmdTransitionsRegistry(defaultTemplate string) *jiracli.CommandRegistryEntr
func CmdTransitionsUsage(cmd *kingpin.CmdClause, opts *TransitionsOptions) error {
jiracli.BrowseUsage(cmd, &opts.CommonOptions)
jiracli.TemplateUsage(cmd, &opts.CommonOptions)
jiracli.GJsonQueryUsage(cmd, &opts.CommonOptions)
cmd.Arg("ISSUE", "issue to list valid transitions").Required().StringVar(&opts.Issue)
return nil
}
@@ -45,7 +46,7 @@ func CmdTransitions(o *oreo.Client, globals *jiracli.GlobalOptions, opts *Transi
if err != nil {
return err
}
if err := jiracli.RunTemplate(opts.Template.Value, editMeta, nil); err != nil {
if err := opts.PrintTemplate(editMeta); err != nil {
return err
}
if opts.Browse.Value {
+2 -1
View File
@@ -36,6 +36,7 @@ func CmdViewRegistry() *jiracli.CommandRegistryEntry {
func CmdViewUsage(cmd *kingpin.CmdClause, opts *ViewOptions) error {
jiracli.BrowseUsage(cmd, &opts.CommonOptions)
jiracli.TemplateUsage(cmd, &opts.CommonOptions)
jiracli.GJsonQueryUsage(cmd, &opts.CommonOptions)
cmd.Flag("expand", "field to expand for the issue").StringsVar(&opts.Expand)
cmd.Flag("field", "field to return for the issue").StringsVar(&opts.Fields)
cmd.Flag("property", "property to return for issue").StringsVar(&opts.Properties)
@@ -49,7 +50,7 @@ func CmdView(o *oreo.Client, globals *jiracli.GlobalOptions, opts *ViewOptions)
if err != nil {
return err
}
if err := jiracli.RunTemplate(opts.Template.Value, data, nil); err != nil {
if err := opts.PrintTemplate(data); err != nil {
return err
}
if opts.Browse.Value {
+1
View File
@@ -42,6 +42,7 @@ func CmdWorklogAddUsage(cmd *kingpin.CmdClause, opts *WorklogAddOptions) error {
cmd.Flag("noedit", "Disable opening the editor").SetValue(&opts.SkipEditing)
cmd.Flag("comment", "Comment message for worklog").Short('m').StringVar(&opts.Comment)
cmd.Flag("time-spent", "Time spent working on issue").Short('T').StringVar(&opts.TimeSpent)
cmd.Flag("started", "Time you started work").Short('S').StringVar(&opts.Started)
cmd.Arg("ISSUE", "issue id to fetch worklogs").Required().StringVar(&opts.Issue)
return nil
}
+3 -2
View File
@@ -35,6 +35,7 @@ func CmdWorklogListRegistry() *jiracli.CommandRegistryEntry {
func CmdWorklogListUsage(cmd *kingpin.CmdClause, opts *WorklogListOptions) error {
jiracli.BrowseUsage(cmd, &opts.CommonOptions)
jiracli.TemplateUsage(cmd, &opts.CommonOptions)
jiracli.GJsonQueryUsage(cmd, &opts.CommonOptions)
cmd.Arg("ISSUE", "issue id to fetch worklogs").Required().StringVar(&opts.Issue)
return nil
}
@@ -45,9 +46,9 @@ func CmdWorklogList(o *oreo.Client, globals *jiracli.GlobalOptions, opts *Worklo
if err != nil {
return err
}
if err := jiracli.RunTemplate(opts.Template.Value, struct {
if err := opts.PrintTemplate(struct {
Worklogs *jiradata.Worklogs `json:"worklogs,omitempty" yaml:"worklogs,omitempty"`
}{data}, nil); err != nil {
}{data}); err != nil {
return err
}
if opts.Browse.Value {
+14 -10
View File
@@ -14,16 +14,17 @@ type SearchProvider interface {
}
type SearchOptions struct {
Assignee string
Query string
QueryFields string
Project string
Component string
IssueType string
Watcher string
Reporter string
Sort string
MaxResults int
Assignee string `yaml:"assignee,omitempty" json:"assignee,omitempty"`
Query string `yaml:"query,omitempty" json:"query,omitempty"`
QueryFields string `yaml:"query-fields,omitempty" json:"query-fields,omitempty"`
Project string `yaml:"project,omitempty" json:"project,omitempty"`
Component string `yaml:"component,omitempty" json:"component,omitempty"`
IssueType string `yaml:"issue-type,omitempty" json:"issue-type,omitempty"`
Watcher string `yaml:"watcher,omitempty" json:"watcher,omitempty"`
Reporter string `yaml:"reporter,omitempty" json:"reporter,omitempty"`
Status string `yaml:"status,omitempty" json:"status,omitempty"`
Sort string `yaml:"sort,omitempty" json:"sort,omitempty"`
MaxResults int `yaml:"max-results,omitempty" json:"max-results,omitempty"`
}
func (o *SearchOptions) ProvideSearchRequest() *jiradata.SearchRequest {
@@ -49,6 +50,9 @@ func (o *SearchOptions) ProvideSearchRequest() *jiradata.SearchRequest {
if o.Reporter != "" {
qbuff.WriteString(fmt.Sprintf(" AND reporter = '%s'", o.Reporter))
}
if o.Status != "" {
qbuff.WriteString(fmt.Sprintf(" AND status = '%s'", o.Status))
}
if o.Sort != "" {
qbuff.WriteString(fmt.Sprintf(" ORDER BY %s", o.Sort))
}
+39
View File
@@ -3,3 +3,42 @@ config:
password-source: pass
endpoint: https://go-jira.atlassian.net
user: gojira
project: BASIC
custom-commands:
- name: env
help: print the JIRA environment variables available to custom commands
script: |-
env | sort | grep JIRA
- name: print-project
help: print the name of the configured project
script: "echo $JIRA_PROJECT"
- name: jira-path
help: print the path the jira command that is running this alias
script: |-
echo {{jira}}
- name: mine
help: display issues assigned to me
script: |-
if [ -n "$JIRA_PROJECT" ]; then
# if `project: ...` configured just list the issues for current project
{{jira}} list --template table --query "resolution = unresolved and assignee=currentuser() and project = $JIRA_PROJECT ORDER BY priority asc, created"
else
# otherwise list issues for all project
{{jira}} list --template table --query "resolution = unresolved and assignee=currentuser() ORDER BY priority asc, created"
fi
- name: argtest
help: testing passing args
script: |-
echo {{args.ARG}}
args:
- name: ARG
help: string to echo for testing
- name: opttest
help: testing passing option flags
script: |-
echo {{options.OPT}}
options:
- name: OPT
help: string to echo for testing
+2
View File
@@ -3,6 +3,8 @@ eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
cd $(dirname $0)
jira="../jira --user admin"
. env.sh
SKIP test -n "$JIRACLOUD" # using Jira Cloud at go-jira.atlassian.net
PLAN 15
+1
View File
@@ -2,6 +2,7 @@
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
cd $(dirname $0)
jira=../jira
. env.sh
SKIP test -n "$JIRACLOUD" # using Jira Cloud at go-jira.atlassian.net
+1 -7
View File
@@ -2,13 +2,7 @@
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
cd $(dirname $0)
jira="../jira"
export JIRA_LOG_FORMAT="%{level:-5s} %{message}"
export COLUMNS=149
ENDPOINT="http://localhost:8080"
if [ -n "$JIRACLOUD" ]; then
ENDPOINT="https://go-jira.atlassian.net"
fi
. env.sh
PLAN 86
+3 -7
View File
@@ -2,12 +2,7 @@
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
cd $(dirname $0)
jira="../jira"
export JIRA_LOG_FORMAT="%{level:-5s} %{message}"
ENDPOINT="http://localhost:8080"
if [ -n "$JIRACLOUD" ]; then
ENDPOINT="https://go-jira.atlassian.net"
fi
. env.sh
PLAN 8
@@ -31,7 +26,7 @@ EOF
###############################################################################
## Add a worklog to an issue
###############################################################################
RUNS $jira worklog add $issue --comment "work is hard" --time-spent "1h 12m" --noedit
RUNS $jira worklog add $issue --comment "work is hard" --time-spent "1h 12m" -S "2017-01-29T09:17:00.000-0500" --noedit
DIFF <<EOF
OK $issue $ENDPOINT/browse/$issue
EOF
@@ -43,6 +38,7 @@ RUNS $jira worklog $issue
DIFF <<EOF
- # gojira, a minute ago
comment: work is hard
started: 2017-01-29T06:17:00.000-0800
timeSpent: 1h 12m
EOF
+88
View File
@@ -0,0 +1,88 @@
#!/bin/bash
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
cd $(dirname $0)
jira="../jira"
. env.sh
PLAN 16
# reset login
RUNS $jira logout
RUNS $jira login
# cleanup from previous failed test executions
($jira ls --project BASIC | awk -F: '{print $1}' | while read issue; do ../jira done $issue; done) | sed 's/^/# CLEANUP: /g'
###############################################################################
## Create an issue
###############################################################################
RUNS $jira create --project BASIC -o summary=summary -o description=description --noedit --saveFile issue.props
issue=$(awk '/issue/{print $2}' issue.props)
DIFF <<EOF
OK $issue $ENDPOINT/browse/$issue
EOF
###############################################################################
## Testing the example custom commands, print-project
###############################################################################
RUNS $jira print-project
DIFF <<EOF
BASIC
EOF
###############################################################################
## Testing the example custom commands, jira-path
###############################################################################
RUNS $jira jira-path
DIFF <<EOF
../jira
EOF
###############################################################################
## Testing the example custom commands, env
###############################################################################
RUNS $jira env
DIFF <<'EOF'
JIRACLOUD=1
JIRA_CUSTOM_COMMANDS=[{"name":"env","script":"env | sort | grep JIRA","help":"print the JIRA environment variables available to custom commands"},{"name":"print-project","script":"echo $JIRA_PROJECT","help":"print the name of the configured project"},{"name":"jira-path","script":"echo {{jira}}","help":"print the path the jira command that is running this alias"},{"name":"mine","script":"if [ -n \"$JIRA_PROJECT\" ]; then\n # if `project: ...` configured just list the issues for current project\n {{jira}} list --template table --query \"resolution = unresolved and assignee=currentuser() and project = $JIRA_PROJECT ORDER BY priority asc, created\"\nelse\n # otherwise list issues for all project\n {{jira}} list --template table --query \"resolution = unresolved and assignee=currentuser() ORDER BY priority asc, created\"\nfi","help":"display issues assigned to me"},{"name":"argtest","args":[{"name":"ARG","help":"string to echo for testing"}],"script":"echo {{args.ARG}}","help":"testing passing args"},{"name":"opttest","options":[{"name":"OPT","help":"string to echo for testing"}],"script":"echo {{options.OPT}}","help":"testing passing option flags"}]
JIRA_ENDPOINT=https://go-jira.atlassian.net
JIRA_LOG_FORMAT=%{level:-5s} %{message}
JIRA_PASSWORD_SOURCE=pass
JIRA_PROJECT=BASIC
JIRA_USER=gojira
EOF
###############################################################################
## Testing the example custom commands, argtest
###############################################################################
RUNS $jira argtest TEST
DIFF <<EOF
TEST
EOF
###############################################################################
## Testing the example custom commands, opttest
###############################################################################
RUNS $jira opttest --OPT TEST
DIFF <<EOF
TEST
EOF
###############################################################################
## Use the "mine" alias to list issues assigned to self
###############################################################################
RUNS $jira mine
DIFF <<EOF
+----------------+---------------------------------------------------------+--------------+--------------+------------+--------------+--------------+
| Issue | Summary | Priority | Status | Age | Reporter | Assignee |
+----------------+---------------------------------------------------------+--------------+--------------+------------+--------------+--------------+
| $(printf %-14s $issue) | summary | Medium | To Do | a minute | gojira | gojira |
+----------------+---------------------------------------------------------+--------------+--------------+------------+--------------+--------------+
EOF
+1 -6
View File
@@ -2,12 +2,7 @@
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
cd $(dirname $0)
jira="../jira"
export JIRA_LOG_FORMAT="%{level:-5s} %{message}"
ENDPOINT="http://localhost:8080"
if [ -n "$JIRACLOUD" ]; then
ENDPOINT="https://go-jira.atlassian.net"
fi
. env.sh
PLAN 84
+1 -6
View File
@@ -2,12 +2,7 @@
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
cd $(dirname $0)
jira="../jira"
export JIRA_LOG_FORMAT="%{level:-5s} %{message}"
ENDPOINT="http://localhost:8080"
if [ -n "$JIRACLOUD" ]; then
ENDPOINT="https://go-jira.atlassian.net"
fi
. env.sh
PLAN 86
+1 -6
View File
@@ -2,12 +2,7 @@
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
cd $(dirname $0)
jira="../jira"
export JIRA_LOG_FORMAT="%{level:-5s} %{message}"
ENDPOINT="http://localhost:8080"
if [ -n "$JIRACLOUD" ]; then
ENDPOINT="https://go-jira.atlassian.net"
fi
. env.sh
PLAN 84
+1 -6
View File
@@ -2,12 +2,7 @@
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
cd $(dirname $0)
jira="../jira"
export JIRA_LOG_FORMAT="%{level:-5s} %{message}"
ENDPOINT="http://localhost:8080"
if [ -n "$JIRACLOUD" ]; then
ENDPOINT="https://go-jira.atlassian.net"
fi
. env.sh
PLAN 84
+1 -6
View File
@@ -2,12 +2,7 @@
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
cd $(dirname $0)
jira="../jira"
export JIRA_LOG_FORMAT="%{level:-5s} %{message}"
ENDPOINT="http://localhost:8080"
if [ -n "$JIRACLOUD" ]; then
ENDPOINT="https://go-jira.atlassian.net"
fi
. env.sh
PLAN 82
+7
View File
@@ -0,0 +1,7 @@
export COLUMNS=149
export JIRA_LOG_FORMAT="%{level:-5s} %{message}"
export ENDPOINT="https://go-jira.atlassian.net"
export GNUPGHOME=$(pwd)/.gnupg
export PASSWORD_STORE_DIR=$(pwd)/.password-store
export JIRACLOUD=1
-2
View File
@@ -1,2 +0,0 @@
{{define "x"}}TEXT{{end}}
{{define "dotV"}}{{.V}}{{end}}
-2
View File
@@ -1,2 +0,0 @@
{{define "dot"}}{{.}}{{end}}
{{define "nested"}}{{template "dot" .}}{{end}}
-3
View File
@@ -1,3 +0,0 @@
template1
{{define "x"}}x{{end}}
{{template "y"}}
-3
View File
@@ -1,3 +0,0 @@
template2
{{define "y"}}y{{end}}
{{template "x"}}
-12
View File
@@ -1,12 +0,0 @@
package math
import "github.com/cheekybits/genny/generic"
type ThisNumberType generic.Number
func ThisNumberTypeMax(fn func(a, b ThisNumberType) bool, a, b ThisNumberType) ThisNumberType {
if fn(a, b) {
return a
}
return b
}
-3
View File
@@ -1,3 +0,0 @@
#!/bin/bash
cat ./generic_max.go | ../../genny gen "NumberType=NUMBERS" > numbers_max_get.go
cat ./func_thing.go | ../../genny gen "ThisNumberType=NUMBERS" > numbers_func_thing.go
-14
View File
@@ -1,14 +0,0 @@
package math
import "github.com/cheekybits/genny/generic"
type NumberType generic.Number
// NumberTypeMax gets the maximum number from the
// two specified.
func NumberTypeMax(a, b NumberType) NumberType {
if a > b {
return a
}
return b
}
-27
View File
@@ -1,27 +0,0 @@
package math_test
import (
"testing"
"github.com/cheekybits/genny/examples/davechaney"
)
func TestNumberTypeMax(t *testing.T) {
var v math.NumberType
v = math.NumberTypeMax(10, 20)
if v != 20 {
t.Errorf("Max of 10 and 20 is 20")
}
v = math.NumberTypeMax(20, 20)
if v != 20 {
t.Errorf("Max of 20 and 20 is 20")
}
v = math.NumberTypeMax(25, 20)
if v != 25 {
t.Errorf("Max of 25 and 20 is 25")
}
}
@@ -1,89 +0,0 @@
// This file was automatically generated by genny.
// Any changes will be lost if this file is regenerated.
// see https://github.com/cheekybits/genny
package math
func Float32Max(fn func(a, b float32) bool, a, b float32) float32 {
if fn(a, b) {
return a
}
return b
}
func Float64Max(fn func(a, b float64) bool, a, b float64) float64 {
if fn(a, b) {
return a
}
return b
}
func IntMax(fn func(a, b int) bool, a, b int) int {
if fn(a, b) {
return a
}
return b
}
func Int16Max(fn func(a, b int16) bool, a, b int16) int16 {
if fn(a, b) {
return a
}
return b
}
func Int32Max(fn func(a, b int32) bool, a, b int32) int32 {
if fn(a, b) {
return a
}
return b
}
func Int64Max(fn func(a, b int64) bool, a, b int64) int64 {
if fn(a, b) {
return a
}
return b
}
func Int8Max(fn func(a, b int8) bool, a, b int8) int8 {
if fn(a, b) {
return a
}
return b
}
func UintMax(fn func(a, b uint) bool, a, b uint) uint {
if fn(a, b) {
return a
}
return b
}
func Uint16Max(fn func(a, b uint16) bool, a, b uint16) uint16 {
if fn(a, b) {
return a
}
return b
}
func Uint32Max(fn func(a, b uint32) bool, a, b uint32) uint32 {
if fn(a, b) {
return a
}
return b
}
func Uint64Max(fn func(a, b uint64) bool, a, b uint64) uint64 {
if fn(a, b) {
return a
}
return b
}
func Uint8Max(fn func(a, b uint8) bool, a, b uint8) uint8 {
if fn(a, b) {
return a
}
return b
}
@@ -1,29 +0,0 @@
// This file was automatically generated by genny.
// Any changes will be lost if this file is regenerated.
// see https://github.com/cheekybits/genny
package gogenerate
type StringStringMap map[string]string
func NewStringStringMap() map[string]string {
return make(map[string]string)
}
type StringIntMap map[string]int
func NewStringIntMap() map[string]int {
return make(map[string]int)
}
type IntStringMap map[int]string
func NewIntStringMap() map[int]string {
return make(map[int]string)
}
type IntIntMap map[int]int
func NewIntIntMap() map[int]int {
return make(map[int]int)
}
-14
View File
@@ -1,14 +0,0 @@
package gogenerate
import "github.com/cheekybits/genny/generic"
//go:generate genny -in=$GOFILE -out=gen-$GOFILE gen "KeyType=string,int ValueType=string,int"
type KeyType generic.Type
type ValueType generic.Type
type KeyTypeValueTypeMap map[KeyType]ValueType
func NewKeyTypeValueTypeMap() map[KeyType]ValueType {
return make(map[KeyType]ValueType)
}
-2
View File
@@ -1,2 +0,0 @@
#!/bin/bash
cat ./queue_generic.go | ../../genny gen "Generic=string,int" > queue_generic_gen.go
-33
View File
@@ -1,33 +0,0 @@
package example
import "github.com/cheekybits/genny/generic"
type Generic generic.Type
// GenericQueue represents a queue of Generic types.
type GenericQueue struct {
items []Generic
}
// NewGenericQueue makes a new empty Generic queue.
func NewGenericQueue() *GenericQueue {
return &GenericQueue{items: make([]Generic, 0)}
}
// Enq adds an item to the queue.
func (q *GenericQueue) Enq(obj Generic) *GenericQueue {
q.items = append(q.items, obj)
return q
}
// Deq removes and returns the next item in the queue.
func (q *GenericQueue) Deq() Generic {
obj := q.items[0]
q.items = q.items[1:]
return obj
}
// Len gets the current number of Generic items in the queue.
func (q *GenericQueue) Len() int {
return len(q.items)
}
@@ -1,32 +0,0 @@
package example
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestNew(t *testing.T) {
q := NewGenericQueue()
assert.NotNil(t, q)
}
func TestEnqueueAndDequeue(t *testing.T) {
item1 := new(Generic)
item2 := new(Generic)
q := NewGenericQueue()
assert.Equal(t, q, q.Enq(item1), "Enq should return the queue")
assert.Equal(t, 1, q.Len())
assert.Equal(t, q, q.Enq(item2), "Enq should return the queue")
assert.Equal(t, 2, q.Len())
assert.Equal(t, item1, q.Deq())
assert.Equal(t, 1, q.Len())
assert.Equal(t, item2, q.Deq())
assert.Equal(t, 0, q.Len())
}
-41
View File
@@ -1,41 +0,0 @@
package parse
// Builtins contains a slice of all built-in Go types.
var Builtins = []string{
"bool",
"byte",
"complex128",
"complex64",
"error",
"float32",
"float64",
"int",
"int16",
"int32",
"int64",
"int8",
"rune",
"string",
"uint",
"uint16",
"uint32",
"uint64",
"uint8",
"uintptr",
}
// Numbers contains a slice of all built-in number types.
var Numbers = []string{
"float32",
"float64",
"int",
"int16",
"int32",
"int64",
"int8",
"uint",
"uint16",
"uint32",
"uint64",
"uint8",
}
-14
View File
@@ -1,14 +0,0 @@
// Package parse contains the generic code generation capabilities
// that power genny.
//
// genny gen "{types}"
//
// gen - generates type specific code (to stdout) from generic code (via stdin)
//
// {types} - (required) Specific types for each generic type in the source
// {types} format: {generic}={specific}[,another][ {generic2}={specific2}]
// Examples:
// Generic=Specific
// Generic1=Specific1 Generic2=Specific2
// Generic1=Specific1,Specific2 Generic2=Specific3,Specific4
package parse
-47
View File
@@ -1,47 +0,0 @@
package parse
import (
"errors"
)
// errMissingSpecificType represents an error when a generic type is not
// satisfied by a specific type.
type errMissingSpecificType struct {
GenericType string
}
// Error gets a human readable string describing this error.
func (e errMissingSpecificType) Error() string {
return "Missing specific type for '" + e.GenericType + "' generic type"
}
// errImports represents an error from goimports.
type errImports struct {
Err error
}
// Error gets a human readable string describing this error.
func (e errImports) Error() string {
return "Failed to goimports the generated code: " + e.Err.Error()
}
// errSource represents an error with the source file.
type errSource struct {
Err error
}
// Error gets a human readable string describing this error.
func (e errSource) Error() string {
return "Failed to parse source file: " + e.Err.Error()
}
type errBadTypeArgs struct {
Message string
Arg string
}
func (e errBadTypeArgs) Error() string {
return "\"" + e.Arg + "\" is bad: " + e.Message
}
var errMissingTypeInformation = errors.New("No type arguments were specified and no \"// +gogen\" tag was found in the source.")
-271
View File
@@ -1,271 +0,0 @@
package parse
import (
"bufio"
"bytes"
"fmt"
"go/ast"
"go/parser"
"go/token"
"io"
"os"
"strings"
"unicode"
"golang.org/x/tools/imports"
)
type isExported bool
var header = []byte(`
// This file was automatically generated by genny.
// Any changes will be lost if this file is regenerated.
// see https://github.com/cheekybits/genny
`)
var (
packageKeyword = []byte("package")
importKeyword = []byte("import")
openBrace = []byte("(")
closeBrace = []byte(")")
space = " "
genericPackage = "generic"
genericType = "generic.Type"
genericNumber = "generic.Number"
linefeed = "\r\n"
)
var unwantedLinePrefixes = [][]byte{
[]byte("//go:generate genny "),
}
func generateSpecific(filename string, in io.ReadSeeker, typeSet map[string]string) ([]byte, error) {
// ensure we are at the beginning of the file
in.Seek(0, os.SEEK_SET)
// parse the source file
fs := token.NewFileSet()
file, err := parser.ParseFile(fs, filename, in, 0)
if err != nil {
return nil, &errSource{Err: err}
}
// make sure every generic.Type is represented in the types
// argument.
for _, decl := range file.Decls {
switch it := decl.(type) {
case *ast.GenDecl:
for _, spec := range it.Specs {
ts, ok := spec.(*ast.TypeSpec)
if !ok {
continue
}
switch tt := ts.Type.(type) {
case *ast.SelectorExpr:
if name, ok := tt.X.(*ast.Ident); ok {
if name.Name == genericPackage {
if _, ok := typeSet[ts.Name.Name]; !ok {
return nil, &errMissingSpecificType{GenericType: ts.Name.Name}
}
}
}
}
}
}
}
// go back to the start of the file
in.Seek(0, os.SEEK_SET)
var buf bytes.Buffer
comment := ""
scanner := bufio.NewScanner(in)
for scanner.Scan() {
l := scanner.Text()
// does this line contain generic.Type?
if strings.Contains(l, genericType) || strings.Contains(l, genericNumber) {
comment = ""
continue
}
for t, specificType := range typeSet {
// does the line contain our type
if strings.Contains(l, t) {
var newLine string
// check each word
for _, word := range strings.Fields(l) {
i := 0
for {
i = strings.Index(word[i:], t) // find out where
if i > -1 {
// if this isn't an exact match
if i > 0 && isAlphaNumeric(rune(word[i-1])) || i < len(word)-len(t) && isAlphaNumeric(rune(word[i+len(t)])) {
// replace the word with a capitolized version
word = strings.Replace(word, t, wordify(specificType, unicode.IsUpper(rune(strings.TrimLeft(word, "*&")[0]))), 1)
} else {
// replace the word as is
word = strings.Replace(word, t, specificType, 1)
}
} else {
newLine = newLine + word + space
break
}
}
}
l = newLine
}
}
if comment != "" {
buf.WriteString(line(comment))
comment = ""
}
// is this line a comment?
// TODO: should we handle /* */ comments?
if strings.HasPrefix(l, "//") {
// record this line to print later
comment = l
continue
}
// write the line
buf.WriteString(line(l))
}
// write it out
return buf.Bytes(), nil
}
// Generics parses the source file and generates the bytes replacing the
// generic types for the keys map with the specific types (its value).
func Generics(filename, pkgName string, in io.ReadSeeker, typeSets []map[string]string) ([]byte, error) {
totalOutput := header
for _, typeSet := range typeSets {
// generate the specifics
parsed, err := generateSpecific(filename, in, typeSet)
if err != nil {
return nil, err
}
totalOutput = append(totalOutput, parsed...)
}
// clean up the code line by line
packageFound := false
insideImportBlock := false
var cleanOutputLines []string
scanner := bufio.NewScanner(bytes.NewReader(totalOutput))
for scanner.Scan() {
// end of imports block?
if insideImportBlock {
if bytes.HasSuffix(scanner.Bytes(), closeBrace) {
insideImportBlock = false
}
continue
}
if bytes.HasPrefix(scanner.Bytes(), packageKeyword) {
if packageFound {
continue
} else {
packageFound = true
}
} else if bytes.HasPrefix(scanner.Bytes(), importKeyword) {
if bytes.HasSuffix(scanner.Bytes(), openBrace) {
insideImportBlock = true
}
continue
}
// check all unwantedLinePrefixes - and skip them
skipline := false
for _, prefix := range unwantedLinePrefixes {
if bytes.HasPrefix(scanner.Bytes(), prefix) {
skipline = true
continue
}
}
if skipline {
continue
}
cleanOutputLines = append(cleanOutputLines, line(scanner.Text()))
}
cleanOutput := strings.Join(cleanOutputLines, "")
output := []byte(cleanOutput)
var err error
// change package name
if pkgName != "" {
output = changePackage(bytes.NewReader([]byte(output)), pkgName)
}
// fix the imports
output, err = imports.Process(filename, output, nil)
if err != nil {
return nil, &errImports{Err: err}
}
return output, nil
}
func line(s string) string {
return fmt.Sprintln(strings.TrimRight(s, linefeed))
}
// isAlphaNumeric gets whether the rune is alphanumeric or _.
func isAlphaNumeric(r rune) bool {
return r == '_' || unicode.IsLetter(r) || unicode.IsDigit(r)
}
// wordify turns a type into a nice word for function and type
// names etc.
func wordify(s string, exported bool) string {
s = strings.TrimRight(s, "{}")
s = strings.TrimLeft(s, "*&")
s = strings.Replace(s, ".", "", -1)
if !exported {
return s
}
return strings.ToUpper(string(s[0])) + s[1:]
}
func changePackage(r io.Reader, pkgName string) []byte {
var out bytes.Buffer
sc := bufio.NewScanner(r)
done := false
for sc.Scan() {
s := sc.Text()
if !done && strings.HasPrefix(s, "package") {
parts := strings.Split(s, " ")
parts[1] = pkgName
s = strings.Join(parts, " ")
done = true
}
fmt.Fprintln(&out, s)
}
return out.Bytes()
}
-35
View File
@@ -1,35 +0,0 @@
package parse
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestIsAlphaNumeric(t *testing.T) {
for _, r := range []rune{'a', '1', '_', 'A', 'Z'} {
assert.True(t, isAlphaNumeric(r))
}
for _, r := range []rune{' ', '[', ']', '!', '"'} {
assert.False(t, isAlphaNumeric(r))
}
}
func TestWordify(t *testing.T) {
for word, wordified := range map[string]string{
"int": "Int",
"*int": "Int",
"string": "String",
"*MyType": "MyType",
"*myType": "MyType",
"interface{}": "Interface",
"pack.type": "Packtype",
"*pack.type": "Packtype",
} {
assert.Equal(t, wordified, wordify(word, true))
}
}
-126
View File
@@ -1,126 +0,0 @@
package parse_test
import (
"io/ioutil"
"log"
"strings"
"testing"
"github.com/cheekybits/genny/parse"
"github.com/stretchr/testify/assert"
)
var tests = []struct {
// input
filename string
pkgName string
in string
types []map[string]string
// expectations
expectedOut string
expectedErr error
}{
{
filename: "generic_queue.go",
in: `test/queue/generic_queue.go`,
types: []map[string]string{{"Something": "int"}},
expectedOut: `test/queue/int_queue.go`,
},
{
filename: "generic_queue.go",
pkgName: "changed",
in: `test/queue/generic_queue.go`,
types: []map[string]string{{"Something": "int"}},
expectedOut: `test/queue/changed/int_queue.go`,
},
{
filename: "generic_queue.go",
in: `test/queue/generic_queue.go`,
types: []map[string]string{{"Something": "float32"}},
expectedOut: `test/queue/float32_queue.go`,
},
{
filename: "generic_simplemap.go",
in: `test/multipletypes/generic_simplemap.go`,
types: []map[string]string{{"KeyType": "string", "ValueType": "int"}},
expectedOut: `test/multipletypes/string_int_simplemap.go`,
},
{
filename: "generic_simplemap.go",
in: `test/multipletypes/generic_simplemap.go`,
types: []map[string]string{{"KeyType": "interface{}", "ValueType": "int"}},
expectedOut: `test/multipletypes/interface_int_simplemap.go`,
},
{
filename: "generic_simplemap.go",
in: `test/multipletypes/generic_simplemap.go`,
types: []map[string]string{{"KeyType": "*MyType1", "ValueType": "*MyOtherType"}},
expectedOut: `test/multipletypes/custom_types_simplemap.go`,
},
{
filename: "generic_internal.go",
in: `test/unexported/generic_internal.go`,
types: []map[string]string{{"secret": "*myType"}},
expectedOut: `test/unexported/mytype_internal.go`,
},
{
filename: "generic_simplemap.go",
in: `test/multipletypesets/generic_simplemap.go`,
types: []map[string]string{
{"KeyType": "int", "ValueType": "string"},
{"KeyType": "float64", "ValueType": "bool"},
},
expectedOut: `test/multipletypesets/many_simplemaps.go`,
},
{
filename: "generic_number.go",
in: `test/numbers/generic_number.go`,
types: []map[string]string{{"NumberType": "int"}},
expectedOut: `test/numbers/int_number.go`,
},
{
filename: "generic_digraph.go",
in: `test/bugreports/generic_digraph.go`,
types: []map[string]string{{"Node": "int"}},
expectedOut: `test/bugreports/int_digraph.go`,
},
}
func TestParse(t *testing.T) {
for _, test := range tests {
test.in = contents(test.in)
test.expectedOut = contents(test.expectedOut)
bytes, err := parse.Generics(test.filename, test.pkgName, strings.NewReader(test.in), test.types)
// check the error
if test.expectedErr == nil {
assert.NoError(t, err, "(%s) No error was expected but got: %s", test.filename, err)
} else {
assert.NotNil(t, err, "(%s) No error was returned by one was expected: %s", test.filename, test.expectedErr)
assert.IsType(t, test.expectedErr, err, "(%s) Generate should return object of type %v", test.filename, test.expectedErr)
}
// assert the response
if !assert.Equal(t, string(bytes), test.expectedOut, "Parse didn't generate the expected output.") {
log.Println("EXPECTED: " + test.expectedOut)
log.Println("ACTUAL: " + string(bytes))
}
}
}
func contents(s string) string {
if strings.HasSuffix(s, "go") {
file, err := ioutil.ReadFile(s)
if err != nil {
panic(err)
}
return string(file)
}
return s
}
@@ -1,30 +0,0 @@
package bugreports
import "github.com/cheekybits/genny/generic"
type Node generic.Type
type DigraphNode struct {
nodes map[Node][]Node
}
func NewDigraphNode() *DigraphNode {
return &DigraphNode{
nodes: make(map[Node][]Node),
}
}
func (dig *DigraphNode) Add(n Node) {
if _, exists := dig.nodes[n]; exists {
return
}
dig.nodes[n] = nil
}
func (dig *DigraphNode) Connect(a, b Node) {
dig.Add(a)
dig.Add(b)
dig.nodes[a] = append(dig.nodes[a], b)
}
@@ -1,30 +0,0 @@
// This file was automatically generated by genny.
// Any changes will be lost if this file is regenerated.
// see https://github.com/cheekybits/genny
package bugreports
type DigraphInt struct {
nodes map[int][]int
}
func NewDigraphInt() *DigraphInt {
return &DigraphInt{
nodes: make(map[int][]int),
}
}
func (dig *DigraphInt) Add(n int) {
if _, exists := dig.nodes[n]; exists {
return
}
dig.nodes[n] = nil
}
func (dig *DigraphInt) Connect(a, b int) {
dig.Add(a)
dig.Add(b)
dig.nodes[a] = append(dig.nodes[a], b)
}
@@ -1,5 +0,0 @@
package multipletypes
type MyType1 struct{}
type MyOtherType struct{}
@@ -1,21 +0,0 @@
// This file was automatically generated by genny.
// Any changes will be lost if this file is regenerated.
// see https://github.com/cheekybits/genny
package multipletypes
type MyType1MyOtherTypeMap map[*MyType1]*MyOtherType
func (m MyType1MyOtherTypeMap) Has(key *MyType1) bool {
_, ok := m[key]
return ok
}
func (m MyType1MyOtherTypeMap) Get(key *MyType1) *MyOtherType {
return m[key]
}
func (m MyType1MyOtherTypeMap) Set(key *MyType1, value *MyOtherType) MyType1MyOtherTypeMap {
m[key] = value
return m
}
@@ -1,22 +0,0 @@
package multipletypes
import "github.com/cheekybits/genny/generic"
type KeyType generic.Type
type ValueType generic.Type
type KeyTypeValueTypeMap map[KeyType]ValueType
func (m KeyTypeValueTypeMap) Has(key KeyType) bool {
_, ok := m[key]
return ok
}
func (m KeyTypeValueTypeMap) Get(key KeyType) ValueType {
return m[key]
}
func (m KeyTypeValueTypeMap) Set(key KeyType, value ValueType) KeyTypeValueTypeMap {
m[key] = value
return m
}
@@ -1,35 +0,0 @@
package multipletypes
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestSimpleMap(t *testing.T) {
key1 := new(KeyType)
key2 := new(KeyType)
value1 := new(ValueType)
m := make(KeyTypeValueTypeMap)
assert.Equal(t, m, m.Set(key1, value1))
assert.True(t, m.Has(key1))
assert.False(t, m.Has(key2))
assert.Equal(t, value1, m.Get(key1))
}
func TestCustomTypesMap(t *testing.T) {
key1 := new(MyType1)
key2 := new(MyType1)
value1 := new(MyOtherType)
m := make(MyType1MyOtherTypeMap)
assert.Equal(t, m, m.Set(key1, value1))
assert.True(t, m.Has(key1))
assert.False(t, m.Has(key2))
assert.Equal(t, value1, m.Get(key1))
}
@@ -1,21 +0,0 @@
// This file was automatically generated by genny.
// Any changes will be lost if this file is regenerated.
// see https://github.com/cheekybits/genny
package multipletypes
type InterfaceIntMap map[interface{}]int
func (m InterfaceIntMap) Has(key interface{}) bool {
_, ok := m[key]
return ok
}
func (m InterfaceIntMap) Get(key interface{}) int {
return m[key]
}
func (m InterfaceIntMap) Set(key interface{}, value int) InterfaceIntMap {
m[key] = value
return m
}
@@ -1,21 +0,0 @@
// This file was automatically generated by genny.
// Any changes will be lost if this file is regenerated.
// see https://github.com/cheekybits/genny
package multipletypes
type StringIntMap map[string]int
func (m StringIntMap) Has(key string) bool {
_, ok := m[key]
return ok
}
func (m StringIntMap) Get(key string) int {
return m[key]
}
func (m StringIntMap) Set(key string, value int) StringIntMap {
m[key] = value
return m
}
@@ -1,27 +0,0 @@
package multipletypesets
import (
"log"
"github.com/cheekybits/genny/generic"
)
type KeyType generic.Type
type ValueType generic.Type
type KeyTypeValueTypeMap map[KeyType]ValueType
func (m KeyTypeValueTypeMap) Has(key KeyType) bool {
_, ok := m[key]
return ok
}
func (m KeyTypeValueTypeMap) Get(key KeyType) ValueType {
return m[key]
}
func (m KeyTypeValueTypeMap) Set(key KeyType, value ValueType) KeyTypeValueTypeMap {
log.Println(value)
m[key] = value
return m
}
@@ -1,21 +0,0 @@
package multipletypesets
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestSimpleMap(t *testing.T) {
key1 := new(KeyType)
key2 := new(KeyType)
value1 := new(ValueType)
m := make(KeyTypeValueTypeMap)
assert.Equal(t, m, m.Set(key1, value1))
assert.True(t, m.Has(key1))
assert.False(t, m.Has(key2))
assert.Equal(t, value1, m.Get(key1))
}
@@ -1,41 +0,0 @@
// This file was automatically generated by genny.
// Any changes will be lost if this file is regenerated.
// see https://github.com/cheekybits/genny
package multipletypesets
import "log"
type IntStringMap map[int]string
func (m IntStringMap) Has(key int) bool {
_, ok := m[key]
return ok
}
func (m IntStringMap) Get(key int) string {
return m[key]
}
func (m IntStringMap) Set(key int, value string) IntStringMap {
log.Println(value)
m[key] = value
return m
}
type Float64BoolMap map[float64]bool
func (m Float64BoolMap) Has(key float64) bool {
_, ok := m[key]
return ok
}
func (m Float64BoolMap) Get(key float64) bool {
return m[key]
}
func (m Float64BoolMap) Set(key float64, value bool) Float64BoolMap {
log.Println(value)
m[key] = value
return m
}
@@ -1,12 +0,0 @@
package numbers
import "github.com/cheekybits/genny/generic"
type NumberType generic.Number
func NumberTypeMax(a, b NumberType) NumberType {
if a > b {
return a
}
return b
}
-12
View File
@@ -1,12 +0,0 @@
// This file was automatically generated by genny.
// Any changes will be lost if this file is regenerated.
// see https://github.com/cheekybits/genny
package numbers
func IntMax(a, b int) int {
if a > b {
return a
}
return b
}
@@ -1,22 +0,0 @@
// This file was automatically generated by genny.
// Any changes will be lost if this file is regenerated.
// see https://github.com/cheekybits/genny
package changed
// IntQueue is a queue of Ints.
type IntQueue struct {
items []int
}
func NewIntQueue() *IntQueue {
return &IntQueue{items: make([]int, 0)}
}
func (q *IntQueue) Push(item int) {
q.items = append(q.items, item)
}
func (q *IntQueue) Pop() int {
item := q.items[0]
q.items = q.items[1:]
return item
}
-22
View File
@@ -1,22 +0,0 @@
// This file was automatically generated by genny.
// Any changes will be lost if this file is regenerated.
// see https://github.com/cheekybits/genny
package queue
// Float32Queue is a queue of Float32s.
type Float32Queue struct {
items []float32
}
func NewFloat32Queue() *Float32Queue {
return &Float32Queue{items: make([]float32, 0)}
}
func (q *Float32Queue) Push(item float32) {
q.items = append(q.items, item)
}
func (q *Float32Queue) Pop() float32 {
item := q.items[0]
q.items = q.items[1:]
return item
}
-23
View File
@@ -1,23 +0,0 @@
package queue
import "github.com/cheekybits/genny/generic"
// Something is a type that does something
type Something generic.Type
// SomethingQueue is a queue of Somethings.
type SomethingQueue struct {
items []Something
}
func NewSomethingQueue() *SomethingQueue {
return &SomethingQueue{items: make([]Something, 0)}
}
func (q *SomethingQueue) Push(item Something) {
q.items = append(q.items, item)
}
func (q *SomethingQueue) Pop() Something {
item := q.items[0]
q.items = q.items[1:]
return item
}
@@ -1,87 +0,0 @@
package queue
import "testing"
func TestSomethingQueue(t *testing.T) {
var item1 *Something = new(Something)
var item2 *Something = new(Something)
var item3 *Something = new(Something)
q := NewSomethingQueue()
q.Push(item1)
if len(q.items) != 1 {
t.Error("Push should add the item")
}
q.Push(item2)
if len(q.items) != 2 {
t.Error("Push should add the item")
}
q.Push(item3)
if len(q.items) != 3 {
t.Error("Push should add the item")
}
if q.Pop() != item1 {
t.Error("Pop should return items in the order in which they were added")
}
if len(q.items) != 2 {
t.Error("Pop should remove the item")
}
if q.Pop() != item2 {
t.Error("Pop should return items in the order in which they were added")
}
if len(q.items) != 1 {
t.Error("Pop should remove the item")
}
if q.Pop() != item3 {
t.Error("Pop should return items in the order in which they were added")
}
if len(q.items) != 0 {
t.Error("Pop should remove the item")
}
}
func TestIntQueue(t *testing.T) {
var item1 int = 1
var item2 int = 2
var item3 int = 3
q := NewIntQueue()
q.Push(item1)
if len(q.items) != 1 {
t.Error("Push should add the item")
}
q.Push(item2)
if len(q.items) != 2 {
t.Error("Push should add the item")
}
q.Push(item3)
if len(q.items) != 3 {
t.Error("Push should add the item")
}
if q.Pop() != item1 {
t.Error("Pop should return items in the order in which they were added")
}
if len(q.items) != 2 {
t.Error("Pop should remove the item")
}
if q.Pop() != item2 {
t.Error("Pop should return items in the order in which they were added")
}
if len(q.items) != 1 {
t.Error("Pop should remove the item")
}
if q.Pop() != item3 {
t.Error("Pop should return items in the order in which they were added")
}
if len(q.items) != 0 {
t.Error("Pop should remove the item")
}
}
-22
View File
@@ -1,22 +0,0 @@
// This file was automatically generated by genny.
// Any changes will be lost if this file is regenerated.
// see https://github.com/cheekybits/genny
package queue
// IntQueue is a queue of Ints.
type IntQueue struct {
items []int
}
func NewIntQueue() *IntQueue {
return &IntQueue{items: make([]int, 0)}
}
func (q *IntQueue) Push(item int) {
q.items = append(q.items, item)
}
func (q *IntQueue) Pop() int {
item := q.items[0]
q.items = q.items[1:]
return item
}
-24
View File
@@ -1,24 +0,0 @@
package slice
import (
"log"
"reflect"
"github.com/cheekybits/genny/generic"
)
type MyType generic.Type
func EnsureSlice(objectOrSlice interface{}) []MyType {
log.Printf("%v", reflect.TypeOf(objectOrSlice))
switch obj := objectOrSlice.(type) {
case []MyType:
log.Println(" returning it untouched")
return obj
case MyType, *MyType:
log.Println(" wrapping in slice")
return []MyType{obj}
default:
panic("ensure slice needs MyType or []MyType")
}
}
@@ -1,24 +0,0 @@
package slice
import (
"log"
"testing"
"github.com/stretchr/testify/assert"
)
func TestEnsureSlice(t *testing.T) {
myType := new(MyType)
slice := EnsureSlice(myType)
if assert.NotNil(t, slice) {
assert.Equal(t, slice[0], myType)
}
slice = EnsureSlice(slice)
log.Printf("%#v", slice[0])
if assert.NotNil(t, slice) {
assert.Equal(t, slice[0], myType)
}
}
@@ -1,3 +0,0 @@
package unexported
type myType struct{}
@@ -1,13 +0,0 @@
package unexported
import (
"fmt"
"github.com/cheekybits/genny/generic"
)
type secret generic.Type
func secretInspect(s secret) string {
return fmt.Sprintf("%#v", s)
}
@@ -1,11 +0,0 @@
// This file was automatically generated by genny.
// Any changes will be lost if this file is regenerated.
// see https://github.com/cheekybits/genny
package unexported
import "fmt"
func myTypeInspect(s *myType) string {
return fmt.Sprintf("%#v", s)
}
-89
View File
@@ -1,89 +0,0 @@
package parse
import "strings"
const (
typeSep = " "
keyValueSep = "="
valuesSep = ","
builtins = "BUILTINS"
numbers = "NUMBERS"
)
// TypeSet turns a type string into a []map[string]string
// that can be given to parse.Generics for it to do its magic.
//
// Acceptable args are:
//
// Person=man
// Person=man Animal=dog
// Person=man Animal=dog Animal2=cat
// Person=man,woman Animal=dog,cat
// Person=man,woman,child Animal=dog,cat Place=london,paris
func TypeSet(arg string) ([]map[string]string, error) {
types := make(map[string][]string)
var keys []string
for _, pair := range strings.Split(arg, typeSep) {
segs := strings.Split(pair, keyValueSep)
if len(segs) != 2 {
return nil, &errBadTypeArgs{Arg: arg, Message: "Generic=Specific expected"}
}
key := segs[0]
keys = append(keys, key)
types[key] = make([]string, 0)
for _, t := range strings.Split(segs[1], valuesSep) {
if t == builtins {
types[key] = append(types[key], Builtins...)
} else if t == numbers {
types[key] = append(types[key], Numbers...)
} else {
types[key] = append(types[key], t)
}
}
}
cursors := make(map[string]int)
for _, key := range keys {
cursors[key] = 0
}
outChan := make(chan map[string]string)
go func() {
buildTypeSet(keys, 0, cursors, types, outChan)
close(outChan)
}()
var typeSets []map[string]string
for typeSet := range outChan {
typeSets = append(typeSets, typeSet)
}
return typeSets, nil
}
func buildTypeSet(keys []string, keyI int, cursors map[string]int, types map[string][]string, out chan<- map[string]string) {
key := keys[keyI]
for cursors[key] < len(types[key]) {
if keyI < len(keys)-1 {
buildTypeSet(keys, keyI+1, copycursors(cursors), types, out)
} else {
// build the typeset for this combination
ts := make(map[string]string)
for k, vals := range types {
ts[k] = vals[cursors[k]]
}
out <- ts
}
cursors[key]++
}
}
func copycursors(source map[string]int) map[string]int {
copy := make(map[string]int)
for k, v := range source {
copy[k] = v
}
return copy
}
-74
View File
@@ -1,74 +0,0 @@
package parse_test
import (
"testing"
"github.com/cheekybits/genny/parse"
"github.com/stretchr/testify/assert"
)
func TestArgsToTypeset(t *testing.T) {
args := "Person=man,woman Animal=dog,cat Place=london,paris"
ts, err := parse.TypeSet(args)
if assert.NoError(t, err) {
if assert.Equal(t, 8, len(ts)) {
assert.Equal(t, ts[0]["Person"], "man")
assert.Equal(t, ts[0]["Animal"], "dog")
assert.Equal(t, ts[0]["Place"], "london")
assert.Equal(t, ts[1]["Person"], "man")
assert.Equal(t, ts[1]["Animal"], "dog")
assert.Equal(t, ts[1]["Place"], "paris")
assert.Equal(t, ts[2]["Person"], "man")
assert.Equal(t, ts[2]["Animal"], "cat")
assert.Equal(t, ts[2]["Place"], "london")
assert.Equal(t, ts[3]["Person"], "man")
assert.Equal(t, ts[3]["Animal"], "cat")
assert.Equal(t, ts[3]["Place"], "paris")
assert.Equal(t, ts[4]["Person"], "woman")
assert.Equal(t, ts[4]["Animal"], "dog")
assert.Equal(t, ts[4]["Place"], "london")
assert.Equal(t, ts[5]["Person"], "woman")
assert.Equal(t, ts[5]["Animal"], "dog")
assert.Equal(t, ts[5]["Place"], "paris")
assert.Equal(t, ts[6]["Person"], "woman")
assert.Equal(t, ts[6]["Animal"], "cat")
assert.Equal(t, ts[6]["Place"], "london")
assert.Equal(t, ts[7]["Person"], "woman")
assert.Equal(t, ts[7]["Animal"], "cat")
assert.Equal(t, ts[7]["Place"], "paris")
}
}
ts, err = parse.TypeSet("Person=man Animal=dog Place=london")
if assert.NoError(t, err) {
assert.Equal(t, 1, len(ts))
}
ts, err = parse.TypeSet("Person=1,2,3,4,5 Animal=1,2,3,4,5 Place=1,2,3,4,5")
if assert.NoError(t, err) {
assert.Equal(t, 125, len(ts))
}
ts, err = parse.TypeSet("Person=1 Animal=1,2,3,4,5 Place=1,2")
if assert.NoError(t, err) {
assert.Equal(t, 10, len(ts))
}
ts, err = parse.TypeSet("Person=interface{} Animal=interface{} Place=interface{}")
if assert.NoError(t, err) {
assert.Equal(t, 1, len(ts))
assert.Equal(t, ts[0]["Animal"], "interface{}")
assert.Equal(t, ts[0]["Person"], "interface{}")
assert.Equal(t, ts[0]["Place"], "interface{}")
}
}
+73
View File
@@ -0,0 +1,73 @@
# 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 = "9127e812e1e9e501ce899a18121d316ecb52e4ba"
[[projects]]
name = "github.com/davecgh/go-spew"
packages = ["spew"]
revision = "6d212800a42e8ab5c146b8ace3490ee17e5225f9"
[[projects]]
branch = "master"
name = "github.com/fatih/camelcase"
packages = ["."]
revision = "f6a740d52f961c60348ebb109adde9f4635d7540"
[[projects]]
name = "github.com/pkg/errors"
packages = ["."]
revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
version = "v0.8.0"
[[projects]]
name = "github.com/pmezard/go-difflib"
packages = ["difflib"]
revision = "d8ed2627bdf02c080bf22230dbb337003b7aba2d"
[[projects]]
name = "github.com/stretchr/testify"
packages = ["assert"]
revision = "69483b4bd14f5845b5a1e55bca19e954e827f1d0"
version = "v1.1.4"
[[projects]]
name = "gopkg.in/alecthomas/kingpin.v2"
packages = ["."]
revision = "7f0871f2e17818990e4eed73f9b5c2f429501228"
version = "v2.2.4"
[[projects]]
branch = "v2"
name = "gopkg.in/coryb/yaml.v2"
packages = ["."]
revision = "fb7cb9628c6e3bdd76c29fb91798d51a09832470"
[[projects]]
name = "gopkg.in/op/go-logging.v1"
packages = ["."]
revision = "b2cb9fa56473e98db8caba80237377e83fe44db5"
version = "v1"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "1879d7c016fcc8e210ca7fdeed4b099f4e7fc931d34ff47a170222c60eea8aab"
solver-name = "gps-cdcl"
solver-version = 1
+47
View File
@@ -0,0 +1,47 @@
# 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"
[[constraint]]
name = "github.com/cheekybits/genny"
[[constraint]]
name = "github.com/fatih/camelcase"
[[constraint]]
name = "github.com/pkg/errors"
version = "0.8.0"
[[constraint]]
name = "github.com/stretchr/testify"
version = "1.1.4"
[[constraint]]
name = "gopkg.in/alecthomas/kingpin.v2"
version = "2.2.4"
[[constraint]]
name = "gopkg.in/coryb/yaml.v2"
[[constraint]]
name = "gopkg.in/op/go-logging.v1"
version = "1.0.0"
-9
View File
@@ -1,9 +0,0 @@
str1:
foo: bar
arr1: strval1
map1:
- abc
- def
int1: true
float1: "strval2"
bool1: 123.45
-13
View File
@@ -1,13 +0,0 @@
#!/bin/sh
cat <<EOM
str1: d3str1val1
arr1:
- d3arr1val1
- d3arr1val2
map1:
key2: d3map1val2
key3: d3map1val3
int1: 333
float1: 3.33
bool1: true
EOM
-12
View File
@@ -1,12 +0,0 @@
str1: d3str1val1
arr1:
- d3arr1val1
- d3arr1val2
- dupval
map1:
key2: d3map1val2
key3: d3map1val3
dup: d3dupval
int1: 333
float1: 3.33
bool1: true
-10
View File
@@ -1,10 +0,0 @@
str1: d3str1val1
arr1:
- d3arr1val1
- d3arr1val2
map1:
key2: d3map1val2
key3: d3map1val3
int1: 333
float1: 3.33
bool1: true
-10
View File
@@ -1,10 +0,0 @@
str1: d3str1val1
arr1:
- d3arr1val1
- d3arr1val2
map1:
key2: d3map1val2
key3: d3map1val3
int1: 333
float1: 3.33
bool1: true
-13
View File
@@ -1,13 +0,0 @@
#!/bin/sh
cat <<EOM
str1: d2str1val1
arr1:
- d2arr1val1
- d2arr1val2
map1:
key1: d2map1val1
key2: d2map1val2
int1: 222
float1: 2.22
bool1: false
EOM
-12
View File
@@ -1,12 +0,0 @@
str1: d2str1val1
arr1:
- d2arr1val1
- d2arr1val2
- dupval
map1:
key1: d2map1val1
key2: d2map1val2
dup: d2dupval
int1: 222
float1: 2.22
bool1: false
-15
View File
@@ -1,15 +0,0 @@
config:
overwrite:
- str1
- arr1
- bool1
str1: d2str1val1
arr1:
- d2arr1val1
- d2arr1val2
map1:
key1: d2map1val1
key2: d2map1val2
int1: 222
float1: 2.22
bool1: false
-12
View File
@@ -1,12 +0,0 @@
config:
stop: true
str1: d2str1val1
arr1:
- d2arr1val1
- d2arr1val2
map1:
key1: d2map1val1
key2: d2map1val2
int1: 222
float1: 2.22
bool1: false
-13
View File
@@ -1,13 +0,0 @@
#!/bin/bash
cat <<EOM
str1: d1str1val1
arr1:
- d1arr1val1
- d1arr1val2
map1:
key0: d1map1val0
key1: d1map1val1
int1: 111
float1: 1.11
bool1: true
EOM
-12
View File
@@ -1,12 +0,0 @@
str1: d1str1val1
arr1:
- d1arr1val1
- d1arr1val2
- dupval
map1:
key0: d1map1val0
key1: d1map1val1
dup: d1dupval
int1: 111
float1: 1.11
bool1: true
-15
View File
@@ -1,15 +0,0 @@
config:
overwrite:
- map1
- int1
- float1
str1: d1str1val1
arr1:
- d1arr1val1
- d1arr1val2
map1:
key0: d1map1val0
key1: d1map1val1
int1: 111
float1: 1.11
bool1: true
-10
View File
@@ -1,10 +0,0 @@
str1: d1str1val1
arr1:
- d1arr1val1
- d1arr1val2
map1:
key0: d1map1val0
key1: d1map1val1
int1: 111
float1: 1.11
bool1: true

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