From 2759515475e589dd3375453913a699845586aa3f Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sun, 12 Apr 2020 14:46:34 -0400 Subject: [PATCH] api: rig up some git plubming data --- graphql/go.mod | 1 + graphql/go.sum | 43 +++++++ graphql/graph/generated/generated.go | 167 +++++++++++++++------------ graphql/graph/model/models_gen.go | 30 +---- graphql/graph/model/object.go | 66 +++++++++++ graphql/graph/model/reference.go | 35 ++++++ graphql/graph/model/repository.go | 30 ++++- graphql/graph/schema.graphqls | 6 +- graphql/graph/schema.resolvers.go | 33 ++++++ 9 files changed, 304 insertions(+), 107 deletions(-) create mode 100644 graphql/graph/model/object.go create mode 100644 graphql/graph/model/reference.go diff --git a/graphql/go.mod b/graphql/go.mod index 86e87a8..299f0bf 100644 --- a/graphql/go.mod +++ b/graphql/go.mod @@ -6,6 +6,7 @@ require ( git.sr.ht/~sircmpwn/gqlgen v0.0.0-20200412134447-57d7234737d4 github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect github.com/go-chi/chi v3.3.2+incompatible + github.com/go-git/go-git/v5 v5.0.0 github.com/gorilla/websocket v1.4.2 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/lib/pq v1.3.0 diff --git a/graphql/go.sum b/graphql/go.sum index b18aec1..047b528 100644 --- a/graphql/go.sum +++ b/graphql/go.sum @@ -5,18 +5,36 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/agnivade/levenshtein v1.0.3 h1:M5ZnqLOoZR8ygVq0FfkXsNOKzMCk0xRiow0R5+5VkQ0= github.com/agnivade/levenshtein v1.0.3/go.mod h1:4SFRZbbXWLF4MU1T9Qg0pGgH3Pjs+t6ie5efyrwRJXs= +github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= +github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= +github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-chi/chi v3.3.2+incompatible h1:uQNcQN3NsV1j4ANsPh42P4ew4t6rnRbJb8frvpp31qQ= github.com/go-chi/chi v3.3.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= +github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= +github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= +github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM= +github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-git v1.0.0 h1:YcN9iDGDoXuIw0vHls6rINwV416HYa0EB2X+RBsyYp4= +github.com/go-git/go-git v4.7.0+incompatible h1:+W9rgGY4DOKKdX2x6HxSR7HNeTxqiKrOvKnuittYVdA= +github.com/go-git/go-git-fixtures/v4 v4.0.1/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= +github.com/go-git/go-git/v5 v5.0.0 h1:k5RWPm4iJwYtfWoxIJy4wJX9ON7ihPeZZYC1fLYDnpg= +github.com/go-git/go-git/v5 v5.0.0/go.mod h1:oYD8y9kWsGINPFJoLdaScGCN6dlKg23blmClfZwtUVA= github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v1.2.0 h1:VJtLvh6VQym50czpZzx07z/kw9EgAxI3x1ZB8taTMQQ= @@ -27,9 +45,15 @@ github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCO github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY= +github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU= github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= @@ -40,10 +64,13 @@ github.com/matryer/moq v0.0.0-20200310130814-7721994d1b54/go.mod h1:9ELz6aaclSIG github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047 h1:zCoDWFD5nrJJVjbXiDZcVhOBSzKn3o9LgRLLMRNuru8= github.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.2.2 h1:dxe5oCinTXiTIcfgmZecdCzPmAJKd46KsCWc35r0TV4= github.com/mitchellh/mapstructure v1.2.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= @@ -55,6 +82,7 @@ github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= @@ -78,9 +106,14 @@ github.com/vektah/gqlparser v1.3.1 h1:8b0IcD3qZKWJQHSzynbDlrtP3IxVydZ2DZepCGofqf github.com/vektah/gqlparser v1.3.1/go.mod h1:bkVf0FX+Stjg/MHnm8mEyubuaArhNEqfQhF+OTiAL74= github.com/vektah/gqlparser/v2 v2.0.1 h1:xgl5abVnsd4hkN9rk65OJID9bfcLSMuTaTcZj777q1o= github.com/vektah/gqlparser/v2 v2.0.1/go.mod h1:SyUiHgLATUR8BiYURfTirrTcGpcE+4XkV2se04Px1Ms= +github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70= +github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 h1:xMPOj6Pz6UipU1wXLkrtqpHbR0AVFnyPEQq/wRWz9lM= +golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -88,13 +121,20 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -108,6 +148,9 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IV golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/graphql/graph/generated/generated.go b/graphql/graph/generated/generated.go index bdc84ae..3895a31 100644 --- a/graphql/graph/generated/generated.go +++ b/graphql/graph/generated/generated.go @@ -82,7 +82,6 @@ type ComplexityRoot struct { Parents func(childComplexity int) int Raw func(childComplexity int) int ShortID func(childComplexity int) int - Timestamp func(childComplexity int) int Tree func(childComplexity int) int Type func(childComplexity int) int } @@ -106,6 +105,7 @@ type ComplexityRoot struct { } Reference struct { + Follow func(childComplexity int) int Name func(childComplexity int) int Target func(childComplexity int) int } @@ -121,7 +121,7 @@ type ComplexityRoot struct { Name func(childComplexity int) int Objects func(childComplexity int, ids []*string) int Owner func(childComplexity int) int - References func(childComplexity int, count *int, glob *string) int + References func(childComplexity int, count *int, next *string, glob *string) int RevparseSingle func(childComplexity int, revspec string) int Tree func(childComplexity int, revspec *string, path *string) int Updated func(childComplexity int) int @@ -199,6 +199,8 @@ type QueryResolver interface { } type RepositoryResolver interface { Owner(ctx context.Context, obj *model.Repository) (model.Entity, error) + + References(ctx context.Context, obj *model.Repository, count *int, next *string, glob *string) ([]*model.Reference, error) } type UserResolver interface { Repositories(ctx context.Context, obj *model.User, count *int, next *int, filter *model.FilterBy) ([]*model.Repository, error) @@ -394,13 +396,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Commit.ShortID(childComplexity), true - case "Commit.timestamp": - if e.complexity.Commit.Timestamp == nil { - break - } - - return e.complexity.Commit.Timestamp(childComplexity), true - case "Commit.tree": if e.complexity.Commit.Tree == nil { break @@ -549,6 +544,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.Version(childComplexity), true + case "Reference.follow": + if e.complexity.Reference.Follow == nil { + break + } + + return e.complexity.Reference.Follow(childComplexity), true + case "Reference.name": if e.complexity.Reference.Name == nil { break @@ -663,7 +665,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Repository.References(childComplexity, args["count"].(*int), args["glob"].(*string)), true + return e.complexity.Repository.References(childComplexity, args["count"].(*int), args["next"].(*string), args["glob"].(*string)), true case "Repository.revparse_single": if e.complexity.Repository.RevparseSingle == nil { @@ -1094,7 +1096,7 @@ type Repository { # # glob: an optional string to filter the list of references, e.g. for tags # use "refs/tags/*", or leave null to enumerate all references - references(count: Int = 10, glob: String): [Reference]! + references(count: Int = 10, next: String, glob: String): [Reference]! # Returns a list of objects for this repository by their IDs (using fully # qualified git object IDs, 40 character hex strings) @@ -1148,6 +1150,7 @@ type Artifact { type Reference { name: String! target: String! + follow: Object } enum ObjectType { @@ -1168,7 +1171,7 @@ interface Object { type Signature { name: String! email: String! - time: Time + time: Time! } type Commit implements Object { @@ -1178,7 +1181,6 @@ type Commit implements Object { raw: String! author: Signature! committer: Signature! - timestamp: Time! message: String! tree: Tree! parents: [Commit!]! @@ -1618,13 +1620,21 @@ func (ec *executionContext) field_Repository_references_args(ctx context.Context } args["count"] = arg0 var arg1 *string - if tmp, ok := rawArgs["glob"]; ok { + if tmp, ok := rawArgs["next"]; ok { arg1, err = ec.unmarshalOString2ᚖstring(ctx, tmp) if err != nil { return nil, err } } - args["glob"] = arg1 + args["next"] = arg1 + var arg2 *string + if tmp, ok := rawArgs["glob"]; ok { + arg2, err = ec.unmarshalOString2ᚖstring(ctx, tmp) + if err != nil { + return nil, err + } + } + args["glob"] = arg2 return args, nil } @@ -2483,13 +2493,13 @@ func (ec *executionContext) _Commit_author(ctx context.Context, field graphql.Co Object: "Commit", Field: field, Args: nil, - IsMethod: false, + IsMethod: true, } ctx = graphql.WithFieldContext(ctx, fc) resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Author, nil + return obj.Author(), nil }) if err != nil { ec.Error(ctx, err) @@ -2517,13 +2527,13 @@ func (ec *executionContext) _Commit_committer(ctx context.Context, field graphql Object: "Commit", Field: field, Args: nil, - IsMethod: false, + IsMethod: true, } ctx = graphql.WithFieldContext(ctx, fc) resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Committer, nil + return obj.Committer(), nil }) if err != nil { ec.Error(ctx, err) @@ -2540,40 +2550,6 @@ func (ec *executionContext) _Commit_committer(ctx context.Context, field graphql return ec.marshalNSignature2ᚖgitᚗsrᚗhtᚋאsircmpwnᚋgitᚗsrᚗhtᚋgraphqlᚋgraphᚋmodelᚐSignature(ctx, field.Selections, res) } -func (ec *executionContext) _Commit_timestamp(ctx context.Context, field graphql.CollectedField, obj *model.Commit) (ret graphql.Marshaler) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - fc := &graphql.FieldContext{ - Object: "Commit", - Field: field, - Args: nil, - IsMethod: false, - } - - ctx = graphql.WithFieldContext(ctx, fc) - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Timestamp, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(time.Time) - fc.Result = res - return ec.marshalNTime2timeᚐTime(ctx, field.Selections, res) -} - func (ec *executionContext) _Commit_message(ctx context.Context, field graphql.CollectedField, obj *model.Commit) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -2585,13 +2561,13 @@ func (ec *executionContext) _Commit_message(ctx context.Context, field graphql.C Object: "Commit", Field: field, Args: nil, - IsMethod: false, + IsMethod: true, } ctx = graphql.WithFieldContext(ctx, fc) resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Message, nil + return obj.Message(), nil }) if err != nil { ec.Error(ctx, err) @@ -3228,13 +3204,13 @@ func (ec *executionContext) _Reference_name(ctx context.Context, field graphql.C Object: "Reference", Field: field, Args: nil, - IsMethod: false, + IsMethod: true, } ctx = graphql.WithFieldContext(ctx, fc) resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Name, nil + return obj.Name(), nil }) if err != nil { ec.Error(ctx, err) @@ -3262,13 +3238,13 @@ func (ec *executionContext) _Reference_target(ctx context.Context, field graphql Object: "Reference", Field: field, Args: nil, - IsMethod: false, + IsMethod: true, } ctx = graphql.WithFieldContext(ctx, fc) resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Target, nil + return obj.Target(), nil }) if err != nil { ec.Error(ctx, err) @@ -3285,6 +3261,37 @@ func (ec *executionContext) _Reference_target(ctx context.Context, field graphql return ec.marshalNString2string(ctx, field.Selections, res) } +func (ec *executionContext) _Reference_follow(ctx context.Context, field graphql.CollectedField, obj *model.Reference) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Reference", + Field: field, + Args: nil, + IsMethod: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Follow(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(model.Object) + fc.Result = res + return ec.marshalOObject2gitᚗsrᚗhtᚋאsircmpwnᚋgitᚗsrᚗhtᚋgraphqlᚋgraphᚋmodelᚐObject(ctx, field.Selections, res) +} + func (ec *executionContext) _Repository_id(ctx context.Context, field graphql.CollectedField, obj *model.Repository) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -3603,7 +3610,7 @@ func (ec *executionContext) _Repository_references(ctx context.Context, field gr Object: "Repository", Field: field, Args: nil, - IsMethod: false, + IsMethod: true, } ctx = graphql.WithFieldContext(ctx, fc) @@ -3616,7 +3623,7 @@ func (ec *executionContext) _Repository_references(ctx context.Context, field gr fc.Args = args resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.References, nil + return ec.resolvers.Repository().References(rctx, obj, args["count"].(*int), args["next"].(*string), args["glob"].(*string)) }) if err != nil { ec.Error(ctx, err) @@ -3685,13 +3692,13 @@ func (ec *executionContext) _Repository_head(ctx context.Context, field graphql. Object: "Repository", Field: field, Args: nil, - IsMethod: false, + IsMethod: true, } ctx = graphql.WithFieldContext(ctx, fc) resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Head, nil + return obj.Head(), nil }) if err != nil { ec.Error(ctx, err) @@ -3952,11 +3959,14 @@ func (ec *executionContext) _Signature_time(ctx context.Context, field graphql.C return graphql.Null } if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } return graphql.Null } - res := resTmp.(*time.Time) + res := resTmp.(time.Time) fc.Result = res - return ec.marshalOTime2ᚖtimeᚐTime(ctx, field.Selections, res) + return ec.marshalNTime2timeᚐTime(ctx, field.Selections, res) } func (ec *executionContext) _Tag_type(ctx context.Context, field graphql.CollectedField, obj *model.Tag) (ret graphql.Marshaler) { @@ -6398,11 +6408,6 @@ func (ec *executionContext) _Commit(ctx context.Context, sel ast.SelectionSet, o if out.Values[i] == graphql.Null { invalids++ } - case "timestamp": - out.Values[i] = ec._Commit_timestamp(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ - } case "message": out.Values[i] = ec._Commit_message(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -6605,6 +6610,8 @@ func (ec *executionContext) _Reference(ctx context.Context, sel ast.SelectionSet if out.Values[i] == graphql.Null { invalids++ } + case "follow": + out.Values[i] = ec._Reference_follow(ctx, field, obj) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -6676,10 +6683,19 @@ func (ec *executionContext) _Repository(ctx context.Context, sel ast.SelectionSe atomic.AddUint32(&invalids, 1) } case "references": - out.Values[i] = ec._Repository_references(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) - } + field := field + out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Repository_references(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + }) case "objects": out.Values[i] = ec._Repository_objects(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -6732,6 +6748,9 @@ func (ec *executionContext) _Signature(ctx context.Context, sel ast.SelectionSet } case "time": out.Values[i] = ec._Signature_time(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/graphql/graph/model/models_gen.go b/graphql/graph/model/models_gen.go index 0567351..76fa674 100644 --- a/graphql/graph/model/models_gen.go +++ b/graphql/graph/model/models_gen.go @@ -13,10 +13,6 @@ type Entity interface { IsEntity() } -type Object interface { - IsObject() -} - type ACL struct { ID int `json:"id"` Created time.Time `json:"created"` @@ -46,21 +42,6 @@ type Blob struct { func (Blob) IsObject() {} -type Commit struct { - Type ObjectType `json:"type"` - ID string `json:"id"` - ShortID string `json:"shortId"` - Raw string `json:"raw"` - Author *Signature `json:"author"` - Committer *Signature `json:"committer"` - Timestamp time.Time `json:"timestamp"` - Message string `json:"message"` - Tree *Tree `json:"tree"` - Parents []*Commit `json:"parents"` -} - -func (Commit) IsObject() {} - type EntityID struct { ID *int `json:"id"` CanonicalName *string `json:"canonicalName"` @@ -75,11 +56,6 @@ type OwnerRepo struct { RepoName *string `json:"repoName"` } -type Reference struct { - Name string `json:"name"` - Target string `json:"target"` -} - type RepoID struct { ID *int `json:"id"` OwnerRepo *OwnerRepo `json:"ownerRepo"` @@ -92,9 +68,9 @@ type RepoInput struct { } type Signature struct { - Name string `json:"name"` - Email string `json:"email"` - Time *time.Time `json:"time"` + Name string `json:"name"` + Email string `json:"email"` + Time time.Time `json:"time"` } type Tag struct { diff --git a/graphql/graph/model/object.go b/graphql/graph/model/object.go new file mode 100644 index 0000000..5d3366b --- /dev/null +++ b/graphql/graph/model/object.go @@ -0,0 +1,66 @@ +package model + +import ( + "errors" + "fmt" + + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing" + "github.com/go-git/go-git/v5/plumbing/object" +) + +type Object interface { + IsObject() +} + +func LookupObject(repo *git.Repository, hash plumbing.Hash) (Object, error) { + obj, err := repo.Object(plumbing.AnyObject, hash) + if err != nil { + return nil, fmt.Errorf("lookup object %s: %w", hash.String(), err) + } + switch obj := obj.(type) { + case *object.Commit: + return &Commit{ + Type: ObjectTypeCommit, + ID: obj.ID().String(), + ShortID: obj.ID().String()[:7], + + commit: obj, + }, nil + default: + return nil, errors.New("Unknown object type") + } +} + +type Commit struct { + Type ObjectType `json:"type"` + ID string `json:"id"` + ShortID string `json:"shortId"` + Raw string `json:"raw"` + Tree *Tree `json:"tree"` + Parents []*Commit `json:"parents"` + + commit *object.Commit +} + +func (Commit) IsObject() {} + +func (c *Commit) Message() string { + return c.commit.Message +} + +func (c *Commit) Author() *Signature { + return &Signature{ + Name: c.commit.Author.Name, + Email: c.commit.Author.Email, + Time: c.commit.Author.When, + } +} + +func (c *Commit) Committer() *Signature { + return &Signature{ + Name: c.commit.Committer.Name, + Email: c.commit.Committer.Email, + Time: c.commit.Committer.When, + } +} diff --git a/graphql/graph/model/reference.go b/graphql/graph/model/reference.go new file mode 100644 index 0000000..54e6d9b --- /dev/null +++ b/graphql/graph/model/reference.go @@ -0,0 +1,35 @@ +package model + +import ( + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing" +) + +type Reference struct { + Repo *git.Repository + Ref *plumbing.Reference +} + +func (r *Reference) Follow() Object { + ref, err := r.Repo.Reference(r.Ref.Name(), true) + if err != nil { + panic(err) + } + obj, err := LookupObject(r.Repo, ref.Hash()) + if err != nil { + panic(err) + } + return obj +} + +func (r *Reference) Name() string { + return string(r.Ref.Name()) +} + +func (r *Reference) Target() string { + if r.Ref.Type() == plumbing.HashReference { + return r.Ref.Hash().String() + } else { + return string(r.Ref.Target()) + } +} diff --git a/graphql/graph/model/repository.go b/graphql/graph/model/repository.go index ac55f46..f0ce498 100644 --- a/graphql/graph/model/repository.go +++ b/graphql/graph/model/repository.go @@ -1,6 +1,10 @@ package model -import "time" +import ( + "time" + + "github.com/go-git/go-git/v5" +) type Repository struct { ID int `json:"id"` @@ -11,9 +15,7 @@ type Repository struct { Visibility Visibility `json:"visibility"` UpstreamURL *string `json:"upstreamUrl"` AccessControlList []*ACL `json:"accessControlList"` - References []*Reference `json:"references"` Objects []Object `json:"objects"` - Head *Reference `json:"head"` Log []*Commit `json:"log"` Tree *Tree `json:"tree"` File *Blob `json:"file"` @@ -21,4 +23,26 @@ type Repository struct { Path string OwnerID int + + repo *git.Repository +} + +func (r *Repository) Repo() *git.Repository { + if r.repo != nil { + return r.repo + } + var err error + r.repo, err = git.PlainOpen(r.Path) + if err != nil { + panic(err) + } + return r.repo +} + +func (r *Repository) Head() *Reference { + ref, err := r.Repo().Head() + if err != nil { + panic(err) + } + return &Reference{Ref: ref, Repo: r.repo} } diff --git a/graphql/graph/schema.graphqls b/graphql/graph/schema.graphqls index 5f5693b..055e1c4 100644 --- a/graphql/graph/schema.graphqls +++ b/graphql/graph/schema.graphqls @@ -82,7 +82,7 @@ type Repository { # # glob: an optional string to filter the list of references, e.g. for tags # use "refs/tags/*", or leave null to enumerate all references - references(count: Int = 10, glob: String): [Reference]! + references(count: Int = 10, next: String, glob: String): [Reference]! # Returns a list of objects for this repository by their IDs (using fully # qualified git object IDs, 40 character hex strings) @@ -136,6 +136,7 @@ type Artifact { type Reference { name: String! target: String! + follow: Object } enum ObjectType { @@ -156,7 +157,7 @@ interface Object { type Signature { name: String! email: String! - time: Time + time: Time! } type Commit implements Object { @@ -166,7 +167,6 @@ type Commit implements Object { raw: String! author: Signature! committer: Signature! - timestamp: Time! message: String! tree: Tree! parents: [Commit!]! diff --git a/graphql/graph/schema.resolvers.go b/graphql/graph/schema.resolvers.go index 9d66664..155e8d9 100644 --- a/graphql/graph/schema.resolvers.go +++ b/graphql/graph/schema.resolvers.go @@ -7,12 +7,14 @@ import ( "context" "database/sql" "fmt" + "sort" "git.sr.ht/~sircmpwn/git.sr.ht/graphql/auth" "git.sr.ht/~sircmpwn/git.sr.ht/graphql/graph/generated" "git.sr.ht/~sircmpwn/git.sr.ht/graphql/graph/model" "git.sr.ht/~sircmpwn/git.sr.ht/graphql/loaders" "git.sr.ht/~sircmpwn/gqlgen/graphql" + "github.com/go-git/go-git/v5/plumbing" ) func (r *mutationResolver) CreateRepository(ctx context.Context, params *model.RepoInput) (*model.Repository, error) { @@ -82,6 +84,37 @@ func (r *repositoryResolver) Owner(ctx context.Context, obj *model.Repository) ( return loaders.ForContext(ctx).UsersById.Load(obj.OwnerID) } +func (r *repositoryResolver) References(ctx context.Context, obj *model.Repository, count *int, next *string, glob *string) ([]*model.Reference, error) { + iter, err := obj.Repo().References() + if err != nil { + return nil, err + } + defer iter.Close() + var refs []*model.Reference + iter.ForEach(func(ref *plumbing.Reference) error { + refs = append(refs, &model.Reference{obj.Repo(), ref}) + return nil + }) + sort.SliceStable(refs, func(i, j int) bool { + return refs[i].Name() < refs[j].Name() + }) + if next != nil { + for i, ref := range refs { + if ref.Name() == *next { + refs = refs[i+1:] + if len(refs) > *count { + refs = refs[:*count] + } + return refs, nil + } + } + } + if len(refs) > *count { + refs = refs[:*count] + } + return refs, nil +} + func (r *userResolver) Repositories(ctx context.Context, obj *model.User, count *int, next *int, filter *model.FilterBy) ([]*model.Repository, error) { var ( err error -- 2.38.4