mirror of
https://github.com/MichaelMure/git-bug.git
synced 2025-01-05 17:33:12 +03:00
bug: refactor to limit abstraction leak and to have a more reusable code for the UIs
This commit is contained in:
parent
e1f597639b
commit
17e2ec8f56
98
bug/bug.go
98
bug/bug.go
@ -8,16 +8,16 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const BugsRefPattern = "refs/bugs/"
|
const bugsRefPattern = "refs/bugs/"
|
||||||
const BugsRemoteRefPattern = "refs/remote/%s/bugs/"
|
const bugsRemoteRefPattern = "refs/remote/%s/bugs/"
|
||||||
const OpsEntryName = "ops"
|
const opsEntryName = "ops"
|
||||||
const RootEntryName = "root"
|
const rootEntryName = "root"
|
||||||
|
|
||||||
const IdLength = 40
|
const idLength = 40
|
||||||
const HumanIdLength = 7
|
const humanIdLength = 7
|
||||||
|
|
||||||
// Bug hold the data of a bug thread, organized in a way close to
|
// Bug hold the data of a bug thread, organized in a way close to
|
||||||
// how it will be persisted inside Git. This is the datastructure
|
// how it will be persisted inside Git. This is the data structure
|
||||||
// used for merge of two different version.
|
// used for merge of two different version.
|
||||||
type Bug struct {
|
type Bug struct {
|
||||||
// Id used as unique identifier
|
// Id used as unique identifier
|
||||||
@ -40,8 +40,8 @@ func NewBug() *Bug {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find an existing Bug matching a prefix
|
// Find an existing Bug matching a prefix
|
||||||
func FindBug(repo repository.Repo, prefix string) (*Bug, error) {
|
func FindLocalBug(repo repository.Repo, prefix string) (*Bug, error) {
|
||||||
ids, err := repo.ListRefs(BugsRefPattern)
|
ids, err := repo.ListRefs(bugsRefPattern)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -64,11 +64,21 @@ func FindBug(repo repository.Repo, prefix string) (*Bug, error) {
|
|||||||
return nil, fmt.Errorf("Multiple matching bug found:\n%s", strings.Join(matching, "\n"))
|
return nil, fmt.Errorf("Multiple matching bug found:\n%s", strings.Join(matching, "\n"))
|
||||||
}
|
}
|
||||||
|
|
||||||
return ReadBug(repo, BugsRefPattern+matching[0])
|
return ReadLocalBug(repo, matching[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadLocalBug(repo repository.Repo, id string) (*Bug, error) {
|
||||||
|
ref := bugsRefPattern + id
|
||||||
|
return readBug(repo, ref)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadRemoteBug(repo repository.Repo, remote string, id string) (*Bug, error) {
|
||||||
|
ref := fmt.Sprintf(bugsRemoteRefPattern, remote) + id
|
||||||
|
return readBug(repo, ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read and parse a Bug from git
|
// Read and parse a Bug from git
|
||||||
func ReadBug(repo repository.Repo, ref string) (*Bug, error) {
|
func readBug(repo repository.Repo, ref string) (*Bug, error) {
|
||||||
hashes, err := repo.ListCommits(ref)
|
hashes, err := repo.ListCommits(ref)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -78,7 +88,7 @@ func ReadBug(repo repository.Repo, ref string) (*Bug, error) {
|
|||||||
refSplitted := strings.Split(ref, "/")
|
refSplitted := strings.Split(ref, "/")
|
||||||
id := refSplitted[len(refSplitted)-1]
|
id := refSplitted[len(refSplitted)-1]
|
||||||
|
|
||||||
if len(id) != IdLength {
|
if len(id) != idLength {
|
||||||
return nil, fmt.Errorf("Invalid ref length")
|
return nil, fmt.Errorf("Invalid ref length")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,12 +112,12 @@ func ReadBug(repo repository.Repo, ref string) (*Bug, error) {
|
|||||||
rootFound := false
|
rootFound := false
|
||||||
|
|
||||||
for _, entry := range entries {
|
for _, entry := range entries {
|
||||||
if entry.Name == OpsEntryName {
|
if entry.Name == opsEntryName {
|
||||||
opsEntry = entry
|
opsEntry = entry
|
||||||
opsFound = true
|
opsFound = true
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if entry.Name == RootEntryName {
|
if entry.Name == rootEntryName {
|
||||||
rootEntry = entry
|
rootEntry = entry
|
||||||
rootFound = true
|
rootFound = true
|
||||||
}
|
}
|
||||||
@ -150,6 +160,50 @@ func ReadBug(repo repository.Repo, ref string) (*Bug, error) {
|
|||||||
return &bug, nil
|
return &bug, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type StreamedBug struct {
|
||||||
|
Bug *Bug
|
||||||
|
Err error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read and parse all local bugs
|
||||||
|
func ReadAllLocalBugs(repo repository.Repo) <-chan StreamedBug {
|
||||||
|
return readAllBugs(repo, bugsRefPattern)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read and parse all remote bugs for a given remote
|
||||||
|
func ReadAllRemoteBugs(repo repository.Repo, remote string) <-chan StreamedBug {
|
||||||
|
refPrefix := fmt.Sprintf(bugsRemoteRefPattern, remote)
|
||||||
|
return readAllBugs(repo, refPrefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read and parse all available bug with a given ref prefix
|
||||||
|
func readAllBugs(repo repository.Repo, refPrefix string) <-chan StreamedBug {
|
||||||
|
out := make(chan StreamedBug)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
defer close(out)
|
||||||
|
|
||||||
|
refs, err := repo.ListRefs(refPrefix)
|
||||||
|
if err != nil {
|
||||||
|
out <- StreamedBug{Err: err}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, ref := range refs {
|
||||||
|
b, err := readBug(repo, ref)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
out <- StreamedBug{Err: err}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
out <- StreamedBug{Bug: b}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// IsValid check if the Bug data is valid
|
// IsValid check if the Bug data is valid
|
||||||
func (bug *Bug) IsValid() bool {
|
func (bug *Bug) IsValid() bool {
|
||||||
// non-empty
|
// non-empty
|
||||||
@ -216,9 +270,9 @@ func (bug *Bug) Commit(repo repository.Repo) error {
|
|||||||
// Write a Git tree referencing this blob
|
// Write a Git tree referencing this blob
|
||||||
hash, err = repo.StoreTree([]repository.TreeEntry{
|
hash, err = repo.StoreTree([]repository.TreeEntry{
|
||||||
// the last pack of ops
|
// the last pack of ops
|
||||||
{ObjectType: repository.Blob, Hash: hash, Name: OpsEntryName},
|
{ObjectType: repository.Blob, Hash: hash, Name: opsEntryName},
|
||||||
// always the first pack of ops (might be the same)
|
// always the first pack of ops (might be the same)
|
||||||
{ObjectType: repository.Blob, Hash: bug.rootPack, Name: RootEntryName},
|
{ObjectType: repository.Blob, Hash: bug.rootPack, Name: rootEntryName},
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -244,7 +298,7 @@ func (bug *Bug) Commit(repo repository.Repo) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create or update the Git reference for this bug
|
// Create or update the Git reference for this bug
|
||||||
ref := fmt.Sprintf("%s%s", BugsRefPattern, bug.id)
|
ref := fmt.Sprintf("%s%s", bugsRefPattern, bug.id)
|
||||||
err = repo.UpdateRef(ref, hash)
|
err = repo.UpdateRef(ref, hash)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -326,7 +380,7 @@ func (bug *Bug) Merge(repo repository.Repo, other *Bug) (bool, error) {
|
|||||||
|
|
||||||
// Update the git ref
|
// Update the git ref
|
||||||
if updated {
|
if updated {
|
||||||
err := repo.UpdateRef(BugsRefPattern+bug.id, bug.lastCommit)
|
err := repo.UpdateRef(bugsRefPattern+bug.id, bug.lastCommit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@ -347,8 +401,12 @@ func (bug *Bug) Id() string {
|
|||||||
|
|
||||||
// Return the Bug identifier truncated for human consumption
|
// Return the Bug identifier truncated for human consumption
|
||||||
func (bug *Bug) HumanId() string {
|
func (bug *Bug) HumanId() string {
|
||||||
format := fmt.Sprintf("%%.%ds", HumanIdLength)
|
return formatHumanId(bug.Id())
|
||||||
return fmt.Sprintf(format, bug.Id())
|
}
|
||||||
|
|
||||||
|
func formatHumanId(id string) string {
|
||||||
|
format := fmt.Sprintf("%%.%ds", humanIdLength)
|
||||||
|
return fmt.Sprintf(format, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lookup for the very first operation of the bug.
|
// Lookup for the very first operation of the bug.
|
||||||
|
119
bug/remote_actions.go
Normal file
119
bug/remote_actions.go
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
package bug
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/MichaelMure/git-bug/repository"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const MsgNew = "new"
|
||||||
|
const MsgInvalid = "invalid data"
|
||||||
|
const MsgUpdated = "updated"
|
||||||
|
const MsgNothing = "nothing to do"
|
||||||
|
|
||||||
|
func Fetch(repo repository.Repo, remote string) error {
|
||||||
|
remoteRefSpec := fmt.Sprintf(bugsRemoteRefPattern, remote)
|
||||||
|
fetchRefSpec := fmt.Sprintf("%s*:%s*", bugsRefPattern, remoteRefSpec)
|
||||||
|
|
||||||
|
return repo.FetchRefs(remote, fetchRefSpec)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Push(repo repository.Repo, remote string) error {
|
||||||
|
return repo.PushRefs(remote, bugsRefPattern+"*")
|
||||||
|
}
|
||||||
|
|
||||||
|
type MergeResult struct {
|
||||||
|
Err error
|
||||||
|
|
||||||
|
Id string
|
||||||
|
HumanId string
|
||||||
|
Status string
|
||||||
|
}
|
||||||
|
|
||||||
|
func newMergeError(id string, err error) MergeResult {
|
||||||
|
return MergeResult{
|
||||||
|
Id: id,
|
||||||
|
HumanId: formatHumanId(id),
|
||||||
|
Status: err.Error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newMergeStatus(id string, status string) MergeResult {
|
||||||
|
return MergeResult{
|
||||||
|
Id: id,
|
||||||
|
HumanId: formatHumanId(id),
|
||||||
|
Status: status,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func MergeAll(repo repository.Repo, remote string) <-chan MergeResult {
|
||||||
|
out := make(chan MergeResult)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
defer close(out)
|
||||||
|
|
||||||
|
remoteRefSpec := fmt.Sprintf(bugsRemoteRefPattern, remote)
|
||||||
|
remoteRefs, err := repo.ListRefs(remoteRefSpec)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
out <- MergeResult{Err: err}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, remoteRef := range remoteRefs {
|
||||||
|
refSplitted := strings.Split(remoteRef, "/")
|
||||||
|
id := refSplitted[len(refSplitted)-1]
|
||||||
|
|
||||||
|
remoteBug, err := readBug(repo, remoteRef)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
out <- newMergeError(id, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for error in remote data
|
||||||
|
if !remoteBug.IsValid() {
|
||||||
|
out <- newMergeStatus(id, MsgInvalid)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
localRef := bugsRefPattern + remoteBug.Id()
|
||||||
|
localExist, err := repo.RefExist(localRef)
|
||||||
|
|
||||||
|
// the bug is not local yet, simply create the reference
|
||||||
|
if !localExist {
|
||||||
|
err := repo.CopyRef(remoteRef, localRef)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
out <- newMergeError(id, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
out <- newMergeStatus(id, MsgNew)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
localBug, err := readBug(repo, localRef)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
out <- newMergeError(id, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
updated, err := localBug.Merge(repo, remoteBug)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
out <- newMergeError(id, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if updated {
|
||||||
|
out <- newMergeStatus(id, MsgUpdated)
|
||||||
|
} else {
|
||||||
|
out <- newMergeStatus(id, MsgNothing)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
@ -18,7 +18,7 @@ func runCloseBug(cmd *cobra.Command, args []string) error {
|
|||||||
|
|
||||||
prefix := args[0]
|
prefix := args[0]
|
||||||
|
|
||||||
b, err := bug.FindBug(repo, prefix)
|
b, err := bug.FindLocalBug(repo, prefix)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ func runComment(cmd *cobra.Command, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
b, err := bug.FindBug(repo, prefix)
|
b, err := bug.FindLocalBug(repo, prefix)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ func runLabel(cmd *cobra.Command, args []string) error {
|
|||||||
|
|
||||||
prefix := args[0]
|
prefix := args[0]
|
||||||
|
|
||||||
b, err := bug.FindBug(repo, prefix)
|
b, err := bug.FindLocalBug(repo, prefix)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -2,28 +2,22 @@ package commands
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
b "github.com/MichaelMure/git-bug/bug"
|
"github.com/MichaelMure/git-bug/bug"
|
||||||
"github.com/MichaelMure/git-bug/util"
|
"github.com/MichaelMure/git-bug/util"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
func runLsBug(cmd *cobra.Command, args []string) error {
|
func runLsBug(cmd *cobra.Command, args []string) error {
|
||||||
ids, err := repo.ListRefs(b.BugsRefPattern)
|
bugs := bug.ReadAllLocalBugs(repo)
|
||||||
|
|
||||||
if err != nil {
|
for b := range bugs {
|
||||||
return err
|
if b.Err != nil {
|
||||||
}
|
return b.Err
|
||||||
|
|
||||||
for _, ref := range ids {
|
|
||||||
bug, err := b.ReadBug(repo, b.BugsRefPattern+ref)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
snapshot := bug.Compile()
|
snapshot := b.Bug.Compile()
|
||||||
|
|
||||||
var author b.Person
|
var author bug.Person
|
||||||
|
|
||||||
if len(snapshot.Comments) > 0 {
|
if len(snapshot.Comments) > 0 {
|
||||||
create := snapshot.Comments[0]
|
create := snapshot.Comments[0]
|
||||||
@ -35,7 +29,7 @@ func runLsBug(cmd *cobra.Command, args []string) error {
|
|||||||
authorFmt := fmt.Sprintf("%-15.15s", author.Name)
|
authorFmt := fmt.Sprintf("%-15.15s", author.Name)
|
||||||
|
|
||||||
fmt.Printf("%s %s\t%s\t%s\t%s\n",
|
fmt.Printf("%s %s\t%s\t%s\t%s\n",
|
||||||
util.Cyan(bug.HumanId()),
|
util.Cyan(b.Bug.HumanId()),
|
||||||
util.Yellow(snapshot.Status),
|
util.Yellow(snapshot.Status),
|
||||||
titleFmt,
|
titleFmt,
|
||||||
util.Magenta(authorFmt),
|
util.Magenta(authorFmt),
|
||||||
|
@ -18,7 +18,7 @@ func runOpenBug(cmd *cobra.Command, args []string) error {
|
|||||||
|
|
||||||
prefix := args[0]
|
prefix := args[0]
|
||||||
|
|
||||||
b, err := bug.FindBug(repo, prefix)
|
b, err := bug.FindLocalBug(repo, prefix)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -19,62 +19,19 @@ func runPull(cmd *cobra.Command, args []string) error {
|
|||||||
|
|
||||||
fmt.Printf("Fetching remote ...\n\n")
|
fmt.Printf("Fetching remote ...\n\n")
|
||||||
|
|
||||||
if err := repo.FetchRefs(remote, bug.BugsRefPattern+"*", bug.BugsRemoteRefPattern+"*"); err != nil {
|
if err := bug.Fetch(repo, remote); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("\nMerging data ...\n\n")
|
fmt.Printf("\nMerging data ...\n\n")
|
||||||
|
|
||||||
remoteRefSpec := fmt.Sprintf(bug.BugsRemoteRefPattern, remote)
|
for merge := range bug.MergeAll(repo, remote) {
|
||||||
remoteRefs, err := repo.ListRefs(remoteRefSpec)
|
if merge.Err != nil {
|
||||||
|
return merge.Err
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, ref := range remoteRefs {
|
|
||||||
remoteRef := fmt.Sprintf(bug.BugsRemoteRefPattern, remote) + ref
|
|
||||||
remoteBug, err := bug.ReadBug(repo, remoteRef)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for error in remote data
|
if merge.Status != bug.MsgNothing {
|
||||||
if !remoteBug.IsValid() {
|
fmt.Printf("%s: %s\n", merge.HumanId, merge.Status)
|
||||||
fmt.Printf("%s: %s\n", remoteBug.HumanId(), "invalid remote data")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
localRef := bug.BugsRefPattern + remoteBug.Id()
|
|
||||||
localExist, err := repo.RefExist(localRef)
|
|
||||||
|
|
||||||
// the bug is not local yet, simply create the reference
|
|
||||||
if !localExist {
|
|
||||||
err := repo.CopyRef(remoteRef, localRef)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("%s: %s\n", remoteBug.HumanId(), "new")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
localBug, err := bug.ReadBug(repo, localRef)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
updated, err := localBug.Merge(repo, remoteBug)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if updated {
|
|
||||||
fmt.Printf("%s: %s\n", remoteBug.HumanId(), "updated")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,9 +16,10 @@ func runPush(cmd *cobra.Command, args []string) error {
|
|||||||
remote = args[0]
|
remote = args[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := repo.PushRefs(remote, bug.BugsRefPattern+"*"); err != nil {
|
if err := bug.Push(repo, remote); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ func runShowBug(cmd *cobra.Command, args []string) error {
|
|||||||
|
|
||||||
prefix := args[0]
|
prefix := args[0]
|
||||||
|
|
||||||
b, err := bug.FindBug(repo, prefix)
|
b, err := bug.FindLocalBug(repo, prefix)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ func runWebUI(cmd *cobra.Command, args []string) error {
|
|||||||
var err error
|
var err error
|
||||||
port, err = freeport.GetFreePort()
|
port, err = freeport.GetFreePort()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,12 +18,12 @@ func graphqlSchema() (graphql.Schema, error) {
|
|||||||
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
|
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
|
||||||
repo := p.Context.Value("repo").(repository.Repo)
|
repo := p.Context.Value("repo").(repository.Repo)
|
||||||
id, _ := p.Args["id"].(string)
|
id, _ := p.Args["id"].(string)
|
||||||
bug, err := bug.FindBug(repo, id)
|
b, err := bug.FindLocalBug(repo, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
snapshot := bug.Compile()
|
snapshot := b.Compile()
|
||||||
|
|
||||||
return snapshot, nil
|
return snapshot, nil
|
||||||
},
|
},
|
||||||
@ -33,22 +33,15 @@ func graphqlSchema() (graphql.Schema, error) {
|
|||||||
Type: graphql.NewList(bugType),
|
Type: graphql.NewList(bugType),
|
||||||
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
|
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
|
||||||
repo := p.Context.Value("repo").(repository.Repo)
|
repo := p.Context.Value("repo").(repository.Repo)
|
||||||
ids, err := repo.ListRefs(bug.BugsRefPattern)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var snapshots []bug.Snapshot
|
var snapshots []bug.Snapshot
|
||||||
|
|
||||||
for _, ref := range ids {
|
for sb := range bug.ReadAllLocalBugs(repo) {
|
||||||
bug, err := bug.ReadBug(repo, bug.BugsRefPattern+ref)
|
if sb.Err != nil {
|
||||||
|
return nil, sb.Err
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
snapshots = append(snapshots, bug.Compile())
|
snapshots = append(snapshots, sb.Bug.Compile())
|
||||||
}
|
}
|
||||||
|
|
||||||
return snapshots, nil
|
return snapshots, nil
|
||||||
|
@ -19,6 +19,8 @@ type GitRepo struct {
|
|||||||
|
|
||||||
// Run the given git command with the given I/O reader/writers, returning an error if it fails.
|
// Run the given git command with the given I/O reader/writers, returning an error if it fails.
|
||||||
func (repo *GitRepo) runGitCommandWithIO(stdin io.Reader, stdout, stderr io.Writer, args ...string) error {
|
func (repo *GitRepo) runGitCommandWithIO(stdin io.Reader, stdout, stderr io.Writer, args ...string) error {
|
||||||
|
fmt.Println("Running git", strings.Join(args, " "))
|
||||||
|
|
||||||
cmd := exec.Command("git", args...)
|
cmd := exec.Command("git", args...)
|
||||||
cmd.Dir = repo.Path
|
cmd.Dir = repo.Path
|
||||||
cmd.Stdin = stdin
|
cmd.Stdin = stdin
|
||||||
@ -99,10 +101,8 @@ func (repo *GitRepo) GetCoreEditor() (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FetchRefs fetch git refs from a remote
|
// FetchRefs fetch git refs from a remote
|
||||||
func (repo *GitRepo) FetchRefs(remote, refPattern, remoteRefPattern string) error {
|
func (repo *GitRepo) FetchRefs(remote, refSpec string) error {
|
||||||
remoteRefSpec := fmt.Sprintf(remoteRefPattern, remote)
|
err := repo.runGitCommandInline("fetch", remote, "\""+refSpec+"\"")
|
||||||
fetchRefSpec := fmt.Sprintf("%s:%s", refPattern, remoteRefSpec)
|
|
||||||
err := repo.runGitCommandInline("fetch", remote, fetchRefSpec)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to fetch from the remote '%s': %v", remote, err)
|
return fmt.Errorf("failed to fetch from the remote '%s': %v", remote, err)
|
||||||
@ -112,8 +112,8 @@ func (repo *GitRepo) FetchRefs(remote, refPattern, remoteRefPattern string) erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PushRefs push git refs to a remote
|
// PushRefs push git refs to a remote
|
||||||
func (repo *GitRepo) PushRefs(remote string, refPattern string) error {
|
func (repo *GitRepo) PushRefs(remote string, refSpec string) error {
|
||||||
err := repo.runGitCommandInline("push", remote, refPattern)
|
err := repo.runGitCommandInline("push", remote, refSpec)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to push to the remote '%s': %v", remote, err)
|
return fmt.Errorf("failed to push to the remote '%s': %v", remote, err)
|
||||||
|
@ -48,11 +48,11 @@ func (r *mockRepoForTest) GetCoreEditor() (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PushRefs push git refs to a remote
|
// PushRefs push git refs to a remote
|
||||||
func (r *mockRepoForTest) PushRefs(remote string, refPattern string) error {
|
func (r *mockRepoForTest) PushRefs(remote string, refSpec string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *mockRepoForTest) FetchRefs(remote string, refPattern string, remoteRefPattern string) error {
|
func (r *mockRepoForTest) FetchRefs(remote string, refSpec string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,10 +22,10 @@ type Repo interface {
|
|||||||
GetCoreEditor() (string, error)
|
GetCoreEditor() (string, error)
|
||||||
|
|
||||||
// FetchRefs fetch git refs from a remote
|
// FetchRefs fetch git refs from a remote
|
||||||
FetchRefs(remote string, refPattern string, remoteRefPattern string) error
|
FetchRefs(remote string, refSpec string) error
|
||||||
|
|
||||||
// PushRefs push git refs to a remote
|
// PushRefs push git refs to a remote
|
||||||
PushRefs(remote string, refPattern string) error
|
PushRefs(remote string, refSpec string) error
|
||||||
|
|
||||||
// StoreData will store arbitrary data and return the corresponding hash
|
// StoreData will store arbitrary data and return the corresponding hash
|
||||||
StoreData(data []byte) (util.Hash, error)
|
StoreData(data []byte) (util.Hash, error)
|
||||||
|
Loading…
Reference in New Issue
Block a user