From patchwork Wed Mar 15 12:51:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nicolas Graves X-Patchwork-Id: 48035 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id EC46C16B5A; Wed, 15 Mar 2023 12:54:04 +0000 (GMT) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=MAILING_LIST_MULTI, RCVD_IN_MSPIKE_H2,SPF_HELO_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.6 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id 8D76C16C76 for ; Wed, 15 Mar 2023 12:54:00 +0000 (GMT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pcQbs-0003PF-PH; Wed, 15 Mar 2023 08:52:04 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pcQbr-0003OL-3M for guix-patches@gnu.org; Wed, 15 Mar 2023 08:52:03 -0400 Received: from debbugs.gnu.org ([209.51.188.43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pcQbq-00038K-Re for guix-patches@gnu.org; Wed, 15 Mar 2023 08:52:02 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1pcQbq-0001Y3-Hc for guix-patches@gnu.org; Wed, 15 Mar 2023 08:52:02 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#62202] [PATCH 01/21] import: juliahub: first script draft. References: <871qlq89kz.fsf@ngraves.fr> In-Reply-To: <871qlq89kz.fsf@ngraves.fr> Resent-From: Nicolas Graves Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Wed, 15 Mar 2023 12:52:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 62202 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 62202@debbugs.gnu.org Cc: ngraves@ngraves.fr Received: via spool by 62202-submit@debbugs.gnu.org id=B62202.16788847055811 (code B ref 62202); Wed, 15 Mar 2023 12:52:02 +0000 Received: (at 62202) by debbugs.gnu.org; 15 Mar 2023 12:51:45 +0000 Received: from localhost ([127.0.0.1]:39290 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1pcQbW-0001VO-0I for submit@debbugs.gnu.org; Wed, 15 Mar 2023 08:51:45 -0400 Received: from 12.mo550.mail-out.ovh.net ([87.98.162.229]:37163) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1pcQbS-0001VD-SL for 62202@debbugs.gnu.org; Wed, 15 Mar 2023 08:51:40 -0400 Received: from director7.ghost.mail-out.ovh.net (unknown [10.109.156.73]) by mo550.mail-out.ovh.net (Postfix) with ESMTP id 790D8260F8 for <62202@debbugs.gnu.org>; Wed, 15 Mar 2023 12:51:37 +0000 (UTC) Received: from ghost-submission-6684bf9d7b-r6rck (unknown [10.111.208.134]) by director7.ghost.mail-out.ovh.net (Postfix) with ESMTPS id CDC3A1FE59; Wed, 15 Mar 2023 12:51:35 +0000 (UTC) Received: from ngraves.fr ([37.59.142.108]) by ghost-submission-6684bf9d7b-r6rck with ESMTPSA id 44hPNVe/EWSQBgAA9fVuhw (envelope-from ); Wed, 15 Mar 2023 12:51:35 +0000 Authentication-Results: garm.ovh; auth=pass (GARM-108S002b48fa032-bfe0-4244-9314-0f7f72124386, F74D9BBE9ED44B45FF66447495DD0B0753EB5D4A) smtp.auth=ngraves@ngraves.fr X-OVh-ClientIp: 81.67.140.142 Date: Wed, 15 Mar 2023 13:51:10 +0100 Message-Id: <20230315125130.23041-1-ngraves@ngraves.fr> X-Mailer: git-send-email 2.39.2 MIME-Version: 1.0 X-Ovh-Tracer-Id: 13788051735402439394 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: 0 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedvhedrvddvkedggeefucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucenucfjughrpefhvfevufffkffogggtgfesthekredtredtjeenucfhrhhomheppfhitgholhgrshcuifhrrghvvghsuceonhhgrhgrvhgvshesnhhgrhgrvhgvshdrfhhrqeenucggtffrrghtthgvrhhnpeelvdetleduhffgtdefffeltddugffhhffftddvieelueefffelheffgfejtdfgleenucffohhmrghinhepghhnuhdrohhrghdpjhhulhhirghhuhgsrdgtohhmpdhjuhhlihgrhhhusgdrohhrghenucfkphepuddvjedrtddrtddruddpfeejrdehledrudegvddruddtkeenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepihhnvghtpeduvdejrddtrddtrddupdhmrghilhhfrhhomhepoehnghhrrghvvghssehnghhrrghvvghsrdhfrheqpdhnsggprhgtphhtthhopedupdhrtghpthhtohepiedvvddtvdesuggvsggsuhhgshdrghhnuhdrohhrghdpoffvtefjohhsthepmhhoheehtddpmhhouggvpehsmhhtphhouhht X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: Nicolas Graves X-ACL-Warn: , Nicolas Graves via Guix-patches X-Patchwork-Original-From: Nicolas Graves via Guix-patches via From: Nicolas Graves Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org X-getmail-retrieved-from-mailbox: Patches --- guix/import/go.scm | 6 +- guix/import/juliahub.scm | 183 +++++++++++++++++++++++++++++++ guix/scripts/import.scm | 2 +- guix/scripts/import/juliahub.scm | 107 ++++++++++++++++++ 4 files changed, 295 insertions(+), 3 deletions(-) create mode 100644 guix/import/juliahub.scm create mode 100644 guix/scripts/import/juliahub.scm diff --git a/guix/import/go.scm b/guix/import/go.scm index 69937f8a4d..f264715fbd 100644 --- a/guix/import/go.scm +++ b/guix/import/go.scm @@ -503,9 +503,11 @@ (define (transform-version version) '(string-append "v" version) '(go-version->git-ref version)))) -(define (vcs->origin vcs-type vcs-repo-url version) +(define* (vcs->origin vcs-type vcs-repo-url version + #:optional transform-version) "Generate the `origin' block of a package depending on what type of source -control system is being used." +control system is being used. Optionally use the function TRANSFORM-VERSION +which takes version as an input." (case vcs-type ((git) (git->origin vcs-repo-url `(tag-or-commit . ,version) transform-version)) diff --git a/guix/import/juliahub.scm b/guix/import/juliahub.scm new file mode 100644 index 0000000000..efe6abbb24 --- /dev/null +++ b/guix/import/juliahub.scm @@ -0,0 +1,183 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2023 Nicolas Graves +;;; +;;; 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 . + +(define-module (guix import juliahub) + #:use-module (ice-9 textual-ports) + #:use-module (ice-9 regex) + #:use-module (ice-9 match) + #:use-module (ice-9 string-fun) + #:use-module (srfi srfi-9) + #:use-module (srfi srfi-1) + #:use-module (guix http-client) + #:use-module (guix import utils) + #:use-module (guix import json) + #:use-module (guix base16) + #:use-module (guix base32) + #:use-module (guix packages) + #:use-module (guix upstream) + #:use-module (json) + #:use-module ((guix licenses) #:prefix license:) + + #:export (juliahub->guix-package)) + +(define (juliahub-uri name) + (let* ((url (string-append "https://docs.juliahub.com/" name "/")) + (port (http-fetch url #:text? #t)) + (_ (get-line port)) + (meta (get-line port)) + (regex "url=[a-zA-Z0-9]{5}\\/[0-9\\.]*") + (redirect (match:substring (string-match regex meta)))) + (close-port port) + (string-drop redirect 4))) + +(define (juliahub-url name) + (let* ((url (string-append "https://docs.juliahub.com/" name "/")) + (uri (juliahub-uri name))) + (string-append url uri "/"))) + +(define (juliahub-slug-version name) + (let* ((uri (juliahub-uri name)) + (slug (string-take uri 5)) + (latest-version (string-drop uri 6))) + `(,slug ,latest-version))) + +(define (json->juliahub-direct-dependencies vector) + (if (vector? vector) + (filter-map + (lambda (el) + (let ((dep (json->juliahub-dependency el))) + (if (juliahub-dependency-direct? dep) + dep + #f))) + (vector->list vector)))) + +;; Julia package. +(define-json-mapping make-juliahub-package juliahub-package? + json->juliahub-package + (homepage juliahub-package-homepage) ;string + (readme juliahub-package-readme) ;string + ;; (slug juliahub-package-slug) ;string + (version juliahub-package-version) ;string + (description juliahub-package-description) ;string + (dependencies + juliahub-package-dependencies "deps" + json->juliahub-direct-dependencies) ;list of + ;; (lambda (vector) + ;; (map json->juliahub-dependency (vector->list vector)))) + (url juliahub-package-url) ;string + (uuid juliahub-package-uuid) ;string + (license juliahub-package-license)) ;string + +(define-json-mapping + make-juliahub-dependency juliahub-dependency? + json->juliahub-dependency + (direct? juliahub-dependency-direct? "direct") ;boolean + (name juliahub-dependency-name) ;string + (uuid juliahub-dependency-uuid) ;string + (versions juliahub-dependency-versions "versions" vector->list)) ;list of strings + ;; (slug juliahub-dependency-slug) ;string + +(define (julia-name->guix-name name) + (string-append "julia-" (snake-case name))) + +(define* (juliahub-fetch name #:key (version #f)) + "Return a record for package NAME, or #f on failure." + (and=> (json-fetch (string-append (juliahub-url name) "pkg.json")) + json->juliahub-package)) + +(define (make-julia-sexp name version uri hash home-page synopsis description + dependencies licenses) + "Return the `package' s-expression for a Julia package with the given NAME, +VERSION, URI, HASH, HOME-PAGE, DESCRIPTION, DEPENDENCIES, and LICENSES." + `(package + (name ,(julia-name->guix-name name)) + (version ,version) + (source (origin + (method url-fetch) + (uri ,uri) + (sha256 + (base32 + "0sjjj9z1dhilhpc8pq4154czrb79z9cm044jvn75kxcjv6v5l2m5" + ;; ,(bytevector->nix-base32-string hash) + )))) + (build-system julia-build-system) + ,@(if (null? dependencies) + '() + `((inputs + (list ,@(map (compose julia-name->guix-name juliahub-dependency-name) + dependencies))))) + (synopsis ,synopsis) + (description ,description) + (home-page ,home-page) + (license ,(match licenses + (() #f) + ((license) (license->symbol license)) + (_ `(list ,@(map license->symbol licenses))))))) + +(define* (juliahub->guix-package package-name + #:key version #:allow-other-keys) + "Fetch the metadata for PACKAGE-NAME from juliahub.org, and return the +`package' s-expression corresponding to that package, or #f on failure. +Optionally include a VERSION string to fetch a specific version juliahub." + (let ((package (if version + (juliahub-fetch package-name version) + (juliahub-fetch package-name)))) + (if package + (let* ((dependencies-names + (map juliahub-dependency-name + (juliahub-package-dependencies package))) + (licenses + (map spdx-string->license + (list (juliahub-package-license package))))) + (values (make-julia-sexp + package-name + (juliahub-package-version package) + (juliahub-package-url package) + "0sjjj9z1dhilhpc8pq4154czrb79z9cm044jvn75kxcjv6v5l2m5" + (juliahub-package-homepage package) + (juliahub-package-description package) + (beautify-description (juliahub-package-readme package)) + (juliahub-package-dependencies package) + licenses) + dependencies-names)) + (values #f '())))) + +(define* (import-release package #:key (version #f)) + "Return an for the latest release of PACKAGE." + (let* ((package-name (guix-package->juliahub-name package)) + (package (juliahub-fetch package-name)) + (version (or version (juliahub-version gem))) + (url (rubyjuliahubs-uri gem-name version))) + (upstream-source + (package (package-name package)) + (version version) + (urls (list url))))) + +(define %juliahub-updater + (upstream-updater + (name 'juliahub) + (description "Updater for Juliahub packages") + (pred juliahub-package?) + (import import-release))) + +(define* (juliahub-recursive-import package-name #:optional version) + (recursive-import package-name + #:repo '() + #:repo->guix-package juliahub->guix-package + #:guix-name ruby-package-name + #:version version)) diff --git a/guix/scripts/import.scm b/guix/scripts/import.scm index f84a964a53..ef4e0b9cc6 100644 --- a/guix/scripts/import.scm +++ b/guix/scripts/import.scm @@ -47,7 +47,7 @@ (define %standard-import-options '()) (define importers '("gnu" "pypi" "cpan" "hackage" "stackage" "egg" "elpa" "gem" "go" "cran" "crate" "texlive" "json" "opam" - "minetest" "elm" "hexpm")) + "minetest" "elm" "hexpm" "juliahub")) (define (resolve-importer name) (let ((module (resolve-interface diff --git a/guix/scripts/import/juliahub.scm b/guix/scripts/import/juliahub.scm new file mode 100644 index 0000000000..1317c67aa3 --- /dev/null +++ b/guix/scripts/import/juliahub.scm @@ -0,0 +1,107 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2023 Nicolas Graves +;;; +;;; 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 . + +(define-module (guix scripts import juliahub) + #:use-module (guix ui) + #:use-module (guix utils) + #:use-module (guix scripts) + #:use-module (guix import juliahub) + #:use-module (guix scripts import) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-11) + #:use-module (srfi srfi-37) + #:use-module (ice-9 match) + #:use-module (ice-9 format) + #:use-module (ice-9 receive) + #:export (guix-import-juliahub)) + + +;;; +;;; Command-line options. +;;; + +(define %default-options + '()) + +(define (show-help) + (display (G_ "Usage: guix import juliahub PACKAGE-NAME[@VERSION] Import and +convert the Julia package for PACKAGE-NAME. Optionally, a version can be +specified after the at-sign (@) character.\n")) + (display (G_ " + -h, --help display this help and exit")) + (display (G_ " + -V, --version display version information and exit")) + (display (G_ " + -r, --recursive generate package expressions for all Gem packages\ + that are not yet in Guix")) + (newline) + (show-bug-report-information)) + +(define %options + ;; Specification of the command-line options. + (cons* (option '(#\h "help") #f #f + (lambda args + (show-help) + (exit 0))) + (option '(#\V "version") #f #f + (lambda args + (show-version-and-exit "guix import gem"))) + (option '(#\r "recursive") #f #f + (lambda (opt name arg result) + (alist-cons 'recursive #t result))) + %standard-import-options)) + + +;;; +;;; Entry point. +;;; + +(define (guix-import-juliahub . args) + (define (parse-options) + ;; Return the alist of option values. + (parse-command-line args %options (list %default-options) + #:build-options? #f)) + + (let* ((opts (parse-options)) + (args (filter-map (match-lambda + (('argument . value) + value) + (_ #f)) + (reverse opts)))) + (match args + ((spec) + (receive (package-name package-version) + (package-name->name+version spec) + (let ((code (if (assoc-ref opts 'recursive) + (map (match-lambda + ((and ('package ('name name) . rest) pkg) + `(define-public ,(string->symbol name) + ,pkg)) + (_ #f)) + (juliahub-recursive-import package-name package-version)) + (let ((sexp (juliahub->guix-package package-name #:version package-version))) + (if sexp sexp #f))))) + (match code + ((or #f '(#f)) + (leave (G_ "failed to download meta-data for package '~a'~%") + package-name)) + (_ code))))) + (() + (leave (G_ "too few arguments~%"))) + ((many ...) + (leave (G_ "too many arguments~%"))))))