guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

01/02: hydra: Add 'build-package-metadata.scm' script.


From: Ludovic Courtès
Subject: 01/02: hydra: Add 'build-package-metadata.scm' script.
Date: Wed, 4 Jan 2023 16:06:22 -0500 (EST)

civodul pushed a commit to branch master
in repository maintenance.

commit 318db3eedf70806cc4e058e37e3cc6c07594ff6e
Author: Ludovic Courtès <ludo@gnu.org>
AuthorDate: Wed Jan 4 18:18:21 2023 +0100

    hydra: Add 'build-package-metadata.scm' script.
    
    This program produces the 'packages.json' and 'sources.json' files that
    are published at https://guix.gnu.org.
    
    So far those files were built as part of the web site's build process,
    via Haunt.  This script is adapted from the (apps packages builder)
    module of the web site.
    
    * hydra/build-package-metadata.scm: New file.
---
 hydra/build-package-metadata.scm | 227 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 227 insertions(+)

diff --git a/hydra/build-package-metadata.scm b/hydra/build-package-metadata.scm
new file mode 100755
index 0000000..9683db7
--- /dev/null
+++ b/hydra/build-package-metadata.scm
@@ -0,0 +1,227 @@
+#!/usr/bin/env -S guix repl --
+!#
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2020, 2021 Simon Tournier <zimon.toutoune@gmail.com>
+;;; Copyright © 2023 Ludovic Courtès <ludo@gnu.org>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix 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 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix 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.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Build package metadata: 'packages.json', for package metadata, and
+;;; 'sources.json', for source code metadata.
+
+(use-modules (gnu packages)
+             (guix packages)
+             (guix channels)
+             (guix diagnostics)
+             (guix i18n)
+             (guix utils)
+             (guix gexp)
+             ((guix build download) #:select (maybe-expand-mirrors))
+             ((guix base64) #:select (base64-encode))
+             ((guix describe) #:select (current-profile))
+             ((guix config) #:select (%guix-version))
+             (guix download)
+             (guix git-download)
+             (guix svn-download)
+             (guix hg-download)
+             (json)
+             (web uri)
+             (ice-9 match)
+             (ice-9 vlist)
+             (srfi srfi-1)
+             (srfi srfi-26))
+
+(define (all-packages)             ;XXX: copied form 'etc/source-manifest.scm'
+  "Return the list of all the packages, public or private, omitting only
+superseded packages."
+  (fold-packages (lambda (package lst)
+                   (match (package-replacement package)
+                     (#f (cons package lst))
+                     (replacement
+                      (append (list replacement package) lst))))
+                 '()
+                 #:select? (negate package-superseded)))
+
+(define (all-origins)              ;XXX: copied form 'etc/source-manifest.scm'
+  "Return the list of origins referred to by all the packages."
+  (let loop ((packages (all-packages))
+             (origins  '())
+             (visited   vlist-null))
+    (match packages
+      ((head . tail)
+       (let ((new (remove (cut vhash-assq <> visited)
+                          (package-direct-sources head))))
+         (loop tail (append new origins)
+               (fold (cut vhash-consq <> #t <>)
+                     visited new))))
+      (()
+       origins))))
+
+;;; Required by 'origin->json' for 'computed-origin-method' corner cases
+(define gexp-references (@@ (guix gexp) gexp-references))
+
+(define (origin->json origin)
+  "Return a list of JSON representations (an alist) of ORIGIN."
+  (define method
+    (origin-method origin))
+
+  (define uri
+    (origin-uri origin))
+
+  (define (resolve urls)
+    (map uri->string
+         (append-map (cut maybe-expand-mirrors <> %mirrors)
+                     (map string->uri urls))))
+
+  (if (eq? method (@@ (guix packages) computed-origin-method))
+      ;; Packages in gnu/packages/gnuzilla.scm and gnu/packages/linux.scm
+      ;; represent their 'uri' as 'promise'.
+      (match uri
+        ((? promise? promise)
+         (match (force promise)
+           ((? gexp? g)
+            (append-map origin->json
+                        (filter-map (match-lambda
+                                      ((? gexp-input? thing)
+                                       (match (gexp-input-thing thing)
+                                         ((? origin? o) o)
+                                         (_ #f)))
+                                      (_ #f))
+                                    (gexp-references g))))
+           (_ `((type . #nil))))))
+      ;; Regular packages represent 'uri' as string.
+      `((("type" . ,(cond ((or (eq? url-fetch method)
+                               (eq? url-fetch/tarbomb method)
+                               (eq? url-fetch/zipbomb method)) 'url)
+                          ((eq? git-fetch method) 'git)
+                          ((or (eq? svn-fetch method)
+                               (eq? svn-multi-fetch method)) 'svn)
+                          ((eq? hg-fetch method) 'hg)
+                          (else                   #nil)))
+         ,@(cond ((or (eq? url-fetch method)
+                      (eq? url-fetch/tarbomb method)
+                      (eq? url-fetch/zipbomb method))
+                  `(("urls" . ,(list->vector
+                                (resolve
+                                 (match uri
+                                   ((? string? url) (list url))
+                                   ((urls ...) urls)))))))
+                 ((eq? git-fetch method)
+                  `(("git_url" . ,(git-reference-url uri))))
+                 ((eq? svn-fetch method)
+                  `(("svn_url" . ,(svn-reference-url uri))))
+                 ((eq? svn-multi-fetch method)
+                  `(("svn_url" . ,(svn-multi-reference-url uri))))
+                 ((eq? hg-fetch method)
+                  `(("hg_url" . ,(hg-reference-url uri))))
+                 (else '()))
+         ,@(if (or (eq? url-fetch method)
+                   (eq? url-fetch/tarbomb method)
+                   (eq? url-fetch/zipbomb method))
+               (let* ((content-hash (origin-hash origin))
+                      (hash-value (content-hash-value content-hash))
+                      (hash-algorithm (content-hash-algorithm content-hash))
+                      (algorithm-string (symbol->string hash-algorithm)))
+                 `(("integrity" . ,(string-append algorithm-string "-"
+                                                  (base64-encode 
hash-value)))))
+               '())
+         ,@(if (eq? method git-fetch)
+               `(("git_ref" . ,(git-reference-commit uri)))
+               '())
+         ,@(if (eq? method svn-fetch)
+               `(("svn_revision" . ,(svn-reference-revision uri)))
+               '())
+         ,@(if (eq? method svn-multi-fetch)
+               `(("svn_revision" . ,(svn-multi-reference-revision uri)))
+               '())
+         ,@(if (eq? method hg-fetch)
+               `(("hg_changeset" . ,(hg-reference-changeset uri)))
+               '())))))
+
+(define (package->json package)
+  (define cpe-name
+    (assoc-ref (package-properties package) 'cpe-name))
+  (define cpe-version
+    (assoc-ref (package-properties package) 'cpe-version))
+
+  `(("name"     . ,(package-name package))
+    ("version"  . ,(package-version package))
+    ,@(if cpe-name `(("cpe_name" . ,cpe-name)) '())
+    ,@(if cpe-version `(("cpe_version" . ,cpe-version)) '())
+    ,@(if (origin? (package-source package))
+          `(("source" . ,(list->vector
+                          (origin->json (package-source package)))))
+          '())
+    ("synopsis" . ,(package-synopsis package))
+    ,@(if (package-home-page package)
+          `(("homepage" . ,(package-home-page package)))
+          '())
+    ,@(match (package-location package)
+        ((? location? location)
+         `(("location"
+            . ,(string-append (location-file location) ":"
+                              (number->string
+                               (+ 1 (location-line location)))))))
+        (#f
+         '()))))
+
+
+(define (sources-json)
+  "Return JSON (an alist) listing all the sources."
+  ;; The Software Heritage format is described here:
+  ;; 
https://forge.softwareheritage.org/source/swh-loader-core/browse/master/swh/loader/package/nixguix/tests/data/https_nix-community.github.io/nixpkgs-swh_sources.json
+  ;; And the loader is implemented here:
+  ;; 
https://forge.softwareheritage.org/source/swh-loader-core/browse/master/swh/loader/package/nixguix/
+  `(("sources" . ,(list->vector (append-map origin->json (all-origins))))
+    ("version" . "1")
+    ("revision" .
+     ,(match (current-profile)
+        (#f %guix-version)                        ;for lack of a better ID
+        (profile
+         (let ((channel (find guix-channel? (profile-channels profile))))
+           (channel-commit channel)))))))
+
+(define (packages-json)
+  "Return JSON (an alist) listing all the packages."
+  (list->vector (map package->json (all-packages))))
+
+(define (write-json json file)
+  "Serialize JSON to FILE."
+  (with-atomic-file-output file
+    (lambda (port)
+      (scm->json json port))))
+
+
+;;;
+;;; Entry point.
+;;;
+
+(define-public (main . args)
+  (match args
+    ((_ directory)
+     (info (G_ "package metadata will be written to '~a'~%") directory)
+     (for-each (lambda (thunk file)
+                 (write-json (thunk)
+                             (string-append directory "/" file)))
+               (list packages-json sources-json)
+               '("packages.json" "sources.json")))
+    ((command . _)
+     (leave (G_ "Usage: ~a DIRECTORY
+
+Write 'packages.json' and 'sources.json' files to DIRECTORY.\n")
+            (basename command)))))
+
+(apply main (command-line))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]