Archived
1
0
Fork 0

style: Add '--styling' option.

* guix/scripts/style.scm (format-package-definition): New procedure.
(%options, show-help): Add "--styling".
(%default-options): Add 'styling-procedure'.
(guix-style): Honor it.
* tests/style.scm (with-test-package)
("input labels, 'safe' policy")
("input labels, 'safe' policy, nothing changed")
("input labels, margin comment")
("input labels, margin comment on long list")
("input labels, line comment")
("input labels, modify-inputs and margin comment"): Pass "-S inputs".
* etc/indent-code.el: Remove.
* doc/contributing.texi (Formatting Code): Mention "guix style" instead
of "etc/indent-code.el".
(Submitting Patches): Add item for "guix style".
* doc/guix.texi (Invoking guix style): Document "-S" and update.
This commit is contained in:
Ludovic Courtès 2022-01-02 17:29:12 +01:00
parent 6f892630ae
commit c4fe13c294
No known key found for this signature in database
GPG key ID: 090B11993D9AEBB5
5 changed files with 111 additions and 147 deletions

View file

@ -959,17 +959,11 @@ If you do not use Emacs, please make sure to let your editor knows these
rules. To automatically indent a package definition, you can also run: rules. To automatically indent a package definition, you can also run:
@example @example
./etc/indent-code.el gnu/packages/@var{file}.scm @var{package} ./pre-inst-env guix style @var{package}
@end example @end example
@noindent @noindent
This automatically indents the definition of @var{package} in @xref{Invoking guix style}, for more information.
@file{gnu/packages/@var{file}.scm} by running Emacs in batch mode. To
indent a whole file, omit the second argument:
@example
./etc/indent-code.el gnu/services/@var{file}.scm
@end example
@cindex Vim, Scheme code editing @cindex Vim, Scheme code editing
If you are editing code with Vim, we recommend that you run @code{:set If you are editing code with Vim, we recommend that you run @code{:set
@ -1038,6 +1032,10 @@ Run @code{guix lint @var{package}}, where @var{package} is the
name of the new or modified package, and fix any errors it reports name of the new or modified package, and fix any errors it reports
(@pxref{Invoking guix lint}). (@pxref{Invoking guix lint}).
@item
Run @code{guix style @var{package}} to format the new package definition
according to the project's conventions (@pxref{Invoking guix style}).
@item @item
Make sure the package builds on your platform, using @code{guix build Make sure the package builds on your platform, using @code{guix build
@var{package}}. @var{package}}.
@ -1175,8 +1173,8 @@ Examples of unrelated changes include the addition of several packages,
or a package update along with fixes to that package. or a package update along with fixes to that package.
@item @item
Please follow our code formatting rules, possibly running the Please follow our code formatting rules, possibly running
@command{etc/indent-code.el} script to do that automatically for you @command{guix style} script to do that automatically for you
(@pxref{Formatting Code}). (@pxref{Formatting Code}).
@item @item

View file

@ -12785,8 +12785,16 @@ otherwise.
The @command{guix style} command helps packagers style their package The @command{guix style} command helps packagers style their package
definitions according to the latest fashionable trends. The command definitions according to the latest fashionable trends. The command
currently focuses on one aspect: the style of package inputs. It may currently provides the providing styling rules:
eventually be extended to handle other stylistic matters.
@itemize
@item
formatting package definitions according to the project's conventions
(@pxref{Formatting Code});
@item
rewriting package inputs to the ``new style'', as explained below.
@end itemize
The way package inputs are written is going through a transition The way package inputs are written is going through a transition
(@pxref{package Reference}, for more on package inputs). Until version (@pxref{package Reference}, for more on package inputs). Until version
@ -12817,7 +12825,7 @@ Package Variants}, for more info on @code{modify-inputs}).
In the vast majority of cases, this is a purely mechanical change on the In the vast majority of cases, this is a purely mechanical change on the
surface syntax that does not even incur a package rebuild. Running surface syntax that does not even incur a package rebuild. Running
@command{guix style} can do that for you, whether you're working on @command{guix style -S inputs} can do that for you, whether you're working on
packages in Guix proper or in an external channel. packages in Guix proper or in an external channel.
The general syntax is: The general syntax is:
@ -12827,15 +12835,48 @@ guix style [@var{options}] @var{package}@dots{}
@end example @end example
This causes @command{guix style} to analyze and rewrite the definition This causes @command{guix style} to analyze and rewrite the definition
of @var{package}@dots{}. It does so in a conservative way: preserving of @var{package}@dots{} or, when @var{package} is omitted, of @emph{all}
comments and bailing out if it cannot make sense of the code that the packages. The @option{--styling} or @option{-S} option allows you
appears in an inputs field. The available options are listed below. to select the style rule, the default rule being @code{format}---see
below.
The available options are listed below.
@table @code @table @code
@item --dry-run @item --dry-run
@itemx -n @itemx -n
Show source file locations that would be edited but do not modify them. Show source file locations that would be edited but do not modify them.
@item --styling=@var{rule}
@itemx -S @var{rule}
Apply @var{rule}, one of the following styling rules:
@table @code
@item format
Format the given package definition(s)---this is the default styling
rule. For example, a packager running Guix on a checkout
(@pxref{Running Guix Before It Is Installed}) might want to reformat the
definition of the Coreutils package like so:
@example
./pre-inst-env guix style coreutils
@end example
@item inputs
Rewrite package inputs to the ``new style'', as described above. This
is how you would rewrite inputs of package @code{whatnot} in your own
channel:
@example
guix style -L ~/my/channel -S inputs whatnot
@end example
Rewriting is done in a conservative way: preserving comments and bailing
out if it cannot make sense of the code that appears in an inputs field.
The @option{--input-simplification} option described below provides
fine-grain control over when inputs should be simplified.
@end table
@item --load-path=@var{directory} @item --load-path=@var{directory}
@itemx -L @var{directory} @itemx -L @var{directory}
Add @var{directory} to the front of the package module search path Add @var{directory} to the front of the package module search path
@ -12854,9 +12895,10 @@ guix style -e '(@@ (gnu packages gcc) gcc-5)'
styles the @code{gcc-5} package definition. styles the @code{gcc-5} package definition.
@item --input-simplification=@var{policy} @item --input-simplification=@var{policy}
Specify the package input simplification policy for cases where an input When using the @code{inputs} styling rule, with @samp{-S inputs}, this
label does not match the corresponding package name. @var{policy} may option specifies the package input simplification policy for cases where
be one of the following: an input label does not match the corresponding package name.
@var{policy} may be one of the following:
@table @code @table @code
@item silent @item silent

