WHAT DID I DO
This commit is contained in:
parent
020ac7a6fb
commit
0cc82e4f87
8 changed files with 157 additions and 51 deletions
|
|
@ -50,3 +50,7 @@ func (ccmd *CommentCmd) Comment() error {
|
|||
|
||||
return jkl.AddComment(ccmd.issueKey, b.String())
|
||||
}
|
||||
|
||||
func (ccmd *CommentCmd) Run() error {
|
||||
return ccmd.Comment()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"errors"
|
||||
"flag"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"otremblay.com/jkl"
|
||||
|
|
@ -27,7 +28,20 @@ func NewCreateCmd(args []string) (*CreateCmd, error) {
|
|||
var ErrCcmdJiraProjectRequired = errors.New("Jira project needs to be set")
|
||||
|
||||
func (ccmd *CreateCmd) Create() error {
|
||||
var b = bytes.NewBufferString(CREATE_TEMPLATE)
|
||||
var b = bytes.NewBuffer([]byte{})
|
||||
var readfile bool
|
||||
if fp := os.Getenv("JIRA_ISSUE_TEMPLATE"); fp != "" {
|
||||
if f, err := os.Open(fp); err == nil {
|
||||
_, err := io.Copy(b, f)
|
||||
if err == nil {
|
||||
readfile = true
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if !readfile {
|
||||
b.WriteString(CREATE_TEMPLATE)
|
||||
}
|
||||
var iss *jkl.JiraIssue
|
||||
var err error
|
||||
if ccmd.file != "" {
|
||||
|
|
@ -49,6 +63,10 @@ func (ccmd *CreateCmd) Create() error {
|
|||
return jkl.Create(iss)
|
||||
}
|
||||
|
||||
func (ccmd *CreateCmd) Run() error {
|
||||
return ccmd.Create()
|
||||
}
|
||||
|
||||
const CREATE_TEMPLATE = `Issue Type:
|
||||
Summary:
|
||||
Description:`
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ type EditCmd struct {
|
|||
args []string
|
||||
project string
|
||||
file string
|
||||
taskKey string
|
||||
}
|
||||
|
||||
func NewEditCmd(args []string) (*EditCmd, error) {
|
||||
|
|
@ -22,12 +23,13 @@ func NewEditCmd(args []string) (*EditCmd, error) {
|
|||
f.StringVar(&ccmd.project, "p", "", "Jira project key")
|
||||
f.StringVar(&ccmd.file, "f", "filename", "File to get issue description from")
|
||||
f.Parse(args)
|
||||
ccmd.taskKey = flag.Arg(0)
|
||||
return ccmd, nil
|
||||
}
|
||||
|
||||
func (ecmd *EditCmd) Edit(taskKey string) error {
|
||||
func (ecmd *EditCmd) Edit() error {
|
||||
b := bytes.NewBuffer(nil)
|
||||
iss, err := jkl.GetIssue(taskKey)
|
||||
iss, err := jkl.GetIssue(ecmd.taskKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -49,10 +51,14 @@ func (ecmd *EditCmd) Edit(taskKey string) error {
|
|||
}
|
||||
|
||||
}
|
||||
iss.Key = taskKey
|
||||
iss.Key = ecmd.taskKey
|
||||
return jkl.Edit(iss)
|
||||
}
|
||||
|
||||
func (ecmd *EditCmd) Run() error {
|
||||
return ecmd.Edit()
|
||||
}
|
||||
|
||||
const EDIT_TEMPLATE = `Summary: {{.Fields.Summary}}
|
||||
Description: {{.Fields.Description}}
|
||||
`
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ func GetIssueFromTmpFile(initial io.Reader) (*jkl.JiraIssue, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return IssueFromFile(f2), nil
|
||||
return IssueFromReader(f2), nil
|
||||
}
|
||||
|
||||
func GetTextFromTmpFile(initial io.Reader) (io.Reader, error) {
|
||||
|
|
@ -99,12 +99,12 @@ func GetIssueFromFile(filename string, initial io.Reader) (*jkl.JiraIssue, error
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return IssueFromFile(f2), nil
|
||||
return IssueFromReader(f2), nil
|
||||
}
|
||||
|
||||
var spacex = regexp.MustCompile(`\s`)
|
||||
|
||||
func IssueFromFile(f io.Reader) *jkl.JiraIssue {
|
||||
func IssueFromReader(f io.Reader) *jkl.JiraIssue {
|
||||
iss := &jkl.JiraIssue{Fields: &jkl.Fields{}}
|
||||
riss := reflect.ValueOf(iss).Elem()
|
||||
fieldsField := riss.FieldByName("Fields").Elem()
|
||||
|
|
@ -118,20 +118,40 @@ func IssueFromFile(f io.Reader) *jkl.JiraIssue {
|
|||
parts := strings.Split(string(b), ":")
|
||||
potentialField := spacex.ReplaceAllString(parts[0], "")
|
||||
|
||||
// Is the current line a field in an issue directly?
|
||||
// Also special cases: Objects that have a deeper depth
|
||||
// have specific fields "flattened" for ease of use.
|
||||
// I think this loop could be made more general, to account
|
||||
// for deeper objects. Then again, there's not that many fields
|
||||
// I actually care about yet.
|
||||
// Custom fields are gonna be hell.
|
||||
|
||||
if newfield := fieldsField.FieldByName(potentialField); newfield.IsValid() {
|
||||
parts = parts[1:len(parts)]
|
||||
if potentialField == "IssueType" {
|
||||
iss.Fields.IssueType = &jkl.IssueType{}
|
||||
currentField = reflect.Value{}
|
||||
f2 := newfield.Elem()
|
||||
f3 := f2.FieldByName("Name")
|
||||
f3.SetString(strings.TrimSpace(strings.Join(parts, ":")))
|
||||
if len(parts) > 0 {
|
||||
iss.Fields.IssueType = &jkl.IssueType{}
|
||||
currentField = reflect.Value{}
|
||||
f2 := newfield.Elem()
|
||||
f3 := f2.FieldByName("Name")
|
||||
f3.SetString(strings.TrimSpace(strings.Join(parts, ":")))
|
||||
}
|
||||
} else if potentialField == "Project" {
|
||||
iss.Fields.Project = &jkl.Project{}
|
||||
currentField = reflect.Value{}
|
||||
f2 := newfield.Elem()
|
||||
f3 := f2.FieldByName("Key")
|
||||
f3.SetString(strings.TrimSpace(strings.Join(parts, ":")))
|
||||
if len(parts) > 0 {
|
||||
iss.Fields.Project = &jkl.Project{}
|
||||
currentField = reflect.Value{}
|
||||
f2 := newfield.Elem()
|
||||
f3 := f2.FieldByName("Key")
|
||||
f3.SetString(strings.TrimSpace(strings.Join(parts, ":")))
|
||||
}
|
||||
} else if potentialField == "Parent" {
|
||||
if len(parts) > 0 {
|
||||
iss.Fields.Parent = &jkl.JiraIssue{}
|
||||
currentField = reflect.Value{}
|
||||
f2 := newfield.Elem()
|
||||
f3 := f2.FieldByName("Key")
|
||||
f3.SetString(strings.TrimSpace(strings.Join(parts, ":")))
|
||||
}
|
||||
} else {
|
||||
currentField = newfield
|
||||
}
|
||||
|
|
@ -144,5 +164,5 @@ func IssueFromFile(f io.Reader) *jkl.JiraIssue {
|
|||
}
|
||||
|
||||
func IssueFromList(list []string) *jkl.JiraIssue {
|
||||
return IssueFromFile(bytes.NewBufferString(strings.Join(list, "\n")))
|
||||
return IssueFromReader(bytes.NewBufferString(strings.Join(list, "\n")))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,57 +4,81 @@ import (
|
|||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"strings"
|
||||
|
||||
"otremblay.com/jkl"
|
||||
)
|
||||
|
||||
var verbose = flag.Bool("v", false, "Output debug information about jkl")
|
||||
var help = flag.Bool("h", false, "Outputs usage information message")
|
||||
|
||||
func main() {
|
||||
jkl.FindRCFile()
|
||||
flag.Parse()
|
||||
jkl.Verbose = verbose
|
||||
if len(flag.Args()) == 0 {
|
||||
fmt.Print(usage)
|
||||
return
|
||||
}
|
||||
if err := runcmd(flag.Args()); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
func runcmd(args []string) error {
|
||||
if len(args) == 0 {
|
||||
if *help {
|
||||
fmt.Fprintln(os.Stderr, usage)
|
||||
flag.PrintDefaults()
|
||||
return nil
|
||||
}
|
||||
args = append(args, "list")
|
||||
}
|
||||
if strings.Contains(args[0], "~") {
|
||||
args = append([]string{"edit-comment"}, args...)
|
||||
}
|
||||
cmd, err := getCmd(args, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func getCmd(args []string, depth int) (Runner, error) {
|
||||
switch args[0] {
|
||||
case "list":
|
||||
if *verbose {
|
||||
fmt.Println("Running List command")
|
||||
}
|
||||
lcmd, err := NewListCmd(flag.Args()[1:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return lcmd.List()
|
||||
return NewListCmd(args[1:])
|
||||
case "create":
|
||||
ccmd, err := NewCreateCmd(flag.Args()[1:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ccmd.Create()
|
||||
return NewCreateCmd(args[1:])
|
||||
case "task":
|
||||
tcmd := &TaskCmd{}
|
||||
return tcmd.Handle(flag.Args()[1:])
|
||||
tcmd := &TaskCmd{args: args[1:]}
|
||||
return tcmd, nil
|
||||
case "edit":
|
||||
ecmd := &EditCmd{}
|
||||
return ecmd.Edit(flag.Arg(1))
|
||||
return NewEditCmd(args[1:])
|
||||
case "comment":
|
||||
ccmd, err := NewCommentCmd(flag.Args()[1:])
|
||||
if err != nil {
|
||||
return err
|
||||
return NewCommentCmd(args[1:])
|
||||
case "edit-comment":
|
||||
return NewEditCommentCmd(args[1:])
|
||||
default:
|
||||
// Think about this real hard.
|
||||
// I want `jkl JIRA-1234 done` to move it to done.
|
||||
// I want `jkl JIRA-1234` to print out info
|
||||
// I want `jkl JIRA-1234 edit` to run the edit command.
|
||||
// I want `jkl JIRA-1234 comment` to run the comment command.
|
||||
// I want `jkl JIRA-1234 attach <filename>` to run the attach command.
|
||||
|
||||
if depth == 0 {
|
||||
// Assume args[0] is a task key
|
||||
args[0], args[1] = args[1], args[0]
|
||||
return getCmd(args, depth+1)
|
||||
} else {
|
||||
// Swapping the first two args didn't help;
|
||||
// this means it's a transition.
|
||||
|
||||
// tcmd, err := NewTransitionCommand(args)
|
||||
// if err != nil {return nil, err}
|
||||
// return tcmd, nil
|
||||
}
|
||||
return ccmd.Comment()
|
||||
}
|
||||
fmt.Println(usage)
|
||||
return nil
|
||||
return nil, ErrTaskSubCommandNotFound
|
||||
}
|
||||
|
||||
const usage = `Usage:
|
||||
|
|
@ -65,4 +89,6 @@ Available commands:
|
|||
list
|
||||
create
|
||||
edit
|
||||
comment
|
||||
|
||||
`
|
||||
|
|
|
|||
|
|
@ -49,6 +49,9 @@ type ListCmd struct {
|
|||
func NewListCmd(args []string) (*ListCmd, error) {
|
||||
ccmd := &ListCmd{}
|
||||
f := flag.NewFlagSet("x", flag.ExitOnError)
|
||||
if *verbose {
|
||||
fmt.Println(&ccmd.tmplstr)
|
||||
}
|
||||
f.StringVar(&ccmd.tmplstr, "listTemplate", "{{.Color}}{{.Key}}{{if .Color}}\x1b[39m{{end}}\t({{.Fields.IssueType.Name}}{{if .Fields.Parent}} of {{.Fields.Parent.Key}}{{end}})\t{{.Fields.Summary}}\t{{if .Fields.Assignee}}[{{.Fields.Assignee.Name}}]{{end}}\n", "Go template used in list command")
|
||||
f.Parse(args)
|
||||
ccmd.args = f.Args()
|
||||
|
|
@ -58,6 +61,12 @@ func NewListCmd(args []string) (*ListCmd, error) {
|
|||
proj = fmt.Sprintf(" and project = %s ", proj)
|
||||
}
|
||||
ccmd.args = []string{fmt.Sprintf("sprint in openSprints() %s order by rank", proj)}
|
||||
if *verbose {
|
||||
fmt.Println("No arguments, running default command")
|
||||
}
|
||||
}
|
||||
if *verbose {
|
||||
fmt.Println(ccmd.args)
|
||||
}
|
||||
ccmd.tmpl = template.Must(template.New("listTemplate").Parse(ccmd.tmplstr))
|
||||
return ccmd, nil
|
||||
|
|
@ -78,3 +87,7 @@ func (l *ListCmd) List() error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *ListCmd) Run() error {
|
||||
return l.List()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,15 +7,18 @@ import (
|
|||
"otremblay.com/jkl"
|
||||
)
|
||||
|
||||
type TaskCmd struct{}
|
||||
type TaskCmd struct {
|
||||
args []string
|
||||
}
|
||||
|
||||
func (t *TaskCmd) Handle(args []string) error {
|
||||
c := len(args)
|
||||
// TODO: split in individual commands.
|
||||
func (t *TaskCmd) Handle() error {
|
||||
c := len(t.args)
|
||||
if c == 1 {
|
||||
return t.Get(args[0])
|
||||
return t.Get(t.args[0])
|
||||
}
|
||||
if c == 2 {
|
||||
return t.Transition(args[0], args[1])
|
||||
return t.Transition(t.args[0], t.args[1])
|
||||
}
|
||||
return ErrTaskSubCommandNotFound
|
||||
}
|
||||
|
|
@ -34,3 +37,7 @@ func (t *TaskCmd) Get(taskKey string) error {
|
|||
func (t *TaskCmd) Transition(taskKey, transition string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TaskCmd) Run() error {
|
||||
return t.Handle()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue