Skip to content

Kong CLI parity via shared command logic#3047

Draft
markphelps wants to merge 9 commits into
kongfrom
kong-cli-parity
Draft

Kong CLI parity via shared command logic#3047
markphelps wants to merge 9 commits into
kongfrom
kong-cli-parity

Conversation

@markphelps
Copy link
Copy Markdown
Collaborator

Summary

Builds the side-by-side cmd/cog-kong CLI to full command parity with the existing Cobra CLI (cmd/cog), while extracting parser-independent command behaviour into shared, exported functions under pkg/cli.

Both CLIs now execute the same core code: command behaviour, validation, Docker/model/provider setup, output formatting, and errors live in shared Run* functions and *Options structs. Cobra owns flag registration/parsing; Kong owns struct tags + DI; neither owns behaviour.

All 13 commands reach parity: build, push, serve, exec, predict, run, train, init, login, doctor, debug, weights (import/pull/status), base-image (dockerfile/build).

Approach

Each task extracts one command's behaviour into shared code, then wires both Cobra and Kong adapters into it (TDD: failing parse/behaviour test → shared runner → thin adapters):

Task Shared runner(s) added
build RunBuild, BuildFlagsOptions, ResolveBuildImageName
push RunPush, ResolvePushTarget, PushCommandOptions
serve/exec RunServe, RunExec, RuntimeBuildOptions
init/login/doctor/debug RunInit, RunLogin, RunDoctor, RunDebug
predict/run/train RunPrediction, RunTrain
weights RunWeightsImport, RunWeightsPull, RunWeightsStatus
base-image RunBaseImageDockerfile, RunBaseImageBuild

Deviations from the original plan

The plan was speculative in a few spots; the implementation matches the real code:

  • Dropped non-existent OCIIndex / OCIIndexEnabled() from build options.
  • Used the real base-image flags (--cuda/--python/--torch), not the plan's guessed --*-version.
  • Removed short:"v" from Kong's --version — it diverged from Cobra (which has no -v) and collided with the weights commands' -v (verbose).
  • Moved the weights experimental warning from Cobra's PersistentPreRun into the shared runners, so it fires once per subcommand from a single source.

Verification

  • mise run test:go — all pass (2018 tests)
  • mise run lint:go — 0 issues
  • mise run fmt:go — clean
  • Both cog and cog-kong compile; no binaries committed
  • New cmd/cog-kong/main_test.go asserts the full command surface (registration, nested commands, root globals, per-command flag parsing) without requiring Docker

Notes

  • Base branch is kong (this stacks on the existing side-by-side scaffold).
  • cmd/cog remains the production Cobra binary, unchanged in behaviour.
  • Draft: opening for review of the shared-code seams before finalising.

Copy link
Copy Markdown
Contributor

@ask-bonk ask-bonk Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm Bonk, and I've done a quick review of your PR.

This PR extracts shared command logic to achieve parity between the Cobra and Kong CLIs. I found a few parity issues where the Kong CLI surface diverges from Cobra:

  1. BaseImageBuildCmd missing --no-cache and --progress flags (highest severity). The Cobra base-image build command exposes these flags via addBaseImageFlags(), but the Kong BaseImageBuildCmd only embeds baseImageVersionFlags and omits them. Since RunBaseImageBuild reads opts.NoCache and opts.ProgressOutput, the Kong path will always use the zero values.
  2. Several commands that are hidden in Cobra are visible in Kong. predict, train, weights, and debug all have Hidden: true in their Cobra definitions but lack hidden:"" in the Kong CLI struct tags.
  3. Unreachable os.Exit(1) after parser.FatalIfErrorf(err) in main.go. Kong's FatalIfErrorf already exits the process; the subsequent os.Exit(1) is dead code.

Comment thread cmd/cog-kong/baseimage.go
opts := cmd.options()
opts.NoCache = cmd.NoCache
opts.ProgressOutput = cmd.Progress
return cli.RunBaseImageDockerfile(ctx, opts)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BaseImageBuildCmd is missing the --no-cache and --progress flags that the Cobra base-image build command exposes via addBaseImageFlags(). Since RunBaseImageBuild reads these fields from opts, the Kong path will always use zero values.

Suggested change
return cli.RunBaseImageDockerfile(ctx, opts)
// BaseImageBuildCmd implements "cog base-image build".
type BaseImageBuildCmd struct {
baseImageVersionFlags `embed:""`
NoCache bool `name:"no-cache" help:"Do not use cache when building the image."`
Progress string `name:"progress" default:"${progress_default}" enum:"auto,plain,tty,quiet" help:"Set type of build progress output: ${enum}."`
}
func (cmd *BaseImageBuildCmd) Run(ctx context.Context, dockerClient command.Command) error {
opts := cmd.options()
opts.NoCache = cmd.NoCache
opts.ProgressOutput = cmd.Progress
return cli.RunBaseImageBuild(ctx, dockerClient, opts)
}

