package projects import ( "bytes" "fmt" "strings" "text/tabwriter" "github.com/pterm/pterm" "gitlab.sweetwater.com/it/devops/tools/gitlab-project-manager/internal/gitlab" ) type ProjectAlias struct { Alias string ProjectID int } func ProjectAliasesString(aliases []*ProjectAlias) string { var str string for _, a := range aliases { str += "[" + pterm.LightCyan(a.Alias) + "] " } return strings.Trim(str, " ") } func (c *Cache) AliasesByProjectString() string { var str bytes.Buffer w := new(tabwriter.Writer) w.Init(&str, 10, 0, 0, ' ', tabwriter.AlignRight) for _, p := range c.GetProjectsWithAliases() { var pa string pa += pterm.LightBlue("- ") pa += fmt.Sprint(pterm.Bold.Sprint(p.String()) + " \t ") pa += fmt.Sprint(ProjectAliasesString(c.GetProjectAliases(p))) fmt.Fprintln(w, pa) } w.Flush() return str.String() } func (c *Cache) ProjectString(p *gitlab.Project) string { info := strings.Builder{} info.WriteString(pterm.LightGreen("\n--------------\n")) info.WriteString(pterm.Bold.Sprint(p.Name)) info.WriteRune('\n') if p.Description != "" { info.WriteString(p.Description) info.WriteRune('\n') } info.WriteString("\nPath: " + pterm.LightGreen(p.PathWithNamespace)) info.WriteString("\nProjectID: " + pterm.LightGreen(p.ID)) info.WriteString("\nURL: " + pterm.LightGreen(p.WebURL)) info.WriteString("\nLastActivity: " + pterm.LightMagenta(p.LastActivityAt.String())) info.WriteString("\nAliases: ") aliases := c.GetProjectAliases(p) info.WriteString(ProjectAliasesString(aliases)) info.WriteString(pterm.LightGreen("\n--------------\n")) return info.String() } func (c *Cache) ProjectStrings(prefix string) []string { projects := make([]string, 0, len(c.Projects)) for _, p := range c.Projects { if strings.HasPrefix(p.NameWithNamespace, prefix) { projects = append(projects, p.NameWithNamespace) } } return projects } func (c *Cache) AliasStrings(prefix string) []string { aliases := make([]string, 0, len(c.Aliases)) for _, a := range c.Aliases { if strings.HasPrefix(a.Alias, prefix) { aliases = append(aliases, a.Alias) } } return aliases } func (c *Cache) GetAliasByName(name string) *ProjectAlias { for _, a := range c.Aliases { if name == a.Alias { return a } } return nil } func (c *Cache) GetProjectByPath(path string) *gitlab.Project { for _, p := range c.Projects { if p.PathWithNamespace == path { return p } } return nil } func (c *Cache) GetProjectByID(id int) *gitlab.Project { for _, p := range c.Projects { if p.ID == id { return p } } return nil } func (c *Cache) GetProjectByAlias(alias *ProjectAlias) *gitlab.Project { if alias == nil { return nil } for _, p := range c.Projects { if p.ID == alias.ProjectID { return p } } return nil } func (c *Cache) GetProjectAliases(project *gitlab.Project) []*ProjectAlias { aliases := make([]*ProjectAlias, 0) for _, alias := range c.Aliases { if alias.ProjectID == project.ID { aliases = append(aliases, alias) } } return aliases } func (c *Cache) LoadProjects() { progressInfo := c.gitlab.StreamProjects(c.config.Cache.Load.OwnerOnly) c.Projects = make([]*gitlab.Project, 0) pBar := pterm.DefaultProgressbar. WithShowPercentage(true). WithTotal(-1). WithTitle("Listing GitLab Projects"). WithMaxWidth(100) defer pBar.Stop() var curProjects int for { select { case p := <-progressInfo.ProgressChan: if pBar.Total == -1 { pBar = pBar.WithTotal(p.TotalProjects) pBar, _ = pBar.Start() } // This sucks, has to be a better way, and why is the logger incompatible // with the progressbar? pterm.Debug.Println(fmt.Sprintf("Update received: %#v", p)) pBar.Add(p.Projects - curProjects) curProjects = p.Projects case p := <-progressInfo.ProjectsChan: c.Projects = append(c.Projects, p...) case e := <-progressInfo.ErrorChan: c.log.Error("Fetch GitLab projects error", c.log.Args("error", e)) case <-c.gitlab.Ctx.Done(): c.log.Warn("LoadProjects cancelled", c.log.Args("reason", c.gitlab.Ctx.Err())) return case <-progressInfo.DoneChan: pBar.Add(pBar.Total - curProjects) fmt.Println("") c.log.Info("Project load complete") return } } }