Commit 01f9b50b authored by Michael Hanus 's avatar Michael Hanus

Command installbin added, testsuite specification generalized to more than one directory

parent 3b105260
......@@ -203,6 +203,7 @@ and installs the executable in the \code{bin} install directory of CPM
\subsection{Checking out Packages}
\label{sec:checkout}
In order to use, experiment with or modify an existing package,
one can use the command
......@@ -221,7 +222,7 @@ $\ldots$ Package 'makefile-1.3.4' checked out into directory 'makefile'.
> cd makefile
> cpm install
$\ldots$
INFO Installing executable `curry-genmake' into `/home/joe/.cpm/bin'
INFO Installing executable 'curry-genmake' into '/home/joe/.cpm/bin'
\end{lstlisting}
%
Now, the tool \code{curry-genmake} is ready to use
......@@ -230,15 +231,48 @@ if \code{\$HOME/.cpm/bin} is in your path
of this default path).
\subsection{Executing the Compiler}
\subsection{Installing Binaries of Packages}
\label{sec:installbin}
Some packages do not contain only useful libraries
but also tools. In order to install such tools without
explicitly using the source code of the package,
one can use the command
\begin{lstlisting}
cpm installbin <package>
\end{lstlisting}
This command checks out the package in some internal directory
(default: \code{\$HOME/.cpm/bin_packages}, see
Section~\ref{sec:config})
and installs the binary of the tool provided by the package
in \code{\$HOME/.cpm/bin} (see also Section~\ref{sec:checkout}).
For instance, the most recent version of the web framework Spicey
can be installed by the following command:
%
\begin{lstlisting}
> cpm installbin spicey
$\ldots$ Package 'spicey-xxx' checked out $\ldots$
$\ldots$
INFO Installing executable 'spiceup' into '/home/joe/.cpm/bin'
\end{lstlisting}
%
Now, the binary \code{spiceup} of Spicey can be used
if \code{\$HOME/.cpm/bin} is in your path
(see Section~\ref{sec:config} for details about changing the location
of this default path).
To use the dependencies of a package, the Curry compiler needs to be started via
CPM, so that the compiler will know where to search for modules. You can use the
\code{cpm curry} command to start the current Curry compiler (the \code{curry}
command that is on the path). Any parameters given to \code{cpm curry} will
be passed along verbatim to the Curry compiler, for example the following will
start the Curry compiler, print the result of evaluating the expression
\code{39+3} and then quit.
\subsection{Executing the Curry Compiler}
To use the dependencies of a package, the Curry compiler needs to be
started via CPM so that the compiler will know where to search for the
modules provided. You can use the \code{cpm curry} command to start the current
Curry compiler (the \code{curry} command that is on the path). Any
parameters given to \code{cpm curry} will be passed along verbatim to
the Curry compiler, for example the following will start the Curry
compiler, print the result of evaluating the expression \code{39+3}
and then quit.
\begin{lstlisting}
> cpm curry :eval "39+3" :quit
......@@ -453,9 +487,12 @@ CPM can be configured via the \code{\$HOME/.cpmrc} configuration file. The
following list shows all configuration options and their default values.
\begin{description}
\item[\fbox{\code{repository_path}}] The path to the index repository.
Default value: \code{\$HOME/.cpm/index}.
\item[\fbox{\code{package_install_path}}] The path to the global package cache.
This is where all downloaded packages are stored. Default value:
\code{\$HOME/.cpm/packages}
This is where all downloaded packages are stored.
Default value: \code{\$HOME/.cpm/packages}
\item[\fbox{\code{bin_install_path}}] The path to the executables
of packages. This is the location where the compiled executables
......@@ -464,9 +501,21 @@ Hence, in order to use such applications, one should have this path
in the personal load path (environment variable \code{PATH}).
Default value: \code{\$HOME/.cpm/bin}
\item[\fbox{\code{repository_path}}] The path to the index repository. Default
value: \code{\$HOME/.cpm/index}.
\item[\fbox{\code{bin_package_path}}]
The path to the package cache where packages are checked out if only
their binaries are installed (see Section~\ref{sec:installbin}).
Default value: \code{\$HOME/.cpm/bin_packages}.
\end{description}
%
Note that one can override the values of these configuration options
by the CPM options \code{-d} or \code{--define}.
For instance, to install the binary
of the package \code{spicey} in the directory \code{\$HOME/bin},
one can execute the command
\begin{lstlisting}
> cpm --define bin_install_path=$\$$HOME/bin installbin spicey
\end{lstlisting}
\section{Some CPM Internals}
\label{sec:internals}
......@@ -499,9 +548,12 @@ caches.
\label{sec:cmd-reference}
This section gives a short description of all available CPM commands. In
addition to the commands listed here, there is a global \code{--$verbosity$}
parameter which defaults to \emph{info} but can be increased to \emph{debug} for
addition to the commands listed here, there is a global parameter
\code{--verbosity}
which defaults to \code{info} but can be increased to \code{debug} for
more output.
Furthermore, there is a global parameter \code{--define} to override
the configuration options of CPM, see Section~\ref{sec:config}.
\begin{description}
\item[\fbox{\code{info}}] Gives information on the current package, e.g. the
......@@ -551,7 +603,7 @@ of a package from the global package cache.
\item[\fbox{\code{checkout $package$ [--$pre$]}}]
Checks out the newest version of a package
into the local directory \code{$package$}
in order to test its operations or install a binary of the package..
in order to test its operations or install a binary of the package.
\code{--$pre$} enables the installation of pre-release versions.
\item[\fbox{\code{checkout $package$ $version$}}]
......@@ -559,6 +611,19 @@ Checks out a specific version of a package
into the local directory \code{$package$}
in order to test its operations or install a binary of the package..
\item[\fbox{\code{installbin $package$ [--$pre$]}}]
Install the binary provided by the newest version of a package.
The binary is installed into the directory \code{\$HOME/.cpm/bin}
(this location can be changed via the \code{\$HOME/.cpmrc} configuration file
or by the CPM option \code{--define}, see Section~\ref{sec:config}).
\code{--$pre$} enables the installation of pre-release versions.
\item[\fbox{\code{installbin $package$ $version$}}]
Install the binary provided by a specific version of a package.
The binary is installed into the directory \code{\$HOME/.cpm/bin}
(this location can be changed via the \code{\$HOME/.cpmrc} configuration file
or by the CPM option \code{--define}, see Section~\ref{sec:config}).
\item[\fbox{\code{upgrade}}]
Upgrades all dependencies of the current package to
the newest compatible version.
......@@ -755,11 +820,8 @@ and installs the executable in the \code{bin} install directory of CPM
\item[\fbox{\code{testsuite}}]
A JSON object specifying a test suite for this package.
This object can contain a list of directories (with key \code{src-dirs})
which are added in front of the \code{CURRYPATH} environment variable
before executing the tests.
This might be useful if there are test modules in a directory
different from the default directory \code{src}.
This object contains a directory (with key \code{src-dir})
in which the tests are executed.
Furthermore, the test suite must also define a list of
modules to be tested (with key \code{modules}).
For instance, a possible test suite specification could be as follows:
......@@ -768,16 +830,36 @@ For instance, a possible test suite specification could be as follows:
{
...,
"testsuite": {
"src-dirs": [ "test" ],
"modules" : [ "testDataConversion", "testIO" ]
"src-dir": "test",
"modules": [ "testDataConversion", "testIO" ]
}
}
\end{lstlisting}
%
Note that all these modules are tested with CurryCheck
All these modules are tested with CurryCheck
by the command \code{cpm test}.
If no test suite is defined, all (exported) modules in the source
directory are tested.
If no test suite is defined, all (exported) modules are tested
in the directory \code{src}.
One can also specify test suites for more than one directory.
In this case, the \code{testsuite} value is an array
of JSON objects as described above.
For instance, a test suite specification for tests in the
directories \code{test} and \code{examples} could be as follows:
%
\begin{lstlisting}
{
...,
"testsuite": [
{ "src-dir": "test",
"modules": [ "testDataConversion", "testIO" ]
},
{ "src-dir": "examples",
"modules": [ "Nats", "Ints" ]
}
]
}
\end{lstlisting}
\end{description}
......
......@@ -17,7 +17,6 @@ import Distribution (FrontendTarget (..), FrontendParams (..), defaultParams
, curryCompiler, installDir, inCurrySubdir, modNameToPath
, inCurrySubdirModule, lookupModuleSource)
import List (intercalate, nub)
import Directory (doesFileExist)
import FilePath ((</>), (<.>), takeFileName, replaceExtension)
import AbstractCurry.Files (readAbstractCurryFile, writeAbstractCurryFile)
import AbstractCurry.Pretty (showCProg)
......
......@@ -6,11 +6,11 @@
module CPM.Config
( Config ( Config, packageInstallDir, binInstallDir, repositoryDir
, packageIndexRepository )
, binPackageDir, packageIndexRepository )
, readConfiguration, readConfigurationWithDefault, defaultConfig ) where
import Char (isSpace)
import Directory (doesFileExist, getHomeDirectory, createDirectoryIfMissing)
import Directory (getHomeDirectory, createDirectoryIfMissing)
import FilePath ((</>))
import Function ((***))
import List (splitOn, intersperse)
......@@ -18,6 +18,7 @@ import Maybe (mapMaybe)
import PropertyFile (readPropertyFile)
import CPM.ErrorLogger
import CPM.FileUtil (ifFileExists)
--- The location of the central package index.
packageIndexURI :: String
......@@ -34,6 +35,8 @@ data Config = Config {
, binInstallDir :: String
--- Directory where the package repository is stored
, repositoryDir :: String
--- Directory where the packages with binary installation only are stored
, binPackageDir :: String
--- URL to the package index repository
, packageIndexRepository :: String
}
......@@ -45,6 +48,7 @@ defaultConfig = Config
{ packageInstallDir = "$HOME/.cpm/packages"
, binInstallDir = "$HOME/.cpm/bin"
, repositoryDir = "$HOME/.cpm/index"
, binPackageDir = "$HOME/.cpm/bin_packages"
, packageIndexRepository = packageIndexURI }
--- Reads the .cpmrc file from the user's home directory (if present) and merges
......@@ -62,10 +66,10 @@ readConfigurationWithDefault :: [(String,String)] -> IO (Either String Config)
readConfigurationWithDefault defsettings = do
home <- getHomeDirectory
configFile <- return $ home </> ".cpmrc"
exists <- doesFileExist configFile
settingsFromFile <- if exists
then readPropertyFile configFile >>= \p -> return $ stripProps p
else return []
settingsFromFile <-
ifFileExists configFile
(readPropertyFile configFile >>= \p -> return $ stripProps p)
(return [])
let mergedSettings = mergeConfigSettings defaultConfig
(settingsFromFile ++ stripProps defsettings)
case mergedSettings of
......@@ -80,6 +84,7 @@ replaceHome cfg = do
packageInstallDir = replaceHome' homeDir (packageInstallDir cfg)
, binInstallDir = replaceHome' homeDir (binInstallDir cfg)
, repositoryDir = replaceHome' homeDir (repositoryDir cfg)
, binPackageDir = replaceHome' homeDir (binPackageDir cfg)
}
where
replaceHome' h s = concat $ intersperse h $ splitOn "$HOME" s
......@@ -89,6 +94,7 @@ createDirectories cfg = do
createDirectoryIfMissing True (packageInstallDir cfg)
createDirectoryIfMissing True (binInstallDir cfg)
createDirectoryIfMissing True (repositoryDir cfg)
createDirectoryIfMissing True (binPackageDir cfg)
--- Merges configuration options from a configuration file or argument options
--- into a configuration record. May return an error using Left.
......@@ -120,6 +126,7 @@ keySetters =
[ ("repository_path" , \v c -> c { repositoryDir = v })
, ("package_install_path", \v c -> c { packageInstallDir = v})
, ("bin_install_path" , \v c -> c { binInstallDir = v})
, ("bin_package_path" , \v c -> c { binPackageDir = v})
]
--- Sequentially applies a list of functions that transform a value to a value
......
......@@ -18,7 +18,7 @@ module CPM.ErrorLogger
, failIO
, log
, showLogEntry
, debugMessage
, infoMessage, debugMessage
) where
import Global
......@@ -177,6 +177,10 @@ log lvl msg =
where
showTime t = show (t `div` 1000) ++ "." ++ show ((t `mod` 1000) `div` 10)
--- Prints an info message in the standard IO monad.
infoMessage :: String -> IO ()
infoMessage msg = (log Info msg |> succeedIO ()) >> done
--- Prints a debug message in the standard IO monad.
debugMessage :: String -> IO ()
debugMessage msg = (log Debug msg |> succeedIO ()) >> done
......@@ -18,6 +18,7 @@ module CPM.FileUtil
, recreateDirectory
, removeDirectoryComplete
, safeReadFile, checkAndGetDirectoryContents
, whenFileExists, ifFileExists
) where
import Directory ( doesFileExist, doesDirectoryExist, getCurrentDirectory
......@@ -137,3 +138,15 @@ checkAndGetDirectoryContents dir = do
if exdir then getDirectoryContents dir
else do putStrLn $ "ERROR: Directory '" ++ dir ++ "' does not exist!"
exitWith 1
--- Performs an action when a file exists.
whenFileExists :: FilePath -> IO () -> IO ()
whenFileExists fname act = do
exfile <- doesFileExist fname
when exfile act
--- Performs one of two actions depending on the existence of a file.
ifFileExists :: FilePath -> IO a -> IO a -> IO a
ifFileExists fname thenact elseact = do
exfile <- doesFileExist fname
if exfile then thenact else elseact
This diff is collapsed.
This diff is collapsed.
......@@ -20,7 +20,7 @@ import CPM.Config (Config, binInstallDir)
import CPM.ErrorLogger
import CPM.PackageCache.Global (installedPackageDir)
import CPM.Package ( Package, packageId, PackageExecutable(..)
, configModule, executableSpec )
, configModule, executableSpec, version, showVersion )
import CPM.FileUtil ( copyDirectoryFollowingSymlinks, recreateDirectory )
import CPM.PackageCache.Local as LocalCache
......@@ -89,6 +89,10 @@ writePackageConfig cfg pkgdir pkg =
writeFile configfile $ unlines $
[ "module " ++ configmod ++ " where"
, ""
, "--- Package version as a string."
, "packageVersion :: String"
, "packageVersion = \"" ++ showVersion (version pkg) ++ "\""
, ""
, "--- Package location."
, "packagePath :: String"
, "packagePath = \"" ++ abspkgdir ++ "\""
......
......@@ -202,8 +202,8 @@ renderPackageInfo allinfos _ gc pkg = pPrint doc
doc = vcat $ [ heading, rule, installed, ver, auth, maintnr, synop
, cats, deps, compilers, descr ] ++
if allinfos
then [ expmods, cfgmod, execspec, testsuite, src, licns
, copyrt, homepg, reposy, bugrep]
then [ expmods, cfgmod, execspec] ++ testsuites ++
[ src, licns, copyrt, homepg, reposy, bugrep]
else []
pkgId = packageId pkg
......@@ -236,17 +236,15 @@ renderPackageInfo allinfos _ gc pkg = pPrint doc
indent 4 (bold (text "Name ") <+> text n) <$$>
indent 4 (bold (text "Main module ") <+> text m)
testsuite = case testSuite pkg of
Nothing -> empty
Just (PackageTests dirs mods) ->
(if null dirs
then empty
else fill maxLen (bold (text "Test dirs")) <$$>
indent 4 (fillSep (map text dirs))) <$$>
(if null mods
then empty
else fill maxLen (bold (text "Test modules"))<$$>
indent 4 (fillSep (map text mods)))
testsuites = case testSuite pkg of
Nothing -> []
Just (PackageTests tests) ->
map (\ (dir,mods) ->
bold (text "Test suite") <$$>
indent 4 (bold (text "Directory ") <+> text dir) <$$>
indent 4 (bold (text "Test modules ") <+>
align (fillSep (map text mods))))
tests
descr = showParaField description "Description"
licns = showParaField license "License"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment