package cmd import ( "os" "os/user" "path/filepath" "strings" "github.com/spf13/cobra" "gitlab.sweetwater.com/it/devops/tools/gitlab-project-manager/internal/cache" "gitlab.sweetwater.com/it/devops/tools/gitlab-project-manager/internal/config" "gitlab.sweetwater.com/it/devops/tools/gitlab-project-manager/internal/remotes" gitearemote "gitlab.sweetwater.com/it/devops/tools/gitlab-project-manager/internal/remotes/gitea" gitlabremote "gitlab.sweetwater.com/it/devops/tools/gitlab-project-manager/internal/remotes/gitlab" "gitlab.sweetwater.com/it/devops/tools/gitlab-project-manager/internal/remotes/remote" "golang.org/x/sys/unix" ) // This file contains init methods that may be used by // multiple sub-commands. For instance, the cach and projects // sub-commands both depend on a cache and may both call the initProjectCache // func from their PersistentPreRun commands func initProjectCache(cmd *cobra.Command, args []string) { var err error plog.Debug("Running pre-run for cacheCmd") conf.Cache.File = conf.ProjectPath + "/.cache.yaml" gitRemotes := remotes.NewRemotes() // Load GitLabs gitRemotes.AddRemotes(getGitLabRemotes(cmd)...) // Load Giteas gitRemotes.AddRemotes(getGiteaRemotes(cmd)...) cacheOpts := &cache.CacheOpts{ ProjectsPath: conf.ProjectPath, Path: conf.Cache.File, TTL: conf.Cache.Ttl, Logger: plog, Remotes: gitRemotes, Config: &conf, } if projectCache, err = cache.NewProjectCache(cacheOpts); err != nil { plog.Error("Failed to prepare project cache", plog.Args("error", err)) os.Exit(1) } if err := projectCache.Read(); err != nil { plog.Error("Cache load failed", plog.Args("error", err)) os.Exit(1) } plog.Debug("Remotes Loaded", plog.Args("remotes", cacheOpts.Remotes)) } // Loads all configured giteas func getGiteaRemotes(cmd *cobra.Command) []remote.Remote { gitRemotes := make([]remote.Remote, 0) for _, gitea := range conf.Giteas { if gitea.CloneProto == "" { gitea.CloneProto = config.DefaultCloneProto } giteaRemote, err := gitearemote.NewGiteaRemote(&remote.RemoteInfo{ Ctx: cmd.Context(), Host: gitea.Host, Name: gitea.Name, Token: gitea.Token, CloneProto: gitea.CloneProto, }) if err != nil { plog.Error("Failed to prepare Gitea remote", plog.Args("error", err)) } else { gitRemotes = append(gitRemotes, giteaRemote) } } return gitRemotes } // Loads all configured gitlabs, including as defined by legacy // top-level keys func getGitLabRemotes(cmd *cobra.Command) []remote.Remote { gitRemotes := make([]remote.Remote, 0) // Support legacy keys if conf.GitlabHost != "" && conf.GitlabToken != "" { conf.Gitlabs = append(conf.Gitlabs, config.GitlabConfig{ Host: conf.GitlabHost, Name: conf.GitlabHost, Token: conf.GitlabToken, CloneProto: config.CloneProtoSSH, }) } // Load Gitlabs for _, gl := range conf.Gitlabs { if gl.CloneProto == "" { gl.CloneProto = config.DefaultCloneProto } gitlabRemote, err := gitlabremote.NewGitlabRemote(&remote.RemoteInfo{ Ctx: cmd.Context(), Host: gl.Host, Name: gl.Name, Token: gl.Token, CloneProto: gl.CloneProto, }) if err != nil { plog.Error("Failed to prepare GitLab remote", plog.Args("error", err)) } else { gitRemotes = append(gitRemotes, gitlabRemote) } } return gitRemotes } func postProjectCache(cmd *cobra.Command, args []string) { projectCache.Write() } func initProjectPath(cmd *cobra.Command, args []string) { plog.Debug("Running persistent pre-run for rootCmd") var err error if conf.ProjectPath == "" { conf.ProjectPath = config.DefaultConfig.ProjectPath return } if conf.ProjectPath, err = resolvePath(conf.ProjectPath); err != nil { plog.Error("Failed to determine project path", plog.Args("error", err)) os.Exit(1) } _, err = os.Stat(conf.ProjectPath) if err != nil { plog.Error("Failed to stat project path, trying to create", plog.Args("error", err)) if err := os.MkdirAll(conf.ProjectPath, 0750); err != nil { plog.Error("Failed to create project path", plog.Args("error", err)) os.Exit(1) } plog.Info("Project path created", plog.Args("path", conf.ProjectPath)) } else { if err = unix.Access(conf.ProjectPath, unix.W_OK); err != nil { plog.Error("Unable to write to project path", plog.Args( "path", conf.ProjectPath, "error", err)) os.Exit(1) } } } func resolvePath(path string) (string, error) { if strings.HasPrefix(path, "~/") { usr, _ := user.Current() path = filepath.Join(usr.HomeDir, path[2:]) } return filepath.Abs(path) }