Skip to content

Commit

Permalink
[CLC-228] Scripting mode (hazelcast#305)
Browse files Browse the repository at this point in the history
Added the scripting mode
  • Loading branch information
yuce authored Aug 25, 2023
1 parent ef475e6 commit 30e1791
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 72 deletions.
3 changes: 3 additions & 0 deletions base/commands/demo/dummy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package demo

// This file exists only for compilation
2 changes: 1 addition & 1 deletion base/commands/script.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func (cm ScriptCommand) Exec(ctx context.Context, ec plug.ExecContext) error {
Stderr: ec.Stderr(),
Stdout: ec.Stdout(),
}
m, err := ec.(*cmd.ExecContext).Main().Clone(false)
m, err := ec.(*cmd.ExecContext).Main().Clone(cmd.ModeScripting)
if err != nil {
return fmt.Errorf("cloning Main: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion base/commands/shell.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func (cm *ShellCommand) ExecInteractive(ctx context.Context, ec plug.ExecContext
if len(ec.Args()) > 0 {
return puberrors.ErrNotAvailable
}
m, err := ec.(*cmd.ExecContext).Main().Clone(true)
m, err := ec.(*cmd.ExecContext).Main().Clone(cmd.ModeInteractive)
if err != nil {
return fmt.Errorf("cloning Main: %w", err)
}
Expand Down
60 changes: 34 additions & 26 deletions clc/cmd/clc.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,30 @@ var (
MainCommandShortHelp = "Hazelcast CLC"
)

type Mode int

const (
ModeNonInteractive Mode = iota
ModeInteractive
ModeScripting
)

type Main struct {
root *cobra.Command
cmds map[string]*cobra.Command
lg *logger.Logger
stderr io.WriteCloser
stdout io.WriteCloser
stdin io.Reader
isInteractive bool
outputFormat string
configLoaded bool
props *plug.Properties
cc *CommandContext
cp config.Provider
arg0 string
ciMu *sync.Mutex
ci *atomic.Pointer[hazelcast.ClientInternal]
root *cobra.Command
cmds map[string]*cobra.Command
lg *logger.Logger
stderr io.WriteCloser
stdout io.WriteCloser
stdin io.Reader
mode Mode
outputFormat string
configLoaded bool
props *plug.Properties
cc *CommandContext
cp config.Provider
arg0 string
ciMu *sync.Mutex
ci *atomic.Pointer[hazelcast.ClientInternal]
}

func NewMain(arg0, cfgPath string, cfgProvider config.Provider, logPath, logLevel string, sio clc.IO) (*Main, error) {
Expand Down Expand Up @@ -91,7 +99,7 @@ func NewMain(arg0, cfgPath string, cfgProvider config.Provider, logPath, logLeve
m.props.Set(clc.PropertyConfig, cfgPath)
m.props.Set(clc.PropertyLogPath, logPath)
m.props.Set(clc.PropertyLogLevel, logLevel)
m.cc = NewCommandContext(rc, cfgProvider, m.isInteractive)
m.cc = NewCommandContext(rc, cfgProvider, m.mode)
if err := m.runInitializers(m.cc); err != nil {
return nil, err
}
Expand All @@ -101,9 +109,9 @@ func NewMain(arg0, cfgPath string, cfgProvider config.Provider, logPath, logLeve
return m, nil
}

func (m *Main) Clone(interactive bool) (*Main, error) {
func (m *Main) Clone(mode Mode) (*Main, error) {
mc := *m
mc.isInteractive = true
mc.mode = mode
rc := &cobra.Command{
SilenceErrors: true,
}
Expand All @@ -120,7 +128,7 @@ func (m *Main) Clone(interactive bool) (*Main, error) {
},
})
mc.cmds = map[string]*cobra.Command{}
mc.cc = NewCommandContext(rc, mc.cp, interactive)
mc.cc = NewCommandContext(rc, mc.cp, mode)
if err := mc.runInitializers(mc.cc); err != nil {
return nil, err
}
Expand All @@ -138,7 +146,7 @@ func (m *Main) Execute(ctx context.Context, args ...string) error {
var cm *cobra.Command
var cmdArgs []string
var err error
if !m.isInteractive {
if m.mode == ModeNonInteractive {
cm, cmdArgs, err = m.root.Find(args)
if err != nil {
return err
Expand Down Expand Up @@ -255,11 +263,11 @@ func (m *Main) createCommands() error {
for _, c := range plug.Registry.Commands() {
c := c
// check if current command available in current mode
if !plug.Registry.IsAvailable(m.isInteractive, c.Name) {
if !plug.Registry.IsAvailable(m.mode != ModeNonInteractive, c.Name) {
continue
}
// skip interactive commands in interactive mode
if m.isInteractive {
if m.mode == ModeInteractive {
if _, ok := c.Item.(plug.InteractiveCommander); ok {
continue
}
Expand Down Expand Up @@ -290,7 +298,7 @@ func (m *Main) createCommands() error {
SilenceUsage: true,
}
cmd.SetUsageTemplate(usageTemplate)
cc := NewCommandContext(cmd, m.cp, m.isInteractive)
cc := NewCommandContext(cmd, m.cp, m.mode)
if ci, ok := c.Item.(plug.Initializer); ok {
if err := ci.Init(cc); err != nil {
if errors.Is(err, puberrors.ErrNotAvailable) {
Expand All @@ -300,7 +308,7 @@ func (m *Main) createCommands() error {
}
}
// add the backslash prefix for top-level commands in the interactive mode
if m.isInteractive && parent == m.root {
if m.mode != ModeNonInteractive && parent == m.root {
cmd.Use = fmt.Sprintf("\\%s", cmd.Use)
}
addUniqueCommandGroup(cc, parent)
Expand All @@ -320,7 +328,7 @@ func (m *Main) createCommands() error {
Stderr: m.stderr,
Stdout: m.stdout,
}
ec, err := NewExecContext(m.lg, sio, m.props, m.isInteractive)
ec, err := NewExecContext(m.lg, sio, m.props, m.mode)
if err != nil {
return err
}
Expand Down Expand Up @@ -354,7 +362,7 @@ func (m *Main) createCommands() error {
return err
}
if ic, ok := c.Item.(plug.InteractiveCommander); ok {
ec.SetInteractive(true)
ec.SetMode(ModeInteractive)
if _, ok := c.Item.(plug.UnwrappableCommander); ok {
err = ic.ExecInteractive(ctx, ec)
} else {
Expand Down
34 changes: 17 additions & 17 deletions clc/cmd/command_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,24 @@ import (
)

type CommandContext struct {
Cmd *cobra.Command
CP config.Provider
stringValues map[string]*string
boolValues map[string]*bool
intValues map[string]*int64
isInteractive bool
isTopLevel bool
group *cobra.Group
Cmd *cobra.Command
CP config.Provider
stringValues map[string]*string
boolValues map[string]*bool
intValues map[string]*int64
mode Mode
isTopLevel bool
group *cobra.Group
}

func NewCommandContext(cmd *cobra.Command, cfgProvider config.Provider, isInteractive bool) *CommandContext {
func NewCommandContext(cmd *cobra.Command, cfgProvider config.Provider, mode Mode) *CommandContext {
return &CommandContext{
Cmd: cmd,
CP: cfgProvider,
stringValues: map[string]*string{},
boolValues: map[string]*bool{},
intValues: map[string]*int64{},
isInteractive: isInteractive,
Cmd: cmd,
CP: cfgProvider,
stringValues: map[string]*string{},
boolValues: map[string]*bool{},
intValues: map[string]*int64{},
mode: mode,
}
}

Expand Down Expand Up @@ -85,7 +85,7 @@ func (cc *CommandContext) Hide() {
}

func (cc *CommandContext) Interactive() bool {
return cc.isInteractive
return cc.mode == ModeInteractive
}

func (cc *CommandContext) SetCommandHelp(long, short string) {
Expand Down Expand Up @@ -118,7 +118,7 @@ func (cc *CommandContext) Group() *cobra.Group {

func (cc *CommandContext) AddStringConfig(name, value, flag string, help string) {
cc.CP.Set(name, value)
if flag != "" && !cc.isInteractive {
if flag != "" && !cc.Interactive() {
f := cc.Cmd.Flag(flag)
if f != nil {
cc.CP.BindFlag(name, f)
Expand Down
52 changes: 26 additions & 26 deletions clc/cmd/exec_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,29 +33,29 @@ const (
type ClientFn func(ctx context.Context, cfg hazelcast.Config) (*hazelcast.ClientInternal, error)

type ExecContext struct {
lg log.Logger
stdout io.Writer
stderr io.Writer
stdin io.Reader
args []string
props *plug.Properties
isInteractive bool
cmd *cobra.Command
main *Main
spinnerWait time.Duration
printer plug.Printer
cp config.Provider
}

func NewExecContext(lg log.Logger, sio clc.IO, props *plug.Properties, interactive bool) (*ExecContext, error) {
lg log.Logger
stdout io.Writer
stderr io.Writer
stdin io.Reader
args []string
props *plug.Properties
mode Mode
cmd *cobra.Command
main *Main
spinnerWait time.Duration
printer plug.Printer
cp config.Provider
}

func NewExecContext(lg log.Logger, sio clc.IO, props *plug.Properties, mode Mode) (*ExecContext, error) {
return &ExecContext{
lg: lg,
stdout: sio.Stdout,
stderr: sio.Stderr,
stdin: sio.Stdin,
props: props,
isInteractive: interactive,
spinnerWait: 1 * time.Second,
lg: lg,
stdout: sio.Stdout,
stderr: sio.Stderr,
stdin: sio.Stdin,
props: props,
mode: mode,
spinnerWait: 1 * time.Second,
}, nil
}

Expand Down Expand Up @@ -137,7 +137,7 @@ func (ec *ExecContext) ClientInternal(ctx context.Context) (*hazelcast.ClientInt
}

func (ec *ExecContext) Interactive() bool {
return ec.isInteractive
return ec.mode == ModeInteractive
}

func (ec *ExecContext) AddOutputRows(ctx context.Context, rows ...output.Row) error {
Expand All @@ -159,7 +159,7 @@ func (ec *ExecContext) AddOutputStream(ctx context.Context, ch <-chan output.Row

func (ec *ExecContext) ShowHelpAndExit() {
Must(ec.cmd.Help())
if !ec.isInteractive {
if !ec.Interactive() {
os.Exit(0)
}
}
Expand All @@ -168,8 +168,8 @@ func (ec *ExecContext) CommandName() string {
return ec.cmd.CommandPath()
}

func (ec *ExecContext) SetInteractive(value bool) {
ec.isInteractive = value
func (ec *ExecContext) SetMode(mode Mode) {
ec.mode = mode
}

// ExecuteBlocking runs the given blocking function.
Expand Down
1 change: 0 additions & 1 deletion cmd/clc/imports.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
_ "github.com/hazelcast/hazelcast-commandline-client/base/commands/multimap"
_ "github.com/hazelcast/hazelcast-commandline-client/base/commands/object"
_ "github.com/hazelcast/hazelcast-commandline-client/base/commands/project"
_ "github.com/hazelcast/hazelcast-commandline-client/base/commands/set"
_ "github.com/hazelcast/hazelcast-commandline-client/base/commands/queue"
_ "github.com/hazelcast/hazelcast-commandline-client/base/commands/set"
_ "github.com/hazelcast/hazelcast-commandline-client/base/commands/snapshot"
Expand Down

0 comments on commit 30e1791

Please sign in to comment.