Commit a78070ee authored by Michael Hanus's avatar Michael Hanus
Browse files

CPM updated

parent d4533e8d
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
\usepackage{listings} \usepackage{listings}
\usepackage{amsmath} \usepackage{amsmath}
\lstset{aboveskip=1.5ex, \lstset{aboveskip=1.5ex,
belowskip=1.5ex, belowskip=1.2ex,
showstringspaces=false, showstringspaces=false,
mathescape=true, mathescape=true,
flexiblecolumns=false, flexiblecolumns=false,
...@@ -649,7 +649,7 @@ category (see Section~\ref{sec:reference}) ...@@ -649,7 +649,7 @@ category (see Section~\ref{sec:reference})
of the central package index. of the central package index.
The option \code{--csv} shows the information in CSV format. The option \code{--csv} shows the information in CSV format.
\item[\fbox{\code{search [--module] $query$}}] \item[\fbox{\code{search [--module|--exec] $query$}}]
Searches the names, synopses, and exported module names of all Searches the names, synopses, and exported module names of all
packages of the central package index for occurrences of the given packages of the central package index for occurrences of the given
search term. search term.
...@@ -660,6 +660,17 @@ exporting the module \code{JSON.Data} can be found by the command ...@@ -660,6 +660,17 @@ exporting the module \code{JSON.Data} can be found by the command
\begin{lstlisting} \begin{lstlisting}
> cpm search --module JSON.Data > cpm search --module JSON.Data
\end{lstlisting} \end{lstlisting}
%
If the option \code{--exec} is set, then the search is restricted
to the name of the executable provided by the package.
For instance, the command
%
\begin{lstlisting}
> cpm search --exec show
\end{lstlisting}
%
lists all packages where the name of the executable contains the
string \ccode{show}.
\item[\fbox{\code{update}}] Updates the local copy of the central package index \item[\fbox{\code{update}}] Updates the local copy of the central package index
to the newest available version. to the newest available version.
......
...@@ -47,7 +47,7 @@ cpmBanner :: String ...@@ -47,7 +47,7 @@ cpmBanner :: String
cpmBanner = unlines [bannerLine,bannerText,bannerLine] cpmBanner = unlines [bannerLine,bannerText,bannerLine]
where where
bannerText = bannerText =
"Curry Package Manager <curry-language.org/tools/cpm> (version of 02/07/2017)" "Curry Package Manager <curry-language.org/tools/cpm> (version of 17/07/2017)"
bannerLine = take (length bannerText) (repeat '-') bannerLine = take (length bannerText) (repeat '-')
main :: IO () main :: IO ()
...@@ -97,8 +97,8 @@ runWithArgs opts = do ...@@ -97,8 +97,8 @@ runWithArgs opts = do
New o -> newPackage o New o -> newPackage o
_ -> do repo <- readRepository config _ -> do repo <- readRepository config
case optCommand opts of case optCommand opts of
List o -> listCmd o config repo List o -> listCmd o config repo
Search o -> search o config repo Search o -> searchCmd o config repo
_ -> do globalCache <- getGlobalCache config repo _ -> do globalCache <- getGlobalCache config repo
case optCommand opts of case optCommand opts of
Deps -> deps config repo globalCache Deps -> deps config repo globalCache
...@@ -182,8 +182,9 @@ data ListOptions = ListOptions ...@@ -182,8 +182,9 @@ data ListOptions = ListOptions
} }
data SearchOptions = SearchOptions data SearchOptions = SearchOptions
{ searchQuery :: String { searchQuery :: String -- the term to search for
, searchModule :: Bool , searchModule :: Bool -- search for some module?
, searchExec :: Bool -- search for some executable?
} }
data UpgradeOptions = UpgradeOptions data UpgradeOptions = UpgradeOptions
...@@ -253,7 +254,7 @@ listOpts s = case optCommand s of ...@@ -253,7 +254,7 @@ listOpts s = case optCommand s of
searchOpts :: Options -> SearchOptions searchOpts :: Options -> SearchOptions
searchOpts s = case optCommand s of searchOpts s = case optCommand s of
Search opts -> opts Search opts -> opts
_ -> SearchOptions "" False _ -> SearchOptions "" False False
upgradeOpts :: Options -> UpgradeOptions upgradeOpts :: Options -> UpgradeOptions
upgradeOpts s = case optCommand s of upgradeOpts s = case optCommand s of
...@@ -596,7 +597,12 @@ optionParser = optParser ...@@ -596,7 +597,12 @@ optionParser = optParser
{ searchModule = True } }) { searchModule = True } })
( short "m" ( short "m"
<> long "module" <> long "module"
<> help "Search an exported module" ) <> help "Search for an exported module" )
<.> flag (\a -> Right $ a { optCommand = Search (searchOpts a)
{ searchExec = True } })
( short "x"
<> long "exec"
<> help "Search for the name of an executable" )
<.> arg (\s a -> Right $ a { optCommand = Search (searchOpts a) <.> arg (\s a -> Right $ a { optCommand = Search (searchOpts a)
{ searchQuery = s } }) { searchQuery = s } })
( metavar "QUERY" ( metavar "QUERY"
...@@ -858,21 +864,15 @@ listCmd (ListOptions lv csv cat) cfg repo = ...@@ -858,21 +864,15 @@ listCmd (ListOptions lv csv cat) cfg repo =
else renderPkgs allpkgs else renderPkgs allpkgs
in putStr listresult >> succeedIO () in putStr listresult >> succeedIO ()
where where
-- filter all packages compatible to the current compiler but leave at least
-- one package
filterCompatPkgs pkgs =
let comppkgs = filter (isCompatibleToCompiler cfg) pkgs
in if null comppkgs then take 1 pkgs else comppkgs
-- all packages (and versions if `lv`) -- all packages (and versions if `lv`)
allpkgs = concatMap (if lv then id else ((:[]) . head . filterCompatPkgs)) allpkgs = concatMap (if lv then id else ((:[]) . filterCompatPkgs cfg))
(sortBy (\ps1 ps2 -> name (head ps1) <= name (head ps2)) (sortBy (\ps1 ps2 -> name (head ps1) <= name (head ps2))
(listPackages repo)) (listPackages repo))
-- all categories together with their package names: -- all categories together with their package names:
catgroups = catgroups =
let pkgid p = name p ++ '-' : showVersionIfCompatible cfg p let pkgid p = name p ++ '-' : showVersionIfCompatible cfg p
newpkgs = map (head . filterCompatPkgs) (listPackages repo) newpkgs = map (filterCompatPkgs cfg) (listPackages repo)
catpkgs = concatMap (\p -> map (\c -> (c, pkgid p)) (category p)) catpkgs = concatMap (\p -> map (\c -> (c, pkgid p)) (category p))
newpkgs newpkgs
nocatps = map pkgid (filter (null . category) newpkgs) nocatps = map pkgid (filter (null . category) newpkgs)
...@@ -896,6 +896,14 @@ listCmd (ListOptions lv csv cat) cfg repo = ...@@ -896,6 +896,14 @@ listCmd (ListOptions lv csv cat) cfg repo =
if csv then showCSV (head rows : drop 2 rows) if csv then showCSV (head rows : drop 2 rows)
else unlines [render (table rows colsizes), cpmInfo, cpmUpdate] else unlines [render (table rows colsizes), cpmInfo, cpmUpdate]
--- Returns the first package of a list of packages compatible to the
--- current compiler (according to the given configuration).
--- If there is no compatible package, returns the first one.
filterCompatPkgs :: Config -> [Package] -> Package
filterCompatPkgs cfg pkgs =
let comppkgs = filter (isCompatibleToCompiler cfg) pkgs
in if null comppkgs then head pkgs else head comppkgs
-- Format a list of packages by showing their names, synopsis, and versions -- Format a list of packages by showing their names, synopsis, and versions
-- as table rows. Returns also the column sizes. -- as table rows. Returns also the column sizes.
packageVersionAsTable :: Config -> [Package] -> ([Int],[[String]]) packageVersionAsTable :: Config -> [Package] -> ([Int],[[String]])
...@@ -923,16 +931,21 @@ cpmUpdate = "Use 'cpm update' to download the newest package index." ...@@ -923,16 +931,21 @@ cpmUpdate = "Use 'cpm update' to download the newest package index."
--- Search in all (compiler-compatible) packages in the given repository. --- Search in all (compiler-compatible) packages in the given repository.
search :: SearchOptions -> Config -> Repository -> IO (ErrorLogger ()) searchCmd :: SearchOptions -> Config -> Repository -> IO (ErrorLogger ())
search (SearchOptions q smod) cfg repo = putStr rendered >> succeedIO () searchCmd (SearchOptions q smod sexec) cfg repo =
putStr rendered >> succeedIO ()
where where
results = sortBy (\p1 p2 -> name p1 <= name p2) (searchPackages repo smod q) results = sortBy (\p1 p2 -> name p1 <= name p2)
(map (filterCompatPkgs cfg)
(searchPackages repo smod sexec q))
(colsizes,rows) = packageVersionAsTable cfg results (colsizes,rows) = packageVersionAsTable cfg results
rendered = unlines $ rendered = unlines $
if null results if null results
then ["No packages found for '" ++ q, "'", cpmUpdate] then ["No packages found for '" ++ q ++ "'", cpmUpdate]
else [ render (table rows colsizes), cpmInfo, cpmUpdate ] else [ render (table rows colsizes), cpmInfo, cpmUpdate ]
--- `upgrade` command.
upgrade :: UpgradeOptions -> Config -> Repository -> GlobalCache upgrade :: UpgradeOptions -> Config -> Repository -> GlobalCache
-> IO (ErrorLogger ()) -> IO (ErrorLogger ())
upgrade (UpgradeOptions Nothing) cfg repo gc = upgrade (UpgradeOptions Nothing) cfg repo gc =
...@@ -946,6 +959,7 @@ upgrade (UpgradeOptions (Just pkg)) cfg repo gc = ...@@ -946,6 +959,7 @@ upgrade (UpgradeOptions (Just pkg)) cfg repo gc =
upgradeSinglePackage cfg repo gc specDir pkg upgradeSinglePackage cfg repo gc specDir pkg
--- `link` command.
linkCmd :: LinkOptions -> Config -> IO (ErrorLogger ()) linkCmd :: LinkOptions -> Config -> IO (ErrorLogger ())
linkCmd (LinkOptions src) _ = linkCmd (LinkOptions src) _ =
tryFindLocalPackageSpec "." |>= \specDir -> tryFindLocalPackageSpec "." |>= \specDir ->
......
-------------------------------------------------------------------------------- ------------------------------------------------------------------------------
--- This module contains the data types for a package specification and versions --- This module contains the data types for a package specification and
--- as well as functions for reading/showing/comparing package specs and --- versions as well as functions for reading/showing/comparing package specs
--- package versions. --- and package versions.
-------------------------------------------------------------------------------- ------------------------------------------------------------------------------
module CPM.Package module CPM.Package
( Version, initialVersion ( Version, initialVersion
...@@ -11,6 +11,7 @@ module CPM.Package ...@@ -11,6 +11,7 @@ module CPM.Package
, CompilerCompatibility (..) , CompilerCompatibility (..)
, Package (..), emptyPackage , Package (..), emptyPackage
, Dependency (..) , Dependency (..)
, execOfPackage
, showVersion , showVersion
, replaceVersionInTag , replaceVersionInTag
, readVersion , readVersion
...@@ -202,6 +203,13 @@ emptyPackage = Package { ...@@ -202,6 +203,13 @@ emptyPackage = Package {
, documentation = Nothing , documentation = Nothing
} }
--- Returns the name of the executable of the package.
--- Returns the empty string if the package has no executable to install.
execOfPackage :: Package -> String
execOfPackage p =
maybe "" (\ (PackageExecutable e _ _) -> e) (executableSpec p)
------------------------------------------------------------------------------
--- Translates a package to a JSON object. --- Translates a package to a JSON object.
packageSpecToJSON :: Package -> JValue packageSpecToJSON :: Package -> JValue
packageSpecToJSON pkg = JObject $ packageSpecToJSON pkg = JObject $
...@@ -911,16 +919,20 @@ readVersion s = parse pVersion s ...@@ -911,16 +919,20 @@ readVersion s = parse pVersion s
pVersion :: Parser Version pVersion :: Parser Version
pVersion = pPureVersion pVersion = pPureVersion
<|> (\(maj, min, pat, _) pre -> (maj, min, pat, Just pre)) <$> pPureVersion <*> (char '-' *> pPreRelease) <|> (\(maj, min, pat, _) pre -> (maj, min, pat, Just pre))
<$> pPureVersion <*> (char '-' *> pPreRelease)
pPureVersion :: Parser Version pPureVersion :: Parser Version
pPureVersion = (\maj (min, pat) -> (maj, min, pat, Nothing)) <$> (pNum <* char '.') <*> ((\min pat -> (min, pat)) <$> pNum <* char '.' <*> pNum) pPureVersion = (\maj (min, pat) -> (maj, min, pat, Nothing))
<$> (pNum <* char '.') <*> ((\min pat -> (min, pat))
<$> pNum <* char '.' <*> pNum)
pPreRelease :: Parser String pPreRelease :: Parser String
pPreRelease = some (check isAscii anyChar) pPreRelease = some (check isAscii anyChar)
pNum :: Parser Int pNum :: Parser Int
pNum = (\cs -> foldl1 ((+).(10*)) (map (\c' -> ord c' - ord '0') cs)) <$> some pDigit pNum = (\cs -> foldl1 ((+).(10*)) (map (\c' -> ord c' - ord '0') cs))
<$> some pDigit
pDigit :: Parser Char pDigit :: Parser Char
pDigit = check isDigit anyChar pDigit = check isDigit anyChar
...@@ -209,11 +209,11 @@ renderPackageInfo allinfos plain gc pkg = pPrint doc ...@@ -209,11 +209,11 @@ renderPackageInfo allinfos plain gc pkg = pPrint doc
boldText s = (if plain then id else bold) $ text s boldText s = (if plain then id else bold) $ text s
maxLen = 12 maxLen = 12
doc = vcat $ [ heading, rule, installed, ver, auth, maintnr, synop doc = vcat $ [ heading, rule, installed, ver, auth, maintnr, synop
, cats, deps, compilers, descr ] ++ , cats, deps, compilers, descr, execspec ] ++
if allinfos if allinfos
then [ srcdirs, expmods, cfgmod, execspec] ++ testsuites ++ then [ srcdirs, expmods, cfgmod ] ++ testsuites ++
[ docuspec, src, licns, licfl, copyrt, homepg [ docuspec, src, licns, licfl, copyrt, homepg
, reposy, bugrep] , reposy, bugrep ]
else [] else []
pkgId = packageId pkg pkgId = packageId pkg
...@@ -246,13 +246,15 @@ renderPackageInfo allinfos plain gc pkg = pPrint doc ...@@ -246,13 +246,15 @@ renderPackageInfo allinfos plain gc pkg = pPrint doc
execspec = case executableSpec pkg of execspec = case executableSpec pkg of
Nothing -> empty Nothing -> empty
Just (PackageExecutable n m eopts) -> Just (PackageExecutable n m eopts) ->
boldText "Executable" <$$> if allinfos
indent 4 (boldText "Name " <+> text n) <$$> then boldText "Executable" <$$>
indent 4 (boldText "Main module " <+> text m) <$$> indent 4 (boldText "Name " <+> text n) <$$>
if null eopts indent 4 (boldText "Main module " <+> text m) <$$>
then empty if null eopts
else indent 4 (boldText "Options ") <+> then empty
align (vsep (map (\ (c,o) -> text $ c ++ ": " ++ o) eopts)) else indent 4 (boldText "Options ") <+>
align (vsep (map (\ (c,o) -> text $ c ++ ": " ++ o) eopts))
else fill maxLen (boldText "Executable") <+> text n
testsuites = case testSuite pkg of testsuites = case testSuite pkg of
Nothing -> [] Nothing -> []
......
...@@ -61,26 +61,33 @@ findAllVersions (Repository ps) p pre = ...@@ -61,26 +61,33 @@ findAllVersions (Repository ps) p pre =
--- Search the names and synopses of all compiler-compatbile packages --- Search the names and synopses of all compiler-compatbile packages
--- in the repository for a particular term. --- in the repository for a particular term.
--- Lower/upercase is ignored for the search. --- Lower/upercase is ignored for the search.
--- Returns the newest matching version of each package. --- Returns all matching versions (newest first) of each package.
--- ---
--- @param repo - the repository --- @param repo - the repository
--- @searchmod - search for some module? --- @param searchmod - search for some module?
--- @param q - the term to search for --- @param searchexec - search for some executable?
searchPackages :: Repository -> Bool -> String -> [Package] --- @param searchterm - the term to search for
searchPackages (Repository ps) searchmod searchstring = searchPackages :: Repository -> Bool -> Bool -> String -> [[Package]]
map (head . sortedByVersion) groupedResults searchPackages (Repository ps) searchmod searchexec searchterm =
map sortedByVersion (groupBy (\a b -> name a == name b) allResults)
where where
groupedResults = groupBy namesEqual allResults allResults = let s = lowerS searchterm
allResults = if searchmod in if searchmod
then filter (\p -> searchstring `elem` (exportedModules p)) ps then filter (\p -> s `elem` exportedModules p) ps
else filter (matches (lowerS searchstring)) ps else if searchexec
then filter (\p -> s `isInfixOf`
(lowerS $ execOfPackage p)) ps
else filter (matches s) ps
matches q p = q `isInfixOf` (lowerS $ name p) || matches q p = q `isInfixOf` (lowerS $ name p) ||
q `isInfixOf` (lowerS $ synopsis p) || q `isInfixOf` (lowerS $ synopsis p) ||
q `isInfixOf` (lowerS $ unwords (exportedModules p)) q `isInfixOf` (lowerS $ unwords (exportedModules p))
namesEqual a b = (name a) == (name b)
sortedByVersion = sortBy (\a b -> (version a) `vgt` (version b)) sortedByVersion = sortBy (\a b -> version a `vgt` version b)
lowerS = map toLower lowerS = map toLower
--- Get all packages in the repository and group them by versions --- Get all packages in the repository and group them by versions
--- (newest first). --- (newest first).
--- ---
......
...@@ -28,7 +28,7 @@ Thus, to install the newest version of CASS, use the following commands: ...@@ -28,7 +28,7 @@ Thus, to install the newest version of CASS, use the following commands:
% %
\begin{curry} \begin{curry}
> cpm update > cpm update
> cpm installapp cass > cpm install cass
\end{curry} \end{curry}
% %
This downloads the newest package, compiles it, and places This downloads the newest package, compiles it, and places
......
...@@ -28,7 +28,7 @@ Thus, to install the newest version of CASS, use the following commands: ...@@ -28,7 +28,7 @@ Thus, to install the newest version of CASS, use the following commands:
% %
\begin{curry} \begin{curry}
> cpm update > cpm update
> cpm installapp cass > cpm install cass
\end{curry} \end{curry}
% %
This downloads the newest package, compiles it, and places This downloads the newest package, compiles it, and places
......
...@@ -28,7 +28,7 @@ Thus, to install the newest version of CASS, use the following commands: ...@@ -28,7 +28,7 @@ Thus, to install the newest version of CASS, use the following commands:
% %
\begin{curry} \begin{curry}
> cpm update > cpm update
> cpm installapp cass > cpm install cass
\end{curry} \end{curry}
% %
This downloads the newest package, compiles it, and places This downloads the newest package, compiles it, and places
......
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