gogh

package module
v3.6.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 14, 2025 License: MIT Imports: 20 Imported by: 0

README

Gogh

Gogh is a tool to manage GitHub repositories efficiently, inspired by ghq.

PkgGoDev Go Report Card Coverage Status GitHub release

Description

gogh is forked from ghq.

$ gogh list
github.com/kyoh86/git-branches
github.com/kyoh86/gogh
github.com/kyoh86/vim-wipeout
github.com/kyoh86-tryouts/bare
github.com/nvim-telescope/telescope.nvim
...

gogh provides a way to organize remote repository clones, like go get does. When you clone a remote repository by gogh get, gogh makes a directory under a specific root directory (by default ~/go/src) using the remote repository URL's host and path. And creating new one by gogh new, gogh make both of a local project and a remote repository.

$ gogh get https://github.com/kyoh86/gogh
# Runs `git clone https://github.com/kyoh86/gogh ~/go/src/github.com/kyoh86/gogh`

You can also do:

  • List projects (local repositories) (gogh list).
  • Create a new project (gogh new).
  • Fork a repository (gogh fork).
  • Clone a repository (gogh clone).
  • Delete a project (gogh delete).
  • List remote repositories (gogh repos).

See #Available commands for more information.

Install

For Golang developers

Ensure you have Go installed before running the following commands.

$ go install github.com/kyoh86/gogh/v3/cmd/gogh@latest

If you want zsh-completions, you can create completions file like this:

$ echo "autoload -Uz compinit && compinit" >> ~/.zshrc
$ gogh completion zsh > $fpath[1]/_gogh
Homebrew/Linuxbrew
$ brew tap kyoh86/tap
$ brew update
$ brew install kyoh86/tap/gogh
Makepkg
$ mkdir -p gogh_build && \
  cd gogh_build && \
  curl -L --silent https://github.com/kyoh86/gogh/releases/latest/download/gogh_PKGBUILD.tar.gz | tar -xvz
$ makepkg -i

Setup

gogh manages repositories in multiple servers that is pairs of an owner and a host name. To login in new server or logout, you should use auth login.

Available commands

See usage/gogh.md for detailed command usage.

Show projects
Command Description
gogh list List local projects
gogh repos List remote repositories
gogh cwd Print the project in current working directory
Manipulate projects
Command Description
gogh create Create a new project with a remote repository
gogh delete Delete a repository with a remote repository
gogh fork Fork a repository
gogh clone Clone a repository to local
Others
Command Description
gogh roots Manage roots
gogh auth Manage Authentications
gogh bundle Manage bundle
gogh help Help about any command

Use gogh [command] --help for more information about a command. Or see the manual in usage/gogh.md.

Environment variables

  • GOGH_CONFIG_PATH: The path to the configuration file. Default: ${XDG_CONFIG_HOME}/gogh/config.yaml.
  • GOGH_FLAG_PATH: The path to the configuration file. Default: ${XDG_CONFIG_HOME}/gogh/flag.yaml.
  • GOGH_TOKENS_PATH: The path to the configuration file. Default: ${XDG_CACHE_HOME}/gogh/tokens.yaml.

Configurations

Roots

gogh manages projects under the roots directories.

See also: Directory structures

You can change the roots with roots add <path> or roots remove <path> and see all of them by roots list. gogh uses the first one as the default one, create, fork or clone will put a local project under it. If you want to change the default, use roots set-default <path>.

Default: ~/Projects.

Default Host and Owner

When you specify a repository with ambiguous user or host, it will be interpolated with a default value. You may set them with auth set-default.

If you set them like below:

key value
host example.com
owner kyoh86

ambiguous repository names will be interpolated:

Ambiguous name Interpolated name
gogh example.com/kyoh86/gogh
foobar/gogh example.com/foobar/gogh

NOTE: default host will be "github.com" if you don't set it.

Directory structures

