From 76ec9bcf94e94177199522480871367138661125 Mon Sep 17 00:00:00 2001 From: Angel Misevski Date: Thu, 9 May 2024 13:09:51 -0600 Subject: [PATCH] Refactor kit dev flags to subcommands Replace --stop and --logs flags for kit dev with subcommands: * kit dev start -> start the server * kit dev stop -> stop a running server * kit dev logs -> print logs from last run --- pkg/cmd/dev/cmd.go | 164 +++++++++++++++++++++---------------------- pkg/cmd/dev/dev.go | 4 +- pkg/cmd/dev/opts.go | 77 ++++++++++++++++++++ pkg/cmd/dev/usage.go | 47 +++++++++++++ 4 files changed, 205 insertions(+), 87 deletions(-) create mode 100644 pkg/cmd/dev/opts.go create mode 100644 pkg/cmd/dev/usage.go diff --git a/pkg/cmd/dev/cmd.go b/pkg/cmd/dev/cmd.go index d0a83e0e..3c4ede0d 100644 --- a/pkg/cmd/dev/cmd.go +++ b/pkg/cmd/dev/cmd.go @@ -16,10 +16,6 @@ package dev import ( - "context" - "fmt" - "kitops/pkg/lib/constants" - "kitops/pkg/lib/filesystem" "kitops/pkg/lib/harness" "kitops/pkg/output" "net" @@ -30,76 +26,58 @@ import ( "github.com/spf13/cobra" ) -const ( - shortDesc = `Start development server (experimental)` - longDesc = `Start development server (experimental) with the specified context directory and kitfile` - example = `kit dev ./my-model --port 8080` -) - -type DevOptions struct { - host string - port int - modelFile string - contextDir string - configHome string - stop bool - printLogs bool -} - -func (opts *DevOptions) complete(ctx context.Context, args []string) error { - - configHome, ok := ctx.Value(constants.ConfigKey{}).(string) - if !ok { - return fmt.Errorf("default config path not set on command context") - } - opts.configHome = configHome - if !opts.stop && !opts.printLogs { - opts.contextDir = "" - if len(args) == 1 { - opts.contextDir = args[0] - } - if opts.modelFile == "" { - foundKitfile, err := filesystem.FindKitfileInPath(opts.contextDir) - if err != nil { - return err - } - opts.modelFile = foundKitfile - } - if opts.host == "" { - opts.host = "127.0.0.1" - } - - if opts.port == 0 { - availPort, err := findAvailablePort() - if err != nil { - output.Fatalf("Invalid arguments: %s", err) - return err - } - opts.port = availPort - } +func DevCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "dev [flags]", + Short: devShortDesc, + Long: devLongDesc, + Example: devExample, } - return nil + cmd.AddCommand(DevStartCommand()) + cmd.AddCommand(DevStopCommand()) + cmd.AddCommand(DevLogsCommand()) + return cmd } -func DevCommand() *cobra.Command { - opts := &DevOptions{} +func DevStartCommand() *cobra.Command { + opts := &DevStartOptions{} cmd := &cobra.Command{ - Use: "dev [flags]", - Short: shortDesc, - Long: longDesc, - Example: example, - Run: runCommand(opts), + Use: "start [flags]", + Short: devStartShortDesc, + Long: devStartLongDesc, + Example: devStartExample, + Run: runStartCommand(opts), } cmd.Args = cobra.MaximumNArgs(1) cmd.Flags().StringVarP(&opts.modelFile, "file", "f", "", "Path to the kitfile") cmd.Flags().StringVar(&opts.host, "host", "127.0.0.1", "Host for the development server") cmd.Flags().IntVar(&opts.port, "port", 0, "Port for development server to listen on") - cmd.Flags().BoolVar(&opts.stop, "stop", false, "Stop the development server") - cmd.Flags().BoolVar(&opts.printLogs, "logs", false, "Print logs for the running development server") return cmd } -func runCommand(opts *DevOptions) func(cmd *cobra.Command, args []string) { +func DevStopCommand() *cobra.Command { + opts := &DevBaseOptions{} + cmd := &cobra.Command{ + Use: "stop", + Short: devStopShortDesc, + Long: devStopLongDesc, + Run: runStopCommand(opts), + } + return cmd +} + +func DevLogsCommand() *cobra.Command { + opts := &DevBaseOptions{} + cmd := &cobra.Command{ + Use: "logs", + Short: devLogsShortDesc, + Long: devLogsLongDesc, + Run: runLogsCommand(opts), + } + return cmd +} + +func runStartCommand(opts *DevStartOptions) func(cmd *cobra.Command, args []string) { return func(cmd *cobra.Command, args []string) { if runtime.GOOS == "windows" || runtime.GOOS == "linux" { output.Infoln("Development server is not yet supported in this platform") @@ -111,29 +89,45 @@ func runCommand(opts *DevOptions) func(cmd *cobra.Command, args []string) { output.Errorf("failed to complete options: %s", err) return } - switch { - case opts.stop: - output.Infoln("Stopping development server...") - err := stopDev(cmd.Context(), opts) - if err != nil { - output.Errorf("Failed to stop dev server: %s", err) - os.Exit(1) - } - output.Infoln("Development server stopped") - case opts.printLogs: - err := harness.PrintLogs(opts.configHome, cmd.OutOrStdout()) - if err != nil { - output.Errorln(err) - os.Exit(1) - } - default: - err := runDev(cmd.Context(), opts) - if err != nil { - output.Errorf("Failed to start dev server: %s", err) - os.Exit(1) - } - output.Infof("Development server started at http://%s:%d", opts.host, opts.port) - output.Infof("Use \"kit dev --stop\" to stop the development server") + + err := runDev(cmd.Context(), opts) + if err != nil { + output.Errorf("Failed to start dev server: %s", err) + os.Exit(1) + } + output.Infof("Development server started at http://%s:%d", opts.host, opts.port) + output.Infof("Use \"kit dev stop\" to stop the development server") + } +} + +func runStopCommand(opts *DevBaseOptions) func(cmd *cobra.Command, args []string) { + return func(cmd *cobra.Command, args []string) { + if err := opts.complete(cmd.Context(), args); err != nil { + output.Errorf("failed to complete options: %s", err) + return + } + + output.Infoln("Stopping development server...") + err := stopDev(cmd.Context(), opts) + if err != nil { + output.Errorf("Failed to stop dev server: %s", err) + os.Exit(1) + } + output.Infoln("Development server stopped") + } +} + +func runLogsCommand(opts *DevBaseOptions) func(cmd *cobra.Command, args []string) { + return func(cmd *cobra.Command, args []string) { + if err := opts.complete(cmd.Context(), args); err != nil { + output.Errorf("failed to complete options: %s", err) + return + } + + err := harness.PrintLogs(opts.configHome, cmd.OutOrStdout()) + if err != nil { + output.Errorln(err) + os.Exit(1) } } } diff --git a/pkg/cmd/dev/dev.go b/pkg/cmd/dev/dev.go index 818ce5a1..01713a89 100644 --- a/pkg/cmd/dev/dev.go +++ b/pkg/cmd/dev/dev.go @@ -26,7 +26,7 @@ import ( "os" ) -func runDev(ctx context.Context, options *DevOptions) error { +func runDev(ctx context.Context, options *DevStartOptions) error { kitfile := &artifact.KitFile{} @@ -67,7 +67,7 @@ func runDev(ctx context.Context, options *DevOptions) error { return nil } -func stopDev(ctx context.Context, options *DevOptions) error { +func stopDev(_ context.Context, options *DevBaseOptions) error { llmHarness := &harness.LLMHarness{} llmHarness.ConfigHome = options.configHome diff --git a/pkg/cmd/dev/opts.go b/pkg/cmd/dev/opts.go new file mode 100644 index 00000000..2c8b210e --- /dev/null +++ b/pkg/cmd/dev/opts.go @@ -0,0 +1,77 @@ +// Copyright 2024 The KitOps Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +package dev + +import ( + "context" + "fmt" + "kitops/pkg/lib/constants" + "kitops/pkg/lib/filesystem" + "kitops/pkg/output" +) + +type DevBaseOptions struct { + configHome string +} + +func (opts *DevBaseOptions) complete(ctx context.Context, args []string) error { + configHome, ok := ctx.Value(constants.ConfigKey{}).(string) + if !ok { + return fmt.Errorf("default config path not set on command context") + } + opts.configHome = configHome + return nil +} + +type DevStartOptions struct { + DevBaseOptions + host string + port int + modelFile string + contextDir string +} + +func (opts *DevStartOptions) complete(ctx context.Context, args []string) error { + if err := opts.DevBaseOptions.complete(ctx, args); err != nil { + return err + } + + opts.contextDir = "" + if len(args) == 1 { + opts.contextDir = args[0] + } + if opts.modelFile == "" { + foundKitfile, err := filesystem.FindKitfileInPath(opts.contextDir) + if err != nil { + return err + } + opts.modelFile = foundKitfile + } + if opts.host == "" { + opts.host = "127.0.0.1" + } + + if opts.port == 0 { + availPort, err := findAvailablePort() + if err != nil { + output.Fatalf("Invalid arguments: %s", err) + return err + } + opts.port = availPort + } + return nil +} diff --git a/pkg/cmd/dev/usage.go b/pkg/cmd/dev/usage.go new file mode 100644 index 00000000..7549dbcc --- /dev/null +++ b/pkg/cmd/dev/usage.go @@ -0,0 +1,47 @@ +// Copyright 2024 The KitOps Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +package dev + +const ( + devShortDesc = "Run models locally (experimental)" + devLongDesc = "Start a local server and interact with a model in the browser" + devExample = "kit dev start" + + devStartShortDesc = "Start development server (experimental)" + devStartLongDesc = `Start development server (experimental) from a modelkit + +Start a development server for an unpacked modelkit, using a context directory +that includes the model and a kitfile. +` + devStartExample = `# Serve the model located in the current directory +kit dev start + +# Serve the modelkit in ./my-model on port 8080 +kit dev start ./my-model --port 8080 +` + + devStopShortDesc = "Stop development server" + devStopLongDesc = "Stop the development server if it is running" + + devLogsShortDesc = "View logs for development server" + devLogsLongDesc = `Print any logs output by the development server. + +If the development server is currently running, the logs for this server will +be printed. If it is stopped, the logs for the previous run of the server, if +available, will be printed instead. +` +)