diff --git a/cmd/alias/alias_add.go b/cmd/alias/alias_add.go index 0d57196..47e4ea1 100644 --- a/cmd/alias/alias_add.go +++ b/cmd/alias/alias_add.go @@ -28,7 +28,15 @@ func runAddAliasCmd(cmd *cobra.Command, args []string) { // Check by flag if projectID := viper.GetInt(util.ViperAliasAddPID); projectID > 0 { utils.Logger().Debug(fmt.Sprintf("Adding for inbound project ID %d", projectID)) - project = utils.Cache().GetProjectByID(projectID) + + projects := utils.Cache().GetProjectsByID(projectID) + if len(projects) > 0 { + project = projects[0] + } + if len(projects) > 1 { + utils.Logger(). + Warn(fmt.Sprintf("found %d remotes with same ID, using first remote", len(projects))) + } } // Check by arg @@ -45,10 +53,10 @@ func runAddAliasCmd(cmd *cobra.Command, args []string) { } } - AddNewAliases(cmd, project.ID) + AddNewAliases(cmd, project.GetID()) } -func AddNewAliases(cmd *cobra.Command, projectID int) { +func AddNewAliases(cmd *cobra.Command, projectID string) { u := util.MustFromCtx(cmd.Context()) project := u.Cache().GetProjectByID(projectID) if project == nil { @@ -65,7 +73,7 @@ func AddNewAliases(cmd *cobra.Command, projectID int) { if a == "" { continue } - if err := u.Cache().AddAlias(a, project.ID, project.Remote); err != nil { + if err := u.Cache().AddAlias(a, project); err != nil { u.Logger().Debug("Skipping alias add", u.Logger().Args( "error", err, "alias", a, diff --git a/cmd/project/project.go b/cmd/project/project.go index 59cc261..789aa2a 100644 --- a/cmd/project/project.go +++ b/cmd/project/project.go @@ -50,7 +50,7 @@ func getProject(cmd *cobra.Command, args []string) *projects.Project { if len(utils.Cache().GetProjectAliases(project)) == 0 { utils.Logger().Info("New project, set aliases or press enter for default") - alias.AddNewAliases(cmd, project.ID) + alias.AddNewAliases(cmd, project.GetID()) } return project diff --git a/internal/cache/cache_aliases.go b/internal/cache/cache_aliases.go index 89e4698..dd1fc1e 100644 --- a/internal/cache/cache_aliases.go +++ b/internal/cache/cache_aliases.go @@ -22,7 +22,7 @@ func (c *Cache) DeleteAlias(alias *ProjectAlias) { c.deleteAlias(alias) } -func (c *Cache) addAlias(alias string, projectID int, remote string) error { +func (c *Cache) addAlias(alias string, project *projects.Project) error { if c.GetAliasByName(alias) != nil { return errors.New("failed to add alias, already exists") } @@ -30,26 +30,27 @@ func (c *Cache) addAlias(alias string, projectID int, remote string) error { c.Aliases = append(c.Aliases, &ProjectAlias{ Alias: alias, - ProjectID: projectID, - Remote: remote, + ProjectID: project.ID, + ID: project.GetID(), + Remote: project.Remote, }) return nil } -func (c *Cache) AddAlias(alias string, projectID int, remote string) error { +func (c *Cache) AddAlias(alias string, project *projects.Project) error { c.lock.Lock() defer c.lock.Unlock() - return c.addAlias(alias, projectID, remote) + return c.addAlias(alias, project) } func (c *Cache) GetProjectsWithAliases() []*projects.Project { projectList := make([]*projects.Project, 0) - projectsFound := make([]int, 0) + projectsFound := make([]string, 0) for _, a := range c.Aliases { - if !slices.Contains(projectsFound, a.ProjectID) { + if !slices.Contains(projectsFound, a.ID) { projectList = append(projectList, c.GetProjectByAlias(a)) - projectsFound = append(projectsFound, a.ProjectID) + projectsFound = append(projectsFound, a.ID) } } return projectList @@ -68,12 +69,13 @@ func (c *Cache) setAliasRemotes() { } func (c *Cache) setAliasRemote(alias *ProjectAlias) { - project := c.GetProjectByID(alias.ProjectID) + project := c.GetProjectByID(alias.ID) if project != nil { alias.Remote = project.Remote c.log.Debug("Fixed missing alias remote", c.log.Args( "alias", alias.Alias, "projectID", alias.ProjectID, + "ID", alias.ID, "remote", alias.Remote, )) } diff --git a/internal/cache/projects.go b/internal/cache/projects.go index 16fed6d..272bf99 100644 --- a/internal/cache/projects.go +++ b/internal/cache/projects.go @@ -4,8 +4,9 @@ import ( "strings" "github.com/pterm/pterm" - "gitea.libretechconsulting.com/rmcguire/git-project-manager/internal/remotes/projects" "golang.org/x/exp/slices" + + "gitea.libretechconsulting.com/rmcguire/git-project-manager/internal/remotes/projects" ) func (c *Cache) ProjectString(p *projects.Project) string { @@ -60,9 +61,9 @@ func (c *Cache) GetProjectByRemoteAndId(remote string, id int) *projects.Project return nil } -func (c *Cache) GetProjectByID(id int) *projects.Project { +func (c *Cache) GetProjectByID(id string) *projects.Project { for _, p := range c.Projects { - if p.ID == id { + if p.GetID() == id { return p } } diff --git a/internal/cache/projects_alias.go b/internal/cache/projects_alias.go index 17906d2..0d76bf0 100644 --- a/internal/cache/projects_alias.go +++ b/internal/cache/projects_alias.go @@ -7,13 +7,15 @@ import ( "text/tabwriter" "github.com/pterm/pterm" - "gitea.libretechconsulting.com/rmcguire/git-project-manager/internal/remotes/projects" "golang.org/x/exp/slices" + + "gitea.libretechconsulting.com/rmcguire/git-project-manager/internal/remotes/projects" ) type ProjectAlias struct { Alias string ProjectID int + ID string Remote string } @@ -96,7 +98,7 @@ func (c *Cache) GetProjectByAlias(alias *ProjectAlias) *projects.Project { return nil } for _, p := range c.Projects { - if p.ID == alias.ProjectID && p.Remote == alias.Remote { + if p.GetID() == alias.ID { return p } } diff --git a/internal/remotes/projects/projects.go b/internal/remotes/projects/projects.go index 18a3133..a8847ea 100644 --- a/internal/remotes/projects/projects.go +++ b/internal/remotes/projects/projects.go @@ -1,6 +1,7 @@ package projects import ( + "crypto/sha1" "fmt" "strings" "time" @@ -35,8 +36,7 @@ type ProjectLanguage struct { } func NewProjectLanguages() *ProjectLanguages { - var pLangs ProjectLanguages - pLangs = make([]*ProjectLanguage, 0) + var pLangs ProjectLanguages = make([]*ProjectLanguage, 0) return &pLangs } @@ -44,6 +44,21 @@ func (pl *ProjectLanguages) AddLanguage(lang *ProjectLanguage) { *pl = append(*pl, lang) } +// Gets a unique ID using a short-sha of the http repo URL +// along with the numerical ID of the project. +// Uses SSH URL and then Remote if previous is empty +func (p *Project) GetID() string { + shaText := p.HTTPURLToRepo + if shaText == "" && p.SSHURLToRepo != "" { + shaText = p.SSHURLToRepo + } else if shaText == "" { + shaText = p.Remote + } + + shortSha := fmt.Sprintf("%x", sha1.Sum([]byte(shaText)))[:12] + return fmt.Sprintf("%s||%d", shortSha, p.ID) +} + func (p *Project) String() string { var projectString string if p != nil { diff --git a/internal/remotes/projects/projects_net.go b/internal/remotes/projects/projects_net.go index ddc0d6a..2b3942c 100644 --- a/internal/remotes/projects/projects_net.go +++ b/internal/remotes/projects/projects_net.go @@ -20,9 +20,7 @@ const ( GitProtoHTTP ) -var ( - ErrUnknownHost error = errors.New("No addresses found for host") -) +var ErrUnknownHost error = errors.New("no addresses found for host") func (p *Project) CheckHost(proto GitProto) error { switch proto { @@ -31,7 +29,7 @@ func (p *Project) CheckHost(proto GitProto) error { case GitProtoSSH: return p.checkSSHRemote() } - return errors.New("Unknown git protocol") + return errors.New("unknown git protocol") } func (p *Project) checkHTTPRemote() error {