Commit e7dd2a10 authored by Michael Hanus 's avatar Michael Hanus

CPM updated

parent f88dd57b
Hints about CPM's Implementation
================================
Information about CPM's local storage structure can be found in the manual.
Here is some information about CPM's global storage structure.
Global package index
--------------------
CPM requires a global index containing the specifications
of all available packages. The default URL is defined in
`CPM.Config.packageIndexDefaultURL`, currently as
https://git.ps.informatik.uni-kiel.de/curry-packages/cpm-index.git
This configuration can be changed by the `.cpmrc` value
PACKAGE_INDEX_URL
Currently, it is a git repository but it could also be a tar file
or a gzipped tar file.
The directory referenced by this URL must contains for each
package `pkg` and version `vers` a file
pkg/vers/package.json
containing the package specification in JSON format.
For instance, it contains the files
cpm/2.0.0/package.json
cpm/2.1.0/package.json
cpm/2.1.1/package.json
The global package index is downloaded by the CPM command
cypm update
This command also create a local sqlite3 database containing
the most important information about each package.
The database is used by various CPM commands to accelerate
the access to information about packages.
Global package store
--------------------
CPM uses a global store containing a gzipped tar file for each package.
The default URL is defined in `CPM.Config.packageTarFilesDefaultURL`,
currently as
https://www.informatik.uni-kiel.de/~curry/cpm/PACKAGES/
This configuration can be changed by the `.cpmrc` value
PACKAGE_TARFILES_URL
Currently, it is a git repository but it could also be a tar file
or a gzipped tar file.
In order to download the package `pkg` in version `vers`,
CPM extends this URL by the string `pkg-vers.tar.gz`.
For instance, CPM downloads version 2.1.0 of the package `cpm` from
https://www.informatik.uni-kiel.de/~curry/cpm/PACKAGES/cpm-2.1.0.tar.gz
If CPM cannot download anything from this location,
it tries to download the package from the `source` field
of the package description.
Global package index cache
--------------------------
In order to accelerate the creation of the sqlite3 database
during the `update` command, CPM tries to download the file
https://www.informatik.uni-kiel.de/~curry/cpm/PACKAGES/REPOSITORY_CACHE.csv
which contains the database information in CSV format.
If CPM cannot download this file, it creates the database
by reading all package specifications of the global package index
(which takes more time than reading the CSV file).
Uploading packages
------------------
Currently, new package or package version can be uploaded to these
global stores by the command
cypm upload
(see the manual for more details). Currently, only packages having
a source specification of the form
"source": {
"git": "...git.ps.informatik.uni-kiel.de/curry-packages/....git",
"tag": "$version"
can be uploaded. Furthermore, one has to have write access to the
source repository. This command tests the package and, in case
of a successful test, uploads the package to the global package
index and store via the web script at URL
https://www-ps.informatik.uni-kiel.de/~mh/cpm-upload.cgi
......@@ -5,7 +5,7 @@ The Curry package manager (CPM) is a tool to
distribute and install Curry libraries and applications
and manage version dependencies between these libraries.
Since CPM offers a lot of functionality, there is a separate
manual available.\footnote{\url{http://curry-language.org/tools/cpm}}
manual available.\footnote{\url{http://curry-lang.org/tools/cpm}}
Therefore, we describe here only some basic CPM commands.
The executable \code{cypm} is located in the \code{bin} directory
......@@ -48,7 +48,7 @@ one can use the command
\end{curry}
%
This command checks out the package in some internal directory
(\code{\$HOME/.cpm/app_packages})
(\code{\$HOME/.cpm/apps_\ldots})
and installs the binary of the tool provided by the package
in \code{\$HOME/.cpm/bin}.
Hence it is recommended to add this directory to your path.
......
......@@ -47,7 +47,7 @@
\author{Jonas Oberschweiber \qquad Michael Hanus\\[1ex]
{\small Institut f\"ur Informatik, CAU Kiel, Germany}\\[1ex]
{\small\texttt{packages@curry-language.org}}
{\small\texttt{packages@curry-lang.org}}
}
\maketitle
......@@ -663,7 +663,7 @@ If you have access to the Git
repository containing the central package index, then you can push
the modified version of this Git repository.
Otherwise, send your package
specification file to \url{packages@curry-language.org} in order to
specification file to \url{packages@curry-lang.org} in order to
publish it.
......
......@@ -14,33 +14,34 @@ module CPM.Diff.API
, showDifferences
) where
import AbstractCurry.Types (CurryProg (..), CFuncDecl (..), CTypeDecl (..)
, COpDecl (..), QName, CFixity (..)
, CVisibility (..))
import AbstractCurry.Pretty
import AbstractCurry.Select (functions, funcName, types, typeName)
import Directory (getTemporaryDirectory)
import FilePath ((</>))
import Function (both)
import List (nub)
import Maybe (listToMaybe, catMaybes)
import FilePath ( (</>) )
import Function ( both )
import List ( nub )
import Maybe ( listToMaybe, catMaybes )
import Text.Pretty (pPrint, text, (<+>), vcat, empty, red, ($$))
import AbstractCurry.Types ( CurryProg (..), CFuncDecl (..), CTypeDecl (..)
, COpDecl (..), QName, CFixity (..)
, CVisibility (..))
import AbstractCurry.Pretty
import AbstractCurry.Select ( functions, funcName, types, typeName )
import Text.Pretty ( pPrint, text, (<+>), vcat, empty, red, ($$) )
import CPM.AbstractCurry (readAbstractCurryFromPackagePath)
import CPM.Config (Config)
import CPM.AbstractCurry ( readAbstractCurryFromPackagePath )
import CPM.Config ( Config )
import CPM.ErrorLogger
import CPM.FileUtil (copyDirectory, recreateDirectory)
import CPM.Package (Package, Version, packageId, loadPackageSpec
, exportedModules)
import CPM.FileUtil ( copyDirectory, recreateDirectory, tempDir )
import CPM.Package ( Package, Version, packageId, loadPackageSpec
, exportedModules)
import CPM.PackageCache.Global as GC
import CPM.PackageCopy (resolveAndCopyDependencies)
import CPM.Repository (Repository)
import CPM.PackageCopy ( resolveAndCopyDependencies )
import CPM.Repository ( Repository )
getBaseTemp :: IO (ErrorLogger String)
getBaseTemp = getTemporaryDirectory >>=
\tmpDir -> let tmp = tmpDir </> "cpm" </> "diff"
in recreateDirectory tmp >> succeedIO tmp
getBaseTemp = do
tmpDir <- tempDir
let tmp = tmpDir </> "diff"
recreateDirectory tmp
succeedIO tmp
--- Compares two versions of a package from the global package cache.
---
......
......@@ -9,7 +9,6 @@
module CPM.Diff.Behavior
( ComparisonInfo (..)
, createBaseTemp
, getBaseTemp
, genCurryCheckProgram
, diffBehavior
......@@ -20,7 +19,7 @@ module CPM.Diff.Behavior
) where
import Char ( isAlphaNum )
import Directory ( createDirectory, doesDirectoryExist, getTemporaryDirectory )
import Directory ( createDirectory, doesDirectoryExist )
import FilePath ( (</>), joinPath )
import Function ( both )
import List ( intercalate, intersect, nub, splitOn, isPrefixOf, isInfixOf
......@@ -55,7 +54,7 @@ import CPM.Diff.CurryComments (readComments, getFuncComment)
import CPM.Diff.Rename (prefixPackageAndDeps)
import CPM.ErrorLogger
import CPM.FileUtil ( copyDirectory, recreateDirectory, inDirectory
, joinSearchPath)
, joinSearchPath, tempDir )
import CPM.Package ( Package, Version, name, version, showVersion, packageId
, exportedModules, loadPackageSpec)
import CPM.PackageCache.Global as GC
......@@ -130,18 +129,16 @@ data ComparisonInfo = ComparisonInfo
, infModMapB :: [(String, String)] --- Map from old to new module names, ver B
}
--- Create temporary directory for the behavior diff.
createBaseTemp :: IO (ErrorLogger String)
createBaseTemp = do
tmpDir <- getTemporaryDirectory
let tmp = tmpDir </> "CPM" </> "bdiff"
recreateDirectory tmp >> succeedIO tmp
--- Get temporary directory for the behavior diff.
getBaseTemp :: IO (ErrorLogger String)
getBaseTemp = do
tmpDir <- getTemporaryDirectory
succeedIO $ tmpDir </> "CPM" </> "bdiff"
tmpdir <- tempDir
succeedIO $ tmpdir </> "bdiff"
--- Create temporary directory for the behavior diff.
createBaseTemp :: IO (ErrorLogger String)
createBaseTemp =
getBaseTemp |>= \tmp -> recreateDirectory tmp >> succeedIO tmp
--- This message is printed before CurryCheck is executed.
infoText :: String
......
......@@ -12,11 +12,8 @@ module CPM.FileUtil
, linkTarget
, copyDirectoryFollowingSymlinks
, quote
, tempDir
, inTempDir
, inDirectory
, recreateDirectory
, removeDirectoryComplete
, tempDir, cleanTempDir, inTempDir
, inDirectory, recreateDirectory, removeDirectoryComplete
, safeReadFile, checkAndGetVisibleDirectoryContents
, whenFileExists, ifFileExists
) where
......@@ -25,7 +22,7 @@ import Directory ( doesFileExist, doesDirectoryExist, getCurrentDirectory
, setCurrentDirectory, getDirectoryContents
, getTemporaryDirectory, doesDirectoryExist, createDirectory
, createDirectoryIfMissing, getAbsolutePath )
import System ( system, getEnviron, exitWith )
import System ( exitWith, getEnviron, getPID, system )
import IOExts ( evalCmd, readCompleteFile )
import FilePath ( FilePath, replaceFileName, (</>), searchPathSeparator )
import List ( intercalate, isPrefixOf, splitOn )
......@@ -80,11 +77,16 @@ linkTarget link = do
quote :: String -> String
quote s = "\"" ++ s ++ "\""
--- Gets CPM's temporary directory.
--- Gets a temporary directory for some CPM command.
tempDir :: IO String
tempDir = do
t <- getTemporaryDirectory
return (t </> "cpm")
t <- getTemporaryDirectory
pid <- getPID
return (t </> "cpm" ++ show pid)
--- Removes the temporary directory for some CPM command.
cleanTempDir :: IO ()
cleanTempDir = tempDir >>= removeDirectoryComplete
--- Executes an IO action with the current directory set to CPM's temporary
--- directory.
......
......@@ -29,8 +29,8 @@ import System.Path ( fileInPath )
import Text.CSV ( showCSV )
import CPM.ErrorLogger
import CPM.FileUtil ( joinSearchPath, safeReadFile, whenFileExists
, ifFileExists, inDirectory, inTempDir, recreateDirectory
import CPM.FileUtil ( cleanTempDir, joinSearchPath, safeReadFile, whenFileExists
, ifFileExists, inDirectory, recreateDirectory
, removeDirectoryComplete, copyDirectory, quote, tempDir )
import CPM.Config ( Config (..)
, readConfigurationWith, showCompilerVersion
......@@ -60,7 +60,7 @@ cpmBanner :: String
cpmBanner = unlines [bannerLine,bannerText,bannerLine]
where
bannerText =
"Curry Package Manager <curry-language.org/tools/cpm> (version of 13/06/2019)"
"Curry Package Manager <curry-lang.org/tools/cpm> (version of 28/10/2019)"
bannerLine = take (length bannerText) (repeat '-')
main :: IO ()
......@@ -1385,7 +1385,8 @@ diffCmd opts cfg =
installIfNecessary repo localname diffv |> putStrLn "" >>
readGlobalCache cfg repo |>= \gc ->
diffAPIIfEnabled repo gc specDir localSpec diffv |>
diffBehaviorIfEnabled repo gc specDir localSpec diffv
diffBehaviorIfEnabled repo gc specDir localSpec diffv |>
cleanTempDir >> succeedIO ()
where
getDiffVersion repo localname = case diffVersion opts of
Nothing -> case findLatestVersion cfg repo localname False of
......@@ -1403,15 +1404,15 @@ diffCmd opts cfg =
diffAPIIfEnabled repo gc specDir localSpec diffversion =
if diffAPI opts
then (putStrLn "Running API diff...\n" >> succeedIO ()) |>
APIDiff.compareModulesFromPackageAndDir cfg repo gc specDir
(name localSpec) diffversion (diffModules opts) |>=
\diffResults ->
let diffOut = APIDiff.showDifferences (map snd diffResults)
(version localSpec) diffversion
in unless (null diffOut) (putStrLn diffOut >> putStrLn "") >>
succeedIO ()
else succeedIO ()
then (putStrLn "Running API diff...\n" >> succeedIO ()) |>
APIDiff.compareModulesFromPackageAndDir cfg repo gc specDir
(name localSpec) diffversion (diffModules opts) |>=
\diffResults ->
let diffOut = APIDiff.showDifferences (map snd diffResults)
(version localSpec) diffversion
in unless (null diffOut) (putStrLn diffOut >> putStrLn "") >>
succeedIO ()
else succeedIO ()
diffBehaviorIfEnabled repo gc specDir localSpec diffversion =
if diffBehavior opts
......@@ -1537,14 +1538,14 @@ uploadCmd opts cfg =
loadPackageSpec (instdir </> pkgid) |>= \pkg ->
testPackage pkgid instdir >>= \ecode ->
if ecode > 0
then removeDirectoryComplete instdir >>
then cleanTempDir >>
log Critical "ERROR in package, package not uploaded!"
else log Info "Uploading package to global repository..." |>
removeInstalledPkg pkgid >>
uploadPackageSpec (instdir </> pkgid </> "package.json") |>
-- add package to local copy of repository:
addPackageToRepo pkgrepodir (instdir </> pkgid) pkg >>
removeDirectoryComplete instdir >>
cleanTempDir >>
log Info ("Package '" ++ pkgid ++ "' uploaded")
where
addPackageToRepo pkgrepodir pkgdir pkg = do
......
......@@ -336,7 +336,7 @@ loadPackageSpec dir = do
case readPackageSpec contents of
Left err -> failIO err
Right v -> succeedIO v )
(failIO $ "Illegal package: file `package.json' does not exist!")
(failIO $ "Illegal package: file '" ++ packageFile ++ "' does not exist!")
--- Checks whether two package ids are equal, i.e. if their names and versions
--- match.
......
......@@ -21,7 +21,7 @@ import Text.Pretty hiding ( (</>) )
import CPM.Config ( Config, homePackageDir )
import CPM.ErrorLogger
import CPM.FileUtil ( inDirectory, inTempDir, quote
import CPM.FileUtil ( cleanTempDir, inDirectory, inTempDir, quote
, removeDirectoryComplete, tempDir, whenFileExists )
import CPM.Helpers ( strip )
import CPM.Package
......@@ -77,7 +77,8 @@ installPackageSourceTo pkg (Http url) installdir = do
" " ++ quote url
if c == 0
then installPkgFromFile pkg tmppkgfile pkgDir True
else failIO $ "`curl` failed with exit status " ++ show c
else do cleanTempDir
failIO $ "`curl` failed with exit status " ++ show c
--- Installs a package from a .zip or .tar.gz file into the specified
--- package directory. If the last argument is true, the file will be
......@@ -93,6 +94,7 @@ installPkgFromFile pkg pkgfile pkgDir rmfile = do
else inDirectory pkgDir $ showExecCmd $
"tar -xzf " ++ quote absfile
when rmfile (showExecCmd ("rm -f " ++ absfile) >> done)
cleanTempDir
if c == 0
then log Info $ "Installed " ++ packageId pkg
else do removeDirectoryComplete pkgDir
......
......@@ -33,7 +33,8 @@ import FilePath
import CPM.Config ( Config, packageInstallDir, packageTarFilesURL )
import CPM.ErrorLogger
import CPM.FileUtil ( copyDirectory, inTempDir, recreateDirectory, inDirectory
import CPM.FileUtil ( cleanTempDir, copyDirectory, inTempDir
, recreateDirectory, inDirectory
, removeDirectoryComplete, tempDir, whenFileExists
, checkAndGetVisibleDirectoryContents, quote )
import CPM.Package
......@@ -163,8 +164,9 @@ installFromZip cfg zip = do
then
loadPackageSpec (t </> "installtmp") |>= \pkgSpec ->
log Debug ("ZIP contains " ++ packageId pkgSpec) |>
(cleanTempDir >> succeedIO ()) |>
installFromSource cfg pkgSpec (FileSource zip)
else failIO "failed to extract ZIP file"
else cleanTempDir >> failIO "failed to extract ZIP file"
--- Installs a package's missing dependencies.
installMissingDependencies :: Config -> GlobalCache -> [Package]
......
......@@ -22,7 +22,8 @@ import Text.CSV
import CPM.Config ( Config, packageTarFilesURL, readConfigurationWith
, repositoryDir )
import CPM.ErrorLogger
import CPM.FileUtil ( inTempDir, quote, tempDir, whenFileExists )
import CPM.FileUtil ( cleanTempDir, inTempDir, quote, tempDir
, whenFileExists )
import CPM.Repository.RepositoryDB
import CPM.Package
import CPM.Repository
......@@ -72,7 +73,7 @@ writeRepositoryDB cfg writecsv = do
addPackagesToRepositoryDB cfg False pkgentries
putChar '\n'
log Info "Repository cache DB written"
showExecCmd $ "/bin/rm -f " ++ csvfile
cleanTempDir
if writecsv then saveDBAsCSV cfg
else succeedIO ()
......
......@@ -3,7 +3,7 @@
--- Curry system.
---
--- @author Bernd Brassel, Michael Hanus, Bjoern Peemoeller, Finn Teegen
--- @version December 2018
--- @version October 2019
------------------------------------------------------------------------------
module System.FrontendExec
......@@ -14,7 +14,7 @@ module System.FrontendExec
, specials, setQuiet, setExtended, setCpp, addDefinition, setDefinitions
, setOverlapWarn, setFullPath, setHtmlDir, setLogfile, addTarget, setSpecials
, callFrontend, callFrontendWithParams
, callFrontend, callFrontendWithParams, showFrontendTarget
) where
import Char ( toUpper )
......@@ -220,7 +220,8 @@ callFrontendWithParams target params modpath = do
parsecurry <- callParseCurry
let lf = maybe "" id (logfile params)
tgts = nub (target : targets params)
syscall = unwords $ [parsecurry] ++ map showFrontendTarget tgts ++
syscall = unwords $ [parsecurry] ++
map (\t -> "--" ++ showFrontendTarget t) tgts ++
[showFrontendParams, cppParams, takeFileName modpath]
retcode <- if null lf
then system syscall
......@@ -238,19 +239,6 @@ callFrontendWithParams target params modpath = do
quote s = '"' : s ++ "\""
showFrontendTarget FCY = "--flat"
showFrontendTarget TFCY = "--typed-flat"
showFrontendTarget TAFCY = "--type-annotated-flat"
showFrontendTarget FINT = "--flat"
showFrontendTarget ACY = "--acy"
showFrontendTarget UACY = "--uacy"
showFrontendTarget HTML = "--html"
showFrontendTarget CY = "--parse-only"
showFrontendTarget TOKS = "--tokens"
showFrontendTarget AST = "--ast"
showFrontendTarget SAST = "--short-ast"
showFrontendTarget COMMS = "--comments"
showFrontendParams = unwords
[ if quiet params then runQuiet else ""
, if extended params then "--extended" else ""
......@@ -266,4 +254,19 @@ callFrontendWithParams target params modpath = do
showDefinition (s, v) = "-D" ++ s ++ "=" ++ show v
--- Shows the FrontendTarget as the parameter passed to the front-end.
showFrontendTarget :: FrontendTarget -> String
showFrontendTarget FCY = "flat"
showFrontendTarget TFCY = "typed-flat"
showFrontendTarget TAFCY = "type-annotated-flat"
showFrontendTarget FINT = "flat"
showFrontendTarget ACY = "acy"
showFrontendTarget UACY = "uacy"
showFrontendTarget HTML = "html"
showFrontendTarget CY = "parse-only"
showFrontendTarget TOKS = "tokens"
showFrontendTarget AST = "ast"
showFrontendTarget SAST = "short-ast"
showFrontendTarget COMMS = "comments"
------------------------------------------------------------------------------
......@@ -3,7 +3,7 @@
--- Curry system.
---
--- @author Bernd Brassel, Michael Hanus, Bjoern Peemoeller, Finn Teegen
--- @version December 2018
--- @version October 2019
------------------------------------------------------------------------------
module System.FrontendExec
......@@ -14,7 +14,7 @@ module System.FrontendExec
, specials, setQuiet, setExtended, setCpp, addDefinition, setDefinitions
, setOverlapWarn, setFullPath, setHtmlDir, setLogfile, addTarget, setSpecials
, callFrontend, callFrontendWithParams
, callFrontend, callFrontendWithParams, showFrontendTarget
) where
import Char ( toUpper )
......@@ -220,7 +220,8 @@ callFrontendWithParams target params modpath = do
parsecurry <- callParseCurry
let lf = maybe "" id (logfile params)
tgts = nub (target : targets params)
syscall = unwords $ [parsecurry] ++ map showFrontendTarget tgts ++
syscall = unwords $ [parsecurry] ++
map (\t -> "--" ++ showFrontendTarget t) tgts ++
[showFrontendParams, cppParams, takeFileName modpath]
retcode <- if null lf
then system syscall
......@@ -238,19 +239,6 @@ callFrontendWithParams target params modpath = do
quote s = '"' : s ++ "\""
showFrontendTarget FCY = "--flat"
showFrontendTarget TFCY = "--typed-flat"
showFrontendTarget TAFCY = "--type-annotated-flat"
showFrontendTarget FINT = "--flat"
showFrontendTarget ACY = "--acy"
showFrontendTarget UACY = "--uacy"
showFrontendTarget HTML = "--html"
showFrontendTarget CY = "--parse-only"
showFrontendTarget TOKS = "--tokens"
showFrontendTarget AST = "--ast"
showFrontendTarget SAST = "--short-ast"
showFrontendTarget COMMS = "--comments"
showFrontendParams = unwords
[ if quiet params then runQuiet else ""
, if extended params then "--extended" else ""
......@@ -266,4 +254,19 @@ callFrontendWithParams target params modpath = do
showDefinition (s, v) = "-D" ++ s ++ "=" ++ show v
--- Shows the FrontendTarget as the parameter passed to the front-end.
showFrontendTarget :: FrontendTarget -> String
showFrontendTarget FCY = "flat"
showFrontendTarget TFCY = "typed-flat"
showFrontendTarget TAFCY = "type-annotated-flat"
showFrontendTarget FINT = "flat"
showFrontendTarget ACY = "acy"
showFrontendTarget UACY = "uacy"
showFrontendTarget HTML = "html"
showFrontendTarget CY = "parse-only"
showFrontendTarget TOKS = "tokens"
showFrontendTarget AST = "ast"
showFrontendTarget SAST = "short-ast"
showFrontendTarget COMMS = "comments"
------------------------------------------------------------------------------
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