View file

@ -1,120 +0,0 @@
:;exec emacs --batch --quick --load="$0" --funcall=main "$@"
;;; indent-code.el --- Run Emacs to indent a package definition.
;; Copyright © 2017 Alex Kost <alezost@gmail.com>
;; Copyright © 2017 Ludovic Courtès <ludo@gnu.org>
;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com>
;; Copyright © 2020 Tobias Geerinckx-Rice <me@tobias.gr>
;; 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 this program. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; This scripts indents the given file or package definition in the specified
;; file using Emacs.
;;; Code:
;; Load Scheme indentation rules from ".dir-locals.el".
(with-temp-buffer
(scheme-mode)
(let ((default-directory (file-name-as-directory load-file-name))
(enable-local-variables :all))
(hack-dir-local-variables)
(hack-local-variables-apply)))
;; Add indentation info for Scheme constructs that are not Guix-specific.
;; This is normally provided by Geiser but this file is for people who may not
;; be running Geiser, so we just copy it here (from 'geiser-syntax.el').
(defmacro guix-syntax--scheme-indent (&rest pairs)
`(progn ,@(mapcar (lambda (p)
`(put ',(car p) 'scheme-indent-function ',(cadr p)))
pairs)))
(guix-syntax--scheme-indent
(and-let* 1)
(case-lambda 0)
(catch defun)
(class defun)
(dynamic-wind 0)
(guard 1)
(let*-values 1)
(let-values 1)
(let/ec 1)
(letrec* 1)
(match 1)
(match-lambda 0)
(match-lambda* 0)
(match-let scheme-let-indent)
(match-let* 1)
(match-letrec 1)
(opt-lambda 1)
(parameterize 1)
(parameterize* 1)
(receive 2)
(require-extension 0)
(syntax-case 2)
(test-approximate 1)
(test-assert 1)
(test-eq 1)
(test-equal 1)
(test-eqv 1)
(test-group-with-cleanup 1)
(test-runner-on-bad-count! 1)
(test-runner-on-bad-end-name! 1)
(test-runner-on-final! 1)
(test-runner-on-group-begin! 1)
(test-runner-on-group-end! 1)
(test-runner-on-test-begin! 1)
(test-runner-on-test-end! 1)
(test-with-runner 1)
(unless 1)
(when 1)
(while 1)
(with-exception-handler 1)
(with-syntax 1))
(defun main ()
(pcase command-line-args-left
(`(,file-name ,package-name)
;; Indent the definition of PACKAGE-NAME in FILE-NAME.
(find-file file-name)
(goto-char (point-min))
(if (re-search-forward (concat "^(define\\(\\|-public\\) +"
package-name)
nil t)
(let ((indent-tabs-mode nil))
(beginning-of-defun)
(mark-sexp)
(untabify (point) (mark))
(indent-sexp)
(save-buffer)
(message "Done!"))
(error "Package '%s' not found in '%s'"
package-name file-name)))
(`(,file-name)
;; Indent all of FILE-NAME.
(find-file file-name)
(let ((indent-tabs-mode nil))
(untabify (point-min) (point-max))
(indent-region (point-min) (point-max))
(save-buffer)
(message "Done!")))
(x
(error "Usage: indent-code.el FILE [PACKAGE]"))))
;;; indent-code.el ends here

