Skip to content

Commit

Permalink
refactored flags and added completions for shells
Browse files Browse the repository at this point in the history
  • Loading branch information
ZelvaMan committed Apr 24, 2024
1 parent e016865 commit fa5b9ef
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 52 deletions.
15 changes: 15 additions & 0 deletions cmd/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package cmd

import "github.com/keenmate/db-gen/common"

const (
keyDebug = "debug"
keyConnectionString = "connectionString"
keyConfig = "config"
)

var commonFlags = []common.FlagArgument{
common.NewBoolFlag(keyDebug, "d", false, "Print debug logs and create debug files"),
common.NewStringFlag(keyConfig, "s", "", "Connection string used to connect to database"),
common.NewStringFlag(keyConnectionString, "c", "", "Path to configuration file"),
}
66 changes: 66 additions & 0 deletions cmd/completion.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package cmd

import (
"fmt"
"github.com/spf13/cobra"
"os"
)

var completionCmd = &cobra.Command{
Use: "completion [bash|zsh|fish|powershell]",
Short: "Generate completion script",
Long: fmt.Sprintf(`To load completions:
Bash:
$ source <(%[1]s completion bash)
# To load completions for each session, execute once:
# Linux:
$ %[1]s completion bash > /etc/bash_completion.d/%[1]s
# macOS:
$ %[1]s completion bash > $(brew --prefix)/etc/bash_completion.d/%[1]s
Zsh:
# 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 for each session, execute once:
$ %[1]s completion zsh > "${fpath[1]}/_%[1]s"
# You will need to start a new shell for this setup to take effect.
fish:
$ %[1]s completion fish | source
# To load completions for each session, execute once:
$ %[1]s completion fish > ~/.config/fish/completions/%[1]s.fish
PowerShell:
PS> %[1]s completion powershell | Out-String | Invoke-Expression
# To load completions for every new session, run:
PS> %[1]s completion powershell > %[1]s.ps1
# and source this file from your PowerShell profile.
`, rootCmd.Root().Name()),
DisableFlagsInUseLine: true,
ValidArgs: []string{"bash", "zsh", "fish", "powershell"},
Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs),
Run: func(cmd *cobra.Command, args []string) {
switch args[0] {
case "bash":
cmd.Root().GenBashCompletion(os.Stdout)
case "zsh":
cmd.Root().GenZshCompletion(os.Stdout)
case "fish":
cmd.Root().GenFishCompletion(os.Stdout, true)
case "powershell":
cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout)
}
},
}
23 changes: 7 additions & 16 deletions cmd/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,11 @@ import (
"log"
)

const (
keyDebug = "debug"
keyConnectionString = "connectionString"
keyConfig = "config"
keyUseRoutinesFile = "useRoutinesFile"
)
const keyUseRoutinesFile = "useRoutinesFile"

var generateFlags = []common.FlagArgument{
common.NewBoolFlag(keyUseRoutinesFile, "", false, "Use routines file to generate code"),
}

