From patchwork Thu Nov 2 15:04:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Graves X-Patchwork-Id: 55831 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 C67B927BBEA; Thu, 2 Nov 2023 15:17:14 +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.9 required=5.0 tests=BAYES_00,MAILING_LIST_MULTI, SPF_HELO_PASS autolearn=ham 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 3B06227BBE2 for ; Thu, 2 Nov 2023 15:17:13 +0000 (GMT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qyZR0-0007Z4-B7; Thu, 02 Nov 2023 11:16:38 -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 1qyZQu-0007Xm-8e for guix-patches@gnu.org; Thu, 02 Nov 2023 11:16:34 -0400 Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qyZQt-0002OS-8I for guix-patches@gnu.org; Thu, 02 Nov 2023 11:16:31 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1qyZRS-0006WJ-7L for guix-patches@gnu.org; Thu, 02 Nov 2023 11:17:06 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#42338] [PATCH 9/9] gnu: composer-build-system: Full check phase rewrite. Resent-From: Nicolas Graves Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Thu, 02 Nov 2023 15:17:06 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 42338 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 42338@debbugs.gnu.org Cc: ngraves@ngraves.fr Received: via spool by 42338-submit@debbugs.gnu.org id=B42338.169893818224925 (code B ref 42338); Thu, 02 Nov 2023 15:17:06 +0000 Received: (at 42338) by debbugs.gnu.org; 2 Nov 2023 15:16:22 +0000 Received: from localhost ([127.0.0.1]:55751 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qyZQj-0006Tu-Iu for submit@debbugs.gnu.org; Thu, 02 Nov 2023 11:16:22 -0400 Received: from 10.mo576.mail-out.ovh.net ([46.105.73.241]:42317) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qyZQf-0006T1-Dj for 42338@debbugs.gnu.org; Thu, 02 Nov 2023 11:16:18 -0400 Received: from director2.ghost.mail-out.ovh.net (unknown [10.109.146.175]) by mo576.mail-out.ovh.net (Postfix) with ESMTP id 3C4982C822 for <42338@debbugs.gnu.org>; Thu, 2 Nov 2023 15:15:40 +0000 (UTC) Received: from ghost-submission-6684bf9d7b-dv48j (unknown [10.110.208.218]) by director2.ghost.mail-out.ovh.net (Postfix) with ESMTPS id 7B14F1FE81; Thu, 2 Nov 2023 15:15:40 +0000 (UTC) Received: from ngraves.fr ([37.59.142.95]) by ghost-submission-6684bf9d7b-dv48j with ESMTPSA id wQXxGhy9Q2WVJgAA8wfQ9g (envelope-from ); Thu, 02 Nov 2023 15:15:40 +0000 Authentication-Results: garm.ovh; auth=pass (GARM-95G0011f1c6534-6a77-47fc-94cb-b1f951337a60, 1761E107A7246F2314AE904A186E6A889A3776EC) smtp.auth=ngraves@ngraves.fr X-OVh-ClientIp: 87.88.157.103 Date: Thu, 2 Nov 2023 16:04:29 +0100 Message-ID: <20231102151523.30581-10-ngraves@ngraves.fr> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231102151523.30581-1-ngraves@ngraves.fr> References: <20231102151523.30581-1-ngraves@ngraves.fr> MIME-Version: 1.0 X-Ovh-Tracer-Id: 13626766575565333218 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: 0 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedvkedruddtiedgjeegucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucenucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefpihgtohhlrghsucfirhgrvhgvshcuoehnghhrrghvvghssehnghhrrghvvghsrdhfrheqnecuggftrfgrthhtvghrnhepleffjeetueethfefkeffffefvddukeejkefgleduiedthfekvefhiedvhfffgeegnecukfhppeduvdejrddtrddtrddupdekjedrkeekrdduheejrddutdefpdefjedrheelrddugedvrdelheenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepihhnvghtpeduvdejrddtrddtrddupdhmrghilhhfrhhomhepoehnghhrrghvvghssehnghhrrghvvghsrdhfrheqpdhnsggprhgtphhtthhopedupdhrtghpthhtohepgedvfeefkeesuggvsggsuhhgshdrghhnuhdrohhrghdpoffvtefjohhsthepmhhoheejiedpmhhouggvpehsmhhtphhouhht 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 Change-Id: I824b27b925cd718ee83ef6b2ee4a8a1e69455de6 --- guix/build-system/composer.scm | 2 + guix/build/composer-build-system.scm | 239 ++++++++++++++++----------- 2 files changed, 148 insertions(+), 93 deletions(-) diff --git a/guix/build-system/composer.scm b/guix/build-system/composer.scm index 8bf99ff9c5..7d2ad2b398 100644 --- a/guix/build-system/composer.scm +++ b/guix/build-system/composer.scm @@ -107,6 +107,7 @@ (define* (composer-build name inputs (composer-file "composer.json") (tests? #t) (test-target "test") + (test-flags ''()) (install-target "install") (validate-runpath? #t) (patch-shebangs? #t) @@ -140,6 +141,7 @@ (define builder #:composer-file #$composer-file #:tests? #$tests? #:test-target #$test-target + #:test-flags #$test-flags #:install-target #$install-target #:validate-runpath? #$validate-runpath? #:patch-shebangs? #$patch-shebangs? diff --git a/guix/build/composer-build-system.scm b/guix/build/composer-build-system.scm index bcbae27021..6f05801ad1 100644 --- a/guix/build/composer-build-system.scm +++ b/guix/build/composer-build-system.scm @@ -53,9 +53,22 @@ (define (if-specified-to-list fn) (define-json-mapping make-composer-autoload composer-autoload? json->composer-autoload - (psr-4 composer-autoload-psr-4 "psr-4" (if-specified-to-list identity)) + (psr-4 composer-autoload-psr-4 "psr-4" + (match-lambda + ((? unspecified?) '()) + ((? (lambda (al) + (and (list? al) (pair? (car al)) (vector? (cdar al)))) al) + (append-map + (lambda (vect-el) + (list (cons (caar al) vect-el))) + (vector->list (cdar al)))) + ((? list? l) l) + (_ '()))) + (psr-0 composer-autoload-psr-0 "psr-0" (if-specified-to-list identity)) (classmap composer-autoload-classmap "classmap" - (if-specified-to-list vector->list))) + (if-specified-to-list vector->list)) + (files composer-autoload-files "files" + (if-specified-to-list vector->list))) (define-json-mapping make-composer-package composer-package? json->composer-package @@ -76,65 +89,57 @@ (define* (read-package-data #:key (filename "composer.json")) (lambda (port) (json->composer-package (json->scm port))))) -(define* (check #:key composer-file inputs outputs tests? test-target #:allow-other-keys) - "Test the given package." +(define* (create-test-autoload #:key composer-file inputs outputs tests? + #:allow-other-keys) + "Create the autoload.php file for tests. This is a standalone phase so that +the autoload.php file can be edited before the check phase." (when tests? (mkdir-p "vendor") (create-autoload (string-append (getcwd) "/vendor") composer-file - (append inputs outputs) #:dev-dependencies? #t) - (let* ((package-data (read-package-data #:filename composer-file)) - (scripts (composer-package-scripts package-data)) - (test-script (assoc-ref scripts test-target)) - (dependencies (composer-package-require package-data)) - (dependencies-dev (composer-package-dev-require package-data)) - (name (composer-package-name package-data))) - (for-each - (match-lambda - ((_ . input) - (let ((bin (find-php-bin input))) - (when bin - (copy-recursively bin "vendor/bin"))))) - inputs) - (match test-script - ((? string? command) - (unless (zero? (system command)) - (throw 'failed-command command))) - (('@ (? string? command) ...) - (for-each - (lambda (c) - (unless (zero? (system c)) - (throw 'failed-command c))) - command)) - (#f (invoke "vendor/bin/phpunit")))))) + inputs #:dev-dependencies? #t))) -(define (find-php-bin input) - (let* ((web-dir (string-append input "/share/web")) - (vendors (if (file-exists? web-dir) - (find-files web-dir "^vendor$" #:directories? #t) - #f))) - (match vendors - ((vendor) - (let ((bin (string-append vendor "/bin"))) - (and (file-exists? bin) bin))) - (_ #f)))) +(define (find-bin script inputs) + (search-input-file inputs + (string-append + "bin/" + (string-drop script (string-length "vendor/bin/"))))) -(define (find-php-dep inputs dependency) - (let loop ((inputs inputs)) - (match inputs - (() (throw 'unsatisfied-dependency "Unsatisfied dependency: required " - dependency)) - (((_ . input) inputs ...) - (let ((autoload (string-append input "/share/web/" dependency - "/vendor/autoload_conf.php"))) - (if (file-exists? autoload) - autoload - (loop inputs)))) - ((input inputs ...) - (let ((autoload (string-append input "/share/web/" dependency - "/vendor/autoload_conf.php"))) - (if (file-exists? autoload) - autoload - (loop inputs))))))) +(define* (check #:key composer-file inputs + tests? test-target test-flags #:allow-other-keys) + "Test the given package. +Please note that none of the PHP packages at the time of the rewrite of the +build-system did use the test-script field. This means that the @code{match +test-script} part is not tested on a real example and relies on the original +implementation." + (if tests? + (let* ((package-data (read-package-data #:filename composer-file)) + (scripts (composer-package-scripts package-data)) + (test-script (assoc-ref scripts test-target))) + (match test-script + ((? string? bin) + (let ((command (find-bin bin inputs))) + (unless (zero? (apply system command test-flags)) + (throw 'failed-command command)))) + (('@ (? string? bins) ...) + (for-each + (lambda (c) + (let ((command (find-bin bin inputs))) + (unless (zero? (apply system command test-flags)) + (throw 'failed-command command)))) + bins)) + (_ (if (file-exists? "phpunit.xml.dist") + (apply invoke + (with-exception-handler + (lambda (exn) + (if (search-error? exn) + (error "\ +Missing php-phpunit-phpunit native input.~%") + (raise exn))) + (lambda () + (search-input-file (or inputs '()) "bin/phpunit"))) + test-flags)) + (format #t "No test suite found.~%")))) + (format #t "Test suite not run.~%"))) (define* (create-autoload vendor composer-file inputs #:key dev-dependencies?) "creates an autoload.php file that sets up the class locations for this package, @@ -144,15 +149,14 @@ (define* (create-autoload vendor composer-file inputs #:key dev-dependencies?) (display (string-append " $path) { - $loader->set($namespace, $path); -} -foreach ($psr4map as $namespace => $path) { - $loader->setPsr4($namespace, $path); +foreach ($psr4map as $namespace => $paths) { + foreach ($paths as $path) { + $loader->addPsr4($namespace, $path); + } } $loader->addClassMap($classmap); $loader->register(); @@ -170,37 +174,85 @@ (define* (create-autoload vendor composer-file inputs #:key dev-dependencies?) (format #t "// autoload_conf.php @generated by Guix~%") (force-output) (for-each - (lambda (psr4) - (match psr4 - ((key . value) - (format #t "$psr4map['~a'] = '~a/../~a';~%" - (string-join (string-split key #\\) "\\\\") - vendor value)))) + (match-lambda + ((key . value) + (let ((vals (if (list? value) + (reverse value) + (list value)))) + (apply + format + #t + (string-append + "$psr4map['~a'][] = [" + (string-join + (make-list (length vals) "'~a/../~a'") ",") + "];~%") + (cons* (string-join (string-split key #\\) "\\\\") + (append-map (lambda (v) (list vendor v)) vals))))) + (_ (format #t ""))) + (merge-duplicates (append - (composer-autoload-psr-4 autoload) - (if dev-dependencies? - (composer-autoload-psr-4 autoload-dev) - '()))) + (composer-autoload-psr-4 autoload) + (if (and dev-dependencies? (not (null? autoload-dev))) + (composer-autoload-psr-4 autoload-dev) + '())) + '())) (for-each - (lambda (classmap) - (for-each - (lambda (file) - (invoke "php" (assoc-ref inputs "findclass.php") - "-i" (string-append vendor "/..") "-f" file)) - (find-files classmap ".(php|hh|inc)$"))) - (append - (composer-autoload-classmap autoload) - (if dev-dependencies? - (composer-autoload-classmap autoload-dev) - '()))) + (lambda (psr0) + (match psr0 + ((key . value) + (format #t "$psr4map['~a'][] = ['~a/../~a/~a'];~%" + (string-join (string-split key #\\) "\\\\") + vendor + value + (string-join (string-split key #\\) "/"))) + (_ (format #t "")))) + (append + (composer-autoload-psr-0 autoload) + (if (and dev-dependencies? (not (null? autoload-dev))) + (composer-autoload-psr-0 autoload-dev) + '()))) (for-each - (lambda (dep) - (format #t "require_once '~a';~%" (find-php-dep inputs dep))) - (append - dependencies - (if dev-dependencies? - dependencies-dev - '()))))))) + (lambda (classmap) + (for-each + (lambda (file) + (invoke "php" (assoc-ref inputs "findclass.php") + "-i" (string-append vendor "/..") "-f" file)) + (find-files classmap ".(php|hh|inc)$"))) + (append + (composer-autoload-classmap autoload) + (if (and dev-dependencies? (not (null? autoload-dev))) + (composer-autoload-classmap autoload-dev) + '()))) + (for-each + (lambda (file) + (format #t "require_once '~a/../~a';~%" vendor file)) + (append + (composer-autoload-files autoload) + (if (and dev-dependencies? (not (null? autoload-dev))) + (composer-autoload-files autoload-dev) + '()))) + (for-each + (lambda (dep) + (format + #t "require_once '~a';~%" + (search-input-file + inputs + (string-append "/share/web/" dep "/vendor/autoload_conf.php")))) + dependencies) + ;; Also add native-inputs that are not necessarily given in the + ;; composer.json. This allows to simply add a package in tests by + ;; adding it in native-inputs, without the need to patch composer.json. + (for-each + (match-lambda + ((name . loc) + (match (find-files loc "autoload_conf\\.php$") + (() #t) + (((? string? conf) . ()) + (format #t "require_once '~a';~%" conf)) + (_ #t))) + (_ #t)) + (or inputs '())))))) (define* (install #:key inputs outputs composer-file #:allow-other-keys) "Install the given package." @@ -237,7 +289,8 @@ (define %standard-phases (delete 'build) (delete 'check) (replace 'install install) - (add-after 'install 'check check))) + (add-after 'install 'check check) + (add-after 'install 'create-test-autoload create-test-autoload))) (define* (composer-build #:key inputs (phases %standard-phases) #:allow-other-keys #:rest args)