[PATCH] Add composer build system (PHP)

OpenSubmitted by Julien Lepiller.
Details
4 participants
  • db
  • Julien Lepiller
  • Ludovic Courtès
  • Maxim Cournoyer
Owner
unassigned
Severity
normal
J
J
Julien Lepiller wrote on 13 Jul 2020 00:20
(address . guix-patches@gnu.org)
20200713002055.1553f136@tachikoma.lepiller.eu
Hi Guix!
This patch series adds the composer-build-system, along with animporter and an updater (first 3 patches).
The patch series also adds some php packages for phpunit and itsdependencies.
The patches are available in my composer branch athttps://framagit.org/tyreunom/guix/-/tree/composer
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 01/34] guix: import: Add composer importer.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-1-julien@lepiller.eu
* guix/import/composer.scm: New file.* guix/scripts/import/composer.scm: New file.* Makefile.am: Add them.* guix/scripts/import.scm: Add composer importer.--- Makefile.am | 2 + guix/import/composer.scm | 252 +++++++++++++++++++++++++++++++ guix/scripts/import.scm | 2 +- guix/scripts/import/composer.scm | 107 +++++++++++++ 4 files changed, 362 insertions(+), 1 deletion(-) create mode 100644 guix/import/composer.scm create mode 100644 guix/scripts/import/composer.scm
Toggle diff (406 lines)diff --git a/Makefile.am b/Makefile.amindex 20d43cd130..623ddf32b2 100644--- a/Makefile.am+++ b/Makefile.am@@ -219,6 +219,7 @@ MODULES = \ guix/search-paths.scm \ guix/packages.scm \ guix/import/cabal.scm \+ guix/import/composer.scm \ guix/import/cpan.scm \ guix/import/cran.scm \ guix/import/crate.scm \@@ -265,6 +266,7 @@ MODULES = \ guix/scripts/system/reconfigure.scm \ guix/scripts/lint.scm \ guix/scripts/challenge.scm \+ guix/scripts/import/composer.scm \ guix/scripts/import/crate.scm \ guix/scripts/import/cran.scm \ guix/scripts/import/elpa.scm \diff --git a/guix/import/composer.scm b/guix/import/composer.scmnew file mode 100644index 0000000000..0e17eb0487--- /dev/null+++ b/guix/import/composer.scm@@ -0,0 +1,252 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2019 Julien Lepiller <julien@lepiller.eu>+;;;+;;; 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/>.++(define-module (guix import composer)+ #:use-module (ice-9 match)+ #:use-module (json)+ #:use-module (gcrypt hash)+ #:use-module (guix base32)+ #:use-module (guix build git)+ #:use-module (guix build utils)+ #:use-module (guix build-system)+ #:use-module (guix import json)+ #:use-module (guix import utils)+ #:use-module ((guix licenses) #:prefix license:)+ #:use-module (guix packages)+ #:use-module (guix serialization)+ #:use-module (guix upstream)+ #:use-module (guix utils)+ #:use-module (srfi srfi-1)+ #:use-module (srfi srfi-11)+ #:export (composer->guix-package+ %composer-updater+ composer-recursive-import))++;; XXX adapted from (guix scripts hash)+(define (file-hash file select? recursive?)+ ;; Compute the hash of FILE.+ (if recursive?+ (let-values (((port get-hash) (open-sha256-port)))+ (write-file file port #:select? select?)+ (force-output port)+ (get-hash))+ (call-with-input-file file port-sha256)))++;; XXX taken from (guix scripts hash)+(define (vcs-file? file stat)+ (case (stat:type stat)+ ((directory)+ (member (basename file) '(".bzr" ".git" ".hg" ".svn" "CVS")))+ ((regular)+ ;; Git sub-modules have a '.git' file that is a regular text file.+ (string=? (basename file) ".git"))+ (else+ #f)))++(define (latest-version versions)+ (fold (lambda (a b) (if (version>? a b) a b)) (car versions) versions))++(define (fix-version version)+ "Return a fixed version from a version string. For instance, v10.1 -> 10.1"+ (cond+ ((string-prefix? "version" version)+ (if (char-set-contains? char-set:digit (string-ref version 7))+ (substring version 7)+ (substring version 8)))+ ((string-prefix? "v" version)+ (substring version 1))+ (else version)))++(define* (composer-fetch name #:optional version)+ "Return an alist representation of the Composer metadata for the package NAME,+or #f on failure."+ (let ((package (json-fetch+ (string-append "https://repo.packagist.org/p/" name ".json"))))+ (if package+ (let* ((packages (assoc-ref package "packages"))+ (package (assoc-ref packages name))+ (versions (filter+ (lambda (version)+ (and (not (string-contains version "dev"))+ (not (string-contains version "beta"))))+ (map car package)))+ (versions (map+ (lambda (version)+ (cons (fix-version version) version))+ versions))+ (version (or (if (null? version) #f version)+ (latest-version (map car versions)))))+ (assoc-ref package (assoc-ref versions version)))+ #f)))++(define (php-package-name name)+ "Given the NAME of a package on Packagist, return a Guix-compliant name for+the package."+ (let ((name (string-join (string-split name #\/) "-")))+ (if (string-prefix? "php-" name)+ (snake-case name)+ (string-append "php-" (snake-case name)))))++(define (make-php-sexp name version home-page description dependencies+ dev-dependencies licenses source)+ "Return the `package' s-expression for a PHP package with the given NAME,+VERSION, HOME-PAGE, DESCRIPTION, DEPENDENCIES, LICENSES and SOURCE."+ (let ((git? (equal? (assoc-ref source "type") "git")))+ ((if git? call-with-temporary-directory call-with-temporary-output-file)+ (lambda* (temp #:optional port)+ (and (if git?+ (begin+ (mkdir-p temp)+ (git-fetch (assoc-ref source "url")+ (assoc-ref source "reference")+ temp))+ (url-fetch (assoc-ref source "url") temp))+ `(package+ (name ,(php-package-name name))+ (version ,version)+ (source (origin+ ,@(if git?+ `((method git-fetch)+ (uri (git-reference+ (url ,(assoc-ref source "url"))+ (commit ,(assoc-ref source "reference"))))+ (file-name (git-file-name name version))+ (sha256+ (base32+ ,(bytevector->nix-base32-string+ (file-hash temp (negate vcs-file?) #t)))))+ `((method url-fetch)+ (uri ,(assoc-ref source "url"))+ (sha256 (base32 ,(guix-hash-url temp)))))))+ (build-system composer-build-system)+ ,@(if (null? dependencies)+ '()+ `((inputs+ (,'quasiquote+ ,(map (lambda (name)+ `(,name+ (,'unquote+ ,(string->symbol name))))+ dependencies)))))+ ,@(if (null? dev-dependencies)+ '()+ `((native-inputs+ (,'quasiquote+ ,(map (lambda (name)+ `(,name+ (,'unquote+ ,(string->symbol name))))+ dev-dependencies)))))+ (synopsis "")+ (description ,description)+ (home-page ,home-page)+ (license ,(match licenses+ (() #f)+ ((license) (license->symbol license))+ (_ `(list ,@(map license->symbol licenses)))))))))))++(define* (composer->guix-package package-name #:optional version)+ "Fetch the metadata for PACKAGE-NAME from packagist.org, and return the+`package' s-expression corresponding to that package, or #f on failure."+ (let ((package (composer-fetch package-name version)))+ (and package+ (let* ((name (assoc-ref package "name"))+ (version (fix-version (assoc-ref package "version")))+ (description (beautify-description+ (assoc-ref package "description")))+ (home-page (assoc-ref package "homepage"))+ (dependencies-names (filter+ (lambda (dep)+ (string-contains dep "/"))+ (map car (assoc-ref package "require"))))+ (dependencies (map php-package-name dependencies-names))+ (require-dev (assoc-ref package "require-dev"))+ (dev-dependencies-names+ (if require-dev+ (filter+ (lambda (dep)+ (string-contains dep "/"))+ (map car require-dev))+ '()))+ (dev-dependencies (map php-package-name dev-dependencies-names))+ (licenses (map string->license+ (vector->list+ (assoc-ref package "license")))))+ (values (make-php-sexp name version home-page description dependencies+ dev-dependencies licenses (assoc-ref package "source"))+ (append dependencies-names dev-dependencies-names))))))++(define (guix-name->composer-name name)+ "Given a guix package name, return the name of the package in Packagist."+ (if (string-prefix? "php-" name)+ (let ((components (string-split (substring name 4) #\-)))+ (match components+ ((namespace name ...)+ (string-append namespace "/" (string-join name "-")))))+ name))++(define (guix-package->composer-name package)+ "Given a Composer PACKAGE built from Packagist, return the name of the+package in Packagist."+ (let ((upstream-name (assoc-ref+ (package-properties package)+ 'upstream-name))+ (name (package-name package)))+ (if upstream-name+ upstream-name+ (guix-name->composer-name name))))++(define (string->license str)+ "Convert the string STR into a license object."+ (match str+ ("GNU LGPL" license:lgpl2.0)+ ("GPL" license:gpl3)+ ((or "BSD" "BSD License" "BSD-3-Clause") license:bsd-3)+ ((or "MIT" "MIT license" "Expat license") license:expat)+ ("Public domain" license:public-domain)+ ((or "Apache License, Version 2.0" "Apache 2.0") license:asl2.0)+ (_ #f)))++(define (php-package? package)+ "Return true if PACKAGE is a PHP package from Packagist."+ (and+ (eq? (build-system-name (package-build-system package)) 'composer)+ (string-prefix? "php-" (package-name package))))++(define (latest-release package)+ "Return an <upstream-source> for the latest release of PACKAGE."+ (let* ((php-name (guix-package->composer-name package))+ (metadata (composer-fetch php-name))+ (version (fix-version (assoc-ref metadata "version")))+ (url (assoc-ref (assoc-ref metadata "source") "url")))+ (upstream-source+ (package (package-name package))+ (version version)+ (urls (list url)))))++(define %composer-updater+ (upstream-updater+ (name 'composer)+ (description "Updater for Composer packages")+ (pred php-package?)+ (latest latest-release)))++(define* (composer-recursive-import package-name #:optional version)+ (recursive-import package-name '()+ #:repo->guix-package composer->guix-package+ #:guix-name php-package-name))diff --git a/guix/scripts/import.scm b/guix/scripts/import.scmindex c6cc93fad8..4c91627283 100644--- a/guix/scripts/import.scm+++ b/guix/scripts/import.scm@@ -76,7 +76,7 @@ rather than \\n." ;;; (define importers '("gnu" "nix" "pypi" "cpan" "hackage" "stackage" "elpa" "gem"- "cran" "crate" "texlive" "json" "opam"))+ "cran" "crate" "texlive" "json" "opam" "composer")) (define (resolve-importer name) (let ((module (resolve-interfacediff --git a/guix/scripts/import/composer.scm b/guix/scripts/import/composer.scmnew file mode 100644index 0000000000..412bae6318--- /dev/null+++ b/guix/scripts/import/composer.scm@@ -0,0 +1,107 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2015 David Thompson <davet@gnu.org>+;;; Copyright © 2018 Oleg Pykhalov <go.wigust@gmail.com>+;;;+;;; 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/>.++(define-module (guix scripts import composer)+ #:use-module (guix ui)+ #:use-module (guix utils)+ #:use-module (guix scripts)+ #:use-module (guix import composer)+ #:use-module (guix scripts import)+ #:use-module (srfi srfi-1)+ #:use-module (srfi srfi-11)+ #:use-module (srfi srfi-37)+ #:use-module (srfi srfi-41)+ #:use-module (ice-9 match)+ #:use-module (ice-9 format)+ #:export (guix-import-composer))++ +;;;+;;; Command-line options.+;;;++(define %default-options+ '())++(define (show-help)+ (display (G_ "Usage: guix import composer PACKAGE-NAME+Import and convert the Composer package for PACKAGE-NAME.\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 Composer 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 composer")))+ (option '(#\r "recursive") #f #f+ (lambda (opt name arg result)+ (alist-cons 'recursive #t result)))+ %standard-import-options))++ +;;;+;;; Entry point.+;;;++(define (guix-import-composer . args)+ (define (parse-options)+ ;; Return the alist of option values.+ (args-fold* args %options+ (lambda (opt name arg result)+ (leave (G_ "~A: unrecognized option~%") name))+ (lambda (arg result)+ (alist-cons 'argument arg result))+ %default-options))++ (let* ((opts (parse-options))+ (args (filter-map (match-lambda+ (('argument . value)+ value)+ (_ #f))+ (reverse opts))))+ (match args+ ((package-name)+ (if (assoc-ref opts 'recursive)+ (map (match-lambda+ ((and ('package ('name name) . rest) pkg)+ `(define-public ,(string->symbol name)+ ,pkg))+ (_ #f))+ (composer-recursive-import package-name))+ (let ((sexp (composer->guix-package package-name)))+ (unless sexp+ (leave (G_ "failed to download meta-data for package '~a'~%")+ package-name))+ sexp)))+ (()+ (leave (G_ "too few arguments~%")))+ ((many ...)+ (leave (G_ "too many arguments~%"))))))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 02/34] gnu: Add composer-classloader.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-2-julien@lepiller.eu
* gnu/packages/php-xyz.scm: New file.* gnu/local.mk (GNU_SYSTEM_MODULES): Add it.--- gnu/local.mk | 1 + gnu/packages/php-xyz.scm | 61 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 gnu/packages/php-xyz.scm
Toggle diff (81 lines)diff --git a/gnu/local.mk b/gnu/local.mkindex 3046a840c9..90d1b1302b 100644--- a/gnu/local.mk+++ b/gnu/local.mk@@ -424,6 +424,7 @@ GNU_SYSTEM_MODULES = \ %D%/packages/photo.scm \ %D%/packages/phabricator.scm \ %D%/packages/php.scm \+ %D%/packages/php-xyz.scm \ %D%/packages/pkg-config.scm \ %D%/packages/plotutils.scm \ %D%/packages/poedit.scm \diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmnew file mode 100644index 0000000000..dab660f84f--- /dev/null+++ b/gnu/packages/php-xyz.scm@@ -0,0 +1,61 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2019 Julien Lepiller <julien@lepiller.eu>+;;;+;;; 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/>.++(define-module (gnu packages php-xyz)+ #:use-module (gnu packages)+ #:use-module (gnu packages php)+ #:use-module (guix packages)+ #:use-module (guix download)+ #:use-module (guix git-download)+ #:use-module (guix build-system composer)+ #:use-module (guix build-system gnu)+ #:use-module (guix utils)+ #:use-module ((guix licenses) #:prefix license:))++(define-public composer-classloader+ (package+ (name "composer-classloader")+ (version "1.9.0")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/composer/composer.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "0127zmmg3yx84ljngfs86q7kjhyypybkf4d1ihfrfnzgynzxfxdf"))))+ (build-system gnu-build-system)+ (arguments+ `(#:phases+ (modify-phases %standard-phases+ (delete 'configure)+ (delete 'build)+ (delete 'check)+ (replace 'install+ (lambda* (#:key outputs #:allow-other-keys)+ (let* ((out (assoc-ref outputs "out"))+ (install (string-append out "/share/web/composer/ClassLoader.php")))+ (mkdir-p (dirname install))+ (copy-file "src/Composer/Autoload/ClassLoader.php" install)))))))+ (home-page "https://getcomposer.org")+ (synopsis "PHP class loader extracted from the composer package")+ (description "This package contains the class loader class used by Composer to+build its autoloading feature. This package is used by the composer-build-system+to build its own store-aware autoloading feature.")+ (license license:expat)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 03/34] guix: Add composer-build-system.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-3-julien@lepiller.eu
* guix/build-system/composer.scm: New file.* guix/build/composer-build-system.scm: New file.* guix/build-system/findclass.php: New file.* Makefile.am: Add them.* doc/guix.texi (Build Systems): Document it.--- Makefile.am | 2 + doc/guix.texi | 14 ++ guix/build-system/composer.scm | 169 ++++++++++++++++++++ guix/build-system/findclass.php | 102 ++++++++++++ guix/build/composer-build-system.scm | 224 +++++++++++++++++++++++++++ 5 files changed, 511 insertions(+) create mode 100644 guix/build-system/composer.scm create mode 100644 guix/build-system/findclass.php create mode 100644 guix/build/composer-build-system.scm
Toggle diff (560 lines)diff --git a/Makefile.am b/Makefile.amindex 623ddf32b2..363af872fa 100644--- a/Makefile.am+++ b/Makefile.am@@ -117,6 +117,7 @@ MODULES = \ guix/build-system/cargo.scm \ guix/build-system/clojure.scm \ guix/build-system/cmake.scm \+ guix/build-system/composer.scm \ guix/build-system/dub.scm \ guix/build-system/dune.scm \ guix/build-system/emacs.scm \@@ -164,6 +165,7 @@ MODULES = \ guix/build/cargo-build-system.scm \ guix/build/cargo-utils.scm \ guix/build/cmake-build-system.scm \+ guix/build/composer-build-system.scm \ guix/build/dub-build-system.scm \ guix/build/dune-build-system.scm \ guix/build/emacs-build-system.scm \diff --git a/doc/guix.texi b/doc/guix.texiindex 17338ed764..0613f669a0 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -6687,6 +6687,20 @@ debugging information''), which roughly means that code is compiled with @code{-O2 -g}, as is the case for Autoconf-based packages by default. @end defvr +@defvr {Scheme Variable} composer-build-system+This variable is exported by @code{(guix build-system composer)}. It+implements the build procedure for packages using+@url{https://getcomposer.org/, Composer}, the PHP package manager.++It automatically adds the @code{php} package to the set of inputs. Which+package is used can be specified with the @code{#:php} parameter.++The @code{#:test-target} parameter is used to control which script is run+for the tests. By default, the @code{test} script is run if it exists. If+the script does not exist, the build system will run @code{phpunit} from the+source directory, assuming there is a @file{phpunit.xml} file.+@end defvr+ @defvr {Scheme Variable} dune-build-system This variable is exported by @code{(guix build-system dune)}. It supports builds of packages using @uref{https://dune.build/, Dune}, a builddiff --git a/guix/build-system/composer.scm b/guix/build-system/composer.scmnew file mode 100644index 0000000000..19455b1920--- /dev/null+++ b/guix/build-system/composer.scm@@ -0,0 +1,169 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2019 Julien Lepiller <julien@lepiller.eu>+;;;+;;; 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/>.+(define-module (guix build-system composer)+ #:use-module (guix store)+ #:use-module (guix utils)+ #:use-module (guix derivations)+ #:use-module (guix search-paths)+ #:use-module (guix build-system)+ #:use-module (guix build-system gnu)+ #:use-module (guix gexp)+ #:use-module (guix packages)+ #:use-module (ice-9 match)+ #:use-module (srfi srfi-1)+ #:export (%composer-build-system-modules+ lower+ composer-build+ composer-build-system))++;; Commentary:+;;+;; Standard build procedure for PHP packages using Composer. This is implemented+;; as an extension of `gnu-build-system'.+;;+;; Code:++(define (default-php)+ "Return the default PHP package."++ ;; Do not use `@' to avoid introducing circular dependencies.+ (let ((module (resolve-interface '(gnu packages php))))+ (module-ref module 'php)))++(define (default-findclass)+ "Return the default findclass script."+ (local-file (string-append (current-source-directory) "/findclass.php")))++(define (default-composer-classloader)+ "Return the default composer-classloader package."++ ;; Do not use `@' to avoid introducing circular dependencies.+ (let ((module (resolve-interface '(gnu packages php-xyz))))+ (module-ref module 'composer-classloader)))++(define %composer-build-system-modules+ ;; Build-side modules imported by default.+ `((guix build composer-build-system)+ (guix build json)+ (guix build union)+ ,@%gnu-build-system-modules))++(define* (lower name+ #:key source inputs native-inputs outputs system target+ (php (default-php))+ (composer-classloader (default-composer-classloader))+ (findclass (default-findclass))+ #:allow-other-keys+ #:rest arguments)+ "Return a bag for NAME."+ (define private-keywords+ '(#:source #:target #:php #:composer-classloader #:findclass #:inputs #:native-inputs))++ (and (not target) ;XXX: no cross-compilation+ (bag+ (name name)+ (system system)+ (host-inputs `(,@(if source+ `(("source" ,source))+ '())+ ,@inputs++ ;; Keep the standard inputs of 'gnu-build-system'.+ ,@(standard-packages)))+ (build-inputs `(("php" ,php)+ ("findclass.php" ,findclass)+ ("composer-classloader" ,composer-classloader)+ ,@native-inputs))+ (outputs outputs)+ (build composer-build)+ (arguments (strip-keyword-arguments private-keywords arguments)))))++(define* (composer-build store name inputs+ #:key (guile #f)+ (outputs '("out")) (configure-flags ''())+ (search-paths '())+ (out-of-source? #t)+ (composer-file "composer.json")+ (tests? #t)+ (test-target "test")+ (install-target "install")+ (validate-runpath? #t)+ (patch-shebangs? #t)+ (strip-binaries? #t)+ (strip-flags ''("--strip-debug"))+ (strip-directories ''("lib" "lib64" "libexec"+ "bin" "sbin"))+ (phases '(@ (guix build composer-build-system)+ %standard-phases))+ (system (%current-system))+ (imported-modules %composer-build-system-modules)+ (modules '((guix build composer-build-system)+ (guix build json)+ (guix build utils))))+ "Build SOURCE using PHP, and with INPUTS. This assumes that SOURCE provides+a 'composer.json' file as its build system."+ (define builder+ `(begin+ (use-modules ,@modules)+ (composer-build #:source ,(match (assoc-ref inputs "source")+ (((? derivation? source))+ (derivation->output-path source))+ ((source)+ source)+ (source+ source))+ #:system ,system+ #:outputs %outputs+ #:inputs %build-inputs+ #:search-paths ',(map search-path-specification->sexp+ search-paths)+ #:phases ,phases+ #:out-of-source? ,out-of-source?+ #:composer-file ,composer-file+ #:tests? ,tests?+ #:test-target ,test-target+ #:install-target ,install-target+ #:validate-runpath? ,validate-runpath?+ #:patch-shebangs? ,patch-shebangs?+ #:strip-binaries? ,strip-binaries?+ #:strip-flags ,strip-flags+ #:strip-directories ,strip-directories)))++ (define guile-for-build+ (match guile+ ((? package?)+ (package-derivation store guile system #:graft? #f))+ (#f ; the default+ (let* ((distro (resolve-interface '(gnu packages commencement)))+ (guile (module-ref distro 'guile-final)))+ (package-derivation store guile system #:graft? #f)))))++ (build-expression->derivation store name builder+ #:system system+ #:inputs inputs+ #:modules imported-modules+ #:outputs outputs+ #:guile-for-build guile-for-build))++(define composer-build-system+ (build-system+ (name 'composer)+ (description "The standard Composer build system")+ (lower lower)))++;;; composer.scm ends herediff --git a/guix/build-system/findclass.php b/guix/build-system/findclass.phpnew file mode 100644index 0000000000..a9704f809c--- /dev/null+++ b/guix/build-system/findclass.php@@ -0,0 +1,102 @@+<?php+/**+ * Extract the classes in the given file+ *+ * @param string $path The file to check+ * @throws \RuntimeException+ * @return array The found classes+ */+function findClasses($path)+{+ $extraTypes = PHP_VERSION_ID < 50400 ? '' : '|trait';+ if (defined('HHVM_VERSION') && version_compare(HHVM_VERSION, '3.3', '>=')) {+ $extraTypes .= '|enum';+ }+ // Use @ here instead of Silencer to actively suppress 'unhelpful' output+ // @link https://github.com/composer/composer/pull/4886+ $contents = @php_strip_whitespace($path);+ if (!$contents) {+ if (!file_exists($path)) {+ $message = 'File at "%s" does not exist, check your classmap definitions';+ } elseif (!is_readable($path)) {+ $message = 'File at "%s" is not readable, check its permissions';+ } elseif ('' === trim(file_get_contents($path))) {+ // The input file was really empty and thus contains no classes+ return array();+ } else {+ $message = 'File at "%s" could not be parsed as PHP, it may be binary or corrupted';+ }+ $error = error_get_last();+ if (isset($error['message'])) {+ $message .= PHP_EOL . 'The following message may be helpful:' . PHP_EOL . $error['message'];+ }+ throw new \RuntimeException(sprintf($message, $path));+ }+ // return early if there is no chance of matching anything in this file+ if (!preg_match('{\b(?:class|interface'.$extraTypes.')\s}i', $contents)) {+ return array();+ }+ // strip heredocs/nowdocs+ $contents = preg_replace('{<<<[ \t]*([\'"]?)(\w+)\\1(?:\r\n|\n|\r)(?:.*?)(?:\r\n|\n|\r)(?:\s*)\\2(?=\s+|[;,.)])}s', 'null', $contents);+ // strip strings+ $contents = preg_replace('{"[^"\\\\]*+(\\\\.[^"\\\\]*+)*+"|\'[^\'\\\\]*+(\\\\.[^\'\\\\]*+)*+\'}s', 'null', $contents);+ // strip leading non-php code if needed+ if (substr($contents, 0, 2) !== '<?') {+ $contents = preg_replace('{^.+?<\?}s', '<?', $contents, 1, $replacements);+ if ($replacements === 0) {+ return array();+ }+ }+ // strip non-php blocks in the file+ $contents = preg_replace('{\?>(?:[^<]++|<(?!\?))*+<\?}s', '?><?', $contents);+ // strip trailing non-php code if needed+ $pos = strrpos($contents, '?>');+ if (false !== $pos && false === strpos(substr($contents, $pos), '<?')) {+ $contents = substr($contents, 0, $pos);+ }+ // strip comments if short open tags are in the file+ if (preg_match('{(<\?)(?!(php|hh))}i', $contents)) {+ $contents = preg_replace('{//.* | /\*(?:[^*]++|\*(?!/))*\*/}x', '', $contents);+ }+ preg_match_all('{+ (?:+ \b(?<![\$:>])(?P<type>class|interface'.$extraTypes.') \s++ (?P<name>[a-zA-Z_\x7f-\xff:][a-zA-Z0-9_\x7f-\xff:\-]*+)+ | \b(?<![\$:>])(?P<ns>namespace) (?P<nsname>\s++[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\s*+\\\\\s*+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)*+)? \s*+ [\{;]+ )+ }ix', $contents, $matches);+ $classes = array();+ $namespace = '';+ for ($i = 0, $len = count($matches['type']); $i < $len; $i++) {+ if (!empty($matches['ns'][$i])) {+ $namespace = str_replace(array(' ', "\t", "\r", "\n"), '', $matches['nsname'][$i]) . '\\';+ } else {+ $name = $matches['name'][$i];+ // skip anon classes extending/implementing+ if ($name === 'extends' || $name === 'implements') {+ continue;+ }+ if ($name[0] === ':') {+ // This is an XHP class, https://github.com/facebook/xhp+ $name = 'xhp'.substr(str_replace(array('-', ':'), array('_', '__'), $name), 1);+ } elseif ($matches['type'][$i] === 'enum') {+ // In Hack, something like:+ // enum Foo: int { HERP = '123'; }+ // The regex above captures the colon, which isn't part of+ // the class name.+ $name = rtrim($name, ':');+ }+ $classes[] = ltrim($namespace . $name, '\\');+ }+ }+ return $classes;+}++$options = getopt('i:f:', []);+$file = $options["f"];+$input = $options["i"];++$classes = findClasses($file);+foreach($classes as $class) {+ echo '$classmap[\''.$class.'\'] = \''.$input.'/'.$file.'\';';+ echo "\n";+}diff --git a/guix/build/composer-build-system.scm b/guix/build/composer-build-system.scmnew file mode 100644index 0000000000..3578b91954--- /dev/null+++ b/guix/build/composer-build-system.scm@@ -0,0 +1,224 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2019 Julien Lepiller <julien@lepiller.eu>+;;;+;;; 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/>.++(define-module (guix build composer-build-system)+ #:use-module ((guix build gnu-build-system) #:prefix gnu:)+ #:use-module (guix build json)+ #:use-module (guix build utils)+ #:use-module (ice-9 match)+ #:export (%standard-phases+ composer-build))++;; Commentary:+;;+;; Builder-side code of the standard composer build procedure.+;;+;; Code:++(define* (read-package-data #:key (filename "composer.json"))+ (call-with-input-file filename+ (lambda (port)+ (read-json port))))++(define* (check #:key composer-file inputs outputs tests? test-target #:allow-other-keys)+ "Install the given package."+ (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 (match (assoc-ref package-data "scripts")+ (('@ script ...) script)+ (#f '())))+ (test-script+ (assoc-ref scripts test-target))+ (dependencies (filter (lambda (dep) (string-contains dep "/"))+ (map car+ (match (assoc-ref package-data "require")+ (('@ dependency ...) dependency)+ (#f '())))))+ (dependencies-dev+ (filter (lambda (dep) (string-contains dep "/"))+ (map car+ (match (assoc-ref package-data "require-dev")+ (('@ dependency ...) dependency)+ (#f '())))))+ (name (assoc-ref package-data "name")))+ (for-each+ (lambda (input)+ (let ((bin (find-php-bin (cdr input))))+ (when bin+ (copy-recursively bin "vendor/bin"))))+ inputs)+ (match test-script+ ((? string? command)+ (unless (equal? (system command) 0)+ (throw 'failed-command command)))+ (('@ (? string? command) ...)+ (for-each+ (lambda (c)+ (unless (equal? (system c) 0)+ (throw 'failed-command c)))+ command))+ (#f (invoke "vendor/bin/phpunit")))))+ #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-php-dep inputs dependency)+ (let loop ((inputs (map cdr inputs)))+ (if (null? inputs)+ (throw 'unsatisfied-dependency "Unsatisfied dependency: required " dependency)+ (let ((autoload (string-append (car inputs) "/share/web/" dependency "/vendor/autoload_conf.php")))+ (if (file-exists? autoload)+ autoload+ (loop (cdr inputs)))))))++(define* (create-autoload vendor composer-file inputs #:key dev-dependencies?)+ (with-output-to-file (string-append vendor "/autoload.php")+ (lambda _+ (format #t "<?php~%")+ (format #t "// autoload.php @generated by Guix~%")+ (format #t "$map = $psr4map = $classmap = array();~%")+ (format #t "require_once '~a/autoload_conf.php';~%" vendor)+ (format #t "require_once '~a/share/web/composer/ClassLoader.php';~%"+ (assoc-ref inputs "composer-classloader"))+ (format #t "$loader = new \\Composer\\Autoload\\ClassLoader();~%")+ (format #t "foreach ($map as $namespace => $path) {~%")+ (format #t " $loader->set($namespace, $path);~%")+ (format #t "}~%")+ (format #t "foreach ($psr4map as $namespace => $path) {~%")+ (format #t " $loader->setPsr4($namespace, $path);~%")+ (format #t "}~%")+ (format #t "$loader->addClassMap($classmap);~%")+ (format #t "$loader->register();~%")))+ (let* ((package-data (read-package-data #:filename composer-file))+ (autoload+ (match (assoc-ref package-data "autoload")+ (('@ autoload ...) autoload)+ (#f '())))+ (autoload-dev+ (match (assoc-ref package-data "autoload-dev")+ (('@ autoload-dev ...) autoload-dev)+ (#f '())))+ (dependencies (filter (lambda (dep) (string-contains dep "/"))+ (map car+ (match (assoc-ref package-data "require")+ (('@ dependency ...) dependency)+ (#f '())))))+ (dependencies-dev+ (filter (lambda (dep) (string-contains dep "/"))+ (map car+ (match (assoc-ref package-data "require-dev")+ (('@ dependency ...) dependency)+ (#f '()))))))+ (with-output-to-file (string-append vendor "/autoload_conf.php")+ (lambda _+ (format #t "<?php~%")+ (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))))+ (append+ (match (assoc-ref autoload "psr-4")+ (('@ psr4 ...) psr4)+ (#f '()))+ (if dev-dependencies?+ (match (assoc-ref autoload-dev "psr-4")+ (('@ psr4 ...) psr4)+ (#f '()))+ '())))+ (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+ (or (assoc-ref autoload "classmap") '())+ (if dev-dependencies?+ (or (assoc-ref autoload-dev "classmap") '())+ '())))+ (for-each+ (lambda (dep)+ (format #t "require_once '~a';~%" (find-php-dep inputs dep)))+ (append+ dependencies+ (if dev-dependencies?+ dependencies-dev+ '())))))))++(define* (install #:key inputs outputs composer-file #:allow-other-keys)+ "Install the given package."+ (let* ((out (assoc-ref outputs "out"))+ (package-data (read-package-data #:filename composer-file))+ (name (assoc-ref package-data "name"))+ (php-dir (string-append out "/share/web/" name))+ (bin-dir (string-append php-dir "/vendor/bin"))+ (bin (string-append out "/bin"))+ (binaries (assoc-ref package-data "bin")))+ (mkdir-p php-dir)+ (copy-recursively "." php-dir)+ (mkdir-p (string-append php-dir "/vendor"))+ (when binaries+ (mkdir-p bin-dir)+ (mkdir-p bin)+ (for-each+ (lambda (file)+ (let ((installed-file (string-append bin-dir "/" (basename file)))+ (bin-file (string-append bin "/" (basename file)))+ (original-file (string-append php-dir "/" file)))+ (symlink original-file installed-file)+ (symlink original-file bin-file)))+ binaries))+ (create-autoload (string-append php-dir "/vendor")+ composer-file inputs))+ #t)++(define %standard-phases+ ;; Everything is as with the GNU Build System except for the `configure'+ ;; , `build', `check' and `install' phases.+ (modify-phases gnu:%standard-phases+ (delete 'bootstrap)+ (delete 'configure)+ (delete 'build)+ (delete 'check)+ (replace 'install install)+ (add-after 'install 'check check)))++(define* (composer-build #:key inputs (phases %standard-phases)+ #:allow-other-keys #:rest args)+ "Build the given package, applying all of PHASES in order."+ (apply gnu:gnu-build #:inputs inputs #:phases phases args))++;;; composer-build-system.scm ends here-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 04/34] gnu: Add php-doctrine-instantiator.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-4-julien@lepiller.eu
* gnu/packages/php-xyz.scm (php-doctrine-instantiator): New variable.--- gnu/packages/php-xyz.scm | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
Toggle diff (33 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex dab660f84f..28d8909dad 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -59,3 +59,26 @@ build its autoloading feature. This package is used by the composer-build-system to build its own store-aware autoloading feature.") (license license:expat)))++(define-public php-doctrine-instantiator+ (package+ (name "php-doctrine-instantiator")+ (version "1.3.1")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/doctrine/instantiator.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "17c72j29p77gdgh06b9qc0nivmav0k5yc22z4ryygj7dhr1h65nq"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (synopsis "Utility for instantiating PHP objects")+ (description "This package provides a small, lightweight utility to+instantiate objects in PHP without invoking their constructors")+ (home-page "https://www.doctrine-project.org/projects/instantiator.html")+ (license license:expat)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 05/34] gnu: Add php-sebastian-recursion-context.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-5-julien@lepiller.eu
* gnu/packages/php-xyz.scm (php-sebastian-recursion-context): New variable.--- gnu/packages/php-xyz.scm | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
Toggle diff (33 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex 28d8909dad..b04b8e0859 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -82,3 +82,26 @@ to build its own store-aware autoloading feature.") instantiate objects in PHP without invoking their constructors") (home-page "https://www.doctrine-project.org/projects/instantiator.html") (license license:expat)))++(define-public php-sebastian-recursion-context+ (package+ (name "php-sebastian-recursion-context")+ (version "4.0.2")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/sebastianbergmann/recursion-context.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "0glpydmvr95f9xbmh76vgid2nz7rf6lxwfz1j7ksvgmf4m1dniyz"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (synopsis "Process PHP variables recursively")+ (description "This package provides functionality to recursively process+PHP variables")+ (home-page "http://www.github.com/sebastianbergmann/recursion-context")+ (license license:bsd-3)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 06/34] gnu: Add php-sebastian-exporter.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-6-julien@lepiller.eu
* gnu/packages/php-xyz.scm (php-sebastian-exporter): New variable.--- gnu/packages/php-xyz.scm | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
Toggle diff (35 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex b04b8e0859..ae7d7ff6b2 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -105,3 +105,28 @@ instantiate objects in PHP without invoking their constructors") PHP variables") (home-page "http://www.github.com/sebastianbergmann/recursion-context") (license license:bsd-3)))++(define-public php-sebastian-exporter+ (package+ (name "php-sebastian-exporter")+ (version "4.0.2")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/sebastianbergmann/exporter.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "03xj9gbi8ifnbj5n72gfpwyg65l71gg1r8yvzpbg6d3yxbqaa8f6"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (inputs+ `(("php-sebastian-recursion-context" ,php-sebastian-recursion-context)))+ (synopsis "Visualize PHP variables")+ (description "This package provides the functionality to export PHP+variables for visualization")+ (home-page "http://www.github.com/sebastianbergmann/exporter")+ (license license:bsd-3)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 07/34] gnu: Add php-myclabs-deep-copy.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-7-julien@lepiller.eu
* gnu/packages/php-xyz.scm (php-myclabs-deep-copy): New variable.--- gnu/packages/php-xyz.scm | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
Toggle diff (35 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex ae7d7ff6b2..a45726a484 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -130,3 +130,28 @@ PHP variables") variables for visualization") (home-page "http://www.github.com/sebastianbergmann/exporter") (license license:bsd-3)))++(define-public php-myclabs-deep-copy+ (package+ (name "php-myclabs-deep-copy")+ (version "1.10.1")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/myclabs/DeepCopy.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "1ms4qhx5cf19ggdicnd7qjrigwam206py6mj6nw8bz71mafq9nbi"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (synopsis "Create copies of PHP objects")+ (description "This package contains a facility to create deep copies (clones)+of PHP objects. This package not only creates a new copy of an object, it+recursively create new copies of any object referenced by the object. It is+designed to work even in the presence of cycles in the association graph.")+ (home-page "https://github.com/myclabs/DeepCopy.git")+ (license license:expat)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 08/34] gnu: Add php-phar-io-version.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-8-julien@lepiller.eu
* gnu/packages/php-xyz.scm (php-phar-io-version): New variable.--- gnu/packages/php-xyz.scm | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
Toggle diff (35 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex a45726a484..0b64efe6ca 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -155,3 +155,28 @@ recursively create new copies of any object referenced by the object. It is designed to work even in the presence of cycles in the association graph.") (home-page "https://github.com/myclabs/DeepCopy.git") (license license:expat)))++(define-public php-phar-io-version+ (package+ (name "php-phar-io-version")+ (version "3.0.2")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/phar-io/version.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "0r9470p0azw7l0x2wbn7kh0zhpswvjnm32vc8vml5v5nskmnqz4c"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (properties+ `((upstream-name . "phar-io/version")))+ (synopsis "Library for handling version information and constraints")+ (description "This package contains a library for handling version information+and constraints.")+ (home-page "https://phar.io")+ (license license:bsd-3)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 09/34] gnu: Add php-phar-io-manifest.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-9-julien@lepiller.eu
* qnu/packages/php-xyz.scm (php-phar-io-manifest): New variable.--- gnu/packages/php-xyz.scm | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
Toggle diff (37 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex 0b64efe6ca..f0f4fe650a 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -180,3 +180,30 @@ designed to work even in the presence of cycles in the association graph.") and constraints.") (home-page "https://phar.io") (license license:bsd-3)))++(define-public php-phar-io-manifest+ (package+ (name "php-phar-io-manifest")+ (version "2.0.1")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/phar-io/manifest.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "0r2s1qdkhn7782g1y6skxvp5w397vmwb496fymsnik2818w0q469"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (inputs+ `(("php-phar-io-version" ,php-phar-io-version)))+ (properties+ `((upstream-name . "phar-io/manifest")))+ (synopsis "PHP Archive information reader")+ (description "This package contains a component for reading phar.io manifest+information from a PHP Archive (PHAR)")+ (home-page "https://phar.io")+ (license license:bsd-3)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 10/34] gnu: Add php-symfony-polyfill-ctype.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-10-julien@lepiller.eu
* gnu/packages/php.scm (php-symfony-polyfill-ctype): New variable.--- gnu/packages/php-xyz.scm | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
Toggle diff (33 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex f0f4fe650a..51e51ac51b 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -207,3 +207,26 @@ and constraints.") information from a PHP Archive (PHAR)") (home-page "https://phar.io") (license license:bsd-3)))++(define-public php-symfony-polyfill-ctype+ (package+ (name "php-symfony-polyfill-ctype")+ (version "1.17.1")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/symfony/polyfill-ctype.git")+ (commit (string-append "v" version))))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "0bh22vwq2idy7fi8ajm6aggjdvds64s98y9854b5gl9s84dk9pz8"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (synopsis "Ctype functions for older PHP versions")+ (description "This component provides @code{ctype_*} functions to users+who run php versions without the ctype extension.")+ (home-page "https://symfony.com")+ (license license:expat)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 11/34] gnu: Add php-webmozart-assert.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-11-julien@lepiller.eu
* gnu/packages/php-xyz.scm (php-webmozart-assert): New variable.--- gnu/packages/php-xyz.scm | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
Toggle diff (35 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex 51e51ac51b..ffc2eb7b11 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -230,3 +230,28 @@ information from a PHP Archive (PHAR)") who run php versions without the ctype extension.") (home-page "https://symfony.com") (license license:expat)))++(define-public php-webmozart-assert+ (package+ (name "php-webmozart-assert")+ (version "1.9.1")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/webmozart/assert.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "1q9bp4sp11r8ghdzr0qswdf1k5bf9b5s525im3kspar6y8019sh9"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (inputs+ `(("php-symfony-polyfill-ctype" ,php-symfony-polyfill-ctype)))+ (synopsis "Assertions to validate method input/output with nice error messages.")+ (description "This library contains efficient assertions to test the input+and output of PHP methods.")+ (home-page "https://github.com/webmozart/assert")+ (license license:expat)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 13/34] gnu: Add php-phpdocumentor-type-resolver.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-13-julien@lepiller.eu
* gnu/packages/php-xyz.scm (php-phpdocumentor-type-resolver): Newvariable.--- gnu/packages/php-xyz.scm | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
Toggle diff (35 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex 9b604c46f0..93d8649bee 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -279,3 +279,28 @@ the code structure") to analyze the code structure.") (home-page "http://www.phpdoc.org") (license license:expat)))++(define-public php-phpdocumentor-type-resolver+ (package+ (name "php-phpdocumentor-type-resolver")+ (version "1.3.0")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/phpDocumentor/TypeResolver.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "0wshv49z4hxraygg2vhzn0s9ih2y9ymzpcnyjfk14vcfq5yx53l9"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (inputs+ `(("php-phpdocumentor-reflection-common" ,php-phpdocumentor-reflection-common)))+ (synopsis "Resolver of class names, types and structural element names")+ (description "This package provides a PSR-5 based resolver of class names,+types and structural element names.")+ (home-page "http://www.phpdoc.org")+ (license license:expat)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 12/34] gnu: Add php-phpdocumentor-reflection-common.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-12-julien@lepiller.eu
* gnu/packages/php-xyz.scm (php-phpdocumentor-reflection-common): Newvariable.--- gnu/packages/php-xyz.scm | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
Toggle diff (34 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex ffc2eb7b11..9b604c46f0 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -255,3 +255,27 @@ who run php versions without the ctype extension.") and output of PHP methods.") (home-page "https://github.com/webmozart/assert") (license license:expat)))++(define-public php-phpdocumentor-reflection-common+ (package+ (name "php-phpdocumentor-reflection-common")+ (version "2.2.0")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/phpDocumentor/ReflectionCommon.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "1q685cpwbfxqy42iz61xxv6zbcc1qskn07nkipflj6c5s935l8jy"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (synopsis "Common reflection classes used by phpdocumentor to reflect+the code structure")+ (description "This package contains common classes used by phpdocumentor+to analyze the code structure.")+ (home-page "http://www.phpdoc.org")+ (license license:expat)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 14/34] gnu: Add php-phpdocumentor-reflection-docblock.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-14-julien@lepiller.eu
* gnu/packages/php-xyz.scm (php-phpdocumentor-reflection-docblock): Newvariable.--- gnu/packages/php-xyz.scm | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
Toggle diff (38 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex 93d8649bee..df9c490bbf 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -304,3 +304,31 @@ to analyze the code structure.") types and structural element names.") (home-page "http://www.phpdoc.org") (license license:expat)))++(define-public php-phpdocumentor-reflection-docblock+ (package+ (name "php-phpdocumentor-reflection-docblock")+ (version "5.1.0")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/phpDocumentor/ReflectionDocBlock.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "1bsqwcq5ix7f5p56kc92pl1nqpjdpfc92pjvwyshp1syrrspa3rr"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (inputs+ `(("php-webmozart-assert" ,php-webmozart-assert)+ ("php-phpdocumentor-reflection-common" ,php-phpdocumentor-reflection-common)+ ("php-phpdocumentor-type-resolver" ,php-phpdocumentor-type-resolver)))+ (synopsis "Library for retrieving documentation in code fro the code")+ (description "With this component, a library can provide support for+annotations via DocBlocks or otherwise retrieve information that is embedded+in a DocBlock.")+ (home-page "https://github.com/phpDocumentor/ReflectionDocBlock")+ (license license:expat)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 15/34] gnu: Add php-theseer-tokenizer.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-15-julien@lepiller.eu
* gnu/packages/php-xyz.scm (php-theseer-tokenizer): New variable.--- gnu/packages/php-xyz.scm | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
Toggle diff (33 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex df9c490bbf..f54b875d92 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -332,3 +332,26 @@ annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.") (home-page "https://github.com/phpDocumentor/ReflectionDocBlock") (license license:expat)))++(define-public php-theseer-tokenizer+ (package+ (name "php-theseer-tokenizer")+ (version "1.1.3")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/theseer/tokenizer.git")+ (commit "11336f6f84e16a720dae9d8e6ed5019efa85a0f9")))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "0j436a3jpynnlqrvd7la7a7smj78aklkragwa9l8p91973xra18l"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (synopsis "Convert PHP to XML")+ (description "This package provides a small library for converting tokenized+PHP source code into XML and potentially other formats.")+ (home-page "https://github.com/theseer/tokenizer")+ (license license:bsd-3)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 16/34] gnu: Add php-sebastian-code-unit-reverse-lookup.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-16-julien@lepiller.eu
* gnu/packages/php-xyz.scm (php-sebastian-code-unit-reverse-lookup): Newvariable.--- gnu/packages/php-xyz.scm | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
Toggle diff (33 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex f54b875d92..13584273f9 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -355,3 +355,26 @@ in a DocBlock.") PHP source code into XML and potentially other formats.") (home-page "https://github.com/theseer/tokenizer") (license license:bsd-3)))++(define-public php-sebastian-code-unit-reverse-lookup+ (package+ (name "php-sebastian-code-unit-reverse-lookup")+ (version "2.0.2")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "0lppni3qcd6gx50jf16y3n71ldj12xjd06kl9ml78zd5p2s6z4qc"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (synopsis "Look up function name from location")+ (description "This package provides a facility to look up which function or+method a line of code belongs to.")+ (home-page "https://github.com/sebastianbergmann/code-unit-reverse-lookup/")+ (license license:bsd-3)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 17/34] gnu: Add php-phpunit-php-token-stream.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-17-julien@lepiller.eu
* gnu/packages/php-xyz.scm (php-phpunit-php-token-stream): New variable.--- gnu/packages/php-xyz.scm | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
Toggle diff (33 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex 13584273f9..344c413d2c 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -378,3 +378,26 @@ PHP source code into XML and potentially other formats.") method a line of code belongs to.") (home-page "https://github.com/sebastianbergmann/code-unit-reverse-lookup/") (license license:bsd-3)))++(define-public php-phpunit-php-token-stream+ (package+ (name "php-phpunit-php-token-stream")+ (version "4.0.3")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/sebastianbergmann/php-token-stream.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "0iv8ssvyjhgxa1qpp5s8i0j409w49s2kc9qwv1c27qgdhv7yhf7h"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (synopsis "Wrapper around PHP's tokenizer extension")+ (description "This library provides a wrapper around PHP's tokenizer+extension.")+ (home-page "https://github.com/sebastianbergmann/php-token-stream/")+ (license license:bsd-3)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 18/34] gnu: Add php-sebastian-version.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-18-julien@lepiller.eu
* gnu/packages/php-xyz.scm (php-sebastian-version): New variable.--- gnu/packages/php-xyz.scm | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
Toggle diff (33 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex 344c413d2c..906a88d49e 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -401,3 +401,26 @@ method a line of code belongs to.") extension.") (home-page "https://github.com/sebastianbergmann/php-token-stream/") (license license:bsd-3)))++(define-public php-sebastian-version+ (package+ (name "php-sebastian-version")+ (version "3.0.1")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/sebastianbergmann/version.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "1kr2i6s7y4k18bz09cqj4pc4bqzph9n6ncgpqq4p4fg790h5i5ym"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (synopsis "PHP versionning library")+ (description "This package is a library that helps with managing the version+number of Git-hosted PHP projects.")+ (home-page "https://github.com/sebastianbergmann/version")+ (license license:bsd-3)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 19/34] gnu: Add php-phpunit-php-file-iterator.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-19-julien@lepiller.eu
* gnu/packages/php-xyz.scm (php-phpunit-php-file-iterator): Newvariable.--- gnu/packages/php-xyz.scm | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
Toggle diff (33 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex 906a88d49e..5d06bea0cb 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -424,3 +424,26 @@ extension.") number of Git-hosted PHP projects.") (home-page "https://github.com/sebastianbergmann/version") (license license:bsd-3)))++(define-public php-phpunit-php-file-iterator+ (package+ (name "php-phpunit-php-file-iterator")+ (version "3.0.4")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/sebastianbergmann/php-file-iterator.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "1pglbp8m4iv5w16gshlp49k4ngpsx28mhwip761kyvvd5w27ysr2"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (synopsis "Filter file by extension")+ (description "This package contains a @code{FilterIterator} implementation+that filters files based on a list of suffixes.")+ (home-page "https://github.com/sebastianbergmann/php-file-iterator/")+ (license license:bsd-3)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 20/34] gnu: Add php-phpunit-php-text-template.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-20-julien@lepiller.eu
* gnu/packages/php-xyz.scm (php-phpunit-php-text-template): Newvariable.--- gnu/packages/php-xyz.scm | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
Toggle diff (32 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex 5d06bea0cb..b5abcaae36 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -447,3 +447,25 @@ number of Git-hosted PHP projects.") that filters files based on a list of suffixes.") (home-page "https://github.com/sebastianbergmann/php-file-iterator/") (license license:bsd-3)))++(define-public php-phpunit-php-text-template+ (package+ (name "php-phpunit-php-text-template")+ (version "2.0.2")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/sebastianbergmann/php-text-template.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "0x38kj1xlnysg9xgad560k361l93vh32mvkyfn7rss3p2r319jhx"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (synopsis "Simple template engine")+ (description "This package contains a library for a simple templating engine.")+ (home-page "https://github.com/sebastianbergmann/php-text-template/")+ (license license:bsd-3)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 21/34] gnu: Add php-sebastian-diff.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-21-julien@lepiller.eu
* gnu/packages/php-xyz.scm (php-sebastian-diff): New variable.--- gnu/packages/php-xyz.scm | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
Toggle diff (32 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex b5abcaae36..ccc613baaf 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -469,3 +469,25 @@ that filters files based on a list of suffixes.") (description "This package contains a library for a simple templating engine.") (home-page "https://github.com/sebastianbergmann/php-text-template/") (license license:bsd-3)))++(define-public php-sebastian-diff+ (package+ (name "php-sebastian-diff")+ (version "4.0.2")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/sebastianbergmann/diff.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "0fr5vrmz3d1wwpf59y16fin5lgi55sjd7dqfkx0zqmsqadbjrjxq"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (synopsis "Diff implementation")+ (description "This package contains a PHP implementation of a diff function.")+ (home-page "https://github.com/sebastianbergmann/diff")+ (license license:bsd-3)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 22/34] gnu: Add php-sebastian-comparator.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-22-julien@lepiller.eu
* gnu/packages/php-xyz.scm (php-sebastian-comparator): New variable.--- gnu/packages/php-xyz.scm | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
Toggle diff (36 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex ccc613baaf..aff2ed79a7 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -491,3 +491,29 @@ that filters files based on a list of suffixes.") (description "This package contains a PHP implementation of a diff function.") (home-page "https://github.com/sebastianbergmann/diff") (license license:bsd-3)))++(define-public php-sebastian-comparator+ (package+ (name "php-sebastian-comparator")+ (version "4.0.3")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/sebastianbergmann/comparator.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "1scw7vm26layqh5mzvdhjiil520fj6ipixkjnmwm036xr925iww0"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (inputs+ `(("php-sebastian-exporter" ,php-sebastian-exporter)+ ("php-sebastian-diff" ,php-sebastian-diff)))+ (synopsis "PHP value comparison")+ (description "This package provides the functionality to compare PHP values+for equality.")+ (home-page "https://github.com/sebastianbergmann/comparator")+ (license license:bsd-3)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 23/34] gnu: Add php-sebastian-environment.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-23-julien@lepiller.eu
* gnu/packages/php-xyz.scm (php-sebastian-environment): New variable.--- gnu/packages/php-xyz.scm | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
Toggle diff (32 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex aff2ed79a7..9ee823bcda 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -517,3 +517,25 @@ that filters files based on a list of suffixes.") for equality.") (home-page "https://github.com/sebastianbergmann/comparator") (license license:bsd-3)))++(define-public php-sebastian-environment+ (package+ (name "php-sebastian-environment")+ (version "5.1.2")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/sebastianbergmann/environment.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "0lhaiwk6dbwii9kmjaq3gjl2x5s1rikmxkvmy4mjvjcbi7imp38s"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (synopsis "Handle HHVM and PHP environments")+ (description "This package provides functionality to handle HHVM/PHP environments")+ (home-page "http://www.github.com/sebastianbergmann/environment")+ (license license:bsd-3)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 24/34] gnu: Add php-phpspec-prophecy.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-24-julien@lepiller.eu
* gnu/packages/php-xyz.scm (php-phpspec-prophecy): New variable.--- gnu/packages/php-xyz.scm | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
Toggle diff (39 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex 9ee823bcda..8c96d9aabc 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -539,3 +539,32 @@ for equality.") (description "This package provides functionality to handle HHVM/PHP environments") (home-page "http://www.github.com/sebastianbergmann/environment") (license license:bsd-3)))++(define-public php-phpspec-prophecy+ (package+ (name "php-phpspec-prophecy")+ (version "1.11.1")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/phpspec/prophecy.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "1pd6iz6pbfpaz5rqa36q01l569zgiqpjgqmzw3rra2qdh1jrwdy1"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (inputs+ `(("php-sebastian-recursion-context" ,php-sebastian-recursion-context)+ ("php-doctrine-instantiator" ,php-doctrine-instantiator)+ ("php-sebastian-comparator" ,php-sebastian-comparator)+ ("php-phpdocumentor-reflection-docblock"+ ,php-phpdocumentor-reflection-docblock)))+ (synopsis "Mocking framework for PHP 5.3+")+ (description "This package contains a mocking framework for testing PHP+5.3+ projects.")+ (home-page "https://github.com/phpspec/prophecy")+ (license license:expat)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 26/34] gnu: Add php-sebastian-global-state.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-26-julien@lepiller.eu
* gnu/packages/php-xyz.scm (php-sebastian-global-state): New variable.--- gnu/packages/php-xyz.scm | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
Toggle diff (37 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex 899f6a3f69..4872523b31 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -591,3 +591,30 @@ for equality.") inherited and non-public ones.") (home-page "https://github.com/sebastianbergmann/object-reflector/") (license license:bsd-3)))++(define-public php-sebastian-global-state+ (package+ (name "php-sebastian-global-state")+ (version "4.0.0")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/sebastianbergmann/global-state.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "0x6sfw353px5y7azipn2mb15w7w7zxbbpbv3dbhhkryrhad8w064"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (inputs+ `(("php-sebastian-recursion-context" ,php-sebastian-recursion-context)+ ("php-sebastian-object-reflector" ,php-sebastian-object-reflector)))+ (synopsis "Snapshotting of global state")+ (description "This package contains a stand-alone component originally part+of PHPUnit. It provides support for creating a snapshot of the global state+of a PHP program.")+ (home-page "http://www.github.com/sebastianbergmann/global-state")+ (license license:bsd-3)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 28/34] gnu: Add php-sebastian-resource-operations.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-28-julien@lepiller.eu
* gnu/packages/php-xyz.scm (php-sebastian-resource-operations): Newvariable.--- gnu/packages/php-xyz.scm | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
Toggle diff (33 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex 8cf5668030..aee08c0878 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -644,3 +644,26 @@ of a PHP program.") and object graphs to enumerate all referenced objects.") (home-page "https://github.com/sebastianbergmann/object-enumerator/") (license license:bsd-3)))++(define-public php-sebastian-resource-operations+ (package+ (name "php-sebastian-resource-operations")+ (version "3.0.2")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/sebastianbergmann/resource-operations.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "09s2gsmx6fg8sx64yyz2dszy22dcsspazlhskv3d9mflpmrk0d9y"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (synopsis "List built-in PHP functions")+ (description "This package provides a list of PHP built-in functions that+operate on resources.")+ (home-page "https://www.github.com/sebastianbergmann/resource-operations")+ (license license:bsd-3)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 25/34] gnu: Add php-sebastian-object-reflector.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-25-julien@lepiller.eu
* gnu/packages/php-xyz.scm (php-sebastian-object-reflector): Newvariable.--- gnu/packages/php-xyz.scm | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
Toggle diff (33 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex 8c96d9aabc..899f6a3f69 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -568,3 +568,26 @@ for equality.") 5.3+ projects.") (home-page "https://github.com/phpspec/prophecy") (license license:expat)))++(define-public php-sebastian-object-reflector+ (package+ (name "php-sebastian-object-reflector")+ (version "2.0.2")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/sebastianbergmann/object-reflector.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "1qkvp2s932h53f161l30qlnxicw4fklirmnds173wgmavms1b5yb"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (synopsis "PHP reflexion library")+ (description "This package allows reflection of object attributes, including+inherited and non-public ones.")+ (home-page "https://github.com/sebastianbergmann/object-reflector/")+ (license license:bsd-3)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 32/34] gnu: Add php-phpunit-php-invoker.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-32-julien@lepiller.eu
* gnu/packages/php-xyz.scm (php-phpunit-php-invoker): New variable.--- gnu/packages/php-xyz.scm | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
Toggle diff (33 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex 1b6669abcc..484fb17790 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -745,3 +745,26 @@ processing, and rendering functionality for PHP code coverage information.") of PHPUnit. It provides a utility class for timing.") (home-page "https://github.com/sebastianbergmann/php-timer/") (license license:bsd-3)))++(define-public php-phpunit-php-invoker+ (package+ (name "php-phpunit-php-invoker")+ (version "3.0.2")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/sebastianbergmann/php-invoker.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "1xs7m0wiminnhkd400glmixyhrx1ir710j6fds9i03dhicfcj7db"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (synopsis "PHP library for invoking functions")+ (description "This package contains a library to invoke callables with a+timeout.")+ (home-page "https://github.com/sebastianbergmann/php-invoker/")+ (license license:bsd-3)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 30/34] gnu: Add php-phpunit-php-code-coverage.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-30-julien@lepiller.eu
* gnu/packages/php-xyz.scm (php-phpunit-php-code-coverage): Newvariable.--- gnu/packages/php-xyz.scm | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)
Toggle diff (42 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex 9a50c431b7..2d186c5190 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -690,3 +690,35 @@ operate on resources.") the types of the PHP type system.") (home-page "https://github.com/sebastianbergmann/type") (license license:bsd-3)))++(define-public php-phpunit-php-code-coverage+ (package+ (name "php-phpunit-php-code-coverage")+ (version "8.0.2")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/sebastianbergmann/php-code-coverage.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "1qr7x9y8636bvv0fk8hl0kl9d2y8fy6qw65kpi4yb1yyqhfddkgh"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (inputs+ `(("php-theseer-tokenizer" ,php-theseer-tokenizer)+ ("php-sebastian-version" ,php-sebastian-version)+ ("php-sebastian-environment" ,php-sebastian-environment)+ ("php-sebastian-code-unit-reverse-lookup"+ ,php-sebastian-code-unit-reverse-lookup)+ ("php-phpunit-php-text-template" ,php-phpunit-php-text-template)+ ("php-phpunit-php-token-stream" ,php-phpunit-php-token-stream)+ ("php-phpunit-php-file-iterator" ,php-phpunit-php-file-iterator)))+ (synopsis "Code coverage information library")+ (description "This package is a library that provides collection,+processing, and rendering functionality for PHP code coverage information.")+ (home-page "https://github.com/sebastianbergmann/php-code-coverage")+ (license license:bsd-3)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 31/34] gnu: Add php-phpunit-php-timer.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-31-julien@lepiller.eu
* gnu/packages/php-xyz.scm (php-phpunit-php-timer): New variable.--- gnu/packages/php-xyz.scm | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
Toggle diff (33 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex 2d186c5190..1b6669abcc 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -722,3 +722,26 @@ the types of the PHP type system.") processing, and rendering functionality for PHP code coverage information.") (home-page "https://github.com/sebastianbergmann/php-code-coverage") (license license:bsd-3)))++(define-public php-phpunit-php-timer+ (package+ (name "php-phpunit-php-timer")+ (version "5.0.1")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/sebastianbergmann/php-timer.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "0hyy5c8b22zki6836a7fhzr3s6dpvga33r2rzfrsbv1arh19ay60"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (synopsis "Utility class for timing")+ (description "This package contains a stand-alone component originally part+of PHPUnit. It provides a utility class for timing.")+ (home-page "https://github.com/sebastianbergmann/php-timer/")+ (license license:bsd-3)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 33/34] gnu: Add php-sebastian-code-unit.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-33-julien@lepiller.eu
* gnu/packages/php-xyz.scm (php-sebastian-code-unit): New variable.--- gnu/packages/php-xyz.scm | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
Toggle diff (33 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex 484fb17790..0ae92c4600 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -768,3 +768,26 @@ of PHPUnit. It provides a utility class for timing.") timeout.") (home-page "https://github.com/sebastianbergmann/php-invoker/") (license license:bsd-3)))++(define-public php-sebastian-code-unit+ (package+ (name "php-sebastian-code-unit")+ (version "1.0.5")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/sebastianbergmann/code-unit.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "058ykqcmzm900c513j2qvi189bgn0scxsrhbrik5xycrr620krxc"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (synopsis "PHP collection of value objects for code units")+ (description "This package contains a collection of value objects that+represent the PHP code units.")+ (home-page "https://github.com/sebastianbergmann/code-unit")+ (license license:bsd-3)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 29/34] gnu: Add php-sebastian-type.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-29-julien@lepiller.eu
* gnu/packages/php-xyz.scm (php-sebastian-type): New variable.--- gnu/packages/php-xyz.scm | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
Toggle diff (33 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex aee08c0878..9a50c431b7 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -667,3 +667,26 @@ and object graphs to enumerate all referenced objects.") operate on resources.") (home-page "https://www.github.com/sebastianbergmann/resource-operations") (license license:bsd-3)))++(define-public php-sebastian-type+ (package+ (name "php-sebastian-type")+ (version "2.2.1")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/sebastianbergmann/type.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "0gvdb9188a4903q0dnhhdcm9qd67is5pns8jbccxr7hxv8w7d7h3"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (synopsis "PHP type system representation")+ (description "This package is a collection of value objects that represent+the types of the PHP type system.")+ (home-page "https://github.com/sebastianbergmann/type")+ (license license:bsd-3)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 27/34] gnu: Add php-sebastian-object-enumerator.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-27-julien@lepiller.eu
* gnu/packages/php-xyz.scm (php-sebastian-object-enumerator): Newvariable.--- gnu/packages/php-xyz.scm | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
Toggle diff (36 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex 4872523b31..8cf5668030 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -618,3 +618,29 @@ of PHPUnit. It provides support for creating a snapshot of the global state of a PHP program.") (home-page "http://www.github.com/sebastianbergmann/global-state") (license license:bsd-3)))++(define-public php-sebastian-object-enumerator+ (package+ (name "php-sebastian-object-enumerator")+ (version "4.0.2")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/sebastianbergmann/object-enumerator.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "1qx28r0ncbh0x9i0jplyg870paxxsy7g1ibgbdqq11176101aj6q"))))+ (build-system composer-build-system)+ (arguments+ ;; We do not have phpunit yet+ `(#:tests? #f))+ (inputs+ `(("php-sebastian-recursion-context" ,php-sebastian-recursion-context)+ ("php-sebastian-object-reflector" ,php-sebastian-object-reflector)))+ (synopsis "Enumerate PHP objects")+ (description "This package allows PHP programs to traverse array structures+and object graphs to enumerate all referenced objects.")+ (home-page "https://github.com/sebastianbergmann/object-enumerator/")+ (license license:bsd-3)))-- 2.27.0
J
J
Julien Lepiller wrote on 13 Jul 2020 00:25
[PATCH 34/34] gnu: Add phpunit.
(address . 42338@debbugs.gnu.org)
20200712222538.18092-34-julien@lepiller.eu
* gnu/packages/php-xyz.scm (php-phpunit-phpunit): New variable.--- gnu/packages/php-xyz.scm | 45 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+)
Toggle diff (55 lines)diff --git a/gnu/packages/php-xyz.scm b/gnu/packages/php-xyz.scmindex 0ae92c4600..eebf64c1a3 100644--- a/gnu/packages/php-xyz.scm+++ b/gnu/packages/php-xyz.scm@@ -791,3 +791,48 @@ timeout.") represent the PHP code units.") (home-page "https://github.com/sebastianbergmann/code-unit") (license license:bsd-3)))++(define-public php-phpunit-phpunit+ (package+ (name "phpunit")+ (version "9.2.5")+ (source (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/sebastianbergmann/phpunit.git")+ (commit version)))+ (file-name (git-file-name name version))+ (sha256+ (base32+ "1ck41faxkqr6painsqirklzsl08k8biadi2ksnpsmpjf3dp5p5gl"))))+ (build-system composer-build-system)+ (arguments+ ;; Requires phpspec/prophecy-phpunit, which in turns requires phpunit.+ `(#:tests? #f))+ (inputs+ `(("php-sebastian-version" ,php-sebastian-version)+ ("php-sebastian-type" ,php-sebastian-type)+ ("php-sebastian-resource-operations" ,php-sebastian-resource-operations)+ ("php-sebastian-object-enumerator" ,php-sebastian-object-enumerator)+ ("php-sebastian-global-state" ,php-sebastian-global-state)+ ("php-sebastian-exporter" ,php-sebastian-exporter)+ ("php-sebastian-environment" ,php-sebastian-environment)+ ("php-sebastian-diff" ,php-sebastian-diff)+ ("php-sebastian-comparator" ,php-sebastian-comparator)+ ("php-sebastian-code-unit" ,php-sebastian-code-unit)+ ("php-phpunit-php-timer" ,php-phpunit-php-timer)+ ("php-phpunit-php-text-template" ,php-phpunit-php-text-template)+ ("php-phpunit-php-invoker" ,php-phpunit-php-invoker)+ ("php-phpunit-php-file-iterator" ,php-phpunit-php-file-iterator)+ ("php-phpunit-php-code-coverage" ,php-phpunit-php-code-coverage)+ ("php-phpspec-prophecy" ,php-phpspec-prophecy)+ ("php-phar-io-version" ,php-phar-io-version)+ ("php-phar-io-manifest" ,php-phar-io-manifest)+ ("php-myclabs-deep-copy" ,php-myclabs-deep-copy)+ ("php-doctrine-instantiator" ,php-doctrine-instantiator)))+ (properties `((upstream-name . "phpunit/phpunit")))+ (synopsis "PHP Unit Testing framework")+ (description "PHPUnit is a testing framework for PHP. It is an instance of+the xUnit architecture for unit testing frameworks.")+ (home-page "https://phpunit.de/")+ (license license:bsd-3)))-- 2.27.0
L
L
Ludovic Courtès wrote on 7 Sep 2020 16:06
Re: [bug#42338] [PATCH 01/34] guix: import: Add composer importer.
(name . Julien Lepiller)(address . julien@lepiller.eu)(address . 42338@debbugs.gnu.org)
87mu21heay.fsf@gnu.org
Hi Julien,
There’s a lot of interesting work in here! I’m not familiar with PHP;I’ll just make a bird’s eye review.
Julien Lepiller <julien@lepiller.eu> skribis:
Toggle quote (5 lines)> * guix/import/composer.scm: New file.> * guix/scripts/import/composer.scm: New file.> * Makefile.am: Add them.> * guix/scripts/import.scm: Add composer importer.
Please add tests and a mention in “Invoking guix import” in the manual.
For tests, a strategy that I think works well is that used intests/cpan.scm, where we spawn an HTTP server to mock the real one.
Toggle quote (22 lines)> +(define* (composer-fetch name #:optional version)> + "Return an alist representation of the Composer metadata for the package NAME,> +or #f on failure."> + (let ((package (json-fetch> + (string-append "https://repo.packagist.org/p/" name ".json"))))> + (if package> + (let* ((packages (assoc-ref package "packages"))> + (package (assoc-ref packages name))> + (versions (filter> + (lambda (version)> + (and (not (string-contains version "dev"))> + (not (string-contains version "beta"))))> + (map car package)))> + (versions (map> + (lambda (version)> + (cons (fix-version version) version))> + versions))> + (version (or (if (null? version) #f version)> + (latest-version (map car versions)))))> + (assoc-ref package (assoc-ref versions version)))> + #f)))
I recommend using ‘define-json-mapping’ instead of browsing alists: it’sless error-prone, hides the JSON details away, and leads to morereadable code. The pypi, crates, cpan importers use it.
Thanks!
Ludo’.
L
L
Ludovic Courtès wrote on 7 Sep 2020 16:09
Re: [bug#42338] [PATCH 03/34] guix: Add composer-build-system.
(name . Julien Lepiller)(address . julien@lepiller.eu)(address . 42338@debbugs.gnu.org)
87imcphe6a.fsf@gnu.org
Julien Lepiller <julien@lepiller.eu> skribis:
Toggle quote (6 lines)> * guix/build-system/composer.scm: New file.> * guix/build/composer-build-system.scm: New file.> * guix/build-system/findclass.php: New file.> * Makefile.am: Add them.> * doc/guix.texi (Build Systems): Document it.
[...]
Toggle quote (11 lines)> +++ b/guix/build-system/findclass.php> @@ -0,0 +1,102 @@> +<?php> +/**> + * Extract the classes in the given file> + *> + * @param string $path The file to check> + * @throws \RuntimeException> + * @return array The found classes> + */
This should rather be under gnu/packages/aux-files IMO. Also, could youadd a copyright header and possibly info as to where it originates?
Toggle quote (19 lines)> +(define* (create-autoload vendor composer-file inputs #:key dev-dependencies?)> + (with-output-to-file (string-append vendor "/autoload.php")> + (lambda _> + (format #t "<?php~%")> + (format #t "// autoload.php @generated by Guix~%")> + (format #t "$map = $psr4map = $classmap = array();~%")> + (format #t "require_once '~a/autoload_conf.php';~%" vendor)> + (format #t "require_once '~a/share/web/composer/ClassLoader.php';~%"> + (assoc-ref inputs "composer-classloader"))> + (format #t "$loader = new \\Composer\\Autoload\\ClassLoader();~%")> + (format #t "foreach ($map as $namespace => $path) {~%")> + (format #t " $loader->set($namespace, $path);~%")> + (format #t "}~%")> + (format #t "foreach ($psr4map as $namespace => $path) {~%")> + (format #t " $loader->setPsr4($namespace, $path);~%")> + (format #t "}~%")> + (format #t "$loader->addClassMap($classmap);~%")> + (format #t "$loader->register();~%")))
I think it’d be clearer as a single string:
(display "\<?php// autoload.php …")
Ludo’.
J
J
Julien Lepiller wrote on 18 Sep 2020 00:43
Re: [bug#42338] [PATCH 01/34] guix: import: Add composer importer.
(name . Ludovic Courtès)(address . ludo@gnu.org)(address . 42338@debbugs.gnu.org)
20200918004333.127aa5da@tachikoma.lepiller.eu
Le Mon, 07 Sep 2020 16:06:13 +0200,Ludovic Courtès <ludo@gnu.org> a écrit :
Toggle quote (51 lines)> Hi Julien,> > There’s a lot of interesting work in here! I’m not familiar with PHP;> I’ll just make a bird’s eye review.> > Julien Lepiller <julien@lepiller.eu> skribis:> > > * guix/import/composer.scm: New file.> > * guix/scripts/import/composer.scm: New file.> > * Makefile.am: Add them.> > * guix/scripts/import.scm: Add composer importer. > > Please add tests and a mention in “Invoking guix import” in the> manual.> > For tests, a strategy that I think works well is that used in> tests/cpan.scm, where we spawn an HTTP server to mock the real one.> > > +(define* (composer-fetch name #:optional version)> > + "Return an alist representation of the Composer metadata for the> > package NAME, +or #f on failure."> > + (let ((package (json-fetch> > + (string-append "https://repo.packagist.org/p/"> > name ".json"))))> > + (if package> > + (let* ((packages (assoc-ref package "packages"))> > + (package (assoc-ref packages name))> > + (versions (filter> > + (lambda (version)> > + (and (not (string-contains version> > "dev"))> > + (not (string-contains version> > "beta"))))> > + (map car package)))> > + (versions (map> > + (lambda (version)> > + (cons (fix-version version) version))> > + versions))> > + (version (or (if (null? version) #f version)> > + (latest-version (map car versions)))))> > + (assoc-ref package (assoc-ref versions version)))> > + #f))) > > I recommend using ‘define-json-mapping’ instead of browsing alists:> it’s less error-prone, hides the JSON details away, and leads to more> readable code. The pypi, crates, cpan importers use it.> > Thanks!> > Ludo’.
Thanks, here's a new version
From 6d521ca9f066f82488abefd5d3630e38305c0fd1 Mon Sep 17 00:00:00 2001From: Julien Lepiller <julien@lepiller.eu>Date: Tue, 29 Oct 2019 08:07:38 +0100Subject: [PATCH 01/34] guix: import: Add composer importer.
* guix/import/composer.scm: New file.* guix/scripts/import/composer.scm: New file.* guix/tests/composer.scm: New file.* Makefile.am: Add them.* guix/scripts/import.scm: Add composer importer.* doc/guix.texi (Invoking guix import): Mention it.--- Makefile.am | 3 + doc/guix.texi | 6 + guix/import/composer.scm | 257 +++++++++++++++++++++++++++++++ guix/scripts/import.scm | 2 +- guix/scripts/import/composer.scm | 107 +++++++++++++ tests/composer.scm | 92 +++++++++++ 6 files changed, 466 insertions(+), 1 deletion(-) create mode 100644 guix/import/composer.scm create mode 100644 guix/scripts/import/composer.scm create mode 100644 tests/composer.scm
Toggle diff (534 lines)diff --git a/Makefile.am b/Makefile.amindex 8e91e1e558..6ce1430ea6 100644--- a/Makefile.am+++ b/Makefile.am@@ -223,6 +223,7 @@ MODULES = \ guix/search-paths.scm \ guix/packages.scm \ guix/import/cabal.scm \+ guix/import/composer.scm \ guix/import/cpan.scm \ guix/import/cran.scm \ guix/import/crate.scm \@@ -269,6 +270,7 @@ MODULES = \ guix/scripts/system/reconfigure.scm \ guix/scripts/lint.scm \ guix/scripts/challenge.scm \+ guix/scripts/import/composer.scm \ guix/scripts/import/crate.scm \ guix/scripts/import/cran.scm \ guix/scripts/import/elpa.scm \@@ -402,6 +404,7 @@ SCM_TESTS = \ tests/challenge.scm \ tests/channels.scm \ tests/combinators.scm \+ tests/composer.scm \ tests/containers.scm \ tests/cpan.scm \ tests/cpio.scm \diff --git a/doc/guix.texi b/doc/guix.texiindex 88128a4b3a..ca4eb347c7 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -10164,6 +10164,12 @@ in Guix. @cindex OCaml Import metadata from the @uref{https://opam.ocaml.org/, OPAM} package repository used by the OCaml community.++@item composer+@cindex COMPOSER+@cindex PHP+Import metadat from the @uref{https://getcomposer.org/, Composer} package+archive used by the PHP community. @end table The structure of the @command{guix import} code is modular. It would bediff --git a/guix/import/composer.scm b/guix/import/composer.scmnew file mode 100644index 0000000000..db8075edb2--- /dev/null+++ b/guix/import/composer.scm@@ -0,0 +1,257 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2019 Julien Lepiller <julien@lepiller.eu>+;;;+;;; 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/>.++(define-module (guix import composer)+ #:use-module (ice-9 match)+ #:use-module (json)+ #:use-module (gcrypt hash)+ #:use-module (guix base32)+ #:use-module (guix build git)+ #:use-module (guix build utils)+ #:use-module (guix build-system)+ #:use-module (guix import json)+ #:use-module (guix import utils)+ #:use-module ((guix licenses) #:prefix license:)+ #:use-module (guix packages)+ #:use-module (guix serialization)+ #:use-module (guix upstream)+ #:use-module (guix utils)+ #:use-module (srfi srfi-1)+ #:use-module (srfi srfi-11)+ #:export (composer->guix-package+ %composer-updater+ composer-recursive-import++ %composer-base-url))++(define %composer-base-url+ (make-parameter "https://repo.packagist.org"))++;; XXX adapted from (guix scripts hash)+(define (file-hash file select? recursive?)+ ;; Compute the hash of FILE.+ (if recursive?+ (let-values (((port get-hash) (open-sha256-port)))+ (write-file file port #:select? select?)+ (force-output port)+ (get-hash))+ (call-with-input-file file port-sha256)))++;; XXX taken from (guix scripts hash)+(define (vcs-file? file stat)+ (case (stat:type stat)+ ((directory)+ (member (basename file) '(".bzr" ".git" ".hg" ".svn" "CVS")))+ ((regular)+ ;; Git sub-modules have a '.git' file that is a regular text file.+ (string=? (basename file) ".git"))+ (else+ #f)))++(define (latest-version versions)+ (fold (lambda (a b) (if (version>? a b) a b)) (car versions) versions))++(define (fix-version version)+ "Return a fixed version from a version string. For instance, v10.1 -> 10.1"+ (cond+ ((string-prefix? "version" version)+ (if (char-set-contains? char-set:digit (string-ref version 7))+ (substring version 7)+ (substring version 8)))+ ((string-prefix? "v" version)+ (substring version 1))+ (else version)))++(define* (composer-fetch name #:optional version)+ "Return an alist representation of the Composer metadata for the package NAME,+or #f on failure."+ (let ((package (json-fetch+ (string-append (%composer-base-url) "/p/" name ".json"))))+ (if package+ (let* ((packages (assoc-ref package "packages"))+ (package (assoc-ref packages name))+ (versions (filter+ (lambda (version)+ (and (not (string-contains version "dev"))+ (not (string-contains version "beta"))))+ (map car package)))+ (versions (map+ (lambda (version)+ (cons (fix-version version) version))+ versions))+ (version (or (if (null? version) #f version)+ (latest-version (map car versions)))))+ (assoc-ref package (assoc-ref versions version)))+ #f)))++(define (php-package-name name)+ "Given the NAME of a package on Packagist, return a Guix-compliant name for+the package."+ (let ((name (string-join (string-split name #\/) "-")))+ (if (string-prefix? "php-" name)+ (snake-case name)+ (string-append "php-" (snake-case name)))))++(define (make-php-sexp name version home-page description dependencies+ dev-dependencies licenses source)+ "Return the `package' s-expression for a PHP package with the given NAME,+VERSION, HOME-PAGE, DESCRIPTION, DEPENDENCIES, LICENSES and SOURCE."+ (let ((git? (equal? (assoc-ref source "type") "git")))+ ((if git? call-with-temporary-directory call-with-temporary-output-file)+ (lambda* (temp #:optional port)+ (and (if git?+ (begin+ (mkdir-p temp)+ (git-fetch (assoc-ref source "url")+ (assoc-ref source "reference")+ temp))+ (url-fetch (assoc-ref source "url") temp))+ `(package+ (name ,(php-package-name name))+ (version ,version)+ (source (origin+ ,@(if git?+ `((method git-fetch)+ (uri (git-reference+ (url ,(assoc-ref source "url"))+ (commit ,(assoc-ref source "reference"))))+ (file-name (git-file-name name version))+ (sha256+ (base32+ ,(bytevector->nix-base32-string+ (file-hash temp (negate vcs-file?) #t)))))+ `((method url-fetch)+ (uri ,(assoc-ref source "url"))+ (sha256 (base32 ,(guix-hash-url temp)))))))+ (build-system composer-build-system)+ ,@(if (null? dependencies)+ '()+ `((inputs+ (,'quasiquote+ ,(map (lambda (name)+ `(,name+ (,'unquote+ ,(string->symbol name))))+ dependencies)))))+ ,@(if (null? dev-dependencies)+ '()+ `((native-inputs+ (,'quasiquote+ ,(map (lambda (name)+ `(,name+ (,'unquote+ ,(string->symbol name))))+ dev-dependencies)))))+ (synopsis "")+ (description ,description)+ (home-page ,home-page)+ (license ,(match licenses+ (() #f)+ ((license) (license->symbol license))+ (_ `(list ,@(map license->symbol licenses)))))))))))++(define* (composer->guix-package package-name #:optional version)+ "Fetch the metadata for PACKAGE-NAME from packagist.org, and return the+`package' s-expression corresponding to that package, or #f on failure."+ (let ((package (composer-fetch package-name version)))+ (and package+ (let* ((name (assoc-ref package "name"))+ (version (fix-version (assoc-ref package "version")))+ (description (beautify-description+ (assoc-ref package "description")))+ (home-page (assoc-ref package "homepage"))+ (dependencies-names (filter+ (lambda (dep)+ (string-contains dep "/"))+ (map car (assoc-ref package "require"))))+ (dependencies (map php-package-name dependencies-names))+ (require-dev (assoc-ref package "require-dev"))+ (dev-dependencies-names+ (if require-dev+ (filter+ (lambda (dep)+ (string-contains dep "/"))+ (map car require-dev))+ '()))+ (dev-dependencies (map php-package-name dev-dependencies-names))+ (licenses (map string->license+ (vector->list+ (assoc-ref package "license")))))+ (values (make-php-sexp name version home-page description dependencies+ dev-dependencies licenses (assoc-ref package "source"))+ (append dependencies-names dev-dependencies-names))))))++(define (guix-name->composer-name name)+ "Given a guix package name, return the name of the package in Packagist."+ (if (string-prefix? "php-" name)+ (let ((components (string-split (substring name 4) #\-)))+ (match components+ ((namespace name ...)+ (string-append namespace "/" (string-join name "-")))))+ name))++(define (guix-package->composer-name package)+ "Given a Composer PACKAGE built from Packagist, return the name of the+package in Packagist."+ (let ((upstream-name (assoc-ref+ (package-properties package)+ 'upstream-name))+ (name (package-name package)))+ (if upstream-name+ upstream-name+ (guix-name->composer-name name))))++(define (string->license str)+ "Convert the string STR into a license object."+ (match str+ ("GNU LGPL" license:lgpl2.0)+ ("GPL" license:gpl3)+ ((or "BSD" "BSD License" "BSD-3-Clause") license:bsd-3)+ ((or "MIT" "MIT license" "Expat license") license:expat)+ ("Public domain" license:public-domain)+ ((or "Apache License, Version 2.0" "Apache 2.0") license:asl2.0)+ (_ #f)))++(define (php-package? package)+ "Return true if PACKAGE is a PHP package from Packagist."+ (and+ (eq? (build-system-name (package-build-system package)) 'composer)+ (string-prefix? "php-" (package-name package))))++(define (latest-release package)+ "Return an <upstream-source> for the latest release of PACKAGE."+ (let* ((php-name (guix-package->composer-name package))+ (metadata (composer-fetch php-name))+ (version (fix-version (assoc-ref metadata "version")))+ (url (assoc-ref (assoc-ref metadata "source") "url")))+ (upstream-source+ (package (package-name package))+ (version version)+ (urls (list url)))))++(define %composer-updater+ (upstream-updater+ (name 'composer)+ (description "Updater for Composer packages")+ (pred php-package?)+ (latest latest-release)))++(define* (composer-recursive-import package-name #:optional version)+ (recursive-import package-name '()+ #:repo->guix-package composer->guix-package+ #:guix-name php-package-name))diff --git a/guix/scripts/import.scm b/guix/scripts/import.scmindex 0a3863f965..23da295e48 100644--- a/guix/scripts/import.scm+++ b/guix/scripts/import.scm@@ -77,7 +77,7 @@ rather than \\n." ;;; (define importers '("gnu" "nix" "pypi" "cpan" "hackage" "stackage" "elpa" "gem"- "cran" "crate" "texlive" "json" "opam"))+ "cran" "crate" "texlive" "json" "opam" "composer")) (define (resolve-importer name) (let ((module (resolve-interfacediff --git a/guix/scripts/import/composer.scm b/guix/scripts/import/composer.scmnew file mode 100644index 0000000000..412bae6318--- /dev/null+++ b/guix/scripts/import/composer.scm@@ -0,0 +1,107 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2015 David Thompson <davet@gnu.org>+;;; Copyright © 2018 Oleg Pykhalov <go.wigust@gmail.com>+;;;+;;; 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/>.++(define-module (guix scripts import composer)+ #:use-module (guix ui)+ #:use-module (guix utils)+ #:use-module (guix scripts)+ #:use-module (guix import composer)+ #:use-module (guix scripts import)+ #:use-module (srfi srfi-1)+ #:use-module (srfi srfi-11)+ #:use-module (srfi srfi-37)+ #:use-module (srfi srfi-41)+ #:use-module (ice-9 match)+ #:use-module (ice-9 format)+ #:export (guix-import-composer))++ +;;;+;;; Command-line options.+;;;++(define %default-options+ '())++(define (show-help)+ (display (G_ "Usage: guix import composer PACKAGE-NAME+Import and convert the Composer package for PACKAGE-NAME.\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 Composer 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 composer")))+ (option '(#\r "recursive") #f #f+ (lambda (opt name arg result)+ (alist-cons 'recursive #t result)))+ %standard-import-options))++ +;;;+;;; Entry point.+;;;++(define (guix-import-composer . args)+ (define (parse-options)+ ;; Return the alist of option values.+ (args-fold* args %options+ (lambda (opt name arg result)+ (leave (G_ "~A: unrecognized option~%") name))+ (lambda (arg result)+ (alist-cons 'argument arg result))+ %default-options))++ (let* ((opts (parse-options))+ (args (filter-map (match-lambda+ (('argument . value)+ value)+ (_ #f))+ (reverse opts))))+ (match args+ ((package-name)+ (if (assoc-ref opts 'recursive)+ (map (match-lambda+ ((and ('package ('name name) . rest) pkg)+ `(define-public ,(string->symbol name)+ ,pkg))+ (_ #f))+ (composer-recursive-import package-name))+ (let ((sexp (composer->guix-package package-name)))+ (unless sexp+ (leave (G_ "failed to download meta-data for package '~a'~%")+ package-name))+ sexp)))+ (()+ (leave (G_ "too few arguments~%")))+ ((many ...)+ (leave (G_ "too many arguments~%"))))))diff --git a/tests/composer.scm b/tests/composer.scmnew file mode 100644index 0000000000..cefaf9f434--- /dev/null+++ b/tests/composer.scm@@ -0,0 +1,92 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2020 Julien Lepiller <julien@lepiller.eu>+;;;+;;; 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/>.++(define-module (test-composer)+ #:use-module (guix import composer)+ #:use-module (guix base32)+ #:use-module (gcrypt hash)+ #:use-module (guix tests http)+ #:use-module (guix grafts)+ #:use-module (srfi srfi-64)+ #:use-module (web client)+ #:use-module (ice-9 match))++;; Globally disable grafts because they can trigger early builds.+(%graft? #f)++(define test-json+ "{+ \"packages\": {+ \"foo/bar\": {+ \"0.1\": {+ \"name\": \"foo/bar\",+ \"description\": \"description\",+ \"keywords\": [\"testing\"],+ \"homepage\": \"http://example.com\",+ \"version\": \"0.1\",+ \"license\": [\"BSD-3-Clause\"],+ \"source\": {+ \"type\": \"url\",+ \"url\": \"http://example.com/Bar-0.1.tar.gz\"+ },+ \"require\": {},+ \"require-dev\": {\"phpunit/phpunit\": \"1.0.0\"}+ }+ }+ }+}")++(define test-source+ "foobar")++;; Avoid collisions with other tests.+(%http-server-port 10450)++(test-begin "composer")++(test-assert "composer->guix-package"+ ;; Replace network resources with sample data.+ (with-http-server `((200 ,test-json)+ (200 ,test-source))+ (parameterize ((%composer-base-url (%local-url))+ (current-http-proxy (%local-url)))+ (match (composer->guix-package "foo/bar")+ (('package+ ('name "php-foo-bar")+ ('version "0.1")+ ('source ('origin+ ('method 'url-fetch)+ ('uri "http://example.com/Bar-0.1.tar.gz")+ ('sha256+ ('base32+ (? string? hash)))))+ ('build-system 'composer-build-system)+ ('native-inputs+ ('quasiquote+ (("php-phpunit-phpunit" ('unquote 'php-phpunit-phpunit)))))+ ('synopsis "")+ ('description "description")+ ('home-page "http://example.com")+ ('license 'license:bsd-3))+ (string=? (bytevector->nix-base32-string+ (call-with-input-string test-source port-sha256))+ hash))+ (x+ (pk 'fail x #f))))))++(test-end "composer")-- 2.28.0
J
J
Julien Lepiller wrote on 18 Sep 2020 00:44
Re: [bug#42338] [PATCH 03/34] guix: Add composer-build-system.
(name . Ludovic Courtès)(address . ludo@gnu.org)(address . 42338@debbugs.gnu.org)
20200918004403.0d755d60@tachikoma.lepiller.eu
Le Mon, 07 Sep 2020 16:09:01 +0200,Ludovic Courtès <ludo@gnu.org> a écrit :
Toggle quote (55 lines)> Julien Lepiller <julien@lepiller.eu> skribis:> > > * guix/build-system/composer.scm: New file.> > * guix/build/composer-build-system.scm: New file.> > * guix/build-system/findclass.php: New file.> > * Makefile.am: Add them.> > * doc/guix.texi (Build Systems): Document it. > > [...]> > > +++ b/guix/build-system/findclass.php> > @@ -0,0 +1,102 @@> > +<?php> > +/**> > + * Extract the classes in the given file> > + *> > + * @param string $path The file to check> > + * @throws \RuntimeException> > + * @return array The found classes> > + */ > > This should rather be under gnu/packages/aux-files IMO. Also, could> you add a copyright header and possibly info as to where it> originates?> > > +(define* (create-autoload vendor composer-file inputs #:key> > dev-dependencies?)> > + (with-output-to-file (string-append vendor "/autoload.php")> > + (lambda _> > + (format #t "<?php~%")> > + (format #t "// autoload.php @generated by Guix~%")> > + (format #t "$map = $psr4map = $classmap = array();~%")> > + (format #t "require_once '~a/autoload_conf.php';~%" vendor)> > + (format #t "require_once> > '~a/share/web/composer/ClassLoader.php';~%"> > + (assoc-ref inputs "composer-classloader"))> > + (format #t "$loader = new> > \\Composer\\Autoload\\ClassLoader();~%")> > + (format #t "foreach ($map as $namespace => $path) {~%")> > + (format #t " $loader->set($namespace, $path);~%")> > + (format #t "}~%")> > + (format #t "foreach ($psr4map as $namespace => $path) {~%")> > + (format #t " $loader->setPsr4($namespace, $path);~%")> > + (format #t "}~%")> > + (format #t "$loader->addClassMap($classmap);~%")> > + (format #t "$loader->register();~%"))) > > I think it’d be clearer as a single string:> > (display "\> <?php> // autoload.php …")> > Ludo’.
Thanks, here's a new version
From bb5d102b6ea5e6b5c06bbf90a58927c6180e23bc Mon Sep 17 00:00:00 2001From: Julien Lepiller <julien@lepiller.eu>Date: Tue, 29 Oct 2019 20:58:51 +0100Subject: [PATCH 03/34] guix: Add composer-build-system.
* guix/build-system/composer.scm: New file.* guix/build/composer-build-system.scm: New file.* gnu/packages/aux-files/findclass.php: New file.* Makefile.am: Add them.* doc/guix.texi (Build Systems): Document it.--- Makefile.am | 5 +- doc/guix.texi | 14 ++ gnu/packages/aux-files/findclass.php | 125 +++++++++++++++ guix/build-system/composer.scm | 170 ++++++++++++++++++++ guix/build/composer-build-system.scm | 226 +++++++++++++++++++++++++++ 5 files changed, 539 insertions(+), 1 deletion(-) create mode 100644 gnu/packages/aux-files/findclass.php create mode 100644 guix/build-system/composer.scm create mode 100644 guix/build/composer-build-system.scm
Toggle diff (596 lines)diff --git a/Makefile.am b/Makefile.amindex 6ce1430ea6..5af964b0e9 100644--- a/Makefile.am+++ b/Makefile.am@@ -115,6 +115,7 @@ MODULES = \ guix/build-system/cargo.scm \ guix/build-system/clojure.scm \ guix/build-system/cmake.scm \+ guix/build-system/composer.scm \ guix/build-system/dub.scm \ guix/build-system/dune.scm \ guix/build-system/emacs.scm \@@ -163,6 +164,7 @@ MODULES = \ guix/build/cargo-build-system.scm \ guix/build/cargo-utils.scm \ guix/build/cmake-build-system.scm \+ guix/build/composer-build-system.scm \ guix/build/dub-build-system.scm \ guix/build/dune-build-system.scm \ guix/build/emacs-build-system.scm \@@ -354,7 +356,8 @@ AUX_FILES = \ gnu/packages/aux-files/linux-libre/4.4-i686.conf \ gnu/packages/aux-files/linux-libre/4.4-x86_64.conf \ gnu/packages/aux-files/pack-audit.c \- gnu/packages/aux-files/run-in-namespace.c+ gnu/packages/aux-files/run-in-namespace.c \+ gnu/packages/aux-files/findclass.php # Templates, examples. EXAMPLES = \diff --git a/doc/guix.texi b/doc/guix.texiindex ca4eb347c7..6ee4d7e5f0 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -6941,6 +6941,20 @@ debugging information''), which roughly means that code is compiled with @code{-O2 -g}, as is the case for Autoconf-based packages by default. @end defvr +@defvr {Scheme Variable} composer-build-system+This variable is exported by @code{(guix build-system composer)}. It+implements the build procedure for packages using+@url{https://getcomposer.org/, Composer}, the PHP package manager.++It automatically adds the @code{php} package to the set of inputs. Which+package is used can be specified with the @code{#:php} parameter.++The @code{#:test-target} parameter is used to control which script is run+for the tests. By default, the @code{test} script is run if it exists. If+the script does not exist, the build system will run @code{phpunit} from the+source directory, assuming there is a @file{phpunit.xml} file.+@end defvr+ @defvr {Scheme Variable} dune-build-system This variable is exported by @code{(guix build-system dune)}. It supports builds of packages using @uref{https://dune.build/, Dune}, a builddiff --git a/gnu/packages/aux-files/findclass.php b/gnu/packages/aux-files/findclass.phpnew file mode 100644index 0000000000..d0b250c8e1--- /dev/null+++ b/gnu/packages/aux-files/findclass.php@@ -0,0 +1,125 @@+<?php+/**+ * The content of this file is copied from composer's src/Composer/Autoload/ClassMapGenerator.php+ * the findClasses method was extracted, to prevent using any dependency.+ *+ * Composer (and thus this file) is distributed under the expat license, and+ * ClassMapGenerator.php also contains this notice:+ *+ * This file is part of Composer.+ *+ * (c) Nils Adermann <naderman@naderman.de>+ * Jordi Boggiano <j.boggiano@seld.be>+ *+ * For the full copyright and license information, please view the LICENSE+ * file that was distributed with this source code.+ *+ * This file is copied from the Symfony package.+ *+ * (c) Fabien Potencier <fabien@symfony.com>+ * + * To the extent to wich it makes sense, as the author of the extract:+ * Copyright © 2020 Julien Lepiller <julien@lepiller.eu>+ */++/**+ * Extract the classes in the given file+ *+ * @param string $path The file to check+ * @throws \RuntimeException+ * @return array The found classes+ */+function findClasses($path)+{+ $extraTypes = PHP_VERSION_ID < 50400 ? '' : '|trait';+ if (defined('HHVM_VERSION') && version_compare(HHVM_VERSION, '3.3', '>=')) {+ $extraTypes .= '|enum';+ }+ // Use @ here instead of Silencer to actively suppress 'unhelpful' output+ // @link https://github.com/composer/composer/pull/4886+ $contents = @php_strip_whitespace($path);+ if (!$contents) {+ if (!file_exists($path)) {+ $message = 'File at "%s" does not exist, check your classmap definitions';+ } elseif (!is_readable($path)) {+ $message = 'File at "%s" is not readable, check its permissions';+ } elseif ('' === trim(file_get_contents($path))) {+ // The input file was really empty and thus contains no classes+ return array();+ } else {+ $message = 'File at "%s" could not be parsed as PHP, it may be binary or corrupted';+ }+ $error = error_get_last();+ if (isset($error['message'])) {+ $message .= PHP_EOL . 'The following message may be helpful:' . PHP_EOL . $error['message'];+ }+ throw new \RuntimeException(sprintf($message, $path));+ }+ // return early if there is no chance of matching anything in this file+ if (!preg_match('{\b(?:class|interface'.$extraTypes.')\s}i', $contents)) {+ return array();+ }+ // strip heredocs/nowdocs+ $contents = preg_replace('{<<<[ \t]*([\'"]?)(\w+)\\1(?:\r\n|\n|\r)(?:.*?)(?:\r\n|\n|\r)(?:\s*)\\2(?=\s+|[;,.)])}s', 'null', $contents);+ // strip strings+ $contents = preg_replace('{"[^"\\\\]*+(\\\\.[^"\\\\]*+)*+"|\'[^\'\\\\]*+(\\\\.[^\'\\\\]*+)*+\'}s', 'null', $contents);+ // strip leading non-php code if needed+ if (substr($contents, 0, 2) !== '<?') {+ $contents = preg_replace('{^.+?<\?}s', '<?', $contents, 1, $replacements);+ if ($replacements === 0) {+ return array();+ }+ }+ // strip non-php blocks in the file+ $contents = preg_replace('{\?>(?:[^<]++|<(?!\?))*+<\?}s', '?><?', $contents);+ // strip trailing non-php code if needed+ $pos = strrpos($contents, '?>');+ if (false !== $pos && false === strpos(substr($contents, $pos), '<?')) {+ $contents = substr($contents, 0, $pos);+ }+ // strip comments if short open tags are in the file+ if (preg_match('{(<\?)(?!(php|hh))}i', $contents)) {+ $contents = preg_replace('{//.* | /\*(?:[^*]++|\*(?!/))*\*/}x', '', $contents);+ }+ preg_match_all('{+ (?:+ \b(?<![\$:>])(?P<type>class|interface'.$extraTypes.') \s++ (?P<name>[a-zA-Z_\x7f-\xff:][a-zA-Z0-9_\x7f-\xff:\-]*+)+ | \b(?<![\$:>])(?P<ns>namespace) (?P<nsname>\s++[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\s*+\\\\\s*+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)*+)? \s*+ [\{;]+ )+ }ix', $contents, $matches);+ $classes = array();+ $namespace = '';+ for ($i = 0, $len = count($matches['type']); $i < $len; $i++) {+ if (!empty($matches['ns'][$i])) {+ $namespace = str_replace(array(' ', "\t", "\r", "\n"), '', $matches['nsname'][$i]) . '\\';+ } else {+ $name = $matches['name'][$i];+ // skip anon classes extending/implementing+ if ($name === 'extends' || $name === 'implements') {+ continue;+ }+ if ($name[0] === ':') {+ // This is an XHP class, https://github.com/facebook/xhp+ $name = 'xhp'.substr(str_replace(array('-', ':'), array('_', '__'), $name), 1);+ } elseif ($matches['type'][$i] === 'enum') {+ // In Hack, something like:+ // enum Foo: int { HERP = '123'; }+ // The regex above captures the colon, which isn't part of+ // the class name.+ $name = rtrim($name, ':');+ }+ $classes[] = ltrim($namespace . $name, '\\');+ }+ }+ return $classes;+}++$options = getopt('i:f:', []);+$file = $options["f"];+$input = $options["i"];++$classes = findClasses($file);+foreach($classes as $class) {+ echo '$classmap[\''.$class.'\'] = \''.$input.'/'.$file.'\';';+ echo "\n";+}diff --git a/guix/build-system/composer.scm b/guix/build-system/composer.scmnew file mode 100644index 0000000000..ebc472c717--- /dev/null+++ b/guix/build-system/composer.scm@@ -0,0 +1,170 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2019 Julien Lepiller <julien@lepiller.eu>+;;;+;;; 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/>.+(define-module (guix build-system composer)+ #:use-module (guix store)+ #:use-module (guix utils)+ #:use-module (guix derivations)+ #:use-module (guix search-paths)+ #:use-module (guix build-system)+ #:use-module (guix build-system gnu)+ #:use-module (guix gexp)+ #:use-module (guix packages)+ #:use-module (gnu packages)+ #:use-module (ice-9 match)+ #:use-module (srfi srfi-1)+ #:export (%composer-build-system-modules+ lower+ composer-build+ composer-build-system))++;; Commentary:+;;+;; Standard build procedure for PHP packages using Composer. This is implemented+;; as an extension of `gnu-build-system'.+;;+;; Code:++(define (default-php)+ "Return the default PHP package."++ ;; Do not use `@' to avoid introducing circular dependencies.+ (let ((module (resolve-interface '(gnu packages php))))+ (module-ref module 'php)))++(define (default-findclass)+ "Return the default findclass script."+ (search-auxiliary-file "findclass.php"))++(define (default-composer-classloader)+ "Return the default composer-classloader package."++ ;; Do not use `@' to avoid introducing circular dependencies.+ (let ((module (resolve-interface '(gnu packages php-xyz))))+ (module-ref module 'composer-classloader)))++(define %composer-build-system-modules+ ;; Build-side modules imported by default.+ `((guix build composer-build-system)+ (guix build json)+ (guix build union)+ ,@%gnu-build-system-modules))++(define* (lower name+ #:key source inputs native-inputs outputs system target+ (php (default-php))+ (composer-classloader (default-composer-classloader))+ (findclass (default-findclass))+ #:allow-other-keys+ #:rest arguments)+ "Return a bag for NAME."+ (define private-keywords+ '(#:source #:target #:php #:composer-classloader #:findclass #:inputs #:native-inputs))++ (and (not target) ;XXX: no cross-compilation+ (bag+ (name name)+ (system system)+ (host-inputs `(,@(if source+ `(("source" ,source))+ '())+ ,@inputs++ ;; Keep the standard inputs of 'gnu-build-system'.+ ,@(standard-packages)))+ (build-inputs `(("php" ,php)+ ("findclass.php" ,findclass)+ ("composer-classloader" ,composer-classloader)+ ,@native-inputs))+ (outputs outputs)+ (build composer-build)+ (arguments (strip-keyword-arguments private-keywords arguments)))))++(define* (composer-build store name inputs+ #:key (guile #f)+ (outputs '("out")) (configure-flags ''())+ (search-paths '())+ (out-of-source? #t)+ (composer-file "composer.json")+ (tests? #t)+ (test-target "test")+ (install-target "install")+ (validate-runpath? #t)+ (patch-shebangs? #t)+ (strip-binaries? #t)+ (strip-flags ''("--strip-debug"))+ (strip-directories ''("lib" "lib64" "libexec"+ "bin" "sbin"))+ (phases '(@ (guix build composer-build-system)+ %standard-phases))+ (system (%current-system))+ (imported-modules %composer-build-system-modules)+ (modules '((guix build composer-build-system)+ (guix build json)+ (guix build utils))))+ "Build SOURCE using PHP, and with INPUTS. This assumes that SOURCE provides+a 'composer.json' file as its build system."+ (define builder+ `(begin+ (use-modules ,@modules)+ (composer-build #:source ,(match (assoc-ref inputs "source")+ (((? derivation? source))+ (derivation->output-path source))+ ((source)+ source)+ (source+ source))+ #:system ,system+ #:outputs %outputs+ #:inputs %build-inputs+ #:search-paths ',(map search-path-specification->sexp+ search-paths)+ #:phases ,phases+ #:out-of-source? ,out-of-source?+ #:composer-file ,composer-file+ #:tests? ,tests?+ #:test-target ,test-target+ #:install-target ,install-target+ #:validate-runpath? ,validate-runpath?+ #:patch-shebangs? ,patch-shebangs?+ #:strip-binaries? ,strip-binaries?+ #:strip-flags ,strip-flags+ #:strip-directories ,strip-directories)))++ (define guile-for-build+ (match guile+ ((? package?)+ (package-derivation store guile system #:graft? #f))+ (#f ; the default+ (let* ((distro (resolve-interface '(gnu packages commencement)))+ (guile (module-ref distro 'guile-final)))+ (package-derivation store guile system #:graft? #f)))))++ (build-expression->derivation store name builder+ #:system system+ #:inputs inputs+ #:modules imported-modules+ #:outputs outputs+ #:guile-for-build guile-for-build))++(define composer-build-system+ (build-system+ (name 'composer)+ (description "The standard Composer build system")+ (lower lower)))++;;; composer.scm ends herediff --git a/guix/build/composer-build-system.scm b/guix/build/composer-build-system.scmnew file mode 100644index 0000000000..f73684f8d5--- /dev/null+++ b/guix/build/composer-build-system.scm@@ -0,0 +1,226 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2019 Julien Lepiller <julien@lepiller.eu>+;;;+;;; 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/>.++(define-module (guix build composer-build-system)+ #:use-module ((guix build gnu-build-system) #:prefix gnu:)+ #:use-module (guix build json)+ #:use-module (guix build utils)+ #:use-module (ice-9 match)+ #:export (%standard-phases+ composer-build))++;; Commentary:+;;+;; Builder-side code of the standard composer build procedure.+;;+;; Code:++(define* (read-package-data #:key (filename "composer.json"))+ (call-with-input-file filename+ (lambda (port)+ (read-json port))))++(define* (check #:key composer-file inputs outputs tests? test-target #:allow-other-keys)+ "Install the given package."+ (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 (match (assoc-ref package-data "scripts")+ (('@ script ...) script)+ (#f '())))+ (test-script+ (assoc-ref scripts test-target))+ (dependencies (filter (lambda (dep) (string-contains dep "/"))+ (map car+ (match (assoc-ref package-data "require")+ (('@ dependency ...) dependency)+ (#f '())))))+ (dependencies-dev+ (filter (lambda (dep) (string-contains dep "/"))+ (map car+ (match (assoc-ref package-data "require-dev")+ (('@ dependency ...) dependency)+ (#f '())))))+ (name (assoc-ref package-data "name")))+ (for-each+ (lambda (input)+ (let ((bin (find-php-bin (cdr input))))+ (when bin+ (copy-recursively bin "vendor/bin"))))+ inputs)+ (match test-script+ ((? string? command)+ (unless (equal? (system command) 0)+ (throw 'failed-command command)))+ (('@ (? string? command) ...)+ (for-each+ (lambda (c)+ (unless (equal? (system c) 0)+ (throw 'failed-command c)))+ command))+ (#f (invoke "vendor/bin/phpunit")))))+ #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-php-dep inputs dependency)+ (let loop ((inputs (map cdr inputs)))+ (if (null? inputs)+ (throw 'unsatisfied-dependency "Unsatisfied dependency: required " dependency)+ (let ((autoload (string-append (car inputs) "/share/web/" dependency "/vendor/autoload_conf.php")))+ (if (file-exists? autoload)+ autoload+ (loop (cdr inputs)))))))++(define* (create-autoload vendor composer-file inputs #:key dev-dependencies?)+ (with-output-to-file (string-append vendor "/autoload.php")+ (lambda _+ (display "<?php+// autoload.php @generated by Guix+$map = $psr4map = $classmap = array();+")+ (format #t "require_once '~a/autoload_conf.php'~%" vendor)+ (format #t "require_once '~a/share/web/composer/ClassLoader.php'~%"+ (assoc-ref inputs "composer-classloader"))+ (display "$loader = new \\Composer\\Autoload\\ClassLoader();+foreach ($map as $namespace => $path) {+ $loader->set($namespace, $path);+}+foreach ($psr4map as $namespace => $path) {+ $loader->setPsr4($namespace, $path);+}+$loader->addClassMap($classmap);+$loader->register();+")))+ (let* ((package-data (read-package-data #:filename composer-file))+ (autoload+ (match (assoc-ref package-data "autoload")+ (('@ autoload ...) autoload)+ (#f '())))+ (autoload-dev+ (match (assoc-ref package-data "autoload-dev")+ (('@ autoload-dev ...) autoload-dev)+ (#f '())))+ (dependencies (filter (lambda (dep) (string-contains dep "/"))+ (map car+ (match (assoc-ref package-data "require")+ (('@ dependency ...) dependency)+ (#f '())))))+ (dependencies-dev+ (filter (lambda (dep) (string-contains dep "/"))+ (map car+ (match (assoc-ref package-data "require-dev")+ (('@ dependency ...) dependency)+ (#f '()))))))+ (with-output-to-file (string-append vendor "/autoload_conf.php")+ (lambda _+ (format #t "<?php~%")+ (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))))+ (append+ (match (assoc-ref autoload "psr-4")+ (('@ psr4 ...) psr4)+ (#f '()))+ (if dev-dependencies?+ (match (assoc-ref autoload-dev "psr-4")+ (('@ psr4 ...) psr4)+ (#f '()))+ '())))+ (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+ (or (assoc-ref autoload "classmap") '())+ (if dev-dependencies?+ (or (assoc-ref autoload-dev "classmap") '())+ '())))+ (for-each+ (lambda (dep)+ (format #t "require_once '~a';~%" (find-php-dep inputs dep)))+ (append+ dependencies+ (if dev-dependencies?+ dependencies-dev+ '())))))))++(define* (install #:key inputs outputs composer-file #:allow-other-keys)+ "Install the given package."+ (let* ((out (assoc-ref outputs "out"))+ (package-data (read-package-data #:filename composer-file))+ (name (assoc-ref package-data "name"))+ (php-dir (string-append out "/share/web/" name))+ (bin-dir (string-append php-dir "/vendor/bin"))+ (bin (string-append out "/bin"))+ (binaries (assoc-ref package-data "bin")))+ (mkdir-p php-dir)+ (copy-recursively "." php-dir)+ (mkdir-p (string-append php-dir "/vendor"))+ (when binaries+ (mkdir-p bin-dir)+ (mkdir-p bin)+ (for-each+ (lambda (file)+ (let ((installed-file (string-append bin-dir "/" (basename file)))+ (bin-file (string-append bin "/" (basename file)))+ (original-file (string-append php-dir "/" file)))+ (symlink original-file installed-file)+ (symlink original-file bin-file)))+ binaries))+ (create-autoload (string-append php-dir "/vendor")+ composer-file inputs))+ #t)++(define %standard-phases+ ;; Everything is as with the GNU Build System except for the `configure'+ ;; , `build', `check' and `install' phases.+ (modify-phases gnu:%standard-phases+ (delete 'bootstrap)+ (delete 'configure)+ (delete 'build)+ (delete 'check)+ (replace 'install install)+ (add-after 'install 'check check)))++(define* (composer-build #:key inputs (phases %standard-phases)+ #:allow-other-keys #:rest args)+ "Build the given package, applying all of PHASES in order."+ (apply gnu:gnu-build #:inputs inputs #:phases phases args))++;;; composer-build-system.scm ends here-- 2.28.0
L
L
Ludovic Courtès wrote on 18 Sep 2020 10:31
Re: [bug#42338] [PATCH 01/34] guix: import: Add composer importer.
(name . Julien Lepiller)(address . julien@lepiller.eu)(address . 42338@debbugs.gnu.org)
87sgbf1o5w.fsf@gnu.org
Hi!
Julien Lepiller <julien@lepiller.eu> skribis:
Toggle quote (12 lines)> From 6d521ca9f066f82488abefd5d3630e38305c0fd1 Mon Sep 17 00:00:00 2001> From: Julien Lepiller <julien@lepiller.eu>> Date: Tue, 29 Oct 2019 08:07:38 +0100> Subject: [PATCH 01/34] guix: import: Add composer importer.>> * guix/import/composer.scm: New file.> * guix/scripts/import/composer.scm: New file.> * guix/tests/composer.scm: New file.> * Makefile.am: Add them.> * guix/scripts/import.scm: Add composer importer.> * doc/guix.texi (Invoking guix import): Mention it.
[...]
Toggle quote (3 lines)> +@item composer> +@cindex COMPOSER
s/COMPOSER/Composer/ ?
Toggle quote (1 lines)> +Import metadat from the @uref{https://getcomposer.org/,Composer} package
^metadata
Toggle quote (2 lines)> +archive used by the PHP community.
Could you add an example command line like we have for some of the otherimporters? (It’s also useful for us as a test against the actual servers…)
Toggle quote (11 lines)> + (let ((package (json-fetch> + (string-append (%composer-base-url) "/p/" name ".json"))))> + (if package> + (let* ((packages (assoc-ref package "packages"))> + (package (assoc-ref packages name))> + (versions (filter> + (lambda (version)> + (and (not (string-contains version "dev"))> + (not (string-contains version "beta"))))> + (map car package)))
Like I wrote before, I recommend ‘define-json-mapping’. If you preferyou can make that change later on once you’ve pushed this first version,but I really think it’ll help maintainability.
This should also help avoid (map car …), which is frowned upon in Guix.:-)
Toggle quote (3 lines)> + (versions (map> + (lambda (version)
Rather indent as: (map (lambda (version)
Otherwise LGTM!
Ludo’.
L
L
Ludovic Courtès wrote on 18 Sep 2020 10:45
Re: [bug#42338] [PATCH 03/34] guix: Add composer-build-system.
(name . Julien Lepiller)(address . julien@lepiller.eu)(address . 42338@debbugs.gnu.org)
87eemz1nib.fsf@gnu.org
Hi,
Julien Lepiller <julien@lepiller.eu> skribis:
Toggle quote (11 lines)> From bb5d102b6ea5e6b5c06bbf90a58927c6180e23bc Mon Sep 17 00:00:00 2001> From: Julien Lepiller <julien@lepiller.eu>> Date: Tue, 29 Oct 2019 20:58:51 +0100> Subject: [PATCH 03/34] guix: Add composer-build-system.>> * guix/build-system/composer.scm: New file.> * guix/build/composer-build-system.scm: New file.> * gnu/packages/aux-files/findclass.php: New file.> * Makefile.am: Add them.> * doc/guix.texi (Build Systems): Document it.
[...]
Toggle quote (3 lines)> --- /dev/null> +++ b/gnu/packages/aux-files/findclass.php
I can’t believe we’ll have PHP in our code base. :-)
Toggle quote (4 lines)> +;;; You should have received a copy of the GNU General Public License> +;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.> +(define-module (guix build-system composer)
Missing newline.
Toggle quote (19 lines)> + (let* ((package-data (read-package-data #:filename composer-file))> + (scripts (match (assoc-ref package-data "scripts")> + (('@ script ...) script)> + (#f '())))> + (test-script> + (assoc-ref scripts test-target))> + (dependencies (filter (lambda (dep) (string-contains dep "/"))> + (map car> + (match (assoc-ref package-data "require")> + (('@ dependency ...) dependency)> + (#f '())))))> + (dependencies-dev> + (filter (lambda (dep) (string-contains dep "/"))> + (map car> + (match (assoc-ref package-data "require-dev")> + (('@ dependency ...) dependency)> + (#f '())))))> + (name (assoc-ref package-data "name")))
This is also a case for ‘define-json-mapping’. I suppose we could useGuile-JSON instead of (guix build json), no?
I think this code and similar occurrences would be less intimidating ifwe used ‘define-json-mapping’; it would make the data structuresclearer, unlike here where one has to keep in mind what the list/treelooks like so they can map car/cdr around.
Toggle quote (3 lines)> + (for-each> + (lambda (input)
Like for ‘map’, please indent on the same line:
(for-each (lambda (input)
Toggle quote (11 lines)> + (match test-script> + ((? string? command)> + (unless (equal? (system command) 0)> + (throw 'failed-command command)))> + (('@ (? string? command) ...)> + (for-each> + (lambda (c)> + (unless (equal? (system c) 0)> + (throw 'failed-command c)))> + command))
Use (zero? x) instead of (equal? 0 x).
Also, why not use ‘invoke’? I this because these commands are reallyshell commands and expect things like glob patterns and tilde expansion?If these are not shell commands, I recommend ‘invoke’, which will reportfailures more nicely.
Toggle quote (9 lines)> +(define (find-php-dep inputs dependency)> + (let loop ((inputs (map cdr inputs)))> + (if (null? inputs)> + (throw 'unsatisfied-dependency "Unsatisfied dependency: required " dependency)> + (let ((autoload (string-append (car inputs) "/share/web/" dependency "/vendor/autoload_conf.php")))> + (if (file-exists? autoload)> + autoload> + (loop (cdr inputs)))))))
Please use ‘match’ instead of car/cdr.
Toggle quote (21 lines)> +(define* (create-autoload vendor composer-file inputs #:key dev-dependencies?)> + (with-output-to-file (string-append vendor "/autoload.php")> + (lambda _> + (display "<?php> +// autoload.php @generated by Guix> +$map = $psr4map = $classmap = array();> +")> + (format #t "require_once '~a/autoload_conf.php'~%" vendor)> + (format #t "require_once '~a/share/web/composer/ClassLoader.php'~%"> + (assoc-ref inputs "composer-classloader"))> + (display "$loader = new \\Composer\\Autoload\\ClassLoader();> +foreach ($map as $namespace => $path) {> + $loader->set($namespace, $path);> +}> +foreach ($psr4map as $namespace => $path) {> + $loader->setPsr4($namespace, $path);> +}> +$loader->addClassMap($classmap);> +$loader->register();> +")))
Please add a docstring explaining what’s happening here. Also, perhapsuse ‘string-append’ instead of ‘format’ so we don’t end up generatingthings like:
require_once '#f/autoload_conf.php'
:-)
In short, I think we must pay attention to the style to facilitatemaintainability.
Could you send an updated patch?
Thanks!
Ludo’.
J
J
Julien Lepiller wrote on 19 Sep 2020 01:20
Re: [bug#42338] [PATCH 01/34] guix: import: Add composer importer.
(name . Ludovic Courtès)(address . ludo@gnu.org)(address . 42338@debbugs.gnu.org)
20200919012055.1b2e686f@tachikoma.lepiller.eu
Le Fri, 18 Sep 2020 10:31:39 +0200,Ludovic Courtès <ludo@gnu.org> a écrit :
Toggle quote (64 lines)> Hi!> > Julien Lepiller <julien@lepiller.eu> skribis:> > > From 6d521ca9f066f82488abefd5d3630e38305c0fd1 Mon Sep 17 00:00:00> > 2001 From: Julien Lepiller <julien@lepiller.eu>> > Date: Tue, 29 Oct 2019 08:07:38 +0100> > Subject: [PATCH 01/34] guix: import: Add composer importer.> >> > * guix/import/composer.scm: New file.> > * guix/scripts/import/composer.scm: New file.> > * guix/tests/composer.scm: New file.> > * Makefile.am: Add them.> > * guix/scripts/import.scm: Add composer importer.> > * doc/guix.texi (Invoking guix import): Mention it. > > [...]> > > +@item composer> > +@cindex COMPOSER > > s/COMPOSER/Composer/ ?> > > +Import metadat from the @uref{https://getcomposer.org/, Composer}> > package > ^> metadata> > > +archive used by the PHP community. > > Could you add an example command line like we have for some of the> other importers? (It’s also useful for us as a test against the> actual servers…)> > > + (let ((package (json-fetch> > + (string-append (%composer-base-url) "/p/" name> > ".json"))))> > + (if package> > + (let* ((packages (assoc-ref package "packages"))> > + (package (assoc-ref packages name))> > + (versions (filter> > + (lambda (version)> > + (and (not (string-contains version> > "dev"))> > + (not (string-contains version> > "beta"))))> > + (map car package))) > > Like I wrote before, I recommend ‘define-json-mapping’. If you prefer> you can make that change later on once you’ve pushed this first> version, but I really think it’ll help maintainability.> > This should also help avoid (map car …), which is frowned upon in> Guix. :-)> > > + (versions (map> > + (lambda (version) > > Rather indent as: (map (lambda (version)> > Otherwise LGTM! > > Ludo’.
Thanks, here's a new version
From 70b9cb2bb389f3e5f9dcc75a44d7d60c28f997bc Mon Sep 17 00:00:00 2001From: Julien Lepiller <julien@lepiller.eu>Date: Tue, 29 Oct 2019 08:07:38 +0100Subject: [PATCH 01/34] guix: import: Add composer importer.
* guix/import/composer.scm: New file.* guix/scripts/import/composer.scm: New file.* guix/tests/composer.scm: New file.* Makefile.am: Add them.* guix/scripts/import.scm: Add composer importer.* doc/guix.texi (Invoking guix import): Mention it.--- Makefile.am | 3 + doc/guix.texi | 11 ++ guix/import/composer.scm | 270 +++++++++++++++++++++++++++++++ guix/scripts/import.scm | 2 +- guix/scripts/import/composer.scm | 107 ++++++++++++ tests/composer.scm | 92 +++++++++++ 6 files changed, 484 insertions(+), 1 deletion(-) create mode 100644 guix/import/composer.scm create mode 100644 guix/scripts/import/composer.scm create mode 100644 tests/composer.scm
Toggle diff (552 lines)diff --git a/Makefile.am b/Makefile.amindex 8e91e1e558..6ce1430ea6 100644--- a/Makefile.am+++ b/Makefile.am@@ -223,6 +223,7 @@ MODULES = \ guix/search-paths.scm \ guix/packages.scm \ guix/import/cabal.scm \+ guix/import/composer.scm \ guix/import/cpan.scm \ guix/import/cran.scm \ guix/import/crate.scm \@@ -269,6 +270,7 @@ MODULES = \ guix/scripts/system/reconfigure.scm \ guix/scripts/lint.scm \ guix/scripts/challenge.scm \+ guix/scripts/import/composer.scm \ guix/scripts/import/crate.scm \ guix/scripts/import/cran.scm \ guix/scripts/import/elpa.scm \@@ -402,6 +404,7 @@ SCM_TESTS = \ tests/challenge.scm \ tests/channels.scm \ tests/combinators.scm \+ tests/composer.scm \ tests/containers.scm \ tests/cpan.scm \ tests/cpio.scm \diff --git a/doc/guix.texi b/doc/guix.texiindex 88128a4b3a..5d29567153 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -10164,6 +10164,17 @@ in Guix. @cindex OCaml Import metadata from the @uref{https://opam.ocaml.org/, OPAM} package repository used by the OCaml community.++@item composer+@cindex Composer+@cindex PHP+Import metadat from the @uref{https://getcomposer.org/, Composer} package+archive used by the PHP community, as in this example:++@example+guix import composer phpunit/phpunit+@end example+ @end table The structure of the @command{guix import} code is modular. It would bediff --git a/guix/import/composer.scm b/guix/import/composer.scmnew file mode 100644index 0000000000..9b284d0dd2--- /dev/null+++ b/guix/import/composer.scm@@ -0,0 +1,270 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2019 Julien Lepiller <julien@lepiller.eu>+;;;+;;; 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/>.++(define-module (guix import composer)+ #:use-module (ice-9 match)+ #:use-module (json)+ #:use-module (gcrypt hash)+ #:use-module (guix base32)+ #:use-module (guix build git)+ #:use-module (guix build utils)+ #:use-module (guix build-system)+ #:use-module (guix import json)+ #:use-module (guix import utils)+ #:use-module ((guix licenses) #:prefix license:)+ #:use-module (guix packages)+ #:use-module (guix serialization)+ #:use-module (guix upstream)+ #:use-module (guix utils)+ #:use-module (srfi srfi-1)+ #:use-module (srfi srfi-11)+ #:use-module (srfi srfi-26)+ #:export (composer->guix-package+ %composer-updater+ composer-recursive-import++ %composer-base-url))++(define %composer-base-url+ (make-parameter "https://repo.packagist.org"))++;; XXX adapted from (guix scripts hash)+(define (file-hash file select? recursive?)+ ;; Compute the hash of FILE.+ (if recursive?+ (let-values (((port get-hash) (open-sha256-port)))+ (write-file file port #:select? select?)+ (force-output port)+ (get-hash))+ (call-with-input-file file port-sha256)))++;; XXX taken from (guix scripts hash)+(define (vcs-file? file stat)+ (case (stat:type stat)+ ((directory)+ (member (basename file) '(".bzr" ".git" ".hg" ".svn" "CVS")))+ ((regular)+ ;; Git sub-modules have a '.git' file that is a regular text file.+ (string=? (basename file) ".git"))+ (else+ #f)))++(define (fix-version version)+ "Return a fixed version from a version string. For instance, v10.1 -> 10.1"+ (cond+ ((string-prefix? "version" version)+ (if (char-set-contains? char-set:digit (string-ref version 7))+ (substring version 7)+ (substring version 8)))+ ((string-prefix? "v" version)+ (substring version 1))+ (else version)))++(define (latest-version versions)+ (fold (lambda (a b) (if (version>? (fix-version a) (fix-version b)) a b))+ (car versions) versions))++(define (json->require dict)+ (if dict+ (let loop ((result '()) (require dict))+ (match require+ (() result)+ ((((? (cut string-contains <> "/") name) . _)+ require ...)+ (loop (cons name result) require))+ ((_ require ...) (loop result require))))+ '()))++(define-json-mapping <composer-source> make-composer-source composer-source?+ json->composer-source+ (type composer-source-type)+ (url composer-source-url)+ (reference composer-source-reference))++(define-json-mapping <composer-package> make-composer-package composer-package?+ json->composer-package+ (description composer-package-description)+ (homepage composer-package-homepage)+ (source composer-package-source "source" json->composer-source)+ (name composer-package-name "name" php-package-name)+ (version composer-package-version "version" fix-version)+ (require composer-package-require "require" json->require)+ (dev-require composer-package-dev-require "require-dev" json->require)+ (license composer-package-license "license"+ (lambda (vector)+ (map string->license (vector->list vector)))))++(define* (composer-fetch name #:optional version)+ "Return an alist representation of the Composer metadata for the package NAME,+or #f on failure."+ (let ((package (json-fetch+ (string-append (%composer-base-url) "/p/" name ".json"))))+ (if package+ (let* ((packages (assoc-ref package "packages"))+ (package (or (assoc-ref packages name) package))+ (versions (filter+ (lambda (version)+ (and (not (string-contains version "dev"))+ (not (string-contains version "beta"))))+ (map car package)))+ (version (or (if (null? version) #f version)+ (latest-version versions))))+ (assoc-ref package version))+ #f)))++(define (php-package-name name)+ "Given the NAME of a package on Packagist, return a Guix-compliant name for+the package."+ (let ((name (string-join (string-split name #\/) "-")))+ (if (string-prefix? "php-" name)+ (snake-case name)+ (string-append "php-" (snake-case name)))))++(define (make-php-sexp composer-package)+ "Return the `package' s-expression for a PHP package for the given+COMPOSER-PACKAGE."+ (let* ((source (composer-package-source composer-package))+ (dependencies (map php-package-name+ (composer-package-require composer-package)))+ (dev-dependencies (map php-package-name+ (composer-package-dev-require composer-package)))+ (git? (equal? (composer-source-type source) "git")))+ ((if git? call-with-temporary-directory call-with-temporary-output-file)+ (lambda* (temp #:optional port)+ (and (if git?+ (begin+ (mkdir-p temp)+ (git-fetch (composer-source-url source)+ (composer-source-reference source)+ temp))+ (url-fetch (composer-source-url source) temp))+ `(package+ (name ,(composer-package-name composer-package))+ (version ,(composer-package-version composer-package))+ (source (origin+ ,@(if git?+ `((method git-fetch)+ (uri (git-reference+ (url ,(composer-source-url source))+ (commit ,(composer-source-reference source))))+ (file-name (git-file-name name version))+ (sha256+ (base32+ ,(bytevector->nix-base32-string+ (file-hash temp (negate vcs-file?) #t)))))+ `((method url-fetch)+ (uri ,(composer-source-url source))+ (sha256 (base32 ,(guix-hash-url temp)))))))+ (build-system composer-build-system)+ ,@(if (null? dependencies)+ '()+ `((inputs+ (,'quasiquote+ ,(map (lambda (name)+ `(,name+ (,'unquote+ ,(string->symbol name))))+ dependencies)))))+ ,@(if (null? dev-dependencies)+ '()+ `((native-inputs+ (,'quasiquote+ ,(map (lambda (name)+ `(,name+ (,'unquote+ ,(string->symbol name))))+ dev-dependencies)))))+ (synopsis "")+ (description ,(composer-package-description composer-package))+ (home-page ,(composer-package-homepage composer-package))+ (license ,(match (composer-package-license composer-package)+ (() #f)+ ((license) license)+ (_ license)))))))))++(define* (composer->guix-package package-name #:optional version)+ "Fetch the metadata for PACKAGE-NAME from packagist.org, and return the+`package' s-expression corresponding to that package, or #f on failure."+ (let ((package (composer-fetch package-name version)))+ (and package+ (let* ((package (json->composer-package package))+ (dependencies-names (composer-package-require package))+ (dev-dependencies-names (composer-package-dev-require package)))+ (values (make-php-sexp package)+ (append dependencies-names dev-dependencies-names))))))++(define (guix-name->composer-name name)+ "Given a guix package name, return the name of the package in Packagist."+ (if (string-prefix? "php-" name)+ (let ((components (string-split (substring name 4) #\-)))+ (match components+ ((namespace name ...)+ (string-append namespace "/" (string-join name "-")))))+ name))++(define (guix-package->composer-name package)+ "Given a Composer PACKAGE built from Packagist, return the name of the+package in Packagist."+ (let ((upstream-name (assoc-ref+ (package-properties package)+ 'upstream-name))+ (name (package-name package)))+ (if upstream-name+ upstream-name+ (guix-name->composer-name name))))++(define (string->license str)+ "Convert the string STR into a license object."+ (match str+ ("GNU LGPL" 'license:lgpl2.0)+ ("GPL" 'license:gpl3)+ ((or "BSD" "BSD License" "BSD-3-Clause") 'license:bsd-3)+ ((or "MIT" "MIT license" "Expat license") 'license:expat)+ ("Public domain" 'license:public-domain)+ ((or "Apache License, Version 2.0" "Apache 2.0") 'license:asl2.0)+ (_ #f)))++(define (php-package? package)+ "Return true if PACKAGE is a PHP package from Packagist."+ (and+ (eq? (build-system-name (package-build-system package)) 'composer)+ (string-prefix? "php-" (package-name package))))++(define (latest-release package)+ "Return an <upstream-source> for the latest release of PACKAGE."+ (let* ((php-name (guix-package->composer-name package))+ (metadata (composer-fetch php-name))+ (package (json->composer-package metadata))+ (version (composer-package-version package))+ (url (composer-source-url (composer-package-source package))))+ (upstream-source+ (package (package-name package))+ (version version)+ (urls (list url)))))++(define %composer-updater+ (upstream-updater+ (name 'composer)+ (description "Updater for Composer packages")+ (pred php-package?)+ (latest latest-release)))++(define* (composer-recursive-import package-name #:optional version)+ (recursive-import package-name '()+ #:repo->guix-package composer->guix-package+ #:guix-name php-package-name))diff --git a/guix/scripts/import.scm b/guix/scripts/import.scmindex 0a3863f965..23da295e48 100644--- a/guix/scripts/import.scm+++ b/guix/scripts/import.scm@@ -77,7 +77,7 @@ rather than \\n." ;;; (define importers '("gnu" "nix" "pypi" "cpan" "hackage" "stackage" "elpa" "gem"- "cran" "crate" "texlive" "json" "opam"))+ "cran" "crate" "texlive" "json" "opam" "composer")) (define (resolve-importer name) (let ((module (resolve-interfacediff --git a/guix/scripts/import/composer.scm b/guix/scripts/import/composer.scmnew file mode 100644index 0000000000..412bae6318--- /dev/null+++ b/guix/scripts/import/composer.scm@@ -0,0 +1,107 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2015 David Thompson <davet@gnu.org>+;;; Copyright © 2018 Oleg Pykhalov <go.wigust@gmail.com>+;;;+;;; 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/>.++(define-module (guix scripts import composer)+ #:use-module (guix ui)+ #:use-module (guix utils)+ #:use-module (guix scripts)+ #:use-module (guix import composer)+ #:use-module (guix scripts import)+ #:use-module (srfi srfi-1)+ #:use-module (srfi srfi-11)+ #:use-module (srfi srfi-37)+ #:use-module (srfi srfi-41)+ #:use-module (ice-9 match)+ #:use-module (ice-9 format)+ #:export (guix-import-composer))++ +;;;+;;; Command-line options.+;;;++(define %default-options+ '())++(define (show-help)+ (display (G_ "Usage: guix import composer PACKAGE-NAME+Import and convert the Composer package for PACKAGE-NAME.\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 Composer 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 composer")))+ (option '(#\r "recursive") #f #f+ (lambda (opt name arg result)+ (alist-cons 'recursive #t result)))+ %standard-import-options))++ +;;;+;;; Entry point.+;;;++(define (guix-import-composer . args)+ (define (parse-options)+ ;; Return the alist of option values.+ (args-fold* args %options+ (lambda (opt name arg result)+ (leave (G_ "~A: unrecognized option~%") name))+ (lambda (arg result)+ (alist-cons 'argument arg result))+ %default-options))++ (let* ((opts (parse-options))+ (args (filter-map (match-lambda+ (('argument . value)+ value)+ (_ #f))+ (reverse opts))))+ (match args+ ((package-name)+ (if (assoc-ref opts 'recursive)+ (map (match-lambda+ ((and ('package ('name name) . rest) pkg)+ `(define-public ,(string->symbol name)+ ,pkg))+ (_ #f))+ (composer-recursive-import package-name))+ (let ((sexp (composer->guix-package package-name)))+ (unless sexp+ (leave (G_ "failed to download meta-data for package '~a'~%")+ package-name))+ sexp)))+ (()+ (leave (G_ "too few arguments~%")))+ ((many ...)+ (leave (G_ "too many arguments~%"))))))diff --git a/tests/composer.scm b/tests/composer.scmnew file mode 100644index 0000000000..cefaf9f434--- /dev/null+++ b/tests/composer.scm@@ -0,0 +1,92 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2020 Julien Lepiller <julien@lepiller.eu>+;;;+;;; 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/>.++(define-module (test-composer)+ #:use-module (guix import composer)+ #:use-module (guix base32)+ #:use-module (gcrypt hash)+ #:use-module (guix tests http)+ #:use-module (guix grafts)+ #:use-module (srfi srfi-64)+ #:use-module (web client)+ #:use-module (ice-9 match))++;; Globally disable grafts because they can trigger early builds.+(%graft? #f)++(define test-json+ "{+ \"packages\": {+ \"foo/bar\": {+ \"0.1\": {+ \"name\": \"foo/bar\",+ \"description\": \"description\",+ \"keywords\": [\"testing\"],+ \"homepage\": \"http://example.com\",+ \"version\": \"0.1\",+ \"license\": [\"BSD-3-Clause\"],+ \"source\": {+ \"type\": \"url\",+ \"url\": \"http://example.com/Bar-0.1.tar.gz\"+ },+ \"require\": {},+ \"require-dev\": {\"phpunit/phpunit\": \"1.0.0\"}+ }+ }+ }+}")++(define test-source+ "foobar")++;; Avoid collisions with other tests.+(%http-server-port 10450)++(test-begin "composer")++(test-assert "composer->guix-package"+ ;; Replace network resources with sample data.+ (with-http-server `((200 ,test-json)+ (200 ,test-source))+ (parameterize ((%composer-base-url (%local-url))+ (current-http-proxy (%local-url)))+ (match (composer->guix-package "foo/bar")+ (('package+ ('name "php-foo-bar")+ ('version "0.1")+ ('source ('origin+ ('method 'url-fetch)+ ('uri "http://example.com/Bar-0.1.tar.gz")+ ('sha256+ ('base32+ (? string? hash)))))+ ('build-system 'composer-build-system)+ ('native-inputs+ ('quasiquote+ (("php-phpunit-phpunit" ('unquote 'php-phpunit-phpunit)))))+ ('synopsis "")+ ('description "description")+ ('home-page "http://example.com")+ ('license 'license:bsd-3))+ (string=? (bytevector->nix-base32-string+ (call-with-input-string test-source port-sha256))+ hash))+ (x+ (pk 'fail x #f))))))++(test-end "composer")-- 2.28.0
J
J
Julien Lepiller wrote on 19 Sep 2020 01:24
Re: [bug#42338] [PATCH 03/34] guix: Add composer-build-system.
(name . Ludovic Courtès)(address . ludo@gnu.org)(address . 42338@debbugs.gnu.org)
20200919012420.301201e8@tachikoma.lepiller.eu
Le Fri, 18 Sep 2020 10:45:48 +0200,Ludovic Courtès <ludo@gnu.org> a écrit :
Toggle quote (36 lines)> Hi,> > Julien Lepiller <julien@lepiller.eu> skribis:> > > + (let* ((package-data (read-package-data #:filename> > composer-file))> > + (scripts (match (assoc-ref package-data "scripts")> > + (('@ script ...) script)> > + (#f '())))> > + (test-script> > + (assoc-ref scripts test-target))> > + (dependencies (filter (lambda (dep) (string-contains> > dep "/"))> > + (map car> > + (match (assoc-ref> > package-data "require")> > + (('@ dependency ...)> > dependency)> > + (#f '())))))> > + (dependencies-dev> > + (filter (lambda (dep) (string-contains dep "/"))> > + (map car> > + (match (assoc-ref package-data> > "require-dev")> > + (('@ dependency ...) dependency)> > + (#f '())))))> > + (name (assoc-ref package-data "name"))) > > This is also a case for ‘define-json-mapping’. I suppose we could use> Guile-JSON instead of (guix build json), no?> > I think this code and similar occurrences would be less intimidating> if we used ‘define-json-mapping’; it would make the data structures> clearer, unlike here where one has to keep in mind what the list/tree> looks like so they can map car/cdr around.
I think we already tried that with the node build system, but we had torevert, because we were importing guile-json from the host side. Idon't remember the details though, so if you think it's OK now, I'llgladly make the code look nicer :)
Toggle quote (26 lines)> > > + (for-each> > + (lambda (input) > > Like for ‘map’, please indent on the same line:> > (for-each (lambda (input)> > > + (match test-script> > + ((? string? command)> > + (unless (equal? (system command) 0)> > + (throw 'failed-command command)))> > + (('@ (? string? command) ...)> > + (for-each> > + (lambda (c)> > + (unless (equal? (system c) 0)> > + (throw 'failed-command c)))> > + command)) > > Use (zero? x) instead of (equal? 0 x).> > Also, why not use ‘invoke’? I this because these commands are really> shell commands and expect things like glob patterns and tilde> expansion? If these are not shell commands, I recommend ‘invoke’,> which will report failures more nicely.
Here I have a single string that contains shell commands, so I don'tthink I can use invoke.
L
L
Ludovic Courtès wrote on 25 Sep 2020 12:27
Re: [bug#42338] [PATCH 01/34] guix: import: Add composer importer.
(name . Julien Lepiller)(address . julien@lepiller.eu)(address . 42338@debbugs.gnu.org)
87lfgy179m.fsf@gnu.org
Hi Julien,
Julien Lepiller <julien@lepiller.eu> skribis:
Toggle quote (12 lines)> From 70b9cb2bb389f3e5f9dcc75a44d7d60c28f997bc Mon Sep 17 00:00:00 2001> From: Julien Lepiller <julien@lepiller.eu>> Date: Tue, 29 Oct 2019 08:07:38 +0100> Subject: [PATCH 01/34] guix: import: Add composer importer.>> * guix/import/composer.scm: New file.> * guix/scripts/import/composer.scm: New file.> * guix/tests/composer.scm: New file.> * Makefile.am: Add them.> * guix/scripts/import.scm: Add composer importer.> * doc/guix.texi (Invoking guix import): Mention it.
[...]
Toggle quote (2 lines)> +@cindex PHP> +Import metadat from the @uref{https://getcomposer.org/, Composer} package
^Typo.
Toggle quote (18 lines)> +(define* (composer-fetch name #:optional version)> + "Return an alist representation of the Composer metadata for the package NAME,> +or #f on failure."> + (let ((package (json-fetch> + (string-append (%composer-base-url) "/p/" name ".json"))))> + (if package> + (let* ((packages (assoc-ref package "packages"))> + (package (or (assoc-ref packages name) package))> + (versions (filter> + (lambda (version)> + (and (not (string-contains version "dev"))> + (not (string-contains version "beta"))))> + (map car package)))> + (version (or (if (null? version) #f version)> + (latest-version versions))))> + (assoc-ref package version))> + #f)))
I think this should directly return a <composer-package> since the allthe callers pass the alist through ‘json->composer-package’. The ideais that alists should be converted to records as soon as they enter theprocess.
Also it’s weird that ‘package’ above has a “packages” (plural) entry.Perhaps we’re missing another JSON mapping?
[...]
Toggle quote (6 lines)> +++ b/guix/scripts/import/composer.scm> @@ -0,0 +1,107 @@> +;;; GNU Guix --- Functional package management for GNU> +;;; Copyright © 2015 David Thompson <davet@gnu.org>> +;;; Copyright © 2018 Oleg Pykhalov <go.wigust@gmail.com>
You can preserve these two lines if you think it’s relevant, but I’dsuggest adding one for yourself.
OK to push with changes along these lines.
Thanks for taking the time to convert to ‘define-json-mapping’ and all!
Ludo’.
L
L
Ludovic Courtès wrote on 25 Sep 2020 12:33
Re: [bug#42338] [PATCH 03/34] guix: Add composer-build-system.
(name . Julien Lepiller)(address . julien@lepiller.eu)(address . 42338@debbugs.gnu.org)
87eemq16y3.fsf@gnu.org
Hi,
Julien Lepiller <julien@lepiller.eu> skribis:
Toggle quote (44 lines)> Le Fri, 18 Sep 2020 10:45:48 +0200,> Ludovic Courtès <ludo@gnu.org> a écrit :>>> Hi,>> >> Julien Lepiller <julien@lepiller.eu> skribis:>> >> > + (let* ((package-data (read-package-data #:filename>> > composer-file))>> > + (scripts (match (assoc-ref package-data "scripts")>> > + (('@ script ...) script)>> > + (#f '())))>> > + (test-script>> > + (assoc-ref scripts test-target))>> > + (dependencies (filter (lambda (dep) (string-contains>> > dep "/"))>> > + (map car>> > + (match (assoc-ref>> > package-data "require")>> > + (('@ dependency ...)>> > dependency)>> > + (#f '())))))>> > + (dependencies-dev>> > + (filter (lambda (dep) (string-contains dep "/"))>> > + (map car>> > + (match (assoc-ref package-data>> > "require-dev")>> > + (('@ dependency ...) dependency)>> > + (#f '())))))>> > + (name (assoc-ref package-data "name"))) >> >> This is also a case for ‘define-json-mapping’. I suppose we could use>> Guile-JSON instead of (guix build json), no?>> >> I think this code and similar occurrences would be less intimidating>> if we used ‘define-json-mapping’; it would make the data structures>> clearer, unlike here where one has to keep in mind what the list/tree>> looks like so they can map car/cdr around.>> I think we already tried that with the node build system, but we had to> revert, because we were importing guile-json from the host side. I> don't remember the details though, so if you think it's OK now, I'll> gladly make the code look nicer :)
Yes please. :-) I think code full of alists/dictionaries would be hardto read and to maintain since mistakes could end up being silentlyignored or lead to a wrong-type-#f error far down the road.
Also please remember to avoid car/cdr:
https://guix.gnu.org/manual/en/html_node/Data-Types-and-Pattern-Matching.html
As for Guile-JSON: perhaps you can post a draft that we can play with tosee if there’s anything wrong, but off the top of my head I don’t seewhy it wouldn’t work.
Toggle quote (21 lines)>> > + (match test-script>> > + ((? string? command)>> > + (unless (equal? (system command) 0)>> > + (throw 'failed-command command)))>> > + (('@ (? string? command) ...)>> > + (for-each>> > + (lambda (c)>> > + (unless (equal? (system c) 0)>> > + (throw 'failed-command c)))>> > + command)) >> >> Use (zero? x) instead of (equal? 0 x).>> >> Also, why not use ‘invoke’? I this because these commands are really>> shell commands and expect things like glob patterns and tilde>> expansion? If these are not shell commands, I recommend ‘invoke’,>> which will report failures more nicely.>> Here I have a single string that contains shell commands, so I don't> think I can use invoke.
‘system’ passes the string to “sh -c”, which means the string is subjectto shelly things: glob expansion, semicolon interpretation, stringquotation, etc.
If those strings are meant to be shell-interpreted, then passing them to‘system’ is the right thing. Otherwise, it should be avoided IMO.
Thanks,Ludo’.
J
J
Julien Lepiller wrote on 29 Sep 2020 16:49
(name . Ludovic Courtès)(address . ludo@gnu.org)(address . 42338@debbugs.gnu.org)
20200929164920.0684be42@tachikoma.lepiller.eu
Le Fri, 25 Sep 2020 12:33:56 +0200,Ludovic Courtès <ludo@gnu.org> a écrit :
Toggle quote (9 lines)> Hi,> > As for Guile-JSON: perhaps you can post a draft that we can play with> to see if there’s anything wrong, but off the top of my head I don’t> see why it wouldn’t work.> > Thanks,> Ludo’.
Here's a new version, hopefully this addresses all your remarks. I'mstill not sure how (json) is pulled in to the build side though... Howdoes guix know it needs to use guile-json-3 instead of guile-json-1 forinstance? How does it work with inferiors?
From 432f57aeeb3b2e48591288e6491d66ab299661f0 Mon Sep 17 00:00:00 2001From: Julien Lepiller <julien@lepiller.eu>Date: Tue, 29 Oct 2019 20:58:51 +0100Subject: [PATCH 03/34] guix: Add composer-build-system.
* guix/build-system/composer.scm: New file.* guix/build/composer-build-system.scm: New file.* gnu/packages/aux-files/findclass.php: New file.* Makefile.am: Add them.* doc/guix.texi (Build Systems): Document it.--- Makefile.am | 5 +- doc/guix.texi | 14 ++ gnu/packages/aux-files/findclass.php | 125 ++++++++++++++ guix/build-system/composer.scm | 173 +++++++++++++++++++ guix/build/composer-build-system.scm | 241 +++++++++++++++++++++++++++ 5 files changed, 557 insertions(+), 1 deletion(-) create mode 100644 gnu/packages/aux-files/findclass.php create mode 100644 guix/build-system/composer.scm create mode 100644 guix/build/composer-build-system.scm
Toggle diff (614 lines)diff --git a/Makefile.am b/Makefile.amindex 6ce1430ea6..5af964b0e9 100644--- a/Makefile.am+++ b/Makefile.am@@ -115,6 +115,7 @@ MODULES = \ guix/build-system/cargo.scm \ guix/build-system/clojure.scm \ guix/build-system/cmake.scm \+ guix/build-system/composer.scm \ guix/build-system/dub.scm \ guix/build-system/dune.scm \ guix/build-system/emacs.scm \@@ -163,6 +164,7 @@ MODULES = \ guix/build/cargo-build-system.scm \ guix/build/cargo-utils.scm \ guix/build/cmake-build-system.scm \+ guix/build/composer-build-system.scm \ guix/build/dub-build-system.scm \ guix/build/dune-build-system.scm \ guix/build/emacs-build-system.scm \@@ -354,7 +356,8 @@ AUX_FILES = \ gnu/packages/aux-files/linux-libre/4.4-i686.conf \ gnu/packages/aux-files/linux-libre/4.4-x86_64.conf \ gnu/packages/aux-files/pack-audit.c \- gnu/packages/aux-files/run-in-namespace.c+ gnu/packages/aux-files/run-in-namespace.c \+ gnu/packages/aux-files/findclass.php # Templates, examples. EXAMPLES = \diff --git a/doc/guix.texi b/doc/guix.texiindex 626915fd39..6870163c23 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -6941,6 +6941,20 @@ debugging information''), which roughly means that code is compiled with @code{-O2 -g}, as is the case for Autoconf-based packages by default. @end defvr +@defvr {Scheme Variable} composer-build-system+This variable is exported by @code{(guix build-system composer)}. It+implements the build procedure for packages using+@url{https://getcomposer.org/, Composer}, the PHP package manager.++It automatically adds the @code{php} package to the set of inputs. Which+package is used can be specified with the @code{#:php} parameter.++The @code{#:test-target} parameter is used to control which script is run+for the tests. By default, the @code{test} script is run if it exists. If+the script does not exist, the build system will run @code{phpunit} from the+source directory, assuming there is a @file{phpunit.xml} file.+@end defvr+ @defvr {Scheme Variable} dune-build-system This variable is exported by @code{(guix build-system dune)}. It supports builds of packages using @uref{https://dune.build/, Dune}, a builddiff --git a/gnu/packages/aux-files/findclass.php b/gnu/packages/aux-files/findclass.phpnew file mode 100644index 0000000000..d0b250c8e1--- /dev/null+++ b/gnu/packages/aux-files/findclass.php@@ -0,0 +1,125 @@+<?php+/**+ * The content of this file is copied from composer's src/Composer/Autoload/ClassMapGenerator.php+ * the findClasses method was extracted, to prevent using any dependency.+ *+ * Composer (and thus this file) is distributed under the expat license, and+ * ClassMapGenerator.php also contains this notice:+ *+ * This file is part of Composer.+ *+ * (c) Nils Adermann <naderman@naderman.de>+ * Jordi Boggiano <j.boggiano@seld.be>+ *+ * For the full copyright and license information, please view the LICENSE+ * file that was distributed with this source code.+ *+ * This file is copied from the Symfony package.+ *+ * (c) Fabien Potencier <fabien@symfony.com>+ * + * To the extent to wich it makes sense, as the author of the extract:+ * Copyright © 2020 Julien Lepiller <julien@lepiller.eu>+ */++/**+ * Extract the classes in the given file+ *+ * @param string $path The file to check+ * @throws \RuntimeException+ * @return array The found classes+ */+function findClasses($path)+{+ $extraTypes = PHP_VERSION_ID < 50400 ? '' : '|trait';+ if (defined('HHVM_VERSION') && version_compare(HHVM_VERSION, '3.3', '>=')) {+ $extraTypes .= '|enum';+ }+ // Use @ here instead of Silencer to actively suppress 'unhelpful' output+ // @link https://github.com/composer/composer/pull/4886+ $contents = @php_strip_whitespace($path);+ if (!$contents) {+ if (!file_exists($path)) {+ $message = 'File at "%s" does not exist, check your classmap definitions';+ } elseif (!is_readable($path)) {+ $message = 'File at "%s" is not readable, check its permissions';+ } elseif ('' === trim(file_get_contents($path))) {+ // The input file was really empty and thus contains no classes+ return array();+ } else {+ $message = 'File at "%s" could not be parsed as PHP, it may be binary or corrupted';+ }+ $error = error_get_last();+ if (isset($error['message'])) {+ $message .= PHP_EOL . 'The following message may be helpful:' . PHP_EOL . $error['message'];+ }+ throw new \RuntimeException(sprintf($message, $path));+ }+ // return early if there is no chance of matching anything in this file+ if (!preg_match('{\b(?:class|interface'.$extraTypes.')\s}i', $contents)) {+ return array();+ }+ // strip heredocs/nowdocs+ $contents = preg_replace('{<<<[ \t]*([\'"]?)(\w+)\\1(?:\r\n|\n|\r)(?:.*?)(?:\r\n|\n|\r)(?:\s*)\\2(?=\s+|[;,.)])}s', 'null', $contents);+ // strip strings+ $contents = preg_replace('{"[^"\\\\]*+(\\\\.[^"\\\\]*+)*+"|\'[^\'\\\\]*+(\\\\.[^\'\\\\]*+)*+\'}s', 'null', $contents);+ // strip leading non-php code if needed+ if (substr($contents, 0, 2) !== '<?') {+ $contents = preg_replace('{^.+?<\?}s', '<?', $contents, 1, $replacements);+ if ($replacements === 0) {+ return array();+ }+ }+ // strip non-php blocks in the file+ $contents = preg_replace('{\?>(?:[^<]++|<(?!\?))*+<\?}s', '?><?', $contents);+ // strip trailing non-php code if needed+ $pos = strrpos($contents, '?>');+ if (false !== $pos && false === strpos(substr($contents, $pos), '<?')) {+ $contents = substr($contents, 0, $pos);+ }+ // strip comments if short open tags are in the file+ if (preg_match('{(<\?)(?!(php|hh))}i', $contents)) {+ $contents = preg_replace('{//.* | /\*(?:[^*]++|\*(?!/))*\*/}x', '', $contents);+ }+ preg_match_all('{+ (?:+ \b(?<![\$:>])(?P<type>class|interface'.$extraTypes.') \s++ (?P<name>[a-zA-Z_\x7f-\xff:][a-zA-Z0-9_\x7f-\xff:\-]*+)+ | \b(?<![\$:>])(?P<ns>namespace) (?P<nsname>\s++[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\s*+\\\\\s*+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)*+)? \s*+ [\{;]+ )+ }ix', $contents, $matches);+ $classes = array();+ $namespace = '';+ for ($i = 0, $len = count($matches['type']); $i < $len; $i++) {+ if (!empty($matches['ns'][$i])) {+ $namespace = str_replace(array(' ', "\t", "\r", "\n"), '', $matches['nsname'][$i]) . '\\';+ } else {+ $name = $matches['name'][$i];+ // skip anon classes extending/implementing+ if ($name === 'extends' || $name === 'implements') {+ continue;+ }+ if ($name[0] === ':') {+ // This is an XHP class, https://github.com/facebook/xhp+ $name = 'xhp'.substr(str_replace(array('-', ':'), array('_', '__'), $name), 1);+ } elseif ($matches['type'][$i] === 'enum') {+ // In Hack, something like:+ // enum Foo: int { HERP = '123'; }+ // The regex above captures the colon, which isn't part of+ // the class name.+ $name = rtrim($name, ':');+ }+ $classes[] = ltrim($namespace . $name, '\\');+ }+ }+ return $classes;+}++$options = getopt('i:f:', []);+$file = $options["f"];+$input = $options["i"];++$classes = findClasses($file);+foreach($classes as $class) {+ echo '$classmap[\''.$class.'\'] = \''.$input.'/'.$file.'\';';+ echo "\n";+}diff --git a/guix/build-system/composer.scm b/guix/build-system/composer.scmnew file mode 100644index 0000000000..0299f11906--- /dev/null+++ b/guix/build-system/composer.scm@@ -0,0 +1,173 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2019 Julien Lepiller <julien@lepiller.eu>+;;;+;;; 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/>.+(define-module (guix build-system composer)+ #:use-module (guix store)+ #:use-module (guix utils)+ #:use-module (guix derivations)+ #:use-module (guix search-paths)+ #:use-module (guix build-system)+ #:use-module (guix build-system gnu)+ #:use-module (guix gexp)+ #:use-module (guix packages)+ #:use-module (gnu packages)+ #:use-module (ice-9 match)+ #:use-module (srfi srfi-1)+ #:export (%composer-build-system-modules+ lower+ composer-build+ composer-build-system))++;; Commentary:+;;+;; Standard build procedure for PHP packages using Composer. This is implemented+;; as an extension of `gnu-build-system'.+;;+;; Code:++(define (default-php)+ "Return the default PHP package."++ ;; Do not use `@' to avoid introducing circular dependencies.+ (let ((module (resolve-interface '(gnu packages php))))+ (module-ref module 'php)))++(define (default-findclass)+ "Return the default findclass script."+ (search-auxiliary-file "findclass.php"))++(define (default-composer-classloader)+ "Return the default composer-classloader package."++ ;; Do not use `@' to avoid introducing circular dependencies.+ (let ((module (resolve-interface '(gnu packages php-xyz))))+ (module-ref module 'composer-classloader)))++(define %composer-build-system-modules+ ;; Build-side modules imported by default.+ `((guix build composer-build-system)+ (guix build union)+ (json)+ (json builder)+ (json parser)+ (json record)+ ,@%gnu-build-system-modules))++(define* (lower name+ #:key source inputs native-inputs outputs system target+ (php (default-php))+ (composer-classloader (default-composer-classloader))+ (findclass (default-findclass))+ #:allow-other-keys+ #:rest arguments)+ "Return a bag for NAME."+ (define private-keywords+ '(#:source #:target #:php #:composer-classloader #:findclass #:inputs #:native-inputs))++ (and (not target) ;XXX: no cross-compilation+ (bag+ (name name)+ (system system)+ (host-inputs `(,@(if source+ `(("source" ,source))+ '())+ ,@inputs++ ;; Keep the standard inputs of 'gnu-build-system'.+ ,@(standard-packages)))+ (build-inputs `(("php" ,php)+ ("findclass.php" ,findclass)+ ("composer-classloader" ,composer-classloader)+ ,@native-inputs))+ (outputs outputs)+ (build composer-build)+ (arguments (strip-keyword-arguments private-keywords arguments)))))++(define* (composer-build store name inputs+ #:key (guile #f)+ (outputs '("out")) (configure-flags ''())+ (search-paths '())+ (out-of-source? #t)+ (composer-file "composer.json")+ (tests? #t)+ (test-target "test")+ (install-target "install")+ (validate-runpath? #t)+ (patch-shebangs? #t)+ (strip-binaries? #t)+ (strip-flags ''("--strip-debug"))+ (strip-directories ''("lib" "lib64" "libexec"+ "bin" "sbin"))+ (phases '(@ (guix build composer-build-system)+ %standard-phases))+ (system (%current-system))+ (imported-modules %composer-build-system-modules)+ (modules '((guix build composer-build-system)+ (guix build utils)+ (json))))+ "Build SOURCE using PHP, and with INPUTS. This assumes that SOURCE provides+a 'composer.json' file as its build system."+ (define builder+ `(begin+ (use-modules ,@modules)+ (composer-build #:source ,(match (assoc-ref inputs "source")+ (((? derivation? source))+ (derivation->output-path source))+ ((source)+ source)+ (source+ source))+ #:system ,system+ #:outputs %outputs+ #:inputs %build-inputs+ #:search-paths ',(map search-path-specification->sexp+ search-paths)+ #:phases ,phases+ #:out-of-source? ,out-of-source?+ #:composer-file ,composer-file+ #:tests? ,tests?+ #:test-target ,test-target+ #:install-target ,install-target+ #:validate-runpath? ,validate-runpath?+ #:patch-shebangs? ,patch-shebangs?+ #:strip-binaries? ,strip-binaries?+ #:strip-flags ,strip-flags+ #:strip-directories ,strip-directories)))++ (define guile-for-build+ (match guile+ ((? package?)+ (package-derivation store guile system #:graft? #f))+ (#f ; the default+ (let* ((distro (resolve-interface '(gnu packages commencement)))+ (guile (module-ref distro 'guile-final)))+ (package-derivation store guile system #:graft? #f)))))++ (build-expression->derivation store name builder+ #:system system+ #:inputs inputs+ #:modules imported-modules+ #:outputs outputs+ #:guile-for-build guile-for-build))++(define composer-build-system+ (build-system+ (name 'composer)+ (description "The standard Composer build system")+ (lower lower)))++;;; composer.scm ends herediff --git a/guix/build/composer-build-system.scm b/guix/build/composer-build-system.scmnew file mode 100644index 0000000000..1af5e59b81--- /dev/null+++ b/guix/build/composer-build-system.scm@@ -0,0 +1,241 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2019 Julien Lepiller <julien@lepiller.eu>+;;;+;;; 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/>.++(define-module (guix build composer-build-system)+ #:use-module ((guix build gnu-build-system) #:prefix gnu:)+ #:use-module (guix build utils)+ #:use-module (ice-9 match)+ #:use-module (json)+ #:use-module (srfi srfi-26)+ #:export (%standard-phases+ composer-build))++;; Commentary:+;;+;; Builder-side code of the standard composer build procedure.+;;+;; Code:++(define (json->require dict)+ (if dict+ (let loop ((result '()) (require dict))+ (match require+ (() result)+ ((((? (cut string-contains <> "/") name) . _)+ require ...)+ (loop (cons name result) require))+ ((_ require ...) (loop result require))))+ '()))++(define-json-mapping <composer-autoload> make-composer-autoload composer-autoload?+ json->composer-autoload+ (psr-4 composer-autoload-psr-4 "psr-4"+ (match-lambda+ (#f '())+ (psr-4 psr-4)))+ (classmap composer-autoload-classmap "classmap"+ (match-lambda+ (#f '())+ (#(lst ...) lst))))++(define-json-mapping <composer-package> make-composer-package composer-package?+ json->composer-package+ (name composer-package-name)+ (autoload composer-package-autoload "autoload" json->composer-autoload)+ (autoload-dev composer-package-autoload-dev "autoload-dev" json->composer-autoload)+ (require composer-package-require "require" json->require)+ (dev-require composer-package-dev-require "require-dev" json->require)+ (scripts composer-package-scripts "scripts"+ (match-lambda+ (#f '())+ ((scripts ...) scripts)))+ (binaries composer-package-binaries "bin"+ (match-lambda+ (#f '())+ (#(lst ...) lst))))++(define* (read-package-data #:key (filename "composer.json"))+ (call-with-input-file filename+ (lambda (port)+ (json->composer-package (json->scm port)))))++(define* (check #:key composer-file inputs outputs tests? test-target #:allow-other-keys)+ "Install the given package."+ (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")))))+ #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-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)))))))++(define* (create-autoload vendor composer-file inputs #:key dev-dependencies?)+ "creates an autoload.php file that sets up the class locations for this package,+so it can be autoloaded by PHP when the package classes are required."+ (with-output-to-file (string-append vendor "/autoload.php")+ (lambda _+ (display (string-append+ "<?php+// autoload.php @generated by Guix+$map = $psr4map = $classmap = array();+require_once '" vendor "/autoload_conf.php'+require_once '" (assoc-ref inputs "composer-classloader") "/share/web/composer/ClassLoader.php'+$loader = new \\Composer\\Autoload\\ClassLoader();+foreach ($map as $namespace => $path) {+ $loader->set($namespace, $path);+}+foreach ($psr4map as $namespace => $path) {+ $loader->setPsr4($namespace, $path);+}+$loader->addClassMap($classmap);+$loader->register();+"))))+ ;; Now, create autoload_conf.php that contains the actual data, as a set+ ;; of arrays+ (let* ((package-data (read-package-data #:filename composer-file))+ (autoload (composer-package-autoload package-data))+ (autoload-dev (composer-package-autoload-dev package-data))+ (dependencies (composer-package-require package-data))+ (dependencies-dev (composer-package-dev-require package-data)))+ (with-output-to-file (string-append vendor "/autoload_conf.php")+ (lambda _+ (format #t "<?php~%")+ (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))))+ (append+ (composer-autoload-psr-4 autoload)+ (if dev-dependencies?+ (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)+ '())))+ (for-each+ (lambda (dep)+ (format #t "require_once '~a';~%" (find-php-dep inputs dep)))+ (append+ dependencies+ (if dev-dependencies?+ dependencies-dev+ '())))))))++(define* (install #:key inputs outputs composer-file #:allow-other-keys)+ "Install the given package."+ (let* ((out (assoc-ref outputs "out"))+ (package-data (read-package-data #:filename composer-file))+ (name (composer-package-name package-data))+ (php-dir (string-append out "/share/web/" name))+ (bin-dir (string-append php-dir "/vendor/bin"))+ (bin (string-append out "/bin"))+ (binaries (composer-package-binaries package-data)))+ (mkdir-p php-dir)+ (copy-recursively "." php-dir)+ (mkdir-p (string-append php-dir "/vendor"))+ (when binaries+ (mkdir-p bin-dir)+ (mkdir-p bin)+ (for-each+ (lambda (file)+ (let ((installed-file (string-append bin-dir "/" (basename file)))+ (bin-file (string-append bin "/" (basename file)))+ (original-file (string-append php-dir "/" file)))+ (symlink original-file installed-file)+ (symlink original-file bin-file)))+ binaries))+ (create-autoload (string-append php-dir "/vendor")+ composer-file inputs))+ #t)++(define %standard-phases+ ;; Everything is as with the GNU Build System except for the `configure'+ ;; , `build', `check' and `install' phases.+ (modify-phases gnu:%standard-phases+ (delete 'bootstrap)+ (delete 'configure)+ (delete 'build)+ (delete 'check)+ (replace 'install install)+ (add-after 'install 'check check)))++(define* (composer-build #:key inputs (phases %standard-phases)+ #:allow-other-keys #:rest args)+ "Build the given package, applying all of PHASES in order."+ (apply gnu:gnu-build #:inputs inputs #:phases phases args))++;;; composer-build-system.scm ends here-- 2.28.0
L
L
Ludovic Courtès wrote on 30 Sep 2020 11:24
(name . Julien Lepiller)(address . julien@lepiller.eu)(address . 42338@debbugs.gnu.org)
87blhn39dz.fsf@gnu.org
Hi,
Julien Lepiller <julien@lepiller.eu> skribis:
Toggle quote (5 lines)> Here's a new version, hopefully this addresses all your remarks. I'm> still not sure how (json) is pulled in to the build side though... How> does guix know it needs to use guile-json-3 instead of guile-json-1 for> instance?
Ah, see below.
Toggle quote (2 lines)> How does it work with inferiors?
I think inferiors have nothing to do with it.
Toggle quote (11 lines)> From 432f57aeeb3b2e48591288e6491d66ab299661f0 Mon Sep 17 00:00:00 2001> From: Julien Lepiller <julien@lepiller.eu>> Date: Tue, 29 Oct 2019 20:58:51 +0100> Subject: [PATCH 03/34] guix: Add composer-build-system.>> * guix/build-system/composer.scm: New file.> * guix/build/composer-build-system.scm: New file.> * gnu/packages/aux-files/findclass.php: New file.> * Makefile.am: Add them.> * doc/guix.texi (Build Systems): Document it.
[...]
Toggle quote (9 lines)> +(define %composer-build-system-modules> + ;; Build-side modules imported by default.> + `((guix build composer-build-system)> + (guix build union)> + (json)> + (json builder)> + (json parser)> + (json record)
Here, as the comment says, you’re importing (json …) from the host sideto the build side. That’s why it works.
The problem is that it’s just picking whatever (json …) modules are onyour load path on the host side: if you have Guile-JSON 3.x, it’ll usethat, if you have 4.x, that’ll be 4.x, and if you have nothing, it’llfail to build.
So the fix is to remove those modules from this list. You should onlyever import Guix modules.
Now you need to bring Guile-JSON into the environment. When using gexp,we do that with ‘with-extensions’, but here it’s a bit clunky…
Toggle quote (4 lines)> + (modules '((guix build composer-build-system)> + (guix build utils)> + (json))))
I think you don’t need (json) here. (This is the list of modules inscope.)
Toggle quote (27 lines)> + (define builder> + `(begin> + (use-modules ,@modules)> + (composer-build #:source ,(match (assoc-ref inputs "source")> + (((? derivation? source))> + (derivation->output-path source))> + ((source)> + source)> + (source> + source))> + #:system ,system> + #:outputs %outputs> + #:inputs %build-inputs> + #:search-paths ',(map search-path-specification->sexp> + search-paths)> + #:phases ,phases> + #:out-of-source? ,out-of-source?> + #:composer-file ,composer-file> + #:tests? ,tests?> + #:test-target ,test-target> + #:install-target ,install-target> + #:validate-runpath? ,validate-runpath?> + #:patch-shebangs? ,patch-shebangs?> + #:strip-binaries? ,strip-binaries?> + #:strip-flags ,strip-flags> + #:strip-directories ,strip-directories)))
To bring in Guile-JSON, you need to do something similar to what‘gexp->file’ does with ‘load-path-expression’, along these lines(untested):
(define guile-json-drv (package-derivation store (module-ref (resolve-interface '(gnu packages guile)) 'guile-json) system))
(define builder `(begin (add-to-load-path (string-append ,(derivation->output-path guile-json-drv) "/share/guile/site/" (effective-version))) (use-modules ,@modules) …))
;; …
(build-expression->derivation store name builder ;; … #:inputs (append inputs `(("guile-json" ,guile-json-drv))))
I guess clunkiness is the reason why we didn’t do it last time…
HTH!
Ludo’.
J
J
Julien Lepiller wrote on 19 Dec 2020 00:43
(name . Ludovic Courtès)(address . ludo@gnu.org)(address . 42338@debbugs.gnu.org)
20201219004318.2c94830d@tachikoma.lepiller.eu
Le Wed, 30 Sep 2020 11:24:08 +0200,Ludovic Courtès <ludo@gnu.org> a écrit :
Toggle quote (33 lines)> > To bring in Guile-JSON, you need to do something similar to what> ‘gexp->file’ does with ‘load-path-expression’, along these lines> (untested):> > (define guile-json-drv> (package-derivation store> (module-ref (resolve-interface '(gnu packages> guile)) 'guile-json)> system))> > (define builder> `(begin> (add-to-load-path (string-append ,(derivation->output-path> guile-json-drv) "/share/guile/site/"> (effective-version)))> (use-modules ,@modules)> …))> > ;; …> > (build-expression->derivation store name builder> ;; …> #:inputs (append inputs> `(("guile-json"> ,guile-json-drv))))> > I guess clunkiness is the reason why we didn’t do it last time…> > HTH!> > Ludo’.
Hi Ludo, sorry for the delay!
I tried that (replacing 'guile-json with 'guile-json-4), but it doesn'twork: when building the package, guix first builds a modules-compiledthat fails because it can't find (json). It seems to be related to thecompilation of (guix build composer-build-system) which uses the (json)module: when removing the import, it's modules-compiled works (with alot of warnings), but obviously guix can't build the php package.
L
L
Ludovic Courtès wrote on 21 Dec 2020 15:51
(name . Julien Lepiller)(address . julien@lepiller.eu)(address . 42338@debbugs.gnu.org)
877dpb6wkw.fsf@gnu.org
Hi,
Julien Lepiller <julien@lepiller.eu> skribis:
Toggle quote (7 lines)> I tried that (replacing 'guile-json with 'guile-json-4), but it doesn't> work: when building the package, guix first builds a modules-compiled> that fails because it can't find (json). It seems to be related to the> compilation of (guix build composer-build-system) which uses the (json)> module: when removing the import, it's modules-compiled works (with a> lot of warnings), but obviously guix can't build the php package.
Ah OK. Well, maybe you can sidestep the issue and use a custom JSONmodule instead. Sorry for the broken piece of advice!
Ludo’.
D
(address . 42338@debbugs.gnu.org)
000a01d79803$cbd95220$638bf660$@minikn.xyz
Hello. Is this feature still being worked on? I'd love to make use of it!
Cheers,
Demis.
Attachment: file
M
M
Maxim Cournoyer wrote on 16 Oct 06:15 +0200
(name . Ludovic Courtès)(address . ludo@gnu.org)
87zgr9k3lg.fsf_-_@gmail.com
Hey Julien,
That's a pretty interesting series you have there.
Ludovic Courtès <ludo@gnu.org> writes:
Toggle quote (62 lines)> Hi Julien,>> Julien Lepiller <julien@lepiller.eu> skribis:>>> From 70b9cb2bb389f3e5f9dcc75a44d7d60c28f997bc Mon Sep 17 00:00:00 2001>> From: Julien Lepiller <julien@lepiller.eu>>> Date: Tue, 29 Oct 2019 08:07:38 +0100>> Subject: [PATCH 01/34] guix: import: Add composer importer.>>>> * guix/import/composer.scm: New file.>> * guix/scripts/import/composer.scm: New file.>> * guix/tests/composer.scm: New file.>> * Makefile.am: Add them.>> * guix/scripts/import.scm: Add composer importer.>> * doc/guix.texi (Invoking guix import): Mention it.>> [...]>>> +@cindex PHP>> +Import metadat from the @uref{https://getcomposer.org/, Composer} package> ^> Typo.>>> +(define* (composer-fetch name #:optional version)>> + "Return an alist representation of the Composer metadata for the package NAME,>> +or #f on failure.">> + (let ((package (json-fetch>> + (string-append (%composer-base-url) "/p/" name ".json"))))>> + (if package>> + (let* ((packages (assoc-ref package "packages"))>> + (package (or (assoc-ref packages name) package))>> + (versions (filter>> + (lambda (version)>> + (and (not (string-contains version "dev"))>> + (not (string-contains version "beta"))))>> + (map car package)))>> + (version (or (if (null? version) #f version)>> + (latest-version versions))))>> + (assoc-ref package version))>> + #f)))>> I think this should directly return a <composer-package> since the all> the callers pass the alist through ‘json->composer-package’. The idea> is that alists should be converted to records as soon as they enter the> process.>> Also it’s weird that ‘package’ above has a “packages” (plural) entry.> Perhaps we’re missing another JSON mapping?>> [...]>>> +++ b/guix/scripts/import/composer.scm>> @@ -0,0 +1,107 @@>> +;;; GNU Guix --- Functional package management for GNU>> +;;; Copyright © 2015 David Thompson <davet@gnu.org>>> +;;; Copyright © 2018 Oleg Pykhalov <go.wigust@gmail.com>>> You can preserve these two lines if you think it’s relevant, but I’d> suggest adding one for yourself.>> OK to push with changes along these lines.
Seems you were almost ready to roll. Consider this a very gentle ping:-).
Maxim
?
Your comment

Commenting via the web interface is currently disabled.

To comment on this conversation send email to 42338@debbugs.gnu.org