@@ 3,7 3,9 @@ package git
import (
"context"
"errors"
+ "fmt"
"regexp"
+ "strings"
"github.com/shurcooL/graphql"
"golang.org/x/oauth2"
@@ 36,8 38,13 @@ const (
var nameRegex = regexp.MustCompile("[A-Za-z._-][A-Za-z0-9._-]*")
type Repository struct {
- Id int
- // TODO: add items as needed
+ Id int
+ Owner struct {
+ CanonicalName string
+ }
+ Name string
+ Description *string
+ Visibility Visibility
}
func (c *Client) Create(name, description string, visibility Visibility) error {
@@ 64,3 71,119 @@ func (c *Client) Create(name, description string, visibility Visibility) error {
return err
}
+
+var (
+ // Username must contain between 2 and 30 characters.
+ // Username must start with a lowercase letter or underscore.
+ // Username may contain only lowercase letters, numbers, hyphens and underscores
+ userRegex = regexp.MustCompile("^~[a-z_][a-z0-9\\-_]{1,29}$")
+ userRepoRegex = regexp.MustCompile("^~[a-z_][a-z0-9\\-_]{1,29}/[A-Za-z._-][A-Za-z0-9._-]*$")
+ meRepoRegex = regexp.MustCompile("^[A-Za-z._-][A-Za-z0-9._-]*$")
+)
+
+type RepositoryCursor struct {
+ Results []Repository
+}
+
+func (c *Client) Repo(identificator string) error {
+ if identificator == "" {
+ // list logged in user's repos
+ var query struct {
+ Repositories RepositoryCursor
+ }
+
+ err := c.graphql.Query(context.Background(), &query, nil)
+ if err != nil {
+ return err
+ }
+
+ for _, r := range query.Repositories.Results {
+ repoInfo(&r)
+ }
+
+ return nil
+ } else if userRegex.MatchString(identificator) {
+ // list user's repos
+ identificator = identificator[1:]
+
+ var query struct {
+ User struct {
+ Repositories RepositoryCursor
+ } `graphql:"user(username: $username)"`
+ }
+
+ variables := map[string]interface{}{
+ "username": graphql.String(identificator),
+ }
+
+ err := c.graphql.Query(context.Background(), &query, variables)
+ if err != nil {
+ return err
+ }
+
+ for _, r := range query.User.Repositories.Results {
+ repoInfo(&r)
+ }
+
+ return nil
+ } else if userRepoRegex.MatchString(identificator) {
+ // info about user's specific repo
+ // parsing
+ // TODO: come up with better name
+ slice := strings.Split(identificator, "/")
+ username, reponame := slice[0], slice[1]
+
+ var query struct {
+ RepositoryByOwner *Repository `graphql:"repositoryByOwner(owner: $owner, repo: $repo)"`
+ }
+
+ variables := map[string]interface{}{
+ "owner": graphql.String(username),
+ "repo": graphql.String(reponame),
+ }
+
+ err := c.graphql.Query(context.Background(), &query, variables)
+ if err != nil {
+ return err
+ }
+
+ if query.RepositoryByOwner == nil {
+ return errors.New("repository not found")
+ }
+
+ repoInfo(query.RepositoryByOwner)
+
+ return nil
+ } else if meRepoRegex.MatchString(identificator) {
+ // info about logged in user's repo
+ var query struct {
+ RepositoryByName *Repository `graphql:"repositoryByName(name: $name)"`
+ }
+
+ variables := map[string]interface{}{
+ "name": graphql.String(identificator),
+ }
+
+ err := c.graphql.Query(context.Background(), &query, variables)
+ if err != nil {
+ return err
+ }
+
+ repoInfo(query.RepositoryByName)
+
+ return nil
+ } else {
+ return errors.New("invalid identificator")
+ }
+}
+
+func repoInfo(r *Repository) {
+ if r == nil {
+ return
+ }
+ fmt.Println(r.Owner.CanonicalName + "/" + r.Name + " " + string(r.Visibility))
+ if r.Description != nil {
+ fmt.Println(" " + *r.Description)
+ }
+ fmt.Println()
+}
@@ 48,6 48,14 @@ func gitRoot(args []string) {
log.Fatal(err)
}
case "repo":
+ var identificator string
+ if len(args) >= 2 {
+ identificator = args[1]
+ }
+ err := client.Repo(identificator)
+ if err != nil {
+ log.Fatal(err)
+ }
case "config":
case "delete":
case "permit":