;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2018 Julien Lepiller ;;; Copyright © 2019 Tobias Geerinckx-Rite ;;; ;;; This file is part of GNU Guix. ;;; ;;; GNU Guix is free software; you can redistribute it and/or modify it ;;; under the terms of the GNU General Public License as published by ;;; the Free Software Foundation; either version 3 of the License, or (at ;;; your option) any later version. ;;; ;;; GNU Guix is distributed in the hope that it will be useful, but ;;; WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;;; GNU General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with GNU Guix. If not, see . (define-module (gnu packages maven) #:use-module ((guix licenses) #:prefix license:) #:use-module (guix packages) #:use-module (guix
aboutsummaryrefslogtreecommitdiff
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2016 Jan Nieuwenhuizen <janneke@gnu.org>
;;; Copyright © 2016-2023 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2020 Brice Waegeneire <brice@waegenei.re>
;;; Copyright © 2023 Giacomo Leidi <goodoldpaul@autistici.org>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define-module (gnu services admin)
  #:use-module (gnu packages admin)
  #:use-module ((gnu packages base)
                #:select (canonical-package findutils coreutils sed))
  #:use-module (gnu packages certs)
  #:use-module (gnu packages package-management)
  #:use-module (gnu services)
  #:use-module (gnu services configuration)
  #:use-module (gnu services mcron)
  #:use-module (gnu services shepherd)
  #:use-module (gnu system accounts)
  #:use-module ((gnu system shadow) #:select (account-service-type))
  #:use-module ((guix store) #:select (%store-prefix))
  #:use-module (guix gexp)
  #:use-module (guix modules)
  #:use-module (guix packages)
  #:use-module (guix records)
  #:use-module (srfi srfi-1)
  #:use-module (ice-9 match)
  #:use-module (ice-9 vlist)
  #:export (%default-rotations
            %rotated-files

            log-rotation
            log-rotation?
            log-rotation-frequency
            log-rotation-files
            log-rotation-options
            log-rotation-post-rotate
            %default-log-rotation-options

            rottlog-configuration
            rottlog-configuration?
            rottlog-configuration-rottlog
            rottlog-configuration-rc-file
            rottlog-configuration-rotations
            rottlog-configuration-jobs
            rottlog-service
            rottlog-service-type

            log-cleanup-service-type
            log-cleanup-configuration
            log-cleanup-configuration?
            log-cleanup-configuration-directory
            log-cleanup-configuration-expiry
            log-cleanup-configuration-schedule

            file-database-service-type
            file-database-configuration
            file-database-configuration?
            file-database-configuration-package
            file-database-configuration-schedule
            file-database-configuration-excluded-directories
            %default-file-database-update-schedule
            %default-file-database-excluded-directories

            package-database-service-type
            package-database-configuration
            package-database-configuration?
            package-database-configuration-package
            package-database-configuration-schedule
            package-database-configuration-method
            package-database-configuration-channels

            unattended-upgrade-service-type
            unattended-upgrade-configuration
            unattended-upgrade-configuration?
            unattended-upgrade-configuration-operating-system-file
            unattended-upgrade-configuration-operating-system-expression
            unattended-upgrade-configuration-channels
            unattended-upgrade-configuration-schedule
            unattended-upgrade-configuration-services-to-restart
            unattended-upgrade-configuration-system-expiration
            unattended-upgrade-configuration-maximum-duration
            unattended-upgrade-configuration-log-file))

;;; Commentary:
;;;
;;; This module implements configuration of rottlog by writing
;;; /etc/rottlog/{rc,hourly|daily|weekly}.  Example usage
;;;
;;;     (mcron-service)
;;;     (service rottlog-service-type)
;;;
;;; Code:

(define-record-type* <log-rotation> log-rotation make-log-rotation
  log-rotation?
  (files       log-rotation-files)                ;list of strings
  (frequency   log-rotation-frequency             ;symbol
               (default 'weekly))
  (post-rotate log-rotation-post-rotate           ;#f | gexp
               (default #f))
  (options     log-rotation-options               ;list of strings
               (default %default-log-rotation-options)))

(define %default-log-rotation-options
  ;; Default log rotation options: append ".gz" to file names.
  '("storefile @FILENAME.@COMP_EXT"
    "notifempty"))

(define %rotated-files
  ;; Syslog files subject to rotation.
  '("/var/log/messages" "/var/log/secure" "/var/log/debug"
    "/var/log/maillog" "/var/log/mcron.log"))

(define %default-rotations
  (list (log-rotation                             ;syslog files
         (files %rotated-files)

         (frequency 'weekly)
         (options `(;; These files are worth keeping for a few weeks.
                    "rotate 16"
                    ;; Run post-rotate once per rotation
                    "sharedscripts"

                    ,@%default-log-rotation-options))
         ;; Restart syslogd after rotation.
         (post-rotate #~(let ((pid (call-with-input-file "/var/run/syslog.pid"
                                     read)))
                          (kill pid SIGHUP))))
        (log-rotation
         (files '("/var/log/guix-daemon.log"))
         (options `("rotate 4"                    ;don't keep too many of them
                    ,@%default-log-rotation-options)))))

(define (log-rotation->config rotation)
  "Return a string-valued gexp representing the rottlog configuration snippet
for ROTATION."
  (define post-rotate
    (let ((post (log-rotation-post-rotate rotation)))
      (and post
           (program-file "rottlog-post-rotate.scm" post))))

  #~(let ((post #$post-rotate))
      (string-append (string-join '#$(log-rotation-files rotation) ",")
                     " {"
                     #$(string-join (log-rotation-options rotation)
                                    "\n  " 'prefix)
                     (if post
                         (string-append "\n  postrotate\n    " post
                                        "\n  endscript\n")
                         "")
                     "\n}\n")))

(define (log-rotations->/etc-entries rotations)
  "Return the list of /etc entries for ROTATIONS, a list of <log-rotation>."
  (define (frequency-file frequency rotations)
    (computed-file (string-append "rottlog." (symbol->string frequency))
                   #~(call-with-output-file #$output
                       (lambda (port)
                         (for-each (lambda (str)
                                     (display str port))
                                   (list #$@(map log-rotation->config
                                                 rotations)))))))

  (let* ((frequencies (delete-duplicates
                       (map log-rotation-frequency rotations)))
         (table       (fold (lambda (rotation table)
                              (vhash-consq (log-rotation-frequency rotation)
                                           rotation table))
                            vlist-null
                            rotations)))
    (map (lambda (frequency)
           `(,(symbol->string frequency)
             ,(frequency-file frequency
                              (vhash-foldq* cons '() frequency table))))
         frequencies)))

(define (default-jobs rottlog)
  (list #~(job '(next-hour '(0))                  ;midnight
               #$(file-append rottlog "/sbin/rottlog"))
        #~(job '(next-hour '(12))                 ;noon
               #$(file-append rottlog "/sbin/rottlog"))))

(define-record-type* <rottlog-configuration>
  rottlog-configuration make-rottlog-configuration
  rottlog-configuration?
  (rottlog            rottlog-configuration-rottlog             ;file-like
                      (default rottlog))
  (rc-file            rottlog-configuration-rc-file             ;file-like
                      (default (file-append rottlog "/etc/rc")))
  (rotations          rottlog-configuration-rotations           ;list of <log-rotation>
                      (default %default-rotations))
  (jobs               rottlog-configuration-jobs                ;list of <mcron-job>
                      (default #f)))

(define (rottlog-etc config)
  `(("rottlog"
     ,(file-union "rottlog"
                  (cons `("rc" ,(rottlog-configuration-rc-file config))
                        (log-rotations->/etc-entries
                         (rottlog-configuration-rotations config)))))))

(define (rottlog-jobs-or-default config)
  (or (rottlog-configuration-jobs config)
      (default-jobs (rottlog-configuration-rottlog config))))

(define rottlog-service-type
  (service-type
   (name 'rottlog)
   (description
    "Periodically rotate log files using GNU@tie{}Rottlog and GNU@tie{}mcron.
Old log files are removed or compressed according to the configuration.")
   (extensions (list (service-extension etc-service-type rottlog-etc)
                     (service-extension mcron-service-type
                                        rottlog-jobs-or-default)

                     ;; Add Rottlog to the global profile so users can access
                     ;; the documentation.
                     (service-extension profile-service-type
                                        (compose list rottlog-configuration-rottlog))))
   (compose concatenate)
   (extend (lambda (config rotations)
             (rottlog-configuration
              (inherit config)
              (rotations (append (rottlog-configuration-rotations config)
                                 rotations)))))
   (default-value (rottlog-configuration))))


;;;
;;; Build log removal.
;;;

(define-record-type* <log-cleanup-configuration>
  log-cleanup-configuration make-log-cleanup-configuration
  log-cleanup-configuration?
  (directory log-cleanup-configuration-directory) ;string
  (expiry    log-cleanup-configuration-expiry     ;integer (seconds)
             (default (* 6 30 24 3600)))
  (schedule  log-cleanup-configuration-schedule   ;string or gexp
             (default "30 12 01,08,15,22 * *")))

(define (log-cleanup-program directory expiry)
  (program-file "delete-old-logs"
                (with-imported-modules '((guix build utils))
                  #~(begin
                      (use-modules (guix build utils))

                      (let* ((now  (car (gettimeofday)))
                             (logs (find-files #$directory
					       (lambda (file stat)
					         (> (- now (stat:mtime stat))
						    #$expiry)))))
                        (format #t "deleting ~a log files from '~a'...~%"
                                (length logs) #$directory)
                        (for-each delete-file logs))))))

(define (log-cleanup-mcron-jobs configuration)
  (match-record configuration <log-cleanup-configuration>
    (directory expiry schedule)
    (list #~(job #$schedule
                 #$(log-cleanup-program directory expiry)))))

(define log-cleanup-service-type
  (service-type
   (name 'log-cleanup)
   (extensions
    (list (service-extension mcron-service-type
                             log-cleanup-mcron-jobs)))
   (description
    "Periodically delete old log files.")))


;;;
;;; File databases.
;;;

(define %default-file-database-update-schedule
  ;; Default mcron schedule for the periodic 'updatedb' job: once every
  ;; Sunday.
  "10 23 * * 0")

(define %default-file-database-excluded-directories
  ;; Regexps of directories excluded from the 'locate' database.
  (list (%store-prefix)
        "/tmp" "/var/tmp" "/var/cache" ".*/\\.cache"
        "/run/udev"))

(define (string-or-gexp? obj)
  (or (string? obj) (gexp? obj)))

(define string-list?
  (match-lambda
    (((? string?) ...) #t)
    (_ #f)))

(define-configuration/no-serialization file-database-configuration
  (package
    (file-like (let-system (system target)
                 ;; Unless we're cross-compiling, avoid pulling a second copy
                 ;; of findutils.
                 (if target
                     findutils
                     (canonical-package findutils))))
    "The GNU@tie{}Findutils package from which the @command{updatedb} command
is taken.")
  (schedule
   (string-or-gexp %default-file-database-update-schedule)
   "String or G-exp denoting an mcron schedule for the periodic
@command{updatedb} job (@pxref{Guile Syntax,,, mcron, GNU@tie{}mcron}).")
  (excluded-directories
   (string-list %default-file-database-excluded-directories)
   "List of regular expressions of directories to ignore when building the
file database.  By default, this includes @file{/tmp} and @file{/gnu/store};
the latter should instead be indexed by @command{guix locate} (@pxref{Invoking
guix locate}).  This list is passed to the @option{--prunepaths} option of
@command{updatedb} (@pxref{Invoking updatedb,,, find, GNU@tie{}Findutils})."))

(define (file-database-mcron-jobs configuration)
  (match-record configuration <file-database-configuration>
    (package schedule excluded-directories)
    (let ((updatedb (program-file
                     "updatedb"
                     #~(begin
                         ;; 'updatedb' is a shell script that expects various
                         ;; commands in $PATH.
                         (setenv "PATH"
                                 (string-append #$package "/bin:"
                                                #$(canonical-package coreutils)
                                                "/bin:"
                                                #$(canonical-package sed)
                                                "/bin"))
                         (execl #$(file-append package "/bin/updatedb")
                                "updatedb"
                                #$(string-append "--prunepaths="
                                                 (string-join
                                                  excluded-directories)))))))
      (list #~(job #$schedule #$updatedb)))))

(define file-database-service-type
  (service-type
   (name 'file-database)
   (extensions (list (service-extension mcron-service-type
                                        file-database-mcron-jobs)))
   (description
    "Periodically update the file database used by the @command{locate} command,
which lets you search for files by name.  The database is created by running
the @command{updatedb} command.")
   (default-value (file-database-configuration))))

(define %default-package-database-update-schedule
  ;; Default mcron schedule for the periodic 'guix locate --update' job: once
  ;; every Monday.
  "10 23 * * 1")

(define-configuration/no-serialization package-database-configuration
  (package (file-like guix)
           "The Guix package to use.")
  (schedule (string-or-gexp
             %default-package-database-update-schedule)
            "String or G-exp denoting an mcron schedule for the periodic
@command{guix locate --update} job (@pxref{Guile Syntax,,, mcron,
GNU@tie{}mcron}).")
  (method    (symbol 'store)
             "Indexing method for @command{guix locate}.  The default value,
@code{'store}, yields a more complete database but is relatively expensive in
terms of CPU and input/output.")
  (channels (gexp #~%default-channels)
            "G-exp denoting the channels to use when updating the database
(@pxref{Channels})."))

(define (package-database-mcron-jobs configuration)
  (match-record configuration <package-database-configuration>
    (package schedule method channels)
    (let ((channels (scheme-file "channels.scm" channels)))
      (list #~(job #$schedule
                   ;; XXX: The whole thing's running as "root" just because it
                   ;; needs write access to /var/cache/guix/locate.
                   (string-append #$(file-append package "/bin/guix")
                                  " time-machine -C " #$channels
                                  " -- locate --update --method="
                                  #$(symbol->string method)))))))

(define package-database-service-type
  (service-type
   (name 'package-database)
   (extensions (list (service-extension mcron-service-type
                                        package-database-mcron-jobs)))
   (description
    "Periodically update the package database used by the @code{guix locate} command,
which lets you search for packages that provide a given file.")
   (default-value (package-database-configuration))))


;;;
;;; Unattended upgrade.
;;;

(define-record-type* <unattended-upgrade-configuration>
  unattended-upgrade-configuration make-unattended-upgrade-configuration
  unattended-upgrade-configuration?
  (operating-system-file unattended-upgrade-operating-system-file
                         (default "/run/current-system/configuration.scm"))
  (operating-system-expression unattended-upgrade-operating-system-expression
                               (default #f))
  (schedule             unattended-upgrade-configuration-schedule
                        (default "30 01 * * 0"))
  (channels             unattended-upgrade-configuration-channels
                        (default #~%default-channels))
  (services-to-restart  unattended-upgrade-configuration-services-to-restart
                        (default '(mcron)))
  (system-expiration    unattended-upgrade-system-expiration
                        (default (* 3 30 24 3600)))
  (maximum-duration     unattended-upgrade-maximum-duration
                        (default 3600))
  (log-file             unattended-upgrade-configuration-log-file
                        (default %unattended-upgrade-log-file)))

(define %unattended-upgrade-log-file
  "/var/log/unattended-upgrade.log")

(define (unattended-upgrade-mcron-jobs config)
  (define channels
    (scheme-file "channels.scm"
                 (unattended-upgrade-configuration-channels config)))

  (define log
    (unattended-upgrade-configuration-log-file config))

  (define services
    (unattended-upgrade-configuration-services-to-restart config))

  (define expiration
    (unattended-upgrade-system-expiration config))

  (define config-file
    (unattended-upgrade-operating-system-file config))

  (define expression
    (unattended-upgrade-operating-system-expression config))

  (define arguments
    (if expression
        #~(list "-e" (object->string '#$expression))
        #~(list #$config-file)))

  (define code
    (with-imported-modules (source-module-closure '((guix build utils)
                                                    (gnu services herd)))
      #~(begin
          (use-modules (guix build utils)
                       (gnu services herd)
                       (srfi srfi-19)
                       (srfi srfi-34))

          (define log
            (open-file #$log "a0"))

          (define (timestamp)
            (date->string (time-utc->date (current-time time-utc))
                          "[~4]"))

          (define (alarm-handler . _)
            (format #t "~a time is up, aborting upgrade~%"
                    (timestamp))
            (exit 1))

          ;; 'guix time-machine' needs X.509 certificates to authenticate the
          ;; Git host.
          (setenv "SSL_CERT_DIR"
                  #$(file-append nss-certs "/etc/ssl/certs"))

          ;; Make sure the upgrade doesn't take too long.
          (sigaction SIGALRM alarm-handler)
          (alarm #$(unattended-upgrade-maximum-duration config))

          ;; Redirect stdout/stderr to LOG to save the output of 'guix' below.
          (redirect-port log (current-output-port))
          (redirect-port log (current-error-port))

          (format #t "~a starting upgrade...~%" (timestamp))
          (guard (c ((invoke-error? c)
                     (report-invoke-error c)))
            (apply invoke #$(file-append guix "/bin/guix")
                   "time-machine" "-C" #$channels
                   "--" "system" "reconfigure" #$arguments)

            ;; 'guix system delete-generations' fails when there's no
            ;; matching generation.  Thus, catch 'invoke-error?'.
            (guard (c ((invoke-error? c)
                       (report-invoke-error c)))
              (invoke #$(file-append guix "/bin/guix")
                      "system" "delete-generations"
                      #$(string-append (number->string expiration)
                                       "s")))

            (format #t "~a restarting services...~%" (timestamp))
            (for-each restart-service '#$services)

            ;; XXX: If 'mcron' has been restarted, perhaps this isn't
            ;; reached.
            (format #t "~a upgrade complete~%" (timestamp))))))

  (define upgrade
    (program-file "unattended-upgrade" code))

  (list #~(job #$(unattended-upgrade-configuration-schedule config)
               #$upgrade)))

(define (unattended-upgrade-log-rotations config)
  (list (log-rotation
         (files
          (list (unattended-upgrade-configuration-log-file config))))))

(define unattended-upgrade-service-type
  (service-type
   (name 'unattended-upgrade)
   (extensions
    (list (service-extension mcron-service-type
                             unattended-upgrade-mcron-jobs)
          (service-extension rottlog-service-type
                             unattended-upgrade-log-rotations)))
   (description
    "Periodically upgrade the system from the current configuration.")
   (default-value (unattended-upgrade-configuration))))

;;; admin.scm ends here
a-guava" ,java-guava) ("java-guice" ,java-guice) ("java-javax-inject" ,java-javax-inject) ("java-cglib" ,java-cglib) ("java-slf4j-api" ,java-slf4j-api) ("java-plexus-utils" ,java-plexus-utils) ("java-plexus-cli" ,java-plexus-cli) ("maven-plugin-api" ,maven-plugin-api) ("maven-plugin-annotations" ,maven-plugin-annotations) ("maven-core" ,maven-core) ("maven-model" ,maven-model) ("java-commons-cli" ,java-commons-cli) ("java-qdox" ,java-qdox) ("java-jdom2" ,java-jdom2) ("java-asm" ,java-asm) ("java-geronimo-xbean-reflect" ,java-geronimo-xbean-reflect) ,@(package-native-inputs maven-wagon-provider-api))) (synopsis "Shared Library for wagon providers supporting HTTP.") (description "Maven Wagon is a transport abstraction that is used in Maven's artifact and repository handling code. It uses providers, that are tools to manage artifacts and deployment. This package contains a shared library for wagon providers supporting HTTP."))) (define-public maven-wagon-http (package (inherit maven-wagon-provider-api) (name "maven-wagon-http") (arguments `(#:jar-name "maven-wagon-http.jar" #:source-dir "wagon-providers/wagon-http/src/main/java" #:test-dir "wagon-providers/wagon-http/src/test" #:test-exclude (list "**/Abstract*.java" ;; FIXME: javax.net.ssl.SSLHandshakeException: ;; sun.security.validator.ValidatorException: ;; PKIX path building failed: ;; sun.security.provider.certpath.SunCertPathBuilderException: ;; unable to find valid certification path to requested target "**/HttpsWagonPreemptiveTest.java" "**/HttpsWagonTest.java" ;; Injection errors "**/TckTest.java") #:jdk ,icedtea-8 #:phases (modify-phases %standard-phases (add-before 'build 'copy-resources (lambda _ (install-file "wagon-providers/wagon-http/src/main/resources/META-INF/plexus/components.xml" "build/classes/META-INF/plexus") #t)) (add-before 'check 'fix-resource-path (lambda _ (substitute* '("wagon-providers/wagon-http/src/test/java/org/apache/maven/wagon/providers/http/HttpsWagonPreemptiveTest.java" "wagon-providers/wagon-http/src/test/java/org/apache/maven/wagon/providers/http/HttpsWagonTest.java") (("src/test") "wagon-providers/wagon-http/src/test")) #t))))) (inputs `(("java-plexus-utils" ,java-plexus-utils) ("java-httpcomponents-httpclient" ,java-httpcomponents-httpclient) ("java-httpcomponents-httpcore" ,java-httpcomponents-httpcore) ("maven-wagon-http-shared" ,maven-wagon-http-shared) ("maven-wagon-tck-http" ,maven-wagon-tck-http) ("maven-wagon-provider-api" ,maven-wagon-provider-api))) (native-inputs `(("maven-wagon-provider-test" ,maven-wagon-provider-test) ("java-plexus-component-metadata" ,java-plexus-component-metadata) ("java-plexus-component-annotations" ,java-plexus-component-annotations) ("java-eclipse-sisu-plexus" ,java-eclipse-sisu-plexus) ("java-plexus-container-default" ,java-plexus-container-default) ("java-eclipse-sisu-inject" ,java-eclipse-sisu-inject) ("java-plexus-classworlds" ,java-plexus-classworlds) ("java-guava" ,java-guava) ("java-guice" ,java-guice) ("java-inject" ,java-javax-inject) ("java-cglib" ,java-cglib) ("java-slf4j-api" ,java-slf4j-api) ("java-plexus-utils" ,java-plexus-utils) ("java-plexus-cli" ,java-plexus-cli) ("maven-plugin-api" ,maven-plugin-api) ("maven-plugin-annotations" ,maven-plugin-annotations) ("maven-core" ,maven-core) ("maven-model" ,maven-model) ("java-commons-cli" ,java-commons-cli) ("java-qdox" ,java-qdox) ("java-jdom2" ,java-jdom2) ("java-asm" ,java-asm) ("java-geronimo-xbean-reflect" ,java-geronimo-xbean-reflect) ("java-tomcat" ,java-tomcat) ("java-eclipse-jetty-util-9.2" ,java-eclipse-jetty-util-9.2) ("java-eclipse-jetty-io-9.2" ,java-eclipse-jetty-io-9.2) ("java-eclipse-jetty-http-9.2" ,java-eclipse-jetty-http-9.2) ("java-eclipse-jetty-server-9.2" ,java-eclipse-jetty-server-9.2) ("java-eclipse-jetty-servlet-9.2" ,java-eclipse-jetty-servlet-9.2) ("java-eclipse-jetty-security-9.2" ,java-eclipse-jetty-security-9.2) ("java-hamcrest-core" ,java-hamcrest-core) ("java-commons-logging-minimal" ,java-commons-logging-minimal) ("java-commons-codec" ,java-commons-codec) ("java-commons-io" ,java-commons-io) ("java-jsoup" ,java-jsoup) ("java-slf4j-simple" ,java-slf4j-simple) ,@(package-native-inputs maven-wagon-provider-api))) (synopsis "Wagon provider that gets and puts artifacts through HTTP(S)") (description "Maven Wagon is a transport abstraction that is used in Maven's artifact and repository handling code. It uses providers, that are tools to manage artifacts and deployment. This package contains a Wagon provider that gets and puts artifacts through HTTP(S) using Apache HttpClient-4.x."))) (define-public maven-artifact (package (name "maven-artifact") (version "3.6.0") (source (origin (method url-fetch) (uri (string-append "https://archive.apache.org/dist/maven/" "maven-3/" version "/source/" "apache-maven-" version "-src.tar.gz")) (sha256 (base32 "17jrqfqwn569jgnv8m4pqc27csssb0rf6mznpq61l5bnbd6hl75k")) (modules '((guix build utils))) (snippet '(begin (for-each delete-file (find-files "." "\\.jar$")) #t)) (patches (search-patches "maven-generate-component-xml.patch" "maven-generate-javax-inject-named.patch")))) (build-system ant-build-system) (arguments `(#:jar-name "maven-artifact.jar" #:source-dir "maven-artifact/src/main/java" #:test-dir "maven-artifact/src/test" #:main-class "org.apache.maven.artifact.versioning.ComparableVersion")) (inputs `(("java-plexus-utils" ,java-plexus-utils) ("java-commons-lang3" ,java-commons-lang3))) (native-inputs `(("java-junit" ,java-junit))) (home-page "https://maven.apache.org/") (synopsis "Build system") (description "Apache Maven is a software project management and comprehension tool. This package contains the Maven Artifact classes, providing the @code{Artifact} interface, with its @code{DefaultArtifact} implementation. The jar file is executable and provides a little tool to display how Maven parses and compares versions:") (license license:asl2.0))) (define-public maven-model (package (inherit maven-artifact) (name "maven-model") (arguments `(#:jar-name "maven-model.jar" #:source-dir "maven-model/src/main/java" #:test-dir "maven-model/src/test" #:jdk ,icedtea-8 #:phases (modify-phases %standard-phases (add-before 'build 'generate-models (lambda* (#:key inputs #:allow-other-keys) (define (modello-single-mode file version mode) (invoke "java" "org.codehaus.modello.ModelloCli" file mode "maven-model/src/main/java" version "false" "true")) (let ((file "maven-model/src/main/mdo/maven.mdo")) (modello-single-mode file "4.0.0" "java") (modello-single-mode file "4.0.0" "xpp3-reader") (modello-single-mode file "4.0.0" "xpp3-writer") (modello-single-mode file "4.0.0" "xpp3-extended-reader")) #t))))) (inputs `(("java-commons-lang3" ,java-commons-lang3) ("java-plexus-utils" ,java-plexus-utils))) (native-inputs `(("java-modello-core" ,java-modello-core) ;; for modello: ("java-eclipse-sisu-plexus" ,java-eclipse-sisu-plexus) ("java-plexus-component-annotations" ,java-plexus-component-annotations) ("java-guice" ,java-guice) ("java-cglib" ,java-cglib) ("java-asm" ,java-asm) ("java-eclipse-sisu-inject" ,java-eclipse-sisu-inject) ("java-javax-inject" ,java-javax-inject) ("java-plexus-classworlds" ,java-plexus-classworlds) ("java-guava" ,java-guava) ("java-geronimo-xbean-reflect" ,java-geronimo-xbean-reflect) ("java-sisu-build-api" ,java-sisu-build-api) ;; modello plugins: ("java-modello-plugins-java" ,java-modello-plugins-java) ("java-modello-plugins-xml" ,java-modello-plugins-xml) ("java-modello-plugins-xpp3" ,java-modello-plugins-xpp3) ;; for tests ("java-junit" ,java-junit))) (description "Apache Maven is a software project management and comprehension tool. This package contains the model for Maven @dfn{POM} (Project Object Model), so really just plain Java objects."))) (define-public maven-builder-support (package (inherit maven-artifact) (name "maven-builder-support") (arguments `(#:jar-name "maven-builder-support.jar" #:source-dir "maven-builder-support/src/main/java" #:jdk ,icedtea-8 #:test-dir "maven-builder-support/src/test" #:phases (modify-phases %standard-phases (add-before 'check 'fix-paths (lambda _ (with-directory-excursion "maven-builder-support/src/test/java" (substitute* '("org/apache/maven/building/FileSourceTest.java" "org/apache/maven/building/UrlSourceTest.java") (("target/test-classes") "maven-builder-support/src/test/resources"))) #t))))) (inputs `(("java-plexus-utils" ,java-plexus-utils) ("java-commons-lang3" ,java-commons-lang3))) (native-inputs `(("java-junit" ,java-junit) ("java-hamcrest-core" ,java-hamcrest-core))) (description "Apache Maven is a software project management and comprehension tool. This package contains a support library for descriptor builders (model, setting, toolchains)"))) (define-public maven-settings (package (inherit maven-artifact) (name "maven-settings") (arguments `(#:jar-name "maven-settings.jar" #:source-dir "maven-settings/src/main/java" #:jdk ,icedtea-8 #:tests? #f; no tests #:phases (modify-phases %standard-phases (add-before 'build 'generate-models (lambda* (#:key inputs #:allow-other-keys) (define (modello-single-mode file version mode) (invoke "java" "org.codehaus.modello.ModelloCli" file mode "maven-settings/src/main/java" version "false" "true")) (let ((file "maven-settings/src/main/mdo/settings.mdo")) (modello-single-mode file "1.1.0" "java") (modello-single-mode file "1.1.0" "xpp3-reader") (modello-single-mode file "1.1.0" "xpp3-writer")) #t))))) (inputs '()) (native-inputs `(("java-modello-core" ,java-modello-core) ;; for modello: ;("container" ,java-plexus-container-default) ("java-eclipse-sisu-plexus" ,java-eclipse-sisu-plexus) ("java-plexus-component-annotations" ,java-plexus-component-annotations) ("java-guice" ,java-guice) ("java-cglib" ,java-cglib) ("java-asm" ,java-asm) ("java-eclipse-sisu-inject" ,java-eclipse-sisu-inject) ("java-javax-inject" ,java-javax-inject) ("java-plexus-classworlds" ,java-plexus-classworlds) ("java-plexus-utils" ,java-plexus-utils) ("java-guava" ,java-guava) ("java-geronimo-xbean-reflect" ,java-geronimo-xbean-reflect) ("java-sisu-build-api" ,java-sisu-build-api) ;; modello plugins: ("java-modello-plugins-java" ,java-modello-plugins-java) ("java-modello-plugins-xml" ,java-modello-plugins-xml) ("java-modello-plugins-xpp3" ,java-modello-plugins-xpp3))) (description "Apache Maven is a software project management and comprehension tool. This package contains strictly the model for Maven settings, that is simply plain java objects."))) (define-public maven-settings-builder (package (inherit maven-artifact) (name "maven-settings-builder") (arguments `(#:jar-name "maven-settings-builder.jar" #:source-dir "maven-settings-builder/src/main/java" #:jdk ,icedtea-8 #:test-dir "maven-settings-builder/src/test" #:phases (modify-phases %standard-phases (add-before 'build 'generate-components.xml (lambda _ (mkdir-p "build/classes/META-INF/plexus") (chmod "components.sh" #o755) (invoke "./components.sh" "maven-settings-builder/src/main/java" "build/classes/META-INF/plexus/components.xml") #t))))) (inputs `(("java-plexus-utils" ,java-plexus-utils) ("java-plexus-component-annotations" ,java-plexus-component-annotations) ("java-plexus-interpolation" ,java-plexus-interpolation) ("java-plexus-sec-dispatcher" ,java-plexus-sec-dispatcher) ("maven-builder-support" ,maven-builder-support) ("maven-settings" ,maven-settings) ("java-commons-lang3" ,java-commons-lang3))) (native-inputs `(("java-junit" ,java-junit))) (description "Apache Maven is a software project management and comprehension tool. This package contains the effective model builder, with profile activation, inheritance, interpolation, @dots{}"))) (define-public maven-model-builder (package (inherit maven-artifact) (name "maven-model-builder") (arguments `(#:jar-name "maven-model-builder.jar" #:source-dir "maven-model-builder/src/main/java" #:jdk ,icedtea-8 #:test-dir "maven-model-builder/src/test" #:phases (modify-phases %standard-phases (add-before 'build 'copy-resources (lambda _ (copy-recursively "maven-model-builder/src/main/resources" "build/classes") #t)) (add-before 'build 'generate-components.xml (lambda _ (mkdir-p "build/classes/META-INF/plexus") (chmod "components.sh" #o755) (invoke "./components.sh" "maven-model-builder/src/main/java" "build/classes/META-INF/plexus/components.xml") #t)) (add-before 'check 'fix-paths (lambda _ (substitute* (find-files "maven-model-builder/src/test/java" ".*.java") (("src/test") "maven-model-builder/src/test")) #t))))) (inputs `(("model" ,maven-model) ("artifact" ,maven-artifact) ("support" ,maven-builder-support) ("annotations" ,java-plexus-component-annotations) ("utils" ,java-plexus-utils) ("interpolation" ,java-plexus-interpolation) ("lang3" ,java-commons-lang3) ("guava" ,java-guava))) (native-inputs `(("java-junit" ,java-junit) ("java-hamcrest-core" ,java-hamcrest-core) ("java-eclipse-sisu-plexus" ,java-eclipse-sisu-plexus) ("java-plexus-component-annotations" ,java-plexus-component-annotations) ("guice" ,java-guice) ("java-cglib" ,java-cglib) ("java-asm" ,java-asm) ("sisu-inject" ,java-eclipse-sisu-inject) ("javax-inject" ,java-javax-inject) ("java-xmlunit" ,java-xmlunit) ("java-xmlunit-matchers" ,java-xmlunit-matchers) ("xbean" ,java-geronimo-xbean-reflect) ("classworlds" ,java-plexus-classworlds))) (description "Apache Maven is a software project management and comprehension tool. This package contains the effective model builder, with profile activation, inheritance, interpolation, @dots{}"))) (define-public maven-repository-metadata (package (inherit maven-artifact) (name "maven-repository-metadata") (arguments `(#:jar-name "maven-repository-metadata.jar" #:source-dir "maven-repository-metadata/src/main/java" #:jdk ,icedtea-8 #:tests? #f; no tests #:phases (modify-phases %standard-phases (add-before 'build 'generate-models (lambda* (#:key inputs #:allow-other-keys) (define (modello-single-mode file version mode) (invoke "java" "org.codehaus.modello.ModelloCli" file mode "maven-repository-metadata/src/main/java" version "false" "true")) (let ((file "maven-repository-metadata/src/main/mdo/metadata.mdo")) (modello-single-mode file "1.1.0" "java") (modello-single-mode file "1.1.0" "xpp3-reader") (modello-single-mode file "1.1.0" "xpp3-writer")) #t))))) (inputs '()) (native-inputs `(("modello" ,java-modello-core) ;; for modello: ("java-eclipse-sisu-plexus" ,java-eclipse-sisu-plexus) ("java-plexus-component-annotations" ,java-plexus-component-annotations) ("java-guice" ,java-guice) ("java-cglib" ,java-cglib) ("java-asm" ,java-asm) ("java-eclipse-sisu-inject" ,java-eclipse-sisu-inject) ("java-javax-inject" ,java-javax-inject) ("java-plexus-utils" ,java-plexus-utils) ("java-plexus-classworlds" ,java-plexus-classworlds) ("java-guava" ,java-guava) ("java-geronimo-xbean-reflect" ,java-geronimo-xbean-reflect) ("java-sisu-build-api" ,java-sisu-build-api) ;; modello plugins: ("java-modello-plugins-java" ,java-modello-plugins-java) ("java-modello-plugins-xml" ,java-modello-plugins-xml) ("java-modello-plugins-xpp3" ,java-modello-plugins-xpp3))) (description "Apache Maven is a software project management and comprehension tool. This package contains strictly the model for Maven Repository Metadata, so really just plain objects."))) (define-public maven-resolver-provider (package (inherit maven-artifact) (name "maven-resolver-provider") (arguments `(#:jar-name "maven-resolver-provider.jar" #:source-dir "maven-resolver-provider/src/main/java" #:test-dir "maven-resolver-provider/src/test" #:jdk ,icedtea-8 #:tests? #f; dependency loop on maven-core (@Component RepositorySystem) #:phases (modify-phases %standard-phases (add-before 'build 'generate-sisu-named (lambda _ (mkdir-p "build/classes/META-INF/sisu") (chmod "./sisu.sh" #o755) (invoke "./sisu.sh" "maven-resolver-provider/src/main/java" "build/classes/META-INF/sisu/javax.inject.Named") #t))))) (inputs `(("maven-resolver-spi" ,maven-resolver-spi) ("maven-resolver-api" ,maven-resolver-api) ("maven-resolver-impl" ,maven-resolver-impl) ("maven-resolver-util" ,maven-resolver-util) ("maven-model" ,maven-model) ("maven-model-builder" ,maven-model-builder) ("maven-builder-support" ,maven-builder-support) ("maven-repository-metadata" ,maven-repository-metadata) ("java-plexus-utils" ,java-plexus-utils) ("java-plexus-component-annotations" ,java-plexus-component-annotations) ("java-commons-lang3" ,java-commons-lang3) ("java-guice" ,java-guice) ("java-guava" ,java-guava) ("java-eclipse-sisu-inject" ,java-eclipse-sisu-inject) ("java-javax-inject" ,java-javax-inject))))) (define-public maven-plugin-api (package (inherit maven-artifact) (name "maven-plugin-api") (arguments `(#:jar-name "maven-plugin-api.jar" #:source-dir "maven-plugin-api/src/main/java" #:jdk ,icedtea-8 #:test-dir "maven-plugin-api/src/test" #:phases (modify-phases %standard-phases (add-before 'build 'generate-models (lambda* (#:key inputs #:allow-other-keys) (define (modello-single-mode file version mode) (invoke "java" "org.codehaus.modello.ModelloCli" file mode "maven-plugin-api/src/main/java" version "false" "true")) (let ((file "maven-plugin-api/src/main/mdo/lifecycle.mdo")) (modello-single-mode file "1.0.0" "java") (modello-single-mode file "1.0.0" "xpp3-reader") (modello-single-mode file "1.0.0" "xpp3-writer")) #t))))) (inputs `(("maven-artifact" ,maven-artifact) ("maven-model" ,maven-model) ("java-eclipse-sisu-plexus" ,java-eclipse-sisu-plexus) ("java-plexus-component-annotations" ,java-plexus-component-annotations) ("guice" ,java-guice) ("java-cglib" ,java-cglib) ("java-asm" ,java-asm) ("sisu-inject" ,java-eclipse-sisu-inject) ("javax-inject" ,java-javax-inject) ("utils" ,java-plexus-utils))) (native-inputs `(("modello" ,java-modello-core) ;; for modello: ("classworlds" ,java-plexus-classworlds) ("guava" ,java-guava) ("xbean" ,java-geronimo-xbean-reflect) ("build-api" ,java-sisu-build-api) ;; modello plugins: ("java" ,java-modello-plugins-java) ("xml" ,java-modello-plugins-xml) ("xpp3" ,java-modello-plugins-xpp3) ;; for tests ("java-junit" ,java-junit))) (description "Apache Maven is a software project management and comprehension tool. This package contains strictly the API for plugins -- composed of goals implemented by Mojos -- development. A plugin is described in a @file{META-INF/maven/plugin.xml} plugin descriptor, generally generated from plugin sources using maven-plugin-plugin."))) (define maven-core-bootstrap (package (inherit maven-artifact) (name "maven-core") (arguments `(#:jar-name "maven-core.jar" #:source-dir "src/main/java" #:jdk ,icedtea-8 ;; Tests need maven-compat, which requires maven-core #:tests? #f #:phases (modify-phases %standard-phases (add-before 'configure 'chdir (lambda _ ;; Required for generating components.xml in maven-core (chdir "maven-core") #t)) (add-before 'build 'copy-resources (lambda _ (mkdir-p "build/classes/") (copy-recursively "src/main/resources" "build/classes") #t)) (add-after 'copy-resources 'fill-properties (lambda _ ;; This file controls the output of some mvn subcommands, such as ;; mvn -version. (substitute* "build/classes/org/apache/maven/messages/build.properties" (("\\$\\{buildNumber\\}") "guix_build") (("\\$\\{timestamp\\}") "0") (("\\$\\{project.version\\}") ,(package-version maven-artifact)) (("\\$\\{distributionId\\}") "apache-maven") (("\\$\\{distributionShortName\\}") "Maven") (("\\$\\{distributionName\\}") "Apache Maven")) #t)) (add-before 'build 'generate-sisu-named (lambda _ (mkdir-p "build/classes/META-INF/sisu") (chmod "../sisu.sh" #o755) (invoke "../sisu.sh" "src/main/java" "build/classes/META-INF/sisu/javax.inject.Named") #t)) (add-before 'build 'generate-models (lambda* (#:key inputs #:allow-other-keys) (define (modello-single-mode file version mode) (invoke "java" "org.codehaus.modello.ModelloCli" file mode "src/main/java" version "false" "true")) (let ((file "src/main/mdo/toolchains.mdo")) (modello-single-mode file "1.1.0" "java") (modello-single-mode file "1.1.0" "xpp3-reader") (modello-single-mode file "1.1.0" "xpp3-writer")) #t))))) (inputs `(("maven-artifact" ,maven-artifact) ("maven-resolver-provider" ,maven-resolver-provider) ("maven-builder-support" ,maven-builder-support) ("maven-model" ,maven-model) ("maven-model-builder" ,maven-model-builder) ("maven-settings" ,maven-settings) ("maven-settings-builder" ,maven-settings-builder) ("maven-plugin-api" ,maven-plugin-api) ("maven-repository-metadata" ,maven-repository-metadata) ("maven-shared-utils" ,maven-shared-utils) ("java-plexus-component-annotations" ,java-plexus-component-annotations) ("java-plexus-utils" ,java-plexus-utils) ("java-commons-lang3" ,java-commons-lang3) ("java-guava" ,java-guava) ("java-guice" ,java-guice) ("maven-resolver-api" ,maven-resolver-api) ("maven-resolver-spi" ,maven-resolver-spi) ("maven-resolver-util" ,maven-resolver-util) ("maven-resolver-impl" ,maven-resolver-impl) ("java-eclipse-sisu-inject" ,java-eclipse-sisu-inject) ("java-eclipse-sisu-plexus" ,java-eclipse-sisu-plexus) ("java-javax-inject" ,java-javax-inject) ("java-plexus-classworld" ,java-plexus-classworlds))) (native-inputs `(("java-modello-core" ,java-modello-core) ("java-cglib" ,java-cglib) ("java-asm" ,java-asm) ("java-plexus-classworlds" ,java-plexus-classworlds) ("java-geronimo-xbean-reflect" ,java-geronimo-xbean-reflect) ("java-sisu-build-api" ,java-sisu-build-api) ("java-modello-plugins-java" ,java-modello-plugins-java) ("java-modello-plugins-xml" ,java-modello-plugins-xml) ("java-modello-plugins-xpp3" ,java-modello-plugins-xpp3) ;; tests ("java-junit" ,java-junit) ("java-mockito-1" ,java-mockito-1) ("java-commons-jxpath" ,java-commons-jxpath))) (description "Apache Maven is a software project management and comprehension tool. This package contains the maven core classes managing the whole build process."))) (define-public maven-core (package (inherit maven-core-bootstrap) (arguments (substitute-keyword-arguments (package-arguments maven-core-bootstrap) ((#:phases phases) `(modify-phases ,phases (add-before 'build 'modify-metainf (lambda _ (substitute* "build.xml" (("message=\"\"") "message=\"Implementation-Version: 3.5.4\n\"")) #t)) (add-before 'build 'add-maven-files (lambda _ (mkdir-p "build/classes/META-INF/maven/org.apache.maven/maven-core") (copy-file "pom.xml" "build/classes/META-INF/maven/org.apache.maven/maven-core/pom.xml") (with-output-to-file "build/classes/META-INF/maven/org.apache.maven/maven-core/pom.properties" (lambda _ (format #t "version=~a~% groupId=org.apache.maven~% artifactId=maven-core" ,(package-version maven-core-bootstrap)))) #t)) (add-after 'build 'generate-metadata (lambda _ (define (components file) (let ((sxml (with-input-from-file file (lambda _ (xml->sxml (current-input-port) #:trim-whitespace? #t))))) ;; Select the list of s inside the ;; and . ((@ (ice-9 match) match) sxml (('*TOP* ('*PI* foo ...) ('component-set ('components x ...))) x)))) (use-modules (sxml simple)) (delete-file "build/classes/META-INF/plexus/components.xml") (invoke "java" "-cp" (string-append (getenv "CLASSPATH") ":build/classes") "org.codehaus.plexus.metadata.PlexusMetadataGeneratorCli" "--source" "build/classes/META-INF/plexus" "--output" "build/classes/META-INF/plexus/components.t.xml" "--classes" "build/classes" "--descriptors" "build/classes") ;; Now we merge all other components from hand-written xml (let ((generated-xml (components "build/classes/META-INF/plexus/components.t.xml")) (components-xml (components "src/main/resources/META-INF/plexus/components.xml")) (default-bindings-xml (components "src/main/resources/META-INF/plexus/default-bindings.xml")) (artifact-handlers-xml (components "src/main/resources/META-INF/plexus/artifact-handlers.xml"))) (with-output-to-file "build/classes/META-INF/plexus/components.xml" (lambda _ (display "\n") (sxml->xml `(component-set (components ,@(append generated-xml components-xml default-bindings-xml artifact-handlers-xml))))))) #t)) (add-after 'generate-metadata 'rebuild (lambda _ (invoke "ant" "jar") #t)))))) (native-inputs `(("java-plexus-component-metadata" ,java-plexus-component-metadata) ("java-commons-cli" ,java-commons-cli) ("java-plexus-cli" ,java-plexus-cli) ("java-jdom2" ,java-jdom2) ("java-qdox" ,java-qdox) ("maven-core-boot" ,maven-core-bootstrap) ,@(package-native-inputs maven-core-bootstrap))))) (define-public maven-embedder (package (inherit maven-artifact) (name "maven-embedder") (arguments `(#:jar-name "maven-embedder.jar" #:source-dir "maven-embedder/src/main/java" #:test-dir "maven-embedder/src/test" #:test-exclude (list "**/MavenCliTest.java") #:jdk ,icedtea-8 #:phases (modify-phases %standard-phases (add-before 'build 'generate-sisu-named (lambda _ (mkdir-p "build/classes/META-INF/sisu") (chmod "sisu.sh" #o755) (invoke "./sisu.sh" "maven-embedder/src/main/java" "build/classes/META-INF/sisu/javax.inject.Named") #t)) (add-before 'build 'generate-models (lambda* (#:key inputs #:allow-other-keys) (define (modello-single-mode file version mode) (invoke "java" "org.codehaus.modello.ModelloCli" file mode "maven-embedder/src/main/java" version "false" "true")) (let ((file "maven-embedder/src/main/mdo/core-extensions.mdo")) (modello-single-mode file "1.0.0" "java") (modello-single-mode file "1.0.0" "xpp3-reader") (modello-single-mode file "1.0.0" "xpp3-writer")) #t)) (add-before 'check 'fix-test-paths (lambda _ (substitute* "maven-embedder/src/test/java/org/apache/maven/cli/CLIManagerDocumentationTest.java" (("target/test-classes") "build/test-classes")) #t)) (add-before 'check 'fix-test-compilation (lambda _ ;; Tests are in the java/ subdir. Other subdirectories contain ;; additional test plugins, with duplicate classes, so we can't ;; compile them. Also, they are meant to be built with maven, to ;; test its build process. (substitute* "build.xml" (("srcdir=\"maven-embedder/src/test\"") "srcdir=\"maven-embedder/src/test/java\"")) #t))))) (inputs `(("maven-core" ,maven-core) ("maven-artifact" ,maven-artifact) ("maven-plugin-api" ,maven-plugin-api) ("maven-builder-support" ,maven-builder-support) ("maven-model" ,maven-model) ("maven-model-builder" ,maven-model-builder) ("maven-settings" ,maven-settings) ("maven-settings-builder" ,maven-settings-builder) ("maven-shared-utils" ,maven-shared-utils) ("java-plexus-classworlds" ,java-plexus-classworlds) ("java-plexus-util" ,java-plexus-utils) ("java-eclipse-sisu-plexus" ,java-eclipse-sisu-plexus) ("java-plexus-cipher" ,java-plexus-cipher) ("java-plexus-component-annotations" ,java-plexus-component-annotations) ("java-plexus-sec-dispatcher" ,java-plexus-sec-dispatcher) ("maven-resolevr-util" ,maven-resolver-util) ("maven-resolevr-api" ,maven-resolver-api) ("java-logback-core" ,java-logback-core) ("java-logback-classic" ,java-logback-classic) ("java-commons-cli" ,java-commons-cli) ("java-commons-io" ,java-commons-io) ("java-commons-lang3" ,java-commons-lang3) ("java-guava" ,java-guava) ("java-guice" ,java-guice) ("java-javax-inject" ,java-javax-inject) ("java-slf4j-api" ,java-slf4j-api) ("java-slf4j-simple" ,java-slf4j-simple))) (native-inputs `(("java-modello-core" ,java-modello-core) ("java-geronimo-xbean-reflect" ,java-geronimo-xbean-reflect) ("java-sisu-build-api" ,java-sisu-build-api) ("java-eclipse-sisu-plexus" ,java-eclipse-sisu-plexus) ("java-eclipse-sisu-inject" ,java-eclipse-sisu-inject) ("java-cglib" ,java-cglib) ("java-asm" ,java-asm) ("java-modello-plugins-java" ,java-modello-plugins-java) ("java-modello-plugins-xml" ,java-modello-plugins-xml) ("java-modello-plugins-xpp3" ,java-modello-plugins-xpp3) ;; tests ("java-junit" ,java-junit) ("java-objenesis" ,java-objenesis) ("java-mockito-1" ,java-mockito-1) ("java-hamcrest-core" ,java-hamcrest-core))) (description "Apache Maven is a software project management and comprehension tool. This package contains a Maven embeddable component, with CLI and logging support."))) (define-public maven-compat (package (inherit maven-artifact) (name "maven-compat") (arguments `(#:jar-name "maven-compat.jar" #:source-dir "src/main/java" #:jdk ,icedtea-8 #:test-dir "src/test" #:phases (modify-phases %standard-phases ;; Tests assume we're in this directory (add-before 'configure 'chdir (lambda _ (chdir "maven-compat") #t)) (add-before 'build 'recreate-removed-jar (lambda _ (with-output-to-file "src/test/repository-system/maven-core-2.1.0.jar" (const #t)) (with-directory-excursion "src/test/resources" (with-output-to-file "artifact-install/artifact-1.0.jar" (lambda _ (format #t "dummy~%"))) (for-each (lambda (file) (with-output-to-file file (lambda _ (format #t "foo~%")))) '("local-repo/maven-test/jars/maven-test-a-1.0.jar" "local-repo/maven-test/jars/maven-test-c-1.0.jar" "local-repo/maven-test/jars/maven-test-d-1.0.jar" "inheritance-repo/t04/maven-test/jars/t04-a-1.0.jar" "inheritance-repo/t04/maven-test/jars/t04-b-1.0.jar" "inheritance-repo/t04/maven-test/jars/t04-b-2.0.jar" "inheritance-repo/t04/maven-test/jars/t04-c-1.0.jar" "inheritance-repo/t04/maven-test/jars/t04-c-2.0.jar" "inheritance-repo/t05/maven-test/jars/t05-a-1.0.jar" "inheritance-repo/t05/maven-test/jars/t05-a-2.0.jar" "inheritance-repo/t05/maven-test/jars/t05-b-1.0.jar" "inheritance-repo/t05/maven-test/jars/t05-b-1.1.jar" "inheritance-repo/t05/maven-test/jars/t05-b-2.0.jar" "inheritance-repo/t05/maven-test/jars/t05-c-1.0.jar" "inheritance-repo/t05/maven-test/jars/t05-d-1.0.jar" "inheritance-repo/t05/maven-test/jars/t05-d-1.1.jar" "inheritance-repo/t05/maven-test/jars/t05-d-1.2.jar" "inheritance-repo/t06/maven-test/jars/t06-a-1.0.jar" "inheritance-repo/t06/maven-test/jars/t06-b-1.0.jar" "inheritance-repo/t06/maven-test/jars/t06-b-1.1.jar" "inheritance-repo/t06/maven-test/jars/t06-c-1.0.jar" "inheritance-repo/t06/maven-test/jars/t06-d-1.0.jar" "inheritance-repo/t06/maven-test/jars/t06-d-1.1.jar" "inheritance-repo/t06/maven-test/jars/t06-d-1.2.jar" "inheritance-repo/t07/maven-test/jars/t07-a-1.0.jar" "inheritance-repo/t07/maven-test/jars/t07-b-1.0.jar" "inheritance-repo/t07/maven-test/jars/t07-b-1.1.jar" "inheritance-repo/t07/maven-test/jars/t07-c-1.0.jar" "inheritance-repo/t07/maven-test/jars/t07-d-1.0.jar" "inheritance-repo/t07/maven-test/jars/t07-d-1.1.jar" "inheritance-repo/t07/maven-test/jars/t07-d-1.2.jar" "inheritance-repo/t08/maven-test/jars/t08-a-1.0.jar" "inheritance-repo/t08/maven-test/jars/t08-b-1.0.jar" "inheritance-repo/t08/maven-test/jars/t08-b-1.1.jar" "inheritance-repo/t08/maven-test/jars/t08-c-1.0.jar" "inheritance-repo/t08/maven-test/jars/t08-d-1.0.jar" "inheritance-repo/t08/maven-test/jars/t08-d-1.1.jar" "inheritance-repo/t08/maven-test/jars/t08-d-1.2.jar" "inheritance-repo/t09/maven-test/jars/t09-a-1.0.jar" "inheritance-repo/t09/maven-test/jars/t09-b-1.0.jar" "inheritance-repo/t09/maven-test/jars/t09-c-1.0.jar" "inheritance-repo/t09/maven-test/jars/t09-d-1.0.jar" "inheritance-repo/t10/maven-test/jars/t10-a-1.0.jar" "inheritance-repo/t10/maven-test/jars/t10-b-1.0.jar" "inheritance-repo/t10/maven-test/jars/t10-c-1.0.jar")) (with-directory-excursion "local-repo/snapshot-test/jars" (for-each (lambda (file) (with-output-to-file file (lambda _ ;; No end-of-line (format #t "local")))) '("maven-snapshot-e-1.0-SNAPSHOT.jar" "maven-snapshot-b-1.0-SNAPSHOT.jar" "maven-snapshot-a-1.0-SNAPSHOT.jar")))) (for-each (lambda (letter) (with-directory-excursion (string-append "src/test/remote-repo/org/apache/maven/its/" letter "/0.1") (let ((dir (string-append "META-INF/maven/org.apache.maven.its/" letter))) (mkdir-p dir) (copy-file (string-append letter "-0.1.pom") (string-append dir "/pom.xml")) (with-output-to-file (string-append dir "/pom.properties") (lambda _ (format #t "version=0.1~%") (format #t "groupId=org.apache.maven.its") (format #t (string-append "artifactId=" letter)))) (with-output-to-file "META-INF/MANIFEST.MF" (lambda _ (format #t "Manifest-Version: 1.0~%")))) (invoke "jar" "cmf" "META-INF/MANIFEST.MF" (string-append letter "-0.1.jar") "META-INF"))) '("a" "b")) #t)) (add-before 'build 'generate-models (lambda* (#:key inputs #:allow-other-keys) (define (modello-single-mode file version mode) (invoke "java" "org.codehaus.modello.ModelloCli" file mode "src/main/java" version "false" "true")) (let ((file "src/main/mdo/profiles.mdo")) (modello-single-mode file "1.0.0" "java") (modello-single-mode file "1.0.0" "xpp3-reader") (modello-single-mode file "1.0.0" "xpp3-writer")) (let ((file "src/main/mdo/paramdoc.mdo")) (modello-single-mode file "1.0.0" "java") (modello-single-mode file "1.0.0" "xpp3-reader") (modello-single-mode file "1.0.0" "xpp3-writer")) #t)) (add-after 'build 'generate-metadata (lambda _ (invoke "java" "-cp" (string-append (getenv "CLASSPATH") ":build/classes") "org.codehaus.plexus.metadata.PlexusMetadataGeneratorCli" "--source" "src/main/java" "--output" "build/classes/META-INF/plexus/components.xml" "--classes" "build/classes" "--descriptors" "build/classes/META-INF") #t)) (add-before 'check 'build-tests (lambda _ (invoke "ant" "compile-tests") #t)) (add-after 'build-tests 'generate-test-metadata (lambda _ (invoke "java" "-cp" (string-append (getenv "CLASSPATH") ":build/classes" ":build/test-classes") "org.codehaus.plexus.metadata.PlexusMetadataGeneratorCli" "--source" "src/test/java" "--output" "build/test-classes/META-INF/plexus/components.xml" "--classes" "build/test-classes" "--descriptors" "build/test-classes/META-INF") #t)) (add-after 'generate-metadata 'rebuild (lambda _ (invoke "ant" "jar") #t))))) (inputs `(("maven-artifact" ,maven-artifact) ("maven-repository-metadata" ,maven-repository-metadata) ("maven-builder-support" ,maven-builder-support) ("maven-model" ,maven-model) ("maven-model-builder" ,maven-model-builder) ("maven-settings" ,maven-settings) ("maven-settings-builder" ,maven-settings-builder) ("maven-core" ,maven-core) ("maven-wagon-provider-api" ,maven-wagon-provider-api) ("maven-wagon-file" ,maven-wagon-file) ("maven-resolver-api" ,maven-resolver-api) ("maven-resolver-util" ,maven-resolver-util) ("maven-resolver-spi" ,maven-resolver-spi) ("java-plexus-interpolation" ,java-plexus-interpolation))) (native-inputs `(("java-modello-core" ,java-modello-core) ("java-plexus-utils" ,java-plexus-utils) ("java-plexus-component-annotations" ,java-plexus-component-annotations) ("java-plexus-classworlds" ,java-plexus-classworlds) ("java-geronimo-xbean-reflect" ,java-geronimo-xbean-reflect) ("java-sisu-build-api" ,java-sisu-build-api) ("java-eclipse-sisu-plexus" ,java-eclipse-sisu-plexus) ("java-exclispe-sisu-inject" ,java-eclipse-sisu-inject) ("java-javax-inject" ,java-javax-inject) ("java-guice" ,java-guice) ("java-guava" ,java-guava) ("java-cglib" ,java-cglib) ("java-asm" ,java-asm) ("java-modello-plugins-java" ,java-modello-plugins-java) ("java-modello-plugins-xml" ,java-modello-plugins-xml) ("java-modello-plugins-xpp3" ,java-modello-plugins-xpp3) ;; metadata ("java-plexus-component-metadata" ,java-plexus-component-metadata) ("java-commons-cli" ,java-commons-cli) ("java-plexus-cli" ,java-plexus-cli) ("java-jdom2" ,java-jdom2) ("maven-plugin-api" ,maven-plugin-api) ("java-qdox" ,java-qdox) ;; tests ("java-plexus-cipher" ,java-plexus-cipher) ("java-plexus-sec-dispatcher" ,java-plexus-sec-dispatcher) ("java-jsr250" ,java-jsr250) ("java-cdi-api" ,java-cdi-api) ("java-junit" ,java-junit) ("maven-resolver-impl" ,maven-resolver-impl) ("maven-resolver-connector-basic" ,maven-resolver-connector-basic) ("maven-resolver-transport-wagon" ,maven-resolver-transport-wagon) ("java-commons-lang3" ,java-commons-lang3) ("java-aop" ,java-aopalliance) ("maven-resolver-provider" ,maven-resolver-provider) ("java-slf4j-api" ,java-slf4j-api) ("java-slf4j-simple" ,java-slf4j-simple) ,@(package-inputs java-slf4j-api))) (description "Apache Maven is a software project management and comprehension tool. This package contains Maven2 classes maintained as compatibility layer for plugins that need to keep Maven2 compatibility."))) (define-public maven (package (inherit maven-artifact) (name "maven") (arguments `(#:phases (modify-phases %standard-phases (replace 'build (lambda* (#:key inputs #:allow-other-keys) ;; Recreate the configuration for the loader (with-output-to-file "apache-maven/src/bin/m2.conf" (lambda _ (format #t "main is org.apache.maven.cli.MavenCli from plexus.core~%") (format #t "~%") (format #t "set maven.conf default ${maven.home}/conf~%") (format #t "~%") (format #t "[plexus.core]~%") (format #t "load ${maven.conf}/logging~%") (format #t "optionally ${maven.home}/lib/ext/*.jar~%") ;; Reference every jar so plexus-classworlds can find them. (for-each (lambda (dependency) (format #t "load ~a/share/java/*.jar~%" (assoc-ref inputs dependency))) '("maven-artifact" "maven-embedder" "maven-core" "maven-compat" "maven-builder-support" "maven-model" "maven-model-builder" "maven-settings" "maven-settings-builder" "maven-plugin-api" "maven-repository-metadata" "maven-shared-utils" "maven-resolver-api" "maven-resolver-spi" "maven-resolver-util" "maven-resolver-impl" "maven-resolver-connector-basic" "maven-resolver-provider" "maven-resolver-transport-wagon" "maven-wagon-provider-api" "maven-wagon-file" "maven-wagon-http" "java-commons-logging-minimal" "java-httpcomponents-httpclient" "java-httpcomponents-httpcore" "maven-wagon-http-shared" "maven-wagon-tck-http" "java-eclipse-sisu-plexus" "java-guice" "java-aopalliance" "java-cglib" "java-asm" "java-eclipse-sisu-inject" "java-javax-inject" "java-plexus-component-annotations" "java-plexus-utils" "java-plexus-interpolation" "java-plexus-sec-dispatcher" "java-plexus-cipher" "java-guava" "java-jansi" "java-jsr250" "java-cdi-api" "java-commons-cli" "java-commons-io" "java-commons-lang3" "java-slf4j-api" "java-slf4j-simple")))) (substitute* "apache-maven/src/bin/mvn" (("cygwin=false;") (string-append "CLASSPATH=" (car (find-files (assoc-ref inputs "java-plexus-classworlds") ".*.jar")) "\ncygwin=false;")) (("-classpath.*") "-classpath ${CLASSPATH} \\\n")) #t)) (delete 'check) (replace 'install (lambda* (#:key outputs #:allow-other-keys) (let ((bin (string-append (assoc-ref outputs "out") "/bin/")) (conf (string-append (assoc-ref outputs "out") "/conf/"))) (mkdir-p (string-append (assoc-ref outputs "out") "/lib")) (for-each (lambda (file) (install-file (string-append "apache-maven/src/bin/" file) bin) (chmod (string-append bin file) #o755)) '("mvn" "mvnDebug" "mvnyjp")) (install-file "apache-maven/src/bin/m2.conf" bin) (copy-recursively "apache-maven/src/conf" conf)) #t))))) (inputs `(("java-plexus-classworlds" ,java-plexus-classworlds) ("maven-artifact" ,maven-artifact) ("maven-embedder" ,maven-embedder) ("maven-core" ,maven-core) ("maven-compat" ,maven-compat) ("maven-builder-support" ,maven-builder-support) ("maven-model" ,maven-model) ("maven-model-builder" ,maven-model-builder) ("maven-settings" ,maven-settings) ("maven-settings-builder" ,maven-settings-builder) ("maven-plugin-api" ,maven-plugin-api) ("maven-repository-metadata" ,maven-repository-metadata) ("maven-shared-utils" ,maven-shared-utils) ("maven-resolver-api" ,maven-resolver-api) ("maven-resolver-spi" ,maven-resolver-spi) ("maven-resolver-util" ,maven-resolver-util) ("maven-resolver-impl" ,maven-resolver-impl) ("maven-resolver-connector-basic" ,maven-resolver-connector-basic) ("maven-resolver-provider" ,maven-resolver-provider) ("maven-resolver-transport-wagon" ,maven-resolver-transport-wagon) ("maven-wagon-provider-api" ,maven-wagon-provider-api) ("maven-wagon-file" ,maven-wagon-file) ("maven-wagon-http" ,maven-wagon-http) ("java-commons-logging-minimal" ,java-commons-logging-minimal) ("java-httpcomponents-httpclient" ,java-httpcomponents-httpclient) ("java-httpcomponents-httpcore" ,java-httpcomponents-httpcore) ("maven-wagon-http-shared" ,maven-wagon-http-shared) ("maven-wagon-tck-http" ,maven-wagon-tck-http) ("java-eclipse-sisu-plexus" ,java-eclipse-sisu-plexus) ("java-guice" ,java-guice) ("java-aopalliance" ,java-aopalliance) ("java-cglib" ,java-cglib) ("java-asm" ,java-asm) ("java-eclipse-sisu-inject" ,java-eclipse-sisu-inject) ("java-javax-inject" ,java-javax-inject) ("java-plexus-component-annotations" ,java-plexus-component-annotations) ("java-plexus-utils" ,java-plexus-utils) ("java-plexus-interpolation" ,java-plexus-interpolation) ("java-plexus-sec-dispatcher" ,java-plexus-sec-dispatcher) ("java-plexus-cipher" ,java-plexus-cipher) ("java-guava" ,java-guava) ("java-jansi" ,java-jansi) ("java-jsr250" ,java-jsr250) ("java-cdi-api" ,java-cdi-api) ("java-commons-cli" ,java-commons-cli) ("java-commons-io" ,java-commons-io) ("java-commons-lang3" ,java-commons-lang3) ("java-slf4j-api" ,java-slf4j-api) ;; TODO: replace with maven-slf4j-provider ("java-slf4j-simple" ,java-slf4j-simple))) (propagated-inputs `(("coreutils" ,coreutils) ("which" ,which))) (description "Apache Maven is a software project management and comprehension tool. Based on the concept of a project object model: builds, dependency management, documentation creation, site publication, and distribution publication are all controlled from the @file{pom.xml} declarative file. Maven can be extended by plugins to utilise a number of other development tools for reporting or the build process.")))