]> git.bundesbrandschatzamt.de Git - emacsconfig.git/commitdiff
update ghub
authorAndreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
Thu, 31 Oct 2019 15:54:29 +0000 (16:54 +0100)
committerAndreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
Thu, 31 Oct 2019 15:54:29 +0000 (16:54 +0100)
21 files changed:
elpa/ghub-20190121.2116/buck.el [deleted file]
elpa/ghub-20190121.2116/dir [deleted file]
elpa/ghub-20190121.2116/ghub-autoloads.el [deleted file]
elpa/ghub-20190121.2116/ghub-graphql.el [deleted file]
elpa/ghub-20190121.2116/ghub-pkg.el [deleted file]
elpa/ghub-20190121.2116/ghub.el [deleted file]
elpa/ghub-20190121.2116/ghub.info [deleted file]
elpa/ghub-20190121.2116/glab.el [deleted file]
elpa/ghub-20190121.2116/gogs.el [deleted file]
elpa/ghub-20190121.2116/gtea.el [deleted file]
elpa/ghub-20191007.1420/buck.el [new file with mode: 0644]
elpa/ghub-20191007.1420/dir [new file with mode: 0644]
elpa/ghub-20191007.1420/ghub-autoloads.el [new file with mode: 0644]
elpa/ghub-20191007.1420/ghub-graphql.el [new file with mode: 0644]
elpa/ghub-20191007.1420/ghub-pkg.el [new file with mode: 0644]
elpa/ghub-20191007.1420/ghub.el [new file with mode: 0644]
elpa/ghub-20191007.1420/ghub.info [new file with mode: 0644]
elpa/ghub-20191007.1420/glab.el [new file with mode: 0644]
elpa/ghub-20191007.1420/gogs.el [new file with mode: 0644]
elpa/ghub-20191007.1420/gsexp.el [new file with mode: 0644]
elpa/ghub-20191007.1420/gtea.el [new file with mode: 0644]