Local projects are placed under gogh.roots with named `host/user/repo.

~/Projects
+-- github.com/
    |-- google/
    |   +-- go-github/
    |-- kyoh86/
    |   +-- gogh/
    +-- alecthomas/
        +-- kingpin/

LICENSE

MIT License

This software is released under the MIT License, see LICENSE. And this software is based on ghq.

Documentation

Overview

Package gogh manages GitHub repositories for the local directory structures.

Index

Constants

View Source
const (
	RepositoryRelationOwner              = RepositoryRelation("owner")
	RepositoryRelationOrganizationMember = RepositoryRelation("organizationMember")
	RepositoryRelationCollaborator       = RepositoryRelation("collaborator")
)
View Source
const DefaultHost = "github.com"
View Source
const DefaultRootDirName = "Projects"
View Source
const (
	RepositoryListMaxLimitPerPage = 100
)

Variables

View Source
var (
	ErrEmptyHost  = ErrInvalidHost("empty host")
	ErrEmptyOwner = ErrInvalidOwner("empty owner")
	ErrEmptyName  = ErrInvalidName("empty name")
)
View Source
var (
	ErrTooManySlashes = errors.New("too many slashes")
)

Functions

func CreateLocalProject

func CreateLocalProject(
	_ context.Context,
	project Project,
	remoteURL string,
	_ *LocalCreateOption,
) error

func DeleteLocalProject

func DeleteLocalProject(_ context.Context, project Project, _ *LocalDeleteOption) error

func FalsePtr

func FalsePtr(b bool) *bool

FalsePtr converts bool (default: false) to *bool (default: nil as true)

func GetDefaultRemoteURLFromLocalProject

func GetDefaultRemoteURLFromLocalProject(_ context.Context, project Project) (string, error)

func GetRemoteURLsFromLocalProject

func GetRemoteURLsFromLocalProject(
	_ context.Context,
	project Project,
	name string,
) ([]string, error)

func NilablePtr

func NilablePtr[T comparable](v T) *T

NilablePtr converts a value of any type to a pointer, returning nil if the value is the zero value.

func Ptr

func Ptr[T any](v T) *T

Ptr converts a value of any type to a pointer to that value.

func SetRemoteURLsOnLocalProject

func SetRemoteURLsOnLocalProject(
	_ context.Context,
	project Project,
	remotes map[string][]string,
) error

func ValidateHost

func ValidateHost(h string) error

func ValidateName

func ValidateName(name string) error

func ValidateOwner

func ValidateOwner(owner string) error

Types

type ErrInvalidHost

type ErrInvalidHost string

func (ErrInvalidHost) Error

func (e ErrInvalidHost) Error() string

type ErrInvalidName

type ErrInvalidName string

func (ErrInvalidName) Error

func (e ErrInvalidName) Error() string

type ErrInvalidOwner

type ErrInvalidOwner string

func (ErrInvalidOwner) Error

func (e ErrInvalidOwner) Error() string

type Host

type Host = string

type LocalCloneOption

type LocalCloneOption struct {
	Alias *Spec
}

type LocalController

type LocalController struct {
	// contains filtered or unexported fields
}

func NewLocalController

func NewLocalController(root string) *LocalController

func (*LocalController) Clone

func (l *LocalController) Clone(
	ctx context.Context,
	spec Spec,
	token string,
	opt *LocalCloneOption,
) (Project, error)

func (*LocalController) Create

func (l *LocalController) Create(
	ctx context.Context,
	spec Spec,
	opt *LocalCreateOption,
) (Project, error)

func (*LocalController) Delete

func (l *LocalController) Delete(ctx context.Context, spec Spec, opt *LocalDeleteOption) error

func (*LocalController) Exist

func (l *LocalController) Exist(
	ctx context.Context,
	spec Spec,
	opt *LocalExistOption,
) (bool, error)

func (*LocalController) GetRemoteURLs

func (l *LocalController) GetRemoteURLs(
	ctx context.Context,
	spec Spec,
	name string,
) ([]string, error)

func (*LocalController) List

func (l *LocalController) List(ctx context.Context, opt *LocalListOption) ([]Project, error)

func (*LocalController) SetRemoteSpecs

func (l *LocalController) SetRemoteSpecs(
	ctx context.Context,
	spec Spec,
	remotes map[string][]Spec,
) error

func (*LocalController) SetRemoteURLs

func (l *LocalController) SetRemoteURLs(
	ctx context.Context,
	spec Spec,
	remotes map[string][]string,
) error

func (*LocalController) Walk

func (l *LocalController) Walk(
	ctx context.Context,
	opt *LocalWalkOption,
	walkFn LocalWalkFunc,
) error

type LocalCreateOption

type LocalCreateOption struct {
}

type LocalDeleteOption

type LocalDeleteOption struct{}

type LocalExistOption

type LocalExistOption struct {
}

type LocalListOption

type LocalListOption struct {
	Query string
}

type LocalWalkFunc

type LocalWalkFunc func(Project) error

type LocalWalkOption

type LocalWalkOption struct {
	Query string
}

type Map

type Map[TKey comparable, TVal any] map[TKey]TVal

func (*Map[TKey, TVal]) Delete

func (m *Map[TKey, TVal]) Delete(key TKey)

func (*Map[TKey, TVal]) Get

func (m *Map[TKey, TVal]) Get(key TKey) TVal

func (*Map[TKey, TVal]) Has

func (m *Map[TKey, TVal]) Has(key TKey) bool

func (*Map[TKey, TVal]) Set

func (m *Map[TKey, TVal]) Set(key TKey, val TVal)

func (*Map[TKey, TVal]) TryGet

func (m *Map[TKey, TVal]) TryGet(key TKey, def TVal) TVal

type OrderDirection

type OrderDirection = githubv4.OrderDirection

type Owner

type Owner = string

type Project

type Project struct {
	// contains filtered or unexported fields
}

Project is the location of a repository in the local. It is a valid location, that never means "exist".

func NewProject

func NewProject(root string, spec Spec) Project

func (Project) CheckEntity

func (p Project) CheckEntity() error

CheckEntity checks the project is exist in the local file-system.

func (Project) FullFilePath

func (p Project) FullFilePath() string

func (Project) FullLevels

func (p Project) FullLevels() []string

func (Project) Host

func (p Project) Host() string

func (Project) Name

func (p Project) Name() string

func (Project) Owner

func (p Project) Owner() string

func (Project) RelFilePath

func (p Project) RelFilePath() string

func (Project) RelLevels

func (p Project) RelLevels() []string

func (Project) RelPath

func (p Project) RelPath() string

func (Project) Root

func (p Project) Root() string

type RemoteController

type RemoteController struct {
	// contains filtered or unexported fields
}

func NewRemoteController

func NewRemoteController(adaptor github.Adaptor) *RemoteController

func (*RemoteController) Create

func (c *RemoteController) Create(
	ctx context.Context,
	name string,
	option *RemoteCreateOption,
) (Repository, error)

func (*RemoteController) CreateFromTemplate

func (c *RemoteController) CreateFromTemplate(
	ctx context.Context,
	templateOwner, templateName, name string,
	option *RemoteCreateFromTemplateOption,
) (Repository, error)

func (*RemoteController) Delete

func (c *RemoteController) Delete(
	ctx context.Context,
	owner string,
	name string,
	_ *RemoteDeleteOption,
) error

func (*RemoteController) Fork

func (c *RemoteController) Fork(
	ctx context.Context,
	owner string,
	name string,
	option *RemoteForkOption,
) (Repository, error)

func (*RemoteController) Get

func (c *RemoteController) Get(
	ctx context.Context,
	owner string,
	name string,
	_ *RemoteGetOption,
) (Repository, error)

func (*RemoteController) List

func (c *RemoteController) List(
	ctx context.Context,
	option *RemoteListOption,
) (allSpecs []Repository, _ error)

func (*RemoteController) ListAsync

func (c *RemoteController) ListAsync(
	ctx context.Context,
	option *RemoteListOption,
) (<-chan Repository, <-chan error)

func (*RemoteController) Me

func (c *RemoteController) Me(
	ctx context.Context,
) (string, error)

type RemoteCreateFromTemplateOption

type RemoteCreateFromTemplateOption struct {
	Owner       string `json:"owner,omitempty"`
	Description string `json:"description,omitempty"`
	Private     bool   `json:"private,omitempty"`
}

type RemoteCreateOption

type RemoteCreateOption struct {
	Description         string
	Homepage            string
	Organization        string
	LicenseTemplate     string
	GitignoreTemplate   string
	TeamID              int64
	DisableDownloads    bool
	IsTemplate          bool
	Private             bool
	DisableWiki         bool
	AutoInit            bool
	DisableProjects     bool
	DisableIssues       bool
	PreventSquashMerge  bool
	PreventMergeCommit  bool
	PreventRebaseMerge  bool
	DeleteBranchOnMerge bool
}

func (*RemoteCreateOption) GetOrganization

func (o *RemoteCreateOption) GetOrganization() string

type RemoteDeleteOption

type RemoteDeleteOption struct{}

type RemoteForkOption

type RemoteForkOption struct {
	// Organization is the name of the organization that owns the repository.
	Organization string
}

func (*RemoteForkOption) GetOptions

type RemoteGetOption

type RemoteGetOption struct{}

type RemoteListOption

type RemoteListOption struct {
	Private    *bool
	IsFork     *bool
	IsArchived *bool
	Order      OrderDirection
	Sort       RepositoryOrderField
	Relation   []RepositoryRelation
	Limit      int
}

func (*RemoteListOption) GetOptions

type Repository

type Repository struct {
	UpdatedAt   time.Time `json:"updatedAt"`
	Parent      *Spec     `json:"parent,omitempty"`
	Spec        Spec      `json:"spec"`
	URL         string    `json:"url"`
	Description string    `json:"description,omitempty"`
	Homepage    string    `json:"homepage,omitempty"`
	Language    string    `json:"language,omitempty"`
	Archived    bool      `json:"archived,omitempty"`
	Private     bool      `json:"private,omitempty"`
	IsTemplate  bool      `json:"isTemplate,omitempty"`
	Fork        bool      `json:"fork,omitempty"`
}

func (Repository) Host

func (r Repository) Host() string

func (Repository) Name

func (r Repository) Name() string

func (Repository) Owner

func (r Repository) Owner() string

type RepositoryOrderField

type RepositoryOrderField = githubv4.RepositoryOrderField

type RepositoryRelation

type RepositoryRelation string

func (RepositoryRelation) String

func (r RepositoryRelation) String() string

type Spec

type Spec struct {
	// contains filtered or unexported fields
}

Spec describes which project is in a root.

func NewSpec

func NewSpec(host, owner, name string) (Spec, error)

func ParseSiblingSpec

func ParseSiblingSpec(base Spec, s string) (Spec, error)

ParseSiblingSpec parses string as a repository specification in the same host and same owner.

func (Spec) Host

func (s Spec) Host() string

func (Spec) MarshalJSON

func (s Spec) MarshalJSON() ([]byte, error)

func (Spec) Name

func (s Spec) Name() string

func (Spec) Owner

func (s Spec) Owner() string

func (Spec) RelLevels

func (s Spec) RelLevels() []string

func (Spec) String

func (s Spec) String() string

func (Spec) URL

func (s Spec) URL() string

func (*Spec) UnmarshalJSON

func (s *Spec) UnmarshalJSON(b []byte) error

type SpecParser

type SpecParser struct {
	// contains filtered or unexported fields
}

SpecParser will parse any string as a Spec.

If it is clear that the string has host, user and name explicitly, use "NewSpec" instead to build Spec.

func NewSpecParser

func NewSpecParser(defaultHost, defaultOwner string) SpecParser

NewSpecParser will build Spec with a default host and default owner.

func (SpecParser) Parse

func (p SpecParser) Parse(s string) (Spec, error)

Parse a string and build a Spec.

If the string does not have a host or a user explicitly, they will be replaced with a default host and default owner.

func (SpecParser) ParseWithAlias

func (p SpecParser) ParseWithAlias(s string) (Spec, *Spec, error)

ParseWithAlias parses string as a Spec and following alias. We can specify an alias with following '='(equal) and the alias.

If it's not specified, alias will be nil value. If it's specified a value which equals to the spec, alias will be nil value.

type TokenEntry

type TokenEntry struct {
	Host  Host
	Owner Owner
	Token github.Token
}

func (TokenEntry) String

func (e TokenEntry) String() string

type TokenHost

type TokenHost struct {
	Owners       Map[Owner, github.Token] `yaml:"owners"`
	DefaultOwner Owner                    `yaml:"default_owner"`
}

func (*TokenHost) GetDefaultToken

func (t *TokenHost) GetDefaultToken() (Owner, github.Token)

type TokenManager

type TokenManager struct {
	Hosts       Map[Host, *TokenHost] `yaml:"hosts,omitempty"`
	DefaultHost Host                  `yaml:"default_host,omitempty"`
}

func (*TokenManager) Delete

func (t *TokenManager) Delete(host, owner string)

func (TokenManager) Entries

func (t TokenManager) Entries() []TokenEntry

func (TokenManager) Get

func (t TokenManager) Get(host, owner string) github.Token

func (TokenManager) GetDefaultKey

func (t TokenManager) GetDefaultKey() (Host, Owner)

func (TokenManager) Has

func (t TokenManager) Has(host, owner string) bool

func (*TokenManager) Set

func (t *TokenManager) Set(hostName, ownerName string, token github.Token)

func (*TokenManager) SetDefaultHost

func (t *TokenManager) SetDefaultHost(hostName string) error

func (*TokenManager) SetDefaultOwner

func (t *TokenManager) SetDefaultOwner(hostName, ownerName string) error

Directories

Path Synopsis
cmd
internal
github
Package github provides GitHub API v3 adaptor
Package github provides GitHub API v3 adaptor
github_mock
Package github_mock is a generated GoMock package.
Package github_mock is a generated GoMock package.
githubv4
Package githubv4 provides GitHub API v4 adaptor
Package githubv4 provides GitHub API v4 adaptor
Package view is the view layer of the gogh command.
Package view is the view layer of the gogh command.
repotab
Package repotab provides a formatter which show repositories as a table in CLI
Package repotab provides a formatter which show repositories as a table in CLI

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL