module Distribution.Client.Init.Simple
(
createProject
, genSimplePkgDesc
, genSimpleLibTarget
, genSimpleExeTarget
, genSimpleTestTarget
) where
import Distribution.Client.Init.Types
import Distribution.Verbosity
import Distribution.Simple.PackageIndex
import Distribution.Client.Types.SourcePackageDb (SourcePackageDb(..))
import qualified Data.List.NonEmpty as NEL
import Distribution.Client.Init.Utils (currentDirPkgName, mkPackageNameDep, fixupDocFiles)
import Distribution.Client.Init.Defaults
import Distribution.Simple.Flag (fromFlagOrDefault, flagElim, Flag (..))
import Distribution.Client.Init.FlagExtractors
import qualified Data.Set as Set
import Distribution.Types.Dependency
import Distribution.Types.PackageName (unPackageName)
createProject
:: Interactive m
=> Verbosity
-> InstalledPackageIndex
-> SourcePackageDb
-> InitFlags
-> m ProjectSettings
createProject :: forall (m :: * -> *).
Interactive m =>
Verbosity
-> InstalledPackageIndex
-> SourcePackageDb
-> InitFlags
-> m ProjectSettings
createProject Verbosity
v InstalledPackageIndex
pkgIx SourcePackageDb
_srcDb InitFlags
initFlags = do
PackageType
pkgType <- forall (m :: * -> *). Interactive m => InitFlags -> m PackageType
packageTypePrompt InitFlags
initFlags
Bool
isMinimal <- forall (m :: * -> *). Interactive m => InitFlags -> m Bool
getMinimal InitFlags
initFlags
Bool
doOverwrite <- forall (m :: * -> *). Interactive m => InitFlags -> m Bool
getOverwrite InitFlags
initFlags
FilePath
pkgDir <- forall (m :: * -> *). Interactive m => InitFlags -> m FilePath
getPackageDir InitFlags
initFlags
PkgDescription
pkgDesc <- forall (m :: * -> *).
Interactive m =>
Verbosity -> PkgDescription -> m PkgDescription
fixupDocFiles Verbosity
v forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (m :: * -> *).
Interactive m =>
InitFlags -> m PkgDescription
genSimplePkgDesc InitFlags
initFlags
let pkgName :: PackageName
pkgName = PkgDescription -> PackageName
_pkgName PkgDescription
pkgDesc
cabalSpec :: CabalSpecVersion
cabalSpec = PkgDescription -> CabalSpecVersion
_pkgCabalVersion PkgDescription
pkgDesc
mkOpts :: Bool -> CabalSpecVersion -> WriteOpts
mkOpts Bool
cs = Bool
-> Bool
-> Bool
-> Verbosity
-> FilePath
-> PackageType
-> PackageName
-> CabalSpecVersion
-> WriteOpts
WriteOpts
Bool
doOverwrite Bool
isMinimal Bool
cs
Verbosity
v FilePath
pkgDir PackageType
pkgType PackageName
pkgName
InitFlags
basedFlags <- forall (m :: * -> *).
Interactive m =>
InstalledPackageIndex -> InitFlags -> m InitFlags
addBaseDepToFlags InstalledPackageIndex
pkgIx InitFlags
initFlags
case PackageType
pkgType of
PackageType
Library -> do
LibTarget
libTarget <- forall (m :: * -> *). Interactive m => InitFlags -> m LibTarget
genSimpleLibTarget InitFlags
basedFlags
Maybe TestTarget
testTarget <- PackageName -> Maybe TestTarget -> Maybe TestTarget
addLibDepToTest PackageName
pkgName forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
Interactive m =>
InitFlags -> m (Maybe TestTarget)
genSimpleTestTarget InitFlags
basedFlags
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ WriteOpts
-> PkgDescription
-> Maybe LibTarget
-> Maybe ExeTarget
-> Maybe TestTarget
-> ProjectSettings
ProjectSettings
(Bool -> CabalSpecVersion -> WriteOpts
mkOpts Bool
False CabalSpecVersion
cabalSpec) PkgDescription
pkgDesc
(forall a. a -> Maybe a
Just LibTarget
libTarget) forall a. Maybe a
Nothing Maybe TestTarget
testTarget
PackageType
Executable -> do
ExeTarget
exeTarget <- forall (m :: * -> *). Interactive m => InitFlags -> m ExeTarget
genSimpleExeTarget InitFlags
basedFlags
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ WriteOpts
-> PkgDescription
-> Maybe LibTarget
-> Maybe ExeTarget
-> Maybe TestTarget
-> ProjectSettings
ProjectSettings
(Bool -> CabalSpecVersion -> WriteOpts
mkOpts Bool
False CabalSpecVersion
cabalSpec) PkgDescription
pkgDesc
forall a. Maybe a
Nothing (forall a. a -> Maybe a
Just ExeTarget
exeTarget) forall a. Maybe a
Nothing
PackageType
LibraryAndExecutable -> do
LibTarget
libTarget <- forall (m :: * -> *). Interactive m => InitFlags -> m LibTarget
genSimpleLibTarget InitFlags
basedFlags
Maybe TestTarget
testTarget <- PackageName -> Maybe TestTarget -> Maybe TestTarget
addLibDepToTest PackageName
pkgName forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
Interactive m =>
InitFlags -> m (Maybe TestTarget)
genSimpleTestTarget InitFlags
basedFlags
ExeTarget
exeTarget <- PackageName -> ExeTarget -> ExeTarget
addLibDepToExe PackageName
pkgName forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). Interactive m => InitFlags -> m ExeTarget
genSimpleExeTarget InitFlags
basedFlags
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ WriteOpts
-> PkgDescription
-> Maybe LibTarget
-> Maybe ExeTarget
-> Maybe TestTarget
-> ProjectSettings
ProjectSettings
(Bool -> CabalSpecVersion -> WriteOpts
mkOpts Bool
False CabalSpecVersion
cabalSpec) PkgDescription
pkgDesc
(forall a. a -> Maybe a
Just LibTarget
libTarget) (forall a. a -> Maybe a
Just ExeTarget
exeTarget) Maybe TestTarget
testTarget
PackageType
TestSuite -> do
Maybe TestTarget
testTarget <- forall (m :: * -> *).
Interactive m =>
InitFlags -> m (Maybe TestTarget)
genSimpleTestTarget InitFlags
basedFlags
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ WriteOpts
-> PkgDescription
-> Maybe LibTarget
-> Maybe ExeTarget
-> Maybe TestTarget
-> ProjectSettings
ProjectSettings
(Bool -> CabalSpecVersion -> WriteOpts
mkOpts Bool
False CabalSpecVersion
cabalSpec) PkgDescription
pkgDesc
forall a. Maybe a
Nothing forall a. Maybe a
Nothing Maybe TestTarget
testTarget
where
addLibDepToTest :: PackageName -> Maybe TestTarget -> Maybe TestTarget
addLibDepToTest PackageName
_ Maybe TestTarget
Nothing = forall a. Maybe a
Nothing
addLibDepToTest PackageName
n (Just TestTarget
t) = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ TestTarget
t
{ _testDependencies :: [Dependency]
_testDependencies = TestTarget -> [Dependency]
_testDependencies TestTarget
t forall a. [a] -> [a] -> [a]
++ [PackageName -> Dependency
mkPackageNameDep PackageName
n]
}
addLibDepToExe :: PackageName -> ExeTarget -> ExeTarget
addLibDepToExe PackageName
n ExeTarget
exe = ExeTarget
exe
{ _exeDependencies :: [Dependency]
_exeDependencies = ExeTarget -> [Dependency]
_exeDependencies ExeTarget
exe forall a. [a] -> [a] -> [a]
++ [PackageName -> Dependency
mkPackageNameDep PackageName
n]
}
genSimplePkgDesc :: Interactive m => InitFlags -> m PkgDescription
genSimplePkgDesc :: forall (m :: * -> *).
Interactive m =>
InitFlags -> m PkgDescription
genSimplePkgDesc InitFlags
flags = PackageName -> PkgDescription
mkPkgDesc forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). Interactive m => m PackageName
currentDirPkgName
where
defaultExtraDoc :: Maybe (Set FilePath)
defaultExtraDoc = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. a -> Set a
Set.singleton FilePath
defaultChangelog
extractExtraDoc :: [FilePath] -> Maybe (Set FilePath)
extractExtraDoc [] = Maybe (Set FilePath)
defaultExtraDoc
extractExtraDoc [FilePath]
fs = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. Ord a => [a] -> Set a
Set.fromList [FilePath]
fs
mkPkgDesc :: PackageName -> PkgDescription
mkPkgDesc PackageName
pkgName = CabalSpecVersion
-> PackageName
-> Version
-> SpecLicense
-> FilePath
-> FilePath
-> FilePath
-> FilePath
-> FilePath
-> Set FilePath
-> Maybe (Set FilePath)
-> PkgDescription
PkgDescription
(forall a. a -> Flag a -> a
fromFlagOrDefault CabalSpecVersion
defaultCabalVersion (InitFlags -> Flag CabalSpecVersion
cabalVersion InitFlags
flags))
PackageName
pkgName
(forall a. a -> Flag a -> a
fromFlagOrDefault Version
defaultVersion (InitFlags -> Flag Version
version InitFlags
flags))
(forall a. a -> Flag a -> a
fromFlagOrDefault (CabalSpecVersion -> SpecLicense
defaultLicense forall a b. (a -> b) -> a -> b
$ InitFlags -> CabalSpecVersion
getCabalVersionNoPrompt InitFlags
flags) (InitFlags -> Flag SpecLicense
license InitFlags
flags))
(forall a. a -> Flag a -> a
fromFlagOrDefault FilePath
"" (InitFlags -> Flag FilePath
author InitFlags
flags))
(forall a. a -> Flag a -> a
fromFlagOrDefault FilePath
"" (InitFlags -> Flag FilePath
email InitFlags
flags))
(forall a. a -> Flag a -> a
fromFlagOrDefault FilePath
"" (InitFlags -> Flag FilePath
homepage InitFlags
flags))
(forall a. a -> Flag a -> a
fromFlagOrDefault FilePath
"" (InitFlags -> Flag FilePath
synopsis InitFlags
flags))
(forall a. a -> Flag a -> a
fromFlagOrDefault FilePath
"" (InitFlags -> Flag FilePath
category InitFlags
flags))
(forall b a. b -> (a -> b) -> Flag a -> b
flagElim forall a. Monoid a => a
mempty forall a. Ord a => [a] -> Set a
Set.fromList (InitFlags -> Flag [FilePath]
extraSrc InitFlags
flags))
(forall b a. b -> (a -> b) -> Flag a -> b
flagElim Maybe (Set FilePath)
defaultExtraDoc [FilePath] -> Maybe (Set FilePath)
extractExtraDoc (InitFlags -> Flag [FilePath]
extraDoc InitFlags
flags))
genSimpleLibTarget :: Interactive m => InitFlags -> m LibTarget
genSimpleLibTarget :: forall (m :: * -> *). Interactive m => InitFlags -> m LibTarget
genSimpleLibTarget InitFlags
flags = do
[Dependency]
buildToolDeps <- forall (m :: * -> *). Interactive m => InitFlags -> m [Dependency]
getBuildTools InitFlags
flags
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ LibTarget
{ _libSourceDirs :: [FilePath]
_libSourceDirs = forall a. a -> Flag a -> a
fromFlagOrDefault [FilePath
defaultSourceDir] forall a b. (a -> b) -> a -> b
$ InitFlags -> Flag [FilePath]
sourceDirs InitFlags
flags
, _libLanguage :: Language
_libLanguage = forall a. a -> Flag a -> a
fromFlagOrDefault Language
defaultLanguage forall a b. (a -> b) -> a -> b
$ InitFlags -> Flag Language
language InitFlags
flags
, _libExposedModules :: NonEmpty ModuleName
_libExposedModules =
forall b a. b -> (a -> b) -> Flag a -> b
flagElim (ModuleName
myLibModule forall a. a -> [a] -> NonEmpty a
NEL.:| []) [ModuleName] -> NonEmpty ModuleName
extractMods forall a b. (a -> b) -> a -> b
$ InitFlags -> Flag [ModuleName]
exposedModules InitFlags
flags
, _libOtherModules :: [ModuleName]
_libOtherModules = forall a. a -> Flag a -> a
fromFlagOrDefault [] forall a b. (a -> b) -> a -> b
$ InitFlags -> Flag [ModuleName]
otherModules InitFlags
flags
, _libOtherExts :: [Extension]
_libOtherExts = forall a. a -> Flag a -> a
fromFlagOrDefault [] forall a b. (a -> b) -> a -> b
$ InitFlags -> Flag [Extension]
otherExts InitFlags
flags
, _libDependencies :: [Dependency]
_libDependencies = forall a. a -> Flag a -> a
fromFlagOrDefault [] forall a b. (a -> b) -> a -> b
$ InitFlags -> Flag [Dependency]
dependencies InitFlags
flags
, _libBuildTools :: [Dependency]
_libBuildTools = [Dependency]
buildToolDeps
}
where
extractMods :: [ModuleName] -> NonEmpty ModuleName
extractMods [] = ModuleName
myLibModule forall a. a -> [a] -> NonEmpty a
NEL.:| []
extractMods [ModuleName]
as = forall a. [a] -> NonEmpty a
NEL.fromList [ModuleName]
as
genSimpleExeTarget :: Interactive m => InitFlags -> m ExeTarget
genSimpleExeTarget :: forall (m :: * -> *). Interactive m => InitFlags -> m ExeTarget
genSimpleExeTarget InitFlags
flags = do
[Dependency]
buildToolDeps <- forall (m :: * -> *). Interactive m => InitFlags -> m [Dependency]
getBuildTools InitFlags
flags
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ ExeTarget
{ _exeMainIs :: HsFilePath
_exeMainIs = forall b a. b -> (a -> b) -> Flag a -> b
flagElim HsFilePath
defaultMainIs FilePath -> HsFilePath
toHsFilePath forall a b. (a -> b) -> a -> b
$ InitFlags -> Flag FilePath
mainIs InitFlags
flags
, _exeApplicationDirs :: [FilePath]
_exeApplicationDirs =
forall a. a -> Flag a -> a
fromFlagOrDefault [FilePath
defaultApplicationDir] forall a b. (a -> b) -> a -> b
$ InitFlags -> Flag [FilePath]
applicationDirs InitFlags
flags
, _exeLanguage :: Language
_exeLanguage = forall a. a -> Flag a -> a
fromFlagOrDefault Language
defaultLanguage forall a b. (a -> b) -> a -> b
$ InitFlags -> Flag Language
language InitFlags
flags
, _exeOtherModules :: [ModuleName]
_exeOtherModules = forall a. a -> Flag a -> a
fromFlagOrDefault [] forall a b. (a -> b) -> a -> b
$ InitFlags -> Flag [ModuleName]
otherModules InitFlags
flags
, _exeOtherExts :: [Extension]
_exeOtherExts = forall a. a -> Flag a -> a
fromFlagOrDefault [] forall a b. (a -> b) -> a -> b
$ InitFlags -> Flag [Extension]
otherExts InitFlags
flags
, _exeDependencies :: [Dependency]
_exeDependencies = forall a. a -> Flag a -> a
fromFlagOrDefault [] forall a b. (a -> b) -> a -> b
$ InitFlags -> Flag [Dependency]
dependencies InitFlags
flags
, _exeBuildTools :: [Dependency]
_exeBuildTools = [Dependency]
buildToolDeps
}
genSimpleTestTarget :: Interactive m => InitFlags -> m (Maybe TestTarget)
genSimpleTestTarget :: forall (m :: * -> *).
Interactive m =>
InitFlags -> m (Maybe TestTarget)
genSimpleTestTarget InitFlags
flags = forall {m :: * -> *}. Interactive m => Bool -> m (Maybe TestTarget)
go forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (m :: * -> *). Interactive m => InitFlags -> m Bool
initializeTestSuitePrompt InitFlags
flags
where
go :: Bool -> m (Maybe TestTarget)
go Bool
initialized
| Bool -> Bool
not Bool
initialized = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
| Bool
otherwise = do
[Dependency]
buildToolDeps <- forall (m :: * -> *). Interactive m => InitFlags -> m [Dependency]
getBuildTools InitFlags
flags
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ TestTarget
{ _testMainIs :: HsFilePath
_testMainIs = forall b a. b -> (a -> b) -> Flag a -> b
flagElim HsFilePath
defaultMainIs FilePath -> HsFilePath
toHsFilePath forall a b. (a -> b) -> a -> b
$ InitFlags -> Flag FilePath
mainIs InitFlags
flags
, _testDirs :: [FilePath]
_testDirs = forall a. a -> Flag a -> a
fromFlagOrDefault [FilePath
defaultTestDir] forall a b. (a -> b) -> a -> b
$ InitFlags -> Flag [FilePath]
testDirs InitFlags
flags
, _testLanguage :: Language
_testLanguage = forall a. a -> Flag a -> a
fromFlagOrDefault Language
defaultLanguage forall a b. (a -> b) -> a -> b
$ InitFlags -> Flag Language
language InitFlags
flags
, _testOtherModules :: [ModuleName]
_testOtherModules = forall a. a -> Flag a -> a
fromFlagOrDefault [] forall a b. (a -> b) -> a -> b
$ InitFlags -> Flag [ModuleName]
otherModules InitFlags
flags
, _testOtherExts :: [Extension]
_testOtherExts = forall a. a -> Flag a -> a
fromFlagOrDefault [] forall a b. (a -> b) -> a -> b
$ InitFlags -> Flag [Extension]
otherExts InitFlags
flags
, _testDependencies :: [Dependency]
_testDependencies = forall a. a -> Flag a -> a
fromFlagOrDefault [] forall a b. (a -> b) -> a -> b
$ InitFlags -> Flag [Dependency]
dependencies InitFlags
flags
, _testBuildTools :: [Dependency]
_testBuildTools = [Dependency]
buildToolDeps
}
addBaseDepToFlags :: Interactive m => InstalledPackageIndex -> InitFlags -> m InitFlags
addBaseDepToFlags :: forall (m :: * -> *).
Interactive m =>
InstalledPackageIndex -> InitFlags -> m InitFlags
addBaseDepToFlags InstalledPackageIndex
pkgIx InitFlags
initFlags = case InitFlags -> Flag [Dependency]
dependencies InitFlags
initFlags of
Flag [Dependency]
as
| forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (forall a. Eq a => a -> a -> Bool
(==) FilePath
"base" forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageName -> FilePath
unPackageName forall b c a. (b -> c) -> (a -> b) -> a -> c
. Dependency -> PackageName
depPkgName) [Dependency]
as -> forall (m :: * -> *) a. Monad m => a -> m a
return InitFlags
initFlags
| Bool
otherwise -> do
[Dependency]
based <- forall (m :: * -> *).
Interactive m =>
InstalledPackageIndex -> InitFlags -> m [Dependency]
dependenciesPrompt InstalledPackageIndex
pkgIx InitFlags
initFlags
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ InitFlags
initFlags
{ dependencies :: Flag [Dependency]
dependencies = forall a. a -> Flag a
Flag forall a b. (a -> b) -> a -> b
$ [Dependency]
based forall a. [a] -> [a] -> [a]
++ [Dependency]
as
}
Flag [Dependency]
NoFlag -> do
[Dependency]
based <- forall (m :: * -> *).
Interactive m =>
InstalledPackageIndex -> InitFlags -> m [Dependency]
dependenciesPrompt InstalledPackageIndex
pkgIx InitFlags
initFlags
forall (m :: * -> *) a. Monad m => a -> m a
return InitFlags
initFlags { dependencies :: Flag [Dependency]
dependencies = forall a. a -> Flag a
Flag [Dependency]
based }