mirror of
https://git.in.rschanz.org/ryan77627/guix.git
synced 2024-12-25 05:48:07 -05:00
ci: Properly construct URLs.
Implement a new function "api-url", which constructs URLs using relative URI and "resolve-uri-reference" (which implements the algorithm specified in RFC 3986 section 5.2.2) for building the URL, instead of just appending strings. This avoids issued if the server-url ends with a slash. Since "api-url" uses URI-objects, it makes sense to also construct the query-part of the URL here. For this "api-url" accepts optional key-value-pairs. New function "json-api-fetch" is a wrapper using "api-url". * guix/ci.scm (api-url): New function. (build): Use it. (json-api-fetch): New function. (queued-builds, latest-builds, evaluation, latest-evaluations, evaluation-jobs: Use it.
This commit is contained in:
parent
ccdf7b8006
commit
3ee0f170c8
1 changed files with 49 additions and 33 deletions
82
guix/ci.scm
82
guix/ci.scm
|
@ -20,9 +20,12 @@
|
|||
(define-module (guix ci)
|
||||
#:use-module (guix http-client)
|
||||
#:use-module (guix utils)
|
||||
#:use-module ((guix build download)
|
||||
#:select (resolve-uri-reference))
|
||||
#:use-module (json)
|
||||
#:use-module (srfi srfi-1)
|
||||
#:use-module (ice-9 match)
|
||||
#:use-module (web uri)
|
||||
#:use-module (guix i18n)
|
||||
#:use-module (guix diagnostics)
|
||||
#:autoload (guix channels) (channel)
|
||||
|
@ -146,16 +149,44 @@ (define %query-limit
|
|||
;; Max number of builds requested in queries.
|
||||
1000)
|
||||
|
||||
(define* (api-url base-url path #:rest query)
|
||||
"Build a proper API url, taking into account BASE-URL's trailing slashes.
|
||||
QUERY takes any number of '(\"name\" value) 2-element lists, with VALUE being
|
||||
either a string or a number (which will be converted to a string). If VALUE
|
||||
is #f, the respective element will not be added to the query parameters.
|
||||
Other types of VALUE will raise an error since this low-level function is
|
||||
api-agnostic."
|
||||
|
||||
(define (build-query-string query)
|
||||
(let lp ((query (or (reverse query) '())) (acc '()))
|
||||
(match query
|
||||
(() (string-concatenate acc))
|
||||
(((_ #f) . rest) (lp rest acc))
|
||||
(((name val) . rest)
|
||||
(lp rest (cons*
|
||||
name "="
|
||||
(if (string? val) (uri-encode val) (number->string val))
|
||||
(if (null? acc) "" "&")
|
||||
acc))))))
|
||||
|
||||
(let* ((query-string (build-query-string query))
|
||||
(base (string->uri base-url))
|
||||
(ref (build-relative-ref #:path path #:query query-string)))
|
||||
(resolve-uri-reference ref base)))
|
||||
|
||||
(define (json-fetch url)
|
||||
(let* ((port (http-fetch url))
|
||||
(json (json->scm port)))
|
||||
(close-port port)
|
||||
json))
|
||||
|
||||
(define* (json-api-fetch base-url path #:rest query)
|
||||
(json-fetch (apply api-url base-url path query)))
|
||||
|
||||
(define* (queued-builds url #:optional (limit %query-limit))
|
||||
"Return the list of queued derivations on URL."
|
||||
(let ((queue (json-fetch (string-append url "/api/queue?nr="
|
||||
(number->string limit)))))
|
||||
(let ((queue
|
||||
(json-api-fetch url "/api/queue" `("nr" ,limit))))
|
||||
(map json->build (vector->list queue))))
|
||||
|
||||
(define* (latest-builds url #:optional (limit %query-limit)
|
||||
|
@ -163,28 +194,21 @@ (define* (latest-builds url #:optional (limit %query-limit)
|
|||
"Return the latest builds performed by the CI server at URL. If EVALUATION
|
||||
is an integer, restrict to builds of EVALUATION. If SYSTEM is true (a system
|
||||
string such as \"x86_64-linux\"), restrict to builds for SYSTEM."
|
||||
(define* (option name value #:optional (->string identity))
|
||||
(if value
|
||||
(string-append "&" name "=" (->string value))
|
||||
""))
|
||||
|
||||
(let ((latest (json-fetch (string-append url "/api/latestbuilds?nr="
|
||||
(number->string limit)
|
||||
(option "evaluation" evaluation
|
||||
number->string)
|
||||
(option "system" system)
|
||||
(option "job" job)
|
||||
(option "status" status
|
||||
number->string)))))
|
||||
(let ((latest (json-api-fetch
|
||||
url "/api/latestbuilds"
|
||||
`("nr" ,limit)
|
||||
`("evaluation" ,evaluation)
|
||||
`("system" ,system)
|
||||
`("job" ,job)
|
||||
`("status" ,status))))
|
||||
;; Note: Hydra does not provide a "derivation" field for entries in
|
||||
;; 'latestbuilds', but Cuirass does.
|
||||
(map json->build (vector->list latest))))
|
||||
|
||||
(define (evaluation url evaluation)
|
||||
"Return the given EVALUATION performed by the CI server at URL."
|
||||
(let ((evaluation (json-fetch
|
||||
(string-append url "/api/evaluation?id="
|
||||
(number->string evaluation)))))
|
||||
(let ((evaluation
|
||||
(json-api-fetch url "/api/evaluation" `("id" ,evaluation))))
|
||||
(json->evaluation evaluation)))
|
||||
|
||||
(define* (latest-evaluations url
|
||||
|
@ -192,16 +216,10 @@ (define* (latest-evaluations url
|
|||
#:key spec)
|
||||
"Return the latest evaluations performed by the CI server at URL. If SPEC
|
||||
is passed, only consider the evaluations for the given SPEC specification."
|
||||
(let ((spec (if spec
|
||||
(format #f "&spec=~a" spec)
|
||||
"")))
|
||||
(map json->evaluation
|
||||
(vector->list
|
||||
(json->scm
|
||||
(http-fetch
|
||||
(string-append url "/api/evaluations?nr="
|
||||
(number->string limit)
|
||||
spec)))))))
|
||||
(map json->evaluation
|
||||
(vector->list
|
||||
(json-api-fetch
|
||||
url "/api/evaluations" `("nr" ,limit) `("spec" ,spec)))))
|
||||
|
||||
(define* (evaluations-for-commit url commit #:optional (limit %query-limit))
|
||||
"Return the evaluations among the latest LIMIT evaluations that have COMMIT
|
||||
|
@ -216,16 +234,14 @@ (define (evaluation-jobs url evaluation-id)
|
|||
"Return the list of jobs of evaluation EVALUATION-ID."
|
||||
(map json->job
|
||||
(vector->list
|
||||
(json->scm (http-fetch
|
||||
(string-append url "/api/jobs?evaluation="
|
||||
(number->string evaluation-id)))))))
|
||||
(json-api-fetch url "/api/jobs" `("evaluation" ,evaluation-id)))))
|
||||
|
||||
(define (build url id)
|
||||
"Look up build ID at URL and return it. Raise &http-get-error if it is not
|
||||
found (404)."
|
||||
(json->build
|
||||
(http-fetch (string-append url "/build/" ;note: no "/api" here
|
||||
(number->string id)))))
|
||||
(http-fetch (api-url url (string-append "/build/" ;note: no "/api" here
|
||||
(number->string id))))))
|
||||
|
||||
(define (job-build url job)
|
||||
"Return the build associated with JOB."
|
||||
|
|
Loading…
Reference in a new issue