|
7 | 7 | ⍝ Apart from the REST interface the class also offers one method that relies on the REST interface but goes beyond |
8 | 8 | ⍝ it: `GetRelease`returns the URL of a tarball or a zipball or an EXE from GitHub.\\ |
9 | 9 | ⍝ For the time being this class runs only under Windows: it relies on .NET. If there is demand for other platforms |
10 | | -⍝ the .NET calls could be exchanged against Rumba.\\ |
| 10 | +⍝ the .NET calls could be exchanged against Rumba or .NET core.\\ |
11 | 11 | ⍝ The project lives on <https://github.com/aplteam/GitHubAPIv3>\\ |
12 | 12 | ⍝ It is part of the [APLTree library](https://github.com/aplteam/apltree/wiki) |
13 | 13 | ⍝ Kai Jaeger ⋄ APL Team Ltd |
|
18 | 18 |
|
19 | 19 | ∇ r←Version |
20 | 20 | :Access Public Shared |
21 | | - r←'GitHub' '0.4.0.15' '2019-06-11' |
22 | | - ∇ |
23 | | - |
24 | | - ∇ ToDo |
25 | | - ⍝ * Implement PutTopics |
26 | | - ⍝ * Add methods for creating and deleting an issue |
| 21 | + r←'GitHub' '0.6.0.18' '2020-03-23' |
27 | 22 | ∇ |
28 | 23 |
|
29 | 24 | ∇ History |
30 | 25 | :Access Public Shared |
| 26 | + ⍝ * 0.6.0 |
| 27 | + ⍝ * File extension is now .aplc rather than .dyalog |
| 28 | + ⍝ * 0.5.0 |
| 29 | + ⍝ * Issue-related methods added: `GetAllIssues`, `GetIssue`, `CreateIssue`, `UpdateIssue`. |
| 30 | + ⍝ * Topic-related methods added: `GetAllTopics` and ... (not yet) `ReplaceAllTopics`. |
31 | 31 | ⍝ * 0.4.0 |
32 | 32 | ⍝ * New methods added: `GetRelease`, `GetLatestTag` and `CheckForUpdate`. |
33 | 33 | ⍝ * There is now a property `regEx`. |
|
139 | 139 | :EndIf |
140 | 140 | ∇ |
141 | 141 |
|
142 | | - ∇ (rc msg ns)←GetAllTopics repoName;gitPath;parms |
| 142 | + ∇ (rc msg r)←GetAllTopics repoName;gitPath;parms;ns |
143 | 143 | :Access Public Instance |
144 | 144 | ⍝ Returns all topics of a given repository.\\ |
145 | 145 | ⍝ You must use `https://` as protocol or not specify a protocol at all. |
|
149 | 149 | ⍝ : Is empty in case `rc ←→ 0` but might offer addtional information otherwise. |
150 | 150 | ⍝ `ns` |
151 | 151 | ⍝ : Namespace with the data received from GitHub. |
| 152 | + r←'' |
152 | 153 | gitPath←'https://api.github.com/repos/',_owner,'/',repoName,'/topics' |
153 | | - parms←CreateParms |
| 154 | + parms←CreateHttpParms |
154 | 155 | parms.Accepted←'application/vnd.github.mercy-preview+json' |
155 | 156 | (rc msg ns)←parms GetJson gitPath |
156 | 157 | :If 0=rc |
157 | | - ns.⎕DF'[JSON object: ',repoName,':topics]' |
| 158 | + r←ns.names |
158 | 159 | :EndIf |
159 | 160 | ∇ |
160 | 161 |
|
|
168 | 169 | :EndIf |
169 | 170 | ∇ |
170 | 171 |
|
| 172 | + ∇ (rc msg ns)←GetAllIssues repoName;gitPath |
| 173 | + :Access Public Instance |
| 174 | + ⍝ Returns all issues for a given repository |
| 175 | + gitPath←'https://api.github.com/repos/',(_owner),'/',repoName,'/issues' |
| 176 | + (rc msg ns)←GetJson gitPath |
| 177 | + :If 0≠≢ns |
| 178 | + ns.{⎕DF'[Issues of repo ',⍵,']'}⊂repoName |
| 179 | + ns.⎕FX⊂⎕CR'∆List' |
| 180 | + ns.⎕FX⊂'r←∆Details instance' 'r←∆List' 'r(instance.GetPrinciple)←''assignees'' ''login''' 'r(instance.GetPrinciple)←''labels'' ''name''' |
| 181 | + ns.⎕FX⊂'r←∆QuickView instance;keyWords' 'r←∆Details instance' 'keyWords←''title'' ''number'' ''state'' ''updated_at'' ''labels'' ''assignees''' 'r←(r[;1]∊keyWords)⌿r' 'r←r[⍋keyWords⍳r[;1];]' |
| 182 | + :EndIf |
| 183 | + ∇ |
| 184 | + |
| 185 | + ∇ (rc msg ns)←GetIssue(repoName number);gitPath |
| 186 | + :Access Public Instance |
| 187 | + ⍝ Returns exactly one issue for a given repository.\\ |
| 188 | + ⍝ Note that `ns` gets three functions injected: ∆List, ∆Details and ∆QuickView. While ∆List does not |
| 189 | + ⍝ require an argument, ∆Details and ∆QuickView require an instance of this class as right argument.\\ |
| 190 | + ⍝ ∆Details and ∆QuickView both replace the JSON objects "assignees" and "labels" by real data, but |
| 191 | + ⍝ ∆QuickView returns a small subset for a quick glance. |
| 192 | + gitPath←'https://api.github.com/repos/',(_owner),'/',repoName,'/issues/',⍕number |
| 193 | + (rc msg ns)←GetJson gitPath |
| 194 | + :If 0≠≢ns |
| 195 | + ns.{⎕DF ⍵}'[Issue ',(⍕number),' of repo ',repoName,']' |
| 196 | + ns.⎕FX ⎕CR'∆List' |
| 197 | + ns.⎕FX'r←∆Details instance' 'r←∆List' 'r(instance.GetPrinciple)←''assignees'' ''login''' 'r(instance.GetPrinciple)←''labels'' ''name''' |
| 198 | + ns.⎕FX'r←∆QuickView instance;keyWords' 'r←∆Details instance' 'keyWords←''title'' ''number'' ''state'' ''updated_at'' ''labels'' ''assignees''' 'r←(r[;1]∊keyWords)⌿r' 'r←r[⍋keyWords⍳r[;1];]' |
| 199 | + :EndIf |
| 200 | + ∇ |
| 201 | + |
| 202 | + ∇ (rc msg ns)←UpdateIssue(repoName parms);gitPath |
| 203 | + :Access Public Instance |
| 204 | + ⍝ Typically the (probably modified) result of call to `GetIssue` is passed as "parms". |
| 205 | + ∘∘∘ ⍝TODO⍝ requires a POST |
| 206 | + gitPath←'https://api.github.com/repos/',(_owner),'/',repoName,'/issues/',⍕number |
| 207 | + (rc msg ns)←GetJson gitPath |
| 208 | + :If 0≠≢ns |
| 209 | + ns.{⎕DF ⍵}'[Issue ',(⍕number),' of repo ',repoName,']' |
| 210 | + ns.⎕FX ⎕CR'∆List' |
| 211 | + ns.⎕FX'r←∆Details instance' 'r←∆List' 'r(instance.GetPrinciple)←''assignees'' ''login''' 'r(instance.GetPrinciple)←''labels'' ''name''' |
| 212 | + ns.⎕FX'r←∆QuickView instance;keyWords' 'r←∆Details instance' 'keyWords←''title'' ''number'' ''state'' ''updated_at'' ''labels'' ''assignees''' 'r←(r[;1]∊keyWords)⌿r' 'r←r[⍋keyWords⍳r[;1];]' |
| 213 | + :EndIf |
| 214 | + ∇ |
| 215 | + |
171 | 216 | ∇ (rc msg endpoints)←GetAllEndpoints;gitPath;msg;rc |
172 | 217 | :Access Public Shared |
173 | 218 | ⍝ This method returns all REST endpoints offered by the API.\\ |
|
193 | 238 | ∇ (rc msg)←PutTopics(repoName topics);gitPath;parms;dummy |
194 | 239 | ⍝ :Access Public Instance ⍝TODO⍝ Not implemented yet |
195 | 240 | ⍝ ... |
| 241 | + ∘∘∘ ⍝TODO⍝ |
196 | 242 | '"topics" must be a vector of character vectors'⎕SIGNAL 11/⍨2≠≡topics |
197 | 243 | gitPath←'https://api.github.com/repos/',(_owner),'/',repoName,'/topics' |
198 | | - parms←CreateParms |
| 244 | + parms←CreateHttpParms |
199 | 245 | parms.Accepted←'application/vnd.github.mercy-preview+json' |
200 | 246 | parms.Method←'PUT' |
201 | 247 | parms.Body←'{',(1 JSON'names'topics),'}' |
|
312 | 358 | r←version_<gitVersion |
313 | 359 | ∇ |
314 | 360 |
|
315 | | - ⍝ ---------- Private stuff |
| 361 | + ∇ r←CreateIssueParms |
| 362 | +⍝ :Access Public Instance ⍝TODO⍝ NOT IMPLEMENTED YET |
| 363 | + r←⎕NS'' |
| 364 | + r.title←'' |
| 365 | + r.body←'' |
| 366 | + r.milestone←0 |
| 367 | + r.labels←'' ⍝ Nested vector |
| 368 | + r.assignees←'' ⍝ Nested vector |
| 369 | + r.⎕FX'r←∆List' 'r←{⍉⍵,[.5]⍎¨⍵}'' ''~¨⍨↓⎕NL 2' |
| 370 | + ∇ |
| 371 | + |
| 372 | + ∇ r←CreateIssue(repoName parms);gitPath;rc;msg;ns |
| 373 | +⍝ :Access Public Instance ⍝TODO⍝ NOT IMPLEMENTED YET |
| 374 | + 'Invalid: "title"'⎕SIGNAL 11/⍨1≠≡,parms.title |
| 375 | + 'Invalid: "title"'⎕SIGNAL 11/⍨' '≠1↑0⍴∊parms.title |
| 376 | + 'Invalid: "milestone"'⎕SIGNAL 11/⍨1≠≢parms.milestone |
| 377 | + 'Invalid: "milestone"'⎕SIGNAL 11/⍨0≠1↑0⍴∊parms.milestone |
| 378 | + 'Invalid: "milestone"'⎕SIGNAL 11/⍨1≠≡,parms.milestone |
| 379 | +⍝ ... and so on ... |
| 380 | + gitPath←'https://api.github.com/repos/',(_owner),'/',repoName,'/issues/' |
| 381 | + gitPath,←'?title=',EncodeBlank parms.title |
| 382 | + (rc msg ns)←GetJson gitPath |
| 383 | + . |
| 384 | + |
| 385 | + ∇ |
| 386 | + |
| 387 | + ∇ r←CreateHttpParms |
| 388 | + ⍝ Create a parameter space that can be passed to some method that actually write to GitHub like `PutTopics' |
| 389 | + :Access Public Instance |
| 390 | + r←⎕NS'' |
| 391 | + r.Accepted←'Accept: application/vnd.github.v3+json' |
| 392 | + r.Method←'GET' |
| 393 | + r.Body←'' |
| 394 | + ∇ |
| 395 | + |
| 396 | + ⍝ ------------------------------------------ Private stuff ---------------------------------- |
316 | 397 |
|
317 | 398 | ∇ html←GetGitHubPage(repoName tag);c;q;buff;⎕USING;cp;req;res |
318 | 399 | :Trap 90 |
|
369 | 450 | ∇ (rc msg ns)←{parms}GetJson gitURL;cp;ServicePointManager;req;res;data;WebRequest;i;noOfPages;headers;owner;parms;str;c;q;⎕USING |
370 | 451 | ⍝ Takes `gitURL`which must specify a valid GitHub API URL and returns the data from GitHub.\\ |
371 | 452 | ⍝ `⍵`: Project URL, for example 'api.github.com/repos/aplteam/testrepo/releases/latest' |
372 | | - ⍝ `⍺`: Optional parameter space, typically create by calling `CreateParms`. |
| 453 | + ⍝ `⍺`: Optional parameter space, typically create by calling `CreateHttpParms`. |
373 | 454 | ⍝ `rc` |
374 | 455 | ⍝ : Either 0 for okay or an error code.\\ |
375 | 456 | ⍝ `msg` |
376 | 457 | ⍝ : Is empty in case `rc←→0` but might offer addtional information otherwise. |
377 | 458 | ⍝ `ns` |
378 | 459 | ⍝ : Namespace with the data received from GitHub. |
379 | | - parms←{0<⎕NC ⍵:⍎⍵ ⋄ CreateParms}'parms' |
| 460 | + parms←{0<⎕NC ⍵:⍎⍵ ⋄ CreateHttpParms}'parms' |
380 | 461 | :If 0=⎕NC'_owner' |
381 | 462 | owner←'APL GitHub API' |
382 | 463 | :Else |
|
422 | 503 | :EndTrap |
423 | 504 | ∇ |
424 | 505 |
|
425 | | - ∇ r←CreateParms |
426 | | - ⍝ Create a parameter space that can be passed to some method that actually write to GitHub like `PutTopics' |
427 | | - r←⎕NS'' |
428 | | - r.Accepted←'Accept: application/vnd.github.v3+json' |
429 | | - r.Method←'GET' |
430 | | - r.Body←'' |
431 | | - ∇ |
432 | | - |
433 | 506 | ∇ r←{type}JSON y;version;buff |
434 | 507 | ⍝ Cover for `⎕JSON` in order to support 15.0 which had only an `⌶` for what became later `⎕JSON`.\\ |
435 | 508 | ⍝ Note that by default this function imports JSON (`type`=0).\\ |
|
459 | 532 | txt←(-offset)⌽new,(≢old)↓offset⌽txt |
460 | 533 | ∇ |
461 | 534 |
|
| 535 | + ∇ data←data GetPrinciple(propName principleName);row;jsonObj;buff |
| 536 | + ⍝ * `propName` is the name of a variable in a data space that is a JSON object |
| 537 | + ⍝ * `principleName` is the principle name of all the properies of that JSON object\\ |
| 538 | + ⍝ Take a ref |
| 539 | + ⍝ is concatenated with a comma and a blank, so ('bug' 'question') become: |
| 540 | + ⍝ 'bug, question' |
| 541 | + :Access Public instance |
| 542 | + row←data[;1]⍳⊂propName |
| 543 | + :If 0≠≢jsonObj←2⊃data[row;] |
| 544 | + buff←jsonObj⍎¨⊂principleName |
| 545 | + data[row;2]←{⍺,', ',⍵}/buff |
| 546 | + :EndIf |
| 547 | + ∇ |
| 548 | + |
| 549 | +⍝ The following function is fixed within the data spaces returned by many if not all commands: |
| 550 | + ∇ r←∆List;names;values;bool |
| 551 | + ⍝ List all variables and their values. See also ∆View |
| 552 | + names←' '~¨⍨↓⎕NL 2 |
| 553 | + values←⍎¨names |
| 554 | + bool←{16::1 ⋄ 0⊣1↑0⍴⍵}¨values ⍝ Were are objects? |
| 555 | + :If ∨/bool |
| 556 | + {⍵.⎕DF⊂'(JSON object)'}¨bool/values |
| 557 | + :EndIf |
| 558 | + r←⍉names,[0.5]values |
| 559 | + ∇ |
| 560 | + |
| 561 | + ∇ r←EncodeBlank r |
| 562 | + ((' '=r)/r)←⊂'%20' |
| 563 | + ∊r |
| 564 | + ∇ |
| 565 | + |
462 | 566 | :EndClass |
0 commit comments