diff --git a/doc/latex/proposal.tex b/doc/latex/proposal.tex index 8009ad9..40e52d7 100644 --- a/doc/latex/proposal.tex +++ b/doc/latex/proposal.tex @@ -1,10 +1,11 @@ -%% $Id: proposal.tex,v 1.1 2004/02/11 19:42:30 michel-schinz Exp $ +%% $Id: proposal.tex,v 1.2 2004/02/29 20:00:47 michel-schinz Exp $ %% TODO %% - clean up permissions mess \documentclass[a4paper,12pt]{article} +\usepackage[latin1]{inputenc} \usepackage{a4wide, palatino, url, hyperref} \newcommand{\file}{\begingroup \urlstyle{tt}\Url} @@ -14,9 +15,9 @@ \newcommand{\package}[1]{\texttt{#1}} \newcommand{\layout}[1]{\texttt{#1}} \newcommand{\location}[1]{\texttt{#1}} +\newcommand{\ident}[1]{\texttt{#1}} \newcommand{\define}[3]{% - \vspace{1em}% \noindent% (\texttt{#1} \textit{#2})\hfill\textit{(#3)}\\[0.5em]% } @@ -75,8 +76,8 @@ simplicity, but it is important to keep in mind that versions are sequences of integers, not strings. A specific version of a package is therefore identified by a name and -a version. The full name of a version of a package is obtained by -concatenating: +a version. The \emph{full name} of a version of a package is obtained +by concatenating: \begin{itemize} \item the name of the package, \item a hyphen `\texttt{-}', @@ -87,12 +88,11 @@ In what follows, the term \emph{package} is often used to designate a specific version of a package, but this should be clear from the context. -\section{Distribution of packages} +\section{Distributing packages} Packages are distributed in \texttt{tar} archives, which can -optionally be compressed by \texttt{gzip} or \texttt{bzip2}. - -The name of the archive is composed by appending: +optionally be compressed by \texttt{gzip} or \texttt{bzip2}. The name +of the archive is composed by appending: \begin{itemize} \item the full name of the package, \item the string \texttt{.tar} indicating that it's a \texttt{tar} @@ -120,7 +120,7 @@ The unpacking directory contains at least the following files: package. \end{description} -\section{Downloading and installation of packages} +\section{Downloading and installing packages} A package can be installed on a target machine by downloading its archive, expanding it and finally running the installation script @@ -129,7 +129,7 @@ located in the unpacking directory. \subsection{Layouts} The installation script installs files according to some given -\emph{layout}. A layout maps abstract locations to concrete +\emph{layout}. A layout maps abstract \emph{locations} to concrete directories on the target machine. For example, a layout could map the abstract location \location{doc}, where documentation is stored, to the directory \file{/usr/local/share/doc/my_package}. @@ -138,26 +138,26 @@ Currently, the following abstract locations are defined: \begin{description} \item[\location{base}] The ``base'' location of a package, where the package loading script \file{load.scm} resides. - + \item[\location{active}] Location containing a symbolic link, with the same name as the package (excluding the version), pointing to the base location of the package. This link is used to designate the \emph{active} version of a package\,---\,the one to load when a package is requested by giving only its name, without an explicit version. - + \item[\location{scheme}] Location containing all Scheme code. If the package comes with some examples showing its usage, they are put in a sub-directory called \file{examples} of this location. - + \item[\location{lib}] Location containing platform-dependent files, like shared libraries. This location contains one sub-directory per platform for which packages have been installed, and nothing else. - + \item[\location{doc}] Location containing all the package - documentation. This location contains one or more sub-directories - which store the documentation in various formats. The contents of - these sub-directories is standardised as follows, to make it easy + documentation. This location contains one or more sub-directories, + one per format in which the documentation is available. The contents + of these sub-directories is standardised as follows, to make it easy for users to find the document they need: \begin{description} \item[\file{html}] Directory containing the HTML documentation of @@ -166,16 +166,16 @@ Currently, the following abstract locations are defined: documentation. \item[\file{pdf}] Directory containing the PDF documentation of the package, if any; this directory should contain at least one file - called \file{.pdf} where \file{} is the name of - the package. + called \file{.pdf} where \file{} is + the name of the package. \item[\file{ps}] Directory containing the PostScript documentation of the package, if any; this directory should contain at least one - file called \file{.ps} where \file{} is the name - of the package. + file called \file{.ps} where \file{} + is the name of the package. \item[\file{text}] Directory containing the raw textual documentation of the package, if any. \end{description} - + \item[\location{misc-shared}] Location containing miscellaneous data which does not belong to any directory above, and which is platform-independant. @@ -193,11 +193,11 @@ to a \emph{prefix}, specified at installation time using the \file{COPYING} which has to be installed in sub-directory \file{license} of the \location{doc} location. If the user chooses to use the default layout, which maps \location{doc} to directory - \file{/doc} (see below), and specifies - \file{/usr/local/etc/scsh/modules} as a prefix, then the + \file{/doc} (see §~\ref{sec:scsh-layout}), and + specifies \file{/usr/local/share/scsh/modules} as a prefix, then the \file{COPYING} file will end up in: \[ -\underbrace{\mathtt{/usr/local/etc/scsh/modules/}}_{1}% +\underbrace{\mathtt{/usr/local/share/scsh/modules/}}_{1}% \underbrace{\mathtt{foo-1.2/doc/}}_{2}% \underbrace{\mathtt{license/COPYING}}_{3} \] @@ -213,16 +213,17 @@ Every installation script comes with a set of predefined layouts which serve different aims. They are described below. \paragraph{The \layout{scsh} layout} +\label{sec:scsh-layout} The \layout{scsh} layout is the default layout. It maps all locations to sub-directories of a single directory, called the package -installation directory, which contains all the files of the package -being installed and nothing else. Its name is simply the full name of -the package in question, and it resides in the \file{prefix} -directory. +installation directory, which contains nothing but the files of the +package being installed. Its name is simply the full name of the +package in question, and it resides in the \file{prefix} directory. The \layout{scsh} layout maps locations as given in the following -table: +table, where \file{} stands for the full name of +the package: \begin{center} \begin{tabular}{|l|l|} \hline @@ -244,6 +245,7 @@ common operations easy. For example, finding to which package a file belongs is trivial, as is the removal of an installed package. \paragraph{The \layout{fhs} layout} +\label{sec:fhs-layout} The \layout{fhs} layout maps locations according to the File Hierarchy Standard (FHS, see \href{http://www.pathname.com/fhs/}% @@ -285,14 +287,45 @@ using the \cloption{--prefix} option. It also accepts the following options: \begin{center} \begin{tabular}{lp{.6\textwidth}} - \cloption{--layout} name & Specifies the layout to use (see \ref{sec:predefined-layouts}) \\ - \cloption{--verbose} & Print messages about what is being done. \\ - \cloption{--dry-run} & Print what actions would be performed to install the package, but do not perform them. \\ - \cloption{--inactive} & Do not activate package after installing it. \\ - \cloption{--non-shared-only} & Only install platform-dependent files, if any. \\ - \cloption{--force} & Overwrite existing files during installation. \\ + \cloption{--layout} name & Specifies the layout to use (see §~\ref{sec:predefined-layouts}). \\ + \cloption{--verbose} & Print messages about what is being done. \\ + \cloption{--dry-run} & Print what actions would be performed to install the package, but do not perform them. \\ + \cloption{--inactive} & Do not activate package after installing it. \\ + \cloption{--non-shared-only} & Only install platform-dependent files, if any. \\ + \cloption{--force} & Overwrite existing files during installation. \\ + \cloption{--no-user-defaults} & Don't read user defaults in \file{.scsh-pkg-defaults} (see §~\ref{sec:user-preferences}). \\ \end{tabular} \end{center} + +\subsubsection{User preferences} +\label{sec:user-preferences} + +Users can store default values for the options passed to the +installation script by storing them in a file called +\file{.scsh-pkg-defaults.scm} residing in their home directory. This +file must contain exactly one Scheme expression whose value is an +association list. The keys of this list, which must be symbols, +identify options and the values specify the default value for these +options. The contents of this file is implicitely quasi-quoted. + +The values stored in this file override the default values of the +options, but they are in turn overriden by the values specified on the +command line of the installation script. Furthermore, it is possible +to ask for this file to be completely ignored by passing the +\cloption{--no-user-defaults} option to the installation script. + +\begin{example} + A \file{.scsh-pkg-defaults} file containing the following: +\begin{verbatim} +;; Default values for scsh packages installation +((layout . "fhs") + (prefix . "/usr/local/share/scsh/modules") + (verbose . #t)) +\end{verbatim} + specifies default values for the \cloption{--layout}, + \cloption{--prefix} and \cloption{--verbose} options. +\end{example} + %% \subsection{Creating images} %% TODO (my current idea is to add support to install-lib to easily @@ -331,25 +364,27 @@ as this forces scsh to search them recursively. This could scsh packages according to the \layout{fhs} layout in prefix directory \file{/usr/local}. The \location{active} location for these packages corresponds to the directory - \file{/usr/local/share/scsh/modules}, according to the layout - specification above. - + \file{/usr/local/share/scsh/modules}, according to section + \ref{sec:fhs-layout}. + Let's also imagine that there is a user called \texttt{john} on this machine, who installs additional scsh packages for himself in his home directory, using \file{/home/john/scsh-packages} as a prefix. To ease their management, he uses the \layout{scsh} layout. The \location{active} location for these packages corresponds to the - directory \file{/home/john/scsh-packages}, according to the layout - specification above. - + directory \file{/home/john/scsh-packages}, according to section + \ref{sec:scsh-layout}. + In order to be able to use scsh packages installed both by the administrator and by himself, user \texttt{john} needs to put both active directories in his \envvar{SCSH\_LIB\_DIRS} environment variable. The value of this variable will therefore be: + \begin{small} \begin{verbatim} "/usr/local/share/scsh/modules" "/home/john/scsh-packages" \end{verbatim} - + \end{small} + Now, in order to use packages \package{foo} and \package{bar} in one of his script, user \texttt{john} just needs to load their loading script using the \cloption{-lel} option when invoking scsh, as @@ -359,7 +394,7 @@ as this forces scsh to search them recursively. This could \end{verbatim} \end{example} -\section{Writing packages} +\section{Authoring packages} Once the Scheme and/or C code for a package has been written, the last step in turning it into a standard package as defined by this proposal @@ -370,13 +405,13 @@ to simplify this task a small scsh installation framework is provided. This framework is composed of several files which are meant to be included in the package archive. These files are: \begin{description} -\item[\file{install-pkg}] a trivial \texttt{sh} script which launches +\item[\file{install-pkg}] A trivial \texttt{sh} script which launches scsh on the main function of the installation library, passing it - all the arguments given by the user, -\item[\file{install-lib.scm}] the code for the installation library, - whose public interface is documented below, + all the arguments given by the user. +\item[\file{install-lib.scm}] The code for the installation library, + whose public interface is documented below. \item[\file{install-lib-module.scm}] Scheme 48 interface and structure - definitions for the installation library, + definitions for the installation library. \end{description} As explained above, when the \file{install-pkg} script is invoked, it @@ -387,44 +422,47 @@ does the following: option), \item load the package definition file, a (Scheme) file called \file{pkg-def.scm}, which is supplied by the package author and - which contains the installation procedure for the package, -\item install the package which was defined in the previous step. + which contains one or several package definition statements, and +\item install the packages which were defined in the previous step. \end{enumerate} -It is actually possible to define several packages in -\file{pkg-def.scm}, and all will be installed. It should not be often -useful, though. +Most package definition files should contain a single package +definition, but the ability to define several packages in one file can +sometimes be useful. The main job of the package author is therefore to write the package -definition file, \file{pkg-def.scm}. - -This file is mostly composed of a package definition statement, which -specifies the name, version and installation code for the package. The -package definition statement is expressed using the -\texttt{define-package} form, defined below. +definition file, \file{pkg-def.scm}. This file is mostly composed of a +package definition statement, which specifies the name, version and +installation code for the package. The package definition statement is +expressed using the \ident{define-package} form, documented in the +next section. \subsection{Installation library} \label{sec:install-library} + +\subsubsection{Package definition} + \defines{define-package}{name version extension body ...}% -Define a package to be installed. \param{Name}, a string, is the -package name, \param{version} its version (a list of integers), -\param{extensions} is an association list of extensions (see below), -and \param{body} is the list of statements to be evaluated in order to +Define a package to be installed. \param{Name} (a string) is the +package name, \param{version} (a list of integers) is its version, +\param{extensions} is a list of extensions (see below), and +\param{body} is the list of statements to be evaluated in order to install the package. The installation statements typically use functions of the installation library in order to install files in their target -location. The functions currently exported are presented in the -remainder of this section. +location. The available functions are presented below. \param{Extensions} is currently used only to specify additional command-line arguments, but in the future it could serve other -purposes. It consists in a list of pairs, each one composed of a -symbol identifying the extension, and extension-specific parameters. +purposes. It consists in a list of lists, each one starting with a +symbol identifying the extension, followed by extension-specific +parameters. + \begin{description} \item[options] enables the script to define additional command-line options. It accepts nine parameters in total, with the last three - being optional. These parameters are described below, in the order - in which they should appear: + being optional. The description of these parameters follows, in the + order in which they should appear: \begin{description} \item[\param{name}] (a symbol) is the name of the option, without the initial double hyphen (\verb|--|), @@ -436,14 +474,15 @@ symbol identifying the extension, and extension-specific parameters. requires an argument or not, \item[\param{optional-arg?}] (a boolean) says whether this option's argument can be omitted or not, - \item[\param{default}] is the default value for the option, + \item[\param{default}] (anything) is the default value for the + option, \item[\param{parser}] (a function from string to anything) parses the option, i.e. turns its string representation into its internal value, \item[\param{unparser}] (a function from anything to string) turns the internal representation of the option into a string, \item[\param{transformer}] is a function taking the current value of - the option, the value submitted by the user and returning its new + the option, the value given by the user and returning its new value. \end{description} By default, \param{parser} and \param{unparser} are the identity @@ -452,6 +491,8 @@ symbol identifying the extension, and extension-specific parameters. option is simply replaced by the one given). \end{description} +\subsubsection{Content installation} + \definep{install-file}{file location [target-dir]}% Install the given \param{file} in the sub-directory \param{target-dir} (which must be a relative directory) of the given \param{location}. @@ -465,11 +506,13 @@ specifies the name of the source file, and its second element the name it will have once installed. The second element must be a simple file name, without any directory part. -\definep{install-file}{file-list location [target-dir]}% -Like install-file but for several files, which are specified as a -list. Each element in the list can be either a simple string or a +\vspace{1em} +\definep{install-files}{file-list location [target-dir]}% +Like \ident{install-file} but for several files, which are specified +as a list. Each element in the list can be either a simple string or a pair, as explained above. +\vspace{1em} \definep{install-directory}{directory location [target-dir]}% Install the given \param{directory} and all its contents, including sub-directories, in sub-directory \param{target-dir} of @@ -479,17 +522,22 @@ but for complete hierarchies. Notice that \param{directory} will be installed as a sub-directory of \param{target-dir}. +\vspace{1em} \definep{install-directories}{dir-list location [target-dir]}% Install several directories in one go. +\vspace{1em} \definep{install-directory-contents}{directory location [target-dir]}% -Install the \emph{contents} of the given \param{directory} in -sub-directory \param{target} of \param{location}. +Install the contents of the given \param{directory} in sub-directory +\param{target} of \param{location}. +\vspace{1em} \definep{install-string}{string location [target-dir]}% Install the contents of \param{string} in sub-directory \param{target-dir} of \param{location}. +\subsubsection{Queries} + \definep{get-directory}{location install?}% Get the absolute name of the directory to which the current layout maps the abstract \param{location}. If \param{install?} is true, the @@ -501,29 +549,34 @@ The distinction between installation-time and usage-time directories is necessary to support staged installation, as performed by package managers like Debian's APT. +\vspace{1em} \definep{get-option-value}{option}% Return the value of the given command-line \param{option} (a symbol). This can be used to get the value of predefined options (like \cloption{--dry-run}) or package-specific options. +\subsubsection{Load script generation} + \definep{with-output-to-load-script*}{thunk}% Evaluate \param{thunk} with the current output opened on the loading script of the current package. If this script was already existing, -its previous contents will be deleted. +its previous contents is deleted. +\vspace{1em} \defines{with-output-to-load-script}{body ...}% -Syntactic sugar for \param{with-output-to-load-script*}. +Syntactic sugar for \ident{with-output-to-load-script*}. +\vspace{1em} \definep{write-to-load-script}{s-expression}% Pretty-print the \param{s-expression} to the loading script of the current package. If this script was already existing, its previous -contents will be deleted. +contents is deleted. \begin{example} A typical package definition file for a simple package called - \package{my\_package} whose version is 1.2 could look like this: + \package{pkg} whose version is 1.2 could look like this: \begin{verbatim} -(define-package "my_package" (1 2) () +(define-package "pkg" (1 2) () (install-file "load.scm" 'base) (install-directory-contents "scheme" 'scheme) (install-file ("LICENSE" . "COPYING") 'doc) @@ -531,24 +584,21 @@ contents will be deleted. \end{verbatim} With such a definition, invoking the installation script with - \file{/usr/local/} as prefix and \layout{fhs} as layout would have - the following effects: + \file{/usr/local/} as prefix and \layout{fhs} as layout has the + following effects: \begin{enumerate} -\item The base directory - \file{/usr/local/share/scsh/modules/my_package-1.2} would be created - and file \file{load.scm} would be copied to it. -\item All the contents of the directory called \file{scheme} would be - copied to directory - \file{/usr/local/share/scsh/modules/my_package-1.2/scheme} which - would be created before, if needed. -\item File \file{LICENSE} would be copied to directory - \file{/usr/local/share/doc/my_package-1.2/} with name - \file{COPYING}. -\item All the contents of the directory called \file{doc} would be - copied to directory \file{/usr/local/share/doc/my_package-1.2/} -\item The package would be activated by creating a symbolic link with - name \file{/usr/local/share/scsh/modules/my_package} pointing to - \file{./my_package-1.2} +\item The base directory \file{/usr/local/share/scsh/modules/pkg-1.2} + is created and file \file{load.scm} is copied to it. +\item All the contents of the directory called \file{scheme} is copied + to directory \file{/usr/local/share/scsh/modules/pkg-1.2/scheme} + which is created before, if needed. +\item File \file{LICENSE} is copied to directory + \file{/usr/local/share/doc/pkg-1.2/} with name \file{COPYING}. +\item All the contents of the directory called \file{doc} is copied to + directory \file{/usr/local/share/doc/pkg-1.2/} +\item The package is activated by creating a symbolic link with name + \file{/usr/local/share/scsh/modules/pkg} pointing to + \file{./pkg-1.2} \end{enumerate} \end{example} @@ -561,8 +611,8 @@ Fortunately, the GNU Autoconf system simplifies the management of these problems, and authors of scsh packages containing C code are strongly encouraged to use it. -Integrating Autoconf into the installation procedure should not be a -major problem thanks to scsh's ability to run separate programs. +%% Integrating Autoconf into the installation procedure should not be a +%% major problem thanks to scsh's ability to run separate programs. \section{Packaging packages}