[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
04/10: guix: Add "potluck" command.
From: |
Andy Wingo |
Subject: |
04/10: guix: Add "potluck" command. |
Date: |
Fri, 28 Apr 2017 07:50:16 -0400 (EDT) |
wingo pushed a commit to branch wip-potluck
in repository guix.
commit 3d3b569d638f153a8f45526e1c3334f1fd966f3d
Author: Andy Wingo <address@hidden>
Date: Mon Apr 24 14:00:07 2017 +0200
guix: Add "potluck" command.
* guix/scripts/potluck.scm: New file.
* Makefile.am: Add new file.
---
Makefile.am | 1 +
guix/scripts/potluck.scm | 310 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 311 insertions(+)
diff --git a/Makefile.am b/Makefile.am
index 64a7a92..295d7b3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -167,6 +167,7 @@ MODULES = \
guix/scripts/graph.scm \
guix/scripts/container.scm \
guix/scripts/container/exec.scm \
+ guix/scripts/potluck.scm \
guix.scm \
$(GNU_SYSTEM_MODULES)
diff --git a/guix/scripts/potluck.scm b/guix/scripts/potluck.scm
new file mode 100644
index 0000000..f9cd40b
--- /dev/null
+++ b/guix/scripts/potluck.scm
@@ -0,0 +1,310 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2017 Andy Wingo <address@hidden>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (guix scripts potluck)
+ #:use-module (guix config)
+ #:use-module (guix base32)
+ #:use-module ((guix build-system) #:select (build-system-description))
+ #:use-module ((guix licenses) #:select (license-uri))
+ #:use-module (guix git)
+ #:use-module (guix ui)
+ #:use-module (guix utils)
+ #:use-module (guix potluck build-systems)
+ #:use-module (guix potluck licenses)
+ #:use-module (guix potluck packages)
+ #:use-module (guix scripts)
+ #:use-module (guix scripts hash)
+ #:use-module (srfi srfi-1)
+ #:use-module (srfi srfi-34)
+ #:use-module (srfi srfi-35)
+ #:use-module (srfi srfi-37)
+ #:use-module (ice-9 format)
+ #:use-module (ice-9 match)
+ #:use-module (ice-9 pretty-print)
+ #:use-module (json)
+ #:use-module (web client)
+ #:use-module (web response)
+ #:use-module (web uri)
+ #:export (guix-potluck))
+
+
+;;;
+;;; guix potluck init
+;;;
+
+(define* (init-potluck remote-git-url #:key
+ (build-system 'gnu) (autoreconf? #f)
+ (license 'gplv3+))
+ (let* ((cwd (getcwd))
+ (dot-git (in-vicinity cwd ".git"))
+ (potluck-dir (in-vicinity cwd "potluck"))
+ (package-name (basename cwd)))
+ (unless (and (file-exists? dot-git)
+ (file-is-directory? dot-git))
+ (leave (_ "init: must be run from the root of a git checkout~%")))
+ (when (file-exists? potluck-dir)
+ (leave (_ "init: ~a already exists~%") potluck-dir))
+ (let* ((user-name (git-config "user.name"))
+ (pkg-name (basename cwd))
+ (pkg-commit (git-rev-parse "HEAD"))
+ (pkg-version
+ (catch #t
+ (lambda () (git-describe pkg-commit))
+ (lambda _
+ (format (current-error-port)
+ "guix potluck init: git describe failed\n")
+ (format (current-error-port)
+ "Add a tag so that git can compute a version.\n")
+ (exit 1))))
+ ;; FIXME: Race condition if HEAD changes between git-rev-parse and
+ ;; here.
+ (pkg-sha256 (guix-hash-git-checkout cwd)))
+ (format #t (_ "Creating potluck/~%"))
+ (mkdir potluck-dir)
+ (format #t (_ "Creating potluck/README.md~%"))
+ (call-with-output-file (in-vicinity potluck-dir "README.md")
+ (lambda (port)
+ (format port
+ "\
+This directory defines potluck packages. Each file in this directory should
+define one package. See https://potluck.guixsd.org/ for more information.
+")))
+ (format #t (_ "Creating potluck/~a.scm~%") package-name)
+ (call-with-output-file (in-vicinity potluck-dir
+ (string-append package-name ".scm"))
+ (lambda (port)
+
+ (define-syntax-rule (dsp exp) (display exp port))
+ (dsp ";;; guix potluck package\n")
+ (dsp ";;; Copyright (C) 2017 ")
+ (dsp user-name)
+ (dsp "\n")
+ (dsp "
+;;; This file 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. No warranty. See
+;;; https://www.gnu.org/licenses/gpl.html for a copy of the GPLv3.
+
+")
+ (pretty-print-potluck-package
+ port
+ (potluck-package
+ (name pkg-name)
+ (version pkg-version)
+ (source
+ (potluck-source
+ (git-uri remote-git-url)
+ (git-commit pkg-commit)
+ (sha256 (bytevector->nix-base32-string pkg-sha256))))
+ (build-system build-system)
+ (inputs '())
+ (native-inputs
+ (if autoreconf?
+ '("autoconf" "automake" "libtool" "pkg-config")
+ '()))
+ (arguments
+ (if autoreconf?
+ '(#:phases (modify-phases %standard-phases
+ (add-before 'configure 'autoconf
+ (lambda _
+ (zero?
+ (system* "autoreconf" "-vfi"))))))
+ '()))
+ (home-page remote-git-url)
+ (synopsis "Declarative synopsis here")
+ (description
+ (string-append (string-titlecase pkg-name)
+ " is a ..."))
+ (license license)))))
+ (format #t (_ "
+Done. Now open potluck/~a.scm in your editor, fill out its \"synopsis\" and
+\"description\" fields, add dependencies to the 'inputs' field, and try to
+build with
+
+ guix build --file=potluck/~a.scm
+
+When you get that working, commit your results to git via:
+
+ git add guix-potluck && git commit -m 'Add initial Guix potluck files.'
+") pkg-name pkg-name))))
+
+
+;;;
+;;; Options.
+;;;
+
+(define (show-help)
+ (display (_ "Usage: guix potluck [OPTION ...] ACTION [ARG ...]
+Create \"potluck\" packages, register them with a central service, and arrange
+to serve those packages as a Guix channel. Some ACTIONS require additional
+ARGS.\n"))
+ (newline)
+ (display (_ "The valid values for ACTION are:\n"))
+ (newline)
+ (display (_ "\
+ init create potluck recipe for current working directory\n"))
+
+ (newline)
+ (display (_ "The available OPTION flags are:\n"))
+ (display (_ "
+ --build-system=SYS for 'init', specify the build system. Use
+ --build-system=help for all available options."))
+ (display (_ "
+ --autotools for 'init', like --build-system=gnu but additionally
+ indicating that the package needs autoreconf before
+ running ./configure"))
+ (display (_ "
+ --license=LICENSE for 'init', specify the license of the package. Use
+ --license=help for all available options."))
+ (display (_ "
+ --verbosity=LEVEL use the given verbosity LEVEL"))
+ (newline)
+ (display (_ "
+ -h, --help display this help and exit"))
+ (display (_ "
+ -V, --version display version information and exit"))
+ (newline)
+ (show-bug-report-information))
+
+(define %options
+ ;; Specifications of the command-line options.
+ (list (option '(#\h "help") #f #f
+ (lambda args
+ (show-help)
+ (exit 0)))
+ (option '(#\V "version") #f #f
+ (lambda args
+ (show-version-and-exit "guix potluck")))
+ (option '("build-system") #t #f
+ (lambda (opt name arg result)
+ (alist-cons 'build-system arg result)))
+ (option '("autotools") #f #f
+ (lambda (opt name arg result)
+ (alist-cons 'autoreconf? #t
+ (alist-cons 'build-system "gnu" result))))
+ (option '("license") #t #f
+ (lambda (opt name arg result)
+ (alist-cons 'license arg result)))
+ (option '("verbosity") #t #f
+ (lambda (opt name arg result)
+ (alist-cons 'verbosity (string->number arg) result)))))
+
+(define %default-options
+ ;; Alist of default option values.
+ `((verbosity . 0)))
+
+(define (parse-url url-str)
+ (unless (string->uri url-str)
+ (leave (_ "invalid url: ~a~%") url-str))
+ url-str)
+
+(define (parse-build-system sys-str)
+ (unless sys-str
+ (leave (_ "\
+init: missing --build-system; try --build-system=help for options~%")))
+ (let ((sys (string->symbol (string-downcase sys-str))))
+ (when (eq? sys 'help)
+ (format #t "guix potluck: Available build systems:~%")
+ (for-each
+ (lambda (name)
+ (let ((sys (build-system-by-name name)))
+ (format #t " ~a ~25t~a~%" name (build-system-description sys))))
+ (all-potluck-build-system-names))
+ (format #t "
+Additionally, --autotools is like --build-system=gnu, but also indicating
+that the package needs autoreconf before running ./configure.~%")
+ (exit 0))
+ (unless (build-system-by-name sys)
+ (leave (_ "invalid build system: ~a; try --build-system=help~%") sys))
+ sys))
+
+(define (parse-license license-str)
+ (unless license-str
+ (leave (_ "init: missing --license; try --license=help for options~%")))
+ (let ((license (string->symbol (string-downcase license-str))))
+ (when (eq? license 'help)
+ (format #t "guix potluck: Available licenses:~%")
+ (for-each
+ (lambda (name)
+ (let ((license (license-by-name name)))
+ (format #t " ~a ~25t~a~%" name (license-uri license))))
+ (all-potluck-license-names))
+ (format #t "
+If your package's license is not in this list, add it to Guix first.~%")
+ (exit 0))
+ (unless (license-by-name license)
+ (leave (_ "invalid license: ~a; try --license=help~%") license))
+ license))
+
+
+;;;
+;;; Entry point.
+;;;
+
+(define (guix-potluck . args)
+ (define (parse-sub-command arg result)
+ (if (assoc-ref result 'action)
+ (alist-cons 'argument arg result)
+ (alist-cons 'action (string->symbol arg) result)))
+
+ (define (match-pair car)
+ ;; Return a procedure that matches a pair with CAR.
+ (match-lambda
+ ((head . tail)
+ (and (eq? car head) tail))
+ (_ #f)))
+
+ (with-error-handling
+ (let* ((opts (parse-command-line args %options
+ (list %default-options)
+ #:argument-handler
+ parse-sub-command))
+ (action (assoc-ref opts 'action))
+ (args (reverse (filter-map (match-pair 'argument) opts))))
+ (define (see-help)
+ (format (current-error-port)
+ (_ "Try 'guix potluck --help' for more information.~%")))
+ (define (wrong-number-of-args usage)
+ (format (current-error-port)
+ (_ "guix potluck ~a: wrong number of arguments~%")
+ action)
+ (display usage (current-error-port))
+ (newline (current-error-port))
+ (see-help)
+ (exit 1))
+ (match action
+ (#f
+ (format (current-error-port)
+ (_ "guix potluck: missing command name~%"))
+ (see-help)
+ (exit 1))
+ ('init
+ (match args
+ ((remote-git-url)
+ (init-potluck (parse-url remote-git-url)
+ #:build-system (parse-build-system
+ (assoc-ref opts 'build-system))
+ #:autoreconf? (assoc-ref opts 'autoreconf?)
+ #:license (parse-license
+ (assoc-ref opts 'license))))
+ (args
+ (wrong-number-of-args
+ (_ "usage: guix potluck init [OPT...] REMOTE-GIT-URL")))))
+ (action
+ (leave (_ "~a: unknown action~%") action))))))
- branch wip-potluck created (now eb81966), Andy Wingo, 2017/04/28
- 06/10: gnu: Add find-package-binding., Andy Wingo, 2017/04/28
- 07/10: potluck: Add ability to lower potluck package to guix package., Andy Wingo, 2017/04/28
- 09/10: doc: Document guix potluck., Andy Wingo, 2017/04/28
- 04/10: guix: Add "potluck" command.,
Andy Wingo <=
- 05/10: potluck: Add ability to load potluck package in sandbox., Andy Wingo, 2017/04/28
- 01/10: guix: Add "potluck" packages., Andy Wingo, 2017/04/28
- 02/10: guix hash: Add --git option to hash a git checkout., Andy Wingo, 2017/04/28
- 10/10: gnu: Add potluck host-channel service., Andy Wingo, 2017/04/28
- 03/10: guix: Add git utility module., Andy Wingo, 2017/04/28
- 08/10: potluck: Add host-channel subcommand., Andy Wingo, 2017/04/28