adding request command, removing dead code

This commit is contained in:
Cory Bennett
2017-08-21 09:33:57 -05:00
parent a1c28495a7
commit 56b1c9df04
6 changed files with 158 additions and 815 deletions
+5 -281
View File
@@ -254,6 +254,11 @@ func main() {
Entry: cli.CmdBrowseRegistry(),
Aliases: []string{"b"},
},
jiracli.CommandRegistry{
Command: "request",
Entry: cli.CmdRequestRegistry(),
Aliases: []string{"req"},
},
}
cli.Register(app, registry)
@@ -270,285 +275,4 @@ func main() {
if err != nil {
log.Fatalf("%s", err)
}
// Usage:
// jira (b|browse) ISSUE
// jira request [-M METHOD] URI [DATA]
// jira ISSUE
// General Options:
// -b --browse Open your browser to the Jira issue
// -e --endpoint=URI URI to use for jira
// -k --insecure disable TLS certificate verification
// -h --help Show this usage
// -t --template=FILE Template file to use for output/editing
// -u --user=USER Username to use for authenticaion (default: %s)
// -v --verbose Increase output logging
// --unixproxy=PATH Path for a unix-socket proxy (eg., --unixproxy /tmp/proxy.sock)
// --version Print version
// Query Options:
// -a --assignee=USER Username assigned the issue
// -c --component=COMPONENT Component to Search for
// -f --queryfields=FIELDS Fields that are used in "list" template: (default: %s)
// -i --issuetype=ISSUETYPE The Issue Type
// -l --limit=VAL Maximum number of results to return in query (default: %d)
// --start=START Start parameter for pagination
// -p --project=PROJECT Project to Search for
// -q --query=JQL Jira Query Language expression for the search
// -r --reporter=USER Reporter to search for
// -s --sort=ORDER For list operations, sort issues (default: %s)
// Edit Options:
// -m --comment=COMMENT Comment message for transition
// -o --override=KEY=VAL Set custom key/value pairs
// Create Options:
// -i --issuetype=ISSUETYPE Jira Issue Type (default: Bug)
// -m --comment=COMMENT Comment message for transition
// -o --override=KEY=VAL Set custom key/value pairs
// Worklog Options:
// -T --time-spent=TIMESPENT Time spent working on issue
// -m --comment=COMMENT Comment message for worklog
// Command Options:
// -d --directory=DIR Directory to export templates to (default: %s)
// `, user, defaultQueryFields, defaultMaxResults, defaultSort, user, fmt.Sprintf("%s/.jira.d/templates", home))
// printer(output)
// }
// jiraCommands := map[string]string{
// "browse": "browse",
// "req": "request",
// "request": "request",
// }
// defaults := map[string]interface{}{
// "user": user,
// "queryfields": defaultQueryFields,
// "directory": fmt.Sprintf("%s/.jira.d/templates", home),
// "sort": defaultSort,
// "max_results": defaultMaxResults,
// "method": "GET",
// "quiet": false,
// }
// opts := make(map[string]interface{})
// setopt := func(name string, value interface{}) {
// opts[name] = value
// }
// op := optigo.NewDirectAssignParser(map[string]interface{}{
// "h|help": usage,
// "version": func() {
// fmt.Println(fmt.Sprintf("version: %s", jira.VERSION))
// os.Exit(0)
// },
// "v|verbose+": func() {
// logging.SetLevel(logging.GetLevel("")+1, "")
// },
// "dryrun": setopt,
// "b|browse": setopt,
// "editor=s": setopt,
// "u|user=s": setopt,
// "endpoint=s": setopt,
// "k|insecure": setopt,
// "t|template=s": setopt,
// "q|query=s": setopt,
// "p|project=s": setopt,
// "c|component=s": setopt,
// "a|assignee=s": setopt,
// "i|issuetype=s": setopt,
// "remove": setopt,
// "r|reporter=s": setopt,
// "f|queryfields=s": setopt,
// "x|expand=s": setopt,
// "s|sort=s": setopt,
// "l|limit|max_results=i": setopt,
// "start|start_at=i": setopt,
// "o|override=s%": &opts,
// "noedit": setopt,
// "edit": setopt,
// "m|comment=s": setopt,
// "d|dir|directory=s": setopt,
// "M|method=s": setopt,
// "S|saveFile=s": setopt,
// "T|time-spent=s": setopt,
// "Q|quiet": setopt,
// "unixproxy": setopt,
// "down": setopt,
// "default": setopt,
// })
// if err := op.ProcessAll(os.Args[1:]); err != nil {
// log.Errorf("%s", err)
// usage(false)
// }
// args := op.Args
// var command string
// if len(args) > 0 {
// if alias, ok := jiraCommands[args[0]]; ok {
// command = alias
// args = args[1:]
// } else if len(args) > 1 {
// // look at second arg for "dups" and "blocks" commands
// // also for 'set/add/remove' actions like 'labels'
// if alias, ok := jiraCommands[args[1]]; ok {
// command = alias
// args = append(args[:1], args[2:]...)
// }
// }
// }
// if command == "" && len(args) > 0 {
// command = args[0]
// args = args[1:]
// }
// os.Setenv("JIRA_OPERATION", command)
// loadConfigs(opts)
// // check to see if it was set in the configs:
// if value, ok := opts["command"].(string); ok {
// command = value
// } else if _, ok := jiraCommands[command]; !ok || command == "" {
// if command != "" {
// args = append([]string{command}, args...)
// }
// command = "view"
// }
// // apply defaults
// for k, v := range defaults {
// if _, ok := opts[k]; !ok {
// log.Debugf("Setting %q to %#v from defaults", k, v)
// opts[k] = v
// }
// }
// log.Debugf("opts: %v", opts)
// log.Debugf("args: %v", args)
// if _, ok := opts["endpoint"]; !ok {
// log.Errorf("endpoint option required. Either use --endpoint or set a endpoint option in your ~/.jira.d/config.yml file")
// os.Exit(1)
// }
// c := jira.New(opts)
// log.Debugf("opts: %s", opts)
// setEditing := func(dflt bool) {
// log.Debugf("Default Editing: %t", dflt)
// if dflt {
// if val, ok := opts["noedit"].(bool); ok && val {
// log.Debugf("Setting edit = false")
// opts["edit"] = false
// } else {
// log.Debugf("Setting edit = true")
// opts["edit"] = true
// }
// } else {
// if _, ok := opts["edit"].(bool); !ok {
// log.Debugf("Setting edit = %t", dflt)
// opts["edit"] = dflt
// }
// }
// }
// requireArgs := func(count int) {
// if len(args) < count {
// log.Errorf("Not enough arguments. %d required, %d provided", count, len(args))
// usage(false)
// }
// }
// var err error
// switch command {
// case "request":
// requireArgs(1)
// data := ""
// if len(args) > 1 {
// data = args[1]
// }
// err = c.CmdRequest(args[0], data)
// default:
// log.Errorf("Unknown command %s", command)
// os.Exit(1)
// }
// if err != nil {
// log.Errorf("%s", err)
// os.Exit(1)
// }
// os.Exit(0)
}
// func parseYaml(file string, opts map[string]interface{}) {
// if fh, err := ioutil.ReadFile(file); err == nil {
// log.Debugf("Found Config file: %s", file)
// if err := yaml.Unmarshal(fh, &opts); err != nil {
// log.Errorf("Unable to parse %s: %s", file, err)
// }
// }
// }
// func populateEnv(opts map[string]interface{}) {
// for k, v := range opts {
// envName := fmt.Sprintf("JIRA_%s", strings.ToUpper(k))
// var val string
// switch t := v.(type) {
// case string:
// val = t
// case int, int8, int16, int32, int64:
// val = fmt.Sprintf("%d", t)
// case float32, float64:
// val = fmt.Sprintf("%f", t)
// case bool:
// val = fmt.Sprintf("%t", t)
// default:
// val = fmt.Sprintf("%v", t)
// }
// os.Setenv(envName, val)
// }
// }
// func loadConfigs(opts map[string]interface{}) {
// populateEnv(opts)
// paths := jira.FindParentPaths(".jira.d/config.yml")
// // prepend
// paths = append(paths, "/etc/go-jira.yml")
// // iterate paths in reverse
// for i := 0; i < len(paths); i++ {
// file := paths[i]
// if stat, err := os.Stat(file); err == nil {
// tmp := make(map[string]interface{})
// // check to see if config file is exectuable
// if stat.Mode()&0111 == 0 {
// parseYaml(file, tmp)
// } else {
// log.Debugf("Found Executable Config file: %s", file)
// // it is executable, so run it and try to parse the output
// cmd := exec.Command(file)
// stdout := bytes.NewBufferString("")
// cmd.Stdout = stdout
// cmd.Stderr = bytes.NewBufferString("")
// if err := cmd.Run(); err != nil {
// log.Errorf("%s is exectuable, but it failed to execute: %s\n%s", file, err, cmd.Stderr)
// os.Exit(1)
// }
// yaml.Unmarshal(stdout.Bytes(), &tmp)
// }
// for k, v := range tmp {
// if _, ok := opts[k]; !ok {
// log.Debugf("Setting %q to %#v from %s", k, v, file)
// opts[k] = v
// }
// }
// populateEnv(opts)
// }
// }
// }
+64 -323
View File
@@ -31,17 +31,6 @@ type JiraCli struct {
oreoAgent *oreo.Client
}
func New(configDir string) *JiraCli {
agent := oreo.New().WithCookieFile(filepath.Join(homedir(), configDir, "cookies.js"))
return &JiraCli{
ConfigDir: configDir,
Jira: jira.Jira{
UA: agent,
},
oreoAgent: agent,
}
}
type Exit struct {
Code int
}
@@ -55,6 +44,70 @@ type GlobalOptions struct {
User string `json:"user,omitempty", yaml:"user,omitempty"`
}
type CommandRegistryEntry struct {
Help string
ExecuteFunc func() error
UsageFunc func(*kingpin.CmdClause) error
}
type CommandRegistry struct {
Command string
Aliases []string
Entry *CommandRegistryEntry
Default bool
}
// either kingpin.Application or kingpin.CmdClause fit this interface
type kingpinAppOrCommand interface {
Command(string, string) *kingpin.CmdClause
GetCommand(string) *kingpin.CmdClause
}
func New(configDir string) *JiraCli {
agent := oreo.New().WithCookieFile(filepath.Join(homedir(), configDir, "cookies.js"))
return &JiraCli{
ConfigDir: configDir,
Jira: jira.Jira{
UA: agent,
},
oreoAgent: agent,
}
}
func (jc *JiraCli) Register(app *kingpin.Application, reg []CommandRegistry) {
for _, command := range reg {
copy := command
commandFields := strings.Fields(copy.Command)
var appOrCmd kingpinAppOrCommand = app
if len(commandFields) > 1 {
for _, name := range commandFields[0 : len(commandFields)-1] {
tmp := appOrCmd.GetCommand(name)
if tmp == nil {
tmp = appOrCmd.Command(name, "")
}
appOrCmd = tmp
}
}
cmd := appOrCmd.Command(commandFields[len(commandFields)-1], copy.Entry.Help)
for _, alias := range copy.Aliases {
cmd = cmd.Alias(alias)
}
if copy.Default {
cmd = cmd.Default()
}
if copy.Entry.UsageFunc != nil {
copy.Entry.UsageFunc(cmd)
}
cmd.Action(
func(_ *kingpin.ParseContext) error {
return copy.Entry.ExecuteFunc()
},
)
}
}
func (jc *JiraCli) GlobalUsage(cmd *kingpin.CmdClause, opts *GlobalOptions) error {
jc.LoadConfigs(cmd, opts)
cmd.PreAction(func(_ *kingpin.ParseContext) error {
@@ -265,315 +318,3 @@ func (jc *JiraCli) editLoop(opts *GlobalOptions, input interface{}, output inter
}
return nil
}
// // New creates go-jira client object
// func New(opts map[string]interface{}) *Cli {
// homedir := homedir()
// cookieJar, _ := cookiejar.New(nil)
// endpoint, _ := opts["endpoint"].(string)
// url, _ := url.Parse(strings.TrimRight(endpoint, "/"))
// if project, ok := opts["project"].(string); ok {
// opts["project"] = strings.ToUpper(project)
// }
// var ua *http.Client
// if unixProxyPath, ok := opts["unixproxy"].(string); ok {
// ua = &http.Client{
// Jar: cookieJar,
// Transport: UnixProxy(unixProxyPath),
// }
// } else {
// transport := &http.Transport{
// Proxy: http.ProxyFromEnvironment,
// TLSClientConfig: &tls.Config{},
// }
// if insecureSkipVerify, ok := opts["insecure"].(bool); ok {
// transport.TLSClientConfig.InsecureSkipVerify = insecureSkipVerify
// }
// ua = &http.Client{
// Jar: cookieJar,
// Transport: transport,
// }
// }
// cli := &Cli{
// endpoint: url,
// opts: opts,
// cookieFile: filepath.Join(homedir, ".jira.d", "cookies.js"),
// ua: ua,
// }
// cli.ua.Jar.SetCookies(url, cli.loadCookies())
// return cli
// }
// // NoChangesFound is an error returned from when editing templates
// // and no modifications were made while editing
// type NoChangesFound struct{}
// func (f NoChangesFound) Error() string {
// return "No changes found, aborting"
// }
// func (c *Cli) editTemplate(template string, tmpFilePrefix string, templateData map[string]interface{}, templateProcessor func(string) error) error {
// tmpdir := filepath.Join(homedir(), ".jira.d", "tmp")
// if err := mkdir(tmpdir); err != nil {
// return err
// }
// fh, err := ioutil.TempFile(tmpdir, tmpFilePrefix)
// if err != nil {
// log.Errorf("Failed to make temp file in %s: %s", tmpdir, err)
// return err
// }
// oldFileName := fh.Name()
// tmpFileName := fmt.Sprintf("%s.yml", oldFileName)
// // close tmpfile so we can rename on windows
// fh.Close()
// if err := os.Rename(oldFileName, tmpFileName); err != nil {
// log.Errorf("Failed to rename %s to %s: %s", oldFileName, tmpFileName, err)
// return err
// }
// fh, err = os.OpenFile(tmpFileName, os.O_RDWR|os.O_EXCL, 0600)
// if err != nil {
// log.Errorf("Failed to reopen temp file file in %s: %s", tmpFileName, err)
// return err
// }
// defer fh.Close()
// defer func() {
// os.Remove(tmpFileName)
// }()
// err = runTemplate(template, templateData, fh)
// if err != nil {
// return err
// }
// fh.Close()
// editor, ok := c.opts["editor"].(string)
// if !ok {
// editor = os.Getenv("JIRA_EDITOR")
// if editor == "" {
// editor = os.Getenv("EDITOR")
// if editor == "" {
// editor = "vim"
// }
// }
// }
// editing := c.getOptBool("edit", true)
// tmpFileNameOrig := fmt.Sprintf("%s.orig", tmpFileName)
// copyFile(tmpFileName, tmpFileNameOrig)
// defer func() {
// os.Remove(tmpFileNameOrig)
// }()
// for true {
// if editing {
// shell, _ := shellquote.Split(editor)
// shell = append(shell, tmpFileName)
// log.Debugf("Running: %#v", shell)
// cmd := exec.Command(shell[0], shell[1:]...)
// cmd.Stdout, cmd.Stderr, cmd.Stdin = os.Stdout, os.Stderr, os.Stdin
// if err := cmd.Run(); err != nil {
// log.Errorf("Failed to edit template with %s: %s", editor, err)
// if promptYN("edit again?", true) {
// continue
// }
// return err
// }
// diff := exec.Command("diff", "-q", tmpFileNameOrig, tmpFileName)
// // if err == nil then diff found no changes
// if err := diff.Run(); err == nil {
// return NoChangesFound{}
// }
// }
// edited := make(map[string]interface{})
// var data []byte
// if data, err = ioutil.ReadFile(tmpFileName); err != nil {
// log.Errorf("Failed to read tmpfile %s: %s", tmpFileName, err)
// if editing && promptYN("edit again?", true) {
// continue
// }
// return err
// }
// if err := yaml.Unmarshal(data, &edited); err != nil {
// log.Errorf("Failed to parse YAML: %s", err)
// if editing && promptYN("edit again?", true) {
// continue
// }
// return err
// }
// var fixed interface{}
// if fixed, err = yamlFixup(edited); err != nil {
// return err
// }
// edited = fixed.(map[string]interface{})
// // if you want to abort editing a jira issue then
// // you can add the "abort: true" flag to the document
// // and we will abort now
// if val, ok := edited["abort"].(bool); ok && val {
// log.Infof("abort flag found in template, quiting")
// return fmt.Errorf("abort flag found in template, quiting")
// }
// if _, ok := templateData["meta"]; ok {
// mf := templateData["meta"].(map[string]interface{})["fields"]
// if f, ok := edited["fields"].(map[string]interface{}); ok {
// for k := range f {
// if _, ok := mf.(map[string]interface{})[k]; !ok {
// err := fmt.Errorf("Field %s is not editable", k)
// log.Errorf("%s", err)
// if editing && promptYN("edit again?", true) {
// continue
// }
// return err
// }
// }
// }
// }
// json, err := jsonEncode(edited)
// if err != nil {
// return err
// }
// if err := templateProcessor(json); err != nil {
// log.Errorf("%s", err)
// if editing && promptYN("edit again?", true) {
// continue
// }
// }
// return nil
// }
// return nil
// }
// // SaveData will write out the yaml formated --saveFile file with provided data
// func (c *Cli) SaveData(data interface{}) error {
// if val, ok := c.opts["saveFile"].(string); ok && val != "" {
// yamlWrite(val, data)
// }
// return nil
// }
// // FindIssues will return a list of issues that match the given options.
// // If the "query" option is undefined it will generate a JQL query
// // using any/all of the provide options: project, component, assignee,
// // issuetype, watcher, reporter, sort
// // Further it will restrict the fields being extracted from the jira
// // response with the 'queryfields' option
// func (c *Cli) FindIssues() (interface{}, error) {
// var query string
// var ok bool
// // project = BAKERY and status not in (Resolved, Closed)
// if query, ok = c.opts["query"].(string); !ok {
// qbuff := bytes.NewBufferString("resolution = unresolved")
// var project string
// if project, ok = c.opts["project"].(string); !ok {
// err := fmt.Errorf("Missing required arguments, either 'query' or 'project' are required")
// log.Errorf("%s", err)
// return nil, err
// }
// qbuff.WriteString(fmt.Sprintf(" AND project = '%s'", project))
// if component, ok := c.opts["component"]; ok {
// qbuff.WriteString(fmt.Sprintf(" AND component = '%s'", component))
// }
// if assignee, ok := c.opts["assignee"]; ok {
// qbuff.WriteString(fmt.Sprintf(" AND assignee = '%s'", assignee))
// }
// if issuetype, ok := c.opts["issuetype"]; ok {
// qbuff.WriteString(fmt.Sprintf(" AND issuetype = '%s'", issuetype))
// }
// if watcher, ok := c.opts["watcher"]; ok {
// qbuff.WriteString(fmt.Sprintf(" AND watcher = '%s'", watcher))
// }
// if reporter, ok := c.opts["reporter"]; ok {
// qbuff.WriteString(fmt.Sprintf(" AND reporter = '%s'", reporter))
// }
// if sort, ok := c.opts["sort"]; ok && sort != "" {
// qbuff.WriteString(fmt.Sprintf(" ORDER BY %s", sort))
// }
// query = qbuff.String()
// }
// fields := []string{"summary"}
// if qf, ok := c.opts["queryfields"].(string); ok {
// fields = strings.Split(qf, ",")
// }
// json, err := jsonEncode(map[string]interface{}{
// "jql": query,
// "startAt": c.opts["start_at"],
// "maxResults": c.opts["max_results"],
// "fields": fields,
// "expand": c.expansions(),
// })
// if err != nil {
// return nil, err
// }
// uri := fmt.Sprintf("%s/rest/api/2/search", c.endpoint)
// var data interface{}
// if data, err = responseToJSON(c.post(uri, json)); err != nil {
// return nil, err
// }
// return data, nil
// }
// // GetOptString will extract the string from the Cli object options
// // otherwise return the provided default
// func (c *Cli) GetOptString(optName string, dflt string) string {
// return c.getOptString(optName, dflt)
// }
// func (c *Cli) getOptString(optName string, dflt string) string {
// if val, ok := c.opts[optName].(string); ok {
// return val
// }
// return dflt
// }
// // GetOptBool will extract the boolean value from the Client object options
// // otherwise return the provided default\
// func (c *Cli) GetOptBool(optName string, dflt bool) bool {
// return c.getOptBool(optName, dflt)
// }
// func (c *Cli) getOptBool(optName string, dflt bool) bool {
// if val, ok := c.opts[optName].(bool); ok {
// return val
// }
// return dflt
// }
// // expansions returns a comma-separated list of values for field expansion
// func (c *Cli) expansions() []string {
// var expansions []string
// if x, ok := c.opts["expand"].(string); ok {
// expansions = strings.Split(x, ",")
// }
// return expansions
// }
-82
View File
@@ -1,83 +1 @@
package jiracli
import (
"strings"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
type CommandRegistryEntry struct {
Help string
ExecuteFunc func() error
UsageFunc func(*kingpin.CmdClause) error
}
type CommandRegistry struct {
Command string
Aliases []string
Entry *CommandRegistryEntry
Default bool
}
// either kingpin.Application or kingpin.CmdClause fit this interface
type kingpinAppOrCommand interface {
Command(string, string) *kingpin.CmdClause
GetCommand(string) *kingpin.CmdClause
}
func (jc *JiraCli) Register(app *kingpin.Application, reg []CommandRegistry) {
for _, command := range reg {
copy := command
commandFields := strings.Fields(copy.Command)
var appOrCmd kingpinAppOrCommand = app
if len(commandFields) > 1 {
for _, name := range commandFields[0 : len(commandFields)-1] {
tmp := appOrCmd.GetCommand(name)
if tmp == nil {
tmp = appOrCmd.Command(name, "")
}
appOrCmd = tmp
}
}
cmd := appOrCmd.Command(commandFields[len(commandFields)-1], copy.Entry.Help)
for _, alias := range copy.Aliases {
cmd = cmd.Alias(alias)
}
if copy.Default {
cmd = cmd.Default()
}
if copy.Entry.UsageFunc != nil {
copy.Entry.UsageFunc(cmd)
}
cmd.Action(
func(_ *kingpin.ParseContext) error {
return copy.Entry.ExecuteFunc()
},
)
}
}
// // CmdRequest will use the given uri to make a request and potentially send provided content.
// func (c *Cli) CmdRequest(uri, content string) (err error) {
// log.Debugf("request called")
// if !strings.HasPrefix(uri, "http") {
// uri = fmt.Sprintf("%s%s", c.endpoint, uri)
// }
// method := strings.ToUpper(c.opts["method"].(string))
// var data interface{}
// if method == "GET" {
// data, err = responseToJSON(c.get(uri))
// } else if method == "POST" {
// data, err = responseToJSON(c.post(uri, content))
// } else if method == "PUT" {
// data, err = responseToJSON(c.put(uri, content))
// }
// if err != nil {
// return err
// }
// return runTemplate(c.getTemplate("request"), data, nil)
// }
-8
View File
@@ -43,15 +43,7 @@ func (jc *JiraCli) CmdEditUsage(cmd *kingpin.CmdClause, opts *EditOptions) error
jc.EditorUsage(cmd, &opts.GlobalOptions)
jc.TemplateUsage(cmd, &opts.GlobalOptions)
cmd.Flag("noedit", "Disable opening the editor").BoolVar(&opts.SkipEditing)
// 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').Default("500").IntVar(&opts.MaxResults)
// cmd.Flag("project", "Project to search for").Short('p').StringVar(&opts.Project)
cmd.Flag("query", "Jira Query Language (JQL) expression for the search to edit multiple issues").Short('q').StringVar(&opts.Query)
// cmd.Flag("reporter", "Reporter to search for").Short('r').StringVar(&opts.Reporter)
// cmd.Flag("sort", "Sort order to return").Short('s').Default("priority asc, key").StringVar(&opts.Sort)
// cmd.Flag("watcher", "Watcher to search for").Short('w').StringVar(&opts.Watcher)
cmd.Flag("comment", "Comment message for issue").Short('m').PreAction(func(ctx *kingpin.ParseContext) error {
opts.Overrides["comment"] = flagValue(ctx, "comment")
return nil
+89
View File
@@ -0,0 +1,89 @@
package jiracli
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/url"
"strings"
"github.com/coryb/oreo"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
type RequestOptions struct {
GlobalOptions
Method string
URI string
Data string
}
func (jc *JiraCli) CmdRequestRegistry() *CommandRegistryEntry {
opts := RequestOptions{
GlobalOptions: GlobalOptions{
Template: "request",
},
Method: "GET",
}
return &CommandRegistryEntry{
"Open issue in requestr",
func() error {
return jc.CmdRequest(&opts)
},
func(cmd *kingpin.CmdClause) error {
return jc.CmdRequestUsage(cmd, &opts)
},
}
}
func (jc *JiraCli) CmdRequestUsage(cmd *kingpin.CmdClause, opts *RequestOptions) error {
if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil {
return err
}
cmd.Flag("method", "HTTP request method to use").Short('m').EnumVar(&opts.Method, "GET", "PUT", "POST", "DELETE")
cmd.Arg("API", "Path to Jira API (ie: /rest/api/2/issue)").Required().StringVar(&opts.URI)
cmd.Arg("JSON", "JSON Content to send to API").Required().StringVar(&opts.Data)
return nil
}
// CmdRequest open the default system requestr to the provided issue
func (jc *JiraCli) CmdRequest(opts *RequestOptions) error {
uri := opts.URI
if !strings.HasPrefix(uri, "http") {
uri = jc.Endpoint + uri
}
parsedURI, err := url.Parse(uri)
if err != nil {
return err
}
builder := oreo.RequestBuilder(parsedURI).WithMethod(opts.Method)
if opts.Data != "" {
builder = builder.WithJSON(opts.Data)
}
resp, err := jc.UA.Do(builder.Build())
if err != nil {
return err
}
defer resp.Body.Close()
content, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
if len(content) == 0 {
fmt.Println("No Content")
return nil
}
var data interface{}
err = json.Unmarshal(content, &data)
if err != nil {
return fmt.Errorf("JSON Parse Error: %s from %q", err, content)
}
return jc.runTemplate(opts.Template, &data, nil)
}
-121
View File
@@ -67,17 +67,6 @@ func flagValue(ctx *kingpin.ParseContext, name string) string {
return ""
}
// func readFile(file string) string {
// var bytes []byte
// var err error
// log.Debugf("readFile: reading %q", file)
// if bytes, err = ioutil.ReadFile(file); err != nil {
// log.Errorf("Failed to read file %s: %s", file, err)
// os.Exit(1)
// }
// return string(bytes)
// }
func copyFile(src, dst string) (err error) {
var s, d *os.File
if s, err = os.Open(src); err == nil {
@@ -121,98 +110,6 @@ func dateFormat(format string, content string) (string, error) {
return t.Format(format), nil
}
// // RunTemplate will run the give templateContent as a golang text/template
// // and pass the provided data to the template execution. It will write
// // the output to the provided "out" writer.
// func RunTemplate(templateContent string, data interface{}, out io.Writer) error {
// return runTemplate(templateContent, data, out)
// }
// func responseToJSON(resp *http.Response, err error) (interface{}, error) {
// if err != nil {
// return nil, err
// }
// data := jsonDecode(resp.Body)
// if resp.StatusCode == 400 {
// if val, ok := data.(map[string]interface{})["errorMessages"]; ok {
// for _, errMsg := range val.([]interface{}) {
// log.Errorf("%s", errMsg)
// }
// }
// }
// return data, nil
// }
// func jsonDecode(io io.Reader) interface{} {
// content, err := ioutil.ReadAll(io)
// var data interface{}
// err = json.Unmarshal(content, &data)
// if err != nil {
// log.Errorf("JSON Parse Error: %s from %s", err, content)
// }
// return data
// }
// func jsonEncode(data interface{}) (string, error) {
// buffer := bytes.NewBuffer(make([]byte, 0))
// enc := json.NewEncoder(buffer)
// err := enc.Encode(data)
// if err != nil {
// log.Errorf("Failed to encode data %s: %s", data, err)
// return "", err
// }
// return buffer.String(), nil
// }
// func jsonWrite(file string, data interface{}) {
// fh, err := os.OpenFile(file, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
// defer fh.Close()
// if err != nil {
// log.Errorf("Failed to open %s: %s", file, err)
// os.Exit(1)
// }
// enc := json.NewEncoder(fh)
// enc.Encode(data)
// }
// func yamlWrite(file string, data interface{}) {
// fh, err := os.OpenFile(file, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
// defer fh.Close()
// if err != nil {
// log.Errorf("Failed to open %s: %s", file, err)
// os.Exit(1)
// }
// if out, err := yaml.Marshal(data); err != nil {
// log.Errorf("Failed to marshal yaml %v: %s", data, err)
// os.Exit(1)
// } else {
// fh.Write(out)
// }
// }
// func promptYN(prompt string, yes bool) bool {
// reader := bufio.NewReader(os.Stdin)
// if !yes {
// prompt = fmt.Sprintf("%s [y/N]: ", prompt)
// } else {
// prompt = fmt.Sprintf("%s [Y/n]: ", prompt)
// }
// fmt.Printf("%s", prompt)
// text, _ := reader.ReadString('\n')
// ans := strings.ToLower(strings.TrimRight(text, "\n"))
// if ans == "" {
// return yes
// }
// if strings.HasPrefix(ans, "y") {
// return true
// }
// return false
// }
// this is a HACK to make yaml parsed documents to be serializable
// to json, so prevent this:
// json: unsupported type: map[interface {}]interface {}
@@ -283,21 +180,3 @@ func yamlFixup(data interface{}) (interface{}, error) {
return d, nil
}
}
// func mkdir(dir string) error {
// if stat, err := os.Stat(dir); err != nil && !os.IsNotExist(err) {
// log.Errorf("Failed to stat %s: %s", dir, err)
// return err
// } else if err == nil && !stat.IsDir() {
// err := fmt.Errorf("%s exists and is not a directory", dir)
// log.Errorf("%s", err)
// return err
// } else {
// // dir does not exist, so try to create it
// if err := os.MkdirAll(dir, 0755); err != nil {
// log.Errorf("Failed to mkdir -p %s: %s", dir, err)
// return err
// }
// }
// return nil
// }