Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cli): enable extended client access #285

Merged
merged 8 commits into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 9 additions & 26 deletions internals/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ const defaultPebbleDir = "/var/lib/pebble/default"
// ErrExtraArgs is returned if extra arguments to a command are found
var ErrExtraArgs = fmt.Errorf("too many arguments for command")

// CmdOptions exposes state made accessible during command execution.
type CmdOptions struct {
Client *client.Client
Parser *flags.Parser
}

// CmdInfo holds information needed by the CLI to execute commands and
// populate entries in the help manual.
type CmdInfo struct {
Expand All @@ -67,9 +73,8 @@ type CmdInfo struct {
// command, and in the Pebble man page.
Description string

// Builder is a function that creates a new instance of the command
// struct containing an Execute(args []string) implementation.
Builder func() flags.Commander
// New is a function that creates a new instance of the command.
New func(*CmdOptions) flags.Commander
flotter marked this conversation as resolved.
Show resolved Hide resolved

// ArgsHelp (optional) contains help about the command-line arguments
// (including options) supported by the command.
Expand Down Expand Up @@ -139,22 +144,6 @@ func fixupArg(optName string) string {
return optName
}

type clientSetter interface {
setClient(*client.Client)
}

type clientMixin struct {
client *client.Client
}

func (ch *clientMixin) setClient(cli *client.Client) {
ch.client = cli
}

type parserSetter interface {
setParser(*flags.Parser)
}

type defaultOptions struct {
Version func() `long:"version" hidden:"yes" description:"Print the version and exit"`
}
Expand Down Expand Up @@ -192,13 +181,7 @@ func Parser(cli *client.Client) *flags.Parser {

// Add all commands
for _, c := range commands {
obj := c.Builder()
if x, ok := obj.(clientSetter); ok {
x.setClient(cli)
}
if x, ok := obj.(parserSetter); ok {
x.setParser(parser)
}
obj := c.New(&CmdOptions{Client: cli, Parser: parser})
anpep marked this conversation as resolved.
Show resolved Hide resolved

var target *flags.Command
if c.Debug {
Expand Down
7 changes: 5 additions & 2 deletions internals/cli/cmd_add.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ label (or append if the label is not found).
`

type cmdAdd struct {
clientMixin
client *client.Client

Combine bool `long:"combine"`
Positional struct {
Label string `positional-arg-name:"<label>" required:"1"`
Expand All @@ -48,7 +49,9 @@ func init() {
ArgsHelp: map[string]string{
"--combine": "Combine the new layer with an existing layer that has the given label (default is to append)",
},
Builder: func() flags.Commander { return &cmdAdd{} },
New: func(opts *CmdOptions) flags.Commander {
return &cmdAdd{client: opts.Client}
},
})
}

Expand Down
8 changes: 6 additions & 2 deletions internals/cli/cmd_autostart.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ to start by default.
`

type cmdAutoStart struct {
client *client.Client

waitMixin
}

Expand All @@ -36,7 +38,9 @@ func init() {
Summary: cmdAutoStartSummary,
Description: cmdAutoStartDescription,
ArgsHelp: waitArgsHelp,
Builder: func() flags.Commander { return &cmdAutoStart{} },
New: func(opts *CmdOptions) flags.Commander {
return &cmdAutoStart{client: opts.Client}
},
})
}

Expand All @@ -51,7 +55,7 @@ func (cmd cmdAutoStart) Execute(args []string) error {
return err
}

if _, err := cmd.wait(changeID); err != nil {
if _, err := cmd.wait(cmd.client, changeID); err != nil {
anpep marked this conversation as resolved.
Show resolved Hide resolved
if err == noWait {
return nil
}
Expand Down
15 changes: 11 additions & 4 deletions internals/cli/cmd_changes.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ The changes command displays a summary of system changes performed recently.
`

type cmdChanges struct {
clientMixin
client *client.Client

timeMixin
Positional struct {
Service string `positional-arg-name:"<service>"`
Expand All @@ -44,6 +45,8 @@ change that happened recently.
`

type cmdTasks struct {
client *client.Client

timeMixin
changeIDMixin
}
Expand All @@ -54,14 +57,18 @@ func init() {
Summary: cmdChangesSummary,
Description: cmdChangesDescription,
ArgsHelp: timeArgsHelp,
Builder: func() flags.Commander { return &cmdChanges{} },
New: func(opts *CmdOptions) flags.Commander {
return &cmdChanges{client: opts.Client}
},
})
AddCommand(&CmdInfo{
Name: "tasks",
Summary: cmdTasksSummary,
Description: cmdTasksDescription,
ArgsHelp: merge(changeIDMixinArgsHelp, timeArgsHelp),
Builder: func() flags.Commander { return &cmdTasks{} },
New: func(opts *CmdOptions) flags.Commander {
return &cmdTasks{client: opts.Client}
},
})
}

Expand Down Expand Up @@ -133,7 +140,7 @@ func (c *cmdChanges) Execute(args []string) error {
}

func (c *cmdTasks) Execute([]string) error {
chid, err := c.GetChangeID()
chid, err := c.GetChangeID(c.client)
if err != nil {
if err == noChangeFoundOK {
return nil
Expand Down
7 changes: 5 additions & 2 deletions internals/cli/cmd_checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ arguments.
`

type cmdChecks struct {
clientMixin
client *client.Client

Level string `long:"level"`
Positional struct {
Checks []string `positional-arg-name:"<check>"`
Expand All @@ -45,7 +46,9 @@ func init() {
ArgsHelp: map[string]string{
"--level": `Check level to filter for ("alive" or "ready")`,
},
Builder: func() flags.Commander { return &cmdChecks{} },
New: func(opts *CmdOptions) flags.Commander {
return &cmdChecks{client: opts.Client}
},
})
}

Expand Down
16 changes: 8 additions & 8 deletions internals/cli/cmd_enter.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (

"github.com/canonical/go-flags"

"github.com/canonical/pebble/client"
"github.com/canonical/pebble/internals/logger"
)

Expand Down Expand Up @@ -46,21 +47,24 @@ These subcommands are currently supported:
`

type cmdEnter struct {
clientMixin
client *client.Client
parser *flags.Parser

sharedRunEnterOpts
Run bool `long:"run"`
Positional struct {
Cmd []string `positional-arg-name:"<subcommand>"`
} `positional-args:"yes"`
parser *flags.Parser
}

func init() {
AddCommand(&CmdInfo{
Name: "enter",
Summary: cmdEnterSummary,
Description: cmdEnterDescription,
Builder: func() flags.Commander { return &cmdEnter{} },
New: func(opts *CmdOptions) flags.Commander {
return &cmdEnter{client: opts.Client, parser: opts.Parser}
},
ArgsHelp: merge(sharedRunEnterArgsHelp, map[string]string{
"--run": "Start default services before executing subcommand",
}),
Expand Down Expand Up @@ -104,8 +108,8 @@ func (cmd *cmdEnter) Execute(args []string) error {

runCmd := cmdRun{
sharedRunEnterOpts: cmd.sharedRunEnterOpts,
client: cmd.client,
}
runCmd.setClient(cmd.client)

if len(cmd.Positional.Cmd) == 0 {
runCmd.run(nil)
Expand Down Expand Up @@ -195,7 +199,3 @@ func (cmd *cmdEnter) Execute(args []string) error {

return err
}

func (cmd *cmdEnter) setParser(parser *flags.Parser) {
cmd.parser = parser
}
7 changes: 5 additions & 2 deletions internals/cli/cmd_exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ pebble exec --timeout 10s -- echo -n foo bar
`

type cmdExec struct {
clientMixin
client *client.Client

WorkingDir string `short:"w"`
Env []string `long:"env"`
UserID *int `long:"uid"`
Expand Down Expand Up @@ -81,7 +82,9 @@ func init() {
"-I": "Disable interactive mode and use a pipe for stdin",
},
PassAfterNonOption: true,
Builder: func() flags.Commander { return &cmdExec{} },
New: func(opts *CmdOptions) flags.Commander {
return &cmdExec{client: opts.Client}
},
})
}

Expand Down
7 changes: 5 additions & 2 deletions internals/cli/cmd_help.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@ The help command displays information about commands.
`

type cmdHelp struct {
parser *flags.Parser

All bool `long:"all"`
Manpage bool `long:"man" hidden:"true"`
Positional struct {
Subs []string `positional-arg-name:"<command>"`
} `positional-args:"yes"`
parser *flags.Parser
}

func init() {
Expand All @@ -48,7 +49,9 @@ func init() {
"--all": "Show a short summary of all commands",
"--man": "Generate the manpage",
},
Builder: func() flags.Commander { return &cmdHelp{} },
New: func(opts *CmdOptions) flags.Commander {
return &cmdHelp{parser: opts.Parser}
},
})
}

Expand Down
7 changes: 5 additions & 2 deletions internals/cli/cmd_logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ if none are specified) and displays them in chronological order.
`

type cmdLogs struct {
clientMixin
client *client.Client

Follow bool `short:"f" long:"follow"`
Format string `long:"format"`
N string `short:"n"`
Expand All @@ -53,7 +54,9 @@ func init() {
"--format": "Output format: \"text\" (default) or \"json\" (JSON lines).",
"-n": "Number of logs to show (before following); defaults to 30.\nIf 'all', show all buffered logs.",
},
Builder: func() flags.Commander { return &cmdLogs{} },
New: func(opts *CmdOptions) flags.Commander {
return &cmdLogs{client: opts.Client}
},
})
}

Expand Down
9 changes: 5 additions & 4 deletions internals/cli/cmd_ls.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,11 @@ may be specified for the last path element.
`

type cmdLs struct {
clientMixin
timeMixin
client *client.Client

timeMixin
Directory bool `short:"d"`
LongFormat bool `short:"l"`

Positional struct {
Path string `positional-arg-name:"<path>"`
} `positional-args:"yes" required:"yes"`
Expand All @@ -53,7 +52,9 @@ func init() {
"-d": "List matching entries themselves, not directory contents",
"-l": "Use a long listing format",
}),
Builder: func() flags.Commander { return &cmdLs{} },
New: func(opts *CmdOptions) flags.Commander {
return &cmdLs{client: opts.Client}
},
})
}

Expand Down
9 changes: 5 additions & 4 deletions internals/cli/cmd_mkdir.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,15 @@ The mkdir command creates the specified directory.
`

type cmdMkdir struct {
clientMixin
client *client.Client

MakeParents bool `short:"p"`
Permissions string `short:"m"`
UserID *int `long:"uid"`
User string `long:"user"`
GroupID *int `long:"gid"`
Group string `long:"group"`

Positional struct {
Positional struct {
Path string `positional-arg-name:"<path>"`
} `positional-args:"yes" required:"yes"`
}
Expand All @@ -49,7 +48,6 @@ func init() {
Name: "mkdir",
Summary: cmdMkdirSummary,
Description: cmdMkdirDescription,
Builder: func() flags.Commander { return &cmdMkdir{} },
ArgsHelp: map[string]string{
"-p": "Create parent directories as needed",
"-m": "Set permissions (e.g. 0644)",
Expand All @@ -58,6 +56,9 @@ func init() {
"--gid": "Use specified group ID",
"--group": "Use specified group name",
},
New: func(opts *CmdOptions) flags.Commander {
return &cmdMkdir{client: opts.Client}
},
})
}

Expand Down
6 changes: 4 additions & 2 deletions internals/cli/cmd_plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,17 @@ format. Layers are combined according to the override rules defined in them.
`

type cmdPlan struct {
clientMixin
client *client.Client
}

func init() {
AddCommand(&CmdInfo{
Name: "plan",
Summary: cmdPlanSummary,
Description: cmdPlanDescription,
Builder: func() flags.Commander { return &cmdPlan{} },
New: func(opts *CmdOptions) flags.Commander {
return &cmdPlan{client: opts.Client}
},
})
}

Expand Down
Loading
Loading