Skip to content

Commit 92eca68

Browse files
authored
Merge pull request #424 from rsteube/added-glab
added glab
2 parents eb1c3d9 + 3d85b6d commit 92eca68

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+2586
-0
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package action
2+
3+
import (
4+
"io/ioutil"
5+
"os"
6+
7+
"github.com/rsteube/carapace"
8+
"gopkg.in/yaml.v3"
9+
)
10+
11+
func loadAliases() (aliases map[string]string, err error) {
12+
var dir string
13+
if dir, err = os.UserConfigDir(); err == nil {
14+
var content []byte
15+
if content, err = ioutil.ReadFile(dir + "/glab-cli/aliases.yml"); err == nil {
16+
err = yaml.Unmarshal(content, &aliases)
17+
}
18+
}
19+
return
20+
}
21+
22+
func ActionAliases() carapace.Action {
23+
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
24+
aliases, err := loadAliases()
25+
if err != nil {
26+
return carapace.ActionMessage(err.Error())
27+
}
28+
29+
vals := make([]string, 0)
30+
for alias, desc := range aliases {
31+
vals = append(vals, alias, desc)
32+
}
33+
return carapace.ActionValuesDescribed(vals...)
34+
})
35+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package action
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"net/url"
7+
"strings"
8+
9+
"github.com/rsteube/carapace"
10+
"github.com/spf13/cobra"
11+
)
12+
13+
func actionApi(cmd *cobra.Command, query string, v interface{}, transform func() carapace.Action) carapace.Action {
14+
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
15+
if flag := cmd.Flag("repo"); flag != nil && flag.Changed {
16+
project := strings.Join(strings.Split(flag.Value.String(), "/")[1:], "/")
17+
query = strings.Replace(query, ":fullpath", url.PathEscape(project), 1)
18+
}
19+
20+
args := []string{"api"}
21+
if flag := cmd.Flag("repo"); flag != nil && flag.Changed {
22+
host := strings.Split(flag.Value.String(), "/")[0]
23+
args = append(args, "--hostname", host)
24+
}
25+
args = append(args, query)
26+
return carapace.ActionExecCommand("glab", args...)(func(output []byte) carapace.Action {
27+
if err := json.Unmarshal(output, &v); err != nil {
28+
return carapace.ActionMessage("failed to unmarshall response: " + err.Error())
29+
}
30+
return transform()
31+
})
32+
})
33+
}
34+
35+
func actionGraphql(cmd *cobra.Command, query string, v interface{}, transform func() carapace.Action) carapace.Action {
36+
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
37+
args := []string{"api", "graphql"}
38+
if flag := cmd.Flag("repo"); flag != nil && flag.Changed {
39+
host := strings.Split(flag.Value.String(), "/")[0]
40+
args = append(args, "--hostname", host)
41+
}
42+
args = append(args, "-f", fmt.Sprintf("query=%v", query))
43+
return carapace.ActionExecCommand("glab", args...)(func(output []byte) carapace.Action {
44+
if err := json.Unmarshal(output, &v); err != nil {
45+
return carapace.ActionMessage("failed to unmarshall response: " + err.Error())
46+
}
47+
return transform()
48+
})
49+
})
50+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package action
2+
3+
import (
4+
"fmt"
5+
"net/url"
6+
7+
"github.com/rsteube/carapace"
8+
"github.com/spf13/cobra"
9+
)
10+
11+
type branch struct {
12+
Name string
13+
Commit struct {
14+
Title string
15+
}
16+
}
17+
18+
func ActionBranches(cmd *cobra.Command) carapace.Action {
19+
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
20+
var branches []branch
21+
query := fmt.Sprintf("/projects/:fullpath/repository/branches?search=^%v", url.QueryEscape(c.CallbackValue))
22+
return actionApi(cmd, query, &branches, func() carapace.Action {
23+
vals := make([]string, 0, len(branches)*2)
24+
for _, branch := range branches {
25+
vals = append(vals, branch.Name, branch.Commit.Title)
26+
}
27+
return carapace.ActionValuesDescribed(vals...)
28+
})
29+
})
30+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package action
2+
3+
import (
4+
"io/ioutil"
5+
"os"
6+
7+
"github.com/rsteube/carapace"
8+
"gopkg.in/yaml.v3"
9+
)
10+
11+
func ActionConfigHosts() carapace.Action {
12+
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
13+
if hosts, err := hosts(); err != nil {
14+
return carapace.ActionMessage(err.Error())
15+
} else {
16+
return carapace.ActionValues(hosts...)
17+
}
18+
})
19+
}
20+
21+
type glabConfig struct {
22+
Hosts map[string]interface{}
23+
}
24+
25+
func hosts() ([]string, error) {
26+
config, err := loadConfig()
27+
if err != nil {
28+
return nil, err
29+
}
30+
31+
hosts := make([]string, 0)
32+
for host := range config.Hosts {
33+
hosts = append(hosts, host)
34+
}
35+
return hosts, nil
36+
}
37+
38+
func loadConfig() (config *glabConfig, err error) {
39+
var dir string
40+
if dir, err = os.UserConfigDir(); err == nil {
41+
var content []byte
42+
if content, err = ioutil.ReadFile(dir + "/glab-cli/config.yml"); err == nil {
43+
err = yaml.Unmarshal(content, &config)
44+
}
45+
}
46+
return
47+
}
48+
49+
func ActionConfigKeys() carapace.Action {
50+
return carapace.ActionValuesDescribed(
51+
"token", "Your gitlab access token, defaults to environment variables",
52+
"gitlab_uri", "if unset, defaults to https://gitlab.com",
53+
"browser", "if unset, defaults to environment variables",
54+
"editor", "if unset, defaults to environment variables.",
55+
"visual", "alternative for editor. if unset, defaults to environment variables.",
56+
"glamour_style", "Your desired markdown renderer style.",
57+
)
58+
}
59+
60+
func ActionConfigValues(key string) carapace.Action {
61+
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
62+
actions := map[string]carapace.Action{
63+
"token": carapace.ActionValues(),
64+
"gitlab_uri": carapace.ActionValues(),
65+
"browser": carapace.ActionFiles(),
66+
"editor": carapace.ActionFiles(),
67+
"visual": carapace.ActionFiles(),
68+
"glamour_style": carapace.ActionValues("dark", "light", "notty"),
69+
}
70+
71+
return actions[key]
72+
})
73+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package action
2+
3+
import (
4+
"github.com/rsteube/carapace"
5+
"github.com/spf13/cobra"
6+
)
7+
8+
type environment struct {
9+
Name string
10+
ExternalUrl string `json:"external_url"`
11+
}
12+
13+
func ActionEnvironments(cmd *cobra.Command) carapace.Action {
14+
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
15+
var queryResult []environment
16+
return actionApi(cmd, "projects/:fullpath/environments", &queryResult, func() carapace.Action {
17+
vals := make([]string, 0, len(queryResult)*2)
18+
for _, env := range queryResult {
19+
vals = append(vals, env.Name, env.ExternalUrl)
20+
}
21+
return carapace.ActionValuesDescribed(vals...)
22+
})
23+
})
24+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package action
2+
3+
import (
4+
"fmt"
5+
"net/url"
6+
7+
"github.com/rsteube/carapace"
8+
"github.com/spf13/cobra"
9+
)
10+
11+
type group struct {
12+
Path string
13+
Description string
14+
}
15+
16+
func ActionGroups(cmd *cobra.Command) carapace.Action {
17+
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
18+
query := fmt.Sprintf(`groups?all_available=true&search=%v`, url.QueryEscape(c.CallbackValue))
19+
20+
var queryResult []group
21+
return actionApi(cmd, query, queryResult, func() carapace.Action {
22+
vals := make([]string, 0, len(queryResult)*2)
23+
for _, group := range queryResult {
24+
vals = append(vals, group.Path, group.Description)
25+
}
26+
return carapace.ActionValuesDescribed(vals...)
27+
})
28+
})
29+
}
30+
31+
func ActionSubgroups(cmd *cobra.Command, groupID string) carapace.Action {
32+
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
33+
query := fmt.Sprintf(`groups/%v/subgroups?all_available=true&search=%v`, url.PathEscape(groupID), url.QueryEscape(c.CallbackValue))
34+
35+
var queryResult []group
36+
return actionApi(cmd, query, &queryResult, func() carapace.Action {
37+
// TODO allow failure
38+
// if strings.Contains(err.Error(), "404 Group Not Found") {
39+
// return carapace.ActionValues() // fail silently for repo completion
40+
// }
41+
vals := make([]string, 0, len(queryResult)*2)
42+
for _, group := range queryResult {
43+
vals = append(vals, group.Path, group.Description)
44+
}
45+
return carapace.ActionValuesDescribed(vals...)
46+
})
47+
})
48+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package action
2+
3+
import (
4+
"fmt"
5+
"net/url"
6+
"strconv"
7+
8+
"github.com/rsteube/carapace"
9+
"github.com/spf13/cobra"
10+
)
11+
12+
type issue struct {
13+
Iid int
14+
Title string
15+
}
16+
17+
func ActionIssues(cmd *cobra.Command, state string) carapace.Action {
18+
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
19+
stateQuery := ""
20+
if state != "" {
21+
stateQuery = "&state=" + url.QueryEscape(state)
22+
}
23+
24+
var queryResult []issue
25+
return actionApi(cmd, fmt.Sprintf("projects/:fullpath/issues?order_by=updated_at&per_page=100%v", stateQuery), &queryResult, func() carapace.Action {
26+
vals := make([]string, 0, len(queryResult)*2)
27+
for _, issue := range queryResult {
28+
vals = append(vals, strconv.Itoa(issue.Iid), issue.Title)
29+
}
30+
return carapace.ActionValuesDescribed(vals...)
31+
})
32+
})
33+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package action
2+
3+
import (
4+
"github.com/rsteube/carapace"
5+
"github.com/spf13/cobra"
6+
)
7+
8+
type label struct {
9+
Name string
10+
Description string
11+
}
12+
13+
func ActionLabels(cmd *cobra.Command) carapace.Action {
14+
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
15+
//repo := "" // TODO from config or var
16+
17+
var queryResult []label
18+
return actionApi(cmd, "projects/:fullpath/labels", &queryResult, func() carapace.Action {
19+
vals := make([]string, 0, len(queryResult)*2)
20+
for _, label := range queryResult {
21+
vals = append(vals, label.Name, label.Description)
22+
}
23+
return carapace.ActionValuesDescribed(vals...)
24+
//}).Cache(1*time.Hour, cache.String(repo.FullName()))
25+
})
26+
})
27+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package action
2+
3+
import (
4+
"fmt"
5+
"net/url"
6+
"strconv"
7+
8+
"github.com/rsteube/carapace"
9+
"github.com/spf13/cobra"
10+
)
11+
12+
type mergeRequest struct {
13+
Iid int
14+
Title string
15+
}
16+
17+
func ActionMergeRequests(cmd *cobra.Command, state string) carapace.Action {
18+
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
19+
stateQuery := ""
20+
if state != "" {
21+
stateQuery = "&state=" + url.QueryEscape(state)
22+
}
23+
24+
var queryResult []mergeRequest
25+
return actionApi(cmd, fmt.Sprintf("projects/:fullpath/merge_requests?order_by=updated_at&per_page=100%v", stateQuery), queryResult, func() carapace.Action {
26+
vals := make([]string, 0, len(queryResult)*2)
27+
for _, mr := range queryResult {
28+
vals = append(vals, strconv.Itoa(mr.Iid), mr.Title)
29+
}
30+
return carapace.ActionValuesDescribed(vals...)
31+
})
32+
})
33+
}
34+
35+
func ActionMergeRequestsAndBranches(cmd *cobra.Command, state string) carapace.Action {
36+
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
37+
branches := ActionBranches(cmd).Invoke(c)
38+
mergeRequests := ActionMergeRequests(cmd, state).Invoke(c)
39+
return branches.Merge(mergeRequests).Filter(c.Args).ToA()
40+
})
41+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package action
2+
3+
import (
4+
"github.com/rsteube/carapace"
5+
"github.com/spf13/cobra"
6+
)
7+
8+
type milestone struct {
9+
Title string
10+
Description string
11+
}
12+
13+
func ActionMilestones(cmd *cobra.Command) carapace.Action {
14+
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
15+
var queryResult []milestone
16+
return actionApi(cmd, "projects/:fullpath/milestones", &queryResult, func() carapace.Action {
17+
vals := make([]string, 0, len(queryResult)*2)
18+
for _, milestone := range queryResult {
19+
vals = append(vals, milestone.Title, milestone.Description)
20+
}
21+
return carapace.ActionValuesDescribed(vals...)
22+
})
23+
})
24+
}

0 commit comments

Comments
 (0)