Commit 1d6ccb26 authored by Michael Hanus's avatar Michael Hanus
Browse files

CPM updated

parent 1c860f27
Copyright (c) 2017, Michael Hanus
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the names of the copyright holders nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
......@@ -26,7 +26,7 @@ clean:
uninstall: clean
rm -f $(TOOL)
src/CPM.Main: $(DEPS)
src/CPM.Main: src/CPM/ConfigPackage.curry $(DEPS)
@echo Root location of Curry system: $(ROOT)
@if [ ! -d "$(ROOT)" ] ; then echo "Error: not a valid directory!" ; exit 1; fi
@export CURRYPATH=""; \
......@@ -36,6 +36,12 @@ src/CPM.Main: $(DEPS)
echo "Set CURRYPATH to $$CURRYPATH"; \
cd src; $(REPL) $(REPL_OPTS) :l CPM.Main :save :quit
src/CPM/ConfigPackage.curry: Makefile
@echo "module CPM.ConfigPackage where" > $@
@echo "packagePath :: String" >> $@
@echo "packagePath = \"$(CURDIR)\"" >> $@
@echo "Curry configuration module '$@' written."
runtest:
@export CURRYPATH=""; \
for i in `ls vendor`; do \
......
......@@ -154,9 +154,11 @@ To use a Curry package in your project, create a
information discussed in the previous session, and move your Curry code to a
\code{src} directory inside your project's directory. Alternatively, if you are
starting a new project, use the \code{cpm new <project-name>} command, which
will ask you a few questions and then create a new project directory with a
\code{package.json} file for you. Declare a dependency inside the new
\code{package.json} file, e.g.:
creates a new project directory with a
\code{package.json} file for you.\footnote{The \code{new} command
also creates some other useful template files. Look into the
output of this command.}
Declare a dependency inside the new \code{package.json} file, e.g.:
\begin{lstlisting}
{
......@@ -714,7 +716,8 @@ Note that a binary installed in the CPM \code{bin} directory
Hence, this command can be used to clean an application package
after installing the application.
\item[\fbox{\code{new}}] Asks a few questions and creates a new package.
\item[\fbox{\code{new $project$}}]
Creates a new project package with the given name and some template files.
\end{description}
......
......@@ -7,7 +7,7 @@ module CPM.Main where
import Char ( toLower )
import CSV ( showCSV )
import Directory ( doesFileExist, getAbsolutePath, doesDirectoryExist
, createDirectory, createDirectoryIfMissing
, copyFile, createDirectory, createDirectoryIfMissing
, getDirectoryContents, getModificationTime
, renameFile, removeFile, setCurrentDirectory )
import Distribution ( stripCurrySuffix, addCurrySubdir )
......@@ -38,13 +38,14 @@ import CPM.PackageCache.Runtime ( dependencyPathsSeparate, writePackageConfig )
import CPM.PackageCopy
import CPM.Diff.API as APIDiff
import qualified CPM.Diff.Behavior as BDiff
import CPM.ConfigPackage (packagePath)
-- Banner of this tool:
cpmBanner :: String
cpmBanner = unlines [bannerLine,bannerText,bannerLine]
where
bannerText =
"Curry Package Manager <curry-language.org/tools/cpm> (version of 14/04/2017)"
"Curry Package Manager <curry-language.org/tools/cpm> (version of 20/04/2017)"
bannerLine = take (length bannerText) (repeat '-')
main :: IO ()
......@@ -86,7 +87,7 @@ runWithArgs opts = do
Exec o -> exec o config getRepo getGC
Test o -> test o config getRepo getGC
Clean -> cleanPackage Info
New -> newPackage
New o -> newPackage o
_ -> do repo <- getRepo
case optCommand opts of
List o -> listCmd o config repo
......@@ -150,7 +151,7 @@ data Command
| Test TestOptions
| Diff DiffOptions
| Clean
| New
| New NewOptions
data CheckoutOptions = CheckoutOptions
{ coPackage :: String
......@@ -187,6 +188,9 @@ data UpgradeOptions = UpgradeOptions
data LinkOptions = LinkOptions
{ lnkSource :: String }
data NewOptions = NewOptions
{ projectName :: String }
data ExecOptions = ExecOptions
{ exeCommand :: String -- command to be executed
, exePath :: [String] -- additional load path
......@@ -245,6 +249,11 @@ linkOpts s = case optCommand s of
Link opts -> opts
_ -> LinkOptions ""
newOpts :: Options -> NewOptions
newOpts s = case optCommand s of
New opts -> opts
_ -> NewOptions ""
execOpts :: Options -> ExecOptions
execOpts s = case optCommand s of
Exec opts -> opts
......@@ -372,8 +381,11 @@ optionParser = optParser
(\a -> Right $ a { optCommand = Deps }) []
<|> command "clean" (help "Clean the current package")
(\a -> Right $ a { optCommand = Clean }) []
<|> command "new" (help "Create a new package")
(\a -> Right $ a { optCommand = New }) []
<|> command "new" (help "Create a new package") Right
( arg (\s a -> Right $ a { optCommand = New (newOpts a)
{ projectName = s } })
( metavar "PROJECT"
<> help "The name of the new project" ) )
<|> 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.")
......@@ -467,7 +479,8 @@ optionParser = optParser
( arg (\s a -> Right $ a { optCommand = Search (searchOpts a) { searchQuery = s } })
( metavar "QUERY"
<> help "The search term" ) )
<|> command "upgrade" (help "Upgrade one or more packages") (\a -> Right $ a { optCommand = Upgrade (upgradeOpts a) })
<|> command "upgrade" (help "Upgrade one or more packages")
(\a -> Right $ a { optCommand = Upgrade (upgradeOpts a) })
( arg (\s a -> Right $ a { optCommand = Upgrade (upgradeOpts a) { upgrTarget = Just s } })
( metavar "PACKAGE"
<> help "The package to upgrade"
......@@ -927,55 +940,53 @@ cleanPackage ll =
(system (unwords (["rm", "-rf"] ++ rmdirs)) >> succeedIO ())
--- Creates a new package by asking some questions.
newPackage :: IO (ErrorLogger ())
newPackage = do
putStrLn "Create a new package"
putStrLn "--------------------"
inpName <- askMandatory "What is the name of the new package?"
exists <- doesDirectoryExist inpName
if exists
then do putStrLn $ "There is already a directory with that name. " ++
"I can't overwrite directories!"
exitWith 1
else return ()
inpVersionS <- askDefault "What is the first version of the package?" "0.0.1"
inpVersion <- case readVersion inpVersionS of
Nothing -> putStrLn "Not a valid version!" >> exitWith 1
Just v -> return v
inpAuthor <- askMandatory "Who is the author of the package?"
inpSynopsis <- askMandatory
"Please provide a short (one line) summary of what the package does:\n>"
createDirectory inpName
let pkgSpec = emptyPackage { name = inpName
, version = inpVersion
, author = inpAuthor
, synopsis = inpSynopsis
, category = []
, dependencies = []
newPackage :: NewOptions -> IO (ErrorLogger ())
newPackage (NewOptions pname) = do
exists <- doesDirectoryExist pname
when exists $ do
putStrLn $ "There is already a directory with the new project name. " ++
"I cannot create new project!"
exitWith 1
let emptyAuthor = "YOUR NAME <YOUR EMAIL ADDRESS>"
emptySynopsis = "PLEASE PROVIDE A ONE-LINE SUMMARY ABOUT THE PACKAGE"
createDirectory pname
let pkgSpec = emptyPackage { name = pname
, version = initialVersion
, author = emptyAuthor
, synopsis = emptySynopsis
, category = ["Programming"]
, dependencies = []
, exportedModules = []
, license = Just "BSD-3-Clause"
, licenseFile = Just "LICENSE"
}
writePackageSpec pkgSpec (inpName </> "package.json")
createDirectory (inpName </> "src")
putStrLn $
"A new package in the directory '" ++ inpName ++ "' has been created.\n" ++
"Please go into this directory, add dependencies in 'package.json',\n" ++
"and run 'cpm install' to install all dependencies."
writePackageSpec pkgSpec (pname </> "package.json")
copyFile (packagePath </> "templates" </> "LICENSE") (pname </> "LICENSE")
createDirectory (pname </> "src")
let cmain = "Main.curry"
copyFile (packagePath </> "templates" </> cmain) (pname </> "src" </> cmain)
writeFile (pname </> "README.md") readme
putStr $ unlines todo
succeedIO ()
where
askMandatory question = do
putStr $ question ++ " "
hFlush stdout
val <- getLine
if val == ""
then askMandatory question
else return val
askDefault question def = do
putStr $ question ++ " [" ++ def ++ "] "
hFlush stdout
val <- getLine
if val == ""
then return def
else return val
readme = unlines [pname, take (length pname) (repeat '=')]
todo =
[ "A new package in the directory '" ++ pname ++ "' has been created!"
, ""
, "Please go into this directory and edit the file 'package.json':"
, "- enter correct values for the fields 'author', 'synopsis', 'category'"
, "- add dependencies in the field 'dependencies'"
, "- add further fields (e.g., 'description')"
, "- review field 'license' (and adapt file 'LICENSE')"
, ""
, "Then run 'cpm install' to install all dependencies and"
, "put your program code in directory 'src'"
, "(where you find a template file 'Main.curry')"
, ""
, "Run the main program with:"
, "> cpm curry :load Main :eval main :quit"
]
---------------------------------------------------------------------------
-- Caching the current CURRYPATH of a package for faster startup.
......
......@@ -5,7 +5,7 @@
--------------------------------------------------------------------------------
module CPM.Package
( Version
( Version, initialVersion
, Dependency
, VersionConstraint (..)
, CompilerCompatibility (..)
......@@ -58,6 +58,10 @@ import CPM.FileUtil (ifFileExists)
--- 3.1.1-rc5
type Version = (Int, Int, Int, Maybe String)
--- The initial version of a new package.
initialVersion :: Version
initialVersion = (0,0,1,Nothing)
type Conjunction = [VersionConstraint]
type Disjunction = [Conjunction]
......@@ -152,7 +156,7 @@ data Package = Package {
emptyPackage :: Package
emptyPackage = Package {
name = ""
, version = (0,0,1,Nothing)
, version = initialVersion
, author = ""
, maintainer = Nothing
, synopsis = ""
......@@ -174,20 +178,24 @@ emptyPackage = Package {
, testSuite = Nothing
}
--- Translates the basic package element to a JSON object.
--- Translates the basic package elements to a JSON object.
packageSpecToJSON :: Package -> JValue
packageSpecToJSON pkg = JObject [
packageSpecToJSON pkg = JObject $ [
("name", JString $ name pkg)
, ("version", JString $ showVersion $ version pkg)
, ("author", JString $ author pkg)
, ("synopsis", JString $ synopsis pkg)
, ("category", stringListToJSON $ category pkg)
, ("dependencies", dependenciesToJSON $ dependencies pkg)
, ("exportedModules", stringListToJSON $ exportedModules pkg) ]
, ("exportedModules", stringListToJSON $ exportedModules pkg) ] ++
maybeStringToJSON "license" (license pkg) ++
maybeStringToJSON "licenseFile" (licenseFile pkg)
where
dependenciesToJSON deps = JObject $ map dependencyToJSON deps
dependencyToJSON (Dependency p vc) = (p, JString $ showVersionConstraints vc)
stringListToJSON exps = JArray $ map JString exps
maybeStringToJSON fname mbcont =
maybe [] (\s -> [(fname, JString s)]) mbcont
--- Writes a basic package specification to a JSON file.
---
......
......@@ -210,7 +210,7 @@ renderPackageInfo allinfos _ gc pkg = pPrint doc
, cats, deps, compilers, descr ] ++
if allinfos
then [ srcdirs, expmods, cfgmod, execspec] ++ testsuites ++
[ src, licns, copyrt, homepg, reposy, bugrep]
[ src, licns, licfl, copyrt, homepg, reposy, bugrep]
else []
pkgId = packageId pkg
......@@ -222,7 +222,8 @@ renderPackageInfo allinfos _ gc pkg = pPrint doc
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)
synop = fill maxLen (bold (text "Synopsis")) <+>
indent 0 (fillSep (map text (words (synopsis pkg))))
deps = (bold $ text "Dependencies") <$$>
(vcat $ map (indent 4 . text . showDependency) $ dependencies pkg)
......@@ -233,8 +234,8 @@ renderPackageInfo allinfos _ gc pkg = pPrint doc
cats =
if null (category pkg)
then empty
else bold (text "Category") <+>
indent 4 (fillSep (map text (category pkg)))
else fill maxLen (bold (text "Category")) <+>
indent 0 (fillSep (map text (category pkg)))
execspec = case executableSpec pkg of
Nothing -> empty
......@@ -264,7 +265,8 @@ renderPackageInfo allinfos _ gc pkg = pPrint doc
tests
descr = showParaField description "Description"
licns = showParaField license "License"
licns = showLineField license "License"
licfl = showLineField licenseFile "License file"
copyrt = showParaField copyright "Copyright"
homepg = showLineField homepage "Homepage"
reposy = showLineField repository "Repository"
......@@ -273,9 +275,12 @@ renderPackageInfo allinfos _ gc pkg = pPrint doc
src = case source pkg of
Nothing -> empty
Just (Http s) -> bold (text "Source") <$$> indent 4 (text s)
Just (Git s _) -> bold (text "Source") <$$> indent 4 (text s)
Just (FileSource s) -> bold (text "Source") <$$> indent 4 (text s)
Just (Http s) -> showSource s
Just (Git s _) -> showSource s
Just (FileSource s) -> showSource s
where
showSource s = bold (text "Source") <$$> indent 4 (text s)
srcdirs =
if null (sourceDirs pkg)
......
Copyright (c) 2017, <AUTHOR NAME>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the names of the copyright holders nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
module Main where
main :: IO ()
main = putStrLn "This is my project!"
Supports Markdown
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