aboutsummaryrefslogtreecommitdiff
path: root/guix-qa-frontpage/view/branch.scm
diff options
context:
space:
mode:
Diffstat (limited to 'guix-qa-frontpage/view/branch.scm')
-rw-r--r--guix-qa-frontpage/view/branch.scm239
1 files changed, 239 insertions, 0 deletions
diff --git a/guix-qa-frontpage/view/branch.scm b/guix-qa-frontpage/view/branch.scm
new file mode 100644
index 0000000..c68a1b9
--- /dev/null
+++ b/guix-qa-frontpage/view/branch.scm
@@ -0,0 +1,239 @@
+(define-module (guix-qa-frontpage view branch)
+ #:use-module (srfi srfi-1)
+ #:use-module (ice-9 match)
+ #:use-module (guix-qa-frontpage manage-builds)
+ #:use-module (guix-qa-frontpage view util)
+ #:export (branch-view))
+
+(define (branch-view branch derivation-changes)
+ (define (builds-by-system-excluding-cross-builds side)
+ (fold (lambda (package result)
+ (fold
+ (lambda (change result)
+ (if (string=? (assoc-ref change "target")
+ "")
+ (let ((system (assoc-ref change "system")))
+ `((,system
+ . ,(append
+ (map
+ (lambda (build)
+ `(,@build
+ ("package"
+ . (("name" . ,(assoc-ref package "name"))
+ ("version" . ,(assoc-ref package "version"))))))
+ (vector->list (assoc-ref change "builds")))
+ (or (assoc-ref result system)
+ '())))
+ ,@(alist-delete system result)))
+ result))
+ result
+ (vector->list
+ (assoc-ref package side))))
+ '()
+ derivation-changes))
+
+ (define* (package-derivations-comparison-link system
+ #:key build-change)
+ (let ((revisions
+ (assoc-ref change-details "revisions")))
+ (string-append
+ (simple-format #f "https://data.qa.guix.gnu.org/compare/package-derivations?base_commit=~A&target_commit=~A&system=~A&target=none"
+ (assoc-ref (assoc-ref revisions "base")
+ "commit")
+ (assoc-ref (assoc-ref revisions "target")
+ "commit")
+ system)
+ (if build-change
+ (simple-format #f "&build_change=~A" build-change)
+ ""))))
+
+ (define (categorise-builds all-systems builds-by-system)
+ (define (package-eq? a b)
+ (and
+ (string=?
+ (assoc-ref a "name")
+ (assoc-ref b "name"))
+ (string=?
+ (assoc-ref a "version")
+ (assoc-ref b "version"))))
+
+ (define (group-builds-by-package builds)
+ (fold
+ (lambda (build result)
+ (let ((package (assoc-ref build "package")))
+ `((,package . ,(cons
+ build
+ (or
+ (and=> (find (match-lambda
+ ((p . _)
+ (package-eq? p package)))
+ result)
+ cdr)
+ '())))
+ ,@(remove
+ (match-lambda
+ ((p . _)
+ (package-eq? p package)))
+ result))))
+ '()
+ builds))
+
+ (define systems
+ (map car builds-by-system))
+
+ (map
+ (match-lambda
+ ((system . builds)
+ (let ((builds-by-package
+ (group-builds-by-package builds)))
+ (cons
+ system
+ (fold
+ (match-lambda*
+ (((package . builds) result)
+ (let* ((build-statuses
+ (map (lambda (build)
+ (assoc-ref build "status"))
+ builds))
+ (category
+ (cond
+ ((member "succeeded" build-statuses)
+ 'succeeding)
+ ((and (not (member "suceeded" build-statuses))
+ (member "failed" build-statuses))
+ 'failing)
+ (else
+ 'unknown))))
+
+ `((,category . ,(cons
+ (cons package builds)
+ (assq-ref result category)))
+ ,@(alist-delete category result)))))
+ '((succeeding . ())
+ (failing . ())
+ (unknown . ()))
+ builds-by-package)))))
+
+ (append builds-by-system
+ (map (lambda (system)
+ (cons system '()))
+ (filter (lambda (system)
+ (not (member system systems)))
+ all-systems)))))
+
+ (layout
+ #:title (simple-format #f "Branch ~A" branch)
+ #:body
+ `((main
+
+
+ (div
+ (table
+ (@ (style "border-collapse: collapse;"))
+ (thead
+ (tr
+ (th (@ (rowspan 3)) "System")
+ (th (@ (colspan 6)) "Package build status")
+ (th))
+ (tr
+ (th (@ (colspan 3)) "Base")
+ (th (@ (colspan 3)) "With patches applied")
+ (th))
+ (tr
+ (th (@ (style "min-width: 5rem;"))
+ "Succeeding")
+ (th (@ (style "min-width: 5rem;"))
+ "Failing")
+ (th (@ (style "min-width: 5rem;"))
+ "Unknown")
+ (th (@ (style "min-width: 5rem;"))
+ "Succeeding")
+ (th (@ (style "min-width: 5rem;"))
+ "Failing")
+ (th (@ (style "min-width: 5rem;"))
+ "Unknown")
+ (th)))
+ (tbody
+ ,@(if derivation-changes
+ (let* ((base-builds
+ (builds-by-system-excluding-cross-builds "base"))
+ (target-builds
+ (builds-by-system-excluding-cross-builds "target"))
+
+ (all-systems
+ (delete-duplicates
+ (append (map car base-builds)
+ (map car target-builds))))
+
+ (categorised-base-builds-by-system
+ (categorise-builds all-systems base-builds))
+ (categorised-target-builds-by-system
+ (categorise-builds all-systems target-builds)))
+
+ (if (null? target-builds)
+ `((tr
+ (td (@ (colspan 7))
+ "No package derivation changes")))
+ (map
+ (match-lambda
+ ((system . categorised-target-builds)
+ (let ((categorised-base-builds
+ (assoc-ref categorised-base-builds-by-system
+ system))
+ (highlighed-common
+ " "))
+ (define (count side status)
+ (length
+ (assoc-ref
+ (if (eq? side 'base)
+ categorised-base-builds
+ categorised-target-builds)
+ status)))
+
+ `(tr
+ (td (@ (class "monospace")) ,system)
+ ,@(map (lambda (status)
+ `(td ,(count 'base status)))
+ '(succeeding failing unknown))
+ (td ,@(if (and (>= (count 'target 'succeeding)
+ (count 'base 'succeeding))
+ (> (count 'target 'succeeding)
+ 0))
+ `((@ (class "good")))
+ '())
+ ,(count 'target 'succeeding))
+ ,(if (> (count 'target 'failing)
+ (count 'base 'failing))
+ `(td (@ (class "bad"))
+ (a ;; (@ (href ,(package-derivations-comparison-link
+ ;; system
+ ;; #:build-change "broken")))
+ ,(count 'target 'failing)))
+ `(td ,(count 'target 'failing)))
+ ,(if (> (count 'target 'unknown)
+ (count 'base 'unknown))
+ `(td (@ (class "bad"))
+ (a ;; (@ (href ,(package-derivations-comparison-link
+ ;; system
+ ;; #:build-change "unknown")))
+ ,(count 'target 'unknown)))
+ `(td ,(count 'target 'unknown)))
+ (td (a ;; (@ (href
+ ;; ,(package-derivations-comparison-link system)))
+ "View comparison"))))))
+ (sort
+ categorised-target-builds-by-system
+ (lambda (a b)
+ (< (or (list-index
+ (lambda (s)
+ (string=? (car a) s))
+ %systems-to-submit-builds-for)
+ 10)
+ (or (list-index
+ (lambda (s)
+ (string=? (car b) s))
+ %systems-to-submit-builds-for)
+ 10)))))))
+ '((tr
+ (td (@ (colspan 7))
+ "Comparison unavailable")))))))))))