var generateCmd = &cobra.Command{
Use: "generate",
Expand All @@ -28,11 +27,7 @@ var generateCmd = &cobra.Command{
`,
Run: func(cmd *cobra.Command, args []string) {
common.BindBoolFlag(cmd, keyDebug)
common.BindBoolFlag(cmd, keyUseRoutinesFile)
common.BindStringFlag(cmd, keyConnectionString)
common.BindStringFlag(cmd, keyConfig)

common.BindFlags(cmd, append(commonFlags, generateFlags...))
_, err := dbGen.ReadConfig(viper.GetString(keyConfig))
if err != nil {
common.Exit("configuration error: %s", err)
Expand All @@ -50,11 +45,7 @@ var generateCmd = &cobra.Command{
func init() {
rootCmd.AddCommand(generateCmd)

// set cli flags
common.DefineBoolFlag(generateCmd, keyDebug, "d", false, "Print debug logs and create debug files")
common.DefineBoolFlag(generateCmd, keyUseRoutinesFile, "", false, "Use routines file to generate code")
common.DefineStringFlag(generateCmd, keyConnectionString, "s", "", "Connection string used to connect to database")
common.DefineStringFlag(generateCmd, keyConfig, "c", "", "Path to configuration file")
common.DefineFlags(generateCmd, append(commonFlags, generateFlags...))
}

func doGenerate() error {
Expand Down
6 changes: 3 additions & 3 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ For more information, see github.com/keenmate/db-gen
`,
}

// Execute adds all child commands to the root command and sets flags appropriately.
// Execute adds all child commands to the root command and sets generateCmdFlags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute(versionStringFile string) {
// because this is a top level file, we have to pass it like this
Expand All @@ -33,8 +33,8 @@ func Execute(versionStringFile string) {
func init() {
cobra.OnInitialize(initConfig)

// Here you will define your flags and configuration settings.
// Cobra supports persistent flags, which, if defined here,
// Here you will define your generateCmdFlags and configuration settings.
// Cobra supports persistent generateCmdFlags, which, if defined here,
// will be global for your application.

//common.ConfigurationString(rootCmd, "config", "c", "", "Path to configuration file")
Expand Down
15 changes: 6 additions & 9 deletions cmd/routines.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ var getRoutinesCmd = &cobra.Command{
Short: "Get routines",
Long: "Get routines from database and save them to file to generate later",
Run: func(cmd *cobra.Command, args []string) {
common.BindBoolFlag(cmd, keyDebug)
common.BindBoolFlag(cmd, keyUseRoutinesFile)
common.BindStringFlag(cmd, keyConnectionString)
common.BindStringFlag(cmd, keyConfig)
common.BindFlags(cmd, commonFlags)

configLocation := viper.GetString("config")

Expand All @@ -30,6 +27,10 @@ var getRoutinesCmd = &cobra.Command{

viper.AutomaticEnv() // read in environment variables that match

if args[0] != "" {
viper.Set("routinesFile", args[0])
}

err = doGetRoutines()

if err != nil {
Expand All @@ -41,11 +42,7 @@ var getRoutinesCmd = &cobra.Command{
func init() {
rootCmd.AddCommand(getRoutinesCmd)

// set cli flags
common.DefineBoolFlag(getRoutinesCmd, keyDebug, "d", false, "Print debug logs and create debug files")
common.DefineBoolFlag(getRoutinesCmd, keyUseRoutinesFile, "", false, "Use routines file to generate code")
common.DefineStringFlag(getRoutinesCmd, keyConnectionString, "s", "", "Connection string used to connect to database")
common.DefineStringFlag(getRoutinesCmd, keyConfig, "c", "", "Path to configuration file")
common.DefineFlags(getRoutinesCmd, commonFlags)
}

func doGetRoutines() error {
Expand Down
24 changes: 0 additions & 24 deletions common/configuration.go

This file was deleted.

73 changes: 73 additions & 0 deletions common/flagHelper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package common

import (
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

type FlagArgument interface {
DefineFlag(command *cobra.Command)
BindFlag(command *cobra.Command)
}

type StringFlag struct {
key string
shorthand string
defaultValue string
usage string
}

func (f *StringFlag) DefineFlag(command *cobra.Command) {
command.Flags().StringP(f.key, f.shorthand, f.defaultValue, f.usage)

}

func (f *StringFlag) BindFlag(command *cobra.Command) {
_ = viper.BindPFlag(f.key, command.Flags().Lookup(f.key))
}

func NewStringFlag(key string, shorthand string, defaultValue string, usage string) *StringFlag {
return &StringFlag{
key: key,
shorthand: shorthand,
defaultValue: defaultValue,
usage: usage,
}
}

type BoolFlag struct {
key string
shorthand string
defaultValue bool
usage string
}

func (f *BoolFlag) DefineFlag(command *cobra.Command) {
command.Flags().BoolP(f.key, f.shorthand, f.defaultValue, f.usage)
}

func (f *BoolFlag) BindFlag(command *cobra.Command) {
_ = viper.BindPFlag(f.key, command.Flags().Lookup(f.key))
}

func NewBoolFlag(key string, shorthand string, defaultValue bool, usage string) *BoolFlag {
return &BoolFlag{
key: key,
shorthand: shorthand,
defaultValue: defaultValue,
usage: usage,
}
}

// BindFlags we nned to separate binding from declaration if we dont have unique name for each flag
func BindFlags(command *cobra.Command, flags []FlagArgument) {
for _, flag := range flags {
flag.BindFlag(command)
}
}

func DefineFlags(command *cobra.Command, flags []FlagArgument) {
for _, flag := range flags {
flag.DefineFlag(command)
}
}

0 comments on commit fa5b9ef

Please sign in to comment.