Fix bugs, set constants

This commit is contained in:
2024-10-01 14:29:14 -04:00
parent a54f0629be
commit 03fcbe41ae
20 changed files with 165 additions and 89 deletions

View File

@ -7,6 +7,7 @@ import (
"github.com/pterm/pterm"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"gitlab.sweetwater.com/it/devops/tools/gitlab-project-manager/internal/cache"
"gitlab.sweetwater.com/it/devops/tools/gitlab-project-manager/internal/remotes/projects"
)
@ -24,7 +25,7 @@ func runAddAliasCmd(cmd *cobra.Command, args []string) {
var project *projects.Project
// Check by flag
if projectID := viper.GetInt("alias.add.projectid"); projectID > 0 {
if projectID := viper.GetInt(ViperAliasAddPID); projectID > 0 {
plog.Debug(fmt.Sprintf("Adding for inbound project ID %d", projectID))
project = projectCache.GetProjectByID(projectID)
}
@ -97,9 +98,9 @@ func promptAliasesForProject(p *projects.Project) []string {
func init() {
aliasCmd.AddCommand(aliasAddCmd)
aliasAddCmd.PersistentFlags().Int("projectID", 0, "Specify a project by ID")
aliasAddCmd.PersistentFlags().Int(FlagProjectID, 0, "Specify a project by ID")
aliasAddCmd.RegisterFlagCompletionFunc("projectID", validProjectIdFunc)
aliasAddCmd.RegisterFlagCompletionFunc(FlagProjectID, validProjectIdFunc)
viper.BindPFlag("alias.add.projectID", aliasAddCmd.Flag("projectID"))
viper.BindPFlag(ViperAliasAddPID, aliasAddCmd.Flag(FlagProjectID))
}

View File

@ -19,7 +19,7 @@ var aliasListCmd = &cobra.Command{
}
func runListAliasCmd(cmd *cobra.Command, args []string) {
remotes := viper.GetStringSlice("remote")
remotes := viper.GetStringSlice(FlagRemote)
pterm.DefaultBox.
WithLeftPadding(5).WithRightPadding(5).
WithBoxStyle(&pterm.Style{pterm.FgLightBlue}).

View File

@ -17,7 +17,7 @@ var dumpCmd = &cobra.Command{
}
func runCacheDunpCmd(cmd *cobra.Command, args []string) {
remotes := viper.GetStringSlice("remote")
remotes := viper.GetStringSlice(FlagRemote)
if conf.Dump.Full {
fmt.Println(projectCache.DumpString(true, searchStringFromArgs(args), remotes...))
} else {

View File

@ -17,15 +17,15 @@ wants to find a new project.`,
}
func loadCache(cmd *cobra.Command, args []string) {
remotes := viper.GetStringSlice("remote")
remotes := viper.GetStringSlice(FlagRemote)
projectCache.Refresh(remotes...)
}
func init() {
cacheCmd.AddCommand(loadCmd)
loadCmd.PersistentFlags().Bool("ownerOnly", true,
loadCmd.PersistentFlags().Bool(FlagOwnerOnly, true,
"Only load projects that you are owner of")
viper.BindPFlag("cache.load.ownerOnly", loadCmd.Flag("ownerOnly"))
viper.BindPFlag(ViperCacheLoadOwnerOnly, loadCmd.Flag(FlagOwnerOnly))
}

View File

@ -12,7 +12,7 @@ var unlockCmd = &cobra.Command{
Long: `unlocks cache to display`,
Run: func(cmd *cobra.Command, args []string) {
initProjectCache(cmd, args)
if viper.GetBool("cache.unlock.force") {
if viper.GetBool(ViperCacheUnlockForce) {
projectCache.UnlockCache()
} else if yes, _ := pterm.DefaultInteractiveConfirm.
WithDefaultValue(false).
@ -26,6 +26,6 @@ var unlockCmd = &cobra.Command{
func init() {
cacheCmd.AddCommand(unlockCmd)
unlockCmd.PersistentFlags().BoolP("force", "f", false, "force unlocks cache (don't ask)")
viper.BindPFlag("cache.unlock.force", unlockCmd.LocalFlags().Lookup("force"))
unlockCmd.PersistentFlags().BoolP(FlagCacheForce, "f", false, "force unlocks cache (don't ask)")
viper.BindPFlag(ViperCacheUnlockForce, unlockCmd.LocalFlags().Lookup(FlagCacheForce))
}

View File

@ -8,9 +8,10 @@ import (
"github.com/pterm/pterm"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"gopkg.in/yaml.v3"
"gitlab.sweetwater.com/it/devops/tools/gitlab-project-manager/internal/config"
"gitlab.sweetwater.com/it/devops/tools/gitlab-project-manager/internal/remotes/info"
"gopkg.in/yaml.v3"
)
var configGenerateCmd = &cobra.Command{
@ -35,7 +36,7 @@ func runConfigGenerateCmd(cmd *cobra.Command, args []string) {
newConf := promptConfigSettings(&conf)
if write, _ := cmd.Flags().GetBool("write"); write {
if write, _ := cmd.Flags().GetBool(FlagWrite); write {
write, _ := pterm.DefaultInteractiveContinue.
WithDefaultText("Really write config file?").
WithOptions([]string{"yes", "no"}).
@ -59,7 +60,7 @@ func runConfigGenerateCmd(cmd *cobra.Command, args []string) {
}
func writeConfigFile(c *config.Config, path string) {
file, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0640)
file, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o640)
if err != nil {
plog.Error("Failed to prepare config for writing", plog.Args("error", err))
}
@ -149,6 +150,6 @@ func promptConfigSettings(c *config.Config) *config.Config {
func init() {
configCmd.AddCommand(configGenerateCmd)
configGenerateCmd.PersistentFlags().Bool("prompt", false, "Prompt for settings")
configGenerateCmd.PersistentFlags().Bool("write", false, "Write config to file")
configGenerateCmd.PersistentFlags().Bool(FlagPrompt, false, "Prompt for settings")
configGenerateCmd.PersistentFlags().Bool(FlagWrite, false, "Write config to file")
}

View File

@ -18,7 +18,7 @@ var configShowCmd = &cobra.Command{
func runConfigShowCmd(cmd *cobra.Command, args []string) {
c := conf
showSensitive, _ := cmd.Flags().GetBool("sensitive")
showSensitive, _ := cmd.Flags().GetBool(FlagSensitive)
if !showSensitive {
plog.Info("Sensitive fields hidden, do not use unreviewed as config")
for _, r := range c.Remotes {
@ -35,5 +35,5 @@ func runConfigShowCmd(cmd *cobra.Command, args []string) {
func init() {
configCmd.AddCommand(configShowCmd)
configShowCmd.Flags().BoolP("sensitive", "s", false, "Set to show sensitive fields")
configShowCmd.Flags().BoolP(FlagSensitive, "s", false, "Set to show sensitive fields")
}

View File

@ -3,6 +3,7 @@ package cmd
import (
"github.com/spf13/cobra"
"github.com/spf13/viper"
"gitlab.sweetwater.com/it/devops/tools/gitlab-project-manager/internal/cache"
"gitlab.sweetwater.com/it/devops/tools/gitlab-project-manager/internal/remotes/projects"
)
@ -20,7 +21,7 @@ var projectCmd = &cobra.Command{
}
func getProject(args []string) *projects.Project {
remotes := viper.GetStringSlice("remote")
remotes := viper.GetStringSlice(FlagRemote)
fzfOpts := &fzfProjectOpts{
Ctx: rootCmd.Context(),
Search: searchStringFromArgs(args),

View File

@ -21,7 +21,7 @@ var projectGoCmd = &cobra.Command{
}
func projectGoCmdRun(cmd *cobra.Command, args []string) {
remotes := viper.GetStringSlice("remote")
remotes := viper.GetStringSlice(FlagRemote)
fzfOpts := &fzfProjectOpts{
Ctx: cmd.Context(),
Search: searchStringFromArgs(args),

View File

@ -16,12 +16,12 @@ var projectListCmd = &cobra.Command{
}
func projectListCmdRun(cmd *cobra.Command, args []string) {
remotes := viper.GetStringSlice("remote")
fmt.Println(projectCache.DumpString(viper.GetBool("project.list.all"), searchStringFromArgs(args), remotes...))
remotes := viper.GetStringSlice(FlagRemote)
fmt.Println(projectCache.DumpString(viper.GetBool(ViperProjectListAll), searchStringFromArgs(args), remotes...))
}
func init() {
projectCmd.AddCommand(projectListCmd)
projectListCmd.PersistentFlags().Bool("all", false, "List all, not just cloned locally")
viper.BindPFlag("project.list.all", projectListCmd.Flag("all"))
projectListCmd.PersistentFlags().Bool(FlagAll, false, "List all, not just cloned locally")
viper.BindPFlag(ViperProjectListAll, projectListCmd.Flag(FlagAll))
}

View File

@ -51,7 +51,7 @@ func projectOpenCmdRun(cmd *cobra.Command, args []string) {
plog.Fatal("No usable editor found")
}
remotes := viper.GetStringSlice("remote")
remotes := viper.GetStringSlice(FlagRemote)
fzfOpts := &fzfProjectOpts{
Ctx: cmd.Context(),
Search: searchStringFromArgs(args),
@ -172,7 +172,7 @@ func isEditorExecutable(editor string) bool {
stat, err := os.Stat(editor)
if err == nil && (stat.Mode()&0444 != 0 && stat.Mode()&0111 != 0) {
if err == nil && (stat.Mode()&0o444 != 0 && stat.Mode()&0o111 != 0) {
canExec = true
}

View File

@ -18,7 +18,7 @@ var projectRunCmd = &cobra.Command{
}
func projectRunCmdRun(cmd *cobra.Command, args []string) {
remotes := viper.GetStringSlice("remote")
remotes := viper.GetStringSlice(FlagRemote)
fzfOpts := &fzfProjectOpts{
Ctx: cmd.Context(),
Search: searchStringFromArgs(args),

View File

@ -7,6 +7,7 @@ import (
"github.com/pterm/pterm"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"gitlab.sweetwater.com/it/devops/tools/gitlab-project-manager/internal/remotes/projects"
)
@ -23,7 +24,7 @@ func projectShowCmdRun(cmd *cobra.Command, args []string) {
var project *projects.Project
var inCwd bool
remotes := viper.GetStringSlice("remote")
remotes := viper.GetStringSlice(FlagRemote)
fzfOpts := &fzfProjectOpts{
Ctx: cmd.Context(),
Search: searchStringFromArgs(args),
@ -31,7 +32,7 @@ func projectShowCmdRun(cmd *cobra.Command, args []string) {
}
// Try to find project from current directory
if viper.GetBool("project.show.current") {
if viper.GetBool(ViperProjectShowCurrent) {
var err error
project, err = projectCache.GetProjectFromCwd()
if err != nil {
@ -78,6 +79,6 @@ func projectShowCmdRun(cmd *cobra.Command, args []string) {
func init() {
projectCmd.AddCommand(projectShowCmd)
projectShowCmd.PersistentFlags().Bool("current", false, "Use project in CWD rather than fuzzy find")
viper.BindPFlag("project.show.current", projectShowCmd.Flag("current"))
projectShowCmd.PersistentFlags().Bool(FlagCurrent, false, "Use project in CWD rather than fuzzy find")
viper.BindPFlag(ViperProjectShowCurrent, projectShowCmd.Flag(FlagCurrent))
}

View File

@ -9,11 +9,14 @@ import (
"github.com/pterm/pterm"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"gitlab.sweetwater.com/it/devops/tools/gitlab-project-manager/internal/config"
)
var conf config.Config
var plog *pterm.Logger
var (
conf config.Config
plog *pterm.Logger
)
var rootCmd = &cobra.Command{
Use: "gitlab-project-manager",
@ -36,7 +39,6 @@ func Execute() {
defer cncl()
err := rootCmd.ExecuteContext(ctx)
if err != nil {
pterm.Error.Printfln(pterm.LightYellow("Command failed, " + err.Error()))
os.Exit(1)
@ -48,25 +50,25 @@ func init() {
cobra.OnInitialize(initConfig)
// Global flags
rootCmd.PersistentFlags().String("config", "",
rootCmd.PersistentFlags().String(FlagConfig, "",
"config file (default is "+defConfigPath+")")
rootCmd.PersistentFlags().String("projectPath", "",
rootCmd.PersistentFlags().String(FlagPath, "",
"Sets a path for local clones of projects")
rootCmd.PersistentFlags().String("logLevel", defLogLevel,
rootCmd.PersistentFlags().String(FlagLogLevel, defLogLevel,
"Default log level -- info, warn, error, debug")
rootCmd.PersistentFlags().StringSlice("remote", []string{},
rootCmd.PersistentFlags().StringSlice(FlagRemote, []string{},
"Specify remotes by host for any sub-command. Provide multiple times or comma delimited.")
// Flag autocompletion
rootCmd.RegisterFlagCompletionFunc("logLevel", validLogLevelsFunc)
rootCmd.RegisterFlagCompletionFunc("remote", validRemotesFunc)
rootCmd.RegisterFlagCompletionFunc(FlagLogLevel, validLogLevelsFunc)
rootCmd.RegisterFlagCompletionFunc(FlagRemote, validRemotesFunc)
viper.BindPFlags(rootCmd.PersistentFlags())
}
// initConfig reads in config file and ENV variables if set.
func initConfig() {
cfgFile := viper.GetString("config")
cfgFile := viper.GetString(FlagConfig)
if cfgFile != "" {
// Use config file from the flag.
viper.SetConfigFile(cfgFile)
@ -86,7 +88,7 @@ func initConfig() {
// Configure pretty logger
plog = pterm.DefaultLogger.
WithLevel(getPtermLogLevel(viper.GetString("logLevel"))).
WithLevel(getPtermLogLevel(viper.GetString(FlagLogLevel))).
WithWriter(os.Stderr)
if plog.Level == pterm.LogLevelDebug {
pterm.EnableDebugMessages()
@ -137,7 +139,7 @@ func checkConfigPerms(file string) {
plog.Error("Failure reading configuration", plog.Args("err", err))
return
}
if stat.Mode().Perm()&0004 == 0004 {
if stat.Mode().Perm()&0o004 == 0o004 {
plog.Error("Configuration is world-readable. Recomment 0400.",
plog.Args("mode", stat.Mode().String()))
os.Exit(1)

View File

@ -1,5 +1,28 @@
package cmd
const (
// Cobra Flags
FlagRemote = "remote"
FlagConfig = "config"
FlagPath = "projectPath"
FlagLogLevel = "logLevel"
FlagProjectID = "projectID"
FlagCacheForce = "force"
FlagOwnerOnly = "ownerOnly"
FlagAll = "all"
FlagCurrent = "current"
FlagPrompt = "prompt"
FlagWrite = "write"
FlagSensitive = "sensitive"
// Viper config bindings
ViperAliasAddPID = "alias.add.projectID"
ViperCacheUnlockForce = "cache.unlock.force"
ViperCacheLoadOwnerOnly = "cache.load.ownerOnly"
ViperProjectListAll = "project.list.all"
ViperProjectShowCurrent = "project.show.current"
)
const (
defGitlabHost = "https://gitlab.com"
defLogLevel = "info"

View File

@ -4,9 +4,10 @@ import (
"context"
fzf "github.com/ktr0731/go-fuzzyfinder"
"golang.org/x/exp/slices"
"gitlab.sweetwater.com/it/devops/tools/gitlab-project-manager/internal/cache"
"gitlab.sweetwater.com/it/devops/tools/gitlab-project-manager/internal/remotes/projects"
"golang.org/x/exp/slices"
)
type fzfProjectOpts struct {
@ -96,7 +97,8 @@ func fzfAliasFromAliases(opts *fzfProjectOpts, aliases []*cache.ProjectAlias) *c
// Given a list of aliases, merge them together and use the resulting
// list of projects to return a project
func fzfProjectFromAliases(opts *fzfProjectOpts, aliases []*cache.ProjectAlias) (
*projects.Project, error) {
*projects.Project, error,
) {
mergedProjects := projectsFromAliases(aliases)
if len(mergedProjects) == 1 {
return mergedProjects[0], nil
@ -105,20 +107,16 @@ func fzfProjectFromAliases(opts *fzfProjectOpts, aliases []*cache.ProjectAlias)
}
func projectsFromAliases(aliases []*cache.ProjectAlias) []*projects.Project {
projects := make([]*projects.Project, 0)
projects := make([]*projects.Project, 0, len(aliases))
ALIASES:
for _, a := range aliases {
for _, p := range projects {
// Already have it
if p == nil || (a.ProjectID == p.ID && a.Remote == p.Remote) {
continue ALIASES
}
project := projectCache.GetProjectByAlias(a)
if project != nil && !slices.Contains(projects, project) {
projects = append(projects, project)
}
projects = append(projects, projectCache.GetProjectByAlias(a))
}
return projects
return slices.Clip(projects)
}
// If opts.MustHaveAlias, will only allow selection of projects
@ -137,7 +135,8 @@ func fzfProject(opts *fzfProjectOpts) (*projects.Project, error) {
// Takes a list of projects and performs a fuzzyfind
func fzfProjectFromProjects(opts *fzfProjectOpts, projects []*projects.Project) (
*projects.Project, error) {
*projects.Project, error,
) {
i, err := fzf.Find(projects,
func(i int) string {
// Display the project along with its aliases