summary refs log tree commit diff
diff options
context:
space:
mode:
authorMark H Weaver <mhw@netris.org>2013-02-14 04:15:25 -0500
committerMark H Weaver <mhw@netris.org>2013-02-16 22:17:37 -0500
commite49951eb3e1e1a8e7bad6d7471483e70b0865352 (patch)
tree7924fec33724f1de6a1cdd0757c7ebe38c7bee6b
parent040860152e63bbafb2eb3e93619e18d107c96b55 (diff)
downloadguix-e49951eb3e1e1a8e7bad6d7471483e70b0865352.tar.gz
Replace individual scripts with master 'guix' script.
* scripts/guix.in: New script.

* Makefile.am (bin_SCRIPTS): Add 'scripts/guix'.  Remove 'guix-build',
  'guix-download', 'guix-import', 'guix-package', and 'guix-gc'.

  (MODULES): Add 'guix/scripts/build.scm', 'guix/scripts/download.scm',
  'guix/scripts/import.scm', 'guix/scripts/package.scm', and
  'guix/scripts/gc.scm'.

* configure.ac (AC_CONFIG_FILES): Add 'scripts/guix'.  Remove 'guix-build',
  'guix-download', 'guix-import', 'guix-package', and 'guix-gc'.

* guix-build.in, guix-download.in, guix-gc.in, guix-import.in,
  guix-package.in: Remove shell script boilerplate.  Move to guix-COMMAND.in
  to guix/scripts/COMMAND.scm.  Rename module from (guix-COMMAND) to
  (guix scripts COMMAND).  Change "guix-COMMAND" to "guix COMMAND" in
  usage help string.

* pre-inst-env.in: Add "@abs_top_builddir@/scripts" to the front of $PATH.
  Export $GUIX_UNINSTALLED.

* tests/guix-build.sh, tests/guix-daemon.sh, tests/guix-download.sh,
  tests/guix-gc.sh, tests/guix-package.sh: Use "guix COMMAND" instead of
  "guix-COMMAND".

* doc/guix.texi: Replace all occurrences of "guix-COMMAND" with
  "guix COMMAND".

* po/POTFILES.in: Update.
-rw-r--r--.gitignore6
-rw-r--r--Makefile.am11
-rw-r--r--configure.ac9
-rw-r--r--doc/guix.texi82
-rw-r--r--guix/scripts/build.scm (renamed from guix-build.in)17
-rw-r--r--guix/scripts/download.scm (renamed from guix-download.in)17
-rw-r--r--guix/scripts/gc.scm (renamed from guix-gc.in)22
-rw-r--r--guix/scripts/import.scm (renamed from guix-import.in)17
-rw-r--r--guix/scripts/package.scm (renamed from guix-package.in)17
-rw-r--r--guix/ui.scm38
-rw-r--r--po/POTFILES.in8
-rw-r--r--pre-inst-env.in11
-rw-r--r--scripts/guix.in56
-rw-r--r--tests/guix-build.sh26
-rw-r--r--tests/guix-daemon.sh6
-rw-r--r--tests/guix-download.sh12
-rw-r--r--tests/guix-gc.sh24
-rw-r--r--tests/guix-package.sh56
18 files changed, 227 insertions, 208 deletions
diff --git a/.gitignore b/.gitignore
index ecdaed2ef0..302e473fd8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,7 +34,6 @@ config.cache
 /po/remove-potcdate.sin
 /po/stamp-po
 /po/guix.pot