diff --git a/elpa/ghub-20190121.2116/buck.el b/elpa/ghub-20190121.2116/buck.el
deleted file mode 100644 (file)
index 94e7d81..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-;;; buck.el --- minuscule client library for the Bitbucket API  -*- lexical-binding: t -*-
-
-;; Copyright (C) 2016-2019  Jonas Bernoulli
-
-;; Author: Jonas Bernoulli <jonasNOSPAMbernoul.li>
-;; Homepage: https://github.com/magit/ghub
-;; Keywords: tools
-
-;; This file is not part of GNU Emacs.
-
-;; This file is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
-
-;; This file is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; For a copy of the GPL see https://www.gnu.org/licenses/gpl.txt.
-
-;;; Commentary:
-
-;; Buck is a library that provides basic support for using the Bitbucket API
-;; from Emacs packages.  It abstracts access to API resources using only
-;; a handful of functions that are not resource-specific.
-
-;; This library is implemented on top of Ghub.  Unlike Ghub, Buck does
-;; not support the guided creation of tokens because Bitbucket lacks the
-;; features that would be necessary to implement that.  Users have to
-;; create tokens through the web interface.
-
-;;; Code:
-
-(require 'ghub)
-
-(defconst buck-default-host "api.bitbucket.org/2.0"
-  "The default host that is used if `buck.host' is not set.")
-
-;; HEAD and PATCH are not supported according to
-;; https://developer.atlassian.com/bitbucket/api/2/reference/meta/uri-uuid
-
-(cl-defun buck-get (resource &optional params
-                             &key query payload headers
-                             silent unpaginate noerror reader
-                             username auth host
-                             callback errorback extra)
-  "Make a `GET' request for RESOURCE, with optional query PARAMS.
-Like calling `ghub-request' (which see) with \"GET\" as METHOD
-and `bitbucket' as FORGE."
-  (ghub-request "GET" resource params :forge 'bitbucket
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun buck-put (resource &optional params
-                             &key query payload headers
-                             silent unpaginate noerror reader
-                             username auth host
-                             callback errorback extra)
-  "Make a `PUT' request for RESOURCE, with optional payload PARAMS.
-Like calling `ghub-request' (which see) with \"PUT\" as METHOD
-and `bitbucket' as FORGE."
-  (ghub-request "PUT" resource params :forge 'bitbucket
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun buck-post (resource &optional params
-                              &key query payload headers
-                              silent unpaginate noerror reader
-                              username auth host
-                              callback errorback extra)
-  "Make a `POST' request for RESOURCE, with optional payload PARAMS.
-Like calling `ghub-request' (which see) with \"POST\" as METHOD
-and `bitbucket' as FORGE."
-  (ghub-request "POST" resource params :forge 'bitbucket
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun buck-delete (resource &optional params
-                                &key query payload headers
-                                silent unpaginate noerror reader
-                                username auth host
-                                callback errorback extra)
-  "Make a `DELETE' request for RESOURCE, with optional payload PARAMS.
-Like calling `ghub-request' (which see) with \"DELETE\" as METHOD
-and `bitbucket' as FORGE."
-  (ghub-request "DELETE" resource params :forge 'bitbucket
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun buck-request (method resource &optional params
-                               &key query payload headers
-                               silent unpaginate noerror reader
-                               username auth host
-                               callback errorback extra)
-  "Make a request for RESOURCE and return the response body.
-Like calling `ghub-request' (which see) with `bitbucket' as FORGE."
-  (ghub-request method resource params :forge 'bitbucket
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun buck-repository-id (owner name &key username auth host)
-  "Return the id of the repository specified by OWNER, NAME and HOST."
-  (substring (cdr (assq 'uuid
-                        (buck-get (format "/repositories/%s/%s" owner name)
-                                  nil
-                                  :username username :auth auth :host host)))
-             1 -1))
-
-;;; _
-(provide 'buck)
-;;; buck.el ends here
diff --git a/elpa/ghub-20190121.2116/dir b/elpa/ghub-20190121.2116/dir
deleted file mode 100644 (file)
index 8392fa0..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-This is the file .../info/dir, which contains the
-topmost node of the Info hierarchy, called (dir)Top.
-The first time you invoke Info you start off looking at this node.
-\1f
-File: dir,     Node: Top       This is the top of the INFO tree
-
-  This (the Directory node) gives a menu of major topics.
-  Typing "q" exits, "H" lists all Info commands, "d" returns here,
-  "h" gives a primer for first-timers,
-  "mEmacs<Return>" visits the Emacs manual, etc.
-
-  In Emacs, you can click mouse button 2 on a menu item or cross reference
-  to select it.
-
-* Menu:
-
-Emacs
-* Ghub: (ghub).                 Minuscule client library for the Github API.
diff --git a/elpa/ghub-20190121.2116/ghub-autoloads.el b/elpa/ghub-20190121.2116/ghub-autoloads.el
deleted file mode 100644 (file)
index 2785cba..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-;;; ghub-autoloads.el --- automatically extracted autoloads
-;;
-;;; Code:
-
-(add-to-list 'load-path (directory-file-name
-                         (or (file-name-directory #$) (car load-path))))
-
-\f
-;;;### (autoloads nil "buck" "buck.el" (0 0 0 0))
-;;; Generated autoloads from buck.el
-
-(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "buck" '("buck-default-host")))
-
-;;;***
-\f
-;;;### (autoloads nil "ghub" "ghub.el" (0 0 0 0))
-;;; Generated autoloads from ghub.el
-
-(autoload 'ghub-create-token "ghub" "\
-Create, store and return a new token.
-
-HOST is the Github instance, usually \"api.github.com\".
-USERNAME is the name of a user on that instance.
-PACKAGE is the package that will use the token.
-SCOPES are the scopes the token is given access to.
-
-\(fn HOST USERNAME PACKAGE SCOPES)" t nil)
-
-(autoload 'ghub-token-scopes "ghub" "\
-Return and echo the scopes of the specified token.
-This is intended for debugging purposes only.  The user
-has to provide several values including their password.
-
-\(fn HOST USERNAME PACKAGE)" t nil)
-
-(autoload 'ghub-clear-caches "ghub" "\
-Clear all caches that might negatively affect Ghub.
-
-If a library that is used by Ghub caches incorrect information
-such as a mistyped password, then that can prevent Ghub from
-asking the user for the correct information again.
-
-Set `url-http-real-basic-auth-storage' to nil
-and call `auth-source-forget+'.
-
-\(fn)" t nil)
-
-(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ghub" '("auth-source-netrc-parse-next-interesting@save-match-data" "ghub-")))
-
-;;;***
-\f
-;;;### (autoloads nil "ghub-graphql" "ghub-graphql.el" (0 0 0 0))
-;;; Generated autoloads from ghub-graphql.el
-
-(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ghub-graphql" '("ghub-")))
-
-;;;***
-\f
-;;;### (autoloads nil "glab" "glab.el" (0 0 0 0))
-;;; Generated autoloads from glab.el
-
-(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "glab" '("glab-default-host")))
-
-;;;***
-\f
-;;;### (autoloads nil "gogs" "gogs.el" (0 0 0 0))
-;;; Generated autoloads from gogs.el
-
-(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "gogs" '("gogs-default-host")))
-
-;;;***
-\f
-;;;### (autoloads nil "gtea" "gtea.el" (0 0 0 0))
-;;; Generated autoloads from gtea.el
-
-(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "gtea" '("gtea-default-host")))
-
-;;;***
-\f
-;;;### (autoloads nil nil ("ghub-pkg.el") (0 0 0 0))
-
-;;;***
-\f
-;; Local Variables:
-;; version-control: never
-;; no-byte-compile: t
-;; no-update-autoloads: t
-;; coding: utf-8
-;; End:
-;;; ghub-autoloads.el ends here
diff --git a/elpa/ghub-20190121.2116/ghub-graphql.el b/elpa/ghub-20190121.2116/ghub-graphql.el
deleted file mode 100644 (file)
index 53133e7..0000000
+++ /dev/null
@@ -1,463 +0,0 @@
-;;; ghub-graphql.el --- access Github API using GrapthQL  -*- lexical-binding: t -*-
-
-;; Copyright (C) 2016-2019  Jonas Bernoulli
-
-;; Author: Jonas Bernoulli <jonasNOSPAMbernoul.li>
-;; Homepage: https://github.com/magit/ghub
-
-;; This file is not part of GNU Emacs.
-
-;; This file is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
-
-;; This file is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; For a copy of the GPL see https://www.gnu.org/licenses/gpl.txt.
-
-;;; Code:
-
-(require 'dash)
-(require 'ghub)
-(require 'graphql)
-(require 'treepy)
-
-(eval-when-compile
-  (require 'subr-x))
-
-;;; Api
-
-(cl-defun ghub-graphql (graphql &optional variables
-                                &key username auth host
-                                silent
-                                callback errorback value extra)
-  "Make a GraphQL request using GRAPHQL and VARIABLES.
-Return the response as a JSON-like alist.  Even if the response
-contains `errors', do not raise an error.  GRAPHQL is a GraphQL
-string.  VARIABLES is a JSON-like alist.  The other arguments
-behave as for `ghub-request' (which see)."
-  (cl-assert (stringp graphql))
-  (cl-assert (not (stringp variables)))
-  (ghub-request "POST" "/graphql" nil :payload
-                (json-encode `(("query" . ,graphql)
-                               ,@(and variables `(("variables" ,@variables)))))
-                :silent silent
-                :username username :auth auth :host host
-                :callback callback :errorback errorback
-                :extra extra :value value))
-
-(cl-defun ghub-graphql-rate-limit (&key username auth host)
-  "Return rate limit information."
-  (let-alist (ghub-graphql
-              "query { rateLimit { limit cost remaining resetAt }}"
-              nil :username username :auth auth :host host)
-    .data.rateLimit))
-
-(cl-defun ghub--repository-id (owner name &key username auth host)
-  "Return the id of the repository specified by OWNER, NAME and HOST."
-  (let-alist (ghub-graphql
-              "query ($owner:String!, $name:String!) {
-                 repository(owner:$owner, name:$name) { id }
-               }"
-              `((owner . ,owner)
-                (name  . ,name))
-              :username username :auth auth :host host)
-    .data.repository.id))
-
-;;; Api (drafts)
-
-(defconst ghub-fetch-repository
-  '(query
-    (repository
-     [(owner $owner String!)
-      (name  $name  String!)]
-     name
-     id
-     createdAt
-     updatedAt
-     nameWithOwner
-     (parent nameWithOwner)
-     description
-     homepageUrl
-     (defaultBranchRef name)
-     isArchived
-     isFork
-     isLocked
-     isMirror
-     isPrivate
-     hasIssuesEnabled
-     hasWikiEnabled
-     (licenseInfo name)
-     (stargazers totalCount)
-     (watchers totalCount)
-     (assignableUsers [(:edges t)]
-                      id
-                      login
-                      name)
-     (issues         [(:edges t)
-                      (:singular issue number)
-                      (orderBy ((field . UPDATED_AT) (direction . DESC)))]
-                     number
-                     state
-                     (author login)
-                     title
-                     createdAt
-                     updatedAt
-                     closedAt
-                     locked
-                     (milestone id)
-                     body
-                     (assignees [(:edges t)]
-                                id)
-                     (comments  [(:edges t)]
-                                databaseId
-                                (author login)
-                               createdAt
-                               updatedAt
-                                body)
-                     (labels    [(:edges t)]
-                                id))
-     (labels         [(:edges t)
-                      (:singular label id)]
-                     id
-                     name
-                     color
-                     description)
-     (pullRequests   [(:edges t)
-                      (:singular pullRequest number)
-                      (orderBy ((field . UPDATED_AT) (direction . DESC)))]
-                     number
-                     state
-                     (author login)
-                     title
-                     createdAt
-                     updatedAt
-                     closedAt
-                     mergedAt
-                     locked
-                     maintainerCanModify
-                     isCrossRepository
-                     (milestone id)
-                     body
-                     (baseRef name
-                              (repository nameWithOwner))
-                     (headRef name
-                              (repository (owner login)
-                                          nameWithOwner))
-                     (assignees [(:edges t)]
-                                id)
-                     (comments  [(:edges t)]
-                                databaseId
-                                (author login)
-                                createdAt
-                               updatedAt
-                               body)
-                     (labels    [(:edges t)]
-                                id)))))
-
-(cl-defun ghub-fetch-repository (owner name callback
-                                       &optional until
-                                       &key username auth host forge)
-  "Asynchronously fetch forge data about the specified repository.
-Once all data has been collected, CALLBACK is called with the
-data as the only argument."
-  (ghub--graphql-vacuum ghub-fetch-repository
-                        `((owner . ,owner)
-                          (name  . ,name))
-                        callback until
-                        :narrow   '(repository)
-                        :username username
-                        :auth     auth
-                        :host     host
-                        :forge    forge))
-
-(cl-defun ghub-fetch-issue (owner name number callback
-                                  &optional until
-                                  &key username auth host forge)
-  "Asynchronously fetch forge data about the specified issue.
-Once all data has been collected, CALLBACK is called with the
-data as the only argument."
-  (ghub--graphql-vacuum (ghub--graphql-prepare-query
-                         ghub-fetch-repository
-                         `(repository issues (issue . ,number)))
-                        `((owner . ,owner)
-                          (name  . ,name))
-                        callback until
-                        :narrow   '(repository issue)
-                        :username username
-                        :auth     auth
-                        :host     host
-                        :forge    forge))
-
-(cl-defun ghub-fetch-pullreq (owner name number callback
-                                    &optional until
-                                    &key username auth host forge)
-  "Asynchronously fetch forge data about the specified pull-request.
-Once all data has been collected, CALLBACK is called with the
-data as the only argument."
-  (ghub--graphql-vacuum (ghub--graphql-prepare-query
-                         ghub-fetch-repository
-                         `(repository pullRequests (pullRequest . ,number)))
-                        `((owner . ,owner)
-                          (name  . ,name))
-                        callback until
-                        :narrow   '(repository pullRequest)
-                        :username username
-                        :auth     auth
-                        :host     host
-                        :forge    forge))
-
-;;; Internal
-
-(cl-defstruct (ghub--graphql-req
-               (:include ghub--req)
-               (:constructor ghub--make-graphql-req)
-               (:copier nil))
-  (query     nil :read-only t)
-  (variables nil :read-only t)
-  (until     nil :read-only t)
-  (buffer    nil :read-only t)
-  (pages     0   :read-only nil))
-
-(cl-defun ghub--graphql-vacuum (query variables callback
-                                      &optional until
-                                      &key narrow username auth host forge)
-  "Make a GraphQL request using QUERY and VARIABLES.
-See Info node `(ghub)GraphQL Support'."
-  (unless host
-    (setq host (ghub--host forge)))
-  (unless (or username (stringp auth) (eq auth 'none))
-    (setq username (ghub--username host forge)))
-  (ghub--graphql-retrieve
-   (ghub--make-graphql-req
-    :url       (url-generic-parse-url (concat "https://" host "/graphql"))
-    :method    "POST"
-    :headers   (ghub--headers nil host auth username forge)
-    :handler   'ghub--graphql-handle-response
-    :query     query
-    :variables variables
-    :until     until
-    :buffer    (current-buffer)
-    :callback  (let ((buf (current-buffer)))
-                 (if narrow
-                     (lambda (data)
-                       (let ((path narrow) key)
-                         (while (setq key (pop path))
-                           (setq data (cdr (assq key data)))))
-                       (ghub--graphql-set-mode-line buf nil)
-                       (funcall callback data))
-                   (lambda (data)
-                     (ghub--graphql-set-mode-line buf nil)
-                     (funcall callback data)))))))
-
-(cl-defun ghub--graphql-retrieve (req &optional lineage cursor)
-  (let ((p (cl-incf (ghub--graphql-req-pages req))))
-    (when (> p 1)
-      (ghub--graphql-set-mode-line req "Fetching page %s" p)))
-  (ghub--retrieve
-   (let ((json-false nil))
-     (ghub--encode-payload
-      `((query     . ,(ghub--graphql-encode
-                       (ghub--graphql-prepare-query
-                        (ghub--graphql-req-query req)
-                        lineage cursor)))
-        (variables . ,(ghub--graphql-req-variables req)))))
-   req))
-
-(defun ghub--graphql-prepare-query (query &optional lineage cursor)
-  (when lineage
-    (setq query (ghub--graphql-narrow-query query lineage cursor)))
-  (let ((loc (ghub--alist-zip query))
-        variables)
-    (cl-block nil
-      (while t
-        (let ((node (treepy-node loc)))
-          (when (vectorp node)
-            (let ((alist (cl-coerce node 'list))
-                  vars)
-              (when (assq :edges alist)
-                (push (list 'first 100) vars)
-                (setq loc  (treepy-up loc))
-                (setq node (treepy-node loc))
-                (setq loc  (treepy-replace
-                            loc `(,(car  node)
-                                  ,(cadr node)
-                                  (pageInfo endCursor hasNextPage)
-                                  (edges (node ,@(cddr node))))))
-                (setq loc  (treepy-down loc))
-                (setq loc  (treepy-next loc)))
-              (dolist (elt alist)
-                (cond ((eq (car elt) :alias)
-                       (push elt vars))
-                      ((keywordp (car elt)))
-                      ((= (length elt) 3)
-                       (push (list (nth 0 elt)
-                                   (nth 1 elt)) vars)
-                       (push (list (nth 1 elt)
-                                   (nth 2 elt)) variables))
-                      ((= (length elt) 2)
-                       (push elt vars))))
-              (setq loc (treepy-replace loc (cl-coerce vars 'vector))))))
-        (if (treepy-end-p loc)
-            (let ((node (copy-sequence (treepy-node loc))))
-              (when variables
-                (push (cl-coerce variables 'vector)
-                      (cdr node)))
-              (cl-return node))
-          (setq loc (treepy-next loc)))))))
-
-(defun ghub--graphql-handle-response (status req)
-  (let ((buffer (current-buffer)))
-    (unwind-protect
-        (progn
-          (set-buffer-multibyte t)
-          (let* ((headers (ghub--handle-response-headers status req))
-                 (payload (ghub--handle-response-payload req))
-                 (payload (ghub--handle-response-error status payload req))
-                 (err     (plist-get status :error))
-                 (errors  (cdr (assq 'errors payload)))
-                 (errors  (and errors
-                               (cons 'ghub-graphql-error errors)))
-                 (data    (assq 'data payload))
-                 (value   (ghub--req-value req)))
-            (setf (ghub--req-value req) value)
-            (if (or err errors)
-                (if-let ((errorback (ghub--req-errorback req)))
-                    (funcall errorback (or err errors) headers status req)
-                  (ghub--signal-error (or err errors)))
-              (ghub--graphql-walk-response value data req))))
-      (when (buffer-live-p buffer)
-        (kill-buffer buffer)))))
-
-(defun ghub--graphql-walk-response (loc data req)
-  (if (not loc)
-      (setf (ghub--req-value req)
-            (setq loc (ghub--alist-zip data)))
-    (setq data (ghub--graphql-narrow-data data (ghub--graphql-lineage loc)))
-    (setf (alist-get 'edges data)
-          (append (alist-get 'edges (treepy-node loc))
-                  (or (alist-get 'edges data)
-                      (error "BUG: Expected new nodes"))))
-    (setq loc (treepy-replace loc data)))
-  (cl-block nil
-    (while t
-      (when (eq (car-safe (treepy-node loc)) 'edges)
-        (setq loc (treepy-up loc))
-        (pcase-let ((`(,key . ,val) (treepy-node loc)))
-          (let-alist val
-            (let* ((cursor (and .pageInfo.hasNextPage
-                                .pageInfo.endCursor))
-                   (until (cdr (assq (intern (format "%s-until" key))
-                                     (ghub--graphql-req-until req))))
-                   (nodes (mapcar #'cdar .edges))
-                   (nodes (if until
-                              (--take-while
-                               (or (string> (cdr (assq 'updatedAt it)) until)
-                                   (setq cursor nil))
-                               nodes)
-                            nodes)))
-              (if cursor
-                  (progn
-                    (setf (ghub--req-value req) loc)
-                    (ghub--graphql-retrieve req
-                                            (ghub--graphql-lineage loc)
-                                            cursor)
-                    (cl-return))
-                (setq loc (treepy-replace loc (cons key nodes))))))))
-      (if (not (treepy-end-p loc))
-          (setq loc (treepy-next loc))
-        (funcall (ghub--req-callback req)
-                 (treepy-root loc))
-        (cl-return)))))
-
-(defun ghub--graphql-lineage (loc)
-  (let (lineage)
-    (while (treepy-up loc)
-      (push (car (treepy-node loc)) lineage)
-      (setq loc (treepy-up loc)))
-    lineage))
-
-(defun ghub--graphql-narrow-data (data lineage)
-  (let (key)
-    (while (setq key (pop lineage))
-      (if (consp (car lineage))
-          (progn (pop lineage)
-                 (setf data (cadr data)))
-        (setq data (assq key (cdr data))))))
-  data)
-
-(defun ghub--graphql-narrow-query (query lineage cursor)
-  (if (consp (car lineage))
-      (let* ((child  (cddr query))
-             (alist  (cl-coerce (cadr query) 'list))
-             (single (cdr (assq :singular alist))))
-        `(,(car single)
-          ,(vector (list (cadr single) (cdr (car lineage))))
-          ,@(if (cdr lineage)
-               (ghub--graphql-narrow-query child (cdr lineage) cursor)
-             child)))
-    (let* ((child  (or (assq (car lineage) (cdr query))
-                       (cl-find-if (lambda (c)
-                                     (and (listp c)
-                                          (vectorp (cadr c))
-                                          (eq (cadr (assq :singular
-                                                          (cl-coerce (cadr c)
-                                                                     'list)))
-                                              (car lineage))))
-                                   (cdr query))))
-           (object (car query))
-           (args   (and (vectorp (cadr query))
-                        (cadr query))))
-      `(,object
-        ,@(and args (list args))
-        ,(cond ((cdr lineage)
-                (ghub--graphql-narrow-query child (cdr lineage) cursor))
-               (cursor
-                `(,(car child)
-                  ,(vconcat `((after ,cursor))
-                            (cadr child))
-                  ,@(cddr child)))
-               (t
-                child))))))
-
-(defun ghub--graphql-encode (g)
-  (if (symbolp g)
-      (symbol-name g)
-    (let* ((object (graphql--encode-object (car g)))
-           (args   (and (vectorp (cadr g))
-                        (cl-coerce (cadr g) 'list)))
-           (aliasp (cadr (assq :alias args)))
-           (fields (if args (cddr g) (cdr g)))
-           (fields (and fields
-                        (mapconcat #'ghub--graphql-encode fields "\n")))
-           (args   (and args
-                        (mapconcat (pcase-lambda (`(,key ,val))
-                                     (graphql--encode-argument key val))
-                                   args ",\n"))))
-      (if aliasp
-          (concat object ": " fields)
-        (concat object
-                (and args   (format " (\n%s)" args))
-                (and fields (format " {\n%s\n}" fields)))))))
-
-(defun ghub--alist-zip (root)
-  (let ((branchp (lambda (elt) (and (listp elt) (listp (cdr elt)))))
-        (make-node (lambda (_ children) children)))
-    (treepy-zipper branchp #'identity make-node root)))
-
-(defun ghub--graphql-set-mode-line (buf string &rest args)
-  (when (ghub--graphql-req-p buf)
-    (setq buf (ghub--graphql-req-buffer buf)))
-  (when (buffer-live-p buf)
-    (with-current-buffer buf
-      (setq mode-line-process
-            (and string (concat " " (apply #'format string args))))
-      (force-mode-line-update t))))
-
-;;; _
-(provide 'ghub-graphql)
-;;; ghub-graphql.el ends here
diff --git a/elpa/ghub-20190121.2116/ghub-pkg.el b/elpa/ghub-20190121.2116/ghub-pkg.el
deleted file mode 100644 (file)
index 64348b9..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-(define-package "ghub" "20190121.2116" "Minuscule client libraries for Git forge APIs."
-  '((emacs "25.1")
-    (dash "2.14.1")
-    (graphql "0.1.1")
-    (let-alist "1.0.5")
-    (treepy "0.1.1")))
-;; Local Variables:
-;; no-byte-compile: t
-;; End:
diff --git a/elpa/ghub-20190121.2116/ghub.el b/elpa/ghub-20190121.2116/ghub.el
deleted file mode 100644 (file)
index bdf4ae8..0000000
+++ /dev/null
@@ -1,987 +0,0 @@
-;;; ghub.el --- minuscule client libraries for Git forge APIs  -*- lexical-binding: t -*-
-
-;; Copyright (C) 2016-2019  Jonas Bernoulli
-
-;; Author: Jonas Bernoulli <jonasNOSPAMbernoul.li>
-;; Homepage: https://github.com/magit/ghub
-;; Keywords: tools
-
-;; This file is not part of GNU Emacs.
-
-;; This file is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
-
-;; This file is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; For a copy of the GPL see https://www.gnu.org/licenses/gpl.txt.
-
-;;; Commentary:
-
-;; Ghub provides basic support for using the APIs of various Git forges
-;; from Emacs packages.  Originally it only supported the Github REST
-;; API, but now it also supports the Github GraphQL API as well as the
-;; REST APIs of Gitlab, Gitea, Gogs and Bitbucket.
-
-;; Ghub abstracts access to API resources using only a handful of basic
-;; functions such as `ghub-get'.  These are convenience wrappers around
-;; `ghub-request'.  Additional forge-specific wrappers like `glab-put',
-;; `gtea-put', `gogs-post' and `buck-delete' are also available.  Ghub
-;; does not provide any resource-specific functions, with the exception
-;; of `FORGE-repository-id'.
-
-;; When accessing Github, then Ghub handles the creation and storage of
-;; access tokens using a setup wizard to make it easier for users to get
-;; started.  The tokens for other forges have to be created manually.
-
-;; Ghub is intentionally limited to only provide these two essential
-;; features â€” basic request functions and guided setup â€” to avoid being
-;; too opinionated, which would hinder wide adoption.  It is assumed that
-;; wide adoption would make life easier for users and maintainers alike,
-;; because then all packages that talk to forge APIs could be configured
-;; the same way.
-
-;; Please consult the manual (info "ghub") for more information.
-
-;;; Code:
-
-(require 'auth-source)
-(require 'cl-lib)
-(require 'json)
-(require 'let-alist)
-(require 'url)
-(require 'url-auth)
-(require 'url-http)
-
-(eval-when-compile
-  (require 'subr-x))
-
-(defvar url-callback-arguments)
-(defvar url-http-end-of-headers)
-(defvar url-http-extra-headers)
-(defvar url-http-response-status)
-
-;;; Settings
-
-(defconst ghub-default-host "api.github.com"
-  "The default host that is used if `ghub.host' is not set.")
-
-(defvar ghub-github-token-scopes '(repo)
-  "The Github API scopes that your private tools need.
-
-The token that is created based on the value of this variable
-is used when `ghub-request' (or one of its wrappers) is called
-without providing a value for AUTH.  Packages should always
-identify themselves using that argument, but when you use Ghub
-directly in private tools, then that is not necessary and the
-request is made on behalf of the `ghub' package itself, aka on
-behalf of some private tool.
-
-By default the only requested scope is `repo' because that is
-sufficient as well as required for most common uses.  This and
-other scopes are documented at URL `https://magit.vc/goto/2e586d36'.
-
-If your private tools need other scopes, then you have to add
-them here *before* creating the token.  Alternatively you can
-edit the scopes of an existing token using the web interface
-at URL `https://github.com/settings/tokens'.")
-
-(defvar ghub-override-system-name nil
-  "If non-nil, the string used to identify the local machine.
-If this is nil, then the value returned by `system-name' is
-used instead.")
-
-;;; Request
-;;;; Object
-
-(cl-defstruct (ghub--req
-               (:constructor ghub--make-req)
-               (:copier nil))
-  (url        nil :read-only nil)
-  (forge      nil :read-only t)
-  (silent     nil :read-only t)
-  (method     nil :read-only t)
-  (headers    nil :read-only t)
-  (handler    nil :read-only t)
-  (unpaginate nil :read-only nil)
-  (noerror    nil :read-only t)
-  (reader     nil :read-only t)
-  (callback   nil :read-only t)
-  (errorback  nil :read-only t)
-  (value      nil :read-only nil)
-  (extra      nil :read-only nil))
-
-(defalias 'ghub-req-extra 'ghub--req-extra)
-
-;;;; API
-
-(define-error 'ghub-error "Ghub/Url Error" 'error)
-(define-error 'ghub-http-error "HTTP Error" 'ghub-error)
-
-(defvar ghub-response-headers nil
-  "The headers returned in response to the last request.
-`ghub-request' returns the response body and stores the
-response headers in this variable.")
-
-(cl-defun ghub-head (resource &optional params
-                              &key query payload headers
-                              silent unpaginate noerror reader
-                              username auth host
-                              callback errorback extra)
-  "Make a `HEAD' request for RESOURCE, with optional query PARAMS.
-Like calling `ghub-request' (which see) with \"HEAD\" as METHOD."
-  (ghub-request "HEAD" resource params
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun ghub-get (resource &optional params
-                             &key query payload headers
-                             silent unpaginate noerror reader
-                             username auth host
-                             callback errorback extra)
-  "Make a `GET' request for RESOURCE, with optional query PARAMS.
-Like calling `ghub-request' (which see) with \"GET\" as METHOD."
-  (ghub-request "GET" resource params
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun ghub-put (resource &optional params
-                             &key query payload headers
-                             silent unpaginate noerror reader
-                             username auth host
-                             callback errorback extra)
-  "Make a `PUT' request for RESOURCE, with optional payload PARAMS.
-Like calling `ghub-request' (which see) with \"PUT\" as METHOD."
-  (ghub-request "PUT" resource params
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun ghub-post (resource &optional params
-                              &key query payload headers
-                              silent unpaginate noerror reader
-                              username auth host
-                              callback errorback extra)
-  "Make a `POST' request for RESOURCE, with optional payload PARAMS.
-Like calling `ghub-request' (which see) with \"POST\" as METHOD."
-  (ghub-request "POST" resource params
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun ghub-patch (resource &optional params
-                               &key query payload headers
-                               silent unpaginate noerror reader
-                               username auth host
-                               callback errorback extra)
-  "Make a `PATCH' request for RESOURCE, with optional payload PARAMS.
-Like calling `ghub-request' (which see) with \"PATCH\" as METHOD."
-  (ghub-request "PATCH" resource params
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun ghub-delete (resource &optional params
-                                &key query payload headers
-                                silent unpaginate noerror reader
-                                username auth host
-                                callback errorback extra)
-  "Make a `DELETE' request for RESOURCE, with optional payload PARAMS.
-Like calling `ghub-request' (which see) with \"DELETE\" as METHOD."
-  (ghub-request "DELETE" resource params
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun ghub-request (method resource &optional params
-                               &key query payload headers
-                               silent unpaginate noerror reader
-                               username auth host forge
-                               callback errorback value extra)
-  "Make a request for RESOURCE and return the response body.
-
-Also place the response headers in `ghub-response-headers'.
-
-METHOD is the HTTP method, given as a string.
-RESOURCE is the resource to access, given as a string beginning
-  with a slash.
-
-PARAMS, QUERY, PAYLOAD and HEADERS are alists used to specify
-  data.  The Github API documentation is vague on how data has
-  to be transmitted and for a particular resource usually just
-  talks about \"parameters\".  Generally speaking when the METHOD
-  is \"HEAD\" or \"GET\", then they have to be transmitted as a
-  query, otherwise as a payload.
-Use PARAMS to automatically transmit like QUERY or PAYLOAD would
-  depending on METHOD.
-Use QUERY to explicitly transmit data as a query.
-Use PAYLOAD to explicitly transmit data as a payload.
-  Instead of an alist, PAYLOAD may also be a string, in which
-  case it gets encoded as UTF-8 but is otherwise transmitted as-is.
-Use HEADERS for those rare resources that require that the data
-  is transmitted as headers instead of as a query or payload.
-  When that is the case, then the API documentation usually
-  mentions it explicitly.
-
-If SILENT is non-nil, then don't message progress reports and
-  the like.
-
-If UNPAGINATE is t, then make as many requests as necessary to
-  get all values.  If UNPAGINATE is a natural number, then get
-  at most that many pages.  For any other non-nil value raise
-  an error.
-If NOERROR is non-nil, then do not raise an error if the request
-  fails and return nil instead.  If NOERROR is `return', then
-  return the error payload instead of nil.
-If READER is non-nil, then it is used to read and return from the
-  response buffer.  The default is `ghub--read-json-payload'.
-  For the very few resources that do not return JSON, you might
-  want to use `ghub--decode-payload'.
-
-If USERNAME is non-nil, then make a request on behalf of that
-  user.  It is better to specify the user using the Git variable
-  `github.user' for \"api.github.com\", or `github.HOST.user' if
-  connecting to a Github Enterprise instance.
-
-Each package that uses `ghub' should use its own token. If AUTH
-  is nil, then the generic `ghub' token is used instead.  This
-  is only acceptable for personal utilities.  A packages that
-  is distributed to other users should always use this argument
-  to identify itself, using a symbol matching its name.
-
-  Package authors who find this inconvenient should write a
-  wrapper around this function and possibly for the
-  method-specific functions as well.
-
-  Some symbols have a special meaning.  `none' means to make an
-  unauthorized request.  `basic' means to make a password based
-  request.  If the value is a string, then it is assumed to be
-  a valid token.  `basic' and an explicit token string are only
-  intended for internal and debugging uses.
-
-  If AUTH is a package symbol, then the scopes are specified
-  using the variable `AUTH-github-token-scopes'.  It is an error
-  if that is not specified.  See `ghub-github-token-scopes' for
-  an example.
-
-If HOST is non-nil, then connect to that Github instance.  This
-  defaults to \"api.github.com\".  When a repository is connected
-  to a Github Enterprise instance, then it is better to specify
-  that using the Git variable `github.host' instead of using this
-  argument.
-
-If FORGE is `gitlab', then connect to Gitlab.com or, depending
-  on HOST, to another Gitlab instance.  This is only intended for
-  internal use.  Instead of using this argument you should use
-  function `glab-request' and other `glab-*' functions.
-
-If CALLBACK and/or ERRORBACK is non-nil, then make one or more
-  asynchronous requests and call CALLBACK or ERRORBACK when
-  finished.  If no error occurred, then call CALLBACK, unless
-  that is nil.
-
-  If an error occurred, then call ERRORBACK, or if that is nil,
-  then CALLBACK.  ERRORBACK can also be t, in which case an error
-  is signaled instead.  NOERROR is ignored for all asynchronous
-  requests.
-
-Both callbacks are called with four arguments.
-  1. For CALLBACK, the combined value of the retrieved pages.
-     For ERRORBACK, the error that occured when retrieving the
-     last page.
-  2. The headers of the last page as an alist.
-  3. Status information provided by `url-retrieve'. Its `:error'
-     property holds the same information as ERRORBACK's first
-     argument.
-  4. A `ghub--req' struct, which can be passed to `ghub-continue'
-     (which see) to retrieve the next page, if any."
-  (cl-assert (or (booleanp unpaginate) (natnump unpaginate)))
-  (unless (string-prefix-p "/" resource)
-    (setq resource (concat "/" resource)))
-  (unless host
-    (setq host (ghub--host forge)))
-  (unless (or username (stringp auth) (eq auth 'none))
-    (setq username (ghub--username host forge)))
-  (cond ((not params))
-        ((member method '("GET" "HEAD"))
-         (when query
-           (error "PARAMS and QUERY are mutually exclusive for METHOD %S"
-                  method))
-         (setq query params))
-        (t
-         (when payload
-           (error "PARAMS and PAYLOAD are mutually exclusive for METHOD %S"
-                  method))
-         (setq payload params)))
-  (when (or callback errorback)
-    (setq noerror t))
-  (ghub--retrieve
-   (ghub--encode-payload payload)
-   (ghub--make-req
-    :url (url-generic-parse-url
-          (concat "https://" host resource
-                  (and query (concat "?" (ghub--url-encode-params query)))))
-    :forge forge
-    :silent silent
-    ;; Encode in case caller used (symbol-name 'GET). #35
-    :method     (encode-coding-string method 'utf-8)
-    :headers    (ghub--headers headers host auth username forge)
-    :handler    'ghub--handle-response
-    :unpaginate unpaginate
-    :noerror    noerror
-    :reader     reader
-    :callback   callback
-    :errorback  errorback
-    :value      value
-    :extra      extra)))
-
-(defun ghub-continue (req)
-  "If there is a next page, then retrieve that.
-
-This function is only intended to be called from callbacks.  If
-there is a next page, then retrieve that and return the buffer
-that the result will be loaded into, or t if the process has
-already completed.  If there is no next page, then return nil.
-
-Callbacks are called with four arguments (see `ghub-request').
-The forth argument is a `ghub--req' struct, intended to be passed
-to this function.  A callback may use the struct's `extra' slot
-to pass additional information to the callback that will be
-called after the next request has finished.  Use the function
-`ghub-req-extra' to get and set the value of this slot."
-  (and (assq 'next (ghub-response-link-relations req))
-       (or (ghub--retrieve nil req) t)))
-
-(cl-defun ghub-wait (resource &optional duration &key username auth host)
-  "Busy-wait up to DURATION seconds for RESOURCE to become available.
-
-DURATION specifies how many seconds to wait at most.  It defaults
-to 64 seconds.  The first attempt is made immediately, the second
-after two seconds, and each subsequent attempt is made after
-waiting as long again as we already waited between all preceding
-attempts combined.
-
-See `ghub-request' for information about the other arguments."
-  (unless duration
-    (setq duration 64))
-  (with-local-quit
-    (let ((total 0))
-      (while (not (ghub-get resource nil
-                            :noerror t
-                            :username username
-                            :auth auth
-                            :host host))
-        (message "Waited (%3ss of %ss) for %s..." total duration resource)
-        (if (= total duration)
-            (error "Github is taking too long to create %s" resource)
-          (if (> total 0)
-              (let ((wait (min total (- duration total))))
-                (sit-for wait)
-                (cl-incf total wait))
-            (sit-for (setq total 2))))))))
-
-(defun ghub-response-link-relations (req &optional headers payload)
-  "Return an alist of link relations in HEADERS.
-If optional HEADERS is nil, then return those that were
-previously stored in the variable `ghub-response-headers'.
-
-When accessing a Bitbucket instance then the link relations
-are in PAYLOAD instead of HEADERS, making their API merely
-RESTish and forcing this function to append those relations
-to the value of `ghub-response-headers', for later use when
-this function is called with nil for PAYLOAD."
-  (if (eq (ghub--req-forge req) 'bitbucket)
-      (if payload
-          (let* ((page (cl-mapcan (lambda (key)
-                                    (when-let ((elt (assq key payload)))
-                                      (list elt)))
-                                  '(size page pagelen next previous)))
-                 (headers (cons (cons 'link-alist page) headers)))
-            (if (and req (or (ghub--req-callback req)
-                             (ghub--req-errorback req)))
-                (setq-local ghub-response-headers headers)
-              (setq-default ghub-response-headers headers))
-            page)
-        (cdr (assq 'link-alist ghub-response-headers)))
-  (when-let ((rels (cdr (assoc "Link" (or headers ghub-response-headers)))))
-    (mapcar (lambda (elt)
-              (pcase-let ((`(,url ,rel) (split-string elt "; ")))
-                (cons (intern (substring rel 5 -1))
-                      (substring url 1 -1))))
-            (split-string rels ", ")))))
-
-(cl-defun ghub-repository-id (owner name &key username auth host forge noerror)
-  "Return the id of the specified repository.
-Signal an error if the id cannot be determined."
-  (let ((fn (intern (format "%s-repository-id" (or forge 'ghub)))))
-    (or (funcall (if (eq fn 'ghub-repository-id) 'ghub--repository-id fn)
-                 owner name :username username :auth auth :host host)
-        (and (not noerror)
-             (error "Repository %S does not exist on %S.\n%s%S?"
-                    (concat owner "/" name)
-                    (or host (ghub--host host))
-                    "Maybe it was renamed and you have to update "
-                    "remote.<remote>.url")))))
-
-;;;; Internal
-
-(cl-defun ghub--retrieve (payload req)
-  (let ((url-request-extra-headers
-         (let ((headers (ghub--req-headers req)))
-           (if (functionp headers) (funcall headers) headers)))
-        (url-request-method (ghub--req-method req))
-        (url-request-data payload)
-        (url-show-status nil)
-        (url     (ghub--req-url req))
-        (handler (ghub--req-handler req))
-        (silent  (ghub--req-silent req)))
-    (if (or (ghub--req-callback  req)
-            (ghub--req-errorback req))
-        (url-retrieve url handler (list req) silent)
-      ;; When this function has already been called, then it is a
-      ;; no-op.  Otherwise it sets `url-registered-auth-schemes' among
-      ;; other things.  If we didn't ensure that it has been run, then
-      ;; `url-retrieve-synchronously' would do it, which would cause
-      ;; the value that we let-bind below to be overwritten, and the
-      ;; "default" value to be lost outside the let-binding.
-      (url-do-setup)
-      (with-current-buffer
-          (let ((url-registered-auth-schemes
-                 '(("basic" ghub--basic-auth-errorback . 10))))
-            (url-retrieve-synchronously url silent))
-        (funcall handler (car url-callback-arguments) req)))))
-
-(defun ghub--handle-response (status req)
-  (let ((buffer (current-buffer)))
-    (unwind-protect
-        (progn
-          (set-buffer-multibyte t)
-          (let* ((unpaginate (ghub--req-unpaginate req))
-                 (headers    (ghub--handle-response-headers status req))
-                 (payload    (ghub--handle-response-payload req))
-                 (payload    (ghub--handle-response-error status payload req))
-                 (value      (ghub--handle-response-value payload req))
-                 (prev       (ghub--req-url req))
-                 (next       (cdr (assq 'next (ghub-response-link-relations
-                                               req headers payload)))))
-            (when (numberp unpaginate)
-              (cl-decf unpaginate))
-            (setf (ghub--req-url req)
-                  (url-generic-parse-url next))
-            (setf (ghub--req-unpaginate req) unpaginate)
-            (or (and next
-                     unpaginate
-                     (or (eq unpaginate t)
-                         (>  unpaginate 0))
-                     (ghub-continue req))
-                (let ((callback  (ghub--req-callback req))
-                      (errorback (ghub--req-errorback req))
-                      (err       (plist-get status :error)))
-                  (cond ((and err errorback)
-                         (setf (ghub--req-url req) prev)
-                         (funcall (if (eq errorback t)
-                                      'ghub--errorback
-                                    errorback)
-                                  err headers status req))
-                        (callback
-                         (funcall callback value headers status req))
-                        (t value))))))
-      (when (buffer-live-p buffer)
-        (kill-buffer buffer)))))
-
-(defun ghub--handle-response-headers (status req)
-  (goto-char (point-min))
-  (forward-line 1)
-  (let (headers)
-    (when (memq url-http-end-of-headers '(nil 0))
-      (setq url-debug t)
-      (let ((print-escape-newlines nil))
-        (error "BUG: missing headers
-  See https://github.com/magit/ghub/issues/81.
-  headers: %S
-  status: %S
-  buffer: %S
-  buffer-string:
-  %S
-  --- end of buffer-string ---"
-               url-http-end-of-headers
-               status
-               (current-buffer)
-               (buffer-substring-no-properties
-                (point-min) (point-max)))))
-    (while (re-search-forward "^\\([^:]*\\): \\(.+\\)"
-                              url-http-end-of-headers t)
-      (push (cons (match-string 1)
-                  (match-string 2))
-            headers))
-    (setq headers (nreverse headers))
-    (goto-char (1+ url-http-end-of-headers))
-    (if (and req (or (ghub--req-callback req)
-                     (ghub--req-errorback req)))
-        (setq-local ghub-response-headers headers)
-      (setq-default ghub-response-headers headers))
-    headers))
-
-(defun ghub--handle-response-error (status payload req)
-  (let ((noerror (ghub--req-noerror req))
-        (err (plist-get status :error)))
-    (if err
-        (if noerror
-            (if (eq noerror 'return)
-                payload
-              (setcdr (last err) (list payload))
-              nil)
-          (ghub--signal-error err payload req))
-      payload)))
-
-(defun ghub--signal-error (err &optional payload req)
-  (pcase-let ((`(,symb . ,data) err))
-    (if (eq symb 'error)
-        (if (eq (car-safe data) 'http)
-            (signal 'ghub-http-error
-                    (let ((code (car (cdr-safe data))))
-                      (list code
-                            (nth 2 (assq code url-http-codes))
-                            (and req (url-filename (ghub--req-url req)))
-                            payload)))
-          (signal 'ghub-error data))
-      (signal symb data))))
-
-(defun ghub--errorback (err _headers _status req)
-  (ghub--signal-error err (nth 3 err) req))
-
-(defun ghub--handle-response-value (payload req)
-  (setf (ghub--req-value req)
-        (nconc (ghub--req-value req)
-               (if-let ((nested (and (eq (ghub--req-forge req) 'bitbucket)
-                                     (assq 'values payload))))
-                   (cdr nested)
-                 payload))))
-
-(defun ghub--handle-response-payload (req)
-  (funcall (or (ghub--req-reader req)
-               'ghub--read-json-payload)
-           url-http-response-status))
-
-(defun ghub--read-json-payload (_status)
-  (let ((raw (ghub--decode-payload)))
-    (and raw
-         (condition-case nil
-             (let ((json-object-type 'alist)
-                   (json-array-type  'list)
-                   (json-key-type    'symbol)
-                   (json-false       nil)
-                   (json-null        nil))
-               (json-read-from-string raw))
-           (json-readtable-error
-            `((message
-               . ,(if (looking-at "<!DOCTYPE html>")
-                      (if (re-search-forward
-                           "<p>\\(?:<strong>\\)?\\([^<]+\\)" nil t)
-                          (match-string 1)
-                        "error description missing")
-                    (string-trim (buffer-substring (point) (point-max)))))
-              (documentation_url
-               . "https://github.com/magit/ghub/wiki/Github-Errors")))))))
-
-(defun ghub--decode-payload (&optional _status)
-  (and (not (eobp))
-       (decode-coding-string
-        (buffer-substring-no-properties (point) (point-max))
-        'utf-8)))
-
-(defun ghub--encode-payload (payload)
-  (and payload
-       (progn
-         (unless (stringp payload)
-           (setq payload (json-encode-list payload)))
-         (encode-coding-string payload 'utf-8))))
-
-(defun ghub--url-encode-params (params)
-  (mapconcat (lambda (param)
-               (pcase-let ((`(,key . ,val) param))
-                 (concat (url-hexify-string (symbol-name key)) "="
-                         (if (integerp val)
-                             (number-to-string val)
-                           (url-hexify-string val)))))
-             params "&"))
-
-;;; Authentication
-;;;; API
-
-;;;###autoload
-(defun ghub-create-token (host username package scopes)
-  "Create, store and return a new token.
-
-HOST is the Github instance, usually \"api.github.com\".
-USERNAME is the name of a user on that instance.
-PACKAGE is the package that will use the token.
-SCOPES are the scopes the token is given access to."
-  (interactive
-   (pcase-let ((`(,host ,username ,package)
-                (ghub--read-triplet)))
-     (list host username package
-           (split-string
-            (read-string
-             "Scopes (separated by commas): "
-             (mapconcat #'symbol-name
-                        (symbol-value
-                         (intern (format "%s-github-token-scopes" package)))
-                        ","))
-            "," t "[\s\t]+"))))
-  (let ((user (ghub--ident username package)))
-    (cl-destructuring-bind (save token)
-        (ghub--auth-source-get (list :save-function :secret)
-          :create t :host host :user user
-          :secret
-          (cdr (assq 'token
-                     (ghub-post
-                      "/authorizations"
-                      `((scopes . ,scopes)
-                        (note   . ,(ghub--ident-github package)))
-                      :username username :auth 'basic :host host))))
-      ;; Build-in back-ends return a function that does the actual
-      ;; saving, while for some third-party back-ends ":create t"
-      ;; is enough.
-      (when (functionp save)
-        (funcall save))
-      ;; If the Auth-Source cache contains the information that there
-      ;; is no value, then setting the value does not invalidate that
-      ;; now incorrect information.
-      ;; The (:max 1) is needed and has to be placed at the
-      ;; end for Emacs releases before 26.1.  #24 #64 #72
-      (auth-source-forget (list :host host :user user :max 1))
-      token)))
-
-;;;###autoload
-(defun ghub-token-scopes (host username package)
-  "Return and echo the scopes of the specified token.
-This is intended for debugging purposes only.  The user
-has to provide several values including their password."
-  (interactive (ghub--read-triplet))
-  (let ((scopes
-         (cdr (assq 'scopes (ghub--get-token-plist host username package)))))
-    (when (called-interactively-p 'any)
-      ;; Also show the input values to make it easy for package
-      ;; authors to verify that the user has done it correctly.
-      (message "Scopes for %s@%s: %S"
-               (ghub--ident username package)
-               host scopes))
-    scopes))
-
-;;;###autoload
-(defun ghub-clear-caches ()
-  "Clear all caches that might negatively affect Ghub.
-
-If a library that is used by Ghub caches incorrect information
-such as a mistyped password, then that can prevent Ghub from
-asking the user for the correct information again.
-
-Set `url-http-real-basic-auth-storage' to nil
-and call `auth-source-forget+'."
-  (interactive)
-  (setq url-http-real-basic-auth-storage nil)
-  (auth-source-forget+))
-
-;;;; Internal
-
-(defun ghub--headers (headers host auth username forge)
-  (push (cons "Content-Type" "application/json") headers)
-  (if (eq auth 'none)
-      headers
-    (unless (or username (stringp auth))
-      (setq username (ghub--username host forge)))
-    (lambda ()
-      (if (eq auth 'basic)
-          (cons (cons "Authorization" (ghub--basic-auth host username))
-                headers)
-        (cons (ghub--auth host auth username forge) headers)))))
-
-(defun ghub--auth (host auth &optional username forge)
-  (unless username
-    (setq username (ghub--username host)))
-  (if (eq auth 'basic)
-      (cl-ecase forge
-        ((nil github gitea gogs bitbucket)
-         (cons "Authorization" (ghub--basic-auth host username)))
-        (gitlab
-         (error "Gitlab does not support basic authentication")))
-    (cons (cl-ecase forge
-            ((nil github gitea gogs bitbucket)
-             "Authorization")
-            (gitlab
-             "Private-Token"))
-          (concat
-           (and (not (eq forge 'gitlab)) "token ")
-           (encode-coding-string
-            (cl-typecase auth
-              (string auth)
-              (null   (ghub--token host username 'ghub nil forge))
-              (symbol (ghub--token host username auth  nil forge))
-              (t (signal 'wrong-type-argument
-                         `((or stringp symbolp) ,auth))))
-            'utf-8)))))
-
-(defun ghub--basic-auth (host username)
-  (let ((url (url-generic-parse-url (concat "https://" host))))
-    (setf (url-user url) username)
-    (url-basic-auth url t)))
-
-(defun ghub--basic-auth-errorback (url &optional prompt _overwrite _realm _args)
-  ;; This gets called twice.  Do nothing the first time,
-  ;; when PROMPT is nil.  See `url-get-authentication'.
-  (when prompt
-    (if (assoc "X-GitHub-OTP" (ghub--handle-response-headers nil nil))
-        (progn
-          (setq url-http-extra-headers
-                `(("Pragma" . "no-cache")
-                  ("Content-Type" . "application/json")
-                  ("X-GitHub-OTP" . ,(ghub--read-2fa-code))
-                  ;; Without "Content-Type" and "Authorization".
-                  ;; The latter gets re-added from the return value.
-                  ,@(cddr url-http-extra-headers)))
-          ;; Return the cached values, they are correct.
-          (url-basic-auth url nil nil nil))
-      ;; Remove the invalid cached values and fail, which
-      ;; is better than the invalid values sticking around.
-      (setq url-http-real-basic-auth-storage
-            (cl-delete (format "%s:%d" (url-host url) (url-port url))
-                       url-http-real-basic-auth-storage
-                       :test #'equal :key #'car))
-      nil)))
-
-(defun ghub--token (host username package &optional nocreate forge)
-  (let* ((user (ghub--ident username package))
-         (token
-          (or (car (ghub--auth-source-get (list :secret)
-                     :host host :user user))
-              (progn
-                ;; Auth-Source caches the information that there is no
-                ;; value, but in our case that is a situation that needs
-                ;; fixing so we want to keep trying by invalidating that
-                ;; information.
-                ;; The (:max 1) is needed and has to be placed at the
-                ;; end for Emacs releases before 26.1.  #24 #64 #72
-                (auth-source-forget (list :host host :user user :max 1))
-                (and (not nocreate)
-                     (cl-ecase forge
-                       ((nil github)
-                        (ghub--confirm-create-token host username package))
-                       ((gitlab gitea gogs bitbucket)
-                        (error "Required %s token (%S for %S) does not exist.
-See https://magit.vc/manual/ghub/Support-for-Other-Forges.html for instructions."
-                               (capitalize (symbol-name forge))
-                               user host))))))))
-    (if (functionp token) (funcall token) token)))
-
-(defun ghub--host (&optional forge)
-  (cl-ecase forge
-    ((nil github)
-     (or (ignore-errors (car (process-lines "git" "config" "github.host")))
-         ghub-default-host))
-    (gitlab
-     (or (ignore-errors (car (process-lines "git" "config" "gitlab.host")))
-         (bound-and-true-p glab-default-host)))
-    (gitea
-     (or (ignore-errors (car (process-lines "git" "config" "gitea.host")))
-         (bound-and-true-p gtea-default-host)))
-    (gogs
-     (or (ignore-errors (car (process-lines "git" "config" "gogs.host")))
-         (bound-and-true-p gogs-default-host)))
-    (bitbucket
-     (or (ignore-errors (car (process-lines "git" "config" "bitbucket.host")))
-         (bound-and-true-p buck-default-host)))))
-
-(defun ghub--username (host &optional forge)
-  (let ((var
-         (cl-ecase forge
-           ((nil github)
-            (if (equal host ghub-default-host)
-                "github.user"
-              (format "github.%s.user" host)))
-           (gitlab
-            (if (equal host "gitlab.com/api/v4")
-                "gitlab.user"
-              (format "gitlab.%s.user" host)))
-           (bitbucket
-            (if (equal host "api.bitbucket.org/2.0")
-                "bitbucket.user"
-              (format "bitbucket.%s.user" host)))
-           (gitea
-            (when (zerop (call-process "git" nil nil nil "config" "gitea.host"))
-              (error "gitea.host is set but always ignored"))
-            (format "gitea.%s.user" host))
-           (gogs
-            (when (zerop (call-process "git" nil nil nil "config" "gogs.host"))
-              (error "gogs.host is set but always ignored"))
-            (format "gogs.%s.user"  host)))))
-    (condition-case nil
-        (car (process-lines "git" "config" var))
-      (error
-       (let ((user (read-string
-                    (format "Git variable `%s' is unset.  Set to: " var))))
-         (or (and user (progn (call-process "git" nil nil nil
-                                            "config" "--global" var user)
-                              user))
-             (user-error "Abort")))))))
-
-(defun ghub--ident (username package)
-  (format "%s^%s" username package))
-
-(defun ghub--ident-github (package)
-  (format "Emacs package %s @ %s"
-          package
-          (or ghub-override-system-name (system-name))))
-
-(defun ghub--package-scopes (package)
-  (let ((var (intern (format "%s-github-token-scopes" package))))
-    (if (boundp var)
-        (symbol-value var)
-      (error "%s fails to define %s" package var))))
-
-(defun ghub--confirm-create-token (host username package)
-  (let* ((ident (ghub--ident-github package))
-         (scopes (ghub--package-scopes package))
-         (max-mini-window-height 40))
-    (if (let ((message-log-max nil))
-          (yes-or-no-p
-           (format
-            "Such a Github API token is not available:
-
-  Host:    %s
-  User:    %s
-  Package: %s
-
-  Scopes requested in `%s-github-token-scopes':\n%s
-  Store on Github as:\n    %S
-  Store locally according to option `auth-sources':\n    %S
-%s
-If in doubt, then abort and first view the section of
-the Ghub documentation called \"Interactively Creating
-and Storing a Token\".
-
-Otherwise confirm and then provide your Github username and
-password at the next two prompts.  Depending on the backend
-you might have to provide a passphrase and confirm that you
-really want to save the token.
-
-Create and store such a token? "
-            host username package package
-            (mapconcat (lambda (scope) (format "    %s" scope)) scopes "\n")
-            ident auth-sources
-            (if (and (stringp (car auth-sources))
-                     (not (string-suffix-p ".gpg" (car auth-sources))))
-                (format "
-WARNING: The token will be stored unencrypted in %S.
-         If you don't want that, you have to abort and customize
-         the `auth-sources' option.\n" (car auth-sources))
-              ""))))
-        (condition-case err
-            ;; Naively attempt to create the token since the user told us to
-            (ghub-create-token host username package scopes)
-          ;; The API _may_ respond with the fact that a token of the name
-          ;; we wanted already exists. At this point we're out of luck. We
-          ;; don't have a token (otherwise why would we be here?) and, if
-          ;; the user is using SMS 2FA, we have no way of telling GitHub
-          ;; to send a new 2FA code to the user other than sending a POST
-          ;; to /authorizations which is ugly.
-          ;;
-          ;; If they are not using SMS 2FA then we could try to delete the
-          ;; existing token (which will require them to hand us another
-          ;; OTP for the delete request) and then call create again,
-          ;; possibly requiring _another_ OTP if they don't do things fast
-          ;; enough, but this is only because non-SMS 2FA doesn't require
-          ;; any action on GitHub's part.
-          ;;
-          ;; GitHub does hand us a header that indicates what type of 2FA
-          ;; is in use, but it's not currently available in this location
-          ;; and would make the following code which is already quite
-          ;; complicated even more complicated. So in the interest of
-          ;; simplicity it's better to error out here and ask the user to
-          ;; take action. This situation should almost never arise anyway.
-          (ghub-http-error
-           (if (equal (alist-get 'code (car (alist-get 'errors (nth 4 err))))
-                      "already_exists")
-               (error "A token named %S already exists on Github.
-Please visit https://github.com/settings/tokens and delete it." ident)
-             (signal (car err) (cdr err)))))
-      (user-error "Abort"))))
-
-(defun ghub--get-token-id (host username package)
-  (let ((ident (ghub--ident-github package)))
-    (cl-some (lambda (x)
-               (let-alist x
-                 (and (equal .app.name ident) .id)))
-             (ghub-get "/authorizations"
-                       '((per_page . 100))
-                       :unpaginate t
-                       :username username :auth 'basic :host host))))
-
-(defun ghub--get-token-plist (host username package)
-  (ghub-get (format "/authorizations/%s"
-                    (ghub--get-token-id host username package))
-            nil :username username :auth 'basic :host host))
-
-(defun ghub--delete-token (host username package)
-  (ghub-delete (format "/authorizations/%s"
-                       (ghub--get-token-id host username package))
-               nil :username username :auth 'basic :host host))
-
-(defun ghub--read-triplet ()
-  (let ((host (read-string "Host: " (ghub--host))))
-    (list host
-          (read-string "Username: " (ghub--username host))
-          (intern (read-string "Package: " "ghub")))))
-
-(defvar ghub--2fa-cache nil)
-
-(defun ghub--read-2fa-code ()
-  (let ((code (read-number "Two-factor authentication code: "
-                           (and ghub--2fa-cache
-                                (< (float-time (time-subtract
-                                                (current-time)
-                                                (cdr ghub--2fa-cache)))
-                                   25)
-                                (car ghub--2fa-cache)))))
-    (setq ghub--2fa-cache (cons code (current-time)))
-    (number-to-string code)))
-
-(defun ghub--auth-source-get (keys &rest spec)
-  (declare (indent 1))
-  (let ((plist (car (apply #'auth-source-search
-                           (append spec (list :max 1))))))
-    (mapcar (lambda (k)
-              (plist-get plist k))
-            keys)))
-
-(advice-add 'auth-source-netrc-parse-next-interesting :around
-            'auth-source-netrc-parse-next-interesting@save-match-data)
-(defun auth-source-netrc-parse-next-interesting@save-match-data (fn)
-  "Save match-data for the benefit of caller `auth-source-netrc-parse-one'.
-Without wrapping this function in `save-match-data' the caller
-won't see the secret from a line that is followed by a commented
-line."
-  (save-match-data (funcall fn)))
-
-;;; _
-(provide 'ghub)
-(require 'ghub-graphql)
-;;; ghub.el ends here
diff --git a/elpa/ghub-20190121.2116/ghub.info b/elpa/ghub-20190121.2116/ghub.info
deleted file mode 100644 (file)
index a54177b..0000000
+++ /dev/null
@@ -1,1315 +0,0 @@
-This is ghub.info, produced by makeinfo version 6.5 from ghub.texi.
-
-     Copyright (C) 2017-2019 Jonas Bernoulli <jonasNOSPAMbernoul.li>
-
-     You can redistribute this document and/or modify it under the terms
-     of the GNU General Public License as published by the Free Software
-     Foundation, either version 3 of the License, or (at your option)
-     any later version.
-
-     This document is distributed in the hope that it will be useful,
-     but WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-INFO-DIR-SECTION Emacs
-START-INFO-DIR-ENTRY
-* Ghub: (ghub).         Minuscule client library for the Github API.
-END-INFO-DIR-ENTRY
-
-\1f
-File: ghub.info,  Node: Top,  Next: Introduction,  Up: (dir)
-
-Ghub User and Developer Manual
-******************************
-
-Ghub provides basic support for using the APIs of various Git forges
-from Emacs packages.  Originally it only supported the Github REST API,
-but now it also supports the Github GraphQL API as well as the REST APIs
-of Gitlab, Gitea, Gogs and Bitbucket.
-
-   Ghub abstracts access to API resources using only a handful of basic
-functions such as â€˜ghub-get‘.  These are convenience wrappers around
-‘ghub-request‘.  Additional forge-specific wrappers like â€˜glab-put‘,
-‘gtea-put‘, â€˜gogs-post‘ and â€˜buck-delete‘ are also available.  Ghub does
-not provide any resource-specific functions, with the exception of
-‘FORGE-repository-id‘.
-
-   When accessing Github, then Ghub handles the creation and storage of
-access tokens using a setup wizard to make it easier for users to get
-started.  The tokens for other forges have to be created manually.
-
-   Ghub is intentionally limited to only provide these two essential
-features â€” basic request functions and guided setup â€” to avoid being too
-opinionated, which would hinder wide adoption.  It is assumed that wide
-adoption would make life easier for users and maintainers alike, because
-then all packages that talk to forge APIs could be configured the same
-way.
-
-This manual is for Ghub version 3.2.0 (v3.2.0-1-gae7acf4+1).
-
-     Copyright (C) 2017-2019 Jonas Bernoulli <jonasNOSPAMbernoul.li>
-
-     You can redistribute this document and/or modify it under the terms
-     of the GNU General Public License as published by the Free Software
-     Foundation, either version 3 of the License, or (at your option)
-     any later version.
-
-     This document is distributed in the hope that it will be useful,
-     but WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-* Menu:
-
-* Introduction::
-* Getting Started::
-* Using Ghub in Personal Scripts::
-* Using Ghub in a Package::
-* API::
-* GraphQL Support::
-* Support for Other Forges::
-
-— The Detailed Node Listing â€”
-
-Getting Started
-
-* Setting the Username::
-* Interactively Creating and Storing a Token::
-* Manually Creating and Storing a Token::
-* How Ghub uses Auth-Source::
-
-API
-
-* Making Requests::
-* Authentication::
-* Configuration Variables::
-
-Support for Other Forges
-
-* Forge Functions and Variables::
-* Forge Limitations and Notes::
-
-
-\1f
-File: ghub.info,  Node: Introduction,  Next: Getting Started,  Prev: Top,  Up: Top
-
-1 Introduction
-**************
-
-Ghub provides basic support for using the APIs of various Git forges
-from Emacs packages.  Originally it only supported the Github REST API,
-but now it also supports the Github GraphQL API as well as the REST APIs
-of Gitlab, Gitea, Gogs and Bitbucket.
-
-   Ghub abstracts access to API resources using only a handful of basic
-functions such as â€˜ghub-get‘.  These are convenience wrappers around
-‘ghub-request‘.  Additional forge-specific wrappers like â€˜glab-put‘,
-‘gtea-put‘, â€˜gogs-post‘ and â€˜buck-delete‘ are also available.  Ghub does
-not provide any resource-specific functions, with the exception of
-‘FORGE-repository-id‘.
-
-   When accessing Github, then Ghub handles the creation and storage of
-access tokens using a setup wizard to make it easier for users to get
-started.  The tokens for other forges have to be created manually.
-
-   Ghub is intentionally limited to only provide these two essential
-features â€” basic request functions and guided setup â€” to avoid being too
-opinionated, which would hinder wide adoption.  It is assumed that wide
-adoption would make life easier for users and maintainers alike, because
-then all packages that talk to forge APIs could be configured the same
-way.
-
-   Fancier interfaces can be implemented on top of Ghub, and one such
-wrapper â€” named simply Ghub+ â€” has already been implemented.  The
-benefit of basing various opinionated interfaces on top of a single
-library that provides only the core functionality is that choosing the
-programming interface no longer dictates how access tokens are handled.
-Users can then use multiple packages that access the Github API without
-having to learn the various incompatible ways packages expect the
-appropriate token to be made available to them.
-
-   Ghub uses the built-in â€˜auth-source’ library to store access tokens.
-That library is very flexible and supports multiple backends, which
-means that it is up to the user how secrets are stored.  They can, among
-other things, choose between storing secrets in plain text for ease of
-use, or encrypted for better security.
-
-   Previously (as in until this library is widely adopted) it was up to
-package authors to decide if things should be easy or secure.  (Note
-that â€˜auth-source’ defaults to "easy" â€” you have been warned.)
-
-   Ghub expects package authors to use a dedicated access token instead
-of sharing a single token between all packages that rely on it.  That
-means that users cannot configure Ghub once and later start using a new
-package without any additional setup.  But Ghub helps with that.
-
-   When the user invokes some command that ultimately results in
-‘ghub-request’ being called and the appropriate token is not available
-yet, then the user is guided through the process of creating and storing
-a new token, and at the end of that process the request is carried out
-as if the token had been available to begin with.
-
-\1f
-File: ghub.info,  Node: Getting Started,  Next: Using Ghub in Personal Scripts,  Prev: Introduction,  Up: Top
-
-2 Getting Started
-*****************
-
-Each package that uses Ghub uses its own token.  Despite that, chances
-are good that after successfully configuring one package you can just
-start using another package pretty much instantly.
-
-   If the necessary token to access a Github instance is not available
-when a package makes an API request, then a setup wizard pops up, and
-after answering a few questions you are good to go.  Even the request
-that caused the wizard to be summoned should succeed and for most users
-this should be true even when configuring the very first token.
-
-   However, in some situations some manual configuration is necessary
-*before* using the wizard, or the wizard cannot be used at all:
-
-   â€¢ If you don’t want to use the wizard then you don’t have to and can
-     create tokens manually as described in *note Manually Creating and
-     Storing a Token::.
-
-   â€¢ Unfortunately only Github supports the creation of tokens by using
-     the API.  If you want to access another forge, then you have to
-     create the token manually as describe in *note Manually Creating
-     and Storing a Token::.  Also see *note Support for Other Forges::.
-
-   â€¢ If you want to access a Github Enterprise instance, then you have
-     to tell Ghub about that before the wizard makes its appearance by
-     setting the Git variable â€˜github.host’.  You also have to tell Ghub
-     your username for that instance using the variable
-     â€˜github.HOST.user’ even if it is the same as on Github.com.
-
-     These variables are documented in *note Configuration Variables::.
-     Also see *note Setting the Username::.  TL;DR: If your Github
-     Enterprise instance is hosted at â€˜git.example.com’ and your
-     username on that instance is â€˜jtribbiani’, then set â€˜github.host’
-     to â€˜git.example.com/api/v3’ in every repository cloned from that
-     instance (i.e.  _do not_ set it globally) and _globally_ set
-     â€˜github.git.example.com/api/v3.user’ to â€˜jtribbiani’.  The latter
-     is necessary even if your username on Github.com is the same.
-
-   â€¢ If the variable â€˜github.user’ (or â€˜github.HOST.user’ for an
-     Enterprise instance) is unset when the wizard is first summoned,
-     then you are asked to provide your username.  That value is then
-     stored *globally* to avoid having to ask you that question once per
-     repository.  If you have multiple accounts on Github.com (or a
-     Github Enterprise instance), then you have to explicitly tell Ghub
-     about that.  This can be done by setting the repository-local
-     values of the appropriate variable *before* the wizard is invoked.
-
-   â€¢ You might forget to do the above, which is why it is important to
-     carefully read the output of the wizard.  If it turns out that you
-     forgot to set a variable, then you must abort, set the variable,
-     and repeat the request to trigger the wizard again.
-
-   â€¢ The setup wizard should work even if you have enabled two-factor
-     authentication.  However if your Github Enterprise instance
-     enforces Single Sign-On as an additional security measure, then you
-     are out of luck and have to create the token manually as described
-     in *note Manually Creating and Storing a Token::.
-
-   The variables mentioned above â€” and others â€” are documented in *note
-Configuration Variables:: and the setup wizard is documented in *note
-Interactively Creating and Storing a Token::.
-
-* Menu:
-
-* Setting the Username::
-* Interactively Creating and Storing a Token::
-* Manually Creating and Storing a Token::
-* How Ghub uses Auth-Source::
-
-\1f
-File: ghub.info,  Node: Setting the Username,  Next: Interactively Creating and Storing a Token,  Up: Getting Started
-
-2.1 Setting the Username
-========================
-
-If you haven’t set the Git variable â€˜github.user’ yet when making a
-request, then you will be asked:
-
-     Git variable `github.user' is unset.  Set to:
-
-   You are expected to provide your Github username here.  The provided
-value will be saved globally (using â€˜git config --global github.user
-USERNAME’).
-
-   If you need to identify as another user in a particular repository,
-then you have to set that variable locally, *before* making a request:
-
-     cd /path/to/repo
-     git config github.user USERNAME
-
-   For Github Enterprise instances you have to specify where the API can
-be accessed *before* you try to access it and a different variable has
-to be used to set the username.  For example if the API is available at
-‘https://example.com/api/v3’, then you should do this:
-
-     # Do this once
-     git config --global github.example.com/api/v3.user EMPLOYEE
-
-     # Do this for every corporate repository
-     cd /path/to/repo
-     git config github.host example.com/api/v3
-
-   If you do not set â€˜github.example.com/api/v3.user’, then you will be
-asked to provide the value when trying to make a request, but you do
-have to manually set â€˜github.host’, or Ghub assumes that you are trying
-to access â€˜api.github.com’.
-
-\1f
-File: ghub.info,  Node: Interactively Creating and Storing a Token,  Next: Manually Creating and Storing a Token,  Prev: Setting the Username,  Up: Getting Started
-
-2.2 Interactively Creating and Storing a Token
-==============================================
-
-Ghub uses a different token for every package as well as for every
-machine from which you access the Github API (and obviously also for
-every Github instance and user).  This allows packages to only request
-the scopes that they actually need and also gives users the opportunity
-to refuse access to certain scopes if they expect to not use the
-features that need them.
-
-   Usually you don’t have to worry about creating and storing a token
-yourself and can just make a request.  Note however that you don’t have
-to use the setup wizard described below.  Alternatively you can perform
-the setup manually as described in the next section.
-
-   If you make a request and the required token is not available yet,
-then the setup wizard will first ask you something like this:
-
-     Such a Github API token is not available:
-
-       Host:    api.github.com
-       User:    USERNAME
-       Package: PACKAGE
-
-       Scopes requested in `PACKAGE-github-token-scopes':
-         repo
-       Store on Github as:
-         "Emacs package PACKAGE @ LOCAL-MACHINE"
-       Store locally according to option `auth-sources':
-         ("~/.authinfo" "~/.authinfo.gpg" "~/.netrc")
-
-     If in doubt, then abort and first view the section of
-     the Ghub documentation called "Interactively Creating
-     and Storing a Token".
-
-     Create and store such a token? (yes or no)
-
-   If you don’t have any doubts, then answer "yes".  Lets address some
-of the doubts that you might have:
-
-   â€¢ â€˜Host’ usually is "api.github.com" and that is usually what you
-     want.  If you are trying to access a Github Enterprise instance,
-     then it should be something else and you have to set the value
-     manually before the setup wizard is summoned, as described in the
-     parent section.
-
-   â€¢ â€˜User’ should be your Github.com (or Github Enterprise instance)
-     username.  If it is something else and it doesn’t look like a
-     simple typo, then you should read the parent section again.  In
-     either case you have to abort.
-
-   â€¢ â€˜Package’ should be the name of the package you are using to access
-     the Github API.
-
-     If it is â€˜ghub’, then the package author disregarded that
-     convention and you should probably report a bug in the issue
-     tracker of that package.
-
-     Or you yourself are using â€˜ghub-request’ or one of its wrappers
-     directly, in which case this is expected and perfectly fine.  In
-     that case you might however want to abort and change the value of
-     the variable â€˜ghub-github-token-scopes’ before triggering the
-     wizard again.
-
-   â€¢ Each â€˜PACKAGE’ has to specify the tokens that it needs using a
-     variable named â€˜PACKAGE-github-token-scopes’.  The doc-string of
-     that variable should document why the various scopes are needed.
-
-     The meaning of the various scopes are documented at
-     <https://magit.vc/goto/f63aeb0a>.
-
-   â€¢ The value of â€˜auth-sources’ is shown.  The default value causes
-     secrets to be stored in plain text.  Because this might be
-     unexpected, Ghub additionally displays a warning when appropriate.
-
-          WARNING: The token will be stored unencrypted in "~/.authinfo".
-                   If you don't want that, you have to abort and customize
-                   the `auth-sources' option.
-
-     Whether that is something that needs fixing, is up to you.  If your
-     answer is yes, then you should abort and see *note How Ghub uses
-     Auth-Source:: for instructions on how to save the token more
-     securely.
-
-   â€¢ When creating a token it is necessary to provide a token
-     description.  Ghub uses descriptions that have the form "Emacs
-     package PACKAGE @ LOCAL-MACHINE".
-
-     Github uses the token description to identify the token, not merely
-     as something useful to humans.  Token descriptions therefore have
-     to be unique and in rare cases you get an additional prompt, asking
-     you something like:
-
-          A token named "Emacs package PACKAGE @ LOCAL-MACHINE"
-          already exists on Github.  Replace it?
-
-     You might see this message when you have lost the old token and
-     want to replace it with a new one, in which case you should
-     obviously just proceed.
-
-     Or two of your computers have the same hostname, which is bad
-     practice because it gains you nothing but leads to issues such as
-     this.  Or you are dual-booting on this machine and use the same
-     hostname in all operating systems, which is a somewhat reasonable
-     thing to do, but never-the-less leads to issues like this.
-
-     In either case you will have to use something other than the value
-     returned by â€˜system-name’ to identify the current machine or
-     operating system.  Or you can continue to identify different things
-     using the same identifier, in which case you have to manually
-     distribute the token.
-
-     The former is recommended and also easier to do, using the variable
-     â€˜ghub-override-system-name’.  See *note Configuration Variables::
-     for details.
-
-   After the above prompt you are also asked for your username and
-password.  If you have enabled two-factor authentication, then you also
-have to provide the authentication code at least twice.  If you make
-sure the code is still good for a while when asked for it first, then
-you can just press â€˜RET’ at the later prompt(s).
-
-\1f
-File: ghub.info,  Node: Manually Creating and Storing a Token,  Next: How Ghub uses Auth-Source,  Prev: Interactively Creating and Storing a Token,  Up: Getting Started
-
-2.3 Manually Creating and Storing a Token
-=========================================
-
-If you cannot or don’t want to use the wizard then you have to (1)
-figure out what scopes a package wants, (2) create such a token using
-the web interface and (3) store the token where Ghub expects to find it.
-
-   A package named â€˜PACKAGE’ has to specify the scopes that it wants in
-the variable named â€˜PACKAGE-github-token-scopes’.  The doc-string of
-such variables should document what the various scopes are needed for.
-
-   To create or edit a token go to <https://github.com/settings/tokens>.
-For Gitlab.com use <https://gitlab.com/profile/personal_access_tokens>.
-
-   Finally store the token in a place where Ghub looks for it, as
-described in *note How Ghub uses Auth-Source::.
-
-   If you store the token in a file like â€˜~/.authinfo’, then note that
-‘auth-source’’s parsing of that file is brittle.  Make sure the file
-ends with a newline character, that there are no empty or invalid lines,
-and that all comments are prefixed with â€˜#’.
-
-\1f
-File: ghub.info,  Node: How Ghub uses Auth-Source,  Prev: Manually Creating and Storing a Token,  Up: Getting Started
-
-2.4 How Ghub uses Auth-Source
-=============================
-
-Please see *note (auth)Top:: for all the gory details about Auth-Source.
-Some Ghub-specific information and important notes follow.
-
-   The variable â€˜auth-sources’ controls how and where Auth-Source stores
-new secrets and where it looks for known secrets.  The default value is
-‘("~/.authinfo" "~/.authinfo.gpg" "~/.netrc")’, which means that it
-looks in all of these files in order to find secrets and that it stores
-new secrets in â€˜~/.authinfo’ because that is the first element of the
-list.  It doesn’t matter which files already do or don’t exist when
-storing a new secret, the first file is always used.
-
-   Secrets are stored in â€˜~/.authinfo’ in plain text.  If you don’t want
-that (good choice), then you have to customize â€˜auth-sources’, e.g.  by
-flipping the positions of the first two elements.
-
-   Auth-Source also supports storing secrets in various key-chains.
-Refer to its documentation for more information.
-
-   Some Auth-Source backends only support storing three values per
-entry, the "machine", the "login" and the "password".  Because Ghub uses
-separate tokens for each package, it has to squeeze four values into
-those three slots, and it does that by using "USERNAME^PACKAGE" as the
-"login".
-
-   Assuming your username is "ziggy",the package is named "stardust",
-and you want to access *Github.com* an entry in one of the three
-mentioned files would then look like this:
-
-     machine api.github.com login ziggy^stardust password 012345abcdef...
-
-   Assuming your username is "ziggy",the package is named "stardust",
-and you want to access *Gitlab.com* an entry in one of the three
-mentioned files would then look like this:
-
-     machine gitlab.com/api/v4 login ziggy^stardust password 012345abcdef...
-
-\1f
-File: ghub.info,  Node: Using Ghub in Personal Scripts,  Next: Using Ghub in a Package,  Prev: Getting Started,  Up: Top
-
-3 Using Ghub in Personal Scripts
-********************************
-
-You can use â€˜ghub-request’ and its wrapper functions in your personal
-scripts, of course.  Unlike when you use Ghub from a package that you
-distribute for others to use, you don’t have to specify a package in
-personal scripts.
-
-     ;; This is perfectly acceptable in personal scripts ...
-     (ghub-get "/user")
-
-     ;; ... and actually equal to
-     (ghub-get "/user" nil :auth 'ghub)
-
-     ;; In packages you have to specify the package using AUTH.
-     (ghub-get "/user" nil :auth 'foobar)
-
-   When you do not specify the â€˜AUTH’ argument, then a request is made
-on behalf of the â€˜ghub’ package itself.  Like for any package that uses
-Ghub, â€˜ghub’ has to declare what scopes it needs, using, in this case,
-the variable â€˜ghub-github-token-scopes’.
-
-   The default value of that variable is â€˜(repo)’ and you might want to
-add additional scopes.  You can later add additional scopes to an
-existing token, using the web interface at
-<https://github.com/settings/tokens>.
-
-   If you do that, then you might want to also set the variable
-accordingly, but note that Ghub only consults that when *creating* a new
-token.  If you want to know a token’s effective scopes use the command
-‘ghub-token-scopes’, described in the next section.
-
-\1f
-File: ghub.info,  Node: Using Ghub in a Package,  Next: API,  Prev: Using Ghub in Personal Scripts,  Up: Top
-
-4 Using Ghub in a Package
-*************************
-
-Every package should use its own token.  This allows you as the author
-of some package to only request access to API scopes that are actually
-needed, which in turn might make it easier for users to trust your
-package not to do unwanted things.
-
-   The scopes used by â€˜PACKAGE’ have to be defined using the variable
-‘PACKAGE-github-token-scopes’, and you have to tell â€˜ghub-request’ on
-behalf of which package a request is being made by passing the symbol
-‘PACKAGE’ as the value of its â€˜AUTH’ argument.
-
-     (ghub-request "GET" "/user" nil :auth 'PACKAGE)
-
- -- Variable: PACKAGE-github-token-scopes
-
-     This variable defines the token scopes requested by the package
-     named â€˜PACKAGE’.  The doc-string should explain what the various
-     scopes are needed for to prevent users from giving â€˜PACKAGE’ fewer
-     permissions than it absolutely needs and also to give them greater
-     confidence that â€˜PACKAGE’ is only requesting the permissions that
-     it actually needs.
-
-     The value of this variable does not necessarily correspond to the
-     scopes that the respective token actually gives access to.  There
-     is nothing that prevents users from changing the value *after*
-     creating the token or from editing the token’s scopes later on.
-
-     So it is pointless to check the value of this variable before
-     making a request.  You also should not query the API to reliably
-     determine the supported tokens before making a query.  Doing the
-     latter would mean that every request becomes two requests and that
-     the first request would have to be done using the user’s password
-     instead of a token.
-
- -- Command: ghub-token-scopes
-
-     Because we cannot be certain that the user hasn’t messed up the
-     scopes, Ghub provides this command to make it easy to debug such
-     issues without having to rely on users being thoughtful enough to
-     correctly determine the used scopes manually.
-
-     Just tell users to run â€˜M-x ghub-token-scopes’ and to provide the
-     correct values for the â€˜HOST’, â€˜USERNAME’ and â€˜PACKAGE’ when
-     prompted, and to then post the output.
-
-     It is to be expected that users will occasionally mess that up so
-     this command outputs not only the scopes but also the user input so
-     that you can have greater confidence in the validity of the user’s
-     answer.
-
-          Scopes for USERNAME^PACKAGE@HOST: (SCOPE...)
-
-\1f
-File: ghub.info,  Node: API,  Next: GraphQL Support,  Prev: Using Ghub in a Package,  Up: Top
-
-5 API
-*****
-
-This section describes the Ghub API.  In other words it describes the
-public functions and variables provided by the Ghub package and not the
-APIs of the supported forges, which can be accessed by using those
-functions.  The forge APIs are documented at:
-
-   â€¢ Github: <https://developer.github.com/v3>
-
-   â€¢ Gitlab: <https://docs.gitlab.com/ee/api/README.html>
-
-   â€¢ Gitea: <https://docs.gitea.io/en-us/api-usage> and
-     <https://try.gitea.io/api/swagger>
-
-   â€¢ Gogs: <https://github.com/gogs/go-gogs-client/wiki>
-
-   â€¢ Bitbucket:
-     <https://developer.atlassian.com/bitbucket/api/2/reference>
-
-* Menu:
-
-* Making Requests::
-* Authentication::
-* Configuration Variables::
-
-\1f
-File: ghub.info,  Node: Making Requests,  Next: Authentication,  Up: API
-
-5.1 Making Requests
-===================
-
- -- Function: ghub-request method resource &optional params &key query
-          payload headers unpaginate noerror reader username auth host
-          callback errorback url value error extra method*
-
-     This function makes a request for â€˜RESOURCE’ using â€˜METHOD’.
-     â€˜PARAMS’, â€˜QUERY’, â€˜PAYLOAD’ and/or â€˜HEADERS’ are alists holding
-     additional request data.  The response body is returned and the
-     response headers are stored in the variable
-     â€˜ghub-response-headers’.
-
-        â€¢ â€˜METHOD’ is the HTTP method, given as a string.
-
-        â€¢ â€˜RESOURCE’ is the resource to access, given as a string
-          beginning with a slash.
-
-        â€¢ â€˜PARAMS’, â€˜QUERY’, â€˜PAYLOAD’ and â€˜HEADERS’ are alists and are
-          used to specify request data.  All these arguments are alists
-          that resemble the JSON expected and returned by the Github
-          API.  The keys are symbols and the values stored in the â€˜cdr’
-          (not the â€˜cadr’) can be strings, integers, or lists of strings
-          and integers.
-
-          The Github API documentation is vague on how data has to be
-          transmitted and for a particular resource usually just talks
-          about "parameters".  Generally speaking when the â€˜METHOD’ is
-          "HEAD" or "GET", then they have to be transmitted as a query,
-          otherwise as a payload.
-
-             â€¢ Use â€˜PARAMS’ to automatically transmit like â€˜QUERY’ or
-               â€˜PAYLOAD’ would depending on â€˜METHOD’.
-
-             â€¢ Use â€˜QUERY’ to explicitly transmit data as a query.
-
-             â€¢ Use â€˜PAYLOAD’ to explicitly transmit data as a payload.
-               Instead of an alist, â€˜PAYLOAD’ may also be a string, in
-               which case it gets encoded as UTF-8 but is otherwise
-               transmitted as-is.
-
-             â€¢ Use â€˜HEADERS’ for those rare resources that require that
-               the data is transmitted as headers instead of as a query
-               or payload.  When that is the case, then the Github API
-               documentation usually mentions it explicitly.
-
-        â€¢ If â€˜SILENT’ is non-nil, then progress reports and the like are
-          not messaged.
-
-        â€¢ If â€˜UNPAGINATE’ is t, then this function make as many requests
-          as necessary to get all values.  If â€˜UNPAGINATE’ is a natural
-          number, then it gets at most that many pages.  For any other
-          non-nil value it raises an error.
-
-        â€¢ If â€˜NOERROR’ is non-nil, then no error is raised if the
-          request fails and â€˜nil’ is returned instead.  If â€˜NOERROR’ is
-          â€˜return’, then the error payload is returned instead of â€˜nil’.
-
-        â€¢ If â€˜READER’ is non-nil, then it is used to read and return
-          from the response buffer.  The default is
-          â€˜ghub--read-json-payload’.  For the very few resources that do
-          not return JSON, you might want to use â€˜ghub--decode-payload’.
-
-        â€¢ If â€˜USERNAME’ is non-nil, then the request is made on behalf
-          of that user.  It is better to specify the user using the Git
-          variable â€˜github.user’ for "api.github.com", or
-          â€˜github.HOST.user’ if connecting to a Github Enterprise
-          instance.
-
-        â€¢ Each package that uses Ghub should use its own token.  If
-          â€˜AUTH’ is â€˜nil’ or unspecified, then the generic â€˜ghub’ token
-          is used instead.  This is only acceptable for personal
-          utilities.  A packages that is distributed to other users
-          should always use this argument to identify itself, using a
-          symbol matching its name.
-
-          Package authors who find this inconvenient should write a
-          wrapper around this function and possibly for the
-          method-specific functions as well.
-
-          Beside â€˜nil’, some other symbols have a special meaning too.
-          â€˜none’ means to make an unauthorized request.  â€˜basic’ means
-          to make a password based request.  If the value is a string,
-          then it is assumed to be a valid token.  â€˜basic’ and an
-          explicit token string are only intended for internal and
-          debugging uses.
-
-          If â€˜AUTH’ is a package symbol, then the scopes are specified
-          using the variable â€˜AUTH-github-token-scopes’.  It is an error
-          if that is not specified.  See â€˜ghub-github-token-scopes’ for
-          an example.
-
-        â€¢ If â€˜HOST’ is non-nil, then connect to that Github instance.
-          This defaults to "api.github.com".  When a repository is
-          connected to a Github Enterprise instance, then it is better
-          to specify that using the Git variable â€˜github.host’ instead
-          of using this argument.
-
-        â€¢ If â€˜FORGE’ is â€˜gitlab’, then connect to Gitlab.com or,
-          depending on â€˜HOST’, to another Gitlab instance.  This is only
-          intended for internal use.  Instead of using this argument you
-          should use function â€˜glab-request’ and other â€˜glab-*’
-          functions.
-
-        â€¢ If â€˜CALLBACK’ and/or â€˜ERRORBACK’ is non-nil, then this
-          function makes one or more asynchronous requests and calls
-          â€˜CALLBACK’ or â€˜ERRORBACK’ when finished.  If no error
-          occurred, then it calls â€˜CALLBACK’, unless that is â€˜nil’.
-
-          If an error occurred, then it calls â€˜ERRORBACK’, or if that is
-          nil, then â€˜CALLBACK’.  â€˜ERRORBACK’ can also be â€˜t’, in which
-          case it signals instead.  â€˜NOERROR’ is ignored for all
-          asynchronous requests.
-
-          Both callbacks are called with four arguments.
-
-             â€¢ For â€˜CALLBACK’, the combined value of the retrieved
-               pages.  For â€˜ERRORBACK’, the error that occured when
-               retrieving the last page.
-
-             â€¢ The headers of the last page as an alist.
-
-             â€¢ Status information provided by â€˜url-retrieve’.  Its
-               â€˜:error’ property holds the same information as the first
-               argument to â€˜ERRORBACK’.
-
-             â€¢ A â€˜ghub--req’ struct, which can be passed to
-               â€˜ghub-continue’ (which see) to retrieve the next page, if
-               any.
-
- -- Function: ghub-continue args
-
-     If there is a next page, then this function retrieves that.
-
-     This function is only intended to be called from callbacks.  If
-     there is a next page, then that is retrieved and the buffer that
-     the result will be loaded into is returned, or t if the process has
-     already completed.  If there is no next page, then return nil.
-
-     Callbacks are called with four arguments (see â€˜ghub-request’).  The
-     forth argument is a â€˜ghub--req’ struct, intended to be passed to
-     this function.  A callback may use the struct’s â€˜extra’ slot to
-     pass additional information to the callback that will be called
-     after the next request.  Use the function â€˜ghub-req-extra’ to get
-     and set the value of that slot.
-
-     As an example, using â€˜ghub-continue’ in a callback like so:
-
-          (ghub-get "/users/tarsius/repos" nil
-                    :callback (lambda (value _headers _status req)
-                                (unless (ghub-continue req)
-                                  (setq my-value value))))
-
-     is equivalent to:
-
-          (ghub-get "/users/tarsius/repos" nil
-                    :unpaginate t
-                    :callback (lambda (value _headers _status _req)
-                                (setq my-value value)))
-
-     To demonstrate how to pass information from one callback to the
-     next, here we record when we start fetching each page:
-
-          (ghub-get "/users/tarsius/repos" nil
-                    :extra (list (current-time))
-                    :callback (lambda (value _headers _status req)
-                                (push (current-time) (ghub-req-extra req))
-                                (unless (ghub-continue req)
-                                  (setq my-times (ghub-req-extra req))
-                                  (setq my-value value))))
-
- -- Variable: ghub-response-headers
-
-     A select few Github API resources respond by transmitting data in
-     the response header instead of in the response body.  Because there
-     are so few of these inconsistencies, â€˜ghub-request’ always returns
-     the response body.
-
-     To access the response headers use this variable after
-     â€˜ghub-request’ has returned.
-
- -- Function: ghub-response-link-relations req headers payload
-
-     This function returns an alist of the link relations in â€˜HEADERS’,
-     or if optional â€˜HEADERS’ is nil, then those in
-     â€˜ghub-response-headers’.
-
-     When accessing a Bitbucket instance then the link relations are in
-     â€˜PAYLOAD’ instead of â€˜HEADERS’, making their API merely RESTish and
-     forcing this function to append those relations to the value of
-     â€˜ghub-response-headers’, for later use when this function is called
-     with â€˜nil’ for â€˜PAYLOAD’.
-
- -- Variable: ghub-override-system-name
-
-     If non-nil, the value of this variable is used to override the
-     value returned by â€˜system-name’ for the purpose of identifying the
-     local machine, which is necessary because Ghub uses separate tokens
-     for each machine.  Also see *note Configuration Variables::.
-
- -- Variable: ghub-github-token-scopes
- -- Variable: PACKAGE-github-token-scopes
-
-     Such a variable defines the token scopes requested by the
-     respective package â€˜PACKAGE’ given by the first word in the
-     variable name.  â€˜ghub’ itself is treated like any other package.
-     Also see *note Using Ghub in a Package::.
-
- -- Function: ghub-head resource &optional params &key query payload
-          headers unpaginate noerror reader username auth host callback
-          errorback
- -- Function: ghub-get resource &optional params &key query payload
-          headers unpaginate noerror reader username auth host callback
-          errorback
-
-     These functions are simple wrappers around â€˜ghub-request’.  Their
-     signature is identical to that of the latter, except that they do
-     not have an argument named â€˜METHOD’.  The HTTP method is instead
-     given by the second word in the function name.
-
-     As described in the documentation for â€˜ghub-request’, it depends on
-     the used method whether the value of the â€˜PARAMS’ argument is used
-     as the query or the payload.  For the "HEAD" and "GET" methods it
-     is used as the query.
-
- -- Function: ghub-put resource &optional params &key query payload
-          headers unpaginate noerror reader username auth host callback
-          errorback
- -- Function: ghub-post resource &optional params &key query payload
-          headers unpaginate noerror reader username auth host callback
-          errorback
- -- Function: ghub-patch resource &optional params &key query payload
-          headers unpaginate noerror reader username auth host callback
-          errorback
- -- Function: ghub-delete resource &optional params &key query payload
-          headers unpaginate noerror reader username auth host callback
-          errorback
-
-     These functions are simple wrappers around â€˜ghub-request’.  Their
-     signature is identical to that of the latter, except that they do
-     not have an argument named â€˜METHOD’.  The HTTP method is instead
-     given by the second word in the function name.
-
-     As described in the documentation for â€˜ghub-request’, it depends on
-     the used method whether the value of the â€˜PARAMS’ argument is used
-     as the query or the payload.  For the "PUT", "POST", "PATCH" and
-     "DELETE" methods it is used as the payload.
-
- -- Function: ghub-wait resource &optional duration &key username auth
-          host
-
-     Some API requests result in an immediate successful response even
-     when the requested action has not actually been carried out yet.
-     An example is the request for the creation of a new repository,
-     which doesn’t cause the repository to immediately become available.
-     The Github API documentation usually mentions this when describing
-     an affected resource.
-
-     If you want to do something with some resource right after making a
-     request for its creation, then you might have to wait for it to
-     actually be created.  This function can be used to do so.  It
-     repeatedly tries to access the resource until it becomes available
-     or until the timeout exceeds.  In the latter case it signals
-     â€˜ghub-error’.
-
-     â€˜RESOURCE’ specifies the resource that this function waits for.
-
-     â€˜DURATION’ specifies the maximum number of seconds to wait for,
-     defaulting to 64 seconds.  Emacs will block during that time, but
-     the user can abort using â€˜C-g’.
-
-     The first attempt is made immediately and will often succeed.  If
-     not, then another attempt is made after two seconds, and each
-     subsequent attempt is made after waiting as long as we already
-     waited between all preceding attempts combined.
-
-     See â€˜ghub-request’’s documentation above for information about the
-     other arguments.
-
- -- Function: ghub-graphql graphql &optional variables &key username
-          auth host callback
-
-     This function makes a GraphQL request using â€˜GRAPHQL’ and
-     â€˜VARIABLES’ as inputs.  â€˜GRAPHQL’ is a GraphQL string.  â€˜VARIABLES’
-     is a JSON-like alist.  The other arguments behave as for
-     â€˜ghub-request’ (which see).
-
-     The response is returned as a JSON-like alist.  Even if the
-     response contains â€˜errors’, this function does not raise an error.
-     Cursor-handling is likewise left to the caller.
-
-\1f
-File: ghub.info,  Node: Authentication,  Next: Configuration Variables,  Prev: Making Requests,  Up: API
-
-5.2 Authentication
-==================
-
- -- Command: ghub-create-token
-
-     This command creates a new token using the values it reads from the
-     user and then stores it according to the variable â€˜auth-sources’.
-     It can also be called non-interactively, but you shouldn’t do that
-     yourself.
-
-     This is useful if you want to fully setup things before attempting
-     to make the initial request, if you want to provide fewer than the
-     requested scopes or customize â€˜auth-sources’ first, or if something
-     has gone wrong when using the wizard that is used when making a
-     request without doing this first.  (Note that instead of using this
-     command you can also just repeat the initial request after making
-     the desired adjustments â€” that is easier.)
-
-     This command reads, in order, the â€˜HOST’ (Github instance), the
-     â€˜USERNAME’, the â€˜PACKAGE’, and the â€˜SCOPES’ in the minibuffer,
-     providing reasonable default choices.  â€˜SCOPES’ defaults to the
-     scopes that â€˜PACKAGE’ requests using the variable
-     â€˜PACKAGE-github-token-scopes’.
-
- -- Command: ghub-token-scopes
-
-     Users are free to give a token access to fewer scopes than what the
-     respective package requested.  That can, of course, lead to issues,
-     and package maintainers have to be able to quickly determine if
-     such a (mis-)configuration is the root cause when users report
-     issues.
-
-     This command reads the required values in the minibuffer and then
-     shows a message containing these values along with the scopes of
-     the respective token.  It also returns the scopes (only) when
-     called non-interactively.  Also see *note Using Ghub in a
-     Package::.
-
-\1f
-File: ghub.info,  Node: Configuration Variables,  Prev: Authentication,  Up: API
-
-5.3 Configuration Variables
-===========================
-
-The username and, unless you only use Github.com itself, the Github
-Enterprise instance have to be configured using Git variables.  In rare
-cases it might also be necessary to specify the identity of the local
-machine, which is done using a lisp variable.
-
- -- Variable: github.user
-
-     The Github.com username.  This should be set globally and if you
-     have multiple Github.com user accounts, then you should set this
-     locally only for those repositories that you want to access using
-     the secondary identity.
-
- -- Variable: github.HOST.user
-
-     This variable serves the same purpose as â€˜github.user’ but for the
-     Github Enterprise instance identified by â€˜HOST’.
-
-     The reason why separate variables are used is that this makes it
-     possible to set both values globally instead of having to set one
-     of the values locally in each and every repository that is
-     connected to the Github Enterprise instance, not Github.com.
-
- -- Variable: github.host
-
-     This variable should only be set locally for a repository and
-     specifies the Github Enterprise edition that that repository is
-     connected to.  You should not set this globally because then each
-     and every repository becomes connected to the specified Github
-     Enterprise instance, including those that should actually be
-     connected to Github.com.
-
-     When this is undefined, then "api.github.com" is used (defined in
-     the constant â€˜ghub-default-host’, which you should never attempt to
-     change.)
-
- -- Variable: ghub-override-system-name
-
-     Ghub uses a different token for each quadruple â€˜(USERNAME PACKAGE
-     HOST LOCAL-MACHINE)’.  Theoretically it could reuse tokens to some
-     extent but that would be more difficult to implement, less
-     flexible, and less secure (though slightly more convenient).
-
-     A token is identified on the respective Github instance (Github.com
-     or a Github Enterprise instance) using the pair â€˜(PACKAGE .
-     LOCAL-MACHINE)’, or more precisely the string "Emacs package
-     PACKAGE @ LOCAL-MACHINE". â€˜USERNAME’ and â€˜HOST’ do not have to be
-     encoded because the token is stored for â€˜USERNAME’ on â€˜HOST’ and
-     cannot be used by another user and/or on another instance.
-
-     There is one potential problem though; for any given â€˜(PACKAGE .
-     LOCAL-MACHINE)’ there can only be one token identified by "Emacs
-     package PACKAGE @ LOCAL-MACHINE"; Github does not allow multiple
-     tokens with the same description because it uses the description as
-     the identifier (it could use some hash instead, but alas it does
-     not).
-
-     If you have multiple machines and some of them have the same name,
-     then you should probably change that as this is not how things
-     ought to be.  However if you dual-boot, then it might make sense to
-     give that machine the same name regardless of what operating system
-     you have booted into.
-
-     You could use the same token on both operating systems, but setting
-     that up might be somewhat difficult because it is not possible to
-     download an existing token from Github.  You could, of course,
-     locally copy the token, but that is inconvenient and would make it
-     harder to only revoke the token used on your infected Windows
-     installation without also revoking it for your totally safe *BSD
-     installation.
-
-     Alternatively you can set this variable to a unique value, that
-     will then be used to identify the local machine instead of the
-     value returned by â€˜system-name’.
-
-\1f
-File: ghub.info,  Node: GraphQL Support,  Next: Support for Other Forges,  Prev: API,  Up: Top
-
-6 GraphQL Support
-*****************
-
- -- Function: ghub-graphql graphql &optional variables &key username
-          auth host callback silent callback errorback value extra
-
-     This function makes a GraphQL request using â€˜GRAPHQL’ and
-     â€˜VARIABLES’ as inputs.  â€˜GRAPHQL’ is a GraphQL string.  â€˜VARIABLES’
-     is a JSON-like alist.  The other arguments behave as for
-     â€˜ghub-request’ (which see).
-
-     The response is returned as a JSON-like alist.  Even if the
-     response contains â€˜errors’, this function does not raise an error.
-     Cursor-handling is likewise left to the caller.
-
-   â€˜ghub-graphql’ is a thin convenience wrapper around â€˜ghub-request’,
-similar to â€˜ghub-post’ and friends.  While the latter only hard-code the
-value of the â€˜METHOD’ argument, the former also hard-codes â€˜RESOURCE’
-and constructs â€˜PAYLOAD’ from â€˜GRAPHEQL’ and â€˜VARIABLES’.  It also drops
-‘UNPAGINATE’, â€˜NOERROR’, â€˜READER’ (internal functions expect alist-ified
-JSON) and â€˜FORGE’ (only Github currently supports GraphQL).
-
-   â€˜ghub-graphql’ does not account for the fact that pagination works
-differently in GraphQL than it does in REST, so users of this function
-have to deal with that themselves.  Likewise error handling works
-differently and has to be done by the caller too.
-
-   An early attempt at implementing automatic unpaginating for GraphQL
-can be found in the â€˜faithful-graphql’ branch, provided I haven’t
-deleted that by now.  On that branch I try to do things as intended by
-the designers of GraphQL, using variables and fragments, and drowning in
-a sea of boilerplate.
-
-   The problem with that approach is that it only works for applications
-that fetch specific information on demand and actually want things to be
-paginated.  I am convinced that GraphQL is very nice for web apps.
-
-   However the Forge package for which I am implementing all of this has
-very different needs.  It wants to fetch "all the data" and "cache" it
-locally, so that it is available even when there is no internet
-connection.  GraphQL was designed around the idea that you should be
-able to "ask for what you need and get exactly that".  But when that
-boils down to "look, if I persist, then you are going to hand me over
-all the data anyway, so just caught it up already", then things start to
-fall apart.  If Github’s GraphQL allowed pagination to be turned off
-completely, then teaching â€˜ghub-graphql’ about error handling would be
-enough.
-
-   But it doesn’t and when doing things as intended, then that leads to
-huge amounts of repetitive boilerplate, which is so boring to write that
-doing it without introducing bugs left and right is near impossible; so
-I decided to give up on GraphQL variables, fragments and conditions, and
-instead implement something more powerful, though also more opinionated.
-
- -- Function: ghub--graphql-vacuum query variables callback &optional
-          until &key narrow username auth host forge
-
-     This function is an opinionated alternative to â€˜ghub-graphql’.  It
-     relies and dark magic to get the job done.
-
-     It makes an initial request using â€˜QUERY’.  It then looks for
-     paginated edges in the returned data and makes more requests to
-     resolve them.  In order to do so it automatically transforms the
-     initial â€˜QUERY’ into another query suitable for that particular
-     edge.  The data retrieved by subsequent requests is then injected
-     into the data of the original request before that is returned or
-     passed to the callback.  If subsequently retrieved data features
-     new paginated edges, then those are followed recursively.
-
-     The end result is essentially the same as using â€˜ghub-graphql’, if
-     only it were possible to say "do not paginate anything".  The
-     implementation is much more complicated because it is not possible
-     to do that.
-
-     â€˜QUERY’ is a GraphQL query expressed as an s-expression.  The
-     â€˜graphql’ package is used to turn that into a GraphQL query string,
-     but the format is somewhat different than as documented for that
-     package.  Also only a subset of the GraphQL features are supported;
-     fragments for example are not, and magical stuff happens to
-     variables.  This is not documented yet, I am afraid.  Look at
-     existing callers.
-
-     â€˜VARIABLES’ is a JSON-like alist as for â€˜ghub-graphql’.
-
-     â€˜UNTIL’ is an alist â€˜((EDGE-until . VALUE)...)’.  When unpaginating
-     â€˜EDGE’ try not to fetch beyond the element whose first field has
-     the value â€˜VALUE’ and remove that element as well as all "lesser"
-     elements from the retrieved data if necessary.  Look at
-     â€˜forge--pull-repository’ for an example.  This is only useful if
-     you "cache" the response locally and want to avoid fetching data
-     again that you already have.
-
-     Other arguments behave as for â€˜ghub-graphql’ and â€˜ghub-request’,
-     more or less.
-
-   Using â€˜ghub--graphql-vacuum’, the following resource specific
-functions are implemented.  These functions are not part of the public
-API yet and are very much subject to change.
-
- -- Function: ghub-fetch-repository owner name callback &optional until
-          &key username auth host forge
-
-     This function asynchronously fetches forge data about the specified
-     repository.  Once all data has been collected, â€˜CALLBACK’ is called
-     with the data as the only argument.
-
- -- Function: ghub-fetch-issue owner name callback &optional until &key
-          username auth host forge
-
-     This function asynchronously fetches forge data about the specified
-     issue.  Once all data has been collected, â€˜CALLBACK’ is called with
-     the data as the only argument.
-
- -- Function: ghub-fetch-pullreq owner name callback &optional until
-          &key username auth host forge
-
-     This function asynchronously fetches forge data about the specified
-     pull-request.  Once all data has been collected, â€˜CALLBACK’ is
-     called with the data as the only argument.
-
-   Note that in order to avoid duplication all of these functions base
-their initial query on the query stored in â€˜ghub-fetch-repository’.  The
-latter two pass that query through â€˜ghub--graphql-prepare-query’, which
-then used â€˜ghub--graphql-narrow-query’ to remove parts the caller is not
-interested in.  These two functions are also used internally, when
-unpaginating, but as demonstrated here they can be useful even before
-making an initial request.
-
-\1f
-File: ghub.info,  Node: Support for Other Forges,  Prev: GraphQL Support,  Up: Top
-
-7 Support for Other Forges
-**************************
-
-* Menu:
-
-* Forge Functions and Variables::
-* Forge Limitations and Notes::
-
-\1f
-File: ghub.info,  Node: Forge Functions and Variables,  Next: Forge Limitations and Notes,  Up: Support for Other Forges
-
-7.1 Forge Functions and Variables
-=================================
-
-Originally Ghub supported only Github but now it also supports Gitlab,
-Gitea, Gogs and Bitbucket.  The function â€˜ghub-request’ and all the
-‘ghub-METHOD’ convenience wrappers default to acting on a Github forge
-but can be told to act on another forge using their FORGE argument.
-
-   The FORGE argument only specifies what kind of forge to act on, not
-which instance.  The HOST argument can be used to select the instance.
-For some forges a default instance is defined:
-
-   â€¢ Forge â€˜github’ defaults to host â€˜api.github.com’.
-
-   â€¢ Forge â€˜gitlab’ defaults to host â€˜gitlab.com/api/v4’.
-
-   â€¢ Forge â€˜bitbucket’ defaults to host â€˜api.bitbucket.org/2.0’.
-
-   â€¢ No canonical host exists for the â€˜gitea’ and â€˜gogs’ forges and
-     â€˜localhost:3000/api/v1’ is used as the default host in both cases.
-
-   Together the FORGE and HOST arguments specify the forge type and
-instance.  In addition to that, it is also necessary to specify on whose
-behalf the request is being made, which can be done using the USERNAME
-and AUTH arguments.
-
-   Having to specify these arguments for every request is inconvenient.
-Additional variables and convenience functions can be used to make that
-unnecessary in most cases.
-
-   These variables can be set globally and/or for a specific repository
-as explained in *note Configuration Variables:: with a focus on Github
-instances.  To summarize:
-
-   â€¢ For <https://github.com> the Git variable â€˜github.user’ specifies
-     the user.
-
-   â€¢ For another â€˜github’ instance the Git variable â€˜github.HOST.user’
-     specifies the user.  The HOST in that variable name is the same as
-     the value of the HOST argument of the called function.
-
-   â€¢ Instead of specifying the HOST in every function call, the Git
-     variable â€˜github.host’ can be used.  This should only be set
-     locally.
-
-For â€˜gitlab’ and â€˜bitbucket’ forges similar variables are available:
-
-   â€¢ â€˜gitlab.user’ specifies the <https://gitlab.com> user.
-
-   â€¢ â€˜gitlab.HOST.user’ specifies the user for the HOST â€˜gitlab’
-     instance.
-
-   â€¢ â€˜gitlab.host’ specifies the â€˜gitlab’ host, unless the HOST argument
-     is non-nil
-
-   â€¢ â€˜bitbucket.user’ specifies the <https://bitbucket.org> user.
-
-   â€¢ â€˜bitbucket.HOST.user’ specifies the user for the HOST â€˜bitbucket’
-     instance.
-
-   â€¢ â€˜bitbucket.host’ specifies the â€˜bitbucket’ host, unless the HOST
-     argument is non-nil.
-
-   For â€˜gitea’ and â€˜gogs’ forges some similar variables are available,
-however for some of the â€˜ghub.*’ variables no equivalent variable exist
-for these two forges:
-
-   â€¢ â€˜gitea.user’ is *not* used because no canonical â€˜gitea’ instance
-     exists.
-
-   â€¢ â€˜gitea.HOST.user’ specifies the user for the HOST â€˜gitea’ instance.
-
-   â€¢ â€˜gitea.host’ specifies the â€˜gitea’ host, unless the HOST argument
-     is non-nil
-
-   â€¢ â€˜gogs.user’ is *not* used because no canonical â€˜gitea’ instance
-     exists.
-
-   â€¢ â€˜gogs.HOST.user’ specifies the user for the HOST â€˜gogs’ instance.
-
-   â€¢ â€˜gogs.host’ specifies the â€˜gogs’ host, unless the HOST argument is
-     non-nil
-
-   â€˜ghub-request’ and â€˜ghub-METHOD’ can be used to make a request for
-any of the supported forge types, but except when making a request for a
-‘github’ instance, then that requires the use of the FORGE argument.
-
-   To avoid that, functions named â€˜FORGE-request’ and â€˜FORGE-METHOD’ are
-also available.  The following forms are equivalent, for example:
-
-     (ghub-get ... :auth 'PACKAGE :forge 'gitlab)
-     (glab-get ... :auth 'PACKAGE)
-
-   These forms would remain equivalent even if you did not specify a
-value for the AUTH arguments â€” but you should not do that if you plan to
-share your code with others (see *note Using Ghub in a Package::).  If
-you do omit AUTH, then the request is made on behalf of the â€˜ghub’
-package, *regardless* of the symbol prefix of the function you use to do
-so.
-
-   All â€˜FORGE-request’ and â€˜FORGE-METHOD’ functions, including but not
-limited to â€˜ghub-METHOD’, are very simple wrappers around
-‘ghub-request’.  They take fewer arguments than â€˜ghub-request’ and
-instead pass constant values for the arguments METHOD and/or FORGE.
-
-\1f
-File: ghub.info,  Node: Forge Limitations and Notes,  Prev: Forge Functions and Variables,  Up: Support for Other Forges
-
-7.2 Forge Limitations and Notes
-===============================
-
-   â€¢ The token creation wizard is only available for â€˜github’ forges,
-     because all other forges do not support using the API to create an
-     API token.  As a consequence, if the user makes a request and the
-     necessary token cannot be found, then that results in an error.
-     Tokens can be created at:
-
-        â€¢ Gitlab: <https://gitlab.com/profile/personal_access_tokens>
-
-        â€¢ Bitbucket:
-          <https://bitbucket.org/account/user/tarsius/app-passwords>
-
-        â€¢ Gitea: <https://localhost:3000/user/settings/applications>
-
-        â€¢ Gogs: <https://localhost:3000/user/settings/applications>
-
-     Also see *note Manually Creating and Storing a Token:: and *note
-     How Ghub uses Auth-Source::.
-
-   â€¢ As mentioned in the previous node, the variables â€˜gitea.host’ and
-     â€˜gogs.host’ are not taken into account.
-
-   â€¢ Gitea and Gogs do not support limiting a token to certain scopes.
-
-   â€¢ The Bitbucket API is fairly broken.  Some resources only work if a
-     slash is appended while others only work if no slash is appended.
-     I am unable to access any private repositories and some resources
-     don’t work for me at all.  Also the API is only RESTish; pagination
-     information is part of the response body instead of the header.
-     Due to such issues it is possible that I will eventually have to
-     remove support for Bitbucket altogether.
-
-   â€¢ The Gitlab API documentation is not always accurate, though I don’t
-     have an example at hand.  It also isn’t structured well, making it
-     occationally difficult to find the information one is looking for.
-
-   â€¢ Where one would use â€˜user/repo’ when accessing another forge, one
-     has to use â€˜user%2Frepo’ when accessing Gitlab, e.g.:
-
-          (glab-get "/projects/python-mode-devs%2Fpython-mode")
-
-
-\1f
-Tag Table:
-Node: Top\7f764
-Node: Introduction\7f3279
-Node: Getting Started\7f6321
-Node: Setting the Username\7f10055
-Node: Interactively Creating and Storing a Token\7f11480
-Node: Manually Creating and Storing a Token\7f17131
-Node: How Ghub uses Auth-Source\7f18356
-Node: Using Ghub in Personal Scripts\7f20289
-Node: Using Ghub in a Package\7f21745
-Node: API\7f24363
-Node: Making Requests\7f25160
-Node: Authentication\7f39259
-Node: Configuration Variables\7f41104
-Node: GraphQL Support\7f44824
-Node: Support for Other Forges\7f51489
-Node: Forge Functions and Variables\7f51706
-Node: Forge Limitations and Notes\7f56225
-\1f
-End Tag Table
-
-\1f
-Local Variables:
-coding: utf-8
-End:
diff --git a/elpa/ghub-20190121.2116/glab.el b/elpa/ghub-20190121.2116/glab.el
deleted file mode 100644 (file)
index 8aec40e..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-;;; glab.el --- minuscule client library for the Gitlab API  -*- lexical-binding: t -*-
-
-;; Copyright (C) 2016-2019  Jonas Bernoulli
-
-;; Author: Jonas Bernoulli <jonasNOSPAMbernoul.li>
-;; Homepage: https://github.com/magit/ghub
-;; Keywords: tools
-
-;; This file is not part of GNU Emacs.
-
-;; This file is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
-
-;; This file is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; For a copy of the GPL see https://www.gnu.org/licenses/gpl.txt.
-
-;;; Commentary:
-
-;; Glab is a library that provides basic support for using the Gitlab API
-;; from Emacs packages.  It abstracts access to API resources using only
-;; a handful of functions that are not resource-specific.
-
-;; This library is implemented on top of Ghub.  Unlike Ghub, Glab does
-;; not support the guided creation of tokens because Gitlab lacks the
-;; features that would be necessary to implement that.  Users have to
-;; create tokens through the web interface.
-
-;;; Code:
-
-(require 'ghub)
-
-(defconst glab-default-host "gitlab.com/api/v4"
-  "The default host that is used if `glab.host' is not set.")
-
-(cl-defun glab-head (resource &optional params
-                              &key query payload headers
-                              silent unpaginate noerror reader
-                              username auth host
-                              callback errorback extra)
-  "Make a `HEAD' request for RESOURCE, with optional query PARAMS.
-Like calling `ghub-request' (which see) with \"HEAD\" as METHOD
-and `gitlab' as FORGE."
-  (ghub-request "HEAD" resource params :forge 'gitlab
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun glab-get (resource &optional params
-                             &key query payload headers
-                             silent unpaginate noerror reader
-                             username auth host
-                             callback errorback extra)
-  "Make a `GET' request for RESOURCE, with optional query PARAMS.
-Like calling `ghub-request' (which see) with \"GET\" as METHOD
-and `gitlab' as FORGE."
-  (ghub-request "GET" resource params :forge 'gitlab
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun glab-put (resource &optional params
-                             &key query payload headers
-                             silent unpaginate noerror reader
-                             username auth host
-                             callback errorback extra)
-  "Make a `PUT' request for RESOURCE, with optional payload PARAMS.
-Like calling `ghub-request' (which see) with \"PUT\" as METHOD
-and `gitlab' as FORGE."
-  (ghub-request "PUT" resource params :forge 'gitlab
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun glab-post (resource &optional params
-                              &key query payload headers
-                              silent unpaginate noerror reader
-                              username auth host
-                              callback errorback extra)
-  "Make a `POST' request for RESOURCE, with optional payload PARAMS.
-Like calling `ghub-request' (which see) with \"POST\" as METHOD
-and `gitlab' as FORGE."
-  (ghub-request "POST" resource params :forge 'gitlab
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun glab-patch (resource &optional params
-                               &key query payload headers
-                               silent unpaginate noerror reader
-                               username auth host
-                               callback errorback extra)
-  "Make a `PATCH' request for RESOURCE, with optional payload PARAMS.
-Like calling `ghub-request' (which see) with \"PATCH\" as METHOD
-and `gitlab' as FORGE."
-  (ghub-request "PATCH" resource params :forge 'gitlab
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun glab-delete (resource &optional params
-                                &key query payload headers
-                                silent unpaginate noerror reader
-                                username auth host
-                                callback errorback extra)
-  "Make a `DELETE' request for RESOURCE, with optional payload PARAMS.
-Like calling `ghub-request' (which see) with \"DELETE\" as METHOD
-and `gitlab' as FORGE."
-  (ghub-request "DELETE" resource params :forge 'gitlab
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun glab-request (method resource &optional params
-                               &key query payload headers
-                               silent unpaginate noerror reader
-                               username auth host
-                               callback errorback extra)
-  "Make a request for RESOURCE and return the response body.
-Like calling `ghub-request' (which see) with `gitlab' as FORGE."
-  (ghub-request method resource params :forge 'gitlab
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun glab-repository-id (owner name &key username auth host)
-  "Return the id of the repository specified by OWNER, NAME and HOST."
-  (number-to-string
-   (cdr (assq 'id (glab-get (format "/projects/%s%%2F%s"
-                                    (replace-regexp-in-string "/" "%2F" owner)
-                                    name)
-                            nil :username username :auth auth :host host)))))
-
-;;; _
-(provide 'glab)
-;;; glab.el ends here
diff --git a/elpa/ghub-20190121.2116/gogs.el b/elpa/ghub-20190121.2116/gogs.el
deleted file mode 100644 (file)
index 7ce7fcd..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-;;; gogs.el --- minuscule client library for the Gogs API  -*- lexical-binding: t -*-
-
-;; Copyright (C) 2016-2019  Jonas Bernoulli
-
-;; Author: Jonas Bernoulli <jonasNOSPAMbernoul.li>
-;; Homepage: https://github.com/magit/ghub
-;; Keywords: tools
-
-;; This file is not part of GNU Emacs.
-
-;; This file is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
-
-;; This file is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; For a copy of the GPL see https://www.gnu.org/licenses/gpl.txt.
-
-;;; Commentary:
-
-;; Gogs is a library that provides basic support for using the Gogs API
-;; from Emacs packages.  It abstracts access to API resources using only
-;; a handful of functions that are not resource-specific.
-
-;; This library is implemented on top of Ghub.  Unlike Ghub, Gogs does
-;; not support the guided creation of tokens because Gogs lacks the
-;; features that would be necessary to implement that.  Users have to
-;; create tokens through the web interface.
-
-;;; Code:
-
-(require 'ghub)
-
-(defconst gogs-default-host "localhost:3000/api/v1"
-  "The default Gogs host.")
-
-;; HEAD does not appear to be supported.
-
-(cl-defun gogs-get (resource &optional params
-                             &key query payload headers
-                             silent unpaginate noerror reader
-                             username auth host
-                             callback errorback extra)
-  "Make a `GET' request for RESOURCE, with optional query PARAMS.
-Like calling `ghub-request' (which see) with \"GET\" as METHOD
-and `gogs' as FORGE."
-  (ghub-request "GET" resource params :forge 'gogs
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun gogs-put (resource &optional params
-                             &key query payload headers
-                             silent unpaginate noerror reader
-                             username auth host
-                             callback errorback extra)
-  "Make a `PUT' request for RESOURCE, with optional payload PARAMS.
-Like calling `ghub-request' (which see) with \"PUT\" as METHOD
-and `gogs' as FORGE."
-  (ghub-request "PUT" resource params :forge 'gogs
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun gogs-post (resource &optional params
-                              &key query payload headers
-                              silent unpaginate noerror reader
-                              username auth host
-                              callback errorback extra)
-  "Make a `POST' request for RESOURCE, with optional payload PARAMS.
-Like calling `ghub-request' (which see) with \"POST\" as METHOD
-and `gogs' as FORGE."
-  (ghub-request "POST" resource params :forge 'gogs
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun gogs-patch (resource &optional params
-                               &key query payload headers
-                               silent unpaginate noerror reader
-                               username auth host
-                               callback errorback extra)
-  "Make a `PATCH' request for RESOURCE, with optional payload PARAMS.
-Like calling `ghub-request' (which see) with \"PATCH\" as METHOD
-and `gogs' as FORGE."
-  (ghub-request "PATCH" resource params :forge 'gogs
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun gogs-delete (resource &optional params
-                                &key query payload headers
-                                silent unpaginate noerror reader
-                                username auth host
-                                callback errorback extra)
-  "Make a `DELETE' request for RESOURCE, with optional payload PARAMS.
-Like calling `ghub-request' (which see) with \"DELETE\" as METHOD
-and `gogs' as FORGE."
-  (ghub-request "DELETE" resource params :forge 'gogs
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun gogs-request (method resource &optional params
-                               &key query payload headers
-                               silent unpaginate noerror reader
-                               username auth host
-                               callback errorback extra)
-  "Make a request for RESOURCE and return the response body.
-Like calling `ghub-request' (which see) with `gogs' as FORGE."
-  (ghub-request method resource params :forge 'gogs
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun gogs-repository-id (owner name &key username auth host)
-  "Return the id of the repository specified by OWNER, NAME and HOST."
-  (number-to-string
-   (cdr (assq 'id (gogs-get (format "/repos/%s/%s" owner name)
-                            nil :username username :auth auth :host host)))))
-
-;;; _
-(provide 'gogs)
-;;; gogs.el ends here
diff --git a/elpa/ghub-20190121.2116/gtea.el b/elpa/ghub-20190121.2116/gtea.el
deleted file mode 100644 (file)
index 81223bd..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-;;; gtea.el --- minuscule client library for the Gitea API  -*- lexical-binding: t -*-
-
-;; Copyright (C) 2016-2019  Jonas Bernoulli
-
-;; Author: Jonas Bernoulli <jonasNOSPAMbernoul.li>
-;; Homepage: https://github.com/magit/ghub
-;; Keywords: tools
-
-;; This file is not part of GNU Emacs.
-
-;; This file is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
-
-;; This file is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; For a copy of the GPL see https://www.gnu.org/licenses/gpl.txt.
-
-;;; Commentary:
-
-;; Gtea is a library that provides basic support for using the Gitea API
-;; from Emacs packages.  It abstracts access to API resources using only
-;; a handful of functions that are not resource-specific.
-
-;; This library is implemented on top of Ghub.  Unlike Ghub, Gtea does
-;; not support the guided creation of tokens because Gitea lacks the
-;; features that would be necessary to implement that.  Users have to
-;; create tokens through the web interface.
-
-;;; Code:
-
-(require 'ghub)
-
-(defconst gtea-default-host "localhost:3000/api/v1"
-  "The default Gitea host.")
-
-;; HEAD does not appear to be supported.
-
-(cl-defun gtea-get (resource &optional params
-                             &key query payload headers
-                             silent unpaginate noerror reader
-                             username auth host
-                             callback errorback extra)
-  "Make a `GET' request for RESOURCE, with optional query PARAMS.
-Like calling `ghub-request' (which see) with \"GET\" as METHOD
-and `gitea' as FORGE."
-  (ghub-request "GET" resource params :forge 'gitea
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun gtea-put (resource &optional params
-                             &key query payload headers
-                             silent unpaginate noerror reader
-                             username auth host
-                             callback errorback extra)
-  "Make a `PUT' request for RESOURCE, with optional payload PARAMS.
-Like calling `ghub-request' (which see) with \"PUT\" as METHOD
-and `gitea' as FORGE."
-  (ghub-request "PUT" resource params :forge 'gitea
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun gtea-post (resource &optional params
-                              &key query payload headers
-                              silent unpaginate noerror reader
-                              username auth host
-                              callback errorback extra)
-  "Make a `POST' request for RESOURCE, with optional payload PARAMS.
-Like calling `ghub-request' (which see) with \"POST\" as METHOD
-and `gitea' as FORGE."
-  (ghub-request "POST" resource params :forge 'gitea
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun gtea-patch (resource &optional params
-                               &key query payload headers
-                               silent unpaginate noerror reader
-                               username auth host
-                               callback errorback extra)
-  "Make a `PATCH' request for RESOURCE, with optional payload PARAMS.
-Like calling `ghub-request' (which see) with \"PATCH\" as METHOD
-and `gitea' as FORGE."
-  (ghub-request "PATCH" resource params :forge 'gitea
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun gtea-delete (resource &optional params
-                                &key query payload headers
-                                silent unpaginate noerror reader
-                                username auth host
-                                callback errorback extra)
-  "Make a `DELETE' request for RESOURCE, with optional payload PARAMS.
-Like calling `ghub-request' (which see) with \"DELETE\" as METHOD
-and `gitea' as FORGE."
-  (ghub-request "DELETE" resource params :forge 'gitea
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun gtea-request (method resource &optional params
-                               &key query payload headers
-                               silent unpaginate noerror reader
-                               username auth host
-                               callback errorback extra)
-  "Make a request for RESOURCE and return the response body.
-Like calling `ghub-request' (which see) with `gitea' as FORGE."
-  (ghub-request method resource params :forge 'gitea
-                :query query :payload payload :headers headers
-                :silent silent :unpaginate unpaginate
-                :noerror noerror :reader reader
-                :username username :auth auth :host host
-                :callback callback :errorback errorback :extra extra))
-
-(cl-defun gtea-repository-id (owner name &key username auth host)
-  "Return the id of the repository specified by OWNER, NAME and HOST."
-  (number-to-string
-   (cdr (assq 'id (gtea-get (format "/repos/%s/%s" owner name)
-                            nil :username username :auth auth :host host)))))
-
-;;; _
-(provide 'gtea)
-;;; gtea.el ends here
diff --git a/elpa/ghub-20191007.1420/buck.el b/elpa/ghub-20191007.1420/buck.el
new file mode 100644 (file)
index 0000000..94e7d81
--- /dev/null
@@ -0,0 +1,128 @@
+;;; buck.el --- minuscule client library for the Bitbucket API  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2016-2019  Jonas Bernoulli
+
+;; Author: Jonas Bernoulli <jonasNOSPAMbernoul.li>
+;; Homepage: https://github.com/magit/ghub
+;; Keywords: tools
+
+;; This file is not part of GNU Emacs.
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; For a copy of the GPL see https://www.gnu.org/licenses/gpl.txt.
+
+;;; Commentary:
+
+;; Buck is a library that provides basic support for using the Bitbucket API
+;; from Emacs packages.  It abstracts access to API resources using only
+;; a handful of functions that are not resource-specific.
+
+;; This library is implemented on top of Ghub.  Unlike Ghub, Buck does
+;; not support the guided creation of tokens because Bitbucket lacks the
+;; features that would be necessary to implement that.  Users have to
+;; create tokens through the web interface.
+
+;;; Code:
+
+(require 'ghub)
+
+(defconst buck-default-host "api.bitbucket.org/2.0"
+  "The default host that is used if `buck.host' is not set.")
+
+;; HEAD and PATCH are not supported according to
+;; https://developer.atlassian.com/bitbucket/api/2/reference/meta/uri-uuid
+
+(cl-defun buck-get (resource &optional params
+                             &key query payload headers
+                             silent unpaginate noerror reader
+                             username auth host
+                             callback errorback extra)
+  "Make a `GET' request for RESOURCE, with optional query PARAMS.
+Like calling `ghub-request' (which see) with \"GET\" as METHOD
+and `bitbucket' as FORGE."
+  (ghub-request "GET" resource params :forge 'bitbucket
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun buck-put (resource &optional params
+                             &key query payload headers
+                             silent unpaginate noerror reader
+                             username auth host
+                             callback errorback extra)
+  "Make a `PUT' request for RESOURCE, with optional payload PARAMS.
+Like calling `ghub-request' (which see) with \"PUT\" as METHOD
+and `bitbucket' as FORGE."
+  (ghub-request "PUT" resource params :forge 'bitbucket
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun buck-post (resource &optional params
+                              &key query payload headers
+                              silent unpaginate noerror reader
+                              username auth host
+                              callback errorback extra)
+  "Make a `POST' request for RESOURCE, with optional payload PARAMS.
+Like calling `ghub-request' (which see) with \"POST\" as METHOD
+and `bitbucket' as FORGE."
+  (ghub-request "POST" resource params :forge 'bitbucket
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun buck-delete (resource &optional params
+                                &key query payload headers
+                                silent unpaginate noerror reader
+                                username auth host
+                                callback errorback extra)
+  "Make a `DELETE' request for RESOURCE, with optional payload PARAMS.
+Like calling `ghub-request' (which see) with \"DELETE\" as METHOD
+and `bitbucket' as FORGE."
+  (ghub-request "DELETE" resource params :forge 'bitbucket
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun buck-request (method resource &optional params
+                               &key query payload headers
+                               silent unpaginate noerror reader
+                               username auth host
+                               callback errorback extra)
+  "Make a request for RESOURCE and return the response body.
+Like calling `ghub-request' (which see) with `bitbucket' as FORGE."
+  (ghub-request method resource params :forge 'bitbucket
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun buck-repository-id (owner name &key username auth host)
+  "Return the id of the repository specified by OWNER, NAME and HOST."
+  (substring (cdr (assq 'uuid
+                        (buck-get (format "/repositories/%s/%s" owner name)
+                                  nil
+                                  :username username :auth auth :host host)))
+             1 -1))
+
+;;; _
+(provide 'buck)
+;;; buck.el ends here
diff --git a/elpa/ghub-20191007.1420/dir b/elpa/ghub-20191007.1420/dir
new file mode 100644 (file)
index 0000000..8392fa0
--- /dev/null
@@ -0,0 +1,18 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+\1f
+File: dir,     Node: Top       This is the top of the INFO tree
+
+  This (the Directory node) gives a menu of major topics.
+  Typing "q" exits, "H" lists all Info commands, "d" returns here,
+  "h" gives a primer for first-timers,
+  "mEmacs<Return>" visits the Emacs manual, etc.
+
+  In Emacs, you can click mouse button 2 on a menu item or cross reference
+  to select it.
+
+* Menu:
+
+Emacs
+* Ghub: (ghub).                 Minuscule client library for the Github API.
diff --git a/elpa/ghub-20191007.1420/ghub-autoloads.el b/elpa/ghub-20191007.1420/ghub-autoloads.el
new file mode 100644 (file)
index 0000000..f87340c
--- /dev/null
@@ -0,0 +1,51 @@
+;;; ghub-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+\f
+;;;### (autoloads nil "ghub" "ghub.el" (23994 46481 891444 634000))
+;;; Generated autoloads from ghub.el
+
+(autoload 'ghub-create-token "ghub" "\
+Create, store and return a new token.
+
+HOST is the Github instance, usually \"api.github.com\".
+USERNAME is the name of a user on that instance.
+PACKAGE is the package that will use the token.
+SCOPES are the scopes the token is given access to.
+
+\(fn HOST USERNAME PACKAGE SCOPES)" t nil)
+
+(autoload 'ghub-token-scopes "ghub" "\
+Return and echo the scopes of the specified token.
+This is intended for debugging purposes only.  The user
+has to provide several values including their password.
+
+\(fn HOST USERNAME PACKAGE)" t nil)
+
+(autoload 'ghub-clear-caches "ghub" "\
+Clear all caches that might negatively affect Ghub.
+
+If a library that is used by Ghub caches incorrect information
+such as a mistyped password, then that can prevent Ghub from
+asking the user for the correct information again.
+
+Set `url-http-real-basic-auth-storage' to nil
+and call `auth-source-forget+'.
+
+\(fn)" t nil)
+
+;;;***
+\f
+;;;### (autoloads nil nil ("buck.el" "ghub-graphql.el" "ghub-pkg.el"
+;;;;;;  "glab.el" "gogs.el" "gsexp.el" "gtea.el") (23994 46481 895331
+;;;;;;  836000))
+
+;;;***
+\f
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; ghub-autoloads.el ends here
diff --git a/elpa/ghub-20191007.1420/ghub-graphql.el b/elpa/ghub-20191007.1420/ghub-graphql.el
new file mode 100644 (file)
index 0000000..b39f1bc
--- /dev/null
@@ -0,0 +1,454 @@
+;;; ghub-graphql.el --- access Github API using GrapthQL  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2016-2019  Jonas Bernoulli
+
+;; Author: Jonas Bernoulli <jonasNOSPAMbernoul.li>
+;; Homepage: https://github.com/magit/ghub
+
+;; This file is not part of GNU Emacs.
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; For a copy of the GPL see https://www.gnu.org/licenses/gpl.txt.
+
+;;; Code:
+
+(require 'dash)
+(require 'ghub)
+(require 'gsexp)
+(require 'treepy)
+
+(eval-when-compile
+  (require 'subr-x))
+
+;;; Api
+
+(cl-defun ghub-graphql (graphql &optional variables
+                                &key username auth host
+                                silent
+                                callback errorback value extra)
+  "Make a GraphQL request using GRAPHQL and VARIABLES.
+Return the response as a JSON-like alist.  Even if the response
+contains `errors', do not raise an error.  GRAPHQL is a GraphQL
+string.  VARIABLES is a JSON-like alist.  The other arguments
+behave as for `ghub-request' (which see)."
+  (cl-assert (stringp graphql))
+  (cl-assert (not (stringp variables)))
+  (ghub-request "POST" "/graphql" nil :payload
+                (json-encode `(("query" . ,graphql)
+                               ,@(and variables `(("variables" ,@variables)))))
+                :silent silent
+                :username username :auth auth :host host
+                :callback callback :errorback errorback
+                :extra extra :value value))
+
+(cl-defun ghub-graphql-rate-limit (&key username auth host)
+  "Return rate limit information."
+  (let-alist (ghub-graphql
+              "query { rateLimit { limit cost remaining resetAt }}"
+              nil :username username :auth auth :host host)
+    .data.rateLimit))
+
+(cl-defun ghub--repository-id (owner name &key username auth host)
+  "Return the id of the repository specified by OWNER, NAME and HOST."
+  (let-alist (ghub-graphql
+              "query ($owner:String!, $name:String!) {
+                 repository(owner:$owner, name:$name) { id }
+               }"
+              `((owner . ,owner)
+                (name  . ,name))
+              :username username :auth auth :host host)
+    .data.repository.id))
+
+;;; Api (drafts)
+
+(defconst ghub-fetch-repository
+  '(query
+    (repository
+     [(owner $owner String!)
+      (name  $name  String!)]
+     name
+     id
+     createdAt
+     updatedAt
+     nameWithOwner
+     (parent nameWithOwner)
+     description
+     homepageUrl
+     (defaultBranchRef name)
+     isArchived
+     isFork
+     isLocked
+     isMirror
+     isPrivate
+     hasIssuesEnabled
+     hasWikiEnabled
+     (licenseInfo name)
+     (stargazers totalCount)
+     (watchers totalCount)
+     (assignableUsers [(:edges t)]
+                      id
+                      login
+                      name)
+     (issues         [(:edges t)
+                      (:singular issue number)
+                      (orderBy ((field UPDATED_AT) (direction DESC)))]
+                     number
+                     state
+                     (author login)
+                     title
+                     createdAt
+                     updatedAt
+                     closedAt
+                     locked
+                     (milestone id)
+                     body
+                     (assignees [(:edges t)]
+                                id)
+                     (comments  [(:edges t)]
+                                databaseId
+                                (author login)
+                               createdAt
+                               updatedAt
+                                body)
+                     (labels    [(:edges t)]
+                                id))
+     (labels         [(:edges t)
+                      (:singular label id)]
+                     id
+                     name
+                     color
+                     description)
+     (pullRequests   [(:edges t)
+                      (:singular pullRequest number)
+                      (orderBy ((field UPDATED_AT) (direction DESC)))]
+                     number
+                     state
+                     (author login)
+                     title
+                     createdAt
+                     updatedAt
+                     closedAt
+                     mergedAt
+                     locked
+                     maintainerCanModify
+                     isCrossRepository
+                     (milestone id)
+                     body
+                     (baseRef name
+                              (repository nameWithOwner))
+                     (headRef name
+                              (repository (owner login)
+                                          nameWithOwner))
+                     (assignees [(:edges t)]
+                                id)
+                     (reviewRequests [(:edges t)]
+                                     (requestedReviewer "... on User { id }\n"))
+                     (comments  [(:edges t)]
+                                databaseId
+                                (author login)
+                                createdAt
+                               updatedAt
+                               body)
+                     (labels    [(:edges t)]
+                                id)))))
+
+(cl-defun ghub-fetch-repository (owner name callback
+                                       &optional until
+                                       &key username auth host forge)
+  "Asynchronously fetch forge data about the specified repository.
+Once all data has been collected, CALLBACK is called with the
+data as the only argument."
+  (ghub--graphql-vacuum ghub-fetch-repository
+                        `((owner . ,owner)
+                          (name  . ,name))
+                        callback until
+                        :narrow   '(repository)
+                        :username username
+                        :auth     auth
+                        :host     host
+                        :forge    forge))
+
+(cl-defun ghub-fetch-issue (owner name number callback
+                                  &optional until
+                                  &key username auth host forge)
+  "Asynchronously fetch forge data about the specified issue.
+Once all data has been collected, CALLBACK is called with the
+data as the only argument."
+  (ghub--graphql-vacuum (ghub--graphql-prepare-query
+                         ghub-fetch-repository
+                         `(repository issues (issue . ,number)))
+                        `((owner . ,owner)
+                          (name  . ,name))
+                        callback until
+                        :narrow   '(repository issue)
+                        :username username
+                        :auth     auth
+                        :host     host
+                        :forge    forge))
+
+(cl-defun ghub-fetch-pullreq (owner name number callback
+                                    &optional until
+                                    &key username auth host forge)
+  "Asynchronously fetch forge data about the specified pull-request.
+Once all data has been collected, CALLBACK is called with the
+data as the only argument."
+  (ghub--graphql-vacuum (ghub--graphql-prepare-query
+                         ghub-fetch-repository
+                         `(repository pullRequests (pullRequest . ,number)))
+                        `((owner . ,owner)
+                          (name  . ,name))
+                        callback until
+                        :narrow   '(repository pullRequest)
+                        :username username
+                        :auth     auth
+                        :host     host
+                        :forge    forge))
+
+;;; Internal
+
+(cl-defstruct (ghub--graphql-req
+               (:include ghub--req)
+               (:constructor ghub--make-graphql-req)
+               (:copier nil))
+  (query     nil :read-only t)
+  (query-str nil :read-only nil)
+  (variables nil :read-only t)
+  (until     nil :read-only t)
+  (buffer    nil :read-only t)
+  (pages     0   :read-only nil))
+
+(cl-defun ghub--graphql-vacuum (query variables callback
+                                      &optional until
+                                      &key narrow username auth host forge)
+  "Make a GraphQL request using QUERY and VARIABLES.
+See Info node `(ghub)GraphQL Support'."
+  (unless host
+    (setq host (ghub--host forge)))
+  (unless (or username (stringp auth) (eq auth 'none))
+    (setq username (ghub--username host forge)))
+  (ghub--graphql-retrieve
+   (ghub--make-graphql-req
+    :url       (url-generic-parse-url
+                (format "https://%s/graphql"
+                        (if (string-suffix-p "/v3" host)
+                            (substring host 0 -3)
+                          host)))
+    :method    "POST"
+    :headers   (ghub--headers nil host auth username forge)
+    :handler   'ghub--graphql-handle-response
+    :query     query
+    :variables variables
+    :until     until
+    :buffer    (current-buffer)
+    :callback  (let ((buf (current-buffer)))
+                 (if narrow
+                     (lambda (data)
+                       (let ((path narrow) key)
+                         (while (setq key (pop path))
+                           (setq data (cdr (assq key data)))))
+                       (ghub--graphql-set-mode-line buf nil)
+                       (funcall callback data))
+                   (lambda (data)
+                     (ghub--graphql-set-mode-line buf nil)
+                     (funcall callback data)))))))
+
+(cl-defun ghub--graphql-retrieve (req &optional lineage cursor)
+  (let ((p (cl-incf (ghub--graphql-req-pages req))))
+    (when (> p 1)
+      (ghub--graphql-set-mode-line req "Fetching page %s" p)))
+  (setf (ghub--graphql-req-query-str req)
+        (gsexp-encode
+         (ghub--graphql-prepare-query
+          (ghub--graphql-req-query req)
+          lineage cursor)))
+  (ghub--retrieve
+   (let ((json-false nil))
+     (ghub--encode-payload
+      `((query     . ,(ghub--graphql-req-query-str req))
+        (variables . ,(ghub--graphql-req-variables req)))))
+   req))
+
+(defun ghub--graphql-prepare-query (query &optional lineage cursor)
+  (when lineage
+    (setq query (ghub--graphql-narrow-query query lineage cursor)))
+  (let ((loc (ghub--alist-zip query))
+        variables)
+    (cl-block nil
+      (while t
+        (let ((node (treepy-node loc)))
+          (when (vectorp node)
+            (let ((alist (cl-coerce node 'list))
+                  vars)
+              (when (cadr (assq :edges alist))
+                (push (list 'first 100) vars)
+                (setq loc  (treepy-up loc))
+                (setq node (treepy-node loc))
+                (setq loc  (treepy-replace
+                            loc `(,(car  node)
+                                  ,(cadr node)
+                                  (pageInfo endCursor hasNextPage)
+                                  (edges (node ,@(cddr node))))))
+                (setq loc  (treepy-down loc))
+                (setq loc  (treepy-next loc)))
+              (dolist (elt alist)
+                (cond ((keywordp (car elt)))
+                      ((= (length elt) 3)
+                       (push (list (nth 0 elt)
+                                   (nth 1 elt)) vars)
+                       (push (list (nth 1 elt)
+                                   (nth 2 elt)) variables))
+                      ((= (length elt) 2)
+                       (push elt vars))))
+              (setq loc (treepy-replace loc (vconcat (nreverse vars)))))))
+        (if (treepy-end-p loc)
+            (let ((node (copy-sequence (treepy-node loc))))
+              (when variables
+                (push (cl-coerce variables 'vector)
+                      (cdr node)))
+              (cl-return node))
+          (setq loc (treepy-next loc)))))))
+
+(defun ghub--graphql-handle-response (status req)
+  (let ((buffer (current-buffer)))
+    (unwind-protect
+        (progn
+          (set-buffer-multibyte t)
+          (let* ((headers (ghub--handle-response-headers status req))
+                 (payload (ghub--handle-response-payload req))
+                 (payload (ghub--handle-response-error status payload req))
+                 (err     (plist-get status :error))
+                 (errors  (cdr (assq 'errors payload)))
+                 (errors  (and errors (cons 'ghub-graphql-error errors))))
+            (if (or err errors)
+                (if-let ((errorback (ghub--req-errorback req)))
+                    (funcall errorback (or err errors) headers status req)
+                  (ghub--signal-error (or err errors)))
+              (ghub--graphql-walk-response req (assq 'data payload)))))
+      (when (buffer-live-p buffer)
+        (kill-buffer buffer)))))
+
+(defun ghub--graphql-walk-response (req data)
+  (let* ((loc (ghub--req-value req))
+         (loc (if (not loc)
+                  (ghub--alist-zip data)
+                (setq data (ghub--graphql-narrow-data
+                            data (ghub--graphql-lineage loc)))
+                (setf (alist-get 'edges data)
+                      (append (alist-get 'edges (treepy-node loc))
+                              (or (alist-get 'edges data)
+                                  (error "BUG: Expected new nodes"))))
+                (treepy-replace loc data))))
+    (cl-block nil
+      (while t
+        (when (eq (car-safe (treepy-node loc)) 'edges)
+          (setq loc (treepy-up loc))
+          (pcase-let ((`(,key . ,val) (treepy-node loc)))
+            (let-alist val
+              (let* ((cursor (and .pageInfo.hasNextPage
+                                  .pageInfo.endCursor))
+                     (until (cdr (assq (intern (format "%s-until" key))
+                                       (ghub--graphql-req-until req))))
+                     (nodes (mapcar #'cdar .edges))
+                     (nodes (if until
+                                (--take-while
+                                 (or (string> (cdr (assq 'updatedAt it)) until)
+                                     (setq cursor nil))
+                                 nodes)
+                              nodes)))
+                (if cursor
+                    (progn
+                      (setf (ghub--req-value req) loc)
+                      (ghub--graphql-retrieve req
+                                              (ghub--graphql-lineage loc)
+                                              cursor)
+                      (cl-return))
+                  (setq loc (treepy-replace loc (cons key nodes))))))))
+        (if (not (treepy-end-p loc))
+            (setq loc (treepy-next loc))
+          (funcall (ghub--req-callback req)
+                   (treepy-root loc))
+          (cl-return))))))
+
+(defun ghub--graphql-lineage (loc)
+  (let (lineage)
+    (while (treepy-up loc)
+      (push (car (treepy-node loc)) lineage)
+      (setq loc (treepy-up loc)))
+    lineage))
+
+(defun ghub--graphql-narrow-data (data lineage)
+  (let (key)
+    (while (setq key (pop lineage))
+      (if (consp (car lineage))
+          (progn (pop lineage)
+                 (setf data (cadr data)))
+        (setq data (assq key (cdr data))))))
+  data)
+
+(defun ghub--graphql-narrow-query (query lineage cursor)
+  (if (consp (car lineage))
+      (let* ((child  (cddr query))
+             (alist  (cl-coerce (cadr query) 'list))
+             (single (cdr (assq :singular alist))))
+        `(,(car single)
+          ,(vector (list (cadr single) (cdr (car lineage))))
+          ,@(if (cdr lineage)
+               (ghub--graphql-narrow-query child (cdr lineage) cursor)
+              child)))
+    (let* ((child  (or (assq (car lineage) (cdr query))
+                       ;; Alias
+                       (cl-find-if (lambda (c)
+                                     (eq (car-safe (car-safe c))
+                                         (car lineage)))
+                                   query)
+                       ;; Edges
+                       (cl-find-if (lambda (c)
+                                     (and (listp c)
+                                          (vectorp (cadr c))
+                                          (eq (cadr (assq :singular
+                                                          (cl-coerce (cadr c)
+                                                                     'list)))
+                                              (car lineage))))
+                                   (cdr query))
+                       (error "BUG: Failed to narrow query")))
+           (object (car query))
+           (args   (and (vectorp (cadr query))
+                        (cadr query))))
+      `(,object
+        ,@(and args (list args))
+        ,(cond ((cdr lineage)
+                (ghub--graphql-narrow-query child (cdr lineage) cursor))
+               (cursor
+                `(,(car child)
+                  ,(vconcat `((after ,cursor))
+                            (cadr child))
+                  ,@(cddr child)))
+               (t
+                child))))))
+
+(defun ghub--alist-zip (root)
+  (let ((branchp (lambda (elt) (and (listp elt) (listp (cdr elt)))))
+        (make-node (lambda (_ children) children)))
+    (treepy-zipper branchp #'identity make-node root)))
+
+(defun ghub--graphql-set-mode-line (buf string &rest args)
+  (when (ghub--graphql-req-p buf)
+    (setq buf (ghub--graphql-req-buffer buf)))
+  (when (buffer-live-p buf)
+    (with-current-buffer buf
+      (setq mode-line-process
+            (and string (concat " " (apply #'format string args))))
+      (force-mode-line-update t))))
+
+;;; _
+(provide 'ghub-graphql)
+;;; ghub-graphql.el ends here
diff --git a/elpa/ghub-20191007.1420/ghub-pkg.el b/elpa/ghub-20191007.1420/ghub-pkg.el
new file mode 100644 (file)
index 0000000..2cfdd4b
--- /dev/null
@@ -0,0 +1,8 @@
+(define-package "ghub" "20191007.1420" "Minuscule client libraries for Git forge APIs."
+  '((emacs "25.1")
+    (dash "2.14.1")
+    (let-alist "1.0.5")
+    (treepy "0.1.1")))
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/elpa/ghub-20191007.1420/ghub.el b/elpa/ghub-20191007.1420/ghub.el
new file mode 100644 (file)
index 0000000..ec73de5
--- /dev/null
@@ -0,0 +1,1041 @@
+;;; ghub.el --- minuscule client libraries for Git forge APIs  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2016-2019  Jonas Bernoulli
+
+;; Author: Jonas Bernoulli <jonasNOSPAMbernoul.li>
+;; Homepage: https://github.com/magit/ghub
+;; Keywords: tools
+
+;; This file is not part of GNU Emacs.
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; For a copy of the GPL see https://www.gnu.org/licenses/gpl.txt.
+
+;;; Commentary:
+
+;; Ghub provides basic support for using the APIs of various Git forges
+;; from Emacs packages.  Originally it only supported the Github REST
+;; API, but now it also supports the Github GraphQL API as well as the
+;; REST APIs of Gitlab, Gitea, Gogs and Bitbucket.
+
+;; Ghub abstracts access to API resources using only a handful of basic
+;; functions such as `ghub-get'.  These are convenience wrappers around
+;; `ghub-request'.  Additional forge-specific wrappers like `glab-put',
+;; `gtea-put', `gogs-post' and `buck-delete' are also available.  Ghub
+;; does not provide any resource-specific functions, with the exception
+;; of `FORGE-repository-id'.
+
+;; When accessing Github, then Ghub handles the creation and storage of
+;; access tokens using a setup wizard to make it easier for users to get
+;; started.  The tokens for other forges have to be created manually.
+
+;; Ghub is intentionally limited to only provide these two essential
+;; features â€” basic request functions and guided setup â€” to avoid being
+;; too opinionated, which would hinder wide adoption.  It is assumed that
+;; wide adoption would make life easier for users and maintainers alike,
+;; because then all packages that talk to forge APIs could be configured
+;; the same way.
+
+;; Please consult the manual (info "ghub") for more information.
+
+;;; Code:
+
+(require 'auth-source)
+(require 'cl-lib)
+(require 'gnutls)
+(require 'json)
+(require 'let-alist)
+(require 'url)
+(require 'url-auth)
+(require 'url-http)
+
+(eval-when-compile
+  (require 'subr-x))
+
+(defvar url-callback-arguments)
+(defvar url-http-end-of-headers)
+(defvar url-http-extra-headers)
+(defvar url-http-response-status)
+
+;;; Settings
+
+(defconst ghub-default-host "api.github.com"
+  "The default host that is used if `ghub.host' is not set.")
+
+(defvar ghub-github-token-scopes '(repo)
+  "The Github API scopes that your private tools need.
+
+The token that is created based on the value of this variable
+is used when `ghub-request' (or one of its wrappers) is called
+without providing a value for AUTH.  Packages should always
+identify themselves using that argument, but when you use Ghub
+directly in private tools, then that is not necessary and the
+request is made on behalf of the `ghub' package itself, aka on
+behalf of some private tool.
+
+By default the only requested scope is `repo' because that is
+sufficient as well as required for most common uses.  This and
+other scopes are documented at URL `https://magit.vc/goto/2e586d36'.
+
+If your private tools need other scopes, then you have to add
+them here *before* creating the token.  Alternatively you can
+edit the scopes of an existing token using the web interface
+at URL `https://github.com/settings/tokens'.")
+
+(defvar ghub-override-system-name nil
+  "If non-nil, the string used to identify the local machine.
+If this is nil, then the value returned by `system-name' is
+used instead.")
+
+(defvar ghub-insecure-hosts nil
+  "List of hosts that use http instead of https.")
+
+;;; Request
+;;;; Object
+
+(cl-defstruct (ghub--req
+               (:constructor ghub--make-req)
+               (:copier nil))
+  (url        nil :read-only nil)
+  (forge      nil :read-only t)
+  (silent     nil :read-only t)
+  (method     nil :read-only t)
+  (headers    nil :read-only t)
+  (handler    nil :read-only t)
+  (unpaginate nil :read-only nil)
+  (noerror    nil :read-only t)
+  (reader     nil :read-only t)
+  (callback   nil :read-only t)
+  (errorback  nil :read-only t)
+  (value      nil :read-only nil)
+  (extra      nil :read-only nil))
+
+(defalias 'ghub-req-extra 'ghub--req-extra)
+
+;;;; API
+
+(define-error 'ghub-error "Ghub/Url Error" 'error)
+(define-error 'ghub-http-error "HTTP Error" 'ghub-error)
+
+(defvar ghub-response-headers nil
+  "The headers returned in response to the last request.
+`ghub-request' returns the response body and stores the
+response headers in this variable.")
+
+(cl-defun ghub-head (resource &optional params
+                              &key query payload headers
+                              silent unpaginate noerror reader
+                              username auth host
+                              callback errorback extra)
+  "Make a `HEAD' request for RESOURCE, with optional query PARAMS.
+Like calling `ghub-request' (which see) with \"HEAD\" as METHOD."
+  (ghub-request "HEAD" resource params
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun ghub-get (resource &optional params
+                             &key query payload headers
+                             silent unpaginate noerror reader
+                             username auth host
+                             callback errorback extra)
+  "Make a `GET' request for RESOURCE, with optional query PARAMS.
+Like calling `ghub-request' (which see) with \"GET\" as METHOD."
+  (ghub-request "GET" resource params
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun ghub-put (resource &optional params
+                             &key query payload headers
+                             silent unpaginate noerror reader
+                             username auth host
+                             callback errorback extra)
+  "Make a `PUT' request for RESOURCE, with optional payload PARAMS.
+Like calling `ghub-request' (which see) with \"PUT\" as METHOD."
+  (ghub-request "PUT" resource params
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun ghub-post (resource &optional params
+                              &key query payload headers
+                              silent unpaginate noerror reader
+                              username auth host
+                              callback errorback extra)
+  "Make a `POST' request for RESOURCE, with optional payload PARAMS.
+Like calling `ghub-request' (which see) with \"POST\" as METHOD."
+  (ghub-request "POST" resource params
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun ghub-patch (resource &optional params
+                               &key query payload headers
+                               silent unpaginate noerror reader
+                               username auth host
+                               callback errorback extra)
+  "Make a `PATCH' request for RESOURCE, with optional payload PARAMS.
+Like calling `ghub-request' (which see) with \"PATCH\" as METHOD."
+  (ghub-request "PATCH" resource params
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun ghub-delete (resource &optional params
+                                &key query payload headers
+                                silent unpaginate noerror reader
+                                username auth host
+                                callback errorback extra)
+  "Make a `DELETE' request for RESOURCE, with optional payload PARAMS.
+Like calling `ghub-request' (which see) with \"DELETE\" as METHOD."
+  (ghub-request "DELETE" resource params
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun ghub-request (method resource &optional params
+                               &key query payload headers
+                               silent unpaginate noerror reader
+                               username auth host forge
+                               callback errorback value extra)
+  "Make a request for RESOURCE and return the response body.
+
+Also place the response headers in `ghub-response-headers'.
+
+METHOD is the HTTP method, given as a string.
+RESOURCE is the resource to access, given as a string beginning
+  with a slash.
+
+PARAMS, QUERY, PAYLOAD and HEADERS are alists used to specify
+  data.  The Github API documentation is vague on how data has
+  to be transmitted and for a particular resource usually just
+  talks about \"parameters\".  Generally speaking when the METHOD
+  is \"HEAD\" or \"GET\", then they have to be transmitted as a
+  query, otherwise as a payload.
+Use PARAMS to automatically transmit like QUERY or PAYLOAD would
+  depending on METHOD.
+Use QUERY to explicitly transmit data as a query.
+Use PAYLOAD to explicitly transmit data as a payload.
+  Instead of an alist, PAYLOAD may also be a string, in which
+  case it gets encoded as UTF-8 but is otherwise transmitted as-is.
+Use HEADERS for those rare resources that require that the data
+  is transmitted as headers instead of as a query or payload.
+  When that is the case, then the API documentation usually
+  mentions it explicitly.
+
+If SILENT is non-nil, then don't message progress reports and
+  the like.
+
+If UNPAGINATE is t, then make as many requests as necessary to
+  get all values.  If UNPAGINATE is a natural number, then get
+  at most that many pages.  For any other non-nil value raise
+  an error.
+If NOERROR is non-nil, then do not raise an error if the request
+  fails and return nil instead.  If NOERROR is `return', then
+  return the error payload instead of nil.
+If READER is non-nil, then it is used to read and return from the
+  response buffer.  The default is `ghub--read-json-payload'.
+  For the very few resources that do not return JSON, you might
+  want to use `ghub--decode-payload'.
+
+If USERNAME is non-nil, then make a request on behalf of that
+  user.  It is better to specify the user using the Git variable
+  `github.user' for \"api.github.com\", or `github.HOST.user' if
+  connecting to a Github Enterprise instance.
+
+Each package that uses `ghub' should use its own token. If AUTH
+  is nil, then the generic `ghub' token is used instead.  This
+  is only acceptable for personal utilities.  A packages that
+  is distributed to other users should always use this argument
+  to identify itself, using a symbol matching its name.
+
+  Package authors who find this inconvenient should write a
+  wrapper around this function and possibly for the
+  method-specific functions as well.
+
+  Some symbols have a special meaning.  `none' means to make an
+  unauthorized request.  `basic' means to make a password based
+  request.  If the value is a string, then it is assumed to be
+  a valid token.  `basic' and an explicit token string are only
+  intended for internal and debugging uses.
+
+  If AUTH is a package symbol, then the scopes are specified
+  using the variable `AUTH-github-token-scopes'.  It is an error
+  if that is not specified.  See `ghub-github-token-scopes' for
+  an example.
+
+If HOST is non-nil, then connect to that Github instance.  This
+  defaults to \"api.github.com\".  When a repository is connected
+  to a Github Enterprise instance, then it is better to specify
+  that using the Git variable `github.host' instead of using this
+  argument.
+
+If FORGE is `gitlab', then connect to Gitlab.com or, depending
+  on HOST, to another Gitlab instance.  This is only intended for
+  internal use.  Instead of using this argument you should use
+  function `glab-request' and other `glab-*' functions.
+
+If CALLBACK and/or ERRORBACK is non-nil, then make one or more
+  asynchronous requests and call CALLBACK or ERRORBACK when
+  finished.  If no error occurred, then call CALLBACK, unless
+  that is nil.
+
+  If an error occurred, then call ERRORBACK, or if that is nil,
+  then CALLBACK.  ERRORBACK can also be t, in which case an error
+  is signaled instead.  NOERROR is ignored for all asynchronous
+  requests.
+
+Both callbacks are called with four arguments.
+  1. For CALLBACK, the combined value of the retrieved pages.
+     For ERRORBACK, the error that occured when retrieving the
+     last page.
+  2. The headers of the last page as an alist.
+  3. Status information provided by `url-retrieve'. Its `:error'
+     property holds the same information as ERRORBACK's first
+     argument.
+  4. A `ghub--req' struct, which can be passed to `ghub-continue'
+     (which see) to retrieve the next page, if any."
+  (cl-assert (or (booleanp unpaginate) (natnump unpaginate)))
+  (unless (string-prefix-p "/" resource)
+    (setq resource (concat "/" resource)))
+  (unless host
+    (setq host (ghub--host forge)))
+  (unless (or username (stringp auth) (eq auth 'none))
+    (setq username (ghub--username host forge)))
+  (cond ((not params))
+        ((member method '("GET" "HEAD"))
+         (when query
+           (error "PARAMS and QUERY are mutually exclusive for METHOD %S"
+                  method))
+         (setq query params))
+        (t
+         (when payload
+           (error "PARAMS and PAYLOAD are mutually exclusive for METHOD %S"
+                  method))
+         (setq payload params)))
+  (when (or callback errorback)
+    (setq noerror t))
+  (ghub--retrieve
+   (ghub--encode-payload payload)
+   (ghub--make-req
+    :url (url-generic-parse-url
+          (concat (if (member host ghub-insecure-hosts) "http://" "https://")
+                  (if (and (equal resource "/graphql")
+                           (string-suffix-p "/v3" host))
+                      (substring host 0 -3)
+                    host)
+                  resource
+                  (and query (concat "?" (ghub--url-encode-params query)))))
+    :forge forge
+    :silent silent
+    ;; Encode in case caller used (symbol-name 'GET). #35
+    :method     (encode-coding-string method 'utf-8)
+    :headers    (ghub--headers headers host auth username forge)
+    :handler    'ghub--handle-response
+    :unpaginate unpaginate
+    :noerror    noerror
+    :reader     reader
+    :callback   callback
+    :errorback  errorback
+    :value      value
+    :extra      extra)))
+
+(defun ghub-continue (req)
+  "If there is a next page, then retrieve that.
+
+This function is only intended to be called from callbacks.  If
+there is a next page, then retrieve that and return the buffer
+that the result will be loaded into, or t if the process has
+already completed.  If there is no next page, then return nil.
+
+Callbacks are called with four arguments (see `ghub-request').
+The forth argument is a `ghub--req' struct, intended to be passed
+to this function.  A callback may use the struct's `extra' slot
+to pass additional information to the callback that will be
+called after the next request has finished.  Use the function
+`ghub-req-extra' to get and set the value of this slot."
+  (and (assq 'next (ghub-response-link-relations req))
+       (or (ghub--retrieve nil req) t)))
+
+(cl-defun ghub-wait (resource &optional duration &key username auth host)
+  "Busy-wait up to DURATION seconds for RESOURCE to become available.
+
+DURATION specifies how many seconds to wait at most.  It defaults
+to 64 seconds.  The first attempt is made immediately, the second
+after two seconds, and each subsequent attempt is made after
+waiting as long again as we already waited between all preceding
+attempts combined.
+
+See `ghub-request' for information about the other arguments."
+  (unless duration
+    (setq duration 64))
+  (with-local-quit
+    (let ((total 0))
+      (while (not (ghub-get resource nil
+                            :noerror t
+                            :username username
+                            :auth auth
+                            :host host))
+        (message "Waited (%3ss of %ss) for %s..." total duration resource)
+        (if (= total duration)
+            (error "Github is taking too long to create %s" resource)
+          (if (> total 0)
+              (let ((wait (min total (- duration total))))
+                (sit-for wait)
+                (cl-incf total wait))
+            (sit-for (setq total 2))))))))
+
+(defun ghub-response-link-relations (req &optional headers payload)
+  "Return an alist of link relations in HEADERS.
+If optional HEADERS is nil, then return those that were
+previously stored in the variable `ghub-response-headers'.
+
+When accessing a Bitbucket instance then the link relations
+are in PAYLOAD instead of HEADERS, making their API merely
+RESTish and forcing this function to append those relations
+to the value of `ghub-response-headers', for later use when
+this function is called with nil for PAYLOAD."
+  (if (eq (ghub--req-forge req) 'bitbucket)
+      (if payload
+          (let* ((page (cl-mapcan (lambda (key)
+                                    (when-let ((elt (assq key payload)))
+                                      (list elt)))
+                                  '(size page pagelen next previous)))
+                 (headers (cons (cons 'link-alist page) headers)))
+            (if (and req (or (ghub--req-callback req)
+                             (ghub--req-errorback req)))
+                (setq-local ghub-response-headers headers)
+              (setq-default ghub-response-headers headers))
+            page)
+        (cdr (assq 'link-alist ghub-response-headers)))
+  (when-let ((rels (cdr (assoc "Link" (or headers ghub-response-headers)))))
+    (mapcar (lambda (elt)
+              (pcase-let ((`(,url ,rel) (split-string elt "; ")))
+                (cons (intern (substring rel 5 -1))
+                      (substring url 1 -1))))
+            (split-string rels ", ")))))
+
+(cl-defun ghub-repository-id (owner name &key username auth host forge noerror)
+  "Return the id of the specified repository.
+Signal an error if the id cannot be determined."
+  (let ((fn (cl-case forge
+              ((nil ghub github) 'ghub--repository-id)
+              (gitlab            'glab-repository-id)
+              (gittea            'gtea-repository-id)
+              (gogs              'gogs-repository-id)
+              (bitbucket         'buck-repository-id)
+              (t (intern (format "%s-repository-id" forge))))))
+    (unless (fboundp fn)
+      (error "ghub-repository-id: Forge type/abbreviation `%s' is unknown"
+             forge))
+    (or (funcall fn owner name :username username :auth auth :host host)
+        (and (not noerror)
+             (error "Repository %S does not exist on %S.\n%s%S?"
+                    (concat owner "/" name)
+                    (or host (ghub--host forge))
+                    "Maybe it was renamed and you have to update "
+                    "remote.<remote>.url")))))
+
+;;;; Internal
+
+(defvar ghub-use-workaround-for-emacs-bug
+  (and
+   ;; Note: For build sans gnutls, `libgnutls-version' is -1.
+   (>= libgnutls-version 30603)
+   (version<= emacs-version "26.2")
+   'force)
+  "Whether to use a kludge that hopefully works around an Emacs bug.
+
+In Emacs versions before 26.3 there is a bug that causes network
+connections to fail when using TLS1.3.  If this variable is
+non-nil, then Ghub works around that by binding
+`gnutls-algorithm-priority' to \"NORMAL:-VERS-TLS1.3\", unless we
+think it is unnecessary.  If `force' then always use the
+workaround.  Currently the latter is the default except when
+using Emacs 26.3+, or the libgnutls is earlier than 3.6.3 (when
+it introduced TLS1.3).
+
+For more information see https://github.com/magit/ghub/issues/81
+and https://debbugs.gnu.org/cgi/bugreport.cgi?bug=34341.")
+
+(cl-defun ghub--retrieve (payload req)
+  (let ((url-request-extra-headers
+         (let ((headers (ghub--req-headers req)))
+           (if (functionp headers) (funcall headers) headers)))
+        (url-request-method (ghub--req-method req))
+        (url-request-data payload)
+        (url-show-status nil)
+        (url     (ghub--req-url req))
+        (handler (ghub--req-handler req))
+        (silent  (ghub--req-silent req))
+        (gnutls-algorithm-priority
+         (if (and ghub-use-workaround-for-emacs-bug
+                  (or (eq ghub-use-workaround-for-emacs-bug 'force)
+                      (and (not gnutls-algorithm-priority)
+                           (>= libgnutls-version 30603)
+                           (version<= emacs-version "26.2")
+                           (memq (ghub--req-forge req) '(github nil)))))
+             "NORMAL:-VERS-TLS1.3"
+           gnutls-algorithm-priority)))
+    (if (or (ghub--req-callback  req)
+            (ghub--req-errorback req))
+        (url-retrieve url handler (list req) silent)
+      ;; When this function has already been called, then it is a
+      ;; no-op.  Otherwise it sets `url-registered-auth-schemes' among
+      ;; other things.  If we didn't ensure that it has been run, then
+      ;; `url-retrieve-synchronously' would do it, which would cause
+      ;; the value that we let-bind below to be overwritten, and the
+      ;; "default" value to be lost outside the let-binding.
+      (url-do-setup)
+      (with-current-buffer
+          (let ((url-registered-auth-schemes
+                 '(("basic" ghub--basic-auth-errorback . 10))))
+            (url-retrieve-synchronously url silent))
+        (funcall handler (car url-callback-arguments) req)))))
+
+(defun ghub--handle-response (status req)
+  (let ((buffer (current-buffer)))
+    (unwind-protect
+        (progn
+          (set-buffer-multibyte t)
+          (let* ((unpaginate (ghub--req-unpaginate req))
+                 (headers    (ghub--handle-response-headers status req))
+                 (payload    (ghub--handle-response-payload req))
+                 (payload    (ghub--handle-response-error status payload req))
+                 (value      (ghub--handle-response-value payload req))
+                 (prev       (ghub--req-url req))
+                 (next       (cdr (assq 'next (ghub-response-link-relations
+                                               req headers payload)))))
+            (when (numberp unpaginate)
+              (cl-decf unpaginate))
+            (setf (ghub--req-url req)
+                  (url-generic-parse-url next))
+            (setf (ghub--req-unpaginate req) unpaginate)
+            (or (and next
+                     unpaginate
+                     (or (eq unpaginate t)
+                         (>  unpaginate 0))
+                     (ghub-continue req))
+                (let ((callback  (ghub--req-callback req))
+                      (errorback (ghub--req-errorback req))
+                      (err       (plist-get status :error)))
+                  (cond ((and err errorback)
+                         (setf (ghub--req-url req) prev)
+                         (funcall (if (eq errorback t)
+                                      'ghub--errorback
+                                    errorback)
+                                  err headers status req))
+                        (callback
+                         (funcall callback value headers status req))
+                        (t value))))))
+      (when (buffer-live-p buffer)
+        (kill-buffer buffer)))))
+
+(defun ghub--handle-response-headers (status req)
+  (goto-char (point-min))
+  (forward-line 1)
+  (let (headers)
+    (when (memq url-http-end-of-headers '(nil 0))
+      (setq url-debug t)
+      (let ((print-escape-newlines nil))
+        (error "BUG: missing headers
+  See https://github.com/magit/ghub/issues/81.
+  headers: %S
+  status: %S
+  buffer: %S"
+               url-http-end-of-headers
+               status
+               (current-buffer))))
+    (while (re-search-forward "^\\([^:]*\\): \\(.+\\)"
+                              url-http-end-of-headers t)
+      (push (cons (match-string 1)
+                  (match-string 2))
+            headers))
+    (setq headers (nreverse headers))
+    (goto-char (1+ url-http-end-of-headers))
+    (if (and req (or (ghub--req-callback req)
+                     (ghub--req-errorback req)))
+        (setq-local ghub-response-headers headers)
+      (setq-default ghub-response-headers headers))
+    headers))
+
+(defun ghub--handle-response-error (status payload req)
+  (let ((noerror (ghub--req-noerror req))
+        (err (plist-get status :error)))
+    (if err
+        (if noerror
+            (if (eq noerror 'return)
+                payload
+              (setcdr (last err) (list payload))
+              nil)
+          (ghub--signal-error err payload req))
+      payload)))
+
+(defun ghub--signal-error (err &optional payload req)
+  (pcase-let ((`(,symb . ,data) err))
+    (if (eq symb 'error)
+        (if (eq (car-safe data) 'http)
+            (signal 'ghub-http-error
+                    (let ((code (car (cdr-safe data))))
+                      (list code
+                            (nth 2 (assq code url-http-codes))
+                            (and req (url-filename (ghub--req-url req)))
+                            payload)))
+          (signal 'ghub-error data))
+      (signal symb data))))
+
+(defun ghub--errorback (err _headers _status req)
+  (ghub--signal-error err (nth 3 err) req))
+
+(defun ghub--handle-response-value (payload req)
+  (setf (ghub--req-value req)
+        (nconc (ghub--req-value req)
+               (if-let ((nested (and (eq (ghub--req-forge req) 'bitbucket)
+                                     (assq 'values payload))))
+                   (cdr nested)
+                 payload))))
+
+(defun ghub--handle-response-payload (req)
+  (funcall (or (ghub--req-reader req)
+               'ghub--read-json-payload)
+           url-http-response-status))
+
+(defun ghub--read-json-payload (_status)
+  (let ((raw (ghub--decode-payload)))
+    (and raw
+         (condition-case nil
+             (let ((json-object-type 'alist)
+                   (json-array-type  'list)
+                   (json-key-type    'symbol)
+                   (json-false       nil)
+                   (json-null        nil))
+               (json-read-from-string raw))
+           (json-readtable-error
+            `((message
+               . ,(if (looking-at "<!DOCTYPE html>")
+                      (if (re-search-forward
+                           "<p>\\(?:<strong>\\)?\\([^<]+\\)" nil t)
+                          (match-string 1)
+                        "error description missing")
+                    (string-trim (buffer-substring (point) (point-max)))))
+              (documentation_url
+               . "https://github.com/magit/ghub/wiki/Github-Errors")))))))
+
+(defun ghub--decode-payload (&optional _status)
+  (and (not (eobp))
+       (decode-coding-string
+        (buffer-substring-no-properties (point) (point-max))
+        'utf-8)))
+
+(defun ghub--encode-payload (payload)
+  (and payload
+       (progn
+         (unless (stringp payload)
+           (setq payload (json-encode-list payload)))
+         (encode-coding-string payload 'utf-8))))
+
+(defun ghub--url-encode-params (params)
+  (mapconcat (lambda (param)
+               (pcase-let ((`(,key . ,val) param))
+                 (concat (url-hexify-string (symbol-name key)) "="
+                         (if (integerp val)
+                             (number-to-string val)
+                           (url-hexify-string val)))))
+             params "&"))
+
+;;; Authentication
+;;;; API
+
+;;;###autoload
+(defun ghub-create-token (host username package scopes)
+  "Create, store and return a new token.
+
+HOST is the Github instance, usually \"api.github.com\".
+USERNAME is the name of a user on that instance.
+PACKAGE is the package that will use the token.
+SCOPES are the scopes the token is given access to."
+  (interactive
+   (pcase-let ((`(,host ,username ,package)
+                (ghub--read-triplet)))
+     (list host username package
+           (split-string
+            (read-string
+             "Scopes (separated by commas): "
+             (mapconcat #'symbol-name
+                        (symbol-value
+                         (intern (format "%s-github-token-scopes" package)))
+                        ","))
+            "," t "[\s\t]+"))))
+  (let ((user (ghub--ident username package)))
+    (cl-destructuring-bind (save token)
+        (ghub--auth-source-get (list :save-function :secret)
+          :create t :host host :user user
+          :secret
+          (cdr (assq 'token
+                     (ghub-post
+                      "/authorizations"
+                      `((scopes . ,scopes)
+                        (note   . ,(ghub--ident-github package)))
+                      :username username :auth 'basic :host host))))
+      ;; Build-in back-ends return a function that does the actual
+      ;; saving, while for some third-party back-ends ":create t"
+      ;; is enough.
+      (when (functionp save)
+        (funcall save))
+      ;; If the Auth-Source cache contains the information that there
+      ;; is no value, then setting the value does not invalidate that
+      ;; now incorrect information.
+      ;; The (:max 1) is needed and has to be placed at the
+      ;; end for Emacs releases before 26.1.  #24 #64 #72
+      (auth-source-forget (list :host host :user user :max 1))
+      token)))
+
+;;;###autoload
+(defun ghub-token-scopes (host username package)
+  "Return and echo the scopes of the specified token.
+This is intended for debugging purposes only.  The user
+has to provide several values including their password."
+  (interactive (ghub--read-triplet))
+  (let ((scopes
+         (cdr (assq 'scopes (ghub--get-token-plist host username package)))))
+    (when (called-interactively-p 'any)
+      ;; Also show the input values to make it easy for package
+      ;; authors to verify that the user has done it correctly.
+      (message "Scopes for %s@%s: %S"
+               (ghub--ident username package)
+               host scopes))
+    scopes))
+
+;;;###autoload
+(defun ghub-clear-caches ()
+  "Clear all caches that might negatively affect Ghub.
+
+If a library that is used by Ghub caches incorrect information
+such as a mistyped password, then that can prevent Ghub from
+asking the user for the correct information again.
+
+Set `url-http-real-basic-auth-storage' to nil
+and call `auth-source-forget+'."
+  (interactive)
+  (setq url-http-real-basic-auth-storage nil)
+  (auth-source-forget+))
+
+;;;; Internal
+
+(defun ghub--headers (headers host auth username forge)
+  (push (cons "Content-Type" "application/json") headers)
+  (if (eq auth 'none)
+      headers
+    (unless (or username (stringp auth))
+      (setq username (ghub--username host forge)))
+    (lambda ()
+      (if (eq auth 'basic)
+          (cons (cons "Authorization" (ghub--basic-auth host username))
+                headers)
+        (cons (ghub--auth host auth username forge) headers)))))
+
+(defun ghub--auth (host auth &optional username forge)
+  (unless username
+    (setq username (ghub--username host forge)))
+  (if (eq auth 'basic)
+      (cl-ecase forge
+        ((nil github gitea gogs bitbucket)
+         (cons "Authorization" (ghub--basic-auth host username)))
+        (gitlab
+         (error "Gitlab does not support basic authentication")))
+    (cons (cl-ecase forge
+            ((nil github gitea gogs bitbucket)
+             "Authorization")
+            (gitlab
+             "Private-Token"))
+          (if (eq forge 'bitbucket)
+              ;; For some undocumented reason Bitbucket supports
+              ;; values of the form "token <token>" only for GET
+              ;; requests.  For PUT requests we have to use basic
+              ;; authentication.  Note that the secret is a token
+              ;; (aka "app password"), not the actual password.
+              ;; The documentation fails to mention this little
+              ;; detail.  See #97.
+              (concat "Basic "
+                      (base64-encode-string
+                       (concat username ":"
+                               (ghub--token host username auth nil forge))))
+            (concat
+             (and (not (eq forge 'gitlab)) "token ")
+             (encode-coding-string
+              (cl-typecase auth
+                (string auth)
+                (null   (ghub--token host username 'ghub nil forge))
+                (symbol (ghub--token host username auth  nil forge))
+                (t (signal 'wrong-type-argument
+                           `((or stringp symbolp) ,auth))))
+              'utf-8))))))
+
+(defun ghub--basic-auth (host username)
+  (let ((url (url-generic-parse-url
+              (if (member host ghub-insecure-hosts) "http://" "https://"))))
+    (setf (url-user url) username)
+    (url-basic-auth url t)))
+
+(defun ghub--basic-auth-errorback (url &optional prompt _overwrite _realm _args)
+  ;; This gets called twice.  Do nothing the first time,
+  ;; when PROMPT is nil.  See `url-get-authentication'.
+  (when prompt
+    (if (assoc "X-GitHub-OTP" (ghub--handle-response-headers nil nil))
+        (progn
+          (setq url-http-extra-headers
+                `(("Pragma" . "no-cache")
+                  ("Content-Type" . "application/json")
+                  ("X-GitHub-OTP" . ,(ghub--read-2fa-code))
+                  ;; Without "Content-Type" and "Authorization".
+                  ;; The latter gets re-added from the return value.
+                  ,@(cddr url-http-extra-headers)))
+          ;; Return the cached values, they are correct.
+          (url-basic-auth url nil nil nil))
+      ;; Remove the invalid cached values and fail, which
+      ;; is better than the invalid values sticking around.
+      (setq url-http-real-basic-auth-storage
+            (cl-delete (format "%s:%d" (url-host url) (url-port url))
+                       url-http-real-basic-auth-storage
+                       :test #'equal :key #'car))
+      nil)))
+
+(defun ghub--token (host username package &optional nocreate forge)
+  (let* ((user (ghub--ident username package))
+         (token
+          (or (car (ghub--auth-source-get (list :secret)
+                     :host host :user user))
+              (progn
+                ;; Auth-Source caches the information that there is no
+                ;; value, but in our case that is a situation that needs
+                ;; fixing so we want to keep trying by invalidating that
+                ;; information.
+                ;; The (:max 1) is needed and has to be placed at the
+                ;; end for Emacs releases before 26.1.  #24 #64 #72
+                (auth-source-forget (list :host host :user user :max 1))
+                (and (not nocreate)
+                     (cl-ecase forge
+                       ((nil github)
+                        (ghub--confirm-create-token host username package))
+                       ((gitlab gitea gogs bitbucket)
+                        (error "Required %s token (%S for %S) does not exist.
+See https://magit.vc/manual/ghub/Support-for-Other-Forges.html for instructions."
+                               (capitalize (symbol-name forge))
+                               user host))))))))
+    (if (functionp token) (funcall token) token)))
+
+(cl-defmethod ghub--host (forge)
+  (cl-ecase forge
+    ((nil github)
+     (or (ignore-errors (car (process-lines "git" "config" "github.host")))
+         ghub-default-host))
+    (gitlab
+     (or (ignore-errors (car (process-lines "git" "config" "gitlab.host")))
+         (bound-and-true-p glab-default-host)))
+    (gitea
+     (or (ignore-errors (car (process-lines "git" "config" "gitea.host")))
+         (bound-and-true-p gtea-default-host)))
+    (gogs
+     (or (ignore-errors (car (process-lines "git" "config" "gogs.host")))
+         (bound-and-true-p gogs-default-host)))
+    (bitbucket
+     (or (ignore-errors (car (process-lines "git" "config" "bitbucket.host")))
+         (bound-and-true-p buck-default-host)))))
+
+(cl-defmethod ghub--username (host &optional forge)
+  (let ((var
+         (cl-ecase forge
+           ((nil github)
+            (if (equal host ghub-default-host)
+                "github.user"
+              (format "github.%s.user" host)))
+           (gitlab
+            (if (equal host "gitlab.com/api/v4")
+                "gitlab.user"
+              (format "gitlab.%s.user" host)))
+           (bitbucket
+            (if (equal host "api.bitbucket.org/2.0")
+                "bitbucket.user"
+              (format "bitbucket.%s.user" host)))
+           (gitea
+            (when (zerop (call-process "git" nil nil nil "config" "gitea.host"))
+              (error "gitea.host is set but always ignored"))
+            (format "gitea.%s.user" host))
+           (gogs
+            (when (zerop (call-process "git" nil nil nil "config" "gogs.host"))
+              (error "gogs.host is set but always ignored"))
+            (format "gogs.%s.user"  host)))))
+    (condition-case nil
+        (car (process-lines "git" "config" var))
+      (error
+       (let ((user (read-string
+                    (format "Git variable `%s' is unset.  Set to: " var))))
+         (if (equal user "")
+             (user-error "The empty string is not a valid username")
+           (call-process "git" nil nil nil "config" "--global" var user)
+           user))))))
+
+(defun ghub--ident (username package)
+  (format "%s^%s" username package))
+
+(defun ghub--ident-github (package)
+  (format "Emacs package %s @ %s"
+          package
+          (or ghub-override-system-name (system-name))))
+
+(defun ghub--package-scopes (package)
+  (let ((var (intern (format "%s-github-token-scopes" package))))
+    (if (boundp var)
+        (symbol-value var)
+      (error "%s fails to define %s" package var))))
+
+(defun ghub--confirm-create-token (host username package)
+  (let* ((ident (ghub--ident-github package))
+         (scopes (ghub--package-scopes package))
+         (max-mini-window-height 40))
+    (if (let ((message-log-max nil))
+          (yes-or-no-p
+           (format
+            "Such a Github API token is not available:
+
+  Host:    %s
+  User:    %s
+  Package: %s
+
+  Scopes requested in `%s-github-token-scopes':\n%s
+  Store on Github as:\n    %S
+  Store locally according to option `auth-sources':\n    %S
+%s
+If in doubt, then abort and first view the section of
+the Ghub documentation called \"Interactively Creating
+and Storing a Token\".
+
+Otherwise confirm and then provide your Github username and
+password at the next two prompts.  Depending on the backend
+you might have to provide a passphrase and confirm that you
+really want to save the token.
+
+Create and store such a token? "
+            host username package package
+            (mapconcat (lambda (scope) (format "    %s" scope)) scopes "\n")
+            ident auth-sources
+            (if (and (stringp (car auth-sources))
+                     (not (string-suffix-p ".gpg" (car auth-sources))))
+                (format "
+WARNING: The token will be stored unencrypted in %S.
+         If you don't want that, you have to abort and customize
+         the `auth-sources' option.\n" (car auth-sources))
+              ""))))
+        (condition-case err
+            ;; Naively attempt to create the token since the user told us to
+            (ghub-create-token host username package scopes)
+          ;; The API _may_ respond with the fact that a token of the name
+          ;; we wanted already exists. At this point we're out of luck. We
+          ;; don't have a token (otherwise why would we be here?) and, if
+          ;; the user is using SMS 2FA, we have no way of telling GitHub
+          ;; to send a new 2FA code to the user other than sending a POST
+          ;; to /authorizations which is ugly.
+          ;;
+          ;; If they are not using SMS 2FA then we could try to delete the
+          ;; existing token (which will require them to hand us another
+          ;; OTP for the delete request) and then call create again,
+          ;; possibly requiring _another_ OTP if they don't do things fast
+          ;; enough, but this is only because non-SMS 2FA doesn't require
+          ;; any action on GitHub's part.
+          ;;
+          ;; GitHub does hand us a header that indicates what type of 2FA
+          ;; is in use, but it's not currently available in this location
+          ;; and would make the following code which is already quite
+          ;; complicated even more complicated. So in the interest of
+          ;; simplicity it's better to error out here and ask the user to
+          ;; take action. This situation should almost never arise anyway.
+          (ghub-http-error
+           (if (equal (alist-get 'code (car (alist-get 'errors (nth 4 err))))
+                      "already_exists")
+               (error "A token named %S already exists on Github.
+Please visit https://github.com/settings/tokens and delete it." ident)
+             (signal (car err) (cdr err)))))
+      (user-error "Abort"))))
+
+(defun ghub--get-token-id (host username package)
+  (let ((ident (ghub--ident-github package)))
+    (cl-some (lambda (x)
+               (let-alist x
+                 (and (equal .app.name ident) .id)))
+             (ghub-get "/authorizations"
+                       '((per_page . 100))
+                       :unpaginate t
+                       :username username :auth 'basic :host host))))
+
+(defun ghub--get-token-plist (host username package)
+  (ghub-get (format "/authorizations/%s"
+                    (ghub--get-token-id host username package))
+            nil :username username :auth 'basic :host host))
+
+(defun ghub--delete-token (host username package)
+  (ghub-delete (format "/authorizations/%s"
+                       (ghub--get-token-id host username package))
+               nil :username username :auth 'basic :host host))
+
+(defun ghub--read-triplet ()
+  (let ((host (read-string "Host: " (ghub--host))))
+    (list host
+          (read-string "Username: " (ghub--username host))
+          (intern (read-string "Package: " "ghub")))))
+
+(defvar ghub--2fa-cache nil)
+
+(defun ghub--read-2fa-code ()
+  (let ((code (read-string "Two-factor authentication code: "
+                           (and ghub--2fa-cache
+                                (< (float-time (time-subtract
+                                                (current-time)
+                                                (cdr ghub--2fa-cache)))
+                                   25)
+                                (car ghub--2fa-cache)))))
+    (setq ghub--2fa-cache (cons code (current-time)))
+    code))
+
+(defun ghub--auth-source-get (keys &rest spec)
+  (declare (indent 1))
+  (let ((plist (car (apply #'auth-source-search
+                           (append spec (list :max 1))))))
+    (mapcar (lambda (k)
+              (plist-get plist k))
+            keys)))
+
+(advice-add 'auth-source-netrc-parse-next-interesting :around
+            'auth-source-netrc-parse-next-interesting@save-match-data)
+(defun auth-source-netrc-parse-next-interesting@save-match-data (fn)
+  "Save match-data for the benefit of caller `auth-source-netrc-parse-one'.
+Without wrapping this function in `save-match-data' the caller
+won't see the secret from a line that is followed by a commented
+line."
+  (save-match-data (funcall fn)))
+
+;;; _
+(provide 'ghub)
+(require 'ghub-graphql)
+;;; ghub.el ends here
diff --git a/elpa/ghub-20191007.1420/ghub.info b/elpa/ghub-20191007.1420/ghub.info
new file mode 100644 (file)
index 0000000..5d0bdb4
--- /dev/null
@@ -0,0 +1,1319 @@
+This is ghub.info, produced by makeinfo version 6.5 from ghub.texi.
+
+     Copyright (C) 2017-2019 Jonas Bernoulli <jonasNOSPAMbernoul.li>
+
+     You can redistribute this document and/or modify it under the terms
+     of the GNU General Public License as published by the Free Software
+     Foundation, either version 3 of the License, or (at your option)
+     any later version.
+
+     This document is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* Ghub: (ghub).         Minuscule client library for the Github API.
+END-INFO-DIR-ENTRY
+
+\1f
+File: ghub.info,  Node: Top,  Next: Introduction,  Up: (dir)
+
+Ghub User and Developer Manual
+******************************
+
+Ghub provides basic support for using the APIs of various Git forges
+from Emacs packages.  Originally it only supported the Github REST API,
+but now it also supports the Github GraphQL API as well as the REST APIs
+of Gitlab, Gitea, Gogs and Bitbucket.
+
+   Ghub abstracts access to API resources using only a handful of basic
+functions such as â€˜ghub-get‘.  These are convenience wrappers around
+‘ghub-request‘.  Additional forge-specific wrappers like â€˜glab-put‘,
+‘gtea-put‘, â€˜gogs-post‘ and â€˜buck-delete‘ are also available.  Ghub does
+not provide any resource-specific functions, with the exception of
+‘FORGE-repository-id‘.
+
+   When accessing Github, then Ghub handles the creation and storage of
+access tokens using a setup wizard to make it easier for users to get
+started.  The tokens for other forges have to be created manually.
+
+   Ghub is intentionally limited to only provide these two essential
+features â€” basic request functions and guided setup â€” to avoid being too
+opinionated, which would hinder wide adoption.  It is assumed that wide
+adoption would make life easier for users and maintainers alike, because
+then all packages that talk to forge APIs could be configured the same
+way.
+
+This manual is for Ghub version 3.2.0 (v3.2.0-35-g9d75d30+1).
+
+     Copyright (C) 2017-2019 Jonas Bernoulli <jonasNOSPAMbernoul.li>
+
+     You can redistribute this document and/or modify it under the terms
+     of the GNU General Public License as published by the Free Software
+     Foundation, either version 3 of the License, or (at your option)
+     any later version.
+
+     This document is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+* Menu:
+
+* Introduction::
+* Getting Started::
+* Using Ghub in Personal Scripts::
+* Using Ghub in a Package::
+* API::
+* GraphQL Support::
+* Support for Other Forges::
+
+— The Detailed Node Listing â€”
+
+Getting Started
+
+* Setting the Username::
+* Interactively Creating and Storing a Token::
+* Manually Creating and Storing a Token::
+* How Ghub uses Auth-Source::
+
+API
+
+* Making Requests::
+* Authentication::
+* Configuration Variables::
+
+Support for Other Forges
+
+* Forge Functions and Variables::
+* Forge Limitations and Notes::
+
+
+\1f
+File: ghub.info,  Node: Introduction,  Next: Getting Started,  Prev: Top,  Up: Top
+
+1 Introduction
+**************
+
+Ghub provides basic support for using the APIs of various Git forges
+from Emacs packages.  Originally it only supported the Github REST API,
+but now it also supports the Github GraphQL API as well as the REST APIs
+of Gitlab, Gitea, Gogs and Bitbucket.
+
+   Ghub abstracts access to API resources using only a handful of basic
+functions such as â€˜ghub-get‘.  These are convenience wrappers around
+‘ghub-request‘.  Additional forge-specific wrappers like â€˜glab-put‘,
+‘gtea-put‘, â€˜gogs-post‘ and â€˜buck-delete‘ are also available.  Ghub does
+not provide any resource-specific functions, with the exception of
+‘FORGE-repository-id‘.
+
+   When accessing Github, then Ghub handles the creation and storage of
+access tokens using a setup wizard to make it easier for users to get
+started.  The tokens for other forges have to be created manually.
+
+   Ghub is intentionally limited to only provide these two essential
+features â€” basic request functions and guided setup â€” to avoid being too
+opinionated, which would hinder wide adoption.  It is assumed that wide
+adoption would make life easier for users and maintainers alike, because
+then all packages that talk to forge APIs could be configured the same
+way.
+
+   Fancier interfaces can be implemented on top of Ghub, and one such
+wrapper â€” named simply Ghub+ â€” has already been implemented.  The
+benefit of basing various opinionated interfaces on top of a single
+library that provides only the core functionality is that choosing the
+programming interface no longer dictates how access tokens are handled.
+Users can then use multiple packages that access the Github API without
+having to learn the various incompatible ways packages expect the
+appropriate token to be made available to them.
+
+   Ghub uses the built-in â€˜auth-source’ library to store access tokens.
+That library is very flexible and supports multiple backends, which
+means that it is up to the user how secrets are stored.  They can, among
+other things, choose between storing secrets in plain text for ease of
+use, or encrypted for better security.
+
+   Previously (as in until this library is widely adopted) it was up to
+package authors to decide if things should be easy or secure.  (Note
+that â€˜auth-source’ defaults to "easy" â€” you have been warned.)
+
+   Ghub expects package authors to use a dedicated access token instead
+of sharing a single token between all packages that rely on it.  That
+means that users cannot configure Ghub once and later start using a new
+package without any additional setup.  But Ghub helps with that.
+
+   When the user invokes some command that ultimately results in
+‘ghub-request’ being called and the appropriate token is not available
+yet, then the user is guided through the process of creating and storing
+a new token, and at the end of that process the request is carried out
+as if the token had been available to begin with.
+
+\1f
+File: ghub.info,  Node: Getting Started,  Next: Using Ghub in Personal Scripts,  Prev: Introduction,  Up: Top
+
+2 Getting Started
+*****************
+
+Each package that uses Ghub uses its own token.  Despite that, chances
+are good that after successfully configuring one package you can just
+start using another package pretty much instantly.
+
+   If the necessary token to access a Github instance is not available
+when a package makes an API request, then a setup wizard pops up, and
+after answering a few questions you are good to go.  Even the request
+that caused the wizard to be summoned should succeed and for most users
+this should be true even when configuring the very first token.
+
+   However, in some situations some manual configuration is necessary
+*before* using the wizard, or the wizard cannot be used at all:
+
+   â€¢ If you don’t want to use the wizard then you don’t have to and can
+     create tokens manually as described in *note Manually Creating and
+     Storing a Token::.
+
+   â€¢ Unfortunately only Github supports the creation of tokens by using
+     the API.  If you want to access another forge, then you have to
+     create the token manually as describe in *note Manually Creating
+     and Storing a Token::.  Also see *note Support for Other Forges::.
+
+   â€¢ If you want to access a Github Enterprise instance, then you have
+     to tell Ghub about that before the wizard makes its appearance by
+     setting the Git variable â€˜github.host’.  You also have to tell Ghub
+     your username for that instance using the variable
+     â€˜github.HOST.user’ even if it is the same as on Github.com.
+
+     These variables are documented in *note Configuration Variables::.
+     Also see *note Setting the Username::.  TL;DR: If your Github
+     Enterprise instance is hosted at â€˜git.example.com’ and your
+     username on that instance is â€˜jtribbiani’, then set â€˜github.host’
+     to â€˜git.example.com/api/v3’ in every repository cloned from that
+     instance (i.e.  _do not_ set it globally) and _globally_ set
+     â€˜github.git.example.com/api/v3.user’ to â€˜jtribbiani’.  The latter
+     is necessary even if your username on Github.com is the same.
+
+     For some Github Enterprice instances â€˜/api’ has to be used instead
+     of â€˜/api/v3’ as shown above.  If the wizard fails in both cases,
+     then try creating the token manually.
+
+   â€¢ If the variable â€˜github.user’ (or â€˜github.HOST.user’ for an
+     Enterprise instance) is unset when the wizard is first summoned,
+     then you are asked to provide your username.  That value is then
+     stored *globally* to avoid having to ask you that question once per
+     repository.  If you have multiple accounts on Github.com (or a
+     Github Enterprise instance), then you have to explicitly tell Ghub
+     about that.  This can be done by setting the repository-local
+     values of the appropriate variable *before* the wizard is invoked.
+
+   â€¢ You might forget to do the above, which is why it is important to
+     carefully read the output of the wizard.  If it turns out that you
+     forgot to set a variable, then you must abort, set the variable,
+     and repeat the request to trigger the wizard again.
+
+   â€¢ The setup wizard should work even if you have enabled two-factor
+     authentication.  However if your Github Enterprise instance
+     enforces Single Sign-On as an additional security measure, then you
+     are out of luck and have to create the token manually as described
+     in *note Manually Creating and Storing a Token::.
+
+   The variables mentioned above â€” and others â€” are documented in *note
+Configuration Variables:: and the setup wizard is documented in *note
+Interactively Creating and Storing a Token::.
+
+* Menu:
+
+* Setting the Username::
+* Interactively Creating and Storing a Token::
+* Manually Creating and Storing a Token::
+* How Ghub uses Auth-Source::
+
+\1f
+File: ghub.info,  Node: Setting the Username,  Next: Interactively Creating and Storing a Token,  Up: Getting Started
+
+2.1 Setting the Username
+========================
+
+If you haven’t set the Git variable â€˜github.user’ yet when making a
+request, then you will be asked:
+
+     Git variable `github.user' is unset.  Set to:
+
+   You are expected to provide your Github username here.  The provided
+value will be saved globally (using â€˜git config --global github.user
+USERNAME’).
+
+   If you need to identify as another user in a particular repository,
+then you have to set that variable locally, *before* making a request:
+
+     cd /path/to/repo
+     git config github.user USERNAME
+
+   For Github Enterprise instances you have to specify where the API can
+be accessed *before* you try to access it and a different variable has
+to be used to set the username.  For example if the API is available at
+‘https://example.com/api/v3’, then you should do this:
+
+     # Do this once
+     git config --global github.example.com/api/v3.user EMPLOYEE
+
+     # Do this for every corporate repository
+     cd /path/to/repo
+     git config github.host example.com/api/v3
+
+   If you do not set â€˜github.example.com/api/v3.user’, then you will be
+asked to provide the value when trying to make a request, but you do
+have to manually set â€˜github.host’, or Ghub assumes that you are trying
+to access â€˜api.github.com’.
+
+\1f
+File: ghub.info,  Node: Interactively Creating and Storing a Token,  Next: Manually Creating and Storing a Token,  Prev: Setting the Username,  Up: Getting Started
+
+2.2 Interactively Creating and Storing a Token
+==============================================
+
+Ghub uses a different token for every package as well as for every
+machine from which you access the Github API (and obviously also for
+every Github instance and user).  This allows packages to only request
+the scopes that they actually need and also gives users the opportunity
+to refuse access to certain scopes if they expect to not use the
+features that need them.
+
+   Usually you don’t have to worry about creating and storing a token
+yourself and can just make a request.  Note however that you don’t have
+to use the setup wizard described below.  Alternatively you can perform
+the setup manually as described in the next section.
+
+   If you make a request and the required token is not available yet,
+then the setup wizard will first ask you something like this:
+
+     Such a Github API token is not available:
+
+       Host:    api.github.com
+       User:    USERNAME
+       Package: PACKAGE
+
+       Scopes requested in `PACKAGE-github-token-scopes':
+         repo
+       Store on Github as:
+         "Emacs package PACKAGE @ LOCAL-MACHINE"
+       Store locally according to option `auth-sources':
+         ("~/.authinfo" "~/.authinfo.gpg" "~/.netrc")
+
+     If in doubt, then abort and first view the section of
+     the Ghub documentation called "Interactively Creating
+     and Storing a Token".
+
+     Create and store such a token? (yes or no)
+
+   If you don’t have any doubts, then answer "yes".  Lets address some
+of the doubts that you might have:
+
+   â€¢ â€˜Host’ usually is "api.github.com" and that is usually what you
+     want.  If you are trying to access a Github Enterprise instance,
+     then it should be something else and you have to set the value
+     manually before the setup wizard is summoned, as described in the
+     parent section.
+
+   â€¢ â€˜User’ should be your Github.com (or Github Enterprise instance)
+     username.  If it is something else and it doesn’t look like a
+     simple typo, then you should read the parent section again.  In
+     either case you have to abort.
+
+   â€¢ â€˜Package’ should be the name of the package you are using to access
+     the Github API.
+
+     If it is â€˜ghub’, then the package author disregarded that
+     convention and you should probably report a bug in the issue
+     tracker of that package.
+
+     Or you yourself are using â€˜ghub-request’ or one of its wrappers
+     directly, in which case this is expected and perfectly fine.  In
+     that case you might however want to abort and change the value of
+     the variable â€˜ghub-github-token-scopes’ before triggering the
+     wizard again.
+
+   â€¢ Each â€˜PACKAGE’ has to specify the tokens that it needs using a
+     variable named â€˜PACKAGE-github-token-scopes’.  The doc-string of
+     that variable should document why the various scopes are needed.
+
+     The meaning of the various scopes are documented at
+     <https://magit.vc/goto/f63aeb0a>.
+
+   â€¢ The value of â€˜auth-sources’ is shown.  The default value causes
+     secrets to be stored in plain text.  Because this might be
+     unexpected, Ghub additionally displays a warning when appropriate.
+
+          WARNING: The token will be stored unencrypted in "~/.authinfo".
+                   If you don't want that, you have to abort and customize
+                   the `auth-sources' option.
+
+     Whether that is something that needs fixing, is up to you.  If your
+     answer is yes, then you should abort and see *note How Ghub uses
+     Auth-Source:: for instructions on how to save the token more
+     securely.
+
+   â€¢ When creating a token it is necessary to provide a token
+     description.  Ghub uses descriptions that have the form "Emacs
+     package PACKAGE @ LOCAL-MACHINE".
+
+     Github uses the token description to identify the token, not merely
+     as something useful to humans.  Token descriptions therefore have
+     to be unique and in rare cases you get an additional prompt, asking
+     you something like:
+
+          A token named "Emacs package PACKAGE @ LOCAL-MACHINE"
+          already exists on Github.  Replace it?
+
+     You might see this message when you have lost the old token and
+     want to replace it with a new one, in which case you should
+     obviously just proceed.
+
+     Or two of your computers have the same hostname, which is bad
+     practice because it gains you nothing but leads to issues such as
+     this.  Or you are dual-booting on this machine and use the same
+     hostname in all operating systems, which is a somewhat reasonable
+     thing to do, but never-the-less leads to issues like this.
+
+     In either case you will have to use something other than the value
+     returned by â€˜system-name’ to identify the current machine or
+     operating system.  Or you can continue to identify different things
+     using the same identifier, in which case you have to manually
+     distribute the token.
+
+     The former is recommended and also easier to do, using the variable
+     â€˜ghub-override-system-name’.  See *note Configuration Variables::
+     for details.
+
+   After the above prompt you are also asked for your username and
+password.  If you have enabled two-factor authentication, then you also
+have to provide the authentication code at least twice.  If you make
+sure the code is still good for a while when asked for it first, then
+you can just press â€˜RET’ at the later prompt(s).
+
+\1f
+File: ghub.info,  Node: Manually Creating and Storing a Token,  Next: How Ghub uses Auth-Source,  Prev: Interactively Creating and Storing a Token,  Up: Getting Started
+
+2.3 Manually Creating and Storing a Token
+=========================================
+
+If you cannot or don’t want to use the wizard then you have to (1)
+figure out what scopes a package wants, (2) create such a token using
+the web interface and (3) store the token where Ghub expects to find it.
+
+   A package named â€˜PACKAGE’ has to specify the scopes that it wants in
+the variable named â€˜PACKAGE-github-token-scopes’.  The doc-string of
+such variables should document what the various scopes are needed for.
+
+   To create or edit a token go to <https://github.com/settings/tokens>.
+For Gitlab.com use <https://gitlab.com/profile/personal_access_tokens>.
+
+   Finally store the token in a place where Ghub looks for it, as
+described in *note How Ghub uses Auth-Source::.
+
+   If you store the token in a file like â€˜~/.authinfo’, then note that
+‘auth-source’’s parsing of that file is brittle.  Make sure the file
+ends with a newline character, that there are no empty or invalid lines,
+and that all comments are prefixed with â€˜#’.
+
+\1f
+File: ghub.info,  Node: How Ghub uses Auth-Source,  Prev: Manually Creating and Storing a Token,  Up: Getting Started
+
+2.4 How Ghub uses Auth-Source
+=============================
+
+Please see *note (auth)Top:: for all the gory details about Auth-Source.
+Some Ghub-specific information and important notes follow.
+
+   The variable â€˜auth-sources’ controls how and where Auth-Source stores
+new secrets and where it looks for known secrets.  The default value is
+‘("~/.authinfo" "~/.authinfo.gpg" "~/.netrc")’, which means that it
+looks in all of these files in order to find secrets and that it stores
+new secrets in â€˜~/.authinfo’ because that is the first element of the
+list.  It doesn’t matter which files already do or don’t exist when
+storing a new secret, the first file is always used.
+
+   Secrets are stored in â€˜~/.authinfo’ in plain text.  If you don’t want
+that (good choice), then you have to customize â€˜auth-sources’, e.g.  by
+flipping the positions of the first two elements.
+
+   Auth-Source also supports storing secrets in various key-chains.
+Refer to its documentation for more information.
+
+   Some Auth-Source backends only support storing three values per
+entry, the "machine", the "login" and the "password".  Because Ghub uses
+separate tokens for each package, it has to squeeze four values into
+those three slots, and it does that by using "USERNAME^PACKAGE" as the
+"login".
+
+   Assuming your username is "ziggy",the package is named "stardust",
+and you want to access *Github.com* an entry in one of the three
+mentioned files would then look like this:
+
+     machine api.github.com login ziggy^stardust password 012345abcdef...
+
+   Assuming your username is "ziggy",the package is named "stardust",
+and you want to access *Gitlab.com* an entry in one of the three
+mentioned files would then look like this:
+
+     machine gitlab.com/api/v4 login ziggy^stardust password 012345abcdef...
+
+\1f
+File: ghub.info,  Node: Using Ghub in Personal Scripts,  Next: Using Ghub in a Package,  Prev: Getting Started,  Up: Top
+
+3 Using Ghub in Personal Scripts
+********************************
+
+You can use â€˜ghub-request’ and its wrapper functions in your personal
+scripts, of course.  Unlike when you use Ghub from a package that you
+distribute for others to use, you don’t have to specify a package in
+personal scripts.
+
+     ;; This is perfectly acceptable in personal scripts ...
+     (ghub-get "/user")
+
+     ;; ... and actually equal to
+     (ghub-get "/user" nil :auth 'ghub)
+
+     ;; In packages you have to specify the package using AUTH.
+     (ghub-get "/user" nil :auth 'foobar)
+
+   When you do not specify the â€˜AUTH’ argument, then a request is made
+on behalf of the â€˜ghub’ package itself.  Like for any package that uses
+Ghub, â€˜ghub’ has to declare what scopes it needs, using, in this case,
+the variable â€˜ghub-github-token-scopes’.
+
+   The default value of that variable is â€˜(repo)’ and you might want to
+add additional scopes.  You can later add additional scopes to an
+existing token, using the web interface at
+<https://github.com/settings/tokens>.
+
+   If you do that, then you might want to also set the variable
+accordingly, but note that Ghub only consults that when *creating* a new
+token.  If you want to know a token’s effective scopes use the command
+‘ghub-token-scopes’, described in the next section.
+
+\1f
+File: ghub.info,  Node: Using Ghub in a Package,  Next: API,  Prev: Using Ghub in Personal Scripts,  Up: Top
+
+4 Using Ghub in a Package
+*************************
+
+Every package should use its own token.  This allows you as the author
+of some package to only request access to API scopes that are actually
+needed, which in turn might make it easier for users to trust your
+package not to do unwanted things.
+
+   The scopes used by â€˜PACKAGE’ have to be defined using the variable
+‘PACKAGE-github-token-scopes’, and you have to tell â€˜ghub-request’ on
+behalf of which package a request is being made by passing the symbol
+‘PACKAGE’ as the value of its â€˜AUTH’ argument.
+
+     (ghub-request "GET" "/user" nil :auth 'PACKAGE)
+
+ -- Variable: PACKAGE-github-token-scopes
+
+     This variable defines the token scopes requested by the package
+     named â€˜PACKAGE’.  The doc-string should explain what the various
+     scopes are needed for to prevent users from giving â€˜PACKAGE’ fewer
+     permissions than it absolutely needs and also to give them greater
+     confidence that â€˜PACKAGE’ is only requesting the permissions that
+     it actually needs.
+
+     The value of this variable does not necessarily correspond to the
+     scopes that the respective token actually gives access to.  There
+     is nothing that prevents users from changing the value *after*
+     creating the token or from editing the token’s scopes later on.
+
+     So it is pointless to check the value of this variable before
+     making a request.  You also should not query the API to reliably
+     determine the supported tokens before making a query.  Doing the
+     latter would mean that every request becomes two requests and that
+     the first request would have to be done using the user’s password
+     instead of a token.
+
+ -- Command: ghub-token-scopes
+
+     Because we cannot be certain that the user hasn’t messed up the
+     scopes, Ghub provides this command to make it easy to debug such
+     issues without having to rely on users being thoughtful enough to
+     correctly determine the used scopes manually.
+
+     Just tell users to run â€˜M-x ghub-token-scopes’ and to provide the
+     correct values for the â€˜HOST’, â€˜USERNAME’ and â€˜PACKAGE’ when
+     prompted, and to then post the output.
+
+     It is to be expected that users will occasionally mess that up so
+     this command outputs not only the scopes but also the user input so
+     that you can have greater confidence in the validity of the user’s
+     answer.
+
+          Scopes for USERNAME^PACKAGE@HOST: (SCOPE...)
+
+\1f
+File: ghub.info,  Node: API,  Next: GraphQL Support,  Prev: Using Ghub in a Package,  Up: Top
+
+5 API
+*****
+
+This section describes the Ghub API.  In other words it describes the
+public functions and variables provided by the Ghub package and not the
+APIs of the supported forges, which can be accessed by using those
+functions.  The forge APIs are documented at:
+
+   â€¢ Github: <https://developer.github.com/v3>
+
+   â€¢ Gitlab: <https://docs.gitlab.com/ee/api/README.html>
+
+   â€¢ Gitea: <https://docs.gitea.io/en-us/api-usage> and
+     <https://try.gitea.io/api/swagger>
+
+   â€¢ Gogs: <https://github.com/gogs/go-gogs-client/wiki>
+
+   â€¢ Bitbucket:
+     <https://developer.atlassian.com/bitbucket/api/2/reference>
+
+* Menu:
+
+* Making Requests::
+* Authentication::
+* Configuration Variables::
+
+\1f
+File: ghub.info,  Node: Making Requests,  Next: Authentication,  Up: API
+
+5.1 Making Requests
+===================
+
+ -- Function: ghub-request method resource &optional params &key query
+          payload headers unpaginate noerror reader username auth host
+          callback errorback url value error extra method*
+
+     This function makes a request for â€˜RESOURCE’ using â€˜METHOD’.
+     â€˜PARAMS’, â€˜QUERY’, â€˜PAYLOAD’ and/or â€˜HEADERS’ are alists holding
+     additional request data.  The response body is returned and the
+     response headers are stored in the variable
+     â€˜ghub-response-headers’.
+
+        â€¢ â€˜METHOD’ is the HTTP method, given as a string.
+
+        â€¢ â€˜RESOURCE’ is the resource to access, given as a string
+          beginning with a slash.
+
+        â€¢ â€˜PARAMS’, â€˜QUERY’, â€˜PAYLOAD’ and â€˜HEADERS’ are alists and are
+          used to specify request data.  All these arguments are alists
+          that resemble the JSON expected and returned by the Github
+          API.  The keys are symbols and the values stored in the â€˜cdr’
+          (not the â€˜cadr’) can be strings, integers, or lists of strings
+          and integers.
+
+          The Github API documentation is vague on how data has to be
+          transmitted and for a particular resource usually just talks
+          about "parameters".  Generally speaking when the â€˜METHOD’ is
+          "HEAD" or "GET", then they have to be transmitted as a query,
+          otherwise as a payload.
+
+             â€¢ Use â€˜PARAMS’ to automatically transmit like â€˜QUERY’ or
+               â€˜PAYLOAD’ would depending on â€˜METHOD’.
+
+             â€¢ Use â€˜QUERY’ to explicitly transmit data as a query.
+
+             â€¢ Use â€˜PAYLOAD’ to explicitly transmit data as a payload.
+               Instead of an alist, â€˜PAYLOAD’ may also be a string, in
+               which case it gets encoded as UTF-8 but is otherwise
+               transmitted as-is.
+
+             â€¢ Use â€˜HEADERS’ for those rare resources that require that
+               the data is transmitted as headers instead of as a query
+               or payload.  When that is the case, then the Github API
+               documentation usually mentions it explicitly.
+
+        â€¢ If â€˜SILENT’ is non-nil, then progress reports and the like are
+          not messaged.
+
+        â€¢ If â€˜UNPAGINATE’ is t, then this function make as many requests
+          as necessary to get all values.  If â€˜UNPAGINATE’ is a natural
+          number, then it gets at most that many pages.  For any other
+          non-nil value it raises an error.
+
+        â€¢ If â€˜NOERROR’ is non-nil, then no error is raised if the
+          request fails and â€˜nil’ is returned instead.  If â€˜NOERROR’ is
+          â€˜return’, then the error payload is returned instead of â€˜nil’.
+
+        â€¢ If â€˜READER’ is non-nil, then it is used to read and return
+          from the response buffer.  The default is
+          â€˜ghub--read-json-payload’.  For the very few resources that do
+          not return JSON, you might want to use â€˜ghub--decode-payload’.
+
+        â€¢ If â€˜USERNAME’ is non-nil, then the request is made on behalf
+          of that user.  It is better to specify the user using the Git
+          variable â€˜github.user’ for "api.github.com", or
+          â€˜github.HOST.user’ if connecting to a Github Enterprise
+          instance.
+
+        â€¢ Each package that uses Ghub should use its own token.  If
+          â€˜AUTH’ is â€˜nil’ or unspecified, then the generic â€˜ghub’ token
+          is used instead.  This is only acceptable for personal
+          utilities.  A packages that is distributed to other users
+          should always use this argument to identify itself, using a
+          symbol matching its name.
+
+          Package authors who find this inconvenient should write a
+          wrapper around this function and possibly for the
+          method-specific functions as well.
+
+          Beside â€˜nil’, some other symbols have a special meaning too.
+          â€˜none’ means to make an unauthorized request.  â€˜basic’ means
+          to make a password based request.  If the value is a string,
+          then it is assumed to be a valid token.  â€˜basic’ and an
+          explicit token string are only intended for internal and
+          debugging uses.
+
+          If â€˜AUTH’ is a package symbol, then the scopes are specified
+          using the variable â€˜AUTH-github-token-scopes’.  It is an error
+          if that is not specified.  See â€˜ghub-github-token-scopes’ for
+          an example.
+
+        â€¢ If â€˜HOST’ is non-nil, then connect to that Github instance.
+          This defaults to "api.github.com".  When a repository is
+          connected to a Github Enterprise instance, then it is better
+          to specify that using the Git variable â€˜github.host’ instead
+          of using this argument.
+
+        â€¢ If â€˜FORGE’ is â€˜gitlab’, then connect to Gitlab.com or,
+          depending on â€˜HOST’, to another Gitlab instance.  This is only
+          intended for internal use.  Instead of using this argument you
+          should use function â€˜glab-request’ and other â€˜glab-*’
+          functions.
+
+        â€¢ If â€˜CALLBACK’ and/or â€˜ERRORBACK’ is non-nil, then this
+          function makes one or more asynchronous requests and calls
+          â€˜CALLBACK’ or â€˜ERRORBACK’ when finished.  If no error
+          occurred, then it calls â€˜CALLBACK’, unless that is â€˜nil’.
+
+          If an error occurred, then it calls â€˜ERRORBACK’, or if that is
+          nil, then â€˜CALLBACK’.  â€˜ERRORBACK’ can also be â€˜t’, in which
+          case it signals instead.  â€˜NOERROR’ is ignored for all
+          asynchronous requests.
+
+          Both callbacks are called with four arguments.
+
+             â€¢ For â€˜CALLBACK’, the combined value of the retrieved
+               pages.  For â€˜ERRORBACK’, the error that occured when
+               retrieving the last page.
+
+             â€¢ The headers of the last page as an alist.
+
+             â€¢ Status information provided by â€˜url-retrieve’.  Its
+               â€˜:error’ property holds the same information as the first
+               argument to â€˜ERRORBACK’.
+
+             â€¢ A â€˜ghub--req’ struct, which can be passed to
+               â€˜ghub-continue’ (which see) to retrieve the next page, if
+               any.
+
+ -- Function: ghub-continue args
+
+     If there is a next page, then this function retrieves that.
+
+     This function is only intended to be called from callbacks.  If
+     there is a next page, then that is retrieved and the buffer that
+     the result will be loaded into is returned, or t if the process has
+     already completed.  If there is no next page, then return nil.
+
+     Callbacks are called with four arguments (see â€˜ghub-request’).  The
+     forth argument is a â€˜ghub--req’ struct, intended to be passed to
+     this function.  A callback may use the struct’s â€˜extra’ slot to
+     pass additional information to the callback that will be called
+     after the next request.  Use the function â€˜ghub-req-extra’ to get
+     and set the value of that slot.
+
+     As an example, using â€˜ghub-continue’ in a callback like so:
+
+          (ghub-get "/users/tarsius/repos" nil
+                    :callback (lambda (value _headers _status req)
+                                (unless (ghub-continue req)
+                                  (setq my-value value))))
+
+     is equivalent to:
+
+          (ghub-get "/users/tarsius/repos" nil
+                    :unpaginate t
+                    :callback (lambda (value _headers _status _req)
+                                (setq my-value value)))
+
+     To demonstrate how to pass information from one callback to the
+     next, here we record when we start fetching each page:
+
+          (ghub-get "/users/tarsius/repos" nil
+                    :extra (list (current-time))
+                    :callback (lambda (value _headers _status req)
+                                (push (current-time) (ghub-req-extra req))
+                                (unless (ghub-continue req)
+                                  (setq my-times (ghub-req-extra req))
+                                  (setq my-value value))))
+
+ -- Variable: ghub-response-headers
+
+     A select few Github API resources respond by transmitting data in
+     the response header instead of in the response body.  Because there
+     are so few of these inconsistencies, â€˜ghub-request’ always returns
+     the response body.
+
+     To access the response headers use this variable after
+     â€˜ghub-request’ has returned.
+
+ -- Function: ghub-response-link-relations req headers payload
+
+     This function returns an alist of the link relations in â€˜HEADERS’,
+     or if optional â€˜HEADERS’ is nil, then those in
+     â€˜ghub-response-headers’.
+
+     When accessing a Bitbucket instance then the link relations are in
+     â€˜PAYLOAD’ instead of â€˜HEADERS’, making their API merely RESTish and
+     forcing this function to append those relations to the value of
+     â€˜ghub-response-headers’, for later use when this function is called
+     with â€˜nil’ for â€˜PAYLOAD’.
+
+ -- Variable: ghub-override-system-name
+
+     If non-nil, the value of this variable is used to override the
+     value returned by â€˜system-name’ for the purpose of identifying the
+     local machine, which is necessary because Ghub uses separate tokens
+     for each machine.  Also see *note Configuration Variables::.
+
+ -- Variable: ghub-github-token-scopes
+ -- Variable: PACKAGE-github-token-scopes
+
+     Such a variable defines the token scopes requested by the
+     respective package â€˜PACKAGE’ given by the first word in the
+     variable name.  â€˜ghub’ itself is treated like any other package.
+     Also see *note Using Ghub in a Package::.
+
+ -- Function: ghub-head resource &optional params &key query payload
+          headers unpaginate noerror reader username auth host callback
+          errorback
+ -- Function: ghub-get resource &optional params &key query payload
+          headers unpaginate noerror reader username auth host callback
+          errorback
+
+     These functions are simple wrappers around â€˜ghub-request’.  Their
+     signature is identical to that of the latter, except that they do
+     not have an argument named â€˜METHOD’.  The HTTP method is instead
+     given by the second word in the function name.
+
+     As described in the documentation for â€˜ghub-request’, it depends on
+     the used method whether the value of the â€˜PARAMS’ argument is used
+     as the query or the payload.  For the "HEAD" and "GET" methods it
+     is used as the query.
+
+ -- Function: ghub-put resource &optional params &key query payload
+          headers unpaginate noerror reader username auth host callback
+          errorback
+ -- Function: ghub-post resource &optional params &key query payload
+          headers unpaginate noerror reader username auth host callback
+          errorback
+ -- Function: ghub-patch resource &optional params &key query payload
+          headers unpaginate noerror reader username auth host callback
+          errorback
+ -- Function: ghub-delete resource &optional params &key query payload
+          headers unpaginate noerror reader username auth host callback
+          errorback
+
+     These functions are simple wrappers around â€˜ghub-request’.  Their
+     signature is identical to that of the latter, except that they do
+     not have an argument named â€˜METHOD’.  The HTTP method is instead
+     given by the second word in the function name.
+
+     As described in the documentation for â€˜ghub-request’, it depends on
+     the used method whether the value of the â€˜PARAMS’ argument is used
+     as the query or the payload.  For the "PUT", "POST", "PATCH" and
+     "DELETE" methods it is used as the payload.
+
+ -- Function: ghub-wait resource &optional duration &key username auth
+          host
+
+     Some API requests result in an immediate successful response even
+     when the requested action has not actually been carried out yet.
+     An example is the request for the creation of a new repository,
+     which doesn’t cause the repository to immediately become available.
+     The Github API documentation usually mentions this when describing
+     an affected resource.
+
+     If you want to do something with some resource right after making a
+     request for its creation, then you might have to wait for it to
+     actually be created.  This function can be used to do so.  It
+     repeatedly tries to access the resource until it becomes available
+     or until the timeout exceeds.  In the latter case it signals
+     â€˜ghub-error’.
+
+     â€˜RESOURCE’ specifies the resource that this function waits for.
+
+     â€˜DURATION’ specifies the maximum number of seconds to wait for,
+     defaulting to 64 seconds.  Emacs will block during that time, but
+     the user can abort using â€˜C-g’.
+
+     The first attempt is made immediately and will often succeed.  If
+     not, then another attempt is made after two seconds, and each
+     subsequent attempt is made after waiting as long as we already
+     waited between all preceding attempts combined.
+
+     See â€˜ghub-request’’s documentation above for information about the
+     other arguments.
+
+ -- Function: ghub-graphql graphql &optional variables &key username
+          auth host callback
+
+     This function makes a GraphQL request using â€˜GRAPHQL’ and
+     â€˜VARIABLES’ as inputs.  â€˜GRAPHQL’ is a GraphQL string.  â€˜VARIABLES’
+     is a JSON-like alist.  The other arguments behave as for
+     â€˜ghub-request’ (which see).
+
+     The response is returned as a JSON-like alist.  Even if the
+     response contains â€˜errors’, this function does not raise an error.
+     Cursor-handling is likewise left to the caller.
+
+\1f
+File: ghub.info,  Node: Authentication,  Next: Configuration Variables,  Prev: Making Requests,  Up: API
+
+5.2 Authentication
+==================
+
+ -- Command: ghub-create-token
+
+     This command creates a new token using the values it reads from the
+     user and then stores it according to the variable â€˜auth-sources’.
+     It can also be called non-interactively, but you shouldn’t do that
+     yourself.
+
+     This is useful if you want to fully setup things before attempting
+     to make the initial request, if you want to provide fewer than the
+     requested scopes or customize â€˜auth-sources’ first, or if something
+     has gone wrong when using the wizard that is used when making a
+     request without doing this first.  (Note that instead of using this
+     command you can also just repeat the initial request after making
+     the desired adjustments â€” that is easier.)
+
+     This command reads, in order, the â€˜HOST’ (Github instance), the
+     â€˜USERNAME’, the â€˜PACKAGE’, and the â€˜SCOPES’ in the minibuffer,
+     providing reasonable default choices.  â€˜SCOPES’ defaults to the
+     scopes that â€˜PACKAGE’ requests using the variable
+     â€˜PACKAGE-github-token-scopes’.
+
+ -- Command: ghub-token-scopes
+
+     Users are free to give a token access to fewer scopes than what the
+     respective package requested.  That can, of course, lead to issues,
+     and package maintainers have to be able to quickly determine if
+     such a (mis-)configuration is the root cause when users report
+     issues.
+
+     This command reads the required values in the minibuffer and then
+     shows a message containing these values along with the scopes of
+     the respective token.  It also returns the scopes (only) when
+     called non-interactively.  Also see *note Using Ghub in a
+     Package::.
+
+\1f
+File: ghub.info,  Node: Configuration Variables,  Prev: Authentication,  Up: API
+
+5.3 Configuration Variables
+===========================
+
+The username and, unless you only use Github.com itself, the Github
+Enterprise instance have to be configured using Git variables.  In rare
+cases it might also be necessary to specify the identity of the local
+machine, which is done using a lisp variable.
+
+ -- Variable: github.user
+
+     The Github.com username.  This should be set globally and if you
+     have multiple Github.com user accounts, then you should set this
+     locally only for those repositories that you want to access using
+     the secondary identity.
+
+ -- Variable: github.HOST.user
+
+     This variable serves the same purpose as â€˜github.user’ but for the
+     Github Enterprise instance identified by â€˜HOST’.
+
+     The reason why separate variables are used is that this makes it
+     possible to set both values globally instead of having to set one
+     of the values locally in each and every repository that is
+     connected to the Github Enterprise instance, not Github.com.
+
+ -- Variable: github.host
+
+     This variable should only be set locally for a repository and
+     specifies the Github Enterprise edition that that repository is
+     connected to.  You should not set this globally because then each
+     and every repository becomes connected to the specified Github
+     Enterprise instance, including those that should actually be
+     connected to Github.com.
+
+     When this is undefined, then "api.github.com" is used (defined in
+     the constant â€˜ghub-default-host’, which you should never attempt to
+     change.)
+
+ -- Variable: ghub-override-system-name
+
+     Ghub uses a different token for each quadruple â€˜(USERNAME PACKAGE
+     HOST LOCAL-MACHINE)’.  Theoretically it could reuse tokens to some
+     extent but that would be more difficult to implement, less
+     flexible, and less secure (though slightly more convenient).
+
+     A token is identified on the respective Github instance (Github.com
+     or a Github Enterprise instance) using the pair â€˜(PACKAGE .
+     LOCAL-MACHINE)’, or more precisely the string "Emacs package
+     PACKAGE @ LOCAL-MACHINE". â€˜USERNAME’ and â€˜HOST’ do not have to be
+     encoded because the token is stored for â€˜USERNAME’ on â€˜HOST’ and
+     cannot be used by another user and/or on another instance.
+
+     There is one potential problem though; for any given â€˜(PACKAGE .
+     LOCAL-MACHINE)’ there can only be one token identified by "Emacs
+     package PACKAGE @ LOCAL-MACHINE"; Github does not allow multiple
+     tokens with the same description because it uses the description as
+     the identifier (it could use some hash instead, but alas it does
+     not).
+
+     If you have multiple machines and some of them have the same name,
+     then you should probably change that as this is not how things
+     ought to be.  However if you dual-boot, then it might make sense to
+     give that machine the same name regardless of what operating system
+     you have booted into.
+
+     You could use the same token on both operating systems, but setting
+     that up might be somewhat difficult because it is not possible to
+     download an existing token from Github.  You could, of course,
+     locally copy the token, but that is inconvenient and would make it
+     harder to only revoke the token used on your infected Windows
+     installation without also revoking it for your totally safe *BSD
+     installation.
+
+     Alternatively you can set this variable to a unique value, that
+     will then be used to identify the local machine instead of the
+     value returned by â€˜system-name’.
+
+\1f
+File: ghub.info,  Node: GraphQL Support,  Next: Support for Other Forges,  Prev: API,  Up: Top
+
+6 GraphQL Support
+*****************
+
+ -- Function: ghub-graphql graphql &optional variables &key username
+          auth host callback silent callback errorback value extra
+
+     This function makes a GraphQL request using â€˜GRAPHQL’ and
+     â€˜VARIABLES’ as inputs.  â€˜GRAPHQL’ is a GraphQL string.  â€˜VARIABLES’
+     is a JSON-like alist.  The other arguments behave as for
+     â€˜ghub-request’ (which see).
+
+     The response is returned as a JSON-like alist.  Even if the
+     response contains â€˜errors’, this function does not raise an error.
+     Cursor-handling is likewise left to the caller.
+
+   â€˜ghub-graphql’ is a thin convenience wrapper around â€˜ghub-request’,
+similar to â€˜ghub-post’ and friends.  While the latter only hard-code the
+value of the â€˜METHOD’ argument, the former also hard-codes â€˜RESOURCE’
+and constructs â€˜PAYLOAD’ from â€˜GRAPHEQL’ and â€˜VARIABLES’.  It also drops
+‘UNPAGINATE’, â€˜NOERROR’, â€˜READER’ (internal functions expect alist-ified
+JSON) and â€˜FORGE’ (only Github currently supports GraphQL).
+
+   â€˜ghub-graphql’ does not account for the fact that pagination works
+differently in GraphQL than it does in REST, so users of this function
+have to deal with that themselves.  Likewise error handling works
+differently and has to be done by the caller too.
+
+   An early attempt at implementing automatic unpaginating for GraphQL
+can be found in the â€˜faithful-graphql’ branch, provided I haven’t
+deleted that by now.  On that branch I try to do things as intended by
+the designers of GraphQL, using variables and fragments, and drowning in
+a sea of boilerplate.
+
+   The problem with that approach is that it only works for applications
+that fetch specific information on demand and actually want things to be
+paginated.  I am convinced that GraphQL is very nice for web apps.
+
+   However the Forge package for which I am implementing all of this has
+very different needs.  It wants to fetch "all the data" and "cache" it
+locally, so that it is available even when there is no internet
+connection.  GraphQL was designed around the idea that you should be
+able to "ask for what you need and get exactly that".  But when that
+boils down to "look, if I persist, then you are going to hand me over
+all the data anyway, so just caught it up already", then things start to
+fall apart.  If Github’s GraphQL allowed pagination to be turned off
+completely, then teaching â€˜ghub-graphql’ about error handling would be
+enough.
+
+   But it doesn’t and when doing things as intended, then that leads to
+huge amounts of repetitive boilerplate, which is so boring to write that
+doing it without introducing bugs left and right is near impossible; so
+I decided to give up on GraphQL variables, fragments and conditions, and
+instead implement something more powerful, though also more opinionated.
+
+ -- Function: ghub--graphql-vacuum query variables callback &optional
+          until &key narrow username auth host forge
+
+     This function is an opinionated alternative to â€˜ghub-graphql’.  It
+     relies and dark magic to get the job done.
+
+     It makes an initial request using â€˜QUERY’.  It then looks for
+     paginated edges in the returned data and makes more requests to
+     resolve them.  In order to do so it automatically transforms the
+     initial â€˜QUERY’ into another query suitable for that particular
+     edge.  The data retrieved by subsequent requests is then injected
+     into the data of the original request before that is returned or
+     passed to the callback.  If subsequently retrieved data features
+     new paginated edges, then those are followed recursively.
+
+     The end result is essentially the same as using â€˜ghub-graphql’, if
+     only it were possible to say "do not paginate anything".  The
+     implementation is much more complicated because it is not possible
+     to do that.
+
+     â€˜QUERY’ is a GraphQL query expressed as an s-expression.  The
+     â€˜graphql’ package is used to turn that into a GraphQL query string,
+     but the format is somewhat different than as documented for that
+     package.  Also only a subset of the GraphQL features are supported;
+     fragments for example are not, and magical stuff happens to
+     variables.  This is not documented yet, I am afraid.  Look at
+     existing callers.
+
+     â€˜VARIABLES’ is a JSON-like alist as for â€˜ghub-graphql’.
+
+     â€˜UNTIL’ is an alist â€˜((EDGE-until . VALUE)...)’.  When unpaginating
+     â€˜EDGE’ try not to fetch beyond the element whose first field has
+     the value â€˜VALUE’ and remove that element as well as all "lesser"
+     elements from the retrieved data if necessary.  Look at
+     â€˜forge--pull-repository’ for an example.  This is only useful if
+     you "cache" the response locally and want to avoid fetching data
+     again that you already have.
+
+     Other arguments behave as for â€˜ghub-graphql’ and â€˜ghub-request’,
+     more or less.
+
+   Using â€˜ghub--graphql-vacuum’, the following resource specific
+functions are implemented.  These functions are not part of the public
+API yet and are very much subject to change.
+
+ -- Function: ghub-fetch-repository owner name callback &optional until
+          &key username auth host forge
+
+     This function asynchronously fetches forge data about the specified
+     repository.  Once all data has been collected, â€˜CALLBACK’ is called
+     with the data as the only argument.
+
+ -- Function: ghub-fetch-issue owner name callback &optional until &key
+          username auth host forge
+
+     This function asynchronously fetches forge data about the specified
+     issue.  Once all data has been collected, â€˜CALLBACK’ is called with
+     the data as the only argument.
+
+ -- Function: ghub-fetch-pullreq owner name callback &optional until
+          &key username auth host forge
+
+     This function asynchronously fetches forge data about the specified
+     pull-request.  Once all data has been collected, â€˜CALLBACK’ is
+     called with the data as the only argument.
+
+   Note that in order to avoid duplication all of these functions base
+their initial query on the query stored in â€˜ghub-fetch-repository’.  The
+latter two pass that query through â€˜ghub--graphql-prepare-query’, which
+then used â€˜ghub--graphql-narrow-query’ to remove parts the caller is not
+interested in.  These two functions are also used internally, when
+unpaginating, but as demonstrated here they can be useful even before
+making an initial request.
+
+\1f
+File: ghub.info,  Node: Support for Other Forges,  Prev: GraphQL Support,  Up: Top
+
+7 Support for Other Forges
+**************************
+
+* Menu:
+
+* Forge Functions and Variables::
+* Forge Limitations and Notes::
+
+\1f
+File: ghub.info,  Node: Forge Functions and Variables,  Next: Forge Limitations and Notes,  Up: Support for Other Forges
+
+7.1 Forge Functions and Variables
+=================================
+
+Originally Ghub supported only Github but now it also supports Gitlab,
+Gitea, Gogs and Bitbucket.  The function â€˜ghub-request’ and all the
+‘ghub-METHOD’ convenience wrappers default to acting on a Github forge
+but can be told to act on another forge using their FORGE argument.
+
+   The FORGE argument only specifies what kind of forge to act on, not
+which instance.  The HOST argument can be used to select the instance.
+For some forges a default instance is defined:
+
+   â€¢ Forge â€˜github’ defaults to host â€˜api.github.com’.
+
+   â€¢ Forge â€˜gitlab’ defaults to host â€˜gitlab.com/api/v4’.
+
+   â€¢ Forge â€˜bitbucket’ defaults to host â€˜api.bitbucket.org/2.0’.
+
+   â€¢ No canonical host exists for the â€˜gitea’ and â€˜gogs’ forges and
+     â€˜localhost:3000/api/v1’ is used as the default host in both cases.
+
+   Together the FORGE and HOST arguments specify the forge type and
+instance.  In addition to that, it is also necessary to specify on whose
+behalf the request is being made, which can be done using the USERNAME
+and AUTH arguments.
+
+   Having to specify these arguments for every request is inconvenient.
+Additional variables and convenience functions can be used to make that
+unnecessary in most cases.
+
+   These variables can be set globally and/or for a specific repository
+as explained in *note Configuration Variables:: with a focus on Github
+instances.  To summarize:
+
+   â€¢ For <https://github.com> the Git variable â€˜github.user’ specifies
+     the user.
+
+   â€¢ For another â€˜github’ instance the Git variable â€˜github.HOST.user’
+     specifies the user.  The HOST in that variable name is the same as
+     the value of the HOST argument of the called function.
+
+   â€¢ Instead of specifying the HOST in every function call, the Git
+     variable â€˜github.host’ can be used.  This should only be set
+     locally.
+
+For â€˜gitlab’ and â€˜bitbucket’ forges similar variables are available:
+
+   â€¢ â€˜gitlab.user’ specifies the <https://gitlab.com> user.
+
+   â€¢ â€˜gitlab.HOST.user’ specifies the user for the HOST â€˜gitlab’
+     instance.
+
+   â€¢ â€˜gitlab.host’ specifies the â€˜gitlab’ host, unless the HOST argument
+     is non-nil
+
+   â€¢ â€˜bitbucket.user’ specifies the <https://bitbucket.org> user.
+
+   â€¢ â€˜bitbucket.HOST.user’ specifies the user for the HOST â€˜bitbucket’
+     instance.
+
+   â€¢ â€˜bitbucket.host’ specifies the â€˜bitbucket’ host, unless the HOST
+     argument is non-nil.
+
+   For â€˜gitea’ and â€˜gogs’ forges some similar variables are available,
+however for some of the â€˜ghub.*’ variables no equivalent variable exist
+for these two forges:
+
+   â€¢ â€˜gitea.user’ is *not* used because no canonical â€˜gitea’ instance
+     exists.
+
+   â€¢ â€˜gitea.HOST.user’ specifies the user for the HOST â€˜gitea’ instance.
+
+   â€¢ â€˜gitea.host’ specifies the â€˜gitea’ host, unless the HOST argument
+     is non-nil
+
+   â€¢ â€˜gogs.user’ is *not* used because no canonical â€˜gitea’ instance
+     exists.
+
+   â€¢ â€˜gogs.HOST.user’ specifies the user for the HOST â€˜gogs’ instance.
+
+   â€¢ â€˜gogs.host’ specifies the â€˜gogs’ host, unless the HOST argument is
+     non-nil
+
+   â€˜ghub-request’ and â€˜ghub-METHOD’ can be used to make a request for
+any of the supported forge types, but except when making a request for a
+‘github’ instance, then that requires the use of the FORGE argument.
+
+   To avoid that, functions named â€˜FORGE-request’ and â€˜FORGE-METHOD’ are
+also available.  The following forms are equivalent, for example:
+
+     (ghub-get ... :auth 'PACKAGE :forge 'gitlab)
+     (glab-get ... :auth 'PACKAGE)
+
+   These forms would remain equivalent even if you did not specify a
+value for the AUTH arguments â€” but you should not do that if you plan to
+share your code with others (see *note Using Ghub in a Package::).  If
+you do omit AUTH, then the request is made on behalf of the â€˜ghub’
+package, *regardless* of the symbol prefix of the function you use to do
+so.
+
+   All â€˜FORGE-request’ and â€˜FORGE-METHOD’ functions, including but not
+limited to â€˜ghub-METHOD’, are very simple wrappers around
+‘ghub-request’.  They take fewer arguments than â€˜ghub-request’ and
+instead pass constant values for the arguments METHOD and/or FORGE.
+
+\1f
+File: ghub.info,  Node: Forge Limitations and Notes,  Prev: Forge Functions and Variables,  Up: Support for Other Forges
+
+7.2 Forge Limitations and Notes
+===============================
+
+   â€¢ The token creation wizard is only available for â€˜github’ forges,
+     because all other forges do not support using the API to create an
+     API token.  As a consequence, if the user makes a request and the
+     necessary token cannot be found, then that results in an error.
+     Tokens can be created at:
+
+        â€¢ Gitlab: <https://gitlab.com/profile/personal_access_tokens>
+
+        â€¢ Bitbucket:
+          <https://bitbucket.org/account/user/tarsius/app-passwords>
+
+        â€¢ Gitea: <https://localhost:3000/user/settings/applications>
+
+        â€¢ Gogs: <https://localhost:3000/user/settings/applications>
+
+     Also see *note Manually Creating and Storing a Token:: and *note
+     How Ghub uses Auth-Source::.
+
+   â€¢ As mentioned in the previous node, the variables â€˜gitea.host’ and
+     â€˜gogs.host’ are not taken into account.
+
+   â€¢ Gitea and Gogs do not support limiting a token to certain scopes.
+
+   â€¢ The Bitbucket API is fairly broken.  Some resources only work if a
+     slash is appended while others only work if no slash is appended.
+     I am unable to access any private repositories and some resources
+     don’t work for me at all.  Also the API is only RESTish; pagination
+     information is part of the response body instead of the header.
+     Due to such issues it is possible that I will eventually have to
+     remove support for Bitbucket altogether.
+
+   â€¢ The Gitlab API documentation is not always accurate, though I don’t
+     have an example at hand.  It also isn’t structured well, making it
+     occationally difficult to find the information one is looking for.
+
+   â€¢ Where one would use â€˜user/repo’ when accessing another forge, one
+     has to use â€˜user%2Frepo’ when accessing Gitlab, e.g.:
+
+          (glab-get "/projects/python-mode-devs%2Fpython-mode")
+
+
+\1f
+Tag Table:
+Node: Top\7f764
+Node: Introduction\7f3280
+Node: Getting Started\7f6322
+Node: Setting the Username\7f10250
+Node: Interactively Creating and Storing a Token\7f11675
+Node: Manually Creating and Storing a Token\7f17326
+Node: How Ghub uses Auth-Source\7f18551
+Node: Using Ghub in Personal Scripts\7f20484
+Node: Using Ghub in a Package\7f21940
+Node: API\7f24558
+Node: Making Requests\7f25355
+Node: Authentication\7f39454
+Node: Configuration Variables\7f41299
+Node: GraphQL Support\7f45019
+Node: Support for Other Forges\7f51684
+Node: Forge Functions and Variables\7f51901
+Node: Forge Limitations and Notes\7f56420
+\1f
+End Tag Table
+
+\1f
+Local Variables:
+coding: utf-8
+End:
diff --git a/elpa/ghub-20191007.1420/glab.el b/elpa/ghub-20191007.1420/glab.el
new file mode 100644 (file)
index 0000000..8aec40e
--- /dev/null
@@ -0,0 +1,155 @@
+;;; glab.el --- minuscule client library for the Gitlab API  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2016-2019  Jonas Bernoulli
+
+;; Author: Jonas Bernoulli <jonasNOSPAMbernoul.li>
+;; Homepage: https://github.com/magit/ghub
+;; Keywords: tools
+
+;; This file is not part of GNU Emacs.
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; For a copy of the GPL see https://www.gnu.org/licenses/gpl.txt.
+
+;;; Commentary:
+
+;; Glab is a library that provides basic support for using the Gitlab API
+;; from Emacs packages.  It abstracts access to API resources using only
+;; a handful of functions that are not resource-specific.
+
+;; This library is implemented on top of Ghub.  Unlike Ghub, Glab does
+;; not support the guided creation of tokens because Gitlab lacks the
+;; features that would be necessary to implement that.  Users have to
+;; create tokens through the web interface.
+
+;;; Code:
+
+(require 'ghub)
+
+(defconst glab-default-host "gitlab.com/api/v4"
+  "The default host that is used if `glab.host' is not set.")
+
+(cl-defun glab-head (resource &optional params
+                              &key query payload headers
+                              silent unpaginate noerror reader
+                              username auth host
+                              callback errorback extra)
+  "Make a `HEAD' request for RESOURCE, with optional query PARAMS.
+Like calling `ghub-request' (which see) with \"HEAD\" as METHOD
+and `gitlab' as FORGE."
+  (ghub-request "HEAD" resource params :forge 'gitlab
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun glab-get (resource &optional params
+                             &key query payload headers
+                             silent unpaginate noerror reader
+                             username auth host
+                             callback errorback extra)
+  "Make a `GET' request for RESOURCE, with optional query PARAMS.
+Like calling `ghub-request' (which see) with \"GET\" as METHOD
+and `gitlab' as FORGE."
+  (ghub-request "GET" resource params :forge 'gitlab
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun glab-put (resource &optional params
+                             &key query payload headers
+                             silent unpaginate noerror reader
+                             username auth host
+                             callback errorback extra)
+  "Make a `PUT' request for RESOURCE, with optional payload PARAMS.
+Like calling `ghub-request' (which see) with \"PUT\" as METHOD
+and `gitlab' as FORGE."
+  (ghub-request "PUT" resource params :forge 'gitlab
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun glab-post (resource &optional params
+                              &key query payload headers
+                              silent unpaginate noerror reader
+                              username auth host
+                              callback errorback extra)
+  "Make a `POST' request for RESOURCE, with optional payload PARAMS.
+Like calling `ghub-request' (which see) with \"POST\" as METHOD
+and `gitlab' as FORGE."
+  (ghub-request "POST" resource params :forge 'gitlab
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun glab-patch (resource &optional params
+                               &key query payload headers
+                               silent unpaginate noerror reader
+                               username auth host
+                               callback errorback extra)
+  "Make a `PATCH' request for RESOURCE, with optional payload PARAMS.
+Like calling `ghub-request' (which see) with \"PATCH\" as METHOD
+and `gitlab' as FORGE."
+  (ghub-request "PATCH" resource params :forge 'gitlab
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun glab-delete (resource &optional params
+                                &key query payload headers
+                                silent unpaginate noerror reader
+                                username auth host
+                                callback errorback extra)
+  "Make a `DELETE' request for RESOURCE, with optional payload PARAMS.
+Like calling `ghub-request' (which see) with \"DELETE\" as METHOD
+and `gitlab' as FORGE."
+  (ghub-request "DELETE" resource params :forge 'gitlab
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun glab-request (method resource &optional params
+                               &key query payload headers
+                               silent unpaginate noerror reader
+                               username auth host
+                               callback errorback extra)
+  "Make a request for RESOURCE and return the response body.
+Like calling `ghub-request' (which see) with `gitlab' as FORGE."
+  (ghub-request method resource params :forge 'gitlab
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun glab-repository-id (owner name &key username auth host)
+  "Return the id of the repository specified by OWNER, NAME and HOST."
+  (number-to-string
+   (cdr (assq 'id (glab-get (format "/projects/%s%%2F%s"
+                                    (replace-regexp-in-string "/" "%2F" owner)
+                                    name)
+                            nil :username username :auth auth :host host)))))
+
+;;; _
+(provide 'glab)
+;;; glab.el ends here
diff --git a/elpa/ghub-20191007.1420/gogs.el b/elpa/ghub-20191007.1420/gogs.el
new file mode 100644 (file)
index 0000000..7ce7fcd
--- /dev/null
@@ -0,0 +1,140 @@
+;;; gogs.el --- minuscule client library for the Gogs API  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2016-2019  Jonas Bernoulli
+
+;; Author: Jonas Bernoulli <jonasNOSPAMbernoul.li>
+;; Homepage: https://github.com/magit/ghub
+;; Keywords: tools
+
+;; This file is not part of GNU Emacs.
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; For a copy of the GPL see https://www.gnu.org/licenses/gpl.txt.
+
+;;; Commentary:
+
+;; Gogs is a library that provides basic support for using the Gogs API
+;; from Emacs packages.  It abstracts access to API resources using only
+;; a handful of functions that are not resource-specific.
+
+;; This library is implemented on top of Ghub.  Unlike Ghub, Gogs does
+;; not support the guided creation of tokens because Gogs lacks the
+;; features that would be necessary to implement that.  Users have to
+;; create tokens through the web interface.
+
+;;; Code:
+
+(require 'ghub)
+
+(defconst gogs-default-host "localhost:3000/api/v1"
+  "The default Gogs host.")
+
+;; HEAD does not appear to be supported.
+
+(cl-defun gogs-get (resource &optional params
+                             &key query payload headers
+                             silent unpaginate noerror reader
+                             username auth host
+                             callback errorback extra)
+  "Make a `GET' request for RESOURCE, with optional query PARAMS.
+Like calling `ghub-request' (which see) with \"GET\" as METHOD
+and `gogs' as FORGE."
+  (ghub-request "GET" resource params :forge 'gogs
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun gogs-put (resource &optional params
+                             &key query payload headers
+                             silent unpaginate noerror reader
+                             username auth host
+                             callback errorback extra)
+  "Make a `PUT' request for RESOURCE, with optional payload PARAMS.
+Like calling `ghub-request' (which see) with \"PUT\" as METHOD
+and `gogs' as FORGE."
+  (ghub-request "PUT" resource params :forge 'gogs
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun gogs-post (resource &optional params
+                              &key query payload headers
+                              silent unpaginate noerror reader
+                              username auth host
+                              callback errorback extra)
+  "Make a `POST' request for RESOURCE, with optional payload PARAMS.
+Like calling `ghub-request' (which see) with \"POST\" as METHOD
+and `gogs' as FORGE."
+  (ghub-request "POST" resource params :forge 'gogs
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun gogs-patch (resource &optional params
+                               &key query payload headers
+                               silent unpaginate noerror reader
+                               username auth host
+                               callback errorback extra)
+  "Make a `PATCH' request for RESOURCE, with optional payload PARAMS.
+Like calling `ghub-request' (which see) with \"PATCH\" as METHOD
+and `gogs' as FORGE."
+  (ghub-request "PATCH" resource params :forge 'gogs
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun gogs-delete (resource &optional params
+                                &key query payload headers
+                                silent unpaginate noerror reader
+                                username auth host
+                                callback errorback extra)
+  "Make a `DELETE' request for RESOURCE, with optional payload PARAMS.
+Like calling `ghub-request' (which see) with \"DELETE\" as METHOD
+and `gogs' as FORGE."
+  (ghub-request "DELETE" resource params :forge 'gogs
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun gogs-request (method resource &optional params
+                               &key query payload headers
+                               silent unpaginate noerror reader
+                               username auth host
+                               callback errorback extra)
+  "Make a request for RESOURCE and return the response body.
+Like calling `ghub-request' (which see) with `gogs' as FORGE."
+  (ghub-request method resource params :forge 'gogs
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun gogs-repository-id (owner name &key username auth host)
+  "Return the id of the repository specified by OWNER, NAME and HOST."
+  (number-to-string
+   (cdr (assq 'id (gogs-get (format "/repos/%s/%s" owner name)
+                            nil :username username :auth auth :host host)))))
+
+;;; _
+(provide 'gogs)
+;;; gogs.el ends here
diff --git a/elpa/ghub-20191007.1420/gsexp.el b/elpa/ghub-20191007.1420/gsexp.el
new file mode 100644 (file)
index 0000000..ced9dcf
--- /dev/null
@@ -0,0 +1,94 @@
+;;; gsexp.el --- GraphQl as S-expressions  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2016-2019  Jonas Bernoulli
+
+;; Author: Jonas Bernoulli <jonasNOSPAMbernoul.li>
+;; Homepage: https://github.com/magit/ghub
+;; Keywords: tools
+
+;; This file is not part of GNU Emacs.
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; For a copy of the GPL see https://www.gnu.org/licenses/gpl.txt.
+
+;;; Commentary:
+
+;; This library encodes S-expressions as GraphQl documents.  Currently
+;; it is rather incomplete and only intended for use by `ghub-graphql'
+;; but I might fill the gaps and add documentation eventually.  I am
+;; not in a hurry though.
+
+;;; Code:
+
+(require 'cl-lib)
+
+(defun gsexp-encode (document)
+  (gsexp--pp (gsexp--encode-field document)))
+
+(defun gsexp--encode-field (field)
+  (cond
+   ((stringp field)
+    field)
+   ((symbolp field)
+    (symbol-name field))
+   ((listp (car field))
+    (concat (format "%s: " (caar field))
+            (gsexp--encode-field (cons (cadar field)
+                                       (cdr field)))))
+   (t
+    (concat (symbol-name (pop field))
+            (and (vectorp (car field))
+                 (format " (\n%s)"
+                         (mapconcat #'gsexp--encode-argument
+                                    (append (pop field) nil)
+                                    ",\n")))
+            (and field
+                 (format " {\n%s\n}"
+                         (mapconcat #'gsexp--encode-field field "\n")))))))
+
+(cl-defun gsexp--encode-argument ((argument value))
+  (format "%s: %s" argument (gsexp--encode-value value)))
+
+(defun gsexp--encode-value (value)
+  (cond
+   ((numberp value)
+    (number-to-string value))
+   ((symbolp value) ; including variables, enums, booleans and null
+    (symbol-name value))
+   ((stringp value)
+    (prin1-to-string value))
+   ((vectorp value)
+    (format "(%s)" (mapconcat #'gsexp--encode-value value "")))
+   ((listp value)
+    (format "{%s}" (mapconcat
+                    (pcase-lambda (`(,name ,value))
+                      (format "%s: %s" name (gsexp--encode-value value)))
+                    value ", ")))
+   (t (error "Invalid field value: %S" value))))
+
+(defun gsexp--pp (string)
+  (with-temp-buffer
+    (save-excursion
+      (insert string))
+    (while (< (point) (point-max))
+      (unless (and (bolp) (eolp))
+        (save-excursion
+          (let ((level (car (syntax-ppss (point-at-bol)))))
+            (when (looking-at "\\s-*\\s)")
+              (cl-decf level))
+            (indent-line-to (* 2 level)))))
+      (forward-line 1))
+    (buffer-string)))
+
+;;; _
+(provide 'gsexp)
+;;; gsexp.el ends here
diff --git a/elpa/ghub-20191007.1420/gtea.el b/elpa/ghub-20191007.1420/gtea.el
new file mode 100644 (file)
index 0000000..81223bd
--- /dev/null
@@ -0,0 +1,140 @@
+;;; gtea.el --- minuscule client library for the Gitea API  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2016-2019  Jonas Bernoulli
+
+;; Author: Jonas Bernoulli <jonasNOSPAMbernoul.li>
+;; Homepage: https://github.com/magit/ghub
+;; Keywords: tools
+
+;; This file is not part of GNU Emacs.
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; For a copy of the GPL see https://www.gnu.org/licenses/gpl.txt.
+
+;;; Commentary:
+
+;; Gtea is a library that provides basic support for using the Gitea API
+;; from Emacs packages.  It abstracts access to API resources using only
+;; a handful of functions that are not resource-specific.
+
+;; This library is implemented on top of Ghub.  Unlike Ghub, Gtea does
+;; not support the guided creation of tokens because Gitea lacks the
+;; features that would be necessary to implement that.  Users have to
+;; create tokens through the web interface.
+
+;;; Code:
+
+(require 'ghub)
+
+(defconst gtea-default-host "localhost:3000/api/v1"
+  "The default Gitea host.")
+
+;; HEAD does not appear to be supported.
+
+(cl-defun gtea-get (resource &optional params
+                             &key query payload headers
+                             silent unpaginate noerror reader
+                             username auth host
+                             callback errorback extra)
+  "Make a `GET' request for RESOURCE, with optional query PARAMS.
+Like calling `ghub-request' (which see) with \"GET\" as METHOD
+and `gitea' as FORGE."
+  (ghub-request "GET" resource params :forge 'gitea
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun gtea-put (resource &optional params
+                             &key query payload headers
+                             silent unpaginate noerror reader
+                             username auth host
+                             callback errorback extra)
+  "Make a `PUT' request for RESOURCE, with optional payload PARAMS.
+Like calling `ghub-request' (which see) with \"PUT\" as METHOD
+and `gitea' as FORGE."
+  (ghub-request "PUT" resource params :forge 'gitea
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun gtea-post (resource &optional params
+                              &key query payload headers
+                              silent unpaginate noerror reader
+                              username auth host
+                              callback errorback extra)
+  "Make a `POST' request for RESOURCE, with optional payload PARAMS.
+Like calling `ghub-request' (which see) with \"POST\" as METHOD
+and `gitea' as FORGE."
+  (ghub-request "POST" resource params :forge 'gitea
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun gtea-patch (resource &optional params
+                               &key query payload headers
+                               silent unpaginate noerror reader
+                               username auth host
+                               callback errorback extra)
+  "Make a `PATCH' request for RESOURCE, with optional payload PARAMS.
+Like calling `ghub-request' (which see) with \"PATCH\" as METHOD
+and `gitea' as FORGE."
+  (ghub-request "PATCH" resource params :forge 'gitea
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun gtea-delete (resource &optional params
+                                &key query payload headers
+                                silent unpaginate noerror reader
+                                username auth host
+                                callback errorback extra)
+  "Make a `DELETE' request for RESOURCE, with optional payload PARAMS.
+Like calling `ghub-request' (which see) with \"DELETE\" as METHOD
+and `gitea' as FORGE."
+  (ghub-request "DELETE" resource params :forge 'gitea
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun gtea-request (method resource &optional params
+                               &key query payload headers
+                               silent unpaginate noerror reader
+                               username auth host
+                               callback errorback extra)
+  "Make a request for RESOURCE and return the response body.
+Like calling `ghub-request' (which see) with `gitea' as FORGE."
+  (ghub-request method resource params :forge 'gitea
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun gtea-repository-id (owner name &key username auth host)
+  "Return the id of the repository specified by OWNER, NAME and HOST."
+  (number-to-string
+   (cdr (assq 'id (gtea-get (format "/repos/%s/%s" owner name)
+                            nil :username username :auth auth :host host)))))
+
+;;; _
+(provide 'gtea)
+;;; gtea.el ends here