mirror of https://github.com/Chizi123/.emacs.d.git

Chizi123
2018-11-18 21067e7cbe6d7a0f65ff5c317a96b5c337b0b3d8
commit | author | age
5cb5f7 1 This is ghub.info, produced by makeinfo version 6.5 from ghub.texi.
C 2
3      Copyright (C) 2017-2018 Jonas Bernoulli <jonas@bernoul.li>
4
5      You can redistribute this document and/or modify it under the terms
6      of the GNU General Public License as published by the Free Software
7      Foundation, either version 3 of the License, or (at your option)
8      any later version.
9
10      This document is distributed in the hope that it will be useful,
11      but WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15 INFO-DIR-SECTION Emacs
16 START-INFO-DIR-ENTRY
17 * Ghub: (ghub).         Minuscule client library for the Github API.
18 END-INFO-DIR-ENTRY
19
20 
21 File: ghub.info,  Node: Top,  Next: Introduction,  Up: (dir)
22
23 Ghub User and Developer Manual
24 ******************************
25
26 Ghub provides basic support for using the APIs of various Git forges
27 from Emacs packages.  Originally it only supported the Github REST API,
28 but now it also supports the Github GraphQL API as well as the REST APIs
29 of Gitlab, Gitea, Gogs and Bitbucket.
30
31    Ghub abstracts access to API resources using only a handful of basic
32 functions such as ‘ghub-get‘.  These are convenience wrappers around
33 ‘ghub-request‘.  Additional forge-specific wrappers like ‘glab-put‘,
34 ‘gtea-put‘, ‘gogs-post‘ and ‘buck-delete‘ are also available.  Ghub does
35 not provide any resource-specific functions, with the exception of
36 ‘FORGE-repository-id‘.
37
38    When accessing Github, then Ghub handles the creation and storage of
39 access tokens using a setup wizard to make it easier for users to get
40 started.  The tokens for other forges have to be created manually.
41
42    Ghub is intentionally limited to only provide these two essential
43 features — basic request functions and guided setup — to avoid being too
44 opinionated, which would hinder wide adoption.  It is assumed that wide
45 adoption would make life easier for users and maintainers alike, because
46 then all packages that talk to forge APIs could be configured the same
47 way.
48
49 This manual is for Ghub version 3.0.0 (v3.0.0-5-g86a17df+1).
50
51      Copyright (C) 2017-2018 Jonas Bernoulli <jonas@bernoul.li>
52
53      You can redistribute this document and/or modify it under the terms
54      of the GNU General Public License as published by the Free Software
55      Foundation, either version 3 of the License, or (at your option)
56      any later version.
57
58      This document is distributed in the hope that it will be useful,
59      but WITHOUT ANY WARRANTY; without even the implied warranty of
60      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
61      General Public License for more details.
62
63 * Menu:
64
65 * Introduction::
66 * Getting Started::
67 * Using Ghub in Personal Scripts::
68 * Using Ghub in a Package::
69 * API::
70 * GraphQL Support::
71 * Support for Other Forges::
72
73 — The Detailed Node Listing —
74
75 Getting Started
76
77 * Setting the Username::
78 * Interactively Creating and Storing a Token::
79 * Manually Creating and Storing a Token::
80 * How Ghub uses Auth-Source::
81
82 API
83
84 * Making Requests::
85 * Authentication::
86 * Configuration Variables::
87
88 Support for Other Forges
89
90 * Forge Functions and Variables::
91 * Forge Limitations and Notes::
92
93
94 
95 File: ghub.info,  Node: Introduction,  Next: Getting Started,  Prev: Top,  Up: Top
96
97 1 Introduction
98 **************
99
100 Ghub provides basic support for using the APIs of various Git forges
101 from Emacs packages.  Originally it only supported the Github REST API,
102 but now it also supports the Github GraphQL API as well as the REST APIs
103 of Gitlab, Gitea, Gogs and Bitbucket.
104
105    Ghub abstracts access to API resources using only a handful of basic
106 functions such as ‘ghub-get‘.  These are convenience wrappers around
107 ‘ghub-request‘.  Additional forge-specific wrappers like ‘glab-put‘,
108 ‘gtea-put‘, ‘gogs-post‘ and ‘buck-delete‘ are also available.  Ghub does
109 not provide any resource-specific functions, with the exception of
110 ‘FORGE-repository-id‘.
111
112    When accessing Github, then Ghub handles the creation and storage of
113 access tokens using a setup wizard to make it easier for users to get
114 started.  The tokens for other forges have to be created manually.
115
116    Ghub is intentionally limited to only provide these two essential
117 features — basic request functions and guided setup — to avoid being too
118 opinionated, which would hinder wide adoption.  It is assumed that wide
119 adoption would make life easier for users and maintainers alike, because
120 then all packages that talk to forge APIs could be configured the same
121 way.
122
123    Fancier interfaces can be implemented on top of Ghub, and one such
124 wrapper — named simply Ghub+ — has already been implemented.  The
125 benefit of basing various opinionated interfaces on top of a single
126 library that provides only the core functionality is that choosing the
127 programming interface no longer dictates how access tokens are handled.
128 Users can then use multiple packages that access the Github API without
129 having to learn the various incompatible ways packages expect the
130 appropriate token to be made available to them.
131
132    Ghub uses the built-in ‘auth-source’ library to store access tokens.
133 That library is very flexible and supports multiple backends, which
134 means that it is up to the user how secrets are stored.  They can, among
135 other things, choose between storing secrets in plain text for ease of
136 use, or encrypted for better security.
137
138    Previously (as in until this library is widely adopted) it was up to
139 package authors to decide if things should be easy or secure.  (Note
140 that ‘auth-source’ defaults to "easy" — you have been warned.)
141
142    Ghub expects package authors to use a dedicated access token instead
143 of sharing a single token between all packages that rely on it.  That
144 means that users cannot configure Ghub once and later start using a new
145 package without any additional setup.  But Ghub helps with that.
146
147    When the user invokes some command that ultimately results in
148 ‘ghub-request’ being called and the appropriate token is not available
149 yet, then the user is guided through the process of creating and storing
150 a new token, and at the end of that process the request is carried out
151 as if the token had been available to begin with.
152
153 
154 File: ghub.info,  Node: Getting Started,  Next: Using Ghub in Personal Scripts,  Prev: Introduction,  Up: Top
155
156 2 Getting Started
157 *****************
158
159 Each package that uses Ghub uses its own token.  Despite that, chances
160 are good that after successfully configuring one package you can just
161 start using another package pretty much instantly.
162
163    If the necessary token to access a Github instance is not available
164 when a package makes an API request, then a setup wizard pops up, and
165 after answering a few questions you are good to go.  Even the request
166 that caused the wizard to be summoned should succeed and for most users
167 this should be true even when configuring the very first token.
168
169    However, in some situations some manual configuration is necessary
170 *before* using the wizard, or the wizard cannot be used at all:
171
172    • If you don’t want to use the wizard then you don’t have to and can
173      create tokens manually as described in *note Manually Creating and
174      Storing a Token::.
175
176    • Unfortunately only Github supports the creation of tokens by using
177      the API.  If you want to access another forge, then you have to
178      create the token manually as describe in *note Manually Creating
179      and Storing a Token::.  Also see *note Support for Other Forges::.
180
181    • If you want to access a Github Enterprise instance, then you have
182      to tell Ghub about that before the wizard makes its appearance by
183      setting the Git variable ‘github.host’.  You also have to tell Ghub
184      your username for that instance using the variable
185      ‘github.HOST.user’ even if it is the same as on Github.com.
186
187      These variables are documented in *note Configuration Variables::.
188      Also see *note Setting the Username::.  TL;DR: If your Github
189      Enterprise instance is hosted at ‘git.example.com’ and your
190      username on that instance is ‘jtribbiani’, then set ‘github.host’
191      to ‘git.example.com/api/v3’ in every repository cloned from that
192      instance (i.e.  _do not_ set it globally) and _globally_ set
193      ‘github.git.example.com/api/v3.user’ to ‘jtribbiani’.  The latter
194      is necessary even if your username on Github.com is the same.
195
196    • If the variable ‘github.user’ (or ‘github.HOST.user’ for an
197      Enterprise instance) is unset when the wizard is first summoned,
198      then you are asked to provide your username.  That value is then
199      stored *globally* to avoid having to ask you that question once per
200      repository.  If you have multiple accounts on Github.com (or a
201      Github Enterprise instance), then you have to explicitly tell Ghub
202      about that.  This can be done by setting the repository-local
203      values of the appropriate variable *before* the wizard is invoked.
204
205    • You might forget to do the above, which is why it is important to
206      carefully read the output of the wizard.  If it turns out that you
207      forgot to set a variable, then you must abort, set the variable,
208      and repeat the request to trigger the wizard again.
209
210    • The setup wizard should work even if you have enabled two-factor
211      authentication.  However if your Github Enterprise instance
212      enforces Single Sign-On as an additional security measure, then you
213      are out of luck and have to create the token manually as described
214      in *note Manually Creating and Storing a Token::.
215
216    The variables mentioned above — and others — are documented in *note
217 Configuration Variables:: and the setup wizard is documented in *note
218 Interactively Creating and Storing a Token::.
219
220 * Menu:
221
222 * Setting the Username::
223 * Interactively Creating and Storing a Token::
224 * Manually Creating and Storing a Token::
225 * How Ghub uses Auth-Source::
226
227 
228 File: ghub.info,  Node: Setting the Username,  Next: Interactively Creating and Storing a Token,  Up: Getting Started
229
230 2.1 Setting the Username
231 ========================
232
233 If you haven’t set the Git variable ‘github.user’ yet when making a
234 request, then you will be asked:
235
236      Git variable `github.user' is unset.  Set to:
237
238    You are expected to provide your Github username here.  The provided
239 value will be saved globally (using ‘git config --global github.user
240 USERNAME’).
241
242    If you need to identify as another user in a particular repository,
243 then you have to set that variable locally, *before* making a request:
244
245      cd /path/to/repo
246      git config github.user USERNAME
247
248    For Github Enterprise instances you have to specify where the API can
249 be accessed *before* you try to access it and a different variable has
250 to be used to set the username.  For example if the API is available at
251 ‘https://example.com/api/v3’, then you should do this:
252
253      # Do this once
254      git config --global github.example.com/api/v3.user EMPLOYEE
255
256      # Do this for every corporate repository
257      cd /path/to/repo
258      git config github.host example.com/api/v3
259
260    If you do not set ‘github.example.com/api/v3.user’, then you will be
261 asked to provide the value when trying to make a request, but you do
262 have to manually set ‘github.host’, or Ghub assumes that you are trying
263 to access ‘api.github.com’.
264
265 
266 File: ghub.info,  Node: Interactively Creating and Storing a Token,  Next: Manually Creating and Storing a Token,  Prev: Setting the Username,  Up: Getting Started
267
268 2.2 Interactively Creating and Storing a Token
269 ==============================================
270
271 Ghub uses a different token for every package as well as for every
272 machine from which you access the Github API (and obviously also for
273 every Github instance and user).  This allows packages to only request
274 the scopes that they actually need and also gives users the opportunity
275 to refuse access to certain scopes if they expect to not use the
276 features that need them.
277
278    Usually you don’t have to worry about creating and storing a token
279 yourself and can just make a request.  Note however that you don’t have
280 to use the setup wizard described below.  Alternatively you can perform
281 the setup manually as described in the next section.
282
283    If you make a request and the required token is not available yet,
284 then the setup wizard will first ask you something like this:
285
286      Such a Github API token is not available:
287
288        Host:    api.github.com
289        User:    USERNAME
290        Package: PACKAGE
291
292        Scopes requested in `PACKAGE-github-token-scopes':
293          repo
294        Store on Github as:
295          "Emacs package PACKAGE @ LOCAL-MACHINE"
296        Store locally according to option `auth-sources':
297          ("~/.authinfo" "~/.authinfo.gpg" "~/.netrc")
298
299      If in doubt, then abort and first view the section of
300      the Ghub documentation called "Interactively Creating
301      and Storing a Token".
302
303      Create and store such a token? (yes or no)
304
305    If you don’t have any doubts, then answer "yes".  Lets address some
306 of the doubts that you might have:
307
308    • ‘Host’ usually is "api.github.com" and that is usually what you
309      want.  If you are trying to access a Github Enterprise instance,
310      then it should be something else and you have to set the value
311      manually before the setup wizard is summoned, as described in the
312      parent section.
313
314    • ‘User’ should be your Github.com (or Github Enterprise instance)
315      username.  If it is something else and it doesn’t look like a
316      simple typo, then you should read the parent section again.  In
317      either case you have to abort.
318
319    • ‘Package’ should be the name of the package you are using to access
320      the Github API.
321
322      If it is ‘ghub’, then the package author disregarded that
323      convention and you should probably report a bug in the issue
324      tracker of that package.
325
326      Or you yourself are using ‘ghub-request’ or one of its wrappers
327      directly, in which case this is expected and perfectly fine.  In
328      that case you might however want to abort and change the value of
329      the variable ‘ghub-github-token-scopes’ before triggering the
330      wizard again.
331
332    • Each ‘PACKAGE’ has to specify the tokens that it needs using a
333      variable named ‘PACKAGE-github-token-scopes’.  The doc-string of
334      that variable should document why the various scopes are needed.
335
336      The meaning of the various scopes are documented at
337      <https://magit.vc/goto/f63aeb0a>.
338
339    • The value of ‘auth-sources’ is shown.  The default value causes
340      secrets to be stored in plain text.  Because this might be
341      unexpected, Ghub additionally displays a warning when appropriate.
342
343           WARNING: The token will be stored unencrypted in "~/.authinfo".
344                    If you don't want that, you have to abort and customize
345                    the `auth-sources' option.
346
347      Whether that is something that needs fixing, is up to you.  If your
348      answer is yes, then you should abort and see *note How Ghub uses
349      Auth-Source:: for instructions on how to save the token more
350      securely.
351
352    • When creating a token it is necessary to provide a token
353      description.  Ghub uses descriptions that have the form "Emacs
354      package PACKAGE @ LOCAL-MACHINE".
355
356      Github uses the token description to identify the token, not merely
357      as something useful to humans.  Token descriptions therefore have
358      to be unique and in rare cases you get an additional prompt, asking
359      you something like:
360
361           A token named "Emacs package PACKAGE @ LOCAL-MACHINE"
362           already exists on Github.  Replace it?
363
364      You might see this message when you have lost the old token and
365      want to replace it with a new one, in which case you should
366      obviously just proceed.
367
368      Or two of your computers have the same hostname, which is bad
369      practice because it gains you nothing but leads to issues such as
370      this.  Or you are dual-booting on this machine and use the same
371      hostname in all operating systems, which is a somewhat reasonable
372      thing to do, but never-the-less leads to issues like this.
373
374      In either case you will have to use something other than the value
375      returned by ‘system-name’ to identify the current machine or
376      operating system.  Or you can continue to identify different things
377      using the same identifier, in which case you have to manually
378      distribute the token.
379
380      The former is recommended and also easier to do, using the variable
381      ‘ghub-override-system-name’.  See *note Configuration Variables::
382      for details.
383
384    After the above prompt you are also asked for your username and
385 password.  If you have enabled two-factor authentication, then you also
386 have to provide the authentication code at least twice.  If you make
387 sure the code is still good for a while when asked for it first, then
388 you can just press ‘RET’ at the later prompt(s).
389
390 
391 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
392
393 2.3 Manually Creating and Storing a Token
394 =========================================
395
396 If you cannot or don’t want to use the wizard then you have to (1)
397 figure out what scopes a package wants, (2) create such a token using
398 the web interface and (3) store the token where Ghub expects to find it.
399
400    A package named ‘PACKAGE’ has to specify the scopes that it wants in
401 the variable named ‘PACKAGE-ghub-token-scopes’.  The doc-string of such
402 variables should document what the various scopes are needed for.
403
404    To create or edit a token go to <https://github.com/settings/tokens>.
405 For Gitlab.com use <https://gitlab.com/profile/personal_access_tokens>.
406
407    Finally store the token in a place where Ghub looks for it, as
408 described in *note How Ghub uses Auth-Source::.
409
410    If you store the token in a file like ‘~/.authinfo’, then note that
411 ‘auth-source’’s parsing of that file is brittle.  Make sure the file
412 ends with a newline character, that there are no empty or invalid lines,
413 and that all comments are prefixed with ‘#’.
414
415 
416 File: ghub.info,  Node: How Ghub uses Auth-Source,  Prev: Manually Creating and Storing a Token,  Up: Getting Started
417
418 2.4 How Ghub uses Auth-Source
419 =============================
420
421 Please see *note (auth)Top:: for all the gory details about Auth-Source.
422 Some Ghub-specific information and important notes follow.
423
424    The variable ‘auth-sources’ controls how and where Auth-Source stores
425 new secrets and where it looks for known secrets.  The default value is
426 ‘("~/.authinfo" "~/.authinfo.gpg" "~/.netrc")’, which means that it
427 looks in all of these files in order to find secrets and that it stores
428 new secrets in ‘~/.authinfo’ because that is the first element of the
429 list.  It doesn’t matter which files already do or don’t exist when
430 storing a new secret, the first file is always used.
431
432    Secrets are stored in ‘~/.authinfo’ in plain text.  If you don’t want
433 that (good choice), then you have to customize ‘auth-sources’, e.g.  by
434 flipping the positions of the first two elements.
435
436    Auth-Source also supports storing secrets in various key-chains.
437 Refer to its documentation for more information.
438
439    Some Auth-Source backends only support storing three values per
440 entry, the "machine", the "login" and the "password".  Because Ghub uses
441 separate tokens for each package, it has to squeeze four values into
442 those three slots, and it does that by using "USERNAME^PACKAGE" as the
443 "login".
444
445    Assuming your username is "ziggy",the package is named "stardust",
446 and you want to access *Github.com* an entry in one of the three
447 mentioned files would then look like this:
448
449      machine api.github.com login ziggy^stardust password 012345abcdef...
450
451    Assuming your username is "ziggy",the package is named "stardust",
452 and you want to access *Gitlab.com* an entry in one of the three
453 mentioned files would then look like this:
454
455      machine gitlab.com/api/v4 login ziggy^stardust password 012345abcdef...
456
457 
458 File: ghub.info,  Node: Using Ghub in Personal Scripts,  Next: Using Ghub in a Package,  Prev: Getting Started,  Up: Top
459
460 3 Using Ghub in Personal Scripts
461 ********************************
462
463 You can use ‘ghub-request’ and its wrapper functions in your personal
464 scripts, of course.  Unlike when you use Ghub from a package that you
465 distribute for others to use, you don’t have to specify a package in
466 personal scripts.
467
468      ;; This is perfectly acceptable in personal scripts ...
469      (ghub-get "/user")
470
471      ;; ... and actually equal to
472      (ghub-get "/user" nil :auth 'ghub)
473
474      ;; In packages you have to specify the package using AUTH.
475      (ghub-get "/user" nil :auth 'foobar)
476
477    When you do not specify the ‘AUTH’ argument, then a request is made
478 on behalf of the ‘ghub’ package itself.  Like for any package that uses
479 Ghub, ‘ghub’ has to declare what scopes it needs, using, in this case,
480 the variable ‘ghub-github-token-scopes’.
481
482    The default value of that variable is ‘(repo)’ and you might want to
483 add additional scopes.  You can later add additional scopes to an
484 existing token, using the web interface at
485 <https://github.com/settings/tokens>.
486
487    If you do that, then you might want to also set the variable
488 accordingly, but note that Ghub only consults that when *creating* a new
489 token.  If you want to know a token’s effective scopes use the command
490 ‘ghub-token-scopes’, described in the next section.
491
492 
493 File: ghub.info,  Node: Using Ghub in a Package,  Next: API,  Prev: Using Ghub in Personal Scripts,  Up: Top
494
495 4 Using Ghub in a Package
496 *************************
497
498 Every package should use its own token.  This allows you as the author
499 of some package to only request access to API scopes that are actually
500 needed, which in turn might make it easier for users to trust your
501 package not to do unwanted things.
502
503    The scopes used by ‘PACKAGE’ have to be defined using the variable
504 ‘PACKAGE-github-token-scopes’, and you have to tell ‘ghub-request’ on
505 behalf of which package a request is being made by passing the symbol
506 ‘PACKAGE’ as the value of its ‘AUTH’ argument.
507
508      (ghub-request "GET" "/user" nil :auth 'PACKAGE)
509
510  -- Variable: PACKAGE-github-token-scopes
511
512      This variable defines the token scopes requested by the package
513      named ‘PACKAGE’.  The doc-string should explain what the various
514      scopes are needed for to prevent users from giving ‘PACKAGE’ fewer
515      permissions than it absolutely needs and also to give them greater
516      confidence that ‘PACKAGE’ is only requesting the permissions that
517      it actually needs.
518
519      The value of this variable does not necessarily correspond to the
520      scopes that the respective token actually gives access to.  There
521      is nothing that prevents users from changing the value *after*
522      creating the token or from editing the token’s scopes later on.
523
524      So it is pointless to check the value of this variable before
525      making a request.  You also should not query the API to reliably
526      determine the supported tokens before making a query.  Doing the
527      latter would mean that every request becomes two requests and that
528      the first request would have to be done using the user’s password
529      instead of a token.
530
531  -- Command: ghub-token-scopes
532
533      Because we cannot be certain that the user hasn’t messed up the
534      scopes, Ghub provides this command to make it easy to debug such
535      issues without having to rely on users being thoughtful enough to
536      correctly determine the used scopes manually.
537
538      Just tell users to run ‘M-x ghub-token-scopes’ and to provide the
539      correct values for the ‘HOST’, ‘USERNAME’ and ‘PACKAGE’ when
540      prompted, and to then post the output.
541
542      It is to be expected that users will occasionally mess that up so
543      this command outputs not only the scopes but also the user input so
544      that you can have greater confidence in the validity of the user’s
545      answer.
546
547           Scopes for USERNAME^PACKAGE@HOST: (SCOPE...)
548
549 
550 File: ghub.info,  Node: API,  Next: GraphQL Support,  Prev: Using Ghub in a Package,  Up: Top
551
552 5 API
553 *****
554
555 This section describes the Ghub API.  In other words it describes the
556 public functions and variables provided by the Ghub package and not the
557 APIs of the supported forges, which can be accessed by using those
558 functions.  The forge APIs are documented at:
559
560    • Github: <https://developer.github.com/v3>
561
562    • Gitlab: <https://docs.gitlab.com/ee/api/README.html>
563
564    • Gitea: <https://docs.gitea.io/en-us/api-usage> and
565      <https://try.gitea.io/api/swagger>
566
567    • Gogs: <https://github.com/gogs/go-gogs-client/wiki>
568
569    • Bitbucket:
570      <https://developer.atlassian.com/bitbucket/api/2/reference>
571
572 * Menu:
573
574 * Making Requests::
575 * Authentication::
576 * Configuration Variables::
577
578 
579 File: ghub.info,  Node: Making Requests,  Next: Authentication,  Up: API
580
581 5.1 Making Requests
582 ===================
583
584  -- Function: ghub-request method resource &optional params &key query
585           payload headers unpaginate noerror reader username auth host
586           callback errorback url value error extra method*
587
588      This function makes a request for ‘RESOURCE’ using ‘METHOD’.
589      ‘PARAMS’, ‘QUERY’, ‘PAYLOAD’ and/or ‘HEADERS’ are alists holding
590      additional request data.  The response body is returned and the
591      response header is stored in the variable ‘ghub-response-headers’.
592
593         • ‘METHOD’ is the HTTP method, given as a string.
594
595         • ‘RESOURCE’ is the resource to access, given as a string
596           beginning with a slash.
597
598         • ‘PARAMS’, ‘QUERY’, ‘PAYLOAD’ and ‘HEADERS’ are alists and are
599           used to specify request data.  All these arguments are alists
600           that resemble the JSON expected and returned by the Github
601           API.  The keys are symbols and the values stored in the ‘cdr’
602           (not the ‘cadr’) can be strings, integers, or lists of strings
603           and integers.
604
605           The Github API documentation is vague on how data has to be
606           transmitted and for a particular resource usually just talks
607           about "parameters".  Generally speaking when the ‘METHOD’ is
608           "HEAD" or "GET", then they have to be transmitted as a query,
609           otherwise as a payload.
610
611              • Use ‘PARAMS’ to automatically transmit like ‘QUERY’ or
612                ‘PAYLOAD’ would depending on ‘METHOD’.
613
614              • Use ‘QUERY’ to explicitly transmit data as a query.
615
616              • Use ‘PAYLOAD’ to explicitly transmit data as a payload.
617                Instead of an alist, ‘PAYLOAD’ may also be a string, in
618                which case it gets encoded as UTF-8 but is otherwise
619                transmitted as-is.
620
621              • Use ‘HEADERS’ for those rare resources that require that
622                the data is transmitted as headers instead of as a query
623                or payload.  When that is the case, then the Github API
624                documentation usually mentions it explicitly.
625
626         • If ‘SILENT’ is non-nil, then progress reports and the like are
627           not messaged.
628
629         • If ‘UNPAGINATE’ is t, then this function make as many requests
630           as necessary to get all values.  If ‘UNPAGINATE’ is a natural
631           number, then it gets at most that many pages.  For any other
632           non-nil value it raises an error.
633
634         • If ‘NOERROR’ is non-nil, then no error is raised if the
635           request fails and ‘nil’ is returned instead.  If ‘NOERROR’ is
636           ‘return’, then the error payload is returned instead of ‘nil’.
637
638         • If ‘READER’ is non-nil, then it is used to read and return
639           from the response buffer.  The default is
640           ‘ghub--read-json-payload’.  For the very few resources that do
641           not return JSON, you might want to use ‘ghub--decode-payload’.
642
643         • If ‘USERNAME’ is non-nil, then the request is made on behalf
644           of that user.  It is better to specify the user using the Git
645           variable ‘github.user’ for "api.github.com", or
646           ‘github.HOST.user’ if connecting to a Github Enterprise
647           instance.
648
649         • Each package that uses Ghub should use its own token.  If
650           ‘AUTH’ is ‘nil’ or unspecified, then the generic ‘ghub’ token
651           is used instead.  This is only acceptable for personal
652           utilities.  A packages that is distributed to other users
653           should always use this argument to identify itself, using a
654           symbol matching its name.
655
656           Package authors who find this inconvenient should write a
657           wrapper around this function and possibly for the
658           method-specific functions as well.
659
660           Beside ‘nil’, some other symbols have a special meaning too.
661           ‘none’ means to make an unauthorized request.  ‘basic’ means
662           to make a password based request.  If the value is a string,
663           then it is assumed to be a valid token.  ‘basic’ and an
664           explicit token string are only intended for internal and
665           debugging uses.
666
667           If ‘AUTH’ is a package symbol, then the scopes are specified
668           using the variable ‘AUTH-github-token-scopes’.  It is an error
669           if that is not specified.  See ‘ghub-github-token-scopes’ for
670           an example.
671
672         • If ‘HOST’ is non-nil, then connect to that Github instance.
673           This defaults to "api.github.com".  When a repository is
674           connected to a Github Enterprise instance, then it is better
675           to specify that using the Git variable ‘github.host’ instead
676           of using this argument.
677
678         • If ‘FORGE’ is ‘gitlab’, then connect to Gitlab.com or,
679           depending on ‘HOST’, to another Gitlab instance.  This is only
680           intended for internal use.  Instead of using this argument you
681           should use function ‘glab-request’ and other ‘glab-*’
682           functions.
683
684         • If ‘CALLBACK’ and/or ‘ERRORBACK’ is non-nil, then this
685           function makes one or more asynchronous requests and calls
686           ‘CALLBACK’ or ‘ERRORBACK’ when finished.  If an error
687           occurred, then it calls ‘ERRORBACK’, or if that is ‘nil’, then
688           ‘CALLBACK’.  When no error occurred then it calls ‘CALLBACK’.
689           When making asynchronous requests, then no errors are
690           signaled, regardless of the value of ‘NOERROR’.
691
692           Both callbacks are called with four arguments.
693
694              • For ‘CALLBACK’, the combined value of the retrieved
695                pages.  For ‘ERRORBACK’, the error that occured when
696                retrieving the last page.
697
698              • The headers of the last page as an alist.
699
700              • Status information provided by ‘url-retrieve’.  Its
701                ‘:error’ property holds the same information as the first
702                argument to ‘ERRORBACK’.
703
704              • A ‘ghub--req’ struct, which can be passed to
705                ‘ghub-continue’ (which see) to retrieve the next page, if
706                any.
707
708  -- Function: ghub-continue args
709
710      If there is a next page, then this function retrieves that.
711
712      This function is only intended to be called from callbacks.  If
713      there is a next page, then that is retrieve and the buffer that the
714      result will be loaded into is returned, or t if the process has
715      already completed.  If there is no next page, then return nil.
716
717      Callbacks are called with four arguments (see ‘ghub-request’).  The
718      forth argument is a ‘ghub--req’ struct, intended to be passed to
719      this function.  A callback may use the struct’s ‘extra’ slot to
720      pass additional information to the callback that will be called
721      after the next request.  Use the function ‘ghub-req-extra’ to get
722      and set the value of that slot.
723
724      As an example, using ‘ghub-continue’ in a callback like so:
725
726           (ghub-get "/users/tarsius/repos" nil
727                     :callback (lambda (value _headers _status req)
728                                 (unless (ghub-continue req)
729                                   (setq my-value value))))
730
731      is equivalent to:
732
733           (ghub-get "/users/tarsius/repos" nil
734                     :unpaginate t
735                     :callback (lambda (value _headers _status _req)
736                                 (setq my-value value)))
737
738      To demonstrate how to pass information from one callback to the
739      next, here we record when we start fetching each page:
740
741           (ghub-get "/users/tarsius/repos" nil
742                     :extra (list (current-time))
743                     :callback (lambda (value _headers _status req)
744                                 (push (current-time) (ghub-req-extra req))
745                                 (unless (ghub-continue req)
746                                   (setq my-times (ghub-req-extra req))
747                                   (setq my-value value))))
748
749  -- Variable: ghub-response-headers
750
751      A select few Github API resources respond by transmitting data in
752      the response header instead of in the response body.  Because there
753      are so few of these inconsistencies, ‘ghub-request’ always returns
754      the response body.
755
756      To access the response headers use this variable after
757      ‘ghub-request’ has returned.
758
759  -- Function: ghub-response-link-relations req headers payload
760
761      This function returns an alist of the link relations in ‘HEADERS’,
762      or if optional ‘HEADERS’ is nil, then those in
763      ‘ghub-response-headers’.
764
765      When accessing a Bitbucket instance then the link relations are in
766      ‘PAYLOAD’ instead of ‘HEADERS’, making their API merely RESTish and
767      forcing this function to append those relations to the value of
768      ‘ghub-response-headers’, for later use when this function is called
769      with ‘nil’ for ‘PAYLOAD’.
770
771  -- Variable: ghub-override-system-name
772
773      If non-nil, the value of this variable is used to override the
774      value returned by ‘system-name’ for the purpose of identifying the
775      local machine, which is necessary because Ghub uses separate tokens
776      for each machine.  Also see *note Configuration Variables::.
777
778  -- Variable: ghub-github-token-scopes
779  -- Variable: PACKAGE-github-token-scopes
780
781      Such a variable defines the token scopes requested by the
782      respective package ‘PACKAGE’ given by the first word in the
783      variable name.  ‘ghub’ itself is treated like any other package.
784      Also see *note Using Ghub in a Package::.
785
786  -- Function: ghub-head resource &optional params &key query payload
787           headers unpaginate noerror reader username auth host callback
788           errorback
789  -- Function: ghub-get resource &optional params &key query payload
790           headers unpaginate noerror reader username auth host callback
791           errorback
792
793      These functions are simple wrappers around ‘ghub-request’.  Their
794      signature is identical to that of the latter, except that they do
795      not have an argument named ‘METHOD’.  The HTTP method is instead
796      given by the second word in the function name.
797
798      As described in the documentation for ‘ghub-request’, it depends on
799      the used method whether the value of the ‘PARAMS’ argument is used
800      as the query or the payload.  For the "HEAD" and "GET" methods it
801      is used as the query.
802
803  -- Function: ghub-put resource &optional params &key query payload
804           headers unpaginate noerror reader username auth host callback
805           errorback
806  -- Function: ghub-post resource &optional params &key query payload
807           headers unpaginate noerror reader username auth host callback
808           errorback
809  -- Function: ghub-patch resource &optional params &key query payload
810           headers unpaginate noerror reader username auth host callback
811           errorback
812  -- Function: ghub-delete resource &optional params &key query payload
813           headers unpaginate noerror reader username auth host callback
814           errorback
815
816      These functions are simple wrappers around ‘ghub-request’.  Their
817      signature is identical to that of the latter, except that they do
818      not have an argument named ‘METHOD’.  The HTTP method is instead
819      given by the second word in the function name.
820
821      As described in the documentation for ‘ghub-request’, it depends on
822      the used method whether the value of the ‘PARAMS’ argument is used
823      as the query or the payload.  For the "PUT", "POST", "PATCH" and
824      "DELETE" methods it is used as the payload.
825
826  -- Function: ghub-wait resource &optional duration &key username auth
827           host
828
829      Some API requests result in an immediate successful response even
830      when the requested action has not actually been carried out yet.
831      An example is the request for the creation of a new repository,
832      which doesn’t cause the repository to immediately become available.
833      The Github API documentation usually mentions this when describing
834      an affected resource.
835
836      If you want to do something with some resource right after making a
837      request for its creation, then you might have to wait for it to
838      actually be created.  This function can be used to do so.  It
839      repeatedly tries to access the resource until it becomes available
840      or until the timeout exceeds.  In the latter case it signals
841      ‘ghub-error’.
842
843      ‘RESOURCE’ specifies the resource that this function waits for.
844
845      ‘DURATION’ specifies the maximum number of seconds to wait for,
846      defaulting to 64 seconds.  Emacs will block during that time, but
847      the user can abort using ‘C-g’.
848
849      The first attempt is made immediately and will often succeed.  If
850      not, then another attempt is made after two seconds, and each
851      subsequent attempt is made after waiting as long as we already
852      waited between all preceding attempts combined.
853
854      See ‘ghub-request’’s documentation above for information about the
855      other arguments.
856
857  -- Function: ghub-graphql graphql &optional variables &key username
858           auth host callback
859
860      This function makes a GraphQL request using ‘GRAPHQL’ and
861      ‘VARIABLES’ as inputs.  ‘GRAPHQL’ is a GraphQL string.  ‘VARIABLES’
862      is a JSON-like alist.  The other arguments behave as for
863      ‘ghub-request’ (which see).
864
865      The response is returned as a JSON-like alist.  Even if the
866      response contains ‘errors’, this function does not raise an error.
867      Cursor-handling is likewise left to the caller.
868
869 
870 File: ghub.info,  Node: Authentication,  Next: Configuration Variables,  Prev: Making Requests,  Up: API
871
872 5.2 Authentication
873 ==================
874
875  -- Command: ghub-create-token
876
877      This command creates a new token using the values it reads from the
878      user and then stores it according to the variable ‘auth-sources’.
879      It can also be called non-interactively, but you shouldn’t do that
880      yourself.
881
882      This is useful if you want to fully setup things before attempting
883      to make the initial request, if you want to provide fewer than the
884      requested scopes or customize ‘auth-sources’ first, or if something
885      has gone wrong when using the wizard that is used when making a
886      request without doing this first.  (Note that instead of using this
887      command you can also just repeat the initial request after making
888      the desired adjustments — that is easier.)
889
890      This command reads, in order, the ‘HOST’ (Github instance), the
891      ‘USERNAME’, the ‘PACKAGE’, and the ‘SCOPES’ in the minibuffer,
892      providing reasonable default choices.  ‘SCOPES’ defaults to the
893      scopes that ‘PACKAGE’ requests using the variable
894      ‘PACKAGE-github-token-scopes’.
895
896  -- Command: ghub-token-scopes
897
898      Users are free to give a token access to fewer scopes than what the
899      respective package requested.  That can, of course, lead to issues,
900      and package maintainers have to be able to quickly determine if
901      such a (mis-)configuration is the root cause when users report
902      issues.
903
904      This command reads the required values in the minibuffer and then
905      shows a message containing these values along with the scopes of
906      the respective token.  It also returns the scopes (only) when
907      called non-interactively.  Also see *note Using Ghub in a
908      Package::.
909
910 
911 File: ghub.info,  Node: Configuration Variables,  Prev: Authentication,  Up: API
912
913 5.3 Configuration Variables
914 ===========================
915
916 The username and, unless you only use Github.com itself, the Github
917 Enterprise instance have to be configured using Git variables.  In rare
918 cases it might also be necessary to specify the identity of the local
919 machine, which is done using a lisp variable.
920
921  -- Variable: github.user
922
923      The Github.com username.  This should be set globally and if you
924      have multiple Github.com user accounts, then you should set this
925      locally only for those repositories that you want to access using
926      the secondary identity.
927
928  -- Variable: github.HOST.user
929
930      This variable serves the same purpose as ‘github.user’ but for the
931      Github Enterprise instance identified by ‘HOST’.
932
933      The reason why separate variables are used is that this makes it
934      possible to set both values globally instead of having to set one
935      of the values locally in each and every repository that is
936      connected to the Github Enterprise instance, not Github.com.
937
938  -- Variable: github.host
939
940      This variable should only be set locally for a repository and
941      specifies the Github Enterprise edition that that repository is
942      connected to.  You should not set this globally because then each
943      and every repository becomes connected to the specified Github
944      Enterprise instance, including those that should actually be
945      connected to Github.com.
946
947      When this is undefined, then "api.github.com" is used (defined in
948      the constant ‘ghub-default-host’, which you should never attempt to
949      change.)
950
951  -- Variable: ghub-override-system-name
952
953      Ghub uses a different token for each quadruple ‘(USERNAME PACKAGE
954      HOST LOCAL-MACHINE)’.  Theoretically it could reuse tokens to some
955      extent but that would be more difficult to implement, less
956      flexible, and less secure (though slightly more convenient).
957
958      A token is identified on the respective Github instance (Github.com
959      or a Github Enterprise instance) using the pair ‘(PACKAGE .
960      LOCAL-MACHINE)’, or more precisely the string "Emacs package
961      PACKAGE @ LOCAL-MACHINE". ‘USERNAME’ and ‘HOST’ do not have to be
962      encoded because the token is stored for ‘USERNAME’ on ‘HOST’ and
963      cannot be used by another user and/or on another instance.
964
965      There is one potential problem though; for any given ‘(PACKAGE .
966      LOCAL-MACHINE)’ there can only be one token identified by "Emacs
967      package PACKAGE @ LOCAL-MACHINE"; Github does not allow multiple
968      tokens with the same description because it uses the description as
969      the identifier (it could use some hash instead, but alas it does
970      not).
971
972      If you have multiple machines and some of them have the same name,
973      then you should probably change that as this is not how things
974      ought to be.  However if you dual-boot, then it might make sense to
975      give that machine the same name regardless of what operating system
976      you have booted into.
977
978      You could use the same token on both operating systems, but setting
979      that up might be somewhat difficult because it is not possible to
980      download an existing token from Github.  You could, of course,
981      locally copy the token, but that is inconvenient and would make it
982      harder to only revoke the token used on your infected Windows
983      installation without also revoking it for your totally safe *BSD
984      installation.
985
986      Alternatively you can set this variable to a unique value, that
987      will then be used to identify the local machine instead of the
988      value returned by ‘system-name’.
989
990 
991 File: ghub.info,  Node: GraphQL Support,  Next: Support for Other Forges,  Prev: API,  Up: Top
992
993 6 GraphQL Support
994 *****************
995
996  -- Function: ghub-graphql graphql &optional variables &key username
997           auth host callback silent callback errorback value extra
998
999      This function makes a GraphQL request using ‘GRAPHQL’ and
1000      ‘VARIABLES’ as inputs.  ‘GRAPHQL’ is a GraphQL string.  ‘VARIABLES’
1001      is a JSON-like alist.  The other arguments behave as for
1002      ‘ghub-request’ (which see).
1003
1004      The response is returned as a JSON-like alist.  Even if the
1005      response contains ‘errors’, this function does not raise an error.
1006      Cursor-handling is likewise left to the caller.
1007
1008    ‘ghub-graphql’ is a thin convenience wrapper around ‘ghub-request’,
1009 similar to ‘ghub-post’ and friends.  While the latter only hard-code the
1010 value of the ‘METHOD’ argument, the former also hard-codes ‘RESOURCE’
1011 and constructs ‘PAYLOAD’ from ‘GRAPHEQL’ and ‘VARIABLES’.  It also drops
1012 ‘UNPAGINATE’, ‘NOERROR’, ‘READER’ (internal functions expect alist-ified
1013 JSON) and ‘FORGE’ (only Github currently supports GraphQL).
1014
1015    ‘ghub-graphql’ does not account for the fact that pagination works
1016 differently in GraphQL than it does in REST, so users of this function
1017 have to deal with that themselves.  Likewise error handling works
1018 differently and has to be done by the caller too.
1019
1020    An early attempt at implementing automatic unpaginating for GraphQL
1021 can be found in the ‘faithful-graphql’ branch, provided I haven’t
1022 deleted that by now.  On that branch I try to do things as intended by
1023 the designers of GraphQL, using variables and fragments, and drowning in
1024 a sea of boilerplate.
1025
1026    The problem with that approach is that it only works for applications
1027 that fetch specific information on demand and actually want things to be
1028 paginated.  I am convinced that GraphQL is very nice for web apps.
1029
1030    However the Forge package for which I am implementing all of this has
1031 very different needs.  It wants to fetch "all the data" and "cache" it
1032 locally, so that it is available even when there is no internet
1033 connection.  GraphQL was designed around the idea that you should be
1034 able to "ask for what you need and get exactly that".  But when that
1035 boils down to "look, if I persist, then you are going to hand me over
1036 all the data anyway, so just caught it up already", then things start to
1037 fall apart.  If Github’s GraphQL allowed pagination to be turned off
1038 completely, then teaching ‘ghub-graphql’ about error handling would be
1039 enough.
1040
1041    But it doesn’t and when doing things as intended, then that leads to
1042 huge amounts of repetitive boilerplate, which is so boring to write that
1043 doing it without introducing bugs left and right is near impossible; so
1044 I decided to give up on GraphQL variables, fragments and conditions, and
1045 instead implement something more powerful, though also more opinionated.
1046
1047  -- Function: ghub--graphql-vacuum query variables callback &optional
1048           until &key narrow username auth host forge
1049
1050      This function is an opinionated alternative to ‘ghub-graphql’.  It
1051      relies and dark magic to get the job done.
1052
1053      It makes an initial request using ‘QUERY’.  It then looks for
1054      paginated edges in the returned data and makes more requests to
1055      resolve them.  In order to do so it automatically transforms the
1056      initial ‘QUERY’ into another query suitable for that particular
1057      edge.  The data retrieved by subsequent requests is then injected
1058      into the data of the original request before that is returned or
1059      passed to the callback.  If subsequently retrieved data features
1060      new paginated edges, then those are followed recursively.
1061
1062      The end result is essentially the same as using ‘ghub-graphql’, if
1063      only it were possible to say "do not paginate anything".  The
1064      implementation is much more complicated because it is not possible
1065      to do that.
1066
1067      ‘QUERY’ is a GraphQL query expressed as an s-expression.  The
1068      ‘graphql’ package is used to turn that into a GraphQL query string,
1069      but the format is somewhat different than as documented for that
1070      package.  Also only a subset of the GraphQL features are supported;
1071      fragments for example are not, and magical stuff happens to
1072      variables.  This is not documented yet, I am afraid.  Look at
1073      existing callers.
1074
1075      ‘VARIABLES’ is a JSON-like alist as for ‘ghub-graphql’.
1076
1077      ‘UNTIL’ is an alist ‘((EDGE-until . VALUE)...)’.  When unpaginating
1078      ‘EDGE’ try not to fetch beyond the element whose first field has
1079      the value ‘VALUE’ and remove that element as well as all "lesser"
1080      elements from the retrieved data if necessary.  Look at
1081      ‘forge--pull-repository’ for an example.  This is only useful if
1082      you "cache" the response locally and want to avoid fetching data
1083      again that you already have.
1084
1085      Other arguments behave as for ‘ghub-graphql’ and ‘ghub-request’,
1086      more or less.
1087
1088    Using ‘ghub--graphql-vacuum’, the following resource specific
1089 functions are implemented.  These functions are not part of the public
1090 API yet and are very much subject to change.
1091
1092  -- Function: ghub-fetch-repository owner name callback &optional until
1093           &key username auth host forge
1094
1095      This function asynchronously fetches forge data about the specified
1096      repository.  Once all data has been collected, ‘CALLBACK’ is called
1097      with the data as the only argument.
1098
1099  -- Function: ghub-fetch-issue owner name callback &optional until &key
1100           username auth host forge
1101
1102      This function asynchronously fetches forge data about the specified
1103      issue.  Once all data has been collected, ‘CALLBACK’ is called with
1104      the data as the only argument.
1105
1106  -- Function: ghub-fetch-pullreq owner name callback &optional until
1107           &key username auth host forge
1108
1109      This function asynchronously fetches forge data about the specified
1110      pull-request.  Once all data has been collected, ‘CALLBACK’ is
1111      called with the data as the only argument.
1112
1113    Note that in order to avoid duplication all of these functions base
1114 their initial query on the query stored in ‘ghub-fetch-repository’.  The
1115 latter two pass that query through ‘ghub--graphql-prepare-query’, which
1116 then used ‘ghub--graphql-narrow-query’ to remove parts the caller is not
1117 interested in.  These two functions are also used internally, when
1118 unpaginating, but as demonstrated here they can be useful even before
1119 making an initial request.
1120
1121 
1122 File: ghub.info,  Node: Support for Other Forges,  Prev: GraphQL Support,  Up: Top
1123
1124 7 Support for Other Forges
1125 **************************
1126
1127 * Menu:
1128
1129 * Forge Functions and Variables::
1130 * Forge Limitations and Notes::
1131
1132 
1133 File: ghub.info,  Node: Forge Functions and Variables,  Next: Forge Limitations and Notes,  Up: Support for Other Forges
1134
1135 7.1 Forge Functions and Variables
1136 =================================
1137
1138 Originally Ghub supported only Github but now it also supports Gitlab,
1139 Gitea, Gogs and Bitbucket.  The function ‘ghub-request’ and all the
1140 ‘ghub-METHOD’ convenience wrappers default to acting on a Github forge
1141 but can be told to act on another forge using their FORGE argument.
1142
1143    The FORGE argument only specifies what kind of forge to act on, not
1144 which instance.  The HOST argument can be used to select the instance.
1145 For some forges a default instance is defined:
1146
1147    • Forge ‘github’ defaults to host ‘api.github.com’.
1148
1149    • Forge ‘gitlab’ defaults to host ‘gitlab.com/api/v4’.
1150
1151    • Forge ‘bitbucket’ defaults to host ‘api.bitbucket.org/2.0’.
1152
1153    • No canonical host exists for the ‘gitea’ and ‘gogs’ forges and
1154      ‘localhost:3000/api/v1’ is used as the default host in both cases.
1155
1156    Together the FORGE and HOST arguments specify the forge type and
1157 instance.  In addition to that, it is also necessary to specify on whose
1158 behalf the request is being made, which can be done using the USERNAME
1159 and AUTH arguments.
1160
1161    Having to specify these arguments for every request is inconvenient.
1162 Additional variables and convenience functions can be used to make that
1163 unnecessary in most cases.
1164
1165    These variables can be set globally and/or for a specific repository
1166 as explained in *note Configuration Variables:: with a focus on Github
1167 instances.  To summarize:
1168
1169    • For <https://github.com> the Git variable ‘github.user’ specifies
1170      the user.
1171
1172    • For another ‘github’ instance the Git variable ‘github.HOST.user’
1173      specifies the user.  The HOST in that variable name is the same as
1174      the value of the HOST argument of the called function.
1175
1176    • Instead of specifying the HOST in every function call, the Git
1177      variable ‘github.host’ can be used.  This should only be set
1178      locally.
1179
1180 For ‘gitlab’ and ‘bitbucket’ forges similar variables are available:
1181
1182    • ‘gitlab.user’ specifies the <https://gitlab.com> user.
1183
1184    • ‘gitlab.HOST.user’ specifies the user for the HOST ‘gitlab’
1185      instance.
1186
1187    • ‘gitlab.host’ specifies the ‘gitlab’ host, unless the HOST argument
1188      is non-nil
1189
1190    • ‘bitbucket.user’ specifies the <https://bitbucket.org> user.
1191
1192    • ‘bitbucket.HOST.user’ specifies the user for the HOST ‘bitbucket’
1193      instance.
1194
1195    • ‘bitbucket.host’ specifies the ‘bitbucket’ host, unless the HOST
1196      argument is non-nil.
1197
1198    For ‘gitea’ and ‘gogs’ forges some similar variables are available,
1199 however for some of the ‘ghub.*’ variables no equivalent variable exist
1200 for these two forges:
1201
1202    • ‘gitea.user’ is *not* used because no canonical ‘gitea’ instance
1203      exists.
1204
1205    • ‘gitea.HOST.user’ specifies the user for the HOST ‘gitea’ instance.
1206
1207    • ‘gitea.host’ specifies the ‘gitea’ host, unless the HOST argument
1208      is non-nil
1209
1210    • ‘gogs.user’ is *not* used because no canonical ‘gitea’ instance
1211      exists.
1212
1213    • ‘gogs.HOST.user’ specifies the user for the HOST ‘gogs’ instance.
1214
1215    • ‘gogs.host’ specifies the ‘gogs’ host, unless the HOST argument is
1216      non-nil
1217
1218    ‘ghub-request’ and ‘ghub-METHOD’ can be used to make a request for
1219 any of the supported forge types, but except when making a request for a
1220 ‘github’ instance, then that requires the use of the FORGE argument.
1221
1222    To avoid that, functions named ‘FORGE-request’ and ‘FORGE-METHOD’ are
1223 also available.  The following forms are equivalent, for example:
1224
1225      (ghub-get ... :auth 'PACKAGE :forge 'gitlab)
1226      (glab-get ... :auth 'PACKAGE)
1227
1228    These forms would remain equivalent even if you did not specify a
1229 value for the AUTH arguments — but you should not do that if you plan to
1230 share your code with others (see *note Using Ghub in a Package::).  If
1231 you do omit AUTH, then the request is made on behalf of the ‘ghub’
1232 package, *regardless* of the symbol prefix of the function you use to do
1233 so.
1234
1235    All ‘FORGE-request’ and ‘FORGE-METHOD’ functions, including but not
1236 limited to ‘ghub-METHOD’, are very simple wrappers around
1237 ‘ghub-request’.  They take fewer arguments than ‘ghub-request’ and
1238 instead pass constant values for the arguments METHOD and/or FORGE.
1239
1240 
1241 File: ghub.info,  Node: Forge Limitations and Notes,  Prev: Forge Functions and Variables,  Up: Support for Other Forges
1242
1243 7.2 Forge Limitations and Notes
1244 ===============================
1245
1246    • The token creation wizard is only available for ‘github’ forges,
1247      because all other forges do not support using the API to create an
1248      API token.  As a consequence, if the user makes a request and the
1249      necessary token cannot be found, then that results in an error.
1250      Tokens can be created at:
1251
1252         • Gitlab: <https://gitlab.com/profile/personal_access_tokens>
1253
1254         • Bitbucket:
1255           <https://bitbucket.org/account/user/tarsius/app-passwords>
1256
1257         • Gitea: <https://localhost:3000/user/settings/applications>
1258
1259         • Gogs: <https://localhost:3000/user/settings/applications>
1260
1261      Also see *note Manually Creating and Storing a Token:: and *note
1262      How Ghub uses Auth-Source::.
1263
1264    • As mentioned in the previous node, the variables ‘gitea.host’ and
1265      ‘gogs.host’ are not taken into account.
1266
1267    • Gitea and Gogs do not support limiting a token to certain scopes.
1268
1269    • The Bitbucket API is fairly broken.  Some resources only work if a
1270      slash is appended while others only work if no slash is appended.
1271      I am unable to access any private repositories and some resources
1272      don’t work for me at all.  Also the API is only RESTish; pagination
1273      information is part of the response body instead of the header.
1274      Due to such issues it is possible that I will eventually have to
1275      remove support for Bitbucket altogether.
1276
1277    • The Gitlab API documentation is not always accurate, though I don’t
1278      have an example at hand.  It also isn’t structured well, making it
1279      occationally difficult to find the information one is looking for.
1280
1281    • Where one would use ‘user/repo’ when accessing another forge, one
1282      has to use ‘user%2Frepo’ when accessing Gitlab, e.g.:
1283
1284           (glab-get "/projects/python-mode-devs%2Fpython-mode")
1285
1286
1287 
1288 Tag Table:
1289 Node: Top764
1290 Node: Introduction3279
1291 Node: Getting Started6321
1292 Node: Setting the Username10055
1293 Node: Interactively Creating and Storing a Token11480
1294 Node: Manually Creating and Storing a Token17131
1295 Node: How Ghub uses Auth-Source18354
1296 Node: Using Ghub in Personal Scripts20287
1297 Node: Using Ghub in a Package21743
1298 Node: API24361
1299 Node: Making Requests25158
1300 Node: Authentication39197
1301 Node: Configuration Variables41042
1302 Node: GraphQL Support44762
1303 Node: Support for Other Forges51427
1304 Node: Forge Functions and Variables51644
1305 Node: Forge Limitations and Notes56163
1306 
1307 End Tag Table
1308
1309 
1310 Local Variables:
1311 coding: utf-8
1312 End: