Fix bugs, set constants
This commit is contained in:
@ -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))
|
||||
}
|
||||
|
@ -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}).
|
||||
|
@ -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 {
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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")
|
||||
}
|
||||
|
@ -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")
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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))
|
||||
}
|
||||
|
26
cmd/root.go
26
cmd/root.go
@ -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)
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user