View file

@ -686,6 +686,29 @@ PACKAGE."
(list package-inputs package-native-inputs (list package-inputs package-native-inputs
package-propagated-inputs))) package-propagated-inputs)))
;;;
;;; Formatting package definitions.
;;;
(define* (format-package-definition package
#:key policy
(edit-expression edit-expression))
"Reformat the definition of PACKAGE."
(unless (package-definition-location package)
(leave (package-location package)
(G_ "no definition location for package ~a~%")
(package-full-name package)))
(edit-expression
(location->source-properties (package-definition-location package))
(lambda (str)
(let ((exp (call-with-input-string str
read-with-comments)))
(object->string* exp
(location-column
(package-definition-location package)))))))
(define (package-location<? p1 p2) (define (package-location<? p1 p2)
"Return true if P1's location is \"before\" P2's." "Return true if P1's location is \"before\" P2's."
(let ((loc1 (package-location p1)) (let ((loc1 (package-location p1))
@ -712,6 +735,15 @@ PACKAGE."
(option '(#\e "expression") #t #f (option '(#\e "expression") #t #f
(lambda (opt name arg result) (lambda (opt name arg result)
(alist-cons 'expression arg result))) (alist-cons 'expression arg result)))
(option '(#\S "styling") #t #f
(lambda (opt name arg result)
(alist-cons 'styling-procedure
(match arg
("inputs" simplify-package-inputs)
("format" format-package-definition)
(_ (leave (G_ "~a: unknown styling~%")
arg)))
result)))
(option '("input-simplification") #t #f (option '("input-simplification") #t #f
(lambda (opt name arg result) (lambda (opt name arg result)
(let ((symbol (string->symbol arg))) (let ((symbol (string->symbol arg)))
@ -732,6 +764,9 @@ PACKAGE."
(define (show-help) (define (show-help)
(display (G_ "Usage: guix style [OPTION]... [PACKAGE]... (display (G_ "Usage: guix style [OPTION]... [PACKAGE]...
Update package definitions to the latest style.\n")) Update package definitions to the latest style.\n"))
(display (G_ "
-S, --styling=RULE apply RULE, a styling rule"))
(newline)
(display (G_ " (display (G_ "
-n, --dry-run display files that would be edited but do nothing")) -n, --dry-run display files that would be edited but do nothing"))
(display (G_ " (display (G_ "
@ -752,7 +787,8 @@ Update package definitions to the latest style.\n"))
(define %default-options (define %default-options
;; Alist of default option values. ;; Alist of default option values.
'((input-simplification-policy . silent))) `((input-simplification-policy . silent)
(styling-procedure . ,format-package-definition)))
;;; ;;;
@ -779,11 +815,12 @@ Update package definitions to the latest style.\n"))
(edit (if (assoc-ref opts 'dry-run?) (edit (if (assoc-ref opts 'dry-run?)
edit-expression/dry-run edit-expression/dry-run
edit-expression)) edit-expression))
(style (assoc-ref opts 'styling-procedure))
(policy (assoc-ref opts 'input-simplification-policy))) (policy (assoc-ref opts 'input-simplification-policy)))
(with-error-handling (with-error-handling
(for-each (lambda (package) (for-each (lambda (package)
(simplify-package-inputs package #:policy policy (style package #:policy policy
#:edit-expression edit)) #:edit-expression edit))
;; Sort package by source code location so that we start editing ;; Sort package by source code location so that we start editing
;; files from the bottom and going upward. That way, the ;; files from the bottom and going upward. That way, the
;; 'location' field of <package> records is not invalidated as ;; 'location' field of <package> records is not invalidated as

View file

@ -78,7 +78,8 @@
(string-append directory "/my-packages.scm")) (string-append directory "/my-packages.scm"))
;; Run as a separate process to make sure FILE is reloaded. ;; Run as a separate process to make sure FILE is reloaded.
(system* "guix" "style" "-L" directory "my-coreutils") (system* "guix" "style" "-L" directory "-S" "inputs"
"my-coreutils")
(system* "cat" file) (system* "cat" file)
(load file) (load file)
@ -237,6 +238,7 @@
(string-append directory "/my-packages.scm")) (string-append directory "/my-packages.scm"))
(system* "guix" "style" "-L" directory "my-coreutils" (system* "guix" "style" "-L" directory "my-coreutils"
"-S" "inputs"
"--input-simplification=safe") "--input-simplification=safe")
(load file) (load file)
@ -258,6 +260,7 @@
(string-append directory "/my-packages.scm")) (string-append directory "/my-packages.scm"))
(system* "guix" "style" "-L" directory "my-coreutils" (system* "guix" "style" "-L" directory "my-coreutils"
"-S" "inputs"
"--input-simplification=safe") "--input-simplification=safe")
(load file) (load file)
@ -284,7 +287,8 @@
" ;another one\n"))) " ;another one\n")))
(system* "cat" file) (system* "cat" file)
(system* "guix" "style" "-L" directory "my-coreutils") (system* "guix" "style" "-L" directory "-S" "inputs"
"my-coreutils")
(load file) (load file)
(list (package-inputs (@ (my-packages) my-coreutils)) (list (package-inputs (@ (my-packages) my-coreutils))
@ -317,7 +321,8 @@
" ;margin comment\n"))) " ;margin comment\n")))
(system* "cat" file) (system* "cat" file)
(system* "guix" "style" "-L" directory "my-coreutils") (system* "guix" "style" "-L" directory "-S" "inputs"
"my-coreutils")
(load file) (load file)
(list (package-inputs (@ (my-packages) my-coreutils)) (list (package-inputs (@ (my-packages) my-coreutils))
@ -338,7 +343,8 @@
((",gmp\\)(.*)$" _ rest) ((",gmp\\)(.*)$" _ rest)
(string-append ",gmp)\n ;; line comment!\n" rest))) (string-append ",gmp)\n ;; line comment!\n" rest)))
(system* "guix" "style" "-L" directory "my-coreutils") (system* "guix" "style" "-L" directory "-S" "inputs"
"my-coreutils")
(load file) (load file)
(list (package-inputs (@ (my-packages) my-coreutils)) (list (package-inputs (@ (my-packages) my-coreutils))
@ -364,7 +370,8 @@
((",acl\\)(.*)$" _ rest) ((",acl\\)(.*)$" _ rest)
(string-append ",acl) ;another one\n" rest))) (string-append ",acl) ;another one\n" rest)))
(system* "guix" "style" "-L" directory "my-coreutils") (system* "guix" "style" "-L" directory "-S" "inputs"
"my-coreutils")
(load file) (load file)
(list (package-inputs (@ (my-packages) my-coreutils)) (list (package-inputs (@ (my-packages) my-coreutils))