WHAT DID I DO

This commit is contained in:
Olivier 2017-01-10 10:25:14 -05:00
parent 020ac7a6fb
commit 0cc82e4f87
No known key found for this signature in database
GPG key ID: 1A9FE7C1DFF65CB0
8 changed files with 157 additions and 51 deletions

View file

@ -50,3 +50,7 @@ func (ccmd *CommentCmd) Comment() error {
return jkl.AddComment(ccmd.issueKey, b.String())
}
func (ccmd *CommentCmd) Run() error {
return ccmd.Comment()
}

View file

@ -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:`

View file

@ -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}}
`

View file

@ -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")))
}

View file

@ -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
`

View file

@ -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()
}

View file

@ -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()
}