diff --git a/bug/comment.go b/bug/comment.go index c0c07076a0cf3eac0c7d7c1d6dc42de7ab0e2d88..9cc387380631a805e60016ad6374984e405e3e48 100644 --- a/bug/comment.go +++ b/bug/comment.go @@ -6,8 +6,8 @@ import ( ) type Comment struct { - Author Person - Message string + Author Person `json:"author"` + Message string `json:"message"` // 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. diff --git a/bug/person.go b/bug/person.go index 5c9dcc4c2e0380f4d316bc2ffb15b9847fe98cf8..6a70fa9e6e348d82413c3d45a46e43d210e68407 100644 --- a/bug/person.go +++ b/bug/person.go @@ -6,8 +6,8 @@ import ( ) type Person struct { - Name string - Email string + Name string `json:"name"` + Email string `json:"email"` } // GetUser will query the repository for user detail and build the corresponding Person diff --git a/bug/snapshot.go b/bug/snapshot.go index 14ffd629eb459516e171e6027edf7e2043befd4f..5058b3f74d8fab15e7c1cdf5b7d00e70506c2b1a 100644 --- a/bug/snapshot.go +++ b/bug/snapshot.go @@ -10,10 +10,10 @@ import ( type Snapshot struct { id string - Status Status - Title string - Comments []Comment - Labels []Label + Status Status `json:"status"` + Title string `json:"title"` + Comments []Comment `json:"comments"` + Labels []Label `json:"labels"` Operations []Operation } diff --git a/commands/webui.go b/commands/webui.go index af93153ae5d4950fe3badc654969d850399c48ca..0cabbc48ce86e3aba0850a118c3669dca18a08e7 100644 --- a/commands/webui.go +++ b/commands/webui.go @@ -23,7 +23,7 @@ func runWebUI(cmd *cobra.Command, args []string) error { fmt.Printf("Web UI available at %s\n", webUiAddr) - graphqlHandler, err := graphql.NewHandler() + graphqlHandler, err := graphql.NewHandler(repo) if err != nil { return err diff --git a/graphql/handler.go b/graphql/handler.go index 7dbb7a0f218aee2132b8fb881a044d8dd4014a94..b49ca56bc791cf494027e7868b9a518ee534986b 100644 --- a/graphql/handler.go +++ b/graphql/handler.go @@ -1,17 +1,36 @@ package graphql -import "github.com/graphql-go/handler" +import ( + "context" + "net/http" -func NewHandler() (*handler.Handler, error) { - schema, err := newGraphqlSchema() + "github.com/MichaelMure/git-bug/repository" + "github.com/graphql-go/handler" +) + +type Handler struct { + Handler *handler.Handler + Repo repository.Repo +} + +func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctx := context.WithValue(r.Context(), "repo", h.Repo) + h.Handler.ContextHandler(ctx, w, r) +} + +func NewHandler(repo repository.Repo) (*Handler, error) { + schema, err := graphqlSchema() if err != nil { return nil, err } - return handler.New(&handler.Config{ - Schema: &schema, - Pretty: true, - GraphiQL: true, - }), nil + return &Handler{ + Handler: handler.New(&handler.Config{ + Schema: &schema, + Pretty: true, + GraphiQL: true, + }), + Repo: repo, + }, nil } diff --git a/graphql/schema.go b/graphql/schema.go index e929fb44f74597aa8ace09d4dc867ef7ddd09428..4cb893fe2914559d1aea534f66f18c709edfafde 100644 --- a/graphql/schema.go +++ b/graphql/schema.go @@ -1,21 +1,35 @@ package graphql -import "github.com/graphql-go/graphql" +import ( + "github.com/MichaelMure/git-bug/bug" + "github.com/MichaelMure/git-bug/repository" + "github.com/graphql-go/graphql" +) -func newGraphqlSchema() (graphql.Schema, error) { +func graphqlSchema() (graphql.Schema, error) { + fields := graphql.Fields{ + "bug": &graphql.Field{ + Type: bugType, + Args: graphql.FieldConfigArgument{ + "id": &graphql.ArgumentConfig{ + Type: bugIdScalar, + }, + }, + Resolve: func(p graphql.ResolveParams) (interface{}, error) { + repo := p.Context.Value("repo").(repository.Repo) + id, _ := p.Args["id"].(string) + bug, err := bug.FindBug(repo, id) + if err != nil { + return nil, err + } + + snapshot := bug.Compile() - rootQuery := graphql.ObjectConfig{ - Name: "RootQuery", - Fields: graphql.Fields{ - "hello": &graphql.Field{ - Type: graphql.String, + return snapshot, nil }, }, } - - schemaConfig := graphql.SchemaConfig{ - Query: graphql.NewObject(rootQuery), - } - + rootQuery := graphql.ObjectConfig{Name: "RootQuery", Fields: fields} + schemaConfig := graphql.SchemaConfig{Query: graphql.NewObject(rootQuery)} return graphql.NewSchema(schemaConfig) } diff --git a/graphql/types.go b/graphql/types.go index edce9ea151ac546e8e47e90fc2c53f6db8de3e9e..a320ca39ff777734f6f166c5d7f2677a271c33d7 100644 --- a/graphql/types.go +++ b/graphql/types.go @@ -1,13 +1,44 @@ package graphql -import "github.com/graphql-go/graphql" +import ( + "fmt" + + "github.com/graphql-go/graphql" + "github.com/graphql-go/graphql/language/ast" + + "github.com/MichaelMure/git-bug/bug" +) + +func coerceString(value interface{}) interface{} { + if v, ok := value.(*string); ok { + return *v + } + return fmt.Sprintf("%v", value) +} + +var bugIdScalar = graphql.NewScalar(graphql.ScalarConfig{ + Name: "BugID", + Description: "TODO", + Serialize: coerceString, + ParseValue: coerceString, + ParseLiteral: func(valueAST ast.Value) interface{} { + switch valueAST := valueAST.(type) { + case *ast.StringValue: + return valueAST.Value + } + return nil + }, +}) // Internally, it's the Snapshot var bugType = graphql.NewObject(graphql.ObjectConfig{ Name: "Bug", Fields: graphql.Fields{ "id": &graphql.Field{ - Type: graphql.String, + Type: bugIdScalar, + Resolve: func(p graphql.ResolveParams) (interface{}, error) { + return p.Source.(bug.Snapshot).Id(), nil + }, }, "status": &graphql.Field{ Type: graphql.String, @@ -17,6 +48,9 @@ var bugType = graphql.NewObject(graphql.ObjectConfig{ }, "labels": &graphql.Field{ Type: graphql.NewList(graphql.String), + Resolve: func(p graphql.ResolveParams) (interface{}, error) { + return p.Source.(bug.Snapshot).Labels, nil + }, }, // TODO: operations },