-/guix-build
 /tests/*.trs
 /INSTALL
 /m4/*
@@ -44,12 +43,9 @@ config.cache
 /doc/guix.pdf
 /doc/stamp-vti
 /doc/version.texi
-/guix-download
 /gnu/packages/bootstrap/x86_64-linux/guile-2.0.7.tar.xz
 /gnu/packages/bootstrap/i686-linux/guile-2.0.7.tar.xz
-/guix-package
 /guix/config.scm
-/guix-import
 /nix/nix-daemon/nix-daemon.cc
 /nix/config.h
 /nix/config.h.in
@@ -64,7 +60,7 @@ stamp-h[0-9]
 /nix/scripts/list-runtime-roots
 /test-env
 /nix/nix-setuid-helper/nix-setuid-helper.cc
-/guix-gc
+/scripts/guix
 /doc/guix.aux
 /doc/guix.cp
 /doc/guix.cps
diff --git a/Makefile.am b/Makefile.am
index 7a1b6ad163..5932e1350a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -18,17 +18,18 @@
 # along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
 
 bin_SCRIPTS =					\
-  guix-build					\
-  guix-download					\
-  guix-import					\
-  guix-package					\
-  guix-gc
+  scripts/guix
 
 nodist_noinst_SCRIPTS =				\
   pre-inst-env					\
   test-env
 
 MODULES =					\
+  guix/scripts/build.scm			\
+  guix/scripts/download.scm			\
+  guix/scripts/import.scm			\
+  guix/scripts/package.scm			\
+  guix/scripts/gc.scm				\
   guix/base32.scm				\
   guix/utils.scm				\
   guix/derivations.scm				\
diff --git a/configure.ac b/configure.ac
index a9cf17ac57..dd1f843afb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -117,14 +117,9 @@ AC_CONFIG_FILES([Makefile
                  po/Makefile.in
 		 guix/config.scm])
 
-AC_CONFIG_FILES([guix-build
-		 guix-download
-		 guix-import
-		 guix-package
-		 guix-gc
+AC_CONFIG_FILES([scripts/guix
 		 pre-inst-env
 		 test-env],
-  [chmod +x guix-build guix-download guix-import guix-package guix-gc \
-            pre-inst-env test-env])
+  [chmod +x scripts/guix pre-inst-env test-env])
 
 AC_OUTPUT
diff --git a/doc/guix.texi b/doc/guix.texi
index 80149326c1..f84b37686a 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -13,9 +13,9 @@
 @dircategory Package management
 @direntry
 * guix: (guix).       Guix, the functional package manager.
-* guix-package: (guix)Invoking guix-package
+* guix package: (guix)Invoking guix package
                       Managing packages with Guix.
-* guix-build: (guix)Invoking guix-build
+* guix build: (guix)Invoking guix build
                       Building packages with Guix.
 @end direntry
 
@@ -196,7 +196,7 @@ are all performed by a specialized process, the @dfn{Guix daemon}, on
 behalf of clients.  Only the daemon may access the store and its
 associated database.  Thus, any operation that manipulates the store
 goes through the daemon.  For instance, command-line tools such as
-@command{guix-package} and @command{guix-build} communicate with the
+@command{guix package} and @command{guix build} communicate with the
 daemon (@i{via} remote procedure calls) to instruct it what to do.
 
 In a standard multi-user setup, Guix and its daemon---the
@@ -302,8 +302,8 @@ Use @var{n} CPU cores to build each derivation; @code{0} means as many
 as available.
 
 The default value is @code{1}, but it may be overridden by clients, such
-as the @code{--cores} option of @command{guix-build} (@pxref{Invoking
-guix-build}).
+as the @code{--cores} option of @command{guix build} (@pxref{Invoking
+guix build}).
 
 The effect is to define the @code{NIX_BUILD_CORES} environment variable
 in the build process, which can then use it to exploit internal
@@ -319,7 +319,7 @@ Produce debugging output.
 
 This is useful to debug daemon start-up issues, but then it may be
 overridden by clients, for example the @code{--verbosity} option of
-@command{guix-build} (@pxref{Invoking guix-build}).
+@command{guix build} (@pxref{Invoking guix build}).
 
 @item --chroot-directory=@var{dir}
 Add @var{dir} to the build chroot.
@@ -384,8 +384,8 @@ management tools it provides.
 
 @menu
 * Features::                    How Guix will make your life brighter.
-* Invoking guix-package::       Package installation, removal, etc.
-* Invoking guix-gc::            Running the garbage collector.
+* Invoking guix package::       Package installation, removal, etc.
+* Invoking guix gc::            Running the garbage collector.
 @end menu
 
 @node Features
@@ -408,14 +408,14 @@ simply continues to point to
 @file{/nix/store/@dots{}-gcc-4.8.0/bin/gcc}---i.e., both versions of GCC
 coexist on the same system without any interference.
 
-The @command{guix-package} command is the central tool to manage
-packages (@pxref{Invoking guix-package}).  It operates on those per-user
+The @command{guix package} command is the central tool to manage
+packages (@pxref{Invoking guix package}).  It operates on those per-user
 profiles, and can be used @emph{with normal user privileges}.
 
 The command provides the obvious install, remove, and upgrade
 operations.  Each invocation is actually a @emph{transaction}: either
 the specified operation succeeds, or nothing happens.  Thus, if the
-@command{guix-package} process is terminated during the transaction,
+@command{guix package} process is terminated during the transaction,
 or if a power outage occurs during the transaction, then the user's
 profile remains in its previous state, and remains usable.
 
@@ -427,7 +427,7 @@ of their profile, which was known to work well.
 All those packages in the package store may be @emph{garbage-collected}.
 Guix can determine which packages are still referenced by the user
 profiles, and remove those that are provably no longer referenced
-(@pxref{Invoking guix-gc}).  Users may also explicitly remove old
+(@pxref{Invoking guix gc}).  Users may also explicitly remove old
 generations of their profile so that the packages they refer to can be
 collected.
 
@@ -447,17 +447,17 @@ details.}.  When a pre-built binary for a @file{/nix/store} path is
 available from an external source, Guix just downloads it; otherwise, it
 builds the package from source, locally.
 
-@node Invoking guix-package
-@section Invoking @command{guix-package}
+@node Invoking guix package
+@section Invoking @command{guix package}
 
-The @command{guix-package} command is the tool that allows users to
+The @command{guix package} command is the tool that allows users to
 install, upgrade, and remove packages, as well as rolling back to
 previous configurations.  It operates only on the user's own profile,
 and works with normal user privileges (@pxref{Features}).  Its syntax
 is:
 
 @example
-guix-package @var{options}
+guix package @var{options}
 @end example
 
 Primarily, @var{options} specifies the operations to be performed during
@@ -473,13 +473,13 @@ variable, and so on.
 
 In a multi-user setup, user profiles must be stored in a place
 registered as a @dfn{garbage-collector root}, which
-@file{$HOME/.guix-profile} points to (@pxref{Invoking guix-gc}).  That
+@file{$HOME/.guix-profile} points to (@pxref{Invoking guix gc}).  That
 directory is normally
 @code{@var{localstatedir}/profiles/per-user/@var{user}}, where
 @var{localstatedir} is the value passed to @code{configure} as
 @code{--localstatedir}, and @var{user} is the user name.  It must be
 created by @code{root}, with @var{user} as the owner.  When it does not
-exist, @command{guix-package} emits an error about it.
+exist, @command{guix package} emits an error about it.
 
 The @var{options} can be among the following:
 
@@ -548,7 +548,7 @@ useful to distribution developers.
 
 @end table
 
-In addition to these actions @command{guix-package} supports the
+In addition to these actions @command{guix package} supports the
 following options to query the current state of a profile, or the
 availability of packages:
 
@@ -565,7 +565,7 @@ This allows specific fields to be extracted using the @command{recsel}
 command, for instance:
 
 @example
-$ guix-package -s malloc | recsel -p name,version
+$ guix package -s malloc | recsel -p name,version
 name: glibc
 version: 2.17
 
@@ -599,22 +599,22 @@ source location of its definition.
 @end table
 
 
-@node Invoking guix-gc
-@section Invoking @command{guix-gc}
+@node Invoking guix gc
+@section Invoking @command{guix gc}
 
 @cindex garbage collector
 Packages that are installed but not used may be @dfn{garbage-collected}.
-The @command{guix-gc} command allows users to explicitly run the garbage
+The @command{guix gc} command allows users to explicitly run the garbage
 collector to reclaim space from the @file{/nix/store} directory.
 
 The garbage collector has a set of known @dfn{roots}: any file under
 @file{/nix/store} reachable from a root is considered @dfn{live} and
 cannot be deleted; any other file is considered @dfn{dead} and may be
 deleted.  The set of garbage collector roots includes default user
-profiles, and may be augmented with @command{guix-build --root}, for
-example (@pxref{Invoking guix-build}).
+profiles, and may be augmented with @command{guix build --root}, for
+example (@pxref{Invoking guix build}).
 
-The @command{guix-gc} command has three modes of operation: it can be
+The @command{guix gc} command has three modes of operation: it can be
 used to garbage-collect any dead files (the default), to delete specific
 files (the @code{--delete} option), or to print garbage-collector
 information.  The available options are listed below:
@@ -737,7 +737,7 @@ The @code{sha256} field specifies the expected SHA256 hash of the file
 being downloaded.  It is mandatory, and allows Guix to check the
 integrity of the file.  The @code{(base32 @dots{})} form introduces the
 base32 representation of the hash.  A convenient way to obtain this
-information is with the @code{guix-download} tool.
+information is with the @code{guix download} tool.
 
 @item
 @cindex GNU Build System
@@ -795,9 +795,9 @@ Guile process launched by the daemon (@pxref{Derivations}).
 
 Once a package definition is in place@footnote{Simple package
 definitions like the one above may be automatically converted from the
-Nixpkgs distribution using the @command{guix-import} command.}, the
-package may actually be built using the @code{guix-build} command-line
-tool (@pxref{Invoking guix-build}).
+Nixpkgs distribution using the @command{guix import} command.}, the
+package may actually be built using the @code{guix build} command-line
+tool (@pxref{Invoking guix build}).
 
 Behind the scenes, a derivation corresponding to the @code{<package>}
 object is first computed by the @code{package-derivation} procedure.
@@ -1015,22 +1015,22 @@ space.
 @chapter Utilities
 
 @menu
-* Invoking guix-build:: Building packages from the command line.
+* Invoking guix build:: Building packages from the command line.
 @end menu
 
-@node Invoking guix-build
-@section Invoking @command{guix-build}
+@node Invoking guix build
+@section Invoking @command{guix build}
 
-The @command{guix-build} command builds packages or derivations and
+The @command{guix build} command builds packages or derivations and
 their dependencies, and prints the resulting store paths.  Note that it
 does not modify the user's profile---this is the job of the
-@command{guix-package} command (@pxref{Invoking guix-package}).  Thus,
+@command{guix package} command (@pxref{Invoking guix package}).  Thus,
 it is mainly useful for distribution developers.
 
 The general syntax is:
 
 @example
-guix-build @var{options} @var{package-or-derivation}@dots{}
+guix build @var{options} @var{package-or-derivation}@dots{}
 @end example
 
 @var{package-or-derivation} may be either the name of a package found in
@@ -1058,7 +1058,7 @@ version 1.8 of Guile.
 Build the packages' source derivations, rather than the packages
 themselves.
 
-For instance, @code{guix-build -S gcc} returns something like
+For instance, @code{guix build -S gcc} returns something like
 @file{/nix/store/@dots{}-gcc-4.7.2.tar.bz2}, which is GCC's source tarball.
 
 @item --system=@var{system}
@@ -1106,7 +1106,7 @@ may be helpful when debugging setup issues with the build daemon.
 
 @end table
 
-Behind the scenes, @command{guix-build} is essentially an interface to
+Behind the scenes, @command{guix build} is essentially an interface to
 the @code{package-derivation} procedure of the @code{(guix packages)}
 module, and to the @code{build-derivations} procedure of the @code{(guix
 store)} module.
@@ -1121,11 +1121,11 @@ Guix comes with a distribution of free software@footnote{The term
 users of that software}.}  that form the basis of the GNU system.  This
 includes core GNU packages such as GNU libc, GCC, and Binutils, as well
 as many GNU and non-GNU applications.  The complete list of available
-packages can be seen by running @command{guix-package} (@pxref{Invoking
-guix-package}):
+packages can be seen by running @command{guix package} (@pxref{Invoking
+guix package}):
 
 @example
-guix-package --list-available
+guix package --list-available
 @end example
 
 The package definitions of the distribution may are provided by Guile
diff --git a/guix-build.in b/guix/scripts/build.scm
index 35ddb00861..bad04418f1 100644
--- a/guix-build.in
+++ b/guix/scripts/build.scm
@@ -1,16 +1,3 @@
-#!/bin/sh
-# aside from this initial boilerplate, this is actually -*- scheme -*- code
-
-prefix="@prefix@"
-datarootdir="@datarootdir@"
-
-GUILE_LOAD_COMPILED_PATH="@guilemoduledir@:$GUILE_LOAD_COMPILED_PATH"
-export GUILE_LOAD_COMPILED_PATH
-
-main='(module-ref (resolve-interface '\''(guix-build)) '\'guix-build')'
-exec ${GUILE-@GUILE@} -L "@guilemoduledir@" -l "$0"    \
-         -c "(apply $main (cdr (command-line)))" "$@"
-!#
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2012, 2013 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2013 Mark H Weaver <mhw@netris.org>
@@ -30,7 +17,7 @@ exec ${GUILE-@GUILE@} -L "@guilemoduledir@" -l "$0"    \
 ;;; You should have received a copy of the GNU General Public License
 ;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
 
-(define-module (guix-build)
+(define-module (guix scripts build)
   #:use-module (guix ui)
   #:use-module (guix store)
   #:use-module (guix derivations)
@@ -79,7 +66,7 @@ When SOURCE? is true, return the derivations of the package sources."
     (verbosity . 0)))
 
 (define (show-help)
-  (display (_ "Usage: guix-build [OPTION]... PACKAGE-OR-DERIVATION...
+  (display (_ "Usage: guix build [OPTION]... PACKAGE-OR-DERIVATION...
 Build the given PACKAGE-OR-DERIVATION and return their output paths.\n"))
   (display (_ "
   -e, --expression=EXPR  build the package EXPR evaluates to"))
diff --git a/guix-download.in b/guix/scripts/download.scm
index ea62b09a7b..1098e6714b 100644
--- a/guix-download.in
+++ b/guix/scripts/download.scm
@@ -1,16 +1,3 @@
-#!/bin/sh
-# aside from this initial boilerplate, this is actually -*- scheme -*- code
-
-prefix="@prefix@"
-datarootdir="@datarootdir@"
-
-GUILE_LOAD_COMPILED_PATH="@guilemoduledir@:$GUILE_LOAD_COMPILED_PATH"
-export GUILE_LOAD_COMPILED_PATH
-
-main='(module-ref (resolve-interface '\''(guix-download)) '\'guix-download')'
-exec ${GUILE-@GUILE@} -L "@guilemoduledir@" -l "$0"    \
-         -c "(apply $main (cdr (command-line)))" "$@"
-!#
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2012, 2013 Ludovic Courtès <ludo@gnu.org>
 ;;;
@@ -29,7 +16,7 @@ exec ${GUILE-@GUILE@} -L "@guilemoduledir@" -l "$0"    \
 ;;; 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-download)
+(define-module (guix scripts download)
   #:use-module (guix ui)
   #:use-module (guix store)
   #:use-module (guix utils)
@@ -79,7 +66,7 @@ store path."
   `((format . ,bytevector->nix-base32-string)))
 
 (define (show-help)
-  (display (_ "Usage: guix-download [OPTION]... URL
+  (display (_ "Usage: guix download [OPTION]... URL
 Download the file at URL, add it to the store, and print its store path
 and the hash of its contents.\n"))
   (format #t (_ "
diff --git a/guix-gc.in b/guix/scripts/gc.scm
index 1a4a5413d9..8e2587186e 100644
--- a/guix-gc.in
+++ b/guix/scripts/gc.scm
@@ -1,16 +1,3 @@
-#!/bin/sh
-# aside from this initial boilerplate, this is actually -*- scheme -*- code
-
-prefix="@prefix@"
-datarootdir="@datarootdir@"
-
-GUILE_LOAD_COMPILED_PATH="@guilemoduledir@:$GUILE_LOAD_COMPILED_PATH"
-export GUILE_LOAD_COMPILED_PATH
-
-main='(module-ref (resolve-interface '\''(guix-gc)) '\'guix-gc')'
-exec ${GUILE-@GUILE@} -L "@guilemoduledir@" -l "$0"    \
-         -c "(apply $main (cdr (command-line)))" "$@"
-!#
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2012, 2013 Ludovic Courtès <ludo@gnu.org>
 ;;;
@@ -29,7 +16,7 @@ exec ${GUILE-@GUILE@} -L "@guilemoduledir@" -l "$0"    \
 ;;; 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-gc)
+(define-module (guix scripts gc)
   #:use-module (guix ui)
   #:use-module (guix store)
   #:use-module (ice-9 match)
@@ -48,7 +35,7 @@ exec ${GUILE-@GUILE@} -L "@guilemoduledir@" -l "$0"    \
   `((action . collect-garbage)))
 
 (define (show-help)
-  (display (_ "Usage: guix-gc [OPTION]... PATHS...
+  (display (_ "Usage: guix gc [OPTION]... PATHS...
 Invoke the garbage collector.\n"))
   (display (_ "
   -C, --collect-garbage[=MIN]
@@ -155,11 +142,6 @@ interpreted."
                  (alist-cons 'argument arg result))
                %default-options))
 
-  (install-locale)
-  (textdomain "guix")
-  (setvbuf (current-output-port) _IOLBF)
-  (setvbuf (current-error-port) _IOLBF)
-
   (with-error-handling
     (let ((opts  (parse-options))
           (store (open-connection)))
diff --git a/guix-import.in b/guix/scripts/import.scm
index 97619a9a59..0bc6926c66 100644
--- a/guix-import.in
+++ b/guix/scripts/import.scm
@@ -1,16 +1,3 @@
-#!/bin/sh
-# aside from this initial boilerplate, this is actually -*- scheme -*- code
-
-prefix="@prefix@"
-datarootdir="@datarootdir@"
-
-GUILE_LOAD_COMPILED_PATH="@guilemoduledir@:$GUILE_LOAD_COMPILED_PATH"
-export GUILE_LOAD_COMPILED_PATH
-
-main='(module-ref (resolve-interface '\''(guix-import)) '\'guix-import')'
-exec ${GUILE-@GUILE@} -L "@guilemoduledir@" -l "$0"    \
-         -c "(apply $main (cdr (command-line)))" "$@"
-!#
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2012, 2013 Ludovic Courtès <ludo@gnu.org>
 ;;;
@@ -29,7 +16,7 @@ exec ${GUILE-@GUILE@} -L "@guilemoduledir@" -l "$0"    \
 ;;; You should have received a copy of the GNU General Public License
 ;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
 
-(define-module (guix-import)
+(define-module (guix scripts import)
   #:use-module (guix ui)
   #:use-module (guix snix)
   #:use-module (guix utils)
@@ -81,7 +68,7 @@ rather than \\n."
   '())
 
 (define (show-help)
-  (display (_ "Usage: guix-import NIXPKGS ATTRIBUTE
+  (display (_ "Usage: guix import NIXPKGS ATTRIBUTE
 Import and convert the Nix expression ATTRIBUTE of NIXPKGS.\n"))
   (display (_ "
   -h, --help             display this help and exit"))
diff --git a/guix-package.in b/guix/scripts/package.scm
index 584481acd5..4935837d33 100644
--- a/guix-package.in
+++ b/guix/scripts/package.scm
@@ -1,16 +1,3 @@
-#!/bin/sh
-# aside from this initial boilerplate, this is actually -*- scheme -*- code
-
-prefix="@prefix@"
-datarootdir="@datarootdir@"
-
-GUILE_LOAD_COMPILED_PATH="@guilemoduledir@:$GUILE_LOAD_COMPILED_PATH"
-export GUILE_LOAD_COMPILED_PATH
-
-main='(module-ref (resolve-interface '\''(guix-package)) '\'guix-package')'
-exec ${GUILE-@GUILE@} -L "@guilemoduledir@" -l "$0"    \
-         -c "(apply $main (cdr (command-line)))" "$@"
-!#
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2012, 2013 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org>
@@ -31,7 +18,7 @@ exec ${GUILE-@GUILE@} -L "@guilemoduledir@" -l "$0"    \
 ;;; 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-package)
+(define-module (guix scripts package)
   #:use-module (guix ui)
   #:use-module (guix store)
   #:use-module (guix derivations)
@@ -296,7 +283,7 @@ matching packages."
   `((profile . ,%current-profile)))
 
 (define (show-help)
-  (display (_ "Usage: guix-package [OPTION]... PACKAGES...
+  (display (_ "Usage: guix package [OPTION]... PACKAGES...
 Install, remove, or upgrade PACKAGES in a single transaction.\n"))
   (display (_ "
   -i, --install=PACKAGE  install PACKAGE"))
diff --git a/guix/ui.scm b/guix/ui.scm
index 4aa93de3b4..644a3070f6 100644
--- a/guix/ui.scm
+++ b/guix/ui.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2012, 2013 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2013 Mark H Weaver <mhw@netris.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -30,6 +31,7 @@
   #:export (_
             N_
             install-locale
+            initialize-guix
             leave
             show-version-and-exit
             show-bug-report-information
@@ -38,7 +40,9 @@
             location->string
             fill-paragraph
             string->recutils
-            package->recutils))
+            package->recutils
+            run-guix-command
+            guix-main))
 
 ;;; Commentary:
 ;;;
@@ -62,6 +66,12 @@
               (_ "warning: failed to install locale: ~a~%")
               (strerror (system-error-errno args))))))
 
+(define (initialize-guix)
+  (install-locale)
+  (textdomain "guix")
+  (setvbuf (current-output-port) _IOLBF)
+  (setvbuf (current-error-port) _IOLBF))
+
 (define-syntax-rule (leave fmt args ...)
   "Format FMT and ARGS to the error port and exit."
   (begin
@@ -210,4 +220,30 @@ WIDTH columns."
           (and=> (package-description p) description->recutils))
   (newline port))
 
+(define (show-guix-usage)
+  ;; TODO: Dynamically generate a summary of available commands.
+  (format (current-error-port)
+          (_ "Usage: guix COMMAND ARGS...~%")))
+
+(define (run-guix-command command . args)
+  ;; TODO: Gracefully report errors
+  (let* ((module (resolve-interface `(guix scripts ,command)))
+         (command-main (module-ref module
+                                   (symbol-append 'guix- command))))
+    (apply command-main args)))
+
+(define (guix-main arg0 . args)
+  (initialize-guix)
+  (let ()
+    (define (option? str) (string-prefix? "-" str))
+    (match args
+      (() (show-guix-usage) (exit 1))
+      (("--help") (show-guix-usage))
+      (("--version") (show-version-and-exit "guix"))
+      (((? option? arg1) args ...) (show-guix-usage) (exit 1))
+      ((command args ...)
+       (apply run-guix-command
+              (string->symbol command)
+              args)))))
+
 ;;; ui.scm ends here
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 049a1c707e..5c0f131c06 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -4,8 +4,8 @@ gnu/packages/base.scm
 gnu/packages/guile.scm
 gnu/packages/lout.scm
 gnu/packages/recutils.scm
+guix/scripts/build.scm
+guix/scripts/download.scm
+guix/scripts/package.scm
+guix/scripts/gc.scm
 guix/ui.scm
-guix-build.in
-guix-download.in
-guix-package.in
-guix-gc.in
diff --git a/pre-inst-env.in b/pre-inst-env.in
index 1dc63cd90c..4e079c8d41 100644
--- a/pre-inst-env.in
+++ b/pre-inst-env.in
@@ -27,9 +27,9 @@ GUILE_LOAD_COMPILED_PATH="@abs_top_builddir@${GUILE_LOAD_COMPILED_PATH:+:}$GUILE
 GUILE_LOAD_PATH="@abs_top_builddir@:@abs_top_srcdir@${GUILE_LOAD_PATH:+:}:$GUILE_LOAD_PATH"
 export GUILE_LOAD_COMPILED_PATH GUILE_LOAD_PATH
 
-# Define $PATH so that `guix-build' and friends are easily found.
+# Define $PATH so that `guix' and friends are easily found.
 
-PATH="@abs_top_builddir@:$PATH"
+PATH="@abs_top_builddir@/scripts:@abs_top_builddir@:$PATH"
 export PATH
 
 # Daemon helpers.
@@ -43,7 +43,12 @@ export NIX_ROOT_FINDER NIX_SETUID_HELPER
 # auto-compilation.
 
 NIX_HASH="@NIX_HASH@"
-
 export NIX_HASH
 
+# Define $GUIX_UNINSTALLED to prevent `guix' from
+# prepending @guilemoduledir@ to the Guile load paths.
+
+GUIX_UNINSTALLED=1
+export GUIX_UNINSTALLED
+
 exec "$@"
diff --git a/scripts/guix.in b/scripts/guix.in
new file mode 100644
index 0000000000..2fdde7d13a
--- /dev/null
+++ b/scripts/guix.in
@@ -0,0 +1,56 @@
+#!@GUILE@ -s
+-*- scheme -*-
+!#
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2013 Mark H Weaver <mhw@netris.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/>.
+
+;; IMPORTANT: We must avoid loading any modules from Guix here,
+;; because we need to adjust the guile load paths first.
+;; It's okay to import modules from core Guile though.
+(use-modules (ice-9 regex))
+
+(let ()
+  (define-syntax-rule (push! elt v) (set! v (cons elt v)))
+
+  (define config-lookup
+    (let ((config '(("prefix"         . "@prefix@")
+                    ("datarootdir"    . "@datarootdir@")
+                    ("guilemoduledir" . "@guilemoduledir@")))
+          (var-ref-regexp (make-regexp "\\$\\{([a-z]+)\\}")))
+      (define (expand-var-ref match)
+        (lookup (match:substring match 1)))
+      (define (expand str)
+        (regexp-substitute/global #f var-ref-regexp str
+                                  'pre expand-var-ref 'post))
+      (define (lookup name)
+        (expand (assoc-ref config name)))
+      lookup))
+
+  (define (maybe-augment-load-paths!)
+    (unless (getenv "GUIX_UNINSTALLED")
+      (let ((module-dir (config-lookup "guilemoduledir")))
+        (push! module-dir %load-path)
+        (push! module-dir %load-compiled-path))))
+
+  (define (run-guix-main)
+    (let ((guix-main (module-ref (resolve-interface '(guix ui))
+                                 'guix-main)))
+      (apply guix-main (command-line))))
+
+  (maybe-augment-load-paths!)
+  (run-guix-main))
diff --git a/tests/guix-build.sh b/tests/guix-build.sh
index 5718b07d0c..721a7c6769 100644
--- a/tests/guix-build.sh
+++ b/tests/guix-build.sh
@@ -17,44 +17,44 @@
 # along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
 
 #
-# Test the `guix-build' command-line utility.
+# Test the `guix build' command-line utility.
 #
 
-guix-build --version
+guix build --version
 
 # Should fail.
-if guix-build -e +;
+if guix build -e +;
 then false; else true; fi
 
 # Should fail because this is a source-less package.
-if guix-build -e '(@ (gnu packages bootstrap) %bootstrap-glibc)' -S
+if guix build -e '(@ (gnu packages bootstrap) %bootstrap-glibc)' -S
 then false; else true; fi
 
 # Should pass.
-guix-build -e '(@@ (gnu packages base) %bootstrap-guile)' |	\
+guix build -e '(@@ (gnu packages base) %bootstrap-guile)' |	\
     grep -e '-guile-'
-guix-build hello -d |				\
+guix build hello -d |				\
     grep -e '-hello-[0-9\.]\+\.drv$'
 
 # Should fail because the name/version combination could not be found.
-if guix-build hello-0.0.1 -n; then false; else true; fi
+if guix build hello-0.0.1 -n; then false; else true; fi
 
 # Keep a symlink to the result, registered as a root.
 result="t-result-$$"
-guix-build -r "$result"					\
+guix build -r "$result"					\
     -e '(@@ (gnu packages base) %bootstrap-guile)'
 test -x "$result/bin/guile"
 
 # Should fail, because $result already exists.
-if guix-build -r "$result" -e '(@@ (gnu packages base) %bootstrap-guile)'
+if guix build -r "$result" -e '(@@ (gnu packages base) %bootstrap-guile)'
 then false; else true; fi
 
 rm -f "$result"
 
 # Parsing package names and versions.
-guix-build -n time		# PASS
-guix-build -n time-1.7		# PASS, version found
-if guix-build -n time-3.2;	# FAIL, version not found
+guix build -n time		# PASS
+guix build -n time-1.7		# PASS, version found
+if guix build -n time-3.2;	# FAIL, version not found
 then false; else true; fi
-if guix-build -n something-that-will-never-exist; # FAIL
+if guix build -n something-that-will-never-exist; # FAIL
 then false; else true; fi
diff --git a/tests/guix-daemon.sh b/tests/guix-daemon.sh
index 0d39ff4c24..698516490b 100644
--- a/tests/guix-daemon.sh
+++ b/tests/guix-daemon.sh
@@ -23,7 +23,7 @@
 set -e
 
 guix-daemon --version
-guix-build --version
+guix build --version
 
-guix-build -e '(@ (gnu packages bootstrap) %bootstrap-guile)'
-guix-build coreutils -n
+guix build -e '(@ (gnu packages bootstrap) %bootstrap-guile)'
+guix build coreutils -n
diff --git a/tests/guix-download.sh b/tests/guix-download.sh
index f0ea731430..7af6f181f6 100644
--- a/tests/guix-download.sh
+++ b/tests/guix-download.sh
@@ -17,20 +17,20 @@
 # along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
 
 #
-# Test the `guix-download' command-line utility.
+# Test the `guix download' command-line utility.
 #
 
-guix-download --version
+guix download --version
 
 # Make sure it fails here.
-if guix-download http://does.not/exist
+if guix download http://does.not/exist
 then false; else true; fi
 
-if guix-download unknown://some/where;
+if guix download unknown://some/where;
 then false; else true; fi
 
-if guix-download not/a/uri;
+if guix download not/a/uri;
 then false; else true; fi
 
 # This one should succeed.
-guix-download "file://$abs_top_srcdir/README"
+guix download "file://$abs_top_srcdir/README"
diff --git a/tests/guix-gc.sh b/tests/guix-gc.sh
index 805300eeec..a90d085ab2 100644
--- a/tests/guix-gc.sh
+++ b/tests/guix-gc.sh
@@ -17,38 +17,38 @@
 # along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
 
 #
-# Test the `guix-gc' command-line utility.
+# Test the `guix gc' command-line utility.
 #
 
-guix-gc --version
+guix gc --version
 
 trap "rm -f guix-gc-root" EXIT
 rm -f guix-gc-root
 
 # Add then reclaim a .drv file.
-drv="`guix-build idutils -d`"
+drv="`guix build idutils -d`"
 test -f "$drv"
 
-guix-gc --list-dead | grep "$drv"
-guix-gc --delete "$drv"
+guix gc --list-dead | grep "$drv"
+guix gc --delete "$drv"
 ! test -f "$drv"
 
 # Add a .drv, register it as a root.
-drv="`guix-build --root=guix-gc-root lsh -d`"
+drv="`guix build --root=guix-gc-root lsh -d`"
 test -f "$drv" && test -L guix-gc-root
 
-guix-gc --list-live | grep "$drv"
-if guix-gc --delete "$drv";
+guix gc --list-live | grep "$drv"
+if guix gc --delete "$drv";
 then false; else true; fi
 
 rm guix-gc-root
-guix-gc --list-dead | grep "$drv"
-guix-gc --delete "$drv"
+guix gc --list-dead | grep "$drv"
+guix gc --delete "$drv"
 ! test -f "$drv"
 
 # Try a random collection.
-guix-gc -C 1KiB
+guix gc -C 1KiB
 
 # Check trivial error cases.
-if guix-gc --delete /dev/null;
+if guix gc --delete /dev/null;
 then false; else true; fi
diff --git a/tests/guix-package.sh b/tests/guix-package.sh
index 617318b796..cf8bc5c7e8 100644
--- a/tests/guix-package.sh
+++ b/tests/guix-package.sh
@@ -18,10 +18,10 @@
 # along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
 
 #
-# Test the `guix-package' command-line utility.
+# Test the `guix package' command-line utility.
 #
 
-guix-package --version
+guix package --version
 
 readlink_base ()
 {
@@ -33,12 +33,12 @@ rm -f "$profile"
 
 trap 'rm "$profile" "$profile-"[0-9]* ; rm -rf t-home-'"$$" EXIT
 
-guix-package --bootstrap -p "$profile" -i guile-bootstrap
+guix package --bootstrap -p "$profile" -i guile-bootstrap
 test -L "$profile" && test -L "$profile-1-link"
 test -f "$profile/bin/guile"
 
 # Installing the same package a second time does nothing.
-guix-package --bootstrap -p "$profile" -i guile-bootstrap
+guix package --bootstrap -p "$profile" -i guile-bootstrap
 test -L "$profile" && test -L "$profile-1-link"
 ! test -f "$profile-2-link"
 test -f "$profile/bin/guile"
@@ -46,8 +46,8 @@ test -f "$profile/bin/guile"
 # Check whether we have network access.
 if guile -c '(getaddrinfo "www.gnu.org" "80" AI_NUMERICSERV)' 2> /dev/null
 then
-    boot_make="`guix-build -e '(@@ (gnu packages base) gnu-make-boot0)'`"
-    guix-package --bootstrap -p "$profile" -i "$boot_make"
+    boot_make="`guix build -e '(@@ (gnu packages base) gnu-make-boot0)'`"
+    guix package --bootstrap -p "$profile" -i "$boot_make"
     test -L "$profile-2-link"
     test -f "$profile/bin/make" && test -f "$profile/bin/guile"
 
@@ -55,7 +55,7 @@ then
     # Check whether `--list-installed' works.
     # XXX: Change the tests when `--install' properly extracts the package
     # name and version string.
-    installed="`guix-package -p "$profile" --list-installed | cut -f1 | xargs echo | sort`"
+    installed="`guix package -p "$profile" --list-installed | cut -f1 | xargs echo | sort`"
     case "x$installed" in
 	"guile-bootstrap make-boot0")
 	    true;;
@@ -65,68 +65,68 @@ then
             false;;
     esac
 
-    test "`guix-package -p "$profile" -I 'g.*e' | cut -f1`" = "guile-bootstrap"
+    test "`guix package -p "$profile" -I 'g.*e' | cut -f1`" = "guile-bootstrap"
 
     # Search.
-    test "`guix-package -s "GNU Hello" | grep ^name:`" = "name: hello"
-    test "`guix-package -s "n0t4r341p4ck4g3"`" = ""
+    test "`guix package -s "GNU Hello" | grep ^name:`" = "name: hello"
+    test "`guix package -s "n0t4r341p4ck4g3"`" = ""
 
     # Remove a package.
-    guix-package --bootstrap -p "$profile" -r "guile-bootstrap"
+    guix package --bootstrap -p "$profile" -r "guile-bootstrap"
     test -L "$profile-3-link"
     test -f "$profile/bin/make" && ! test -f "$profile/bin/guile"
 
     # Roll back.
-    guix-package --roll-back -p "$profile"
+    guix package --roll-back -p "$profile"
     test "`readlink_base "$profile"`" = "$profile-2-link"
     test -x "$profile/bin/guile" && test -x "$profile/bin/make"
-    guix-package --roll-back -p "$profile"
+    guix package --roll-back -p "$profile"
     test "`readlink_base "$profile"`" = "$profile-1-link"
     test -x "$profile/bin/guile" && ! test -x "$profile/bin/make"
 
     # Move to the empty profile.
     for i in `seq 1 3`
     do
-	guix-package --bootstrap --roll-back -p "$profile"
+	guix package --bootstrap --roll-back -p "$profile"
 	! test -f "$profile/bin"
 	! test -f "$profile/lib"
 	test "`readlink_base "$profile"`" = "$profile-0-link"
     done
 
     # Reinstall after roll-back to the empty profile.
-    guix-package --bootstrap -p "$profile" -i "$boot_make"
+    guix package --bootstrap -p "$profile" -i "$boot_make"
     test "`readlink_base "$profile"`" = "$profile-1-link"
     test -x "$profile/bin/guile" && ! test -x "$profile/bin/make"
 
     # Roll-back to generation 0, and install---all at once.
-    guix-package --bootstrap -p "$profile" --roll-back -i guile-bootstrap
+    guix package --bootstrap -p "$profile" --roll-back -i guile-bootstrap
     test "`readlink_base "$profile"`" = "$profile-1-link"
     test -x "$profile/bin/guile" && ! test -x "$profile/bin/make"
 
     # Install Make.
-    guix-package --bootstrap -p "$profile" -i "$boot_make"
+    guix package --bootstrap -p "$profile" -i "$boot_make"
     test "`readlink_base "$profile"`" = "$profile-2-link"
     test -x "$profile/bin/guile" && test -x "$profile/bin/make"
 
     # Make a "hole" in the list of generations, and make sure we can
     # roll back "over" it.
     rm "$profile-1-link"
-    guix-package --bootstrap -p "$profile" --roll-back
+    guix package --bootstrap -p "$profile" --roll-back
     test "`readlink_base "$profile"`" = "$profile-0-link"
 fi
 
 # Make sure the `:' syntax works.
-guix-package --bootstrap -i "binutils:lib" -p "$profile" -n
+guix package --bootstrap -i "binutils:lib" -p "$profile" -n
 
 # Make sure nonexistent outputs are reported.
-guix-package --bootstrap -i "guile-bootstrap:out" -p "$profile" -n
-if guix-package --bootstrap -i "guile-bootstrap:does-not-exist" -p "$profile" -n;
+guix package --bootstrap -i "guile-bootstrap:out" -p "$profile" -n
+if guix package --bootstrap -i "guile-bootstrap:does-not-exist" -p "$profile" -n;
 then false; else true; fi
-if guix-package --bootstrap -i "guile-bootstrap:does-not-exist" -p "$profile";
+if guix package --bootstrap -i "guile-bootstrap:does-not-exist" -p "$profile";
 then false; else true; fi
 
 # Check whether `--list-available' returns something sensible.
-guix-package -A 'gui.*e' | grep guile
+guix package -A 'gui.*e' | grep guile
 
 #
 # Try with the default profile.
@@ -139,17 +139,17 @@ export HOME
 
 mkdir -p "$HOME"
 
-guix-package --bootstrap -i guile-bootstrap
+guix package --bootstrap -i guile-bootstrap
 test -L "$HOME/.guix-profile"
 test -f "$HOME/.guix-profile/bin/guile"
 
 if guile -c '(getaddrinfo "www.gnu.org" "80" AI_NUMERICSERV)' 2> /dev/null
 then
-    guix-package --bootstrap -i "$boot_make"
+    guix package --bootstrap -i "$boot_make"
     test -f "$HOME/.guix-profile/bin/make"
     first_environment="`cd $HOME/.guix-profile ; pwd`"
 
-    guix-package --bootstrap --roll-back
+    guix package --bootstrap --roll-back
     test -f "$HOME/.guix-profile/bin/guile"
     ! test -f "$HOME/.guix-profile/bin/make"
     test "`cd $HOME/.guix-profile ; pwd`" = "$first_environment"
@@ -159,12 +159,12 @@ fi
 default_profile="`readlink "$HOME/.guix-profile"`"
 for i in `seq 1 3`
 do
-    guix-package --bootstrap --roll-back
+    guix package --bootstrap --roll-back
     ! test -f "$HOME/.guix-profile/bin"
     ! test -f "$HOME/.guix-profile/lib"
     test "`readlink "$default_profile"`" = "$default_profile-0-link"
 done
 
 # Extraneous argument.
-if guix-package install foo-bar;
+if guix package install foo-bar;
 then false; else true; fi