diff options
-rw-r--r-- | bug/comment.go | 9 | ||||
-rw-r--r-- | bug/op_add_comment.go | 2 | ||||
-rw-r--r-- | bug/op_create.go | 2 | ||||
-rw-r--r-- | bug/op_create_test.go | 2 | ||||
-rw-r--r-- | bug/op_edit_comment.go | 14 | ||||
-rw-r--r-- | bug/time.go | 9 | ||||
-rw-r--r-- | bug/timeline.go | 81 | ||||
-rw-r--r-- | graphql/gqlgen.yml | 2 | ||||
-rw-r--r-- | graphql/graph/gen_graph.go | 578 | ||||
-rw-r--r-- | graphql/resolvers/root.go | 16 | ||||
-rw-r--r-- | graphql/resolvers/timeline.go | 36 | ||||
-rw-r--r-- | graphql/schema.graphql | 23 |
12 files changed, 695 insertions, 79 deletions
diff --git a/bug/comment.go b/bug/comment.go index c7168275..db5cc45e 100644 --- a/bug/comment.go +++ b/bug/comment.go @@ -3,7 +3,6 @@ package bug import ( "github.com/MichaelMure/git-bug/util/git" "github.com/dustin/go-humanize" - "time" ) // Comment represent a comment in a Bug @@ -14,16 +13,14 @@ type Comment struct { // Creation time of the comment. // Should be used only for human display, never for ordering as we can't rely on it in a distributed system. - UnixTime int64 + UnixTime Timestamp } // FormatTimeRel format the UnixTime of the comment for human consumption func (c Comment) FormatTimeRel() string { - t := time.Unix(c.UnixTime, 0) - return humanize.Time(t) + return humanize.Time(c.UnixTime.Time()) } func (c Comment) FormatTime() string { - t := time.Unix(c.UnixTime, 0) - return t.Format("Mon Jan 2 15:04:05 2006 +0200") + return c.UnixTime.Time().Format("Mon Jan 2 15:04:05 2006 +0200") } diff --git a/bug/op_add_comment.go b/bug/op_add_comment.go index 4594ba70..7f8b8b5b 100644 --- a/bug/op_add_comment.go +++ b/bug/op_add_comment.go @@ -30,7 +30,7 @@ func (op *AddCommentOperation) Apply(snapshot *Snapshot) { Message: op.Message, Author: op.Author, Files: op.Files, - UnixTime: op.UnixTime, + UnixTime: Timestamp(op.UnixTime), } snapshot.Comments = append(snapshot.Comments, comment) diff --git a/bug/op_create.go b/bug/op_create.go index 5c41eb7c..0553137f 100644 --- a/bug/op_create.go +++ b/bug/op_create.go @@ -32,7 +32,7 @@ func (op *CreateOperation) Apply(snapshot *Snapshot) { comment := Comment{ Message: op.Message, Author: op.Author, - UnixTime: op.UnixTime, + UnixTime: Timestamp(op.UnixTime), } snapshot.Comments = []Comment{comment} diff --git a/bug/op_create_test.go b/bug/op_create_test.go index e9a36cf8..f27f6ee0 100644 --- a/bug/op_create_test.go +++ b/bug/op_create_test.go @@ -26,7 +26,7 @@ func TestCreate(t *testing.T) { t.Fatal(err) } - comment := Comment{Author: rene, Message: "message", UnixTime: create.UnixTime} + comment := Comment{Author: rene, Message: "message", UnixTime: Timestamp(create.UnixTime)} expected := Snapshot{ Title: "title", diff --git a/bug/op_edit_comment.go b/bug/op_edit_comment.go index c6cfab2b..cb4a2216 100644 --- a/bug/op_edit_comment.go +++ b/bug/op_edit_comment.go @@ -57,18 +57,20 @@ func (op *EditCommentOperation) Apply(snapshot *Snapshot) { return } + comment := Comment{ + Message: op.Message, + Files: op.Files, + UnixTime: Timestamp(op.UnixTime), + } + switch target.(type) { case *CreateTimelineItem: item := target.(*CreateTimelineItem) - newComment := item.LastState() - newComment.Message = op.Message - item.History = append(item.History, newComment) + item.Append(comment) case *CommentTimelineItem: item := target.(*CommentTimelineItem) - newComment := item.LastState() - newComment.Message = op.Message - item.History = append(item.History, newComment) + item.Append(comment) } snapshot.Comments[commentIndex].Message = op.Message diff --git a/bug/time.go b/bug/time.go new file mode 100644 index 00000000..a085e8e9 --- /dev/null +++ b/bug/time.go @@ -0,0 +1,9 @@ +package bug + +import "time" + +type Timestamp int64 + +func (t Timestamp) Time() time.Time { + return time.Unix(int64(t), 0) +} diff --git a/bug/timeline.go b/bug/timeline.go index 0f79958b..d734e18b 100644 --- a/bug/timeline.go +++ b/bug/timeline.go @@ -1,50 +1,67 @@ package bug -import "github.com/MichaelMure/git-bug/util/git" +import ( + "github.com/MichaelMure/git-bug/util/git" +) type TimelineItem interface { // Hash return the hash of the item Hash() (git.Hash, error) } +type CommentHistoryStep struct { + Message string + UnixTime Timestamp +} + // CreateTimelineItem replace a Create operation in the Timeline and hold its edition history type CreateTimelineItem struct { - hash git.Hash - History []Comment + CommentTimelineItem } func NewCreateTimelineItem(hash git.Hash, comment Comment) *CreateTimelineItem { return &CreateTimelineItem{ - hash: hash, - History: []Comment{ - comment, + CommentTimelineItem: CommentTimelineItem{ + hash: hash, + Author: comment.Author, + Message: comment.Message, + Files: comment.Files, + CreatedAt: comment.UnixTime, + LastEdit: comment.UnixTime, + History: []CommentHistoryStep{ + { + Message: comment.Message, + UnixTime: comment.UnixTime, + }, + }, }, } } -func (c *CreateTimelineItem) Hash() (git.Hash, error) { - return c.hash, nil -} - -func (c *CreateTimelineItem) LastState() Comment { - if len(c.History) == 0 { - panic("no history yet") - } - - return c.History[len(c.History)-1] -} - // CommentTimelineItem replace a Comment in the Timeline and hold its edition history type CommentTimelineItem struct { - hash git.Hash - History []Comment + hash git.Hash + Author Person + Message string + Files []git.Hash + CreatedAt Timestamp + LastEdit Timestamp + History []CommentHistoryStep } func NewCommentTimelineItem(hash git.Hash, comment Comment) *CommentTimelineItem { return &CommentTimelineItem{ - hash: hash, - History: []Comment{ - comment, + hash: hash, + Author: comment.Author, + Message: comment.Message, + Files: comment.Files, + CreatedAt: comment.UnixTime, + LastEdit: comment.UnixTime, + History: []CommentHistoryStep{ + { + Message: comment.Message, + UnixTime: comment.UnixTime, + }, }, } } @@ -53,10 +70,18 @@ func (c *CommentTimelineItem) Hash() (git.Hash, error) { return c.hash, nil } -func (c *CommentTimelineItem) LastState() Comment { - if len(c.History) == 0 { - panic("no history yet") - } +// Append will append a new comment in the history and update the other values +func (c *CommentTimelineItem) Append(comment Comment) { + c.Message = comment.Message + c.Files = comment.Files + c.LastEdit = comment.UnixTime + c.History = append(c.History, CommentHistoryStep{ + Message: comment.Message, + UnixTime: comment.UnixTime, + }) +} - return c.History[len(c.History)-1] +// Edited say if the comment was edited +func (c *CommentTimelineItem) Edited() bool { + return len(c.History) > 1 } diff --git a/graphql/gqlgen.yml b/graphql/gqlgen.yml index 4ff24f4e..9c0e0842 100644 --- a/graphql/gqlgen.yml +++ b/graphql/gqlgen.yml @@ -33,6 +33,8 @@ models: model: github.com/MichaelMure/git-bug/bug.LabelChangeOperation TimelineItem: model: github.com/MichaelMure/git-bug/bug.TimelineItem + CommentHistoryStep: + model: github.com/MichaelMure/git-bug/bug.CommentHistoryStep CreateTimelineItem: model: github.com/MichaelMure/git-bug/bug.CreateTimelineItem CommentTimelineItem: diff --git a/graphql/graph/gen_graph.go b/graphql/graph/gen_graph.go index 032cf5cb..01e3bb91 100644 --- a/graphql/graph/gen_graph.go +++ b/graphql/graph/gen_graph.go @@ -37,7 +37,10 @@ type Config struct { type ResolverRoot interface { AddCommentOperation() AddCommentOperationResolver Bug() BugResolver + CommentHistoryStep() CommentHistoryStepResolver + CommentTimelineItem() CommentTimelineItemResolver CreateOperation() CreateOperationResolver + CreateTimelineItem() CreateTimelineItemResolver LabelChangeOperation() LabelChangeOperationResolver Mutation() MutationResolver Query() QueryResolver @@ -101,9 +104,19 @@ type ComplexityRoot struct { Node func(childComplexity int) int } + CommentHistoryStep struct { + Message func(childComplexity int) int + Date func(childComplexity int) int + } + CommentTimelineItem struct { Hash func(childComplexity int) int - LastState func(childComplexity int) int + Author func(childComplexity int) int + Message func(childComplexity int) int + Files func(childComplexity int) int + CreatedAt func(childComplexity int) int + LastEdit func(childComplexity int) int + Edited func(childComplexity int) int History func(childComplexity int) int } @@ -117,7 +130,12 @@ type ComplexityRoot struct { CreateTimelineItem struct { Hash func(childComplexity int) int - LastState func(childComplexity int) int + Author func(childComplexity int) int + Message func(childComplexity int) int + Files func(childComplexity int) int + CreatedAt func(childComplexity int) int + LastEdit func(childComplexity int) int + Edited func(childComplexity int) int History func(childComplexity int) int } @@ -214,10 +232,21 @@ type BugResolver interface { Timeline(ctx context.Context, obj *bug.Snapshot, after *string, before *string, first *int, last *int) (models.TimelineItemConnection, error) Operations(ctx context.Context, obj *bug.Snapshot, after *string, before *string, first *int, last *int) (models.OperationConnection, error) } +type CommentHistoryStepResolver interface { + Date(ctx context.Context, obj *bug.CommentHistoryStep) (time.Time, error) +} +type CommentTimelineItemResolver interface { + CreatedAt(ctx context.Context, obj *bug.CommentTimelineItem) (time.Time, error) + LastEdit(ctx context.Context, obj *bug.CommentTimelineItem) (time.Time, error) +} type CreateOperationResolver interface { Author(ctx context.Context, obj *bug.CreateOperation) (bug.Person, error) Date(ctx context.Context, obj *bug.CreateOperation) (time.Time, error) } +type CreateTimelineItemResolver interface { + CreatedAt(ctx context.Context, obj *bug.CreateTimelineItem) (time.Time, error) + LastEdit(ctx context.Context, obj *bug.CreateTimelineItem) (time.Time, error) +} type LabelChangeOperationResolver interface { Author(ctx context.Context, obj *bug.LabelChangeOperation) (bug.Person, error) Date(ctx context.Context, obj *bug.LabelChangeOperation) (time.Time, error) @@ -1134,6 +1163,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.CommentEdge.Node(childComplexity), true + case "CommentHistoryStep.message": + if e.complexity.CommentHistoryStep.Message == nil { + break + } + + return e.complexity.CommentHistoryStep.Message(childComplexity), true + + case "CommentHistoryStep.date": + if e.complexity.CommentHistoryStep.Date == nil { + break + } + + return e.complexity.CommentHistoryStep.Date(childComplexity), true + case "CommentTimelineItem.hash": if e.complexity.CommentTimelineItem.Hash == nil { break @@ -1141,12 +1184,47 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.CommentTimelineItem.Hash(childComplexity), true - case "CommentTimelineItem.lastState": - if e.complexity.CommentTimelineItem.LastState == nil { + case "CommentTimelineItem.author": + if e.complexity.CommentTimelineItem.Author == nil { + break + } + + return e.complexity.CommentTimelineItem.Author(childComplexity), true + + case "CommentTimelineItem.message": + if e.complexity.CommentTimelineItem.Message == nil { + break + } + + return e.complexity.CommentTimelineItem.Message(childComplexity), true + + case "CommentTimelineItem.files": + if e.complexity.CommentTimelineItem.Files == nil { break } - return e.complexity.CommentTimelineItem.LastState(childComplexity), true + return e.complexity.CommentTimelineItem.Files(childComplexity), true + + case "CommentTimelineItem.createdAt": + if e.complexity.CommentTimelineItem.CreatedAt == nil { + break + } + + return e.complexity.CommentTimelineItem.CreatedAt(childComplexity), true + + case "CommentTimelineItem.lastEdit": + if e.complexity.CommentTimelineItem.LastEdit == nil { + break + } + + return e.complexity.CommentTimelineItem.LastEdit(childComplexity), true + + case "CommentTimelineItem.edited": + if e.complexity.CommentTimelineItem.Edited == nil { + break + } + + return e.complexity.CommentTimelineItem.Edited(childComplexity), true case "CommentTimelineItem.history": if e.complexity.CommentTimelineItem.History == nil { @@ -1197,12 +1275,47 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.CreateTimelineItem.Hash(childComplexity), true - case "CreateTimelineItem.lastState": - if e.complexity.CreateTimelineItem.LastState == nil { + case "CreateTimelineItem.author": + if e.complexity.CreateTimelineItem.Author == nil { + break + } + + return e.complexity.CreateTimelineItem.Author(childComplexity), true + + case "CreateTimelineItem.message": + if e.complexity.CreateTimelineItem.Message == nil { + break + } + + return e.complexity.CreateTimelineItem.Message(childComplexity), true + + case "CreateTimelineItem.files": + if e.complexity.CreateTimelineItem.Files == nil { + break + } + + return e.complexity.CreateTimelineItem.Files(childComplexity), true + + case "CreateTimelineItem.createdAt": + if e.complexity.CreateTimelineItem.CreatedAt == nil { + break + } + + return e.complexity.CreateTimelineItem.CreatedAt(childComplexity), true + + case "CreateTimelineItem.lastEdit": + if e.complexity.CreateTimelineItem.LastEdit == nil { + break + } + + return e.complexity.CreateTimelineItem.LastEdit(childComplexity), true + + case "CreateTimelineItem.edited": + if e.complexity.CreateTimelineItem.Edited == nil { break } - return e.complexity.CreateTimelineItem.LastState(childComplexity), true + return e.complexity.CreateTimelineItem.Edited(childComplexity), true case "CreateTimelineItem.history": if e.complexity.CreateTimelineItem.History == nil { @@ -2816,12 +2929,97 @@ func (ec *executionContext) _CommentEdge_node(ctx context.Context, field graphql return ec._Comment(ctx, field.Selections, &res) } +var commentHistoryStepImplementors = []string{"CommentHistoryStep"} + +// nolint: gocyclo, errcheck, gas, goconst +func (ec *executionContext) _CommentHistoryStep(ctx context.Context, sel ast.SelectionSet, obj *bug.CommentHistoryStep) graphql.Marshaler { + fields := graphql.CollectFields(ctx, sel, commentHistoryStepImplementors) + + var wg sync.WaitGroup + out := graphql.NewOrderedMap(len(fields)) + invalid := false + for i, field := range fields { + out.Keys[i] = field.Alias + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("CommentHistoryStep") + case "message": + out.Values[i] = ec._CommentHistoryStep_message(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalid = true + } + case "date": + wg.Add(1) + go func(i int, field graphql.CollectedField) { + out.Values[i] = ec._CommentHistoryStep_date(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalid = true + } + wg.Done() + }(i, field) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + wg.Wait() + if invalid { + return graphql.Null + } + return out +} + +// nolint: vetshadow +func (ec *executionContext) _CommentHistoryStep_message(ctx context.Context, field graphql.CollectedField, obj *bug.CommentHistoryStep) graphql.Marshaler { + rctx := &graphql.ResolverContext{ + Object: "CommentHistoryStep", + Args: nil, + Field: field, + } + ctx = graphql.WithResolverContext(ctx, rctx) + resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { + return obj.Message, nil + }) + if resTmp == nil { + if !ec.HasError(rctx) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + rctx.Result = res + return graphql.MarshalString(res) +} + +// nolint: vetshadow +func (ec *executionContext) _CommentHistoryStep_date(ctx context.Context, field graphql.CollectedField, obj *bug.CommentHistoryStep) graphql.Marshaler { + rctx := &graphql.ResolverContext{ + Object: "CommentHistoryStep", + Args: nil, + Field: field, + } + ctx = graphql.WithResolverContext(ctx, rctx) + resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { + return ec.resolvers.CommentHistoryStep().Date(ctx, obj) + }) + if resTmp == nil { + if !ec.HasError(rctx) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(time.Time) + rctx.Result = res + return graphql.MarshalTime(res) +} + var commentTimelineItemImplementors = []string{"CommentTimelineItem", "TimelineItem"} // nolint: gocyclo, errcheck, gas, goconst func (ec *executionContext) _CommentTimelineItem(ctx context.Context, sel ast.SelectionSet, obj *bug.CommentTimelineItem) graphql.Marshaler { fields := graphql.CollectFields(ctx, sel, commentTimelineItemImplementors) + var wg sync.WaitGroup out := graphql.NewOrderedMap(len(fields)) invalid := false for i, field := range fields { @@ -2835,8 +3033,41 @@ func (ec *executionContext) _CommentTimelineItem(ctx context.Context, sel ast.Se if out.Values[i] == graphql.Null { invalid = true } - case "lastState": - out.Values[i] = ec._CommentTimelineItem_lastState(ctx, field, obj) + case "author": + out.Values[i] = ec._CommentTimelineItem_author(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalid = true + } + case "message": + out.Values[i] = ec._CommentTimelineItem_message(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalid = true + } + case "files": + out.Values[i] = ec._CommentTimelineItem_files(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalid = true + } + case "createdAt": + wg.Add(1) + go func(i int, field graphql.CollectedField) { + out.Values[i] = ec._CommentTimelineItem_createdAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalid = true + } + wg.Done() + }(i, field) + case "lastEdit": + wg.Add(1) + go func(i int, field graphql.CollectedField) { + out.Values[i] = ec._CommentTimelineItem_lastEdit(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalid = true + } + wg.Done() + }(i, field) + case "edited": + out.Values[i] = ec._CommentTimelineItem_edited(ctx, field, obj) if out.Values[i] == graphql.Null { invalid = true } @@ -2849,7 +3080,7 @@ func (ec *executionContext) _CommentTimelineItem(ctx context.Context, sel ast.Se panic("unknown field " + strconv.Quote(field.Name)) } } - + wg.Wait() if invalid { return graphql.Null } @@ -2879,7 +3110,7 @@ func (ec *executionContext) _CommentTimelineItem_hash(ctx context.Context, field } // nolint: vetshadow -func (ec *executionContext) _CommentTimelineItem_lastState(ctx context.Context, field graphql.CollectedField, obj *bug.CommentTimelineItem) graphql.Marshaler { +func (ec *executionContext) _CommentTimelineItem_author(ctx context.Context, field graphql.CollectedField, obj *bug.CommentTimelineItem) graphql.Marshaler { rctx := &graphql.ResolverContext{ Object: "CommentTimelineItem", Args: nil, @@ -2887,7 +3118,7 @@ func (ec *executionContext) _CommentTimelineItem_lastState(ctx context.Context, } ctx = graphql.WithResolverContext(ctx, rctx) resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { - return obj.LastState(), nil + return obj.Author, nil }) if resTmp == nil { if !ec.HasError(rctx) { @@ -2895,10 +3126,129 @@ func (ec *executionContext) _CommentTimelineItem_lastState(ctx context.Context, } return graphql.Null } - res := resTmp.(bug.Comment) + res := resTmp.(bug.Person) rctx.Result = res - return ec._Comment(ctx, field.Selections, &res) + return ec._Person(ctx, field.Selections, &res) +} + +// nolint: vetshadow +func (ec *executionContext) _CommentTimelineItem_message(ctx context.Context, field graphql.CollectedField, obj *bug.CommentTimelineItem) graphql.Marshaler { + rctx := &graphql.ResolverContext{ + Object: "CommentTimelineItem", + Args: nil, + Field: field, + } + ctx = graphql.WithResolverContext(ctx, rctx) + resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { + return obj.Message, nil + }) + if resTmp == nil { + if !ec.HasError(rctx) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + rctx.Result = res + return graphql.MarshalString(res) +} + +// nolint: vetshadow +func (ec *executionContext) _CommentTimelineItem_files(ctx context.Context, field graphql.CollectedField, obj *bug.CommentTimelineItem) graphql.Marshaler { + rctx := &graphql.ResolverContext{ + Object: "CommentTimelineItem", + Args: nil, + Field: field, + } + ctx = graphql.WithResolverContext(ctx, rctx) + resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { + return obj.Files, nil + }) + if resTmp == nil { + if !ec.HasError(rctx) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]git.Hash) + rctx.Result = res + + arr1 := make(graphql.Array, len(res)) + + for idx1 := range res { + arr1[idx1] = func() graphql.Marshaler { + return res[idx1] + }() + } + + return arr1 +} + +// nolint: vetshadow +func (ec *executionContext) _CommentTimelineItem_createdAt(ctx context.Context, field graphql.CollectedField, obj *bug.CommentTimelineItem) graphql.Marshaler { + rctx := &graphql.ResolverContext{ + Object: "CommentTimelineItem", + Args: nil, + Field: field, + } + ctx = graphql.WithResolverContext(ctx, rctx) + resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { + return ec.resolvers.CommentTimelineItem().CreatedAt(ctx, obj) + }) + if resTmp == nil { + if !ec.HasError(rctx) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(time.Time) + rctx.Result = res + return graphql.MarshalTime(res) +} + +// nolint: vetshadow +func (ec *executionContext) _CommentTimelineItem_lastEdit(ctx context.Context, field graphql.CollectedField, obj *bug.CommentTimelineItem) graphql.Marshaler { + rctx := &graphql.ResolverContext{ + Object: "CommentTimelineItem", + Args: nil, + Field: field, + } + ctx = graphql.WithResolverContext(ctx, rctx) + resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { + return ec.resolvers.CommentTimelineItem().LastEdit(ctx, obj) + }) + if resTmp == nil { + if !ec.HasError(rctx) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(time.Time) + rctx.Result = res + return graphql.MarshalTime(res) +} + +// nolint: vetshadow +func (ec *executionContext) _CommentTimelineItem_edited(ctx context.Context, field graphql.CollectedField, obj *bug.CommentTimelineItem) graphql.Marshaler { + rctx := &graphql.ResolverContext{ + Object: "CommentTimelineItem", + Args: nil, + Field: field, + } + ctx = graphql.WithResolverContext(ctx, rctx) + resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { + return obj.Edited(), nil + }) + if resTmp == nil { + if !ec.HasError(rctx) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + rctx.Result = res + return graphql.MarshalBoolean(res) } // nolint: vetshadow @@ -2918,7 +3268,7 @@ func (ec *executionContext) _CommentTimelineItem_history(ctx context.Context, fi } return graphql.Null } - res := resTmp.([]bug.Comment) + res := resTmp.([]bug.CommentHistoryStep) rctx.Result = res arr1 := make(graphql.Array, len(res)) @@ -2942,7 +3292,7 @@ func (ec *executionContext) _CommentTimelineItem_history(ctx context.Context, fi } arr1[idx1] = func() graphql.Marshaler { - return ec._Comment(ctx, field.Selections, &res[idx1]) + return ec._CommentHistoryStep(ctx, field.Selections, &res[idx1]) }() } if isLen1 { @@ -3141,6 +3491,7 @@ var createTimelineItemImplementors = []string{"CreateTimelineItem", "TimelineIte func (ec *executionContext) _CreateTimelineItem(ctx context.Context, sel ast.SelectionSet, obj *bug.CreateTimelineItem) graphql.Marshaler { fields := graphql.CollectFields(ctx, sel, createTimelineItemImplementors) + var wg sync.WaitGroup out := graphql.NewOrderedMap(len(fields)) invalid := false for i, field := range fields { @@ -3154,8 +3505,41 @@ func (ec *executionContext) _CreateTimelineItem(ctx context.Context, sel ast.Sel if out.Values[i] == graphql.Null { invalid = true } - case "lastState": - out.Values[i] = ec._CreateTimelineItem_lastState(ctx, field, obj) + case "author": + out.Values[i] = ec._CreateTimelineItem_author(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalid = true + } + case "message": + out.Values[i] = ec._CreateTimelineItem_message(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalid = true + } + case "files": + out.Values[i] = ec._CreateTimelineItem_files(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalid = true + } + case "createdAt": + wg.Add(1) + go func(i int, field graphql.CollectedField) { + out.Values[i] = ec._CreateTimelineItem_createdAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalid = true + } + wg.Done() + }(i, field) + case "lastEdit": + wg.Add(1) + go func(i int, field graphql.CollectedField) { + out.Values[i] = ec._CreateTimelineItem_lastEdit(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalid = true + } + wg.Done() + }(i, field) + case "edited": + out.Values[i] = ec._CreateTimelineItem_edited(ctx, field, obj) if out.Values[i] == graphql.Null { invalid = true } @@ -3168,7 +3552,7 @@ func (ec *executionContext) _CreateTimelineItem(ctx context.Context, sel ast.Sel panic("unknown field " + strconv.Quote(field.Name)) } } - + wg.Wait() if invalid { return graphql.Null } @@ -3198,7 +3582,7 @@ func (ec *executionContext) _CreateTimelineItem_hash(ctx context.Context, field } // nolint: vetshadow -func (ec *executionContext) _CreateTimelineItem_lastState(ctx context.Context, field graphql.CollectedField, obj *bug.CreateTimelineItem) graphql.Marshaler { +func (ec *executionContext) _CreateTimelineItem_author(ctx context.Context, field graphql.CollectedField, obj *bug.CreateTimelineItem) graphql.Marshaler { rctx := &graphql.ResolverContext{ Object: "CreateTimelineItem", Args: nil, @@ -3206,7 +3590,7 @@ func (ec *executionContext) _CreateTimelineItem_lastState(ctx context.Context, f } ctx = graphql.WithResolverContext(ctx, rctx) resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { - return obj.LastState(), nil + return obj.Author, nil }) if resTmp == nil { if !ec.HasError(rctx) { @@ -3214,10 +3598,129 @@ func (ec *executionContext) _CreateTimelineItem_lastState(ctx context.Context, f } return graphql.Null } - res := resTmp.(bug.Comment) + res := resTmp.(bug.Person) rctx.Result = res - return ec._Comment(ctx, field.Selections, &res) + return ec._Person(ctx, field.Selections, &res) +} + +// nolint: vetshadow +func (ec *executionContext) _CreateTimelineItem_message(ctx context.Context, field graphql.CollectedField, obj *bug.CreateTimelineItem) graphql.Marshaler { + rctx := &graphql.ResolverContext{ + Object: "CreateTimelineItem", + Args: nil, + Field: field, + } + ctx = graphql.WithResolverContext(ctx, rctx) + resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { + return obj.Message, nil + }) + if resTmp == nil { + if !ec.HasError(rctx) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + rctx.Result = res + return graphql.MarshalString(res) +} + +// nolint: vetshadow +func (ec *executionContext) _CreateTimelineItem_files(ctx context.Context, field graphql.CollectedField, obj *bug.CreateTimelineItem) graphql.Marshaler { + rctx := &graphql.ResolverContext{ + Object: "CreateTimelineItem", + Args: nil, + Field: field, + } + ctx = graphql.WithResolverContext(ctx, rctx) + resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { + return obj.Files, nil + }) + if resTmp == nil { + if !ec.HasError(rctx) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]git.Hash) + rctx.Result = res + + arr1 := make(graphql.Array, len(res)) + + for idx1 := range res { + arr1[idx1] = func() graphql.Marshaler { + return res[idx1] + }() + } + + return arr1 +} + +// nolint: vetshadow +func (ec *executionContext) _CreateTimelineItem_createdAt(ctx context.Context, field graphql.CollectedField, obj *bug.CreateTimelineItem) graphql.Marshaler { + rctx := &graphql.ResolverContext{ + Object: "CreateTimelineItem", + Args: nil, + Field: field, + } + ctx = graphql.WithResolverContext(ctx, rctx) + resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { + return ec.resolvers.CreateTimelineItem().CreatedAt(ctx, obj) + }) + if resTmp == nil { + if !ec.HasError(rctx) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(time.Time) + rctx.Result = res + return graphql.MarshalTime(res) +} + +// nolint: vetshadow +func (ec *executionContext) _CreateTimelineItem_lastEdit(ctx context.Context, field graphql.CollectedField, obj *bug.CreateTimelineItem) graphql.Marshaler { + rctx := &graphql.ResolverContext{ + Object: "CreateTimelineItem", + Args: nil, + Field: field, + } + ctx = graphql.WithResolverContext(ctx, rctx) + resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { + return ec.resolvers.CreateTimelineItem().LastEdit(ctx, obj) + }) + if resTmp == nil { + if !ec.HasError(rctx) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(time.Time) + rctx.Result = res + return graphql.MarshalTime(res) +} + +// nolint: vetshadow +func (ec *executionContext) _CreateTimelineItem_edited(ctx context.Context, field graphql.CollectedField, obj *bug.CreateTimelineItem) graphql.Marshaler { + rctx := &graphql.ResolverContext{ + Object: "CreateTimelineItem", + Args: nil, + Field: field, + } + ctx = graphql.WithResolverContext(ctx, rctx) + resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { + return obj.Edited(), nil + }) + if resTmp == nil { + if !ec.HasError(rctx) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + rctx.Result = res + return graphql.MarshalBoolean(res) } // nolint: vetshadow @@ -3237,7 +3740,7 @@ func (ec *executionContext) _CreateTimelineItem_history(ctx context.Context, fie } return graphql.Null } - res := resTmp.([]bug.Comment) + res := resTmp.([]bug.CommentHistoryStep) rctx.Result = res arr1 := make(graphql.Array, len(res)) @@ -3261,7 +3764,7 @@ func (ec *executionContext) _CreateTimelineItem_history(ctx context.Context, fie } arr1[idx1] = func() graphql.Marshaler { - return ec._Comment(ctx, field.Selections, &res[idx1]) + return ec._CommentHistoryStep(ctx, field.Selections, &res[idx1]) }() } if isLen1 { @@ -6603,16 +7106,31 @@ type TimelineItemEdge { node: TimelineItem! } +type CommentHistoryStep { + message: String! + date: Time! +} + type CreateTimelineItem implements TimelineItem { hash: Hash! - lastState: Comment! - history: [Comment!]! + author: Person! + message: String! + files: [Hash!]! + createdAt: Time! + lastEdit: Time! + edited: Boolean! + history: [CommentHistoryStep!]! } type CommentTimelineItem implements TimelineItem { hash: Hash! - lastState: Comment! - history: [Comment!]! + author: Person! + message: String! + files: [Hash!]! + createdAt: Time! + lastEdit: Time! + edited: Boolean! + history: [CommentHistoryStep!]! } """The connection type for Bug.""" diff --git a/graphql/resolvers/root.go b/graphql/resolvers/root.go index ff181784..2322edc7 100644 --- a/graphql/resolvers/root.go +++ b/graphql/resolvers/root.go @@ -32,10 +32,22 @@ func (RootResolver) AddCommentOperation() graph.AddCommentOperationResolver { return &addCommentOperationResolver{} } -func (r RootResolver) Bug() graph.BugResolver { +func (RootResolver) Bug() graph.BugResolver { return &bugResolver{} } +func (RootResolver) CommentHistoryStep() graph.CommentHistoryStepResolver { + return &commentHistoryStepResolver{} +} + +func (RootResolver) CommentTimelineItem() graph.CommentTimelineItemResolver { + return &commentTimelineItemResolver{} +} + +func (RootResolver) CreateTimelineItem() graph.CreateTimelineItemResolver { + return &createTimelineItemResolver{} +} + func (RootResolver) CreateOperation() graph.CreateOperationResolver { return &createOperationResolver{} } @@ -44,7 +56,7 @@ func (RootResolver) LabelChangeOperation() graph.LabelChangeOperationResolver { return &labelChangeOperation{} } -func (r RootResolver) Repository() graph.RepositoryResolver { +func (RootResolver) Repository() graph.RepositoryResolver { return &repoResolver{} } diff --git a/graphql/resolvers/timeline.go b/graphql/resolvers/timeline.go new file mode 100644 index 00000000..9b8262fe --- /dev/null +++ b/graphql/resolvers/timeline.go @@ -0,0 +1,36 @@ +package resolvers + +import ( + "context" + "time" + + "github.com/MichaelMure/git-bug/bug" +) + +type commentHistoryStepResolver struct{} + +func (commentHistoryStepResolver) Date(ctx context.Context, obj *bug.CommentHistoryStep) (time.Time, error) { + return obj.UnixTime.Time(), nil +} + +type commentTimelineItemResolver struct{} + +func (commentTimelineItemResolver) CreatedAt(ctx context.Context, obj *bug.CommentTimelineItem) (time.Time, error) { + return obj.CreatedAt.Time(), nil +} + +func (commentTimelineItemResolver) LastEdit(ctx context.Context, obj *bug.CommentTimelineItem) (time.Time, error) { + return obj.LastEdit.Time(), nil +} + +type createTimelineItemResolver struct{} + +func (createTimelineItemResolver) CreatedAt(ctx context.Context, obj *bug.CreateTimelineItem) (time.Time, error) { + return obj.CreatedAt.Time(), nil + +} + +func (createTimelineItemResolver) LastEdit(ctx context.Context, obj *bug.CreateTimelineItem) (time.Time, error) { + return obj.LastEdit.Time(), nil + +} diff --git a/graphql/schema.graphql b/graphql/schema.graphql index 2e685779..5c0d759f 100644 --- a/graphql/schema.graphql +++ b/graphql/schema.graphql @@ -141,16 +141,31 @@ type TimelineItemEdge { node: TimelineItem! } +type CommentHistoryStep { + message: String! + date: Time! +} + type CreateTimelineItem implements TimelineItem { hash: Hash! - lastState: Comment! - history: [Comment!]! + author: Person! + message: String! + files: [Hash!]! + createdAt: Time! + lastEdit: Time! + edited: Boolean! + history: [CommentHistoryStep!]! } type CommentTimelineItem implements TimelineItem { hash: Hash! - lastState: Comment! - history: [Comment!]! + author: Person! + message: String! + files: [Hash!]! + createdAt: Time! + lastEdit: Time! + edited: Boolean! + history: [CommentHistoryStep!]! } """The connection type for Bug.""" |