~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/cmd/juju/action/list.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2014, 2015 Canonical Ltd.
 
2
// Licensed under the AGPLv3, see LICENCE file for details.
 
3
 
 
4
package action
 
5
 
 
6
import (
 
7
        "bytes"
 
8
        "fmt"
 
9
        "strings"
 
10
        "text/tabwriter"
 
11
 
 
12
        "github.com/juju/cmd"
 
13
        errors "github.com/juju/errors"
 
14
        "github.com/juju/utils"
 
15
        "gopkg.in/juju/names.v2"
 
16
        "launchpad.net/gnuflag"
 
17
 
 
18
        "github.com/juju/juju/apiserver/params"
 
19
        "github.com/juju/juju/cmd/modelcmd"
 
20
)
 
21
 
 
22
func NewListCommand() cmd.Command {
 
23
        return modelcmd.Wrap(&listCommand{})
 
24
}
 
25
 
 
26
// listCommand lists actions defined by the charm of a given service.
 
27
type listCommand struct {
 
28
        ActionCommandBase
 
29
        applicationTag names.ApplicationTag
 
30
        fullSchema     bool
 
31
        out            cmd.Output
 
32
}
 
33
 
 
34
const listDoc = `
 
35
List the actions available to run on the target application, with a short
 
36
description.  To show the full schema for the actions, use --schema.
 
37
 
 
38
For more information, see also the 'run-action' command, which executes actions.
 
39
`
 
40
 
 
41
// Set up the output.
 
42
func (c *listCommand) SetFlags(f *gnuflag.FlagSet) {
 
43
        c.out.AddFlags(f, "smart", cmd.DefaultFormatters)
 
44
        f.BoolVar(&c.fullSchema, "schema", false, "Display the full action schema")
 
45
}
 
46
 
 
47
func (c *listCommand) Info() *cmd.Info {
 
48
        return &cmd.Info{
 
49
                Name:    "actions",
 
50
                Args:    "<application name>",
 
51
                Purpose: "List actions defined for a service.",
 
52
                Doc:     listDoc,
 
53
                Aliases: []string{"list-actions"},
 
54
        }
 
55
}
 
56
 
 
57
// Init validates the service name and any other options.
 
58
func (c *listCommand) Init(args []string) error {
 
59
        switch len(args) {
 
60
        case 0:
 
61
                return errors.New("no application name specified")
 
62
        case 1:
 
63
                svcName := args[0]
 
64
                if !names.IsValidApplication(svcName) {
 
65
                        return errors.Errorf("invalid application name %q", svcName)
 
66
                }
 
67
                c.applicationTag = names.NewApplicationTag(svcName)
 
68
                return nil
 
69
        default:
 
70
                return cmd.CheckEmpty(args[1:])
 
71
        }
 
72
}
 
73
 
 
74
// Run grabs the Actions spec from the api.  It then sets up a sensible
 
75
// output format for the map.
 
76
func (c *listCommand) Run(ctx *cmd.Context) error {
 
77
        api, err := c.NewActionAPIClient()
 
78
        if err != nil {
 
79
                return err
 
80
        }
 
81
        defer api.Close()
 
82
 
 
83
        actions, err := api.ApplicationCharmActions(params.Entity{c.applicationTag.String()})
 
84
        if err != nil {
 
85
                return err
 
86
        }
 
87
 
 
88
        if len(actions) == 0 {
 
89
                return c.out.Write(ctx, "No actions defined for "+c.applicationTag.Id())
 
90
        }
 
91
 
 
92
        if c.fullSchema {
 
93
                verboseSpecs := make(map[string]interface{})
 
94
                for k, v := range actions {
 
95
                        verboseSpecs[k] = v.Params
 
96
                }
 
97
 
 
98
                return c.out.Write(ctx, verboseSpecs)
 
99
        }
 
100
 
 
101
        shortOutput := make(map[string]string)
 
102
        var sortedNames []string
 
103
        for name, action := range actions {
 
104
                shortOutput[name] = action.Description
 
105
                if shortOutput[name] == "" {
 
106
                        shortOutput[name] = "No description"
 
107
                }
 
108
                sortedNames = append(sortedNames, name)
 
109
        }
 
110
        utils.SortStringsNaturally(sortedNames)
 
111
        return c.printTabular(ctx, shortOutput, sortedNames)
 
112
}
 
113
 
 
114
// printTabular prints the list of actions in tabular format
 
115
func (c *listCommand) printTabular(ctx *cmd.Context, actions map[string]string, sortedNames []string) error {
 
116
        var out bytes.Buffer
 
117
        const (
 
118
                // To format things into columns.
 
119
                minwidth = 0
 
120
                tabwidth = 2
 
121
                padding  = 2
 
122
                padchar  = ' '
 
123
                flags    = 0
 
124
        )
 
125
        tw := tabwriter.NewWriter(&out, minwidth, tabwidth, padding, padchar, flags)
 
126
        fmt.Fprintf(tw, "%s\t%s\n", "ACTION", "DESCRIPTION")
 
127
        for _, name := range sortedNames {
 
128
                fmt.Fprintf(tw, "%s\t%s\n", name, strings.TrimSpace(actions[name]))
 
129
        }
 
130
        tw.Flush()
 
131
        return c.out.Write(ctx, string(out.Bytes()))
 
132
}