mirror of
https://github.com/Threnklyn/jira.git
synced 2026-06-07 13:33:32 +02:00
add basic tests for custom-commands
This commit is contained in:
Generated
+4
-4
@@ -1,5 +1,5 @@
|
||||
hash: 4c3ae9c9421b17aae9987ea9566cac7d0a789750bb77c8d235b7be163aec8cae
|
||||
updated: 2017-09-08T18:47:08.390962401-07:00
|
||||
updated: 2017-09-09T17:13:22.172913984-07:00
|
||||
imports:
|
||||
- name: github.com/alecthomas/template
|
||||
version: a0175ee3bccc567396460bf5acd36800cb10c49c
|
||||
@@ -12,7 +12,7 @@ imports:
|
||||
subpackages:
|
||||
- generic
|
||||
- name: github.com/coryb/figtree
|
||||
version: 4429db55820d818320f5af8971ef8401baaf3d21
|
||||
version: 86e7c859d0326621c45ba7be2c32e3b3ae203213
|
||||
- name: github.com/coryb/kingpeon
|
||||
version: 64b561ae2d0f895b94719c486bed798f4236a4b3
|
||||
- name: github.com/coryb/oreo
|
||||
@@ -42,11 +42,11 @@ imports:
|
||||
- name: github.com/tmc/keyring
|
||||
version: 06e6283d50adc5f8fcdb3cdf33ee1244d4400ae1
|
||||
- name: golang.org/x/crypto
|
||||
version: 81e90905daefcd6fd217b62423c0908922eadb30
|
||||
version: 9ba3862cf6a5452ae579de98f9364dd2e544844c
|
||||
subpackages:
|
||||
- ssh/terminal
|
||||
- name: golang.org/x/sys
|
||||
version: 5513e650ab47a692d3a036d49be8fa52ddd09b65
|
||||
version: a5054c7c1385fd50d9394475365355a87a7873ec
|
||||
subpackages:
|
||||
- unix
|
||||
- windows
|
||||
|
||||
@@ -3,3 +3,24 @@ 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: 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
|
||||
|
||||
Executable
+61
@@ -0,0 +1,61 @@
|
||||
#!/bin/bash
|
||||
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
|
||||
cd $(dirname $0)
|
||||
jira="../jira"
|
||||
. env.sh
|
||||
|
||||
PLAN 10
|
||||
|
||||
# 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, 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":"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"}]
|
||||
JIRA_ENDPOINT=https://go-jira.atlassian.net
|
||||
JIRA_LOG_FORMAT=%{level:-5s} %{message}
|
||||
JIRA_PASSWORD_SOURCE=pass
|
||||
JIRA_PROJECT=BASIC
|
||||
JIRA_USER=gojira
|
||||
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
|
||||
+64
-50
@@ -104,11 +104,11 @@ func (f *FigTree) LoadConfigBytes(config []byte, source string, options interfac
|
||||
reflect.ValueOf(options),
|
||||
reflect.ValueOf(tmp),
|
||||
)
|
||||
f.populateEnv(options)
|
||||
if m.Config.Stop {
|
||||
f.stop = true
|
||||
return nil
|
||||
}
|
||||
f.populateEnv(options)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -350,6 +350,60 @@ Outer:
|
||||
return ov
|
||||
}
|
||||
|
||||
func (f *FigTree) formatEnvName(name string) string {
|
||||
name = fmt.Sprintf("%s_%s", f.EnvPrefix, strings.ToUpper(name))
|
||||
|
||||
return strings.Map(func(r rune) rune {
|
||||
if unicode.IsDigit(r) || unicode.IsLetter(r) {
|
||||
return r
|
||||
}
|
||||
return '_'
|
||||
}, name)
|
||||
}
|
||||
|
||||
func (f *FigTree) formatEnvValue(value reflect.Value) (string, bool) {
|
||||
switch t := value.Interface().(type) {
|
||||
case string:
|
||||
return t, true
|
||||
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, bool:
|
||||
return fmt.Sprintf("%v", t), true
|
||||
default:
|
||||
switch value.Kind() {
|
||||
case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
|
||||
if value.IsNil() {
|
||||
return "", false
|
||||
}
|
||||
}
|
||||
if t == nil {
|
||||
return "", false
|
||||
}
|
||||
type definable interface {
|
||||
IsDefined() bool
|
||||
}
|
||||
if def, ok := t.(definable); ok {
|
||||
// skip fields that are not defined
|
||||
if !def.IsDefined() {
|
||||
return "", false
|
||||
}
|
||||
}
|
||||
type gettable interface {
|
||||
GetValue() interface{}
|
||||
}
|
||||
if get, ok := t.(gettable); ok {
|
||||
return fmt.Sprintf("%v", get.GetValue()), true
|
||||
} else {
|
||||
if b, err := json.Marshal(t); err == nil {
|
||||
val := strings.TrimSpace(string(b))
|
||||
if val == "null" {
|
||||
return "", true
|
||||
}
|
||||
return val, true
|
||||
}
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
func (f *FigTree) populateEnv(data interface{}) {
|
||||
options := reflect.ValueOf(data)
|
||||
if options.Kind() == reflect.Ptr {
|
||||
@@ -370,8 +424,11 @@ func (f *FigTree) populateEnv(data interface{}) {
|
||||
}
|
||||
|
||||
name := strings.Join(allParts, "_")
|
||||
envName := fmt.Sprintf("%s_%s", f.EnvPrefix, strings.ToUpper(name))
|
||||
os.Setenv(envName, fmt.Sprintf("%v", options.MapIndex(key).Interface()))
|
||||
envName := f.formatEnvName(name)
|
||||
val, ok := f.formatEnvValue(options.MapIndex(key))
|
||||
if ok {
|
||||
os.Setenv(envName, val)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if options.Kind() == reflect.Struct {
|
||||
@@ -400,54 +457,11 @@ func (f *FigTree) populateEnv(data interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
envName := fmt.Sprintf("%s_%s", f.EnvPrefix, strings.ToUpper(name))
|
||||
|
||||
envName = strings.Map(func(r rune) rune {
|
||||
if unicode.IsDigit(r) || unicode.IsLetter(r) {
|
||||
return r
|
||||
}
|
||||
return '_'
|
||||
}, envName)
|
||||
var val string
|
||||
switch t := options.Field(i).Interface().(type) {
|
||||
case string:
|
||||
val = t
|
||||
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, bool:
|
||||
val = fmt.Sprintf("%v", t)
|
||||
default:
|
||||
switch options.Field(i).Kind() {
|
||||
case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
|
||||
if options.Field(i).IsNil() {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if t == nil {
|
||||
continue
|
||||
}
|
||||
type definable interface {
|
||||
IsDefined() bool
|
||||
}
|
||||
if def, ok := t.(definable); ok {
|
||||
// skip fields that are not defined
|
||||
if !def.IsDefined() {
|
||||
continue
|
||||
}
|
||||
}
|
||||
type gettable interface {
|
||||
GetValue() interface{}
|
||||
}
|
||||
if get, ok := t.(gettable); ok {
|
||||
val = fmt.Sprintf("%v", get.GetValue())
|
||||
} else {
|
||||
if b, err := json.Marshal(t); err == nil {
|
||||
val = strings.TrimSpace(string(b))
|
||||
if val == "null" {
|
||||
val = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
envName := f.formatEnvName(name)
|
||||
val, ok := f.formatEnvValue(options.Field(i))
|
||||
if ok {
|
||||
os.Setenv(envName, val)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+18
-1
@@ -3,7 +3,7 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
Package box authenticates and encrypts messages using public-key cryptography.
|
||||
Package box authenticates and encrypts small messages using public-key cryptography.
|
||||
|
||||
Box uses Curve25519, XSalsa20 and Poly1305 to encrypt and authenticate
|
||||
messages. The length of messages is not hidden.
|
||||
@@ -13,6 +13,23 @@ example, by using nonce 1 for the first message, nonce 2 for the second
|
||||
message, etc. Nonces are long enough that randomly generated nonces have
|
||||
negligible risk of collision.
|
||||
|
||||
Messages should be small because:
|
||||
|
||||
1. The whole message needs to be held in memory to be processed.
|
||||
|
||||
2. Using large messages pressures implementations on small machines to decrypt
|
||||
and process plaintext before authenticating it. This is very dangerous, and
|
||||
this API does not allow it, but a protocol that uses excessive message sizes
|
||||
might present some implementations with no other choice.
|
||||
|
||||
3. Fixed overheads will be sufficiently amortised by messages as small as 8KB.
|
||||
|
||||
4. Performance may be improved by working with messages that fit into data caches.
|
||||
|
||||
Thus large amounts of data should be chunked so that each message is small.
|
||||
(Each message still needs a unique nonce.) If in doubt, 16KB is a reasonable
|
||||
chunk size.
|
||||
|
||||
This package is interoperable with NaCl: https://nacl.cr.yp.to/box.html.
|
||||
*/
|
||||
package box // import "golang.org/x/crypto/nacl/box"
|
||||
|
||||
+17
@@ -13,6 +13,23 @@ example, by using nonce 1 for the first message, nonce 2 for the second
|
||||
message, etc. Nonces are long enough that randomly generated nonces have
|
||||
negligible risk of collision.
|
||||
|
||||
Messages should be small because:
|
||||
|
||||
1. The whole message needs to be held in memory to be processed.
|
||||
|
||||
2. Using large messages pressures implementations on small machines to decrypt
|
||||
and process plaintext before authenticating it. This is very dangerous, and
|
||||
this API does not allow it, but a protocol that uses excessive message sizes
|
||||
might present some implementations with no other choice.
|
||||
|
||||
3. Fixed overheads will be sufficiently amortised by messages as small as 8KB.
|
||||
|
||||
4. Performance may be improved by working with messages that fit into data caches.
|
||||
|
||||
Thus large amounts of data should be chunked so that each message is small.
|
||||
(Each message still needs a unique nonce.) If in doubt, 16KB is a reasonable
|
||||
chunk size.
|
||||
|
||||
This package is interoperable with NaCl: https://nacl.cr.yp.to/secretbox.html.
|
||||
*/
|
||||
package secretbox // import "golang.org/x/crypto/nacl/secretbox"
|
||||
|
||||
+20
-5
@@ -12,7 +12,10 @@ import (
|
||||
)
|
||||
|
||||
func TestKeyExpiry(t *testing.T) {
|
||||
kring, _ := ReadKeyRing(readerFromHex(expiringKeyHex))
|
||||
kring, err := ReadKeyRing(readerFromHex(expiringKeyHex))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
entity := kring[0]
|
||||
|
||||
const timeFormat = "2006-01-02"
|
||||
@@ -104,7 +107,10 @@ func TestGoodCrossSignature(t *testing.T) {
|
||||
|
||||
// TestExternallyRevokableKey attempts to load and parse a key with a third party revocation permission.
|
||||
func TestExternallyRevocableKey(t *testing.T) {
|
||||
kring, _ := ReadKeyRing(readerFromHex(subkeyUsageHex))
|
||||
kring, err := ReadKeyRing(readerFromHex(subkeyUsageHex))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// The 0xA42704B92866382A key can be revoked by 0xBE3893CB843D0FE70C
|
||||
// according to this signature that appears within the key:
|
||||
@@ -125,7 +131,10 @@ func TestExternallyRevocableKey(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestKeyRevocation(t *testing.T) {
|
||||
kring, _ := ReadKeyRing(readerFromHex(revokedKeyHex))
|
||||
kring, err := ReadKeyRing(readerFromHex(revokedKeyHex))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// revokedKeyHex contains these keys:
|
||||
// pub 1024R/9A34F7C0 2014-03-25 [revoked: 2014-03-25]
|
||||
@@ -145,7 +154,10 @@ func TestKeyRevocation(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSubkeyRevocation(t *testing.T) {
|
||||
kring, _ := ReadKeyRing(readerFromHex(revokedSubkeyHex))
|
||||
kring, err := ReadKeyRing(readerFromHex(revokedSubkeyHex))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// revokedSubkeyHex contains these keys:
|
||||
// pub 1024R/4EF7E4BECCDE97F0 2014-03-25
|
||||
@@ -178,7 +190,10 @@ func TestSubkeyRevocation(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestKeyUsage(t *testing.T) {
|
||||
kring, _ := ReadKeyRing(readerFromHex(subkeyUsageHex))
|
||||
kring, err := ReadKeyRing(readerFromHex(subkeyUsageHex))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// subkeyUsageHex contains these keys:
|
||||
// pub 1024R/2866382A created: 2014-04-01 expires: never usage: SC
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Functions to access/create device major and minor numbers matching the
|
||||
// encoding used in FreeBSD's sys/types.h header.
|
||||
//
|
||||
// The information below is extracted and adapted from sys/types.h:
|
||||
//
|
||||
// Minor gives a cookie instead of an index since in order to avoid changing the
|
||||
// meanings of bits 0-15 or wasting time and space shifting bits 16-31 for
|
||||
// devices that don't use them.
|
||||
|
||||
package unix
|
||||
|
||||
// Major returns the major component of a FreeBSD device number.
|
||||
func Major(dev uint64) uint32 {
|
||||
return uint32((dev >> 8) & 0xff)
|
||||
}
|
||||
|
||||
// Minor returns the minor component of a FreeBSD device number.
|
||||
func Minor(dev uint64) uint32 {
|
||||
return uint32(dev & 0xffff00ff)
|
||||
}
|
||||
|
||||
// Mkdev returns a FreeBSD device number generated from the given major and
|
||||
// minor components.
|
||||
func Mkdev(major, minor uint32) uint64 {
|
||||
return uint64((major << 8) | minor)
|
||||
}
|
||||
Reference in New Issue
Block a user