package projects import ( "fmt" "strings" "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) ProjectString(p *gitlab.Project) string { info := strings.Builder{} info.WriteString(pterm.LightBlue(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)) return info.String() } func (c *Cache) ProjectStrings() []string { projects := make([]string, len(c.Projects)) for i, p := range c.Projects { projects[i] = p.NameWithNamespace } return projects } func (c *Cache) AliasStrings() []string { aliases := make([]string, len(c.Aliases)) for i, a := range c.Aliases { aliases[i] = 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) 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.Projects = make([]*gitlab.Project, 0) pBar := pterm.DefaultProgressbar. WithShowPercentage(true). WithTotal(-1). WithTitle("Listing GitLab Projects"). WithMaxWidth(0) 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) c.log.Info("Project load complete") return } } }