Skip to content

Better shell completions - #934

Closed
mohammedahmed18 wants to merge 4 commits into
kitops-ml:mainfrom
mohammedahmed18:feat/shell-completions
Closed

Better shell completions#934
mohammedahmed18 wants to merge 4 commits into
kitops-ml:mainfrom
mohammedahmed18:feat/shell-completions

Conversation

@mohammedahmed18

@mohammedahmed18 mohammedahmed18 commented Jul 31, 2025

Copy link
Copy Markdown
Contributor

Fixes #79

This includes two main changes:

  1. Auto-installation for shell completions — currently supports Zsh, Bash, and Fish.
kitops-completions.online-video-cutter.com.mp4
  1. Command-specific completions, as described in the issue.
command-completions.mp4

Let me know if you'd like to tweak anything!

Signed-off-by: mohammed <mohammed18200118@gmail.com>
@mohammedahmed18
mohammedahmed18 force-pushed the feat/shell-completions branch from c5e0b09 to 5221519 Compare July 31, 2025 23:44
Signed-off-by: mohammed <mohammed18200118@gmail.com>

@gorkem gorkem left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Each command initializes completions by reading all local repos, even if completions aren't used. This adds startup latency ( I have alot of local repos). Lazy load completions - only read local repos when tab-completion is actually triggered

Comment thread cmd/root.go
cobra.AddTemplateFunc("ensureTrailingNewline", ensureTrailingNewline)
err := installShellCompletions(cmd, opts)
if err != nil {
output.Debugf("Failed to install shell completions: %s", err)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Errors are only logged at debug level, but shell completion installation failures should be more visible. Silent failures could confuse users who expect completions to work.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

maybe not doing this because if the user has a problem with the setup, for example (unsupported shell), we don't want to keep showing this message on every command he run, it would be a bad experience for him, what do you think

Comment thread cmd/completions.go Outdated
return nil // already present
}

shellRC, err := os.OpenFile(pathOfShellRC, os.O_APPEND|os.O_WRONLY, 0644)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

There's a race condition between checking if the source command exists and writing to the file. Multiple concurrent executions could result in duplicate entries.

Comment thread cmd/root.go
}

func onConfigHomeError(err error) {
output.Fatalf("Failed to read base config directory")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

output.Fatalf() should terminate execution, but subsequent output.Infof() calls can make it confusing.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

not sure actually that was already there but output.Fatalf() doesn't exit
so I manually os.exit(1)

Comment thread cmd/completions.go Outdated
}
defer shellRC.Close()

_, err = shellRC.WriteString("\n# Kitops completions\nsource " + pathOfCompletionFile + "\n")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is not safe If an attacker can control the configHome path (through the --config flag or KITOPS_HOME environment variable), they could inject malicious shell commands. Properly escape or quote the path.

Signed-off-by: mohammed <mohammed18200118@gmail.com>
@mohammedahmed18
mohammedahmed18 requested a review from gorkem August 2, 2025 16:53
@mohammedahmed18

mohammedahmed18 commented Aug 2, 2025

Copy link
Copy Markdown
Contributor Author

going to fix file lock for windows later today

update: ignoring shell windows completions for now, maybe will add it in a separate PR

Signed-off-by: mohammed <mohammed18200118@gmail.com>
@amisevsk

Copy link
Copy Markdown
Contributor

Thanks @mohammedahmed18 for the contribution. However, I think this approach to completions has a number of issues that make it unsuitable. Have a look at PR #963, which I think is a fair bit cleaner and replaces this one.

  • We shouldn't have to adjust how we're passing data around (the configHome parameter), and making some commands require it explicitly while others get it from context is a little messier than I'd like
  • I don't think we should be installing completions for users; it's error prone and dependent on too many factors to reliably do automatically
  • We should avoid having platform-dependent code wherever possible
  • Generating the completions is a little messy -- they're not static completions in the current revision, as they use the ValidArgsFunction. Additionally, we don't need to check for prefixes in the completion generator.
  • I think it's cleaner to not generate a list of all modelkits and tags when requesting completions -- it's just too much data at once. I took a different approach in Add dynamic shell completions for ModelKit references #963 if you're interested.

@amisevsk amisevsk closed this Sep 16, 2025
@mohammedahmed18

Copy link
Copy Markdown
Contributor Author

@amisevsk yeah, fair points
Thanks for th review though

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.

Support shell completions for commands

3 participants