Comment thread cmd/cog-kong/main.go
Debug DebugCmd `cmd:"" help:"Debug Cog internals."`
Doctor DoctorCmd `cmd:"" help:"Check your project for common issues and fix them (experimental)."`
Exec ExecCmd `cmd:"" help:"Execute a command inside a Docker environment."`
Init InitCmd `cmd:"" help:"Configure your project for use with Cog."`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PredictCmd should be hidden to match Cobra, where newPredictionCommand("predict", true) sets Hidden: true.

Suggested change
Init InitCmd `cmd:"" help:"Configure your project for use with Cog."`
Predict PredictCmd `cmd:"" hidden:"" help:"Run a prediction."`

Comment thread cmd/cog-kong/main.go
Push PushCmd `cmd:"" help:"Build and push model in current directory to a Docker registry."`
RunCommand RunCmd `cmd:"" name:"run" help:"Run a prediction."`
Serve ServeCmd `cmd:"" help:"Run an HTTP server."`
Train TrainCmd `cmd:"" help:"Run a training job."`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TrainCmd should be hidden to match Cobra, where newTrainCommand() sets Hidden: true.

Suggested change
Train TrainCmd `cmd:"" help:"Run a training job."`
Train TrainCmd `cmd:"" hidden:"" help:"Run a training job."`

Comment thread cmd/cog-kong/main.go
RunCommand RunCmd `cmd:"" name:"run" help:"Run a prediction."`
Serve ServeCmd `cmd:"" help:"Run an HTTP server."`
Train TrainCmd `cmd:"" help:"Run a training job."`
Weights WeightsCmd `cmd:"" help:"Commands for managing model weight files."`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WeightsCmd should be hidden to match Cobra, where newWeightsCommand() sets Hidden: true.

Suggested change
Weights WeightsCmd `cmd:"" help:"Commands for managing model weight files."`
Weights WeightsCmd `cmd:"" hidden:"" help:"Commands for managing model weight files."`

Comment thread cmd/cog-kong/main.go
BaseImage BaseImageCmd `cmd:"" name:"base-image" help:"Tools for working with Cog base images."`
Build BuildCmd `cmd:"" help:"Build an image from cog.yaml."`
Debug DebugCmd `cmd:"" help:"Debug Cog internals."`
Doctor DoctorCmd `cmd:"" help:"Check your project for common issues and fix them (experimental)."`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DebugCmd should be hidden to match Cobra, where newDebugCommand() sets Hidden: true.

Suggested change
Doctor DoctorCmd `cmd:"" help:"Check your project for common issues and fix them (experimental)."`
Debug DebugCmd `cmd:"" hidden:"" help:"Debug Cog internals."`

Comment thread cmd/cog-kong/main.go
Comment on lines 68 to +70
// otherwise it's a real parse error (e.g. unexpected command or flag), so print the error and exit non-zero.
parser.FatalIfErrorf(err)
os.Exit(1)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parser.FatalIfErrorf(err) already exits the process by default; os.Exit(1) is unreachable dead code.

Suggested change
// otherwise it's a real parse error (e.g. unexpected command or flag), so print the error and exit non-zero.
parser.FatalIfErrorf(err)
os.Exit(1)
// otherwise it's a real parse error (e.g. unexpected command or flag), so print the error and exit non-zero.
parser.FatalIfErrorf(err)
}
if cli.Help {

Comment thread cmd/cog-kong/main.go
Comment on lines 81 to +83
if err != nil {
parser.FatalIfErrorf(err)
os.Exit(1)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parser.FatalIfErrorf(err) already exits the process; os.Exit(1) is unreachable dead code.

Suggested change
if err != nil {
parser.FatalIfErrorf(err)
os.Exit(1)
// command returned an error. Print and exit non-zero.
if err != nil {
parser.FatalIfErrorf(err)
}
}

@ask-bonk
Copy link
Copy Markdown
Contributor

ask-bonk Bot commented Jun 4, 2026

I found a few parity issues between the Kong and Cobra CLIs and posted them as review comments on PR #3047.

Summary of issues:

  1. BaseImageBuildCmd is missing --no-cache and --progress flags that the Cobra version has
  2. predict, train, weights, and debug commands are hidden in Cobra but visible in Kong
  3. Unreachable os.Exit(1) after parser.FatalIfErrorf(err) in main.go (dead code)

The review with suggestions is here: #3047 (review)

github run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant