aboutsummaryrefslogtreecommitdiff
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2021-2023 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define-module (tests-style)
  #:use-module (guix read-print)
  #:use-module (guix gexp)                        ;for the reader extensions
  #:use-module (srfi srfi-34)
  #:use-module (srfi srfi-35)
  #:use-module (srfi srfi-64)
  #:use-module (ice-9 match))

(define-syntax-rule (test-pretty-print str args ...)
  "Test equality after a round-trip where STR is passed to
'read-with-comments' and the resulting sexp is then passed to
'pretty-print-with-comments'."
  (test-equal str
    (call-with-output-string
      (lambda (port)
        (let ((exp (call-with-input-string str
                     read-with-comments)))
         (pretty-print-with-comments port exp args ...))))))

(define-syntax-rule (test-pretty-print/sequence str args ...)
  "Likewise, but read and print entire sequences rather than individual
expressions."
  (test-equal str
    (call-with-output-string
      (lambda (port)
        (let ((lst (call-with-input-string str
                     read-with-comments/sequence)))
         (pretty-print-with-comments/splice port lst args ...))))))


(test-begin "read-print")

(test-assert "read-with-comments: missing closing paren"
  (guard (c ((error? c) #t))
    (call-with-input-string "(what is going on?"
      read-with-comments)))

(test-equal "read-with-comments: dot notation"
  (cons 'a 'b)
  (call-with-input-string "(a . b)"
    read-with-comments))

(test-equal "read-with-comments: half dot notation"
  '(lambda x x)
  (call-with-input-string "(lambda (. x) x)"
    read-with-comments))

(test-equal "read-with-comments: list with blank line"
  `(list with ,(vertical-space 1) blank line)
  (call-with-input-string "\
(list with

      blank line)\n"
    read-with-comments))

(test-equal "read-with-comments: list with multiple blank lines"
  `(list with ,(comment ";multiple\n" #t)
         ,(vertical-space 3) blank lines)
  (call-with-input-string "\
(list with ;multiple



      blank lines)\n"
    read-with-comments))

(test-equal "read-with-comments: top-level blank lines"
  (list (vertical-space 2) '(a b c) (vertical-space 2))
  (call-with-input-string "

(a b c)\n\n"
    (lambda (port)
      (list (read-with-comments port)
            (read-with-comments port)
            (read-with-comments port)))))

(test-equal "read-with-comments: top-level page break"
  (list (comment ";; Begin.\n") (vertical-space 1)
        (page-break)
        (comment ";; End.\n"))
  (call-with-input-string "\
;; Begin.


;; End.\n"
    (lambda (port)
      (list (read-with-comments port)
            (read-with-comments port)
            (read-with-comments port)
            (read-with-comments port)))))

(test-pretty-print "(list 1 2 3 4)")
(test-pretty-print "((a . 1) (b . 2))")
(test-pretty-print "(a b c . boom)")
(test-pretty-print "(list 1
                          2
                          3
                          4)"
                   #:long-list 3
                   #:indent 20)
(test-pretty-print "\
(list abc
      def)"
                   #:max-width 11)
(test-pretty-print "\
(#:foo
 #:bar)"
                   #:max-width 10)

(test-pretty-print "\
(#:first 1
 #:second 2
 #:third 3)")

(test-pretty-print "\
((x
  1)
 (y
  2)
 (z
  3))"
                   #:max-width 3)

(test-pretty-print "\
(let ((x 1)
      (y 2)
      (z 3)
      (p 4))
  (+ x y))"
                   #:max-width 11)

(test-pretty-print "\
(begin
  1+ 1- 123/ 456*
  (1+ 41))")

(test-pretty-print "\
(lambda (x y)
  ;; This is a procedure.
  (let ((z (+ x y)))
    (* z z)))")

(test-pretty-print "\
(case x
  ((1)
   'one)
  ((2)
   'two))")

(test-pretty-print "\
(cond
  ((zero? x)
   'zero)
  ((odd? x)
   'odd)
  (else #f))")

(test-pretty-print "\
(parameterize ((a 1)
               (b 2))
  (call f g h))")

(test-pretty-print "\
#~(string-append #$coreutils \"/bin/uname\")")

(test-pretty-print "\
(package
  (inherit coreutils)
  (version \"42\"))")

(test-pretty-print "\
(modify-phases %standard-phases
  (add-after 'unpack 'post-unpack
    (lambda _
      #t))
  (add-before 'check 'pre-check
    (lambda* (#:key inputs #:allow-other-keys)
      do things ...)))")

(test-pretty-print "\
(#:phases (modify-phases sdfsdf
            (add-before 'x 'y
              (lambda _
                xyz))))")

(test-pretty-print "\
(string-append \"a\\tb\" \"\\n\")")

(test-pretty-print "\
(display \"This is a very long string.
It contains line breaks, which are preserved,
because it's a long string.\")")

(test-pretty-print "\
(description \"abcdefghijkl
mnopqrstuvwxyz.\")"
                   #:max-width 30)

(test-pretty-print "\
(description
 \"abcdefghijkl
mnopqrstuvwxyz.\")"
                   #:max-width 12)

(test-pretty-print "\
(description
 \"abcdefghijklmnopqrstuvwxyz\")"
                   #:max-width 33)

(test-pretty-print "\
(list ;margin comment
      a b c)")

(test-pretty-print "\
(list
 ;; This is a line comment immediately following the list head.
 #:test-flags #~(list \"-m\" \"not external and not samples\"))")

(test-pretty-print "\
(modify-phases %standard-phases
  (replace 'build
    ;; Nicely indented in 'modify-phases' context.
    (lambda _
      #t)))")

(test-pretty-print "\
(modify-inputs inputs
  ;; Regular indentation for 'replace' here.
  (replace \"gmp\" gmp))")

(test-pretty-print "\
#~(modify-phases phases
    (add-after 'whatever 'something-else
      (lambda _
        ;; This comment appears inside a gexp.
        42)))")

(test-pretty-print "\
#~(list #$@(list coreutils ;yup
                 grep) ;margin comment
        #+sed

        ;; Line comment.
        #$grep)")

(test-pretty-print "\
(package
  ;; Here 'source', 'sha256', and 'arguments' must be
  ;; immediately followed by a newline.
  (source
   (origin
     (method url-fetch)
     (sha256
      (base32 \"not a real base32 string\"))))
  (arguments
   '(#:phases %standard-phases
     #:tests? #f)))")

;; '#:key value' is kept on the same line.
(test-pretty-print "\
(package
  (name \"keyword-value-same-line\")
  (arguments
   (list
    #:phases #~(modify-phases %standard-phases
                 (add-before 'x 'y
                   (lambda* (#:key inputs #:allow-other-keys)
                     (foo bar baz))))
    #:make-flags #~'(\"ANSWER=42\")
    #:tests? #f)))")

(test-pretty-print "\
(let ((x 1)
      (y 2)
      (z (let* ((a 3)
                (b 4))
           (+ a b))))
  (list x y z))")

(test-pretty-print "\
(begin
  (chmod \"foo\" #o750)
  (chmod port
         (logand #o644
                 (lognot (umask))))
  (logand #x7f xyz))")

(test-pretty-print "\
(substitute-keyword-arguments (package-arguments x)
  ((#:phases phases)
   `(modify-phases ,phases
      (add-before 'build 'do-things
        (lambda _
          #t))))
  ((#:configure-flags flags)
   `(cons \"--without-any-problem\"
          ,flags)))")

(test-pretty-print "\
(vertical-space one:

                two:


                three:



                end)")

(test-pretty-print "\
(vertical-space one

                ;; Comment after blank line.
                two)")

(test-pretty-print "\
(begin
  break

  ;; page break above
  end)")

(test-pretty-print "\
(home-environment
  (services
   (list (service-type home-bash-service-type))))")

(test-pretty-print/sequence "\
;;; This is a top-level comment.


;; Above is a page break.
(this is an sexp
      ;; with a comment
      !!)

;; The end.\n")

(test-pretty-print/sequence "
;;; Hello!
;;; Notice that there are three semicolons here.

(define-module (foo bar)
  #:use-module (guix)
  #:use-module (gnu))


;; And now, the OS.
(operating-system
  (host-name \"komputilo\")
  (locale \"eo_EO.UTF-8\")

  (services
   (cons (service mcron-service-type) %base-services)))\n"
                            #:format-comment canonicalize-comment)

(test-equal "pretty-print-with-comments, canonicalize-comment"
  "\
(list abc
      ;; Not a margin comment.
      ;; Ditto.
      ;;
      ;; There's a blank line above.
      def ;margin comment
      ghi)"
  (let ((sexp (call-with-input-string
                  "\
(list abc
  ;Not a margin comment.
  ;;;  Ditto.
  ;;;;;
  ; There's a blank line above.
  def  ;; margin comment
  ghi)"
                read-with-comments)))
    (call-with-output-string
      (lambda (port)
        (pretty-print-with-comments port sexp
                                    #:format-comment
                                    canonicalize-comment)))))

(test-equal "pretty-print-with-comments, canonicalize-vertical-space"
  "\
(list abc

      def

      ;; last one
      ghi)"
  (let ((sexp (call-with-input-string
                  "\
(list abc



  def


;; last one
  ghi)"
                read-with-comments)))
    (call-with-output-string
      (lambda (port)
        (pretty-print-with-comments port sexp
                                    #:format-vertical-space
                                    canonicalize-vertical-space)))))

(test-equal "pretty-print-with-comments, multi-line comment"
  "\
(list abc
      ;; This comment spans
      ;; two lines.
      def)"
  (call-with-output-string
    (lambda (port)
      (pretty-print-with-comments port
                                  `(list abc ,(comment "\
;; This comment spans\n
;; two lines.\n")
                                         def)))))

(test-end)
emove use of 'ENOENT-safe'. (partition-predicate): Wrap READER in 'ENOENT-safe'. Ludovic Courtès 2021-03-10file-systems: 'mount-file-system' preserves the right mount flags....Fixes <https://bugs.gnu.org/47007>. Reported by Jelle Licht <jlicht@fsfe.org>. Since commit dcb640f02b1f9590c3bd4301a22bf31bd60c56d4, we could end up applying the wrong mount flags because the (find ...) expression could pick the "wrong" mount point in the presence of bind mounts. * gnu/build/file-systems.scm (mount-file-system): Use 'statfs' to compute FLAGS whe FS is a bind mount. Ludovic Courtès 2021-02-25file-systems: 'mount-file-system' preserves source flags for bind mounts....Fixes <https://bugs.gnu.org/46292>. * gnu/build/file-systems.scm (mount-file-system): If FS is a bind mount, add its original mount flags to FLAGS. Ludovic Courtès 2020-12-06file-systems: Fix ‘bcachefs fsck’ exit value logic....Bit 1 means the target device was mounted read-only whilst checking. This should never happen in an initrd context but is not an error. * gnu/build/file-systems.scm (check-bcachefs-file-system): Ignore status bits that don't signal an error. Remove the 'reboot-required case. Tobias Geerinckx-Rice 2020-11-07file-systems: Add support for bcachefs....* gnu/build/file-systems.scm (%bcachefs-endianness): New syntax. (bcachefs-superblock?, read-bcachefs-superblock) (bcachefs-superblock-external-uuid, bcachefs-superblock-volume-name) (check-bcachefs-file-system): New procedures. (%partition-label-readers, %partition-uuid-readers, check-file-system): Register them. Tobias Geerinckx-Rice 2020-10-30file-systems: Allow swap space lookup by UUID/label....* gnu/build/file-systems.scm (%linux-swap-magic, %page-size): New variables. (linux-swap-superblock?, read-linux-swap-superblock) (linux-swap-superblock-uuid, linux-swap-superblock-volume-name): New procedures. (%partition-label-readers, %partition-uuid-readers): Add them. Ludovic Courtès 2020-09-07linux-boot: Handle nfs-root device strings....* gnu/build/linux-boot.scm (device-string->file-system-device): Support nfs-root "device" strings. * gnu/build/file-systems.scm (canonicalize-device-spec): Support nfs-root "device" strings. * gnu/machine/ssh.scm (machine-check-file-system-availability): Avoid checking of NFS file systems. * gnu/system.scm (read-boot-parameters, device-sexp->device): Support nfs-root "device" strings. Signed-off-by: Danny Milosavljevic <dannym@scratchpost.org> Stefan 2020-07-31file-system: Add mount-may-fail? option....* gnu/system/file-systems.scm (<file-system>): Add a mount-may-fail? field. (file-system->spec): adapt accordingly, (spec->file-system): ditto. * gnu/build/file-systems.scm (mount-file-system): If 'system-error is raised and mount-may-fail? is true, ignore it. Otherwise, re-raise the exception. Signed-off-by: Mathieu Othacehe <othacehe@gnu.org> Mathieu Othacehe 2020-07-26file-systems: Add NTFS support....* gnu/system/uuid.scm (%ntfs-endianness): New macro, (ntfs-uuid->string): new procedure, (%ntfs-endianness): new variable, (string->ntfs-uuid): new exported procedure, (%uuid-parsers): add NTFS support, (%uuid-printers): add NTFS support. * gnu/build/file-systems.scm (%ntfs-endianness): New macro, (ntfs-superblock?, read-ntfs-superblock, ntfs-superblock-uuid, check-ntfs-file-system): new procedure, (%partition-uuid-readers): add NTFS support, (check-file-system): add NTFS support. Mathieu Othacehe 2020-05-20linux-boot: Refactor boot-system....The --root option can now be omitted, and inferred from the root file system declaration instead. * gnu/build/file-systems.scm (canonicalize-device-spec): Extend to support NFS directly, and... * gnu/build/linux-boot.scm (boot-system): ...remove NFS special casing from here. Remove nested definitions for root-fs-type, root-fs-flags and root-fs-options, and bind those inside the let* instead. Make "--root" take precedence over the device field string representation of the root file system. * doc/guix.texi (Initial RAM Disk): Document that "--root" can be left unspecified. Maxim Cournoyer 2020-05-03file-systems: Fix UTF-16 handling in initrd....Follow-up to f73f4b3a2d7a313a6cb1667bd69205ea4b09f57c. * gnu/build/file-systems.scm (bytevector->u16-list): New procedure. (utf16->string): New procedure. Danny Milosavljevic 2020-05-03file-systems: Fix F2FS volume name accessor....Follow-up to 23b37c3d40d497cc6f07437ab26ab10e60fb6e09. * gnu/build/file-systems.scm (bytevector-utf16-length): New procedure. (null-terminated-utf16->string): New procedure. (f2fs-superblock-volume-name): Use it. Danny Milosavljevic 2020-05-02file-systems: Add support for F2FS....* gnu/build/file-systems.scm (%f2fs-endianness): New syntax. (f2fs-superblock?, read-f2fs-superblock, f2fs-superblock-uuid) (f2fs-superblock-volume-name, check-f2fs-file-system): New procedures. (%partition-label-readers, %partition-uuid-readers, check-file-system): Register them. Signed-off-by: Danny Milosavljevic <dannym@scratchpost.org> raingloom 2020-03-02build: file-systems: Do not warn about file system check for NFS....* gnu/build/file-systems.scm (check-file-system): Define a dummy checker procedure for NFS that always passes to prevent a warning from being emitted. Maxim Cournoyer 2020-01-05file-systems: Handle LUKS2 header....* gnu/build/file-systems.scm (luks-superblock?): Handle LUKS2 header. Signed-off-by: Danny Milosavljevic <dannym@scratchpost.org> David Trudgian 2020-01-03file-systems: Add support for JFS....* gnu/build/file-systems.scm (%jfs-endianness): New syntax. (jfs-superblock?, read-jfs-superblock, jfs-superblock-uuid) (jfs-superblock-volume-name, check-jfs-file-system): New procedures. (%partition-label-readers, %partition-uuid-readers, check-file-system): Register them. Tobias Geerinckx-Rice 2019-12-07file-systems: Add support for 'strict-atime' and 'lazy-time' flags....* guix/build/syscalls.scm (MS_LAZYTIME): New variable. * gnu/build/file-systems.scm (mount-flags->bit-mask): Add match rules for 'strict-atime' and 'lazy-time'. * doc/guix.texi (File Systems): Add 'strict-atime' and 'lazy-time' to the list of supported flags. Signed-off-by: Ludovic Courtès <ludo@gnu.org> Guillaume Le Vaillant 2019-11-18file-systems: Fix docstring....* gnu/build/file-systems.scm (mount-file-system): Clean the documentation from the no longer existing parameters (these are now encapsulated within a <file-system> record). Maxim Cournoyer 2019-04-29file-systems: Support the 'no-atime' flag....* guix/build/syscalls.scm (MS_NOATIME): New variable. * gnu/build/file-systems.scm (mount-flags->bit-mask): Support it. * doc/guix.texi (File Systems): Document it and add cross-references to the relevant documentation. Co-authored-by: Ludovic Courtès <ludo@gnu.org> rendaw 2019-01-17file-systems: Add read-luks-partition-uuid....Add a specific procedure to read luks partition uuid. * gnu/build/file-systems.scm (luks-partition-field-reader): New procedure ... (luks-partition-uuid-predicate): ... used here, (read-luks-partition-uuid): new exported procedure. Mathieu Othacehe 2019-01-17file-systems: Export read-partition-label and read-partition-uuid....* gnu/build/file-systems.scm (read-partition-label): Export it, (read-partition-uuid): ditto. Mathieu Othacehe 2018-12-18file-systems: Have the emergency REPL output to /dev/console....This fixes a bug whereby all emergency REPL output would go to /dev/klog and thus, each line would be prefixed by "[12324.432] shepherd[1]: ". * gnu/build/file-systems.scm (check-file-system): Wrap 'start-repl' call in 'with-output-to-file'. Ludovic Courtès 2018-12-18file-systems: Spawn a REPL only when interaction is possible....Fixes <https://bugs.gnu.org/23697>. Reported by Jan Nieuwenhuizen <janneke@gnu.org>. * gnu/build/file-systems.scm (check-file-system): Call 'start-repl' only if current-input-port passes 'isatty?'. * gnu/services/shepherd.scm (shepherd-configuration-file): After 'for-each' expression, call 'redirect-port'. * gnu/tests/base.scm (run-basic-test)["stdin is /dev/null"]: New test. Ludovic Courtès