~w1ke/hut

9a465da3d9e46bc79ea3e86c733bd5c63e983fda — w1ke 11 months ago a61028a
added hut git repo command
2 files changed, 133 insertions(+), 2 deletions(-)

M api/git/git.go
M cmd/hut/git.go
M api/git/git.go => api/git/git.go +125 -2
@@ 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()
}

M cmd/hut/git.go => cmd/hut/git.go +8 -0
@@ 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":