diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 100d2afa..cae726c7 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -207,7 +207,10 @@ nfpms: package_name: dbc file_name_template: "{{ .ConventionalFileName }}" if: '{{ eq .Os "linux" }}' - vendor: Columnar + vendor: Columnar Technologies Inc. + homepage: "https://columnar.tech/dbc" + license: Apache-2.0 + description: >- A CLI utility for managing ADBC drivers @@ -215,6 +218,17 @@ nfpms: - deb - rpm meta: false + priority: extra + contents: + - src: cmd/dbc/completions/dbc.bash + dst: /etc/bash_completion.d/dbc + + - src: cmd/dbc/completions/dbc.zsh + dst: /usr/share/zsh/vendor-completions/_dbc + + - src: cmd/dbc/completions/dbc.fish + dst: /usr/share/fish/vendor_completions.d/dbc.fish + snapcrafts: - id: snaps diff --git a/cmd/dbc/completions/bash.go b/cmd/dbc/completions/bash.go new file mode 100644 index 00000000..f1bb2a73 --- /dev/null +++ b/cmd/dbc/completions/bash.go @@ -0,0 +1,54 @@ +// Copyright 2025 Columnar Technologies Inc. +// +// 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. + +package completions + +import _ "embed" + +//go:embed dbc.bash +var bashScript string + +type Bash struct{} + +func (Bash) Description() string { + return `Generate the autocompletion script for the bash shell. + +This script depends on the 'bash-completion' package. +If it is not installed already, you can install it via your OS's package manager. + +To load completions in your current shell session: + + source <(dbc completion bash) + +To load completions for every new session, execute once: + + echo 'eval "$(dbc completion bash)"' >> ~/.bashrc + +To install completions system-wide: + +#### Linux: + + dbc completion bash > /etc/bash_completion.d/dbc + +#### macOS: + + dbc completion bash > $(brew --prefix)/etc/bash_completion.d/dbc + +You will need to start a new shell for this setup to take effect. +` +} + +func (Bash) GetScript() string { + return bashScript +} diff --git a/cmd/dbc/completions/completions.go b/cmd/dbc/completions/completions.go new file mode 100644 index 00000000..ce2ad30c --- /dev/null +++ b/cmd/dbc/completions/completions.go @@ -0,0 +1,30 @@ +// Copyright 2025 Columnar Technologies Inc. +// +// 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. + +package completions + +type ShellImpl interface { + GetScript() string +} + +type Cmd struct { + Bash *Bash `arg:"subcommand" help:"Generate autocompletion script for bash"` + Zsh *Zsh `arg:"subcommand" help:"Generate autocompletion script for zsh"` + Fish *Fish `arg:"subcommand" help:"Generate autocompletion script for fish"` +} + +func (Cmd) Description() string { + return "Generate the autocompletion script for dbc for the requested shell.\n" + + "See each sub-command's help for details on how to use the generated script.\n" +} diff --git a/cmd/dbc/completions/dbc.bash b/cmd/dbc/completions/dbc.bash new file mode 100644 index 00000000..58154680 --- /dev/null +++ b/cmd/dbc/completions/dbc.bash @@ -0,0 +1,229 @@ +# bash completion for dbc -*- shell-script -*- + +_dbc() { + local cur prev words cword + _init_completion || return + + local subcommands="install uninstall init add sync search remove completion" + local global_opts="--help -h --version" + + # If we're completing the first argument (subcommand) + if [[ $cword -eq 1 ]]; then + COMPREPLY=($(compgen -W "$subcommands $global_opts" -- "$cur")) + return 0 + fi + + # Get the subcommand (first argument) + local subcommand="${words[1]}" + + case "$subcommand" in + install) + _dbc_install_completions + ;; + uninstall) + _dbc_uninstall_completions + ;; + init) + _dbc_init_completions + ;; + add) + _dbc_add_completions + ;; + sync) + _dbc_sync_completions + ;; + search) + _dbc_search_completions + ;; + remove) + _dbc_remove_completions + ;; + completion) + _dbc_completion_completions + ;; + *) + COMPREPLY=() + ;; + esac +} + +_dbc_install_completions() { + local cur prev + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + case "$prev" in + --level|-l) + COMPREPLY=($(compgen -W "user system" -- "$cur")) + return 0 + ;; + esac + + if [[ "$cur" == -* ]]; then + COMPREPLY=($(compgen -W "--no-verify --level -l" -- "$cur")) + return 0 + fi + + # Driver name completion (no specific completion available) + COMPREPLY=() +} + +_dbc_uninstall_completions() { + local cur prev + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + case "$prev" in + --level|-l) + COMPREPLY=($(compgen -W "user system" -- "$cur")) + return 0 + ;; + esac + + if [[ "$cur" == -* ]]; then + COMPREPLY=($(compgen -W "--level -l" -- "$cur")) + return 0 + fi + + # Driver name completion (no specific completion available) + COMPREPLY=() +} + +_dbc_init_completions() { + local cur prev + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + if [[ "$cur" == -* ]]; then + COMPREPLY=($(compgen -W "-h" -- "$cur")) + return 0 + fi + + # Complete .toml files + COMPREPLY=($(compgen -f -X '!*.toml' -- "$cur")) + # Add directory completion as well + if [[ -d "$cur" ]]; then + COMPREPLY+=($(compgen -d -- "$cur")) + fi +} + +_dbc_add_completions() { + local cur prev + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + case "$prev" in + --path|-p) + # Complete .toml files + COMPREPLY=($(compgen -f -X '!*.toml' -- "$cur")) + if [[ -d "$cur" ]]; then + COMPREPLY+=($(compgen -d -- "$cur")) + fi + return 0 + ;; + esac + + if [[ "$cur" == -* ]]; then + COMPREPLY=($(compgen -W "-h --path -p" -- "$cur")) + return 0 + fi + + # Driver name completion (no specific completion available) + COMPREPLY=() +} + +_dbc_sync_completions() { + local cur prev + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + case "$prev" in + --level|-l) + COMPREPLY=($(compgen -W "user system" -- "$cur")) + return 0 + ;; + --path|-p) + # Complete .toml files + COMPREPLY=($(compgen -f -X '!*.toml' -- "$cur")) + if [[ -d "$cur" ]]; then + COMPREPLY+=($(compgen -d -- "$cur")) + fi + return 0 + ;; + esac + + if [[ "$cur" == -* ]]; then + COMPREPLY=($(compgen -W "-h --level -l --path -p --no-verify" -- "$cur")) + return 0 + fi + + COMPREPLY=() +} + +_dbc_search_completions() { + local cur prev + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + if [[ "$cur" == -* ]]; then + COMPREPLY=($(compgen -W "-h -v -n" -- "$cur")) + return 0 + fi + + # Search term completion (no specific completion available) + COMPREPLY=() +} + +_dbc_remove_completions() { + local cur prev + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + case "$prev" in + --path|-p) + # Complete .toml files + COMPREPLY=($(compgen -f -X '!*.toml' -- "$cur")) + if [[ -d "$cur" ]]; then + COMPREPLY+=($(compgen -d -- "$cur")) + fi + return 0 + ;; + esac + + if [[ "$cur" == -* ]]; then + COMPREPLY=($(compgen -W "-h --path -p" -- "$cur")) + return 0 + fi + + # Driver name completion (no specific completion available) + COMPREPLY=() +} + +_dbc_completion_completions() { + local cur prev + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + # If we're at position 2 (right after "completion"), suggest shell types + if [[ $COMP_CWORD -eq 2 ]]; then + if [[ "$cur" == -* ]]; then + COMPREPLY=($(compgen -W "-h --help" -- "$cur")) + else + COMPREPLY=($(compgen -W "bash zsh fish" -- "$cur")) + fi + return 0 + fi + + # If we've already specified a shell, just offer help + if [[ "$cur" == -* ]]; then + COMPREPLY=($(compgen -W "-h --help" -- "$cur")) + return 0 + fi + + COMPREPLY=() +} + +# Register the completion function +complete -F _dbc dbc + +# ex: ts=4 sw=4 et filetype=sh diff --git a/cmd/dbc/completions/dbc.fish b/cmd/dbc/completions/dbc.fish new file mode 100644 index 00000000..6f4b0f1f --- /dev/null +++ b/cmd/dbc/completions/dbc.fish @@ -0,0 +1,81 @@ +# fish completion for dbc -*- shell-script -*- + +# Helper function to check if a subcommand has been given +function __fish_dbc_needs_command + set -l cmd (commandline -opc) + set -e cmd[1] + if test (count $cmd) -eq 0 + return 0 + end + return 1 +end + +# Helper function to check if we're using a specific subcommand +function __fish_dbc_using_subcommand + set -l cmd (commandline -opc) + if test (count $cmd) -gt 1 + if test $argv[1] = $cmd[2] + return 0 + end + end + return 1 +end + +# Global options +complete -c dbc -n '__fish_dbc_needs_command' -l help -d 'Show help' +complete -c dbc -n '__fish_dbc_needs_command' -s h -d 'Show help' +complete -c dbc -n '__fish_dbc_needs_command' -l version -d 'Show version' + +# Subcommands +complete -f -c dbc -n '__fish_dbc_needs_command' -a 'install' -d 'Install a driver' +complete -f -c dbc -n '__fish_dbc_needs_command' -a 'uninstall' -d 'Uninstall a driver' +complete -f -c dbc -n '__fish_dbc_needs_command' -a 'init' -d 'Create new driver list' +complete -f -c dbc -n '__fish_dbc_needs_command' -a 'add' -d 'Add a driver to the driver list' +complete -f -c dbc -n '__fish_dbc_needs_command' -a 'sync' -d 'Install all drivers in the driver list' +complete -f -c dbc -n '__fish_dbc_needs_command' -a 'search' -d 'Search for drivers' +complete -f -c dbc -n '__fish_dbc_needs_command' -a 'remove' -d 'Remove a driver from the driver list' +complete -f -c dbc -n '__fish_dbc_needs_command' -a 'completion' -d 'Generate shell completions' + +# install subcommand +complete -f -c dbc -n '__fish_dbc_using_subcommand install' -s h -d 'Show Help' +complete -f -c dbc -n '__fish_dbc_using_subcommand install' -l help -d 'Show Help' +complete -f -c dbc -n '__fish_dbc_using_subcommand install' -l no-verify -d 'Do not verify the driver after installation' +complete -f -c dbc -n '__fish_dbc_using_subcommand install' -l level -s l -d 'Installation level' -xa 'user system' + +# uninstall subcommand +complete -f -c dbc -n '__fish_dbc_using_subcommand uninstall' -l level -s l -d 'Installation level' -xa 'user system' + +# init subcommand +complete -f -c dbc -n '__fish_dbc_using_subcommand init' -s h -d 'Help' +complete -f -c dbc -n '__fish_dbc_using_subcommand init' -l help -d 'Help' +complete -c dbc -n '__fish_dbc_using_subcommand init' -F -a '*.toml' -d 'File to create' + +# add subcommand +complete -f -c dbc -n '__fish_dbc_using_subcommand add' -s h -d 'Help' +complete -f -c dbc -n '__fish_dbc_using_subcommand add' -l help -d 'Help' +complete -c dbc -n '__fish_dbc_using_subcommand add' -l path -s p -r -F -a '*.toml' -d 'Driver list to add to' + +# sync subcommand +complete -f -c dbc -n '__fish_dbc_using_subcommand sync' -s h -d 'Help' +complete -f -c dbc -n '__fish_dbc_using_subcommand sync' -l help -d 'Help' +complete -f -c dbc -n '__fish_dbc_using_subcommand sync' -l level -s l -d 'Installation level' -xa 'user system' +complete -c dbc -n '__fish_dbc_using_subcommand sync' -l path -s p -r -F -a '*.toml' -d 'Driver list to sync' +complete -f -c dbc -n '__fish_dbc_using_subcommand sync' -l no-verify -d 'Do not verify the driver after installation' + +# search subcommand +complete -f -c dbc -n '__fish_dbc_using_subcommand search' -s h -d 'Help' +complete -f -c dbc -n '__fish_dbc_using_subcommand search' -l help -d 'Help' +complete -f -c dbc -n '__fish_dbc_using_subcommand search' -s v -d 'Verbose' +complete -f -c dbc -n '__fish_dbc_using_subcommand search' -s n -d 'Names only' + +# remove subcommand +complete -f -c dbc -n '__fish_dbc_using_subcommand remove' -s h -d 'Help' +complete -f -c dbc -n '__fish_dbc_using_subcommand remove' -l help -d 'Help' +complete -c dbc -n '__fish_dbc_using_subcommand remove' -l path -s p -r -F -a '*.toml' -d 'Driver list to remove from' + +# completion subcommand +complete -f -c dbc -n '__fish_dbc_using_subcommand completion' -s h -d 'Help' +complete -f -c dbc -n '__fish_dbc_using_subcommand completion' -l help -d 'Help' +complete -f -c dbc -n '__fish_dbc_using_subcommand completion' -a 'bash' -d 'Generate autocompletion script for bash' +complete -f -c dbc -n '__fish_dbc_using_subcommand completion' -a 'zsh' -d 'Generate autocompletion script for zsh' +complete -f -c dbc -n '__fish_dbc_using_subcommand completion' -a 'fish' -d 'Generate autocompletion script for fish' diff --git a/cmd/dbc/completions/dbc.zsh b/cmd/dbc/completions/dbc.zsh new file mode 100644 index 00000000..d45c8b1d --- /dev/null +++ b/cmd/dbc/completions/dbc.zsh @@ -0,0 +1,131 @@ +#compdef dbc +compdef _dbc dbc + +# zsh completion for dbc -*- shell-script -*- + +function _dbc { + local line state + + _arguments -C \ + "1: :->subcommand" \ + "*::arg:->args" + + case $state in + subcommand) + _values "dbc command" \ + 'install[Install a driver]' \ + 'uninstall[Uninstall a driver]' \ + 'init[Create new driver list]' \ + 'add[Add a driver to the driver list]' \ + 'sync[Install all drivers in the driver list]' \ + 'search[Search for drivers]' \ + 'remove[Remove a driver from the driver list]' \ + 'completion[Generate shell completions]' \ + '--help[Show help]' \ + '-h[Show help]' \ + '--version[Show version]' + ;; + args) + case $line[1] in + install) + _dbc_install_completions + ;; + uninstall) + _dbc_uninstall_completions + ;; + init) + _dbc_init_completions + ;; + add) + _dbc_add_completions + ;; + sync) + _dbc_sync_completions + ;; + search) + _dbc_search_completions + ;; + remove) + _dbc_remove_completions + ;; + completion) + _dbc_completion_completions + ;; + esac + ;; + esac +} + +function _dbc_install_completions { + _arguments \ + '(--help)-h[Help]' \ + '(-h)--help[Help]' \ + '--no-verify[do not verify the driver after installation]' \ + '(-l)--level[installation level]: :(user system)' \ + '(--level)-l[installation level]: :(user system)' \ + ':driver name: ' +} + +function _dbc_uninstall_completions { + _arguments \ + '(-l)--level[installation level]: :(user system)' \ + '(--level)-l[installation level]: :(user system)' \ + ':driver name: ' +} + +function _dbc_init_completions { + _arguments \ + '(--help)-h[Help]' \ + '(-h)--help[Help]' \ + ':file to create:_files -g \*.toml' +} + +function _dbc_add_completions { + _arguments \ + '(--help)-h[Help]' \ + '(-h)--help[Help]' \ + '(-p)--path[driver list to add to]: :_files -g \*.toml' \ + '(--path)-p[driver list to add to]: :_files -g \*.toml' \ + ':driver name: ' +} + +function _dbc_sync_completions { + _arguments \ + '(--help)-h[Help]' \ + '(-h)--help[Help]' \ + '(-l)--level[installation level]: :(user system)' \ + '(--level)-l[installation level]: :(user system)' \ + '(-p)--path[driver list to add to]: :_files -g \*.toml' \ + '(--path)-p[driver list to add to]: :_files -g \*.toml' \ + '--no-verify[do not verify the driver after installation]' +} + +function _dbc_search_completions { + _arguments \ + '(--help)-h[Help]' \ + '(-h)--help[Help]' \ + '-v[verbose]' \ + '-n[names only]' \ + ':search term: ' +} + +function _dbc_remove_completions { + _arguments \ + '(--help)-h[Help]' \ + '(-h)--help[Help]' \ + '(-p)--path[driver list to remove from]: :_files -g \*.toml' \ + '(--path)-p[driver list to remove from]: :_files -g \*.toml' \ + ':driver name: ' +} + +function _dbc_completion_completions { + _arguments \ + '(--help)-h[Help]' \ + '(-h)--help[Help]' \ + ':shell type:(bash zsh fish)' +} + +# don't run the completion function when being source-d or eval-d +if [ "$funcstack[1]" = "_dbc" ]; then + _dbc +fi diff --git a/cmd/dbc/completions/fish.go b/cmd/dbc/completions/fish.go new file mode 100644 index 00000000..b5bab617 --- /dev/null +++ b/cmd/dbc/completions/fish.go @@ -0,0 +1,41 @@ +// Copyright 2025 Columnar Technologies Inc. +// +// 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. + +package completions + +import _ "embed" + +//go:embed dbc.fish +var fishScript string + +type Fish struct{} + +func (Fish) Description() string { + return `Generate the autocompletion script for the fish shell. + +To load completions in your current shell session: + + dbc completion fish | source + +To load completions for every new session, execute once: + + dbc completion fish > ~/.config/fish/completions/dbc.fish + +You will need to start a new shell for this setup to take effect. +` +} + +func (Fish) GetScript() string { + return fishScript +} diff --git a/cmd/dbc/completions/zsh.go b/cmd/dbc/completions/zsh.go new file mode 100644 index 00000000..b575acaf --- /dev/null +++ b/cmd/dbc/completions/zsh.go @@ -0,0 +1,56 @@ +// Copyright 2025 Columnar Technologies Inc. +// +// 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. + +package completions + +import _ "embed" + +//go:embed dbc.zsh +var zshScript string + +type Zsh struct{} + +func (Zsh) Description() string { + return `Generate the autocompletion script for the zsh shell. + +If shell completion is not already enabled in your environment you will need +to enable it. You can execute the following once: + + echo "autoload -U compinit; compinit" >> ~/.zshrc + +To load completions in your current shell session: + + source <(dbc completion zsh) + +To load completions for every new session, execute once: + + echo 'eval "$(dbc completion zsh)"' >> ~/.zshrc + +To install completions system-wide: + +#### Linux: + + dbc completion zsh > "${fpath[1]}/_dbc" + +#### macOS: + + dbc completion zsh > $(brew --prefix)/share/zsh/site-functions/_dbc + +You will need to start a new shell for this setup to take effect. +` +} + +func (Zsh) GetScript() string { + return zshScript +} diff --git a/cmd/dbc/main.go b/cmd/dbc/main.go index e9c9b891..2fe750f3 100644 --- a/cmd/dbc/main.go +++ b/cmd/dbc/main.go @@ -23,6 +23,7 @@ import ( tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" "github.com/columnar-tech/dbc" + "github.com/columnar-tech/dbc/cmd/dbc/completions" "github.com/columnar-tech/dbc/config" "github.com/mattn/go-isatty" ) @@ -124,13 +125,14 @@ func (m baseModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { } type cmds struct { - Install *InstallCmd `arg:"subcommand" help:"Install a driver"` - Uninstall *UninstallCmd `arg:"subcommand" help:"Uninstall a driver"` - Init *InitCmd `arg:"subcommand" help:"Initialize a new dbc driver list"` - Add *AddCmd `arg:"subcommand" help:"Add a driver to the driver list"` - Sync *SyncCmd `arg:"subcommand" help:"Sync installed drivers with drivers in the driver list"` - Search *SearchCmd `arg:"subcommand" help:"Search for a driver"` - Remove *RemoveCmd `arg:"subcommand" help:"Remove a driver from the driver list"` + Install *InstallCmd `arg:"subcommand" help:"Install a driver"` + Uninstall *UninstallCmd `arg:"subcommand" help:"Uninstall a driver"` + Init *InitCmd `arg:"subcommand" help:"Initialize a new dbc driver list"` + Add *AddCmd `arg:"subcommand" help:"Add a driver to the driver list"` + Sync *SyncCmd `arg:"subcommand" help:"Sync installed drivers with drivers in the driver list"` + Search *SearchCmd `arg:"subcommand" help:"Search for a driver"` + Remove *RemoveCmd `arg:"subcommand" help:"Remove a driver from the driver list"` + Completion *completions.Cmd `arg:"subcommand" help:"-"` } func (cmds) Version() string { @@ -140,14 +142,50 @@ func (cmds) Version() string { var prog *tea.Program func main() { - var args cmds + var ( + args cmds + ) + + p, err := arg.NewParser(arg.Config{Program: "dbc"}, &args) + if err != nil { + fmt.Println("Error creating argument parser:", err) + os.Exit(1) + } + + if err = p.Parse(os.Args[1:]); err != nil { + switch { + case err == arg.ErrHelp: + if d, ok := p.Subcommand().(arg.Described); ok { + fmt.Println(d.Description()) + } + p.WriteHelpForSubcommand(os.Stdout, p.SubcommandNames()...) + os.Exit(0) + case err == arg.ErrVersion: + fmt.Println(dbc.Version) + os.Exit(0) + default: + p.FailSubcommand(err.Error(), p.SubcommandNames()...) + } + } - p := arg.MustParse(&args) if p.Subcommand() == nil { p.WriteHelp(os.Stdout) os.Exit(1) } + var m tea.Model + + switch sub := p.Subcommand().(type) { + case *completions.Cmd: // "dbc completions" without specifying the shell type + p.WriteHelpForSubcommand(os.Stdout, p.SubcommandNames()...) + os.Exit(2) + case completions.ShellImpl: + fmt.Print(sub.GetScript()) + os.Exit(0) + case modelCmd: + m = sub.GetModel() + } + // f, err := tea.LogToFile("debug.log", "debug") // if err != nil { // fmt.Println("Error creating log file:", err) @@ -155,15 +193,12 @@ func main() { // } // defer f.Close() - m := p.Subcommand().(modelCmd).GetModel() - if !isatty.IsTerminal(os.Stdout.Fd()) { prog = tea.NewProgram(m, tea.WithoutRenderer(), tea.WithInput(nil)) } else { prog = tea.NewProgram(m) } - var err error if m, err = prog.Run(); err != nil { fmt.Println("Error running program:", err) os.Exit(1) diff --git a/docs/getting_started/installation.md b/docs/getting_started/installation.md index c0f32437..2a85953e 100644 --- a/docs/getting_started/installation.md +++ b/docs/getting_started/installation.md @@ -117,3 +117,37 @@ The following distroless images are available for Linux-based `amd64` and `arm64 - `columnar/dbc:latest` - `columnar/dbc:{major}.{minor}.{patch}`, e.g. `columnar/dbc:0.0.1` + +## Shell Completions + +dbc can generate shell completions for a number of common shells. + +!!! note + + If you aren't sure what shell you're running, you can run the following command in your terminal: + + ```console + $ echo $SHELL + ``` + +=== "Bash" + + ```console + $ echo 'eval "$(dbc completion bash)"' >> ~/.bashrc + ``` + +=== "Zsh" + + ```console + $ echo 'eval "$(dbc completion zsh)"' >> ~/.zshrc + ``` + +=== "fish" + + ```console + $ dbc completion fish > ~/.config/fish/completions/dbc.fish + ``` + +!!! info + + You can use the `dbc completion` subcommand to print extended instructions for your shell, including how to enable your shell's completion mechanism. For example, to print setup instructions for Bash, run `dbc completion bash --help`. diff --git a/go.mod b/go.mod index b0bdc067..2b597123 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ toolchain go1.24.6 require ( github.com/Masterminds/semver/v3 v3.4.0 github.com/ProtonMail/gopenpgp/v3 v3.2.1 - github.com/alexflint/go-arg v1.5.1 + github.com/alexflint/go-arg v1.6.0 github.com/charmbracelet/bubbles v0.21.0 github.com/charmbracelet/bubbletea v1.3.7 github.com/charmbracelet/lipgloss v1.1.0 @@ -66,3 +66,5 @@ require ( golang.org/x/text v0.25.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) + +replace github.com/alexflint/go-arg => github.com/zeroshade/go-arg v0.0.0-20251013220544-4735a7c3184f diff --git a/go.sum b/go.sum index 3a63bd25..82dfa45e 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,6 @@ github.com/ProtonMail/go-crypto v1.2.0 h1:+PhXXn4SPGd+qk76TlEePBfOfivE0zkWFenhGh github.com/ProtonMail/go-crypto v1.2.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE= github.com/ProtonMail/gopenpgp/v3 v3.2.1 h1:ohRlKL5YwyIkN5kk7uBvijiMsyA57mK0yBEJg9xButU= github.com/ProtonMail/gopenpgp/v3 v3.2.1/go.mod h1:x7RduTo/0n/2PjTFRoEHApaxye/8PFbhoCquwfYBUGM= -github.com/alexflint/go-arg v1.5.1 h1:nBuWUCpuRy0snAG+uIJ6N0UvYxpxA0/ghA/AaHxlT8Y= -github.com/alexflint/go-arg v1.5.1/go.mod h1:A7vTJzvjoaSTypg4biM5uYNTkJ27SkNTArtYXnlqVO8= github.com/alexflint/go-scalar v1.2.0 h1:WR7JPKkeNpnYIOfHRa7ivM21aWAdHD0gEWHCx+WQBRw= github.com/alexflint/go-scalar v1.2.0/go.mod h1:LoFvNMqS1CPrMVltza4LvnGKhaSpc3oyLEBUZVhhS2o= github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= @@ -85,6 +83,8 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= +github.com/zeroshade/go-arg v0.0.0-20251013220544-4735a7c3184f h1:XI5fpJaulKcO2AJzuUM0O74hv/wt0XMEB8JkVigncW8= +github.com/zeroshade/go-arg v0.0.0-20251013220544-4735a7c3184f/go.mod h1:nQ0LFYftLJ6njcaee0sU+G0iS2+2XJQfA8I062D0LGc= github.com/zeroshade/machine-id v0.0.0-20250917170903-4283e98485ba h1:yStvOL+OyJJ41jmZVqHqAspXXr4VVKC3gIfnGvO/+Pw= github.com/zeroshade/machine-id v0.0.0-20250917170903-4283e98485ba/go.mod h1:RHX47A/DYmoTfyT25mb6C+Eve7X5miOporc+RVUoRoY= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=