Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
curry
curry-tools
Commits
5473376c
Commit
5473376c
authored
Jan 12, 2018
by
Michael Hanus
Browse files
CPM updated
parent
2228d8e1
Changes
5
Hide whitespace changes
Inline
Side-by-side
cpm/docs/manual.tex
View file @
5473376c
...
...
@@ -347,23 +347,34 @@ This command will set the \code{CURRYPATH} environment variable
and then execute the command given after
\ccode
{
exec
}
.
\subsection
{
Using Packages Without a Package
}
\subsection
{
Using Packages Outside a Package
}
\label
{
sec:meta-package
}
In principle, packages can be used only inside another package
by declaring dependencies.
Thus, if you develop a Curry application which is not a package
but you want to use some package, you have to put
a package specification file into the source directory of
your application where you define the required packages.
As a shortcut for this, you can use the CPM command
\code
{
cypm add --dependency
}
(short:
\code
{
cypm add -d
}
)
to install the package specification file.
by declaring dependencies in the package specification file
\code
{
package.json
}
.
If you invoke
\code
{
cypm
}
in a directory which contains
no package specification file, CPM searches for such a file
from the current directory to the parent directories (up to the
root of the file system).
Thus, if you are outside a package, such a file is not available.
In order to support the use other packages outside package,
CPM provides a meta-package which is usually stored in your home directory
at
\code
{
\char
126/.cpm/
$
Curry system
$
-homepackage
}
.
\footnote
{
%
Use
\code
{
cypm config
}
and look at
\code
{
HOME
_
PACKAGE
_
PATH
}
to see the current location of this meta-package.
}
This meta-package is used when your are not inside another package.
Hence, if you write some Curry program which is not a package
but you want to use some package
\code
{
P
}
, you have to add a dependency
to
\code
{
P
}
to this meta-package.
CPM does this automatically for you with the CPM command
\code
{
cypm add --dependency
}
(short:
\code
{
cypm add -d
}
).
For instance, to use the libraries of the JSON package
in your application, one can use the following commands:
%
\begin{lstlisting}
> cypm add -d json #
generate package specification with
'json' dependency
> cypm add -d json #
add
'json' dependency
to meta-package
> cypm install # download and install all dependencies
> cypm curry # start Curry system with JSON libraries in load path
...
...
...
@@ -391,8 +402,8 @@ your own local copy.
\code
{
cypm link
}
takes a directory containing a copy of one of the current
package's dependencies as its argument. It creates a symbolic link from that
directory the the current package's local package cache. If you had a copy of
\code
{
A-1.0.3
}
in the
\code
{
~
/src/A-1.0.3
}
directory, you could use
\code
{
cypm link
~
/src/A-1.0.3
}
to ensure that any time
\code
{
A-1.0.3
}
is used
\code
{
A-1.0.3
}
in the
\code
{
\char
126
/src/A-1.0.3
}
directory, you could use
\code
{
cypm link
\char
126
/src/A-1.0.3
}
to ensure that any time
\code
{
A-1.0.3
}
is used
from the current package, your local copy is used instead of the one from the
global package cache. To remove any links, use
\code
{
cypm upgrade
}
without any
arguments, which will clear the local package cache. See
...
...
@@ -632,6 +643,11 @@ The path to the package cache where packages are checked out if only
their binaries are installed (see Section~
\ref
{
sec:installapp
}
).
Default value:
\code
{
\$
HOME/.cpm/app
_
packages
}
.
\item
[\fbox{\code{HOME_PACKAGE_PATH}}]
The path to the meta-package which is used if you are outside another
package (see Section~
\ref
{
sec:meta-package
}
).
Default value:
\code
{
\$
HOME/.cpm/
$
Curry system
$
-homepackage
}
.
\item
[\fbox{\code{CURRY_BIN}}]
The name of the executable of the Curry system used
to compile and test packages.
...
...
@@ -962,11 +978,11 @@ The option \ccode{--force} allows to overwrite existing copies
in the central package index.
\item
[\fbox{\code{add --dependency $package$ [--force]
}}
]
Adds the package
$
package
$
as a new dependency
of the current package
.
This command
either modifies the package description file (
\code
{
package.json
}
)
of the current package and adds a dependency to the given package
in this file or, if there is no package description file,
generates a new one with this dependency
.
Adds the package
$
package
$
as a new dependency.
This command
adds a dependency to the given package
either in the package description file (
\code
{
package.json
}
)
of the current package or in the meta-package
(see Section~
\ref
{
sec:meta-package
}
)
.
The option
\ccode
{
--force
}
allows to overwrite existing dependencies
in the package description file.
...
...
cpm/src/CPM/Config.curry
View file @
5473376c
...
...
@@ -6,7 +6,7 @@
module CPM.Config
( Config ( Config, packageInstallDir, binInstallDir, repositoryDir
, appPackageDir, packageIndexRepository, curryExec
, appPackageDir, packageIndexRepository,
homePackageDir,
curryExec
, compilerVersion, compilerBaseVersion, baseVersion )
, readConfigurationWith, defaultConfig
, showConfiguration, showCompilerVersion ) where
...
...
@@ -45,6 +45,8 @@ data Config = Config {
, appPackageDir :: String
--- URL to the package index repository
, packageIndexRepository :: String
--- The directory where the default home package is stored
, homePackageDir :: String
--- The executable of the Curry system used to compile and check packages
, curryExec :: String
--- The compiler version (name,major,minor) used to compile packages
...
...
@@ -64,6 +66,7 @@ defaultConfig = Config
, repositoryDir = "$HOME/.cpm/index"
, appPackageDir = "$HOME/.cpm/app_packages"
, packageIndexRepository = packageIndexURI
, homePackageDir = ""
, curryExec = Dist.installDir </> "bin" </> Dist.curryCompiler
, compilerVersion = ( Dist.curryCompiler
, Dist.curryCompilerMajorVersion
...
...
@@ -83,6 +86,7 @@ showConfiguration cfg = unlines
, "PACKAGE_INSTALL_PATH : " ++ packageInstallDir cfg
, "BIN_INSTALL_PATH : " ++ binInstallDir cfg
, "APP_PACKAGE_PATH : " ++ appPackageDir cfg
, "HOME_PACKAGE_PATH : " ++ homePackageDir cfg
]
--- Shows the compiler version in the configuration.
...
...
@@ -107,6 +111,19 @@ setCompilerExecutable cfg = do
maybe (error $ "Executable '" ++ exec ++ "' not found in path!")
(\absexec -> return cfg { curryExec = absexec })
--- Sets the `homePackageDir` depending on the compiler version.
setHomePackageDir :: Config -> IO Config
setHomePackageDir cfg
| null (homePackageDir cfg)
= do homedir <- getHomeDirectory
if null homedir
then return cfg
else let (cname,cmaj,cmin) = compilerVersion cfg
cvname = cname ++ "-" ++ show cmaj ++ "." ++ show cmin
homepkgdir = homedir </> ".cpm" </> cvname ++ "-homepackage"
in return cfg { homePackageDir = homepkgdir }
| otherwise = return cfg
--- Sets the correct compiler version in the configuration.
setCompilerVersion :: Config -> IO Config
setCompilerVersion cfg0 = do
...
...
@@ -171,7 +188,8 @@ readConfigurationWith defsettings = do
Right s0 -> do s1 <- replaceHome s0
createDirectories s1
s2 <- setCompilerVersion s1
return $ Right s2
s3 <- setHomePackageDir s2
return $ Right s3
replaceHome :: Config -> IO Config
replaceHome cfg = do
...
...
@@ -222,6 +240,7 @@ keySetters =
, ("PACKAGEINSTALLPATH" , \v c -> c { packageInstallDir = v })
, ("BININSTALLPATH" , \v c -> c { binInstallDir = v })
, ("APPPACKAGEPATH" , \v c -> c { appPackageDir = v })
, ("HOMEPACKAGEPATH" , \v c -> c { homePackageDir = v })
, ("CURRYBIN" , \v c -> c { curryExec = v })
, ("BASEVERSION" , \v c -> c { baseVersion = v })
]
...
...
cpm/src/CPM/ErrorLogger.curry
View file @
5473376c
...
...
@@ -140,7 +140,7 @@ showLogEntry :: LogEntry -> IO ()
showLogEntry (LogEntry lvl msg) = do
minLevel <- getLogLevel
if levelGte lvl minLevel
then putStrLn $ pPrint
$
lvlText
<+> (text
msg
)
then putStrLn $ pPrint lvlText
++
msg
else return ()
where
lvlText = case lvl of
...
...
cpm/src/CPM/Main.curry
View file @
5473376c
...
...
@@ -53,7 +53,7 @@ cpmBanner :: String
cpmBanner = unlines [bannerLine,bannerText,bannerLine]
where
bannerText =
"Curry Package Manager <curry-language.org/tools/cpm> (version of
23/12
/201
7
)"
"Curry Package Manager <curry-language.org/tools/cpm> (version of
12/01
/201
8
)"
bannerLine = take (length bannerText) (repeat '-')
main :: IO ()
...
...
@@ -96,7 +96,7 @@ runWithArgs opts = do
PkgInfo o -> infoCmd o config
Link o -> linkCmd o config
Add o -> addCmd o config
Clean -> cleanPackage Info
Clean -> cleanPackage
config
Info
New o -> newPackage o
cmd -> do repo <- readRepository config (cmdWithLargeRepoCache cmd)
case optCommand opts of
...
...
@@ -733,7 +733,7 @@ updateCmd cfg =
-- `deps` command:
depsCmd :: DepsOptions -> Config -> IO (ErrorLogger ())
depsCmd opts cfg =
getLocalPackageSpec "." |>= \specDir ->
getLocalPackageSpec
cfg
"." |>= \specDir ->
loadPackageSpec specDir |>= \pkg ->
checkCompiler cfg pkg >>
if depsPath opts -- show CURRYPATH only?
...
...
@@ -750,7 +750,7 @@ infoCmd :: InfoOptions -> Config -> IO (ErrorLogger ())
infoCmd (InfoOptions Nothing (Just _) _ _) _ =
failIO "Must specify package name"
infoCmd (InfoOptions Nothing Nothing allinfos plain) cfg =
getLocalPackageSpec "." |>= \specDir ->
getLocalPackageSpec
cfg
"." |>= \specDir ->
loadPackageSpec specDir |>= \p ->
printInfo cfg allinfos plain p
infoCmd (InfoOptions (Just pkgname) Nothing allinfos plain) cfg =
...
...
@@ -795,7 +795,7 @@ checkoutCmd (CheckoutOptions pkg (Just ver) _) cfg repo =
installCmd :: InstallOptions -> Config -> Repository -> IO (ErrorLogger ())
installCmd (InstallOptions Nothing Nothing _ instexec False) cfg repo =
getLocalPackageSpec "." |>= \pkgdir ->
getLocalPackageSpec
cfg
"." |>= \pkgdir ->
cleanCurryPathCache pkgdir |>
installLocalDependencies cfg repo pkgdir |>= \ (pkg,_) ->
saveBaseVersionToCache cfg pkgdir >>
...
...
@@ -803,7 +803,7 @@ installCmd (InstallOptions Nothing Nothing _ instexec False) cfg repo =
if instexec then installExecutable cfg pkg else succeedIO ()
-- Install executable only:
installCmd (InstallOptions Nothing Nothing _ _ True) cfg _ =
getLocalPackageSpec "." |>= \pkgdir ->
getLocalPackageSpec
cfg
"." |>= \pkgdir ->
loadPackageSpec pkgdir |>= \pkg ->
installExecutable cfg pkg
installCmd (InstallOptions (Just pkg) vers pre _ _) cfg repo = do
...
...
@@ -905,7 +905,7 @@ uninstall (UninstallOptions (Just pkgname) Nothing) cfg = do
uninstall (UninstallOptions Nothing (Just _)) _ =
log Error "Please provide a package and version number!"
uninstall (UninstallOptions Nothing Nothing) cfg =
getLocalPackageSpec "." |>= \pkgdir ->
getLocalPackageSpec
cfg
"." |>= \pkgdir ->
loadPackageSpec pkgdir |>= uninstallPackageExecutable cfg
uninstallPackageExecutable :: Config -> Package -> IO (ErrorLogger ())
...
...
@@ -1013,20 +1013,20 @@ searchCmd (SearchOptions q smod sexec) cfg repo =
--- `upgrade` command.
upgradeCmd :: UpgradeOptions -> Config -> Repository -> IO (ErrorLogger ())
upgradeCmd (UpgradeOptions Nothing) cfg repo =
getLocalPackageSpec "." |>= \specDir ->
getLocalPackageSpec
cfg
"." |>= \specDir ->
cleanCurryPathCache specDir |>
log Info "Upgrading all packages" |>
upgradeAllPackages cfg repo specDir
upgradeCmd (UpgradeOptions (Just pkg)) cfg repo =
getLocalPackageSpec "." |>= \specDir ->
getLocalPackageSpec
cfg
"." |>= \specDir ->
log Info ("Upgrade " ++ pkg) |>
upgradeSinglePackage cfg repo specDir pkg
--- `link` command.
linkCmd :: LinkOptions -> Config -> IO (ErrorLogger ())
linkCmd (LinkOptions src)
_
=
getLocalPackageSpec "." |>= \specDir ->
linkCmd (LinkOptions src)
cfg
=
getLocalPackageSpec
cfg
"." |>= \specDir ->
cleanCurryPathCache specDir |>
log Info ("Linking '" ++ src ++ "' into local package cache...") |>
linkToLocalCache src specDir
...
...
@@ -1087,9 +1087,8 @@ addDependencyCmd pkgname force config =
[] -> packageNotFoundFailure pkgname
ps -> case filter (isCompatibleToCompiler config) ps of
[] -> compatPackageNotFoundFailure config pkgname useUpdateHelp
(p:_) -> searchLocalPackageSpec "." |>=
maybe (genNewLocalPackage (version p))
(addDepToLocalPackage (version p))
(p:_) -> getLocalPackageSpec config "." |>=
addDepToLocalPackage (version p)
where
addDepToLocalPackage vers pkgdir =
loadPackageSpec pkgdir |>= \pkgSpec ->
...
...
@@ -1100,21 +1099,10 @@ addDependencyCmd pkgname force config =
then writePackageSpec newpkg (pkgdir </> "package.json") |>>
log Info ("Dependency '" ++ pkgname ++ " >= " ++
showVersion vers ++
"' added to
current package specification
")
"' added to
package '" ++ pkgdir ++ "'
")
else log Critical ("Dependency '" ++ pkgname ++
"' already exists!\n" ++ useForce)
genNewLocalPackage vers =
let newpkg = emptyPackage { name = "PSEUDO_PACKAGE"
, version = initialVersion
, author = "NN"
, synopsis = "UNKNOWN"
, dependencies = addDep [[VGte vers]] []
}
in writePackageSpec newpkg "package.json" |>>
log Info ("New package specification 'package.json' with dependency '" ++
pkgname ++ " >= " ++ showVersion vers ++ "' generated")
addDep vcs [] = [Dependency pkgname vcs]
addDep vcs (Dependency pn pvcs : deps) =
if pn == pkgname then Dependency pn vcs : deps
...
...
@@ -1127,7 +1115,7 @@ addDependencyCmd pkgname force config =
--- or on all source modules of the package.
docCmd :: DocOptions -> Config -> IO (ErrorLogger ())
docCmd opts cfg =
getLocalPackageSpec "." |>= \specDir ->
getLocalPackageSpec
cfg
"." |>= \specDir ->
loadPackageSpec specDir |>= \pkg -> do
let docdir = maybe "cdoc" id (docDir opts) </> packageId pkg
absdocdir <- getAbsolutePath docdir
...
...
@@ -1256,7 +1244,7 @@ baseDocURL = "http://www.informatik.uni-kiel.de/~mh/curry/cpm/DOC"
--- or all source modules of the package.
testCmd :: TestOptions -> Config -> IO (ErrorLogger ())
testCmd opts cfg =
getLocalPackageSpec "." |>= \specDir ->
getLocalPackageSpec
cfg
"." |>= \specDir ->
loadPackageSpec specDir |>= \pkg -> do
checkCompiler cfg pkg
aspecDir <- getAbsolutePath specDir
...
...
@@ -1318,7 +1306,7 @@ curryModulesInDir dir = getModules "" dir
diffCmd :: DiffOptions -> Config -> Repository -> IO (ErrorLogger ())
diffCmd opts cfg repo =
readGlobalCache cfg repo |>= \gc ->
getLocalPackageSpec "." |>= \specDir ->
getLocalPackageSpec
cfg
"." |>= \specDir ->
loadPackageSpec specDir |>= \localSpec ->
checkCompiler cfg localSpec >>
let localname = name localSpec
...
...
@@ -1366,7 +1354,7 @@ diffCmd opts cfg repo =
-- Implementation of the "curry" command.
compiler :: ExecOptions -> Config -> IO (ErrorLogger ())
compiler o cfg =
getLocalPackageSpec "." |>= \pkgdir ->
getLocalPackageSpec
cfg
"." |>= \pkgdir ->
loadPackageSpec pkgdir |>= \pkg ->
checkCompiler cfg pkg >>
execWithPkgDir
...
...
@@ -1375,7 +1363,7 @@ compiler o cfg =
execCmd :: ExecOptions -> Config -> IO (ErrorLogger ())
execCmd o cfg =
getLocalPackageSpec "." |>= execWithPkgDir o cfg
getLocalPackageSpec
cfg
"." |>= execWithPkgDir o cfg
execWithPkgDir :: ExecOptions -> Config -> String -> IO (ErrorLogger ())
execWithPkgDir o cfg specDir =
...
...
@@ -1410,9 +1398,9 @@ computePackageLoadPath cfg pkgdir =
showVersion (version pkg) /= compilerBaseVersion cfg
-- Clean auxiliary files in the current package
cleanPackage :: LogLevel -> IO (ErrorLogger ())
cleanPackage ll =
getLocalPackageSpec "." |>= \specDir ->
cleanPackage ::
Config ->
LogLevel -> IO (ErrorLogger ())
cleanPackage
cfg
ll =
getLocalPackageSpec
cfg
"." |>= \specDir ->
loadPackageSpec specDir |>= \pkg ->
let dotcpm = specDir </> ".cpm"
srcdirs = map (specDir </>) (sourceDirsOf pkg)
...
...
cpm/src/CPM/PackageCopy.curry
View file @
5473376c
...
...
@@ -9,7 +9,7 @@ module CPM.PackageCopy
, resolveDependencies
, upgradeAllPackages
, upgradeSinglePackage
, getLocalPackageSpec
, searchLocalPackageSpec
, getLocalPackageSpec
, linkToLocalCache
, acquireAndInstallPackageWithDependencies
, installLocalDependencies
...
...
@@ -21,7 +21,8 @@ import Directory ( doesFileExist, getAbsolutePath, createDirectoryIfMissing
, doesDirectoryExist, getTemporaryDirectory
, getCurrentDirectory, setCurrentDirectory, createDirectory
, removeDirectory, getDirectoryContents, copyFile )
import FilePath ((</>), takeExtension, takeBaseName, joinPath, takeDirectory )
import FilePath ( (</>), takeExtension, takeBaseName, joinPath, splitPath
, splitFileName, takeDirectory )
import AbstractCurry.Types (CurryProg)
import List ( intercalate, splitOn )
import Maybe ( mapMaybe, fromJust )
...
...
@@ -30,8 +31,8 @@ import System ( system )
import Text.Pretty hiding ( (</>) )
import CPM.AbstractCurry
import CPM.Config (Config, packageInstallDir, baseVersion)
import CPM.Repository (Repository, allPackages, readRepository)
import CPM.Config (
Config, packageInstallDir, baseVersion
, homePackageDir
)
import CPM.Repository (
Repository, allPackages, readRepository
)
import qualified CPM.LookupSet as LS
import CPM.ErrorLogger
import CPM.FileUtil ( copyDirectory, recreateDirectory )
...
...
@@ -39,14 +40,7 @@ import CPM.Helpers ( strip )
import qualified CPM.PackageCache.Global as GC
import qualified CPM.PackageCache.Runtime as RuntimeCache
import qualified CPM.PackageCache.Local as LocalCache
import CPM.Package ( Package (..)
, readPackageSpec, packageId, readVersion, Version
, showVersion, PackageSource (..), showDependency
, showCompilerDependency, showPackageSource
, VersionConstraint (..)
, Dependency (..), GitRevision (..), PackageExecutable (..)
, PackageTest (..), PackageDocumentation (..)
, packageIdEq, loadPackageSpec)
import CPM.Package
import CPM.Resolution
--- Resolves dependencies for a package copy.
...
...
@@ -168,30 +162,48 @@ linkToLocalCache src pkgDir = do
else log Critical ("Directory '" ++ src ++ "' does not exist.") |>
succeedIO ()
--- Tries to find a package specification in the current directory or one of its
--- ancestors.
getLocalPackageSpec :: String -> IO (ErrorLogger String)
getLocalPackageSpec dir =
searchLocalPackageSpec dir |>=
maybe (failIO "No package.json found") succeedIO
--- Tries to find a package specification in the current directory or one of its
--- ancestors. Returns `Nothing` if there is not package specifiction.
--- Tries to find a package specification in the given directory or one of its
--- ancestors. If there is no package specifiction in these directories,
--- the home package specification (i.e., `~/.cpm/home-package/package.json`
--- is returned (and created if it does not exist).
--- In order to avoid infinite loops due to cyclic file structures,
--- the search is limited to 10 ancestor hierarchies.
searchLocalPackageSpec :: String -> IO (ErrorLogger (Maybe String))
searchLocalPackageSpec = searchLocalSpec 10
--- the search is limited to the number of directories occurring in the
--- current absolute path.
getLocalPackageSpec :: Config -> String -> IO (ErrorLogger String)
getLocalPackageSpec cfg dir = do
adir <- getAbsolutePath dir
searchLocalSpec (length (splitPath adir)) dir
>>= maybe returnHomePackage succeedIO
where
returnHomePackage = do
let homepkgdir = homePackageDir cfg
homepkgspec = homepkgdir </> "package.json"
specexists <- doesFileExist homepkgspec
unless (specexists || null homepkgdir) $ do
createDirectoryIfMissing True homepkgdir
let newpkg = emptyPackage
{ name = snd (splitFileName homepkgdir)
, version = initialVersion
, author = "CPM"
, synopsis = "Default home package"
, dependencies = []
}
writePackageSpec newpkg homepkgspec
infoMessage $ "New empty package specification '" ++ homepkgspec ++
"' generated"
succeedIO homepkgdir
searchLocalSpec m dir = do
existsLocal <- doesFileExist $ dir </> "package.json"
if existsLocal
then succeedIO (Just dir)
else log Debug ("No package.json in " ++ show dir ++ ", trying " ++
show (dir </> "..")) |> do
parentExists <- doesDirectoryExist $ dir </> ".."
if m>0 && parentExists
then searchLocalSpec (m-1) $ dir </> ".."
else succeedIO Nothing
then return (Just dir)
else do
debugMessage ("No package.json in " ++ show dir ++ ", trying " ++
show (dir </> ".."))
parentExists <- doesDirectoryExist $ dir </> ".."
if m>0 && parentExists
then searchLocalSpec (m-1) $ dir </> ".."
else return Nothing
--- Resolves the dependencies for a package copy and fills the package caches.
resolveAndCopyDependencies :: Config -> Repository -> GC.GlobalCache -> String
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment