Commit 810bb43f authored by Michael Hanus 's avatar Michael Hanus

Some code refactoring and command "cpm list" added

parent cb5ddc1b
......@@ -12,4 +12,6 @@ DOC_*
doc/*.aux
doc/*.pdf
doc/*.log
doc/*.out
doc/*.synctex.gz
cdoc/
# Curry system binary:
export CURRY = curry
# The default options for the REPL
export REPL_OPTS = --noreadline :set -time
.PHONY: build
build: fetchdeps
@export CURRYPATH=""; \
for i in `ls vendor`; do \
@export CURRYPATH=""; \
for i in `ls vendor`; do \
export CURRYPATH="$$CURRYPATH:`pwd`/vendor/$$i/src"; \
done; \
echo "Set CURRYPATH to $$CURRYPATH"; \
cd src; \
curry :l CPM.Main :save :quit; \
cd ..;
@if [ ! -d bin ]; then \
mkdir bin; \
fi; \
cp src/CPM.Main bin/cpm
done; \
echo "Set CURRYPATH to $$CURRYPATH"; \
cd src; $(CURRY) $(REPL_OPTS) :l CPM.Main :save :quit
@if [ ! -d bin ]; then mkdir bin; fi
cp -p src/CPM.Main bin/cpm
.PHONY: buildperf
buildperf: fetchdeps
@export CURRYPATH=""; \
for i in `ls vendor`; do \
@export CURRYPATH=""; \
for i in `ls vendor`; do \
export CURRYPATH="$$CURRYPATH:`pwd`/vendor/$$i/src"; \
done; \
echo "Set CURRYPATH to $$CURRYPATH"; \
cd src; \
curry :l CPM.PerformanceTest :save :quit; \
cd ..;
done; \
echo "Set CURRYPATH to $$CURRYPATH"; \
cd src && $(CURRY) $(REPL_OPTS) :l CPM.PerformanceTest :save :quit
.PHONY: clean
clean:
......@@ -35,23 +34,20 @@ fetchdeps:
.PHONY: test
test: fetchdeps
@export CURRYPATH=""; \
for i in `ls vendor`; do \
@export CURRYPATH=""; \
for i in `ls vendor`; do \
export CURRYPATH="$$CURRYPATH:`pwd`/vendor/$$i/src"; \
done; \
cd src; \
currycheck CPM.Package CPM.Resolution CPM.LookupSet; \
cd ..
done; \
cd src; $(CURRY) check CPM.Package CPM.Resolution CPM.LookupSet
.PHONY: doc
doc: fetchdeps
@export CURRYPATH=""; \
for i in `ls vendor`; do \
@export CURRYPATH=""; \
for i in `ls vendor`; do \
export CURRYPATH="$$CURRYPATH:`pwd`/vendor/$$i/src"; \
done; \
done; \
export CURRYPATH="$$CURRYPATH:`pwd`/src"; \
currydoc cdoc CPM.Main; \
cd ..
$(CURRY) doc cdoc CPM.Main
.PHONY: cloc
cloc:
......
......@@ -44,15 +44,15 @@
\title{CPM User's Manual}
\author{Jonas Oberschweiber\\[1ex]
\author{Jonas Oberschweiber\footnote{and some extensions by Michael Hanus}\\[1ex]
{\small Institut f\"ur Informatik, CAU Kiel, Germany}
}
\maketitle
\begin{abstract}
This document describes the Curry package manager (CPM), an application for
distributing and installing Curry libraries.
This document describes the Curry package manager (CPM), a tool to
distribute and install Curry libraries.
\end{abstract}
\section{Installing the Curry Package Manager}
......@@ -171,10 +171,13 @@ installed on previous runs of \verb|cpm install|, you can use the
compatible versions, or \verb|cpm upgrade <package>| to update a specific
package and all its transitive dependencies to the newest compatible version.
Note that there is also a \verb|cpm update| command, which will update your copy
of the central package index to the newest version. You can search the central
package index via the \verb|cpm search| command. See Section~\ref{sec:cmd-reference}
for a reference of all commands.
Note that there is also a \verb|cpm update| command, which will update
your copy of the central package index to the newest version. You can
list all packages of the central package index via the
\verb|cpm list| command, or you can
search the central package index via the \verb|cpm search|
command. See Section~\ref{sec:cmd-reference} for a reference of all
commands.
\subsection{Executing the Compiler}
......@@ -402,6 +405,10 @@ version of the given package.
\item[\fbox{\code{info $package$ $version$}}] Gives information on the given
package version.
\item[\fbox{\code{list [--all]}}] List the names and synopses of all
packages in the central package index. The option \verb|--all| shows
also all package versions.
\item[\fbox{\code{search $query$}}] Searches the names and synopses of all
packages in the central package index for a term.
......
......@@ -8,16 +8,23 @@ module CPM.Config
(Config (Config, packageInstallDir, repositoryDir, packageIndexRepository)
, readConfiguration, defaultConfig) where
import Char (isSpace)
import Function ((***))
import Char (isSpace)
import Directory (doesFileExist, getHomeDirectory, createDirectoryIfMissing)
import FilePath ((</>))
import Function ((***))
import List (splitOn, intersperse)
import Maybe (mapMaybe)
import PropertyFile (readPropertyFile)
import Directory (doesFileExist, getHomeDirectory, createDirectoryIfMissing)
import FilePath ((</>))
import Maybe (mapMaybe)
import List (splitOn, intersperse)
import CPM.ErrorLogger
--- The location of the central package index.
packageIndexURI :: String
packageIndexURI = "https://git.ps.informatik.uni-kiel.de/curry/cpm-index.git"
-- if you have an ssh access to git.ps:
-- "ssh://git@git.ps.informatik.uni-kiel.de:55055/curry/cpm-index.git"
--- Data type containing the main configuration of CPM.
data Config = Config {
--- The directory where locally installed packages are stored
packageInstallDir :: String
......@@ -33,7 +40,7 @@ defaultConfig :: Config
defaultConfig = Config
{ packageInstallDir = "$HOME/.cpm/packages"
, repositoryDir = "$HOME/.cpm/index"
, packageIndexRepository = "ssh://git@git.ps.informatik.uni-kiel.de:55055/curry/cpm-index.git" }
, packageIndexRepository = packageIndexURI }
--- Reads the .cpmrc file from the user's home directory (if present) and merges
--- its contents into the default configuration. Resolves the $HOME variable
......@@ -50,7 +57,8 @@ readConfiguration = do
mergedSettings <- return $ mergeConfigFile defaultConfig settingsFromFile
case mergedSettings of
Left e -> return $ Left e
Right s' -> replaceHome s' >>= \s'' -> createDirectories s'' >> return (Right s'')
Right s' -> replaceHome s' >>= \s'' -> createDirectories s'' >>
return (Right s'')
replaceHome :: Config -> IO Config
replaceHome cfg = do
......
......@@ -837,8 +837,8 @@ findAllFunctions :: String -> String -> Package -> [Package] -> ACYCache -> IO (
findAllFunctions dirA dirB pkg deps acyCache = foldEL findForMod (acyCache, []) (exportedModules pkg) |>=
\(a, fs) -> succeedIO (a, nub fs)
where
findForMod (acy, acc) mod = readCached dirA deps acy mod |>=
\(acy', progA) -> readCached dirB deps acy mod |>=
findForMod (acy,_) mod = readCached dirA deps acy mod |>=
\(_, progA) -> readCached dirB deps acy mod |>=
\(acy'', progB) ->
let
funcsA = filter isPublic $ functions progA
......
--------------------------------------------------------------------------------
--- This is the main module of the Curry Package Manager.
--------------------------------------------------------------------------------
module CPM.Main where
import Either
......@@ -17,7 +21,7 @@ import CPM.PackageCache.Global (GlobalCache, readInstalledPackagesFromDir
, installFromZip, uninstallPackage)
import CPM.Package
import CPM.Resolution (showResult)
import CPM.Repository (Repository, readRepository, findVersion
import CPM.Repository (Repository, readRepository, findVersion, listPackages
, findLatestVersion, updateRepository, searchPackages)
import CPM.PackageCache.Runtime (copyPackages, dependencyPaths)
import CPM.PackageCopy
......@@ -71,6 +75,7 @@ runWithArgs opts = do
Diff o -> diff o config repo globalCache
Uninstall o -> uninstall o config repo globalCache
Update -> update config repo globalCache
List o -> listAll o config repo
Search o -> search o config repo
Upgrade o -> upgrade o config repo globalCache
Link o -> link o config repo globalCache
......@@ -90,6 +95,7 @@ data Command
| PkgInfo InfoOptions
| Compiler CompilerOptions
| Update
| List ListOptions
| Search SearchOptions
| Upgrade UpgradeOptions
| Link LinkOptions
......@@ -110,6 +116,9 @@ data InfoOptions = InfoOptions
{ infoPackage :: Maybe String
, infoVersion :: Maybe Version }
data ListOptions = ListOptions
{ listVersions :: Bool }
data SearchOptions = SearchOptions
{ searchQuery :: String }
......@@ -144,7 +153,12 @@ uninstallOpts s = case optCommand s of
infoOpts :: Options -> InfoOptions
infoOpts s = case optCommand s of
PkgInfo opts -> opts
_ -> InfoOptions Nothing Nothing
_ -> InfoOptions Nothing Nothing
listOpts :: Options -> ListOptions
listOpts s = case optCommand s of
List opts -> opts
_ -> ListOptions False
searchOpts :: Options -> SearchOptions
searchOpts s = case optCommand s of
......@@ -233,14 +247,15 @@ optionParser = optParser
<|> command "deps" (help "Calculate dependencies") (\a -> Right $ a { optCommand = Deps }) []
<|> command "new" (help "Create a new package") (\a -> Right $ a { optCommand = New }) []
<|> command "update" (help "Update the package index") (\a -> Right $ a { optCommand = Update }) []
<|> command "curry" (help "Load package spec from current directory and start Curry with correct dependencies.") (\a -> Right $ a { optCommand = Compiler (compOpts a) })
<|> command "curry" (help "Load package spec from current directory and start Curry with correct dependencies.")
(\a -> Right $ a { optCommand = Compiler (compOpts a) })
( rest (\s a -> Right $ a { optCommand = Compiler (compOpts a) { comCommand = s } })
( metavar "ARGS"
<> help "The options to pass to the compiler"
<> optional) )
<|> command "exec" (help "Execute a command with the CURRYPATH set") (\a -> Right $ a { optCommand = Exec (execOpts a) })
( rest (\s a -> Right $ a { optCommand = Exec (execOpts a) { exeCommand = s } })
( metavar "COMMAND"
( metavar "CMD"
<> help "The command to execute. Don't forget the quotes!"
<> optional) )
<|> command "info" (help "Print package information") (\a -> Right $ a { optCommand = PkgInfo (infoOpts a) })
......@@ -269,6 +284,14 @@ optionParser = optParser
( long "behavior-only"
<> short "b"
<> help "Diff only the behavior") )
<|> command "list" (help "List all packages of the repository")
(\a -> Right $ a { optCommand = List (listOpts a) })
( flag (\a -> Right $ a { optCommand = List (listOpts a)
{ listVersions = True } })
( short "a"
<> long "all"
<> help "Show also version numbers."
<> optional ) )
<|> command "search" (help "Search the package repository") Right
( arg (\s a -> Right $ a { optCommand = Search (searchOpts a) { searchQuery = s } })
( metavar "QUERY"
......@@ -307,9 +330,10 @@ deps cfg repo gc = tryFindLocalPackageSpec "." |>=
info :: InfoOptions -> Config -> Repository -> GlobalCache -> IO (ErrorLogger ())
info (InfoOptions Nothing Nothing) _ repo gc = tryFindLocalPackageSpec "." |>=
\specDir -> loadPackageSpec specDir |>= printInfo repo gc
info (InfoOptions (Just pkg) Nothing) _ repo gc = case findLatestVersion repo pkg False of
Nothing -> failIO $ "Package '" ++ pkg ++ "' not found in package repository."
Just p -> printInfo repo gc p
info (InfoOptions (Just pkg) Nothing) _ repo gc =
case findLatestVersion repo pkg False of
Nothing -> failIO $ "Package '" ++ pkg ++ "' not found in package repository."
Just p -> printInfo repo gc p
info (InfoOptions (Just pkg) (Just v)) _ repo gc = case findVersion repo pkg v of
Nothing -> failIO $ "Package '" ++ pkg ++ "-" ++ (showVersion v) ++ "' not found in package repository."
Just p -> printInfo repo gc p
......@@ -350,24 +374,41 @@ uninstall (UninstallOptions pkg ver) cfg repo gc = uninstallPackage cfg repo gc
tryFindVersion :: String -> Version -> Repository -> IO (ErrorLogger Package)
tryFindVersion pkg ver repo = case findVersion repo pkg ver of
Nothing -> failIO $ "Package '" ++ pkg ++ "-" ++ (showVersion ver) ++ "' not found in package repository."
Nothing -> failIO $ "Package '" ++ pkg ++ "-" ++ (showVersion ver) ++
"' not found in package repository."
Just p -> succeedIO $ p
update :: Config -> Repository -> GlobalCache -> IO (ErrorLogger ())
update cfg _ _ = updateRepository cfg
--- Lists all packages in the given repository.
listAll :: ListOptions -> Config -> Repository -> IO (ErrorLogger ())
listAll (ListOptions lv) _ repo = putStr rendered >> succeedIO ()
where
results = listPackages repo
rendered = render (table columns [nameLen + 4, 76 - nameLen]) ++
"\nUse `cpm info PACKAGE' for more information about a package.\n"
header = [["Name", "Synopsis"], ["----", "--------"], [" ", " "]]
formatGroup pg = [name (head pg), synopsis (head pg) ++ showPkgVersions pg]
showPkgVersions pg =
if lv then " (" ++ intercalate ", " (map (showVersion . version) pg) ++ ")"
else ""
columns = header ++ map formatGroup results
nameLen = foldl max 0 $ map (length . name) (concat results)
search :: SearchOptions -> Config -> Repository -> IO (ErrorLogger ())
search (SearchOptions q) _ repo = putStr rendered >> succeedIO ()
where
results = searchPackages repo q
rendered = if length results == 0
then "No packages found for '" ++ q ++ "'\n"
else render $ table columns [nameLen + 4, 76 - nameLen]
results = searchPackages repo q
header = [["Name", "Synopsis"], ["----", "--------"], [" ", " "]]
columns = header ++ map (\p -> [name p, synopsis p]) results
nameLen = foldl max 0 $ map (length . name) results
upgrade :: UpgradeOptions -> Config -> Repository -> GlobalCache -> IO (ErrorLogger ())
upgrade :: UpgradeOptions -> Config -> Repository -> GlobalCache
-> IO (ErrorLogger ())
upgrade (UpgradeOptions Nothing) cfg repo gc = tryFindLocalPackageSpec "." |>=
\specDir -> log Info "Upgrading all packages" |>
upgradeAllPackages cfg repo gc specDir
......
......@@ -200,10 +200,13 @@ renderPackageInfo _ gc pkg = pPrint doc
heading = text pkgId
installed = if isInstalled then empty else red $ text "Not installed"
rule = text (take (length pkgId) $ repeat '-')
ver = fill maxLen (bold (text "Version")) <+> (text $ showVersion $ version pkg)
ver = fill maxLen (bold (text "Version")) <+>
(text $ showVersion $ version pkg)
auth = fill maxLen (bold (text "Author")) <+> (text $ author pkg)
synop = fill maxLen (bold (text "Synopsis")) <+> (text $ synopsis pkg)
deps = (bold $ text "Dependencies") <$$> (vcat $ map (indent 4 . text . showDependency) $ dependencies pkg)
deps = (bold $ text "Dependencies") <$$>
(vcat $ map (indent 4 . text . showDependency) $ dependencies pkg)
descr = case description pkg of
Nothing -> empty
Just d -> (bold $ text "Description") <$$> (indent 4 (fillSep (map text (words d))))
Just d -> (bold $ text "Description") <$$>
(indent 4 (fillSep (map text (words d))))
......@@ -15,6 +15,7 @@ module CPM.Repository
, findVersion
, findLatestVersion
, searchPackages
, listPackages
, updateRepository
) where
......@@ -63,6 +64,16 @@ searchPackages (Repository ps) q = map (head . sortedByVersion) groupedResults
namesEqual a b = (name a) == (name b)
sortedByVersion = sortBy (\a b -> (version a) `vgt` (version b))
--- Get all packages in the repository and group them by versions
--- (newest first).
---
--- @param repo - the repository
listPackages :: Repository -> [[Package]]
listPackages (Repository ps) =
map sortedByVersion (groupBy (\a b -> name a == name b) ps)
where
sortedByVersion = sortBy (\a b -> (version a) `vgt` (version b))
--- Finds the latest version of a package.
---
--- @param repo - the central package index
......
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