This commit is contained in:
2023-12-08 23:13:17 -05:00
parent 82e4f2f51e
commit 4e76c9efe1
17 changed files with 265 additions and 65 deletions

View File

@ -5,9 +5,10 @@ import (
)
var aliasCmd = &cobra.Command{
Use: "alias",
Short: "Manage project aliases",
Long: aliasCmdLong,
Use: "alias",
Aliases: []string{"aliases", "a"},
Short: "Manage project aliases",
Long: aliasCmdLong,
// Just re-use the hooks for project
PersistentPreRun: initProjectCmd,
PersistentPostRun: postProjectCmd,

View File

@ -12,11 +12,12 @@ import (
)
var aliasAddCmd = &cobra.Command{
Use: "add",
Short: "Add a project alias",
Args: cobra.ArbitraryArgs,
Long: aliasAddCmdLong,
Run: runAddAliasCmd,
Use: "add",
Aliases: []string{"set", "a", "s"},
Short: "Add a project alias",
Args: cobra.ArbitraryArgs,
Long: aliasAddCmdLong,
Run: runAddAliasCmd,
}
func runAddAliasCmd(cmd *cobra.Command, args []string) {
@ -57,7 +58,7 @@ func addNewAliases(projectID int) {
// Add aliases
for _, a := range aliases {
a = strings.Trim(a, " '\"%")
a = strings.Trim(a, " '\"%<>|`")
if a == "" {
continue
}

View File

@ -3,28 +3,70 @@ package cmd
import (
"fmt"
"github.com/pterm/pterm"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"gitlab.sweetwater.com/it/devops/tools/gitlab-project-manager/internal/gitlab"
)
var aliasDeleteCmd = &cobra.Command{
Use: "delete [fuzzy project or alias]",
Short: "Delete a project alias",
Long: aliasDeleteCmdLong,
Run: runDeleteAliasCmd,
Use: "delete [fuzzy project or alias]",
Aliases: []string{"rm", "del", "d"},
Short: "Delete a project alias",
Long: aliasDeleteCmdLong,
Run: runDeleteAliasCmd,
}
func runDeleteAliasCmd(cmd *cobra.Command, args []string) {
var project *gitlab.Project
var err error
if len(args) > 0 {
project = fzfFindProject(args[0])
} else {
project, _ = fzfProject(cmd.Context())
project, err = fzfProject(cmd.Context(), true)
}
fmt.Println(project.String())
if project == nil || err != nil {
plog.Fatal("Failed to find project to delete aliases from", plog.Args(
"error", err,
))
}
aliasStrings := cache.GetProjectAliasStrings(project)
deletionCandidates, err := pterm.DefaultInteractiveMultiselect.
WithOptions(aliasStrings).
Show()
if err != nil || len(deletionCandidates) < 1 {
plog.Fatal("Failed to find project to delete aliases from", plog.Args(
"error", err,
))
}
for _, a := range deletionCandidates {
confirm, _ := pterm.DefaultInteractiveConfirm.
WithDefaultText(fmt.Sprintf("Really delete %s -> %s?",
a, project.String())).
WithConfirmText("y").
Show()
if !confirm {
plog.Warn("Alias deletion cancelled")
continue
}
plog.Info("Deleting alias", plog.Args(
"project", project.String(),
"alias", a,
))
cache.DeleteAlias(cache.GetAliasByName(a))
}
fmt.Println(cache.ProjectString(project))
}
func init() {

24
cmd/alias_list.go Normal file
View File

@ -0,0 +1,24 @@
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
// listCmd represents the list command
var aliasListCmd = &cobra.Command{
Use: "list",
Aliases: []string{"dump", "show", "ls", "ll", "l"},
Short: "List Aliases",
Long: aliasListCmdLong,
Run: runListAliasCmd,
}
func runListAliasCmd(cmd *cobra.Command, args []string) {
fmt.Print("\n" + cache.AliasesByProjectString() + "\n")
}
func init() {
aliasCmd.AddCommand(aliasListCmd)
}

View File

@ -1,26 +0,0 @@
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
// configCmd represents the config command
var configCmd = &cobra.Command{
Use: "config",
Short: "A brief description of your command",
Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("config called")
},
}
func init() {
rootCmd.AddCommand(configCmd)
}

View File

@ -2,12 +2,14 @@ package cmd
import (
"github.com/spf13/cobra"
"gitlab.sweetwater.com/it/devops/tools/gitlab-project-manager/internal/gitlab"
"gitlab.sweetwater.com/it/devops/tools/gitlab-project-manager/internal/projects"
)
var projectCmd = &cobra.Command{
Use: "project [fuzzy alias search]",
Short: "Use a GitLab project",
Aliases: []string{"proj", "projects", "p"},
Args: cobra.MaximumNArgs(1),
ArgAliases: []string{"alias"},
ValidArgsFunction: validAliasesFunc,
@ -18,10 +20,15 @@ var projectCmd = &cobra.Command{
}
func projectCmdRun(cmd *cobra.Command, args []string) {
goToProject(getProject(args))
}
func getProject(args []string) *gitlab.Project {
var searchString string
if len(args) > 0 {
searchString = args[0]
}
project := fzfFindProject(searchString)
if project == nil {
@ -33,6 +40,13 @@ func projectCmdRun(cmd *cobra.Command, args []string) {
cache.GetProjectAliases(project)),
))
}
if len(cache.GetProjectAliases(project)) == 0 {
plog.Info("New project, set aliases or press enter for default")
addNewAliases(project.ID)
}
return project
}
func initProjectCmd(cmd *cobra.Command, args []string) {

25
cmd/project_go.go Normal file
View File

@ -0,0 +1,25 @@
package cmd
import (
"github.com/spf13/cobra"
"gitlab.sweetwater.com/it/devops/tools/gitlab-project-manager/internal/gitlab"
)
var projectGoCmd = &cobra.Command{
Use: "go [fuzzy alias search]",
Short: "Go to a GitLab project",
Aliases: []string{"goto", "projects", "p"},
Args: cobra.MaximumNArgs(1),
ArgAliases: []string{"project"},
ValidArgsFunction: validAliasesFunc,
Long: projGoCmdLong,
Run: projectCmdRun,
}
func projectGoCmdRun(cmd *cobra.Command, args []string) {
goToProject(getProject(args))
}
func goToProject(project *gitlab.Project) {
cache.GoTo(project)
}

View File

@ -3,7 +3,6 @@ package cmd
import (
"fmt"
"github.com/pterm/pterm"
"github.com/spf13/cobra"
)
@ -34,9 +33,7 @@ func projectShowCmdRun(cmd *cobra.Command, args []string) {
}
}
fmt.Println(pterm.LightGreen("\n--------------"))
fmt.Println(cache.ProjectString(project))
fmt.Println(pterm.LightGreen("--------------\n"))
}
func init() {

View File

@ -9,6 +9,8 @@ const (
const aliasCmdLong = `Manages project aliases, with options for
listing, adding, and deleting.`
const aliasListCmdLong = `Lists all aliases by project`
const aliasAddCmdLong = `Adds a project alias to a project
project ID can be provided, or will otherwise use fuzzy find`
@ -27,5 +29,11 @@ const projCmdLong = `Switches to a GitLab project by name or alias
If not found, will enter fzf mode. If not cloned, will clone
the project locally.`
const projGoCmdLong = `Go to a project, searching by alias
If project is not already cloned, its path will be built and it
will be cloned from source control.
If conf.projects.alwaysPull, a git pull will be ran automatically`
const projShowCmdLong = `Shows detail for a particular project
Will always fuzzy find`

View File

@ -61,23 +61,35 @@ func fzfAliasFromAliases(ctx context.Context, aliases []*projects.ProjectAlias)
return alias
}
func fzfProject(ctx context.Context) (*gitlab.Project, error) {
i, err := fzf.Find(cache.Projects, fzfProjectString,
fzf.WithPreviewWindow(fzfPreviewWindow),
// If a bool=true is provided, will only allow selection of projects
// that have at least one alias defined
func fzfProject(ctx context.Context, mustHaveAlias ...bool) (*gitlab.Project, error) {
var searchableProjects []*gitlab.Project
if len(mustHaveAlias) == 1 && mustHaveAlias[0] {
searchableProjects = cache.GetProjectsWithAliases()
} else {
searchableProjects = cache.Projects
}
i, err := fzf.Find(searchableProjects,
func(i int) string {
return searchableProjects[i].String()
},
fzf.WithPreviewWindow(
func(i, width, height int) string {
return cache.ProjectString(searchableProjects[i])
},
),
fzf.WithContext(ctx),
fzf.WithHeader("Fuzzy find yourself a project"),
)
if err != nil || i < 0 {
return nil, err
}
return cache.Projects[i], nil
return searchableProjects[i], nil
}
func fzfPreviewWindow(i, w, h int) string {
p := cache.Projects[i]
return cache.ProjectString(p)
}
func fzfProjectString(i int) string {
return cache.Projects[i].String()
}

View File

@ -28,10 +28,11 @@ func initProjectCache(cmd *cobra.Command, args []string) {
}
cacheOpts := &projects.CacheOpts{
Path: conf.Cache.File,
TTL: conf.Cache.Ttl,
Logger: plog,
Gitlab: gitlabClient,
ProjectsPath: conf.ProjectPath,
Path: conf.Cache.File,
TTL: conf.Cache.Ttl,
Logger: plog,
Gitlab: gitlabClient,
}
if cache, err = projects.NewProjectCache(cacheOpts); err != nil {
plog.Error("Failed to prepare project cache", plog.Args("error", err))