// 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 (u *Util) from their PersistentPreRun commands package util import ( "fmt" "os" "os/user" "path/filepath" "strings" "github.com/pterm/pterm" "github.com/spf13/cobra" "golang.org/x/sys/unix" "gitea.libretechconsulting.com/rmcguire/git-project-manager/internal/cache" "gitea.libretechconsulting.com/rmcguire/git-project-manager/internal/config" "gitea.libretechconsulting.com/rmcguire/git-project-manager/internal/remotes" gitearemote "gitea.libretechconsulting.com/rmcguire/git-project-manager/internal/remotes/gitea" githubremote "gitea.libretechconsulting.com/rmcguire/git-project-manager/internal/remotes/github" gitlabremote "gitea.libretechconsulting.com/rmcguire/git-project-manager/internal/remotes/gitlab" "gitea.libretechconsulting.com/rmcguire/git-project-manager/internal/remotes/remote" ) func InitProjects(cmd *cobra.Command, args []string) { utils, _ := FromCtx(cmd.Context()) utils.InitProjectCache(cmd, args) utils.mustHaveProjects(cmd, args) } func (u *Utils) mustHaveProjects(cmd *cobra.Command, _ []string) { if len(u.Cache().Projects) == 0 { u.Logger().Fatal("No projects to " + cmd.Name() + ", try running cache load") } } func (u *Utils) InitProjectCache(cmd *cobra.Command, _ []string) { var err error u.Logger().Debug("Running pre-run for cacheCmd") u.Config().Cache.File = u.Config().ProjectPath + "/.cache.yaml" gitRemotes := remotes.NewRemotes() gitRemotes.AddRemotes(*u.GetRemotes(cmd)...) cacheOpts := &cache.CacheOpts{ ProjectsPath: u.Config().ProjectPath, Path: u.Config().Cache.File, TTL: u.Config().Cache.Ttl, Logger: u.Logger(), Remotes: gitRemotes, Config: u.Config(), } projectCache, err := cache.NewProjectCache(cacheOpts) if err != nil { u.Logger().Error("Failed to prepare project cache", u.Logger().Args("error", err)) os.Exit(1) } u.SetCache(projectCache) if err := u.Cache().Read(); err != nil { u.Logger().Error("Cache load failed", u.Logger().Args("error", err)) os.Exit(1) } u.Logger().Debug("Remotes Loaded", u.Logger().Args("remotes", cacheOpts.Remotes)) } // Generically loads remotes from info.RemoteInfo in config.Remotes func (u *Utils) GetRemotes(cmd *cobra.Command) *remotes.Remotes { gitRemotes := new(remotes.Remotes) *gitRemotes = make([]remote.Remote, 0) for _, r := range u.Config().Remotes { // Create a copy, set context gitRemoteInfo := r gitRemoteInfo.SetContext(cmd.Context()) var gitRemote remote.Remote var err error switch r.Type { case "gitlab": gitRemote, err = gitlabremote.NewGitlabRemote(&gitRemoteInfo) case "gitea": gitRemote, err = gitearemote.NewGiteaRemote(&gitRemoteInfo) case "github": gitRemote, err = githubremote.NewGithubRemote(&gitRemoteInfo) } if err != nil { u.Logger().Error("Failed to prepare remote", u.Logger().Args( "error", err, "type", r.Type)) } else { *gitRemotes = append(*gitRemotes, gitRemote) } } return gitRemotes } func PostProjectCmd(cmd *cobra.Command, args []string) { utils, _ := FromCtx(cmd.Context()) utils.PostProjectCache(cmd, args) } func (u *Utils) PostProjectCache(_ *cobra.Command, _ []string) { u.Cache().Write() } func (u *Utils) InitProjectPath(_ *cobra.Command, _ []string) { u.Logger().Debug("Running persistent pre-run for rootCmd") var err error if u.Config().ProjectPath == "" { u.Config().ProjectPath = config.DefaultConfig.ProjectPath return } if u.Config().ProjectPath, err = ResolvePath(u.Config().ProjectPath); err != nil { u.Logger().Error("Failed to determine project path", u.Logger().Args("error", err)) os.Exit(1) } _, err = os.Stat(u.Config().ProjectPath) if err != nil { u.Logger().Error("Failed to stat project path, trying to create", u.Logger().Args("error", err)) if err = os.MkdirAll(u.Config().ProjectPath, 0o750); err != nil { u.Logger().Error("Failed to create project path", u.Logger().Args("error", err)) os.Exit(1) } u.Logger().Info("Project path created", u.Logger().Args("path", u.Config().ProjectPath)) } else { if err = unix.Access(u.Config().ProjectPath, unix.W_OK); err != nil { u.Logger().Error("Unable to write to project path", u.Logger().Args( "path", u.Config().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) } func GetConfigName(configPath string) string { // Check existing config for _, ext := range []string{"yml", "yaml"} { configFile := fmt.Sprintf("%s/%s.%s", configPath, ConfigName, ext) legacyConfigFile := fmt.Sprintf("%s/%s.%s", configPath, LegacyConfigName, ext) if _, err := os.Stat(configFile); err == nil { return ConfigName } else if _, err := os.Stat(legacyConfigFile); err == nil { pterm.DefaultLogger.WithWriter(os.Stderr). Warn(fmt.Sprintf("using legacy config path, suggest using %s/%s.yaml", configPath, ConfigName)) return LegacyConfigName } } // Nothing found, do what we want return ConfigName }