~sircmpwn/sr.ht-dev

lists.sr.ht: api/graph: use GraphQL descriptions for docs v1 APPLIED

Simon Ser: 3
 api/graph: use GraphQL descriptions for docs
 go fmt
 api: import github.com/99designs/gqlgen

 5 files changed, 201 insertions(+), 140 deletions(-)
#658411 alpine.yml success
#658412 archlinux.yml success
#658413 debian.yml success
lists.sr.ht/patches: SUCCESS in 2m30s

[api/graph: use GraphQL descriptions for docs][0] from [Simon Ser][1]

[0]: https://lists.sr.ht/~sircmpwn/sr.ht-dev/patches/27721
[1]: mailto:contact@emersion.fr

✓ #658411 SUCCESS lists.sr.ht/patches/alpine.yml    https://builds.sr.ht/~sircmpwn/job/658411
✓ #658413 SUCCESS lists.sr.ht/patches/debian.yml    https://builds.sr.ht/~sircmpwn/job/658413
✓ #658412 SUCCESS lists.sr.ht/patches/archlinux.yml https://builds.sr.ht/~sircmpwn/job/658412
Thanks!

To git@git.sr.ht:~sircmpwn/lists.sr.ht
   64835fe..9978365  master -> master
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~sircmpwn/sr.ht-dev/patches/27721/mbox | git am -3
Learn more about email & git

[PATCH lists.sr.ht 1/3] api/graph: use GraphQL descriptions for docs Export this patch

---
 api/graph/schema.graphqls | 283 ++++++++++++++++++++++----------------
 1 file changed, 162 insertions(+), 121 deletions(-)

diff --git a/api/graph/schema.graphqls b/api/graph/schema.graphqls
index e53d33012983..e02396bb3ea9 100644
--- a/api/graph/schema.graphqls
+++ b/api/graph/schema.graphqls
@@ -1,18 +1,20 @@
# This schema definition is available in the public domain, or under the terms
# of CC-0, at your choice.

# String of the format %Y-%m-%dT%H:%M:%SZ
"String of the format %Y-%m-%dT%H:%M:%SZ"
scalar Time
# Opaque string
"Opaque string"
scalar Cursor
# URL from which some secondary data may be retrieved. You must provide the
# same Authentication header to this address as you did to the GraphQL resolver
# which provided it. The URL is not guaranteed to be consistent for an extended
# length of time; applications should submit a new GraphQL query each time they
# wish to access the data at the provided URL.
"""
URL from which some secondary data may be retrieved. You must provide the
same Authentication header to this address as you did to the GraphQL resolver
which provided it. The URL is not guaranteed to be consistent for an extended
length of time; applications should submit a new GraphQL query each time they
wish to access the data at the provided URL.
"""
scalar URL

# Used to provide a human-friendly description of an access scope
"Used to provide a human-friendly description of an access scope"
directive @scopehelp(details: String!) on ENUM_VALUE

enum AccessScope {
@@ -29,8 +31,10 @@ enum AccessKind {
  RW @scopehelp(details: "read and write")
}

# Decorates fields for which access requires a particular OAuth 2.0 scope with
# read or write access.
"""
Decorates fields for which access requires a particular OAuth 2.0 scope with
read or write access.
"""
directive @access(scope: AccessScope!, kind: AccessKind!) on FIELD_DEFINITION

# https://semver.org
@@ -39,9 +43,11 @@ type Version {
  minor: Int!
  patch: Int!

  # If this API version is scheduled for deprecation, this is the date on which
  # it will stop working; or null if this API version is not scheduled for
  # deprecation.
  """
  If this API version is scheduled for deprecation, this is the date on which
  it will stop working; or null if this API version is not scheduled for
  deprecation.
  """
  deprecationDate: Time
}

@@ -49,7 +55,7 @@ interface Entity {
  canonicalName: String!
}

# A registered user
"A registered user"
type User implements Entity {
  id: Int!
  created: Time!
@@ -67,7 +73,7 @@ type User implements Entity {
  patches(cursor: Cursor): PatchsetCursor @access(scope: PATCHES, kind: RO)
}

# A mailbox not associated with a registered user
"A mailbox not associated with a registered user"
type Mailbox implements Entity {
  canonicalName: String!
  name: String!
@@ -84,57 +90,61 @@ type MailingList {
  # Markdown
  description: String

  # List of globs for permitted or rejected mimetypes on this list
  # e.g. text/*
  """
  List of globs for permitted or rejected mimetypes on this list
  e.g. text/*
  """
  permitMime: [String!]!
  rejectMime: [String!]!

  # List of threads on this list in order of most recently bumped
  "List of threads on this list in order of most recently bumped"
  threads(cursor: Cursor): ThreadCursor! @access(scope: EMAILS, kind: RO)
  # List of emails received on this list in reverse chronological order
  "List of emails received on this list in reverse chronological order"
  emails(cursor: Cursor): EmailCursor! @access(scope: EMAILS, kind: RO)
  # List of patches received on this list in order of most recently bumped
  "List of patches received on this list in order of most recently bumped"
  patches(cursor: Cursor): PatchsetCursor! @access(scope: PATCHES, kind: RO)

  # True if an import operation is underway for this list
  "True if an import operation is underway for this list"
  importing: Boolean!

  # The access that applies to this user for this list
  "The access that applies to this user for this list"
  access: ACL! @access(scope: ACLS, kind: RO)

  # The user's subscription for this list, if any
  "The user's subscription for this list, if any"
  subscription: Subscription @access(scope: SUBSCRIPTIONS, kind: RO)

  # URLs to application/mbox archives for this mailing list
  "URLs to application/mbox archives for this mailing list"
  archive: URL!
  last30days: URL!

  #
  # The following resolvers are only available to the list owner:

  # Access control list entries for this mailing list
  "Access control list entries for this mailing list"
  acl(cursor: Cursor): MailingListACLCursor! @access(scope: ACLS, kind: RO)
  # Permissions which apply to any non-subscriber
  "Permissions which apply to any non-subscriber"
  nonsubscriber: GeneralACL!
  # Permissions which apply to any subscriber
  "Permissions which apply to any subscriber"
  subscriber: GeneralACL!
  # Permissions which apply to any authenticated account holder
  "Permissions which apply to any authenticated account holder"
  identified: GeneralACL!
}

interface ACL {
  # Permission to browse or subscribe to emails
  "Permission to browse or subscribe to emails"
  browse: Boolean!
  # Permission to reply to existing threads
  "Permission to reply to existing threads"
  reply: Boolean!
  # Permission to start new threads
  "Permission to start new threads"
  post: Boolean!
  # Permission to moderate the list
  "Permission to moderate the list"
  moderate: Boolean!
}

# These ACLs are configured for specific entities, and may be used to expand or
# constrain the rights of a participant.
"""
These ACLs are configured for specific entities, and may be used to expand or
constrain the rights of a participant.
"""
type MailingListACL implements ACL {
  id: Int!
  created: Time!
@@ -147,8 +157,10 @@ type MailingListACL implements ACL {
  moderate: Boolean!
}

# An ACL entry that applies "generally", for example the rights which apply to
# all subscribers to a list.
"""
An ACL entry that applies "generally", for example the rights which apply to
all subscribers to a list.
"""
type GeneralACL implements ACL {
  browse: Boolean!
  reply: Boolean!
@@ -168,42 +180,46 @@ type Thread {

  list: MailingList! @access(scope: LISTS, kind: RO)

  # Replies to this thread, in chronological order
  "Replies to this thread, in chronological order"
  descendants(cursor: Cursor): EmailCursor!

  # A mailto: URI for replying to the latest message in this thread
  "A mailto: URI for replying to the latest message in this thread"
  mailto: String!

  # URL to an application/mbox archive of this thread
  "URL to an application/mbox archive of this thread"
  mbox: URL!
}

type Email {
  id: Int!

  # The entity which sent this email. Will be a User if it can be associated
  # with an account, or a Mailbox otherwise.
  """
  The entity which sent this email. Will be a User if it can be associated
  with an account, or a Mailbox otherwise.
  """
  sender: Entity!
  # Time we received this email (non-forgable).
  "Time we received this email (non-forgable)."
  received: Time!
  # Time given by Date header (forgable).
  "Time given by Date header (forgable)."
  date: Time
  # The Subject header.
  "The Subject header."
  subject: String!
  # The Message-ID header, without angle brackets.
  "The Message-ID header, without angle brackets."
  messageID: String!
  # The In-Reply-To header, if present, without angle brackets.
  "The In-Reply-To header, if present, without angle brackets."
  inReplyTo: String

  # Provides the value (or values) of a specific header from this email. Note
  # that the returned value is coerced to UTF-8 and may be lossy under certain
  # circumstances.
  """
  Provides the value (or values) of a specific header from this email. Note
  that the returned value is coerced to UTF-8 and may be lossy under certain
  circumstances.
  """
  header(want: String!): [String!]!
  # Retrieves the value of an address list header, such as To or Cc.
  "Retrieves the value of an address list header, such as To or Cc."
  addressList(want: String!): [Mailbox!]!
  # The decoded text/plain message part of the email, i.e. email body.
  "The decoded text/plain message part of the email, i.e. email body."
  body: String!
  # A URL from which the full raw message envelope may be downloaded.
  "A URL from which the full raw message envelope may be downloaded."
  envelope: URL!

  thread: Thread!
@@ -214,17 +230,19 @@ type Email {
  list: MailingList! @access(scope: LISTS, kind: RO)
}

# Information parsed from the subject line of a patch, such that the following:
#
#   [PATCH myproject v2 3/4] Add foo to bar
#
# Will produce:
#
# index: 3
# count: 4
# version: 2
# prefix: "myproject"
# subject: "Add foo to bar"
"""
Information parsed from the subject line of a patch, such that the following:

    [PATCH myproject v2 3/4] Add foo to bar

Will produce:

    index: 3
    count: 4
    version: 2
    prefix: "myproject"
    subject: "Add foo to bar"
"""
type Patch {
  index: Int
  count: Int
@@ -260,7 +278,7 @@ type Patchset {
  patches(cursor: Cursor): EmailCursor! @access(scope: EMAILS, kind: RO)
  tools: [PatchsetTool!]!

  # URL to an application/mbox archive of only the patches in this thread
  "URL to an application/mbox archive of only the patches in this thread"
  mbox: URL!
}

@@ -272,8 +290,10 @@ enum ToolIcon {
  CANCELLED
}

# Used to add some kind of indicator for a third-party process associated with
# a patchset, such as a CI service validating the change.
"""
Used to add some kind of indicator for a third-party process associated with
a patchset, such as a CI service validating the change.
"""
type PatchsetTool {
  id: Int!
  created: Time!
@@ -294,94 +314,108 @@ type MailingListSubscription implements Subscription {
  list: MailingList! @access(scope: LISTS, kind: RO)
}

# A cursor for enumerating ACL entries
#
# If there are additional results available, the cursor object may be passed
# back into the same endpoint to retrieve another page. If the cursor is null,
# there are no remaining results to return.
"""
A cursor for enumerating ACL entries

If there are additional results available, the cursor object may be passed
back into the same endpoint to retrieve another page. If the cursor is null,
there are no remaining results to return.
"""
type MailingListACLCursor {
  results: [MailingListACL!]!
  cursor: Cursor
}

# A cursor for enumerating mailing lists
#
# If there are additional results available, the cursor object may be passed
# back into the same endpoint to retrieve another page. If the cursor is null,
# there are no remaining results to return.
"""
A cursor for enumerating mailing lists

If there are additional results available, the cursor object may be passed
back into the same endpoint to retrieve another page. If the cursor is null,
there are no remaining results to return.
"""
type MailingListCursor {
  results: [MailingList!]!
  cursor: Cursor
}

# A cursor for enumerating threads
#
# If there are additional results available, the cursor object may be passed
# back into the same endpoint to retrieve another page. If the cursor is null,
# there are no remaining results to return.
"""
A cursor for enumerating threads

If there are additional results available, the cursor object may be passed
back into the same endpoint to retrieve another page. If the cursor is null,
there are no remaining results to return.
"""
type ThreadCursor {
  results: [Thread!]!
  cursor: Cursor
}

# A cursor for enumerating emails
#
# If there are additional results available, the cursor object may be passed
# back into the same endpoint to retrieve another page. If the cursor is null,
# there are no remaining results to return.
"""
A cursor for enumerating emails

If there are additional results available, the cursor object may be passed
back into the same endpoint to retrieve another page. If the cursor is null,
there are no remaining results to return.
"""
type EmailCursor {
  results: [Email!]!
  cursor: Cursor
}

# A cursor for enumerating patchsets
#
# If there are additional results available, the cursor object may be passed
# back into the same endpoint to retrieve another page. If the cursor is null,
# there are no remaining results to return.
"""
A cursor for enumerating patchsets

If there are additional results available, the cursor object may be passed
back into the same endpoint to retrieve another page. If the cursor is null,
there are no remaining results to return.
"""
type PatchsetCursor {
  results: [Patchset!]!
  cursor: Cursor
}

# A cursor for enumerating subscriptions
#
# If there are additional results available, the cursor object may be passed
# back into the same endpoint to retrieve another page. If the cursor is null,
# there are no remaining results to return.
"""
A cursor for enumerating subscriptions

If there are additional results available, the cursor object may be passed
back into the same endpoint to retrieve another page. If the cursor is null,
there are no remaining results to return.
"""
type SubscriptionCursor {
  results: [Subscription!]!
  cursor: Cursor
}

type Query {
  # Returns API version information
  "Returns API version information"
  version: Version!

  # Returns the authenticated user
  "Returns the authenticated user"
  me: User! @access(scope: PROFILE, kind: RO)

  # Looks up a specific user
  "Looks up a specific user"
  user(id: Int!): User @access(scope: PROFILE, kind: RO)
  userByName(username: String!): User @access(scope: PROFILE, kind: RO)

  # Looks up a specific mailing list
  "Looks up a specific mailing list"
  mailingList(id: Int!): MailingList @access(scope: LISTS, kind: RO)
  mailingListByName(name: String!): MailingList @access(scope: LISTS, kind: RO)
  mailingListByOwner(ownerName: String!, listName: String!): MailingList @access(scope: LISTS, kind: RO)

  # Looks up a specific email by its ID
  "Looks up a specific email by its ID"
  email(id: Int!): Email @access(scope: EMAILS, kind: RO)
  # Looks up a specific email by its Message-ID header, including the angle
  # brackets ('<' and '>').
  """
  Looks up a specific email by its Message-ID header, including the angle
  brackets ('<' and '>').
  """
  message(messageID: String!): Email @access(scope: EMAILS, kind: RO)
  # Looks up a patchset by ID
  "Looks up a patchset by ID"
  patchset(id: Int!): Patchset @access(scope: EMAILS, kind: RO)

  # List of mailing lists that the authenticated user has ownership of
  "List of mailing lists that the authenticated user has ownership of"
  mailingLists(cursor: Cursor): MailingListCursor! @access(scope: LISTS, kind: RO)

  # List of subscriptions of the authenticated user
  "List of subscriptions of the authenticated user"
  subscriptions(cursor: Cursor): SubscriptionCursor @access(scope: SUBSCRIPTIONS, kind: RO)
}

@@ -390,8 +424,10 @@ type Query {
input MailingListInput {
  description: String

  # List of globs for permitted or rejected mimetypes on this list
  # e.g. text/*
  """
  List of globs for permitted or rejected mimetypes on this list
  e.g. text/*
  """
  permitMime: [String!]
  rejectMime: [String!]
}
@@ -405,52 +441,57 @@ input ACLInput {
}

type Mutation {
  # Creates a new mailing list
  "Creates a new mailing list"
  createMailingList(
    name: String!,
    description: String): MailingList! @access(scope: LISTS, kind: RW)

  # Updates a mailing list.
  "Updates a mailing list."
  updateMailingList(
    id: Int!,
    input: MailingListInput!): MailingList @access(scope: LISTS, kind: RW)

  # Deletes a mailing list
  "Deletes a mailing list"
  deleteMailingList(id: Int!): MailingList @access(scope: LISTS, kind: RW)

  # Adds or updates the ACL for a user on a mailing list
  "Adds or updates the ACL for a user on a mailing list"
  updateUserACL(
    listID: Int!,
    userID: Int!,
    input: ACLInput!): MailingListACL @access(scope: ACLS, kind: RW)

  # Adds or updates the ACL for an email address on a mailing list
  "Adds or updates the ACL for an email address on a mailing list"
  updateSenderACL(
    listID: Int!,
    address: String!,
    input: ACLInput!): MailingListACL @access(scope: ACLS, kind: RW)

  # Updates the default ACL for a mailing list, which applies to users and
  # senders for whom a more specific ACL does not exist.
  """
  Updates the default ACL for a mailing list, which applies to users and
  senders for whom a more specific ACL does not exist.
  """
  updateMailingListACL(
    listID: Int!,
    input: ACLInput!): MailingList @access(scope: ACLS, kind: RW)

  # Removes a mailing list ACL. Following this, the default mailing list ACL will apply to this user.
  """
  Removes a mailing list ACL. Following this, the default mailing list ACL will
  apply to this user.
  """
  deleteACL(id: Int!): MailingListACL @access(scope: ACLS, kind: RW)

  # Updates the status of a patchset
  "Updates the status of a patchset"
  updatePatchset(id: Int!, status: PatchsetStatus!): Patchset @access(scope: PATCHES, kind: RW)

  # Create a new patchset tool
  "Create a new patchset tool"
  createTool(patchsetID: Int!, details: String!, icon: ToolIcon!): PatchsetTool @access(scope: PATCHES, kind: RW)

  # Updates the status of a patchset tool by its ID
  "Updates the status of a patchset tool by its ID"
  updateTool(id: Int!, details: String, icon: ToolIcon): PatchsetTool @access(scope: PATCHES, kind: RW)

  # Creates a mailing list subscription
  "Creates a mailing list subscription"
  mailingListSubscribe(listID: Int!): MailingListSubscription @access(scope: SUBSCRIPTIONS, kind: RW)

  # Deletes a mailing list subscription
  "Deletes a mailing list subscription"
  mailingListUnsubscribe(listID: Int!): MailingListSubscription @access(scope: SUBSCRIPTIONS, kind: RW)
}
-- 
2.34.1

[PATCH lists.sr.ht 2/3] go fmt Export this patch

---
 api/webhooks/legacy.go | 34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/api/webhooks/legacy.go b/api/webhooks/legacy.go
index 0bf2c95ebe44..0b497eb510bd 100644
--- a/api/webhooks/legacy.go
+++ b/api/webhooks/legacy.go
@@ -29,11 +29,11 @@ func encodePermissions(bits uint) []string {
}

type ListWebhookPayload struct {
	ID            int       `json:"id"`
	Name          string    `json:"name"`
	Created       time.Time `json:"created"`
	Updated       time.Time `json:"created"`
	Description   *string   `json:"description"`
	ID          int       `json:"id"`
	Name        string    `json:"name"`
	Created     time.Time `json:"created"`
	Updated     time.Time `json:"created"`
	Description *string   `json:"description"`

	Permissions struct {
		Nonsubscriber []string `json:"nonsubscriber"`
@@ -42,8 +42,8 @@ type ListWebhookPayload struct {
	} `json:"permissions"`

	Owner struct {
		CanonicalName string  `json:"canonical_name"`
		Name          string  `json:"name"`
		CanonicalName string `json:"canonical_name"`
		Name          string `json:"name"`
	} `json:"owner"`
}

@@ -54,11 +54,11 @@ func DeliverLegacyUserListEvent(
) {
	queue := LegacyQueueForContext(ctx)

	payload := ListWebhookPayload {
		ID: list.ID,
		Name: list.Name,
		Created: list.Created,
		Updated: list.Updated,
	payload := ListWebhookPayload{
		ID:          list.ID,
		Name:        list.Name,
		Created:     list.Created,
		Updated:     list.Updated,
		Description: list.Description,
	}
	payload.Permissions.Nonsubscriber = encodePermissions(list.RawNonsubscriber)
@@ -92,11 +92,11 @@ func DeliverLegacyListEvent(
) {
	queue := LegacyQueueForContext(ctx)

	payload := ListWebhookPayload {
		ID: list.ID,
		Name: list.Name,
		Created: list.Created,
		Updated: list.Updated,
	payload := ListWebhookPayload{
		ID:          list.ID,
		Name:        list.Name,
		Created:     list.Created,
		Updated:     list.Updated,
		Description: list.Description,
	}
	payload.Permissions.Nonsubscriber = encodePermissions(list.RawNonsubscriber)
-- 
2.34.1

[PATCH lists.sr.ht 3/3] api: import github.com/99designs/gqlgen Export this patch

Create a new generate.go file which imports github.com/99designs/gqlgen.
This fixes this kind of error because go mod now knows about the
dependency:

    /home/simon/go/pkg/mod/github.com/99designs/gqlgen@v0.13.0/cmd/gen.go:9:2: missing go.sum entry for module providing package github.com/urfave/cli/v2 (imported by github.com/99designs/gqlgen/cmd); to add:
    	go get github.com/99designs/gqlgen/cmd@v0.13.0
    /home/simon/go/pkg/mod/github.com/99designs/gqlgen@v0.13.0/internal/imports/prune.go:15:2: missing go.sum entry for module providing package golang.org/x/tools/go/ast/astutil (imported by github.com/99designs/gqlgen/internal/imports); to add:
    	go get github.com/99designs/gqlgen/internal/imports@v0.13.0
    /home/simon/go/pkg/mod/github.com/99designs/gqlgen@v0.13.0/internal/code/packages.go:8:2: missing go.sum entry for module providing package golang.org/x/tools/go/packages (imported by github.com/99designs/gqlgen/internal/code); to add:
    	go get github.com/99designs/gqlgen/internal/code@v0.13.0
    /home/simon/go/pkg/mod/github.com/99designs/gqlgen@v0.13.0/internal/imports/prune.go:16:2: missing go.sum entry for module providing package golang.org/x/tools/imports (imported by github.com/99designs/gqlgen/internal/imports); to add:
    	go get github.com/99designs/gqlgen/internal/imports@v0.13.0
    graph/resolver.go:7: running "go": exit status 1
    missing go.sum entry for module providing package github.com/vektah/dataloaden; to add:
    	go mod download github.com/vektah/dataloaden
    loaders/middleware.go:3: running "./gen": exit status 1
---
 api/go.sum            | 12 ++++++++++++
 api/graph/generate.go | 10 ++++++++++
 api/graph/resolver.go |  2 --
 3 files changed, 22 insertions(+), 2 deletions(-)
 create mode 100644 api/graph/generate.go

diff --git a/api/go.sum b/api/go.sum
index 5b19a4bd1853..a39805758c47 100644
--- a/api/go.sum
+++ b/api/go.sum
@@ -75,6 +75,7 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
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/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -202,8 +203,10 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
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 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw=
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o=
@@ -212,6 +215,7 @@ github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6Fm
github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg=
github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007 h1:reVOUXwnhsYv/8UqjvhrMOu5CNT9UapHFLbQ2JcXsmg=
github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ=
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=
@@ -243,6 +247,7 @@ github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKw
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -269,11 +274,13 @@ github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
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=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
@@ -288,9 +295,11 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/urfave/cli/v2 v2.1.1 h1:Qt8FeAtxE/vfdrLmR3rxR6JRE0RoVmbXu8+6kZtYU4k=
github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec h1:DGmKwyZwEB8dI7tbLt/I/gQuP559o/0FrAkHKlQM/Ks=
github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec/go.mod h1:owBmyHYMLkxyrugmfwE/DLJyW8Ro9mkphwuVErQ0iUw=
github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e h1:+w0Zm/9gaWpEAyDlU1eKOuk5twTjAjuevXqcJJw8hrg=
github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e/go.mod h1:/HUdMve7rvxZma+2ZELQeNh88+003LL7Pf/CZ089j8U=
github.com/vektah/gqlparser v1.3.1 h1:8b0IcD3qZKWJQHSzynbDlrtP3IxVydZ2DZepCGofqfU=
github.com/vektah/gqlparser v1.3.1/go.mod h1:bkVf0FX+Stjg/MHnm8mEyubuaArhNEqfQhF+OTiAL74=
@@ -343,6 +352,7 @@ golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -498,6 +508,7 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a h1:CB3a9Nez8M13wwlr/E2YtwoU+qYHKfC+JrDa45RXXoQ=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -584,6 +595,7 @@ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
diff --git a/api/graph/generate.go b/api/graph/generate.go
new file mode 100644
index 000000000000..89051a7c3b31
--- /dev/null
+++ b/api/graph/generate.go
@@ -0,0 +1,10 @@
//go:build generate
// +build generate

package graph

import (
	_ "github.com/99designs/gqlgen"
)

//go:generate go run github.com/99designs/gqlgen
diff --git a/api/graph/resolver.go b/api/graph/resolver.go
index b5512ba930f4..fa29d83167e3 100644
--- a/api/graph/resolver.go
+++ b/api/graph/resolver.go
@@ -6,8 +6,6 @@ import (
	"git.sr.ht/~sircmpwn/lists.sr.ht/api/graph/model"
)

//go:generate go run github.com/99designs/gqlgen

type Resolver struct{}

var (
-- 
2.34.1
lists.sr.ht/patches: SUCCESS in 2m30s

[api/graph: use GraphQL descriptions for docs][0] from [Simon Ser][1]

[0]: https://lists.sr.ht/~sircmpwn/sr.ht-dev/patches/27721
[1]: mailto:contact@emersion.fr

✓ #658411 SUCCESS lists.sr.ht/patches/alpine.yml    https://builds.sr.ht/~sircmpwn/job/658411
✓ #658413 SUCCESS lists.sr.ht/patches/debian.yml    https://builds.sr.ht/~sircmpwn/job/658413
✓ #658412 SUCCESS lists.sr.ht/patches/archlinux.yml https://builds.sr.ht/~sircmpwn/job/658412
Thanks!

To git@git.sr.ht:~sircmpwn/lists.sr.ht
   64835fe..9978365  master -> master