{-# language CPP #-}
module Hix.Bootstrap where
import Control.Monad.Trans.Class (lift)
import Control.Monad.Trans.Reader (ask)
import qualified Data.Text as Text
import Distribution.Compiler (PerCompilerFlavor (PerCompilerFlavor))
import qualified Distribution.PackageDescription as Cabal
import Distribution.PackageDescription (
BuildInfo,
GenericPackageDescription,
PackageDescription,
UnqualComponentName,
buildType,
licenseFiles,
unPackageName,
unUnqualComponentName,
)
import Distribution.Pretty (pretty)
import Distribution.Simple (Dependency (Dependency), depVerRange)
import Distribution.Types.PackageDescription (license)
import qualified Distribution.Verbosity as Cabal
import Exon (exon)
import Path (Abs, Dir, File, Path, Rel, parent, parseRelFile, relfile, toFilePath, (</>))
import System.FilePattern.Directory (getDirectoryFilesIgnore)
import Hix.Compat (readGenericPackageDescription)
import qualified Hix.Data.BootstrapProjectConfig
import Hix.Data.BootstrapProjectConfig (BootstrapProjectConfig)
import qualified Hix.Data.Monad (AppResources (cwd))
import Hix.Data.Monad (M (M))
import qualified Hix.Data.NewProjectConfig
import Hix.Data.NixExpr (Expr (ExprAttrs, ExprLit, ExprPrefix, ExprString), ExprAttr (ExprAttr, ExprAttrNil))
import Hix.Data.PackageName (PackageName (PackageName))
import qualified Hix.Data.ProjectFile
import Hix.Data.ProjectFile (ProjectFile (ProjectFile), createFile)
import Hix.Error (pathText, tryIO)
import Hix.Monad (AppResources (AppResources), noteBootstrap)
import Hix.NixExpr (mkAttrs, multi, multiOrSingle, nonEmptyAttrs, renderRootExpr, single, singleOpt)
import qualified Hix.Prelude
import Hix.Prelude (Prelude, findPrelude)
#if MIN_VERSION_Cabal(3,14,0)
import Distribution.Utils.Path (makeSymbolicPath)
#endif
data CabalInfo =
CabalInfo {
CabalInfo -> Path Rel Dir
path :: Path Rel Dir,
CabalInfo -> GenericPackageDescription
info :: GenericPackageDescription
}
deriving stock (CabalInfo -> CabalInfo -> Bool
(CabalInfo -> CabalInfo -> Bool)
-> (CabalInfo -> CabalInfo -> Bool) -> Eq CabalInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CabalInfo -> CabalInfo -> Bool
== :: CabalInfo -> CabalInfo -> Bool
$c/= :: CabalInfo -> CabalInfo -> Bool
/= :: CabalInfo -> CabalInfo -> Bool
Eq, Int -> CabalInfo -> ShowS
[CabalInfo] -> ShowS
CabalInfo -> String
(Int -> CabalInfo -> ShowS)
-> (CabalInfo -> String)
-> ([CabalInfo] -> ShowS)
-> Show CabalInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CabalInfo -> ShowS
showsPrec :: Int -> CabalInfo -> ShowS
$cshow :: CabalInfo -> String
show :: CabalInfo -> String
$cshowList :: [CabalInfo] -> ShowS
showList :: [CabalInfo] -> ShowS
Show, (forall x. CabalInfo -> Rep CabalInfo x)
-> (forall x. Rep CabalInfo x -> CabalInfo) -> Generic CabalInfo
forall x. Rep CabalInfo x -> CabalInfo
forall x. CabalInfo -> Rep CabalInfo x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. CabalInfo -> Rep CabalInfo x
from :: forall x. CabalInfo -> Rep CabalInfo x
$cto :: forall x. Rep CabalInfo x -> CabalInfo
to :: forall x. Rep CabalInfo x -> CabalInfo
Generic)
data ComponentType =
Library
|
Executable Text
|
Benchmark Text
|
Test Text
deriving stock (ComponentType -> ComponentType -> Bool
(ComponentType -> ComponentType -> Bool)
-> (ComponentType -> ComponentType -> Bool) -> Eq ComponentType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ComponentType -> ComponentType -> Bool
== :: ComponentType -> ComponentType -> Bool
$c/= :: ComponentType -> ComponentType -> Bool
/= :: ComponentType -> ComponentType -> Bool
Eq, Int -> ComponentType -> ShowS
[ComponentType] -> ShowS
ComponentType -> String
(Int -> ComponentType -> ShowS)
-> (ComponentType -> String)
-> ([ComponentType] -> ShowS)
-> Show ComponentType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ComponentType -> ShowS
showsPrec :: Int -> ComponentType -> ShowS
$cshow :: ComponentType -> String
show :: ComponentType -> String
$cshowList :: [ComponentType] -> ShowS
showList :: [ComponentType] -> ShowS
Show, (forall x. ComponentType -> Rep ComponentType x)
-> (forall x. Rep ComponentType x -> ComponentType)
-> Generic ComponentType
forall x. Rep ComponentType x -> ComponentType
forall x. ComponentType -> Rep ComponentType x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ComponentType -> Rep ComponentType x
from :: forall x. ComponentType -> Rep ComponentType x
$cto :: forall x. Rep ComponentType x -> ComponentType
to :: forall x. Rep ComponentType x -> ComponentType
Generic)
data PreludeWithVersion =
PreludeWithVersion {
PreludeWithVersion -> Prelude
prelude :: Prelude,
PreludeWithVersion -> Maybe Dependency
dep :: Maybe Dependency
}
deriving stock (PreludeWithVersion -> PreludeWithVersion -> Bool
(PreludeWithVersion -> PreludeWithVersion -> Bool)
-> (PreludeWithVersion -> PreludeWithVersion -> Bool)
-> Eq PreludeWithVersion
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: PreludeWithVersion -> PreludeWithVersion -> Bool
== :: PreludeWithVersion -> PreludeWithVersion -> Bool
$c/= :: PreludeWithVersion -> PreludeWithVersion -> Bool
/= :: PreludeWithVersion -> PreludeWithVersion -> Bool
Eq, Int -> PreludeWithVersion -> ShowS
[PreludeWithVersion] -> ShowS
PreludeWithVersion -> String
(Int -> PreludeWithVersion -> ShowS)
-> (PreludeWithVersion -> String)
-> ([PreludeWithVersion] -> ShowS)
-> Show PreludeWithVersion
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PreludeWithVersion -> ShowS
showsPrec :: Int -> PreludeWithVersion -> ShowS
$cshow :: PreludeWithVersion -> String
show :: PreludeWithVersion -> String
$cshowList :: [PreludeWithVersion] -> ShowS
showList :: [PreludeWithVersion] -> ShowS
Show, (forall x. PreludeWithVersion -> Rep PreludeWithVersion x)
-> (forall x. Rep PreludeWithVersion x -> PreludeWithVersion)
-> Generic PreludeWithVersion
forall x. Rep PreludeWithVersion x -> PreludeWithVersion
forall x. PreludeWithVersion -> Rep PreludeWithVersion x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. PreludeWithVersion -> Rep PreludeWithVersion x
from :: forall x. PreludeWithVersion -> Rep PreludeWithVersion x
$cto :: forall x. Rep PreludeWithVersion x -> PreludeWithVersion
to :: forall x. Rep PreludeWithVersion x -> PreludeWithVersion
Generic)
data HixComponent =
HixComponent {
HixComponent -> ComponentType
special :: ComponentType,
HixComponent -> [ExprAttr]
known :: [ExprAttr],
HixComponent -> Maybe PreludeWithVersion
prelude :: Maybe PreludeWithVersion
}
deriving stock (HixComponent -> HixComponent -> Bool
(HixComponent -> HixComponent -> Bool)
-> (HixComponent -> HixComponent -> Bool) -> Eq HixComponent
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: HixComponent -> HixComponent -> Bool
== :: HixComponent -> HixComponent -> Bool
$c/= :: HixComponent -> HixComponent -> Bool
/= :: HixComponent -> HixComponent -> Bool
Eq, Int -> HixComponent -> ShowS
[HixComponent] -> ShowS
HixComponent -> String
(Int -> HixComponent -> ShowS)
-> (HixComponent -> String)
-> ([HixComponent] -> ShowS)
-> Show HixComponent
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> HixComponent -> ShowS
showsPrec :: Int -> HixComponent -> ShowS
$cshow :: HixComponent -> String
show :: HixComponent -> String
$cshowList :: [HixComponent] -> ShowS
showList :: [HixComponent] -> ShowS
Show, (forall x. HixComponent -> Rep HixComponent x)
-> (forall x. Rep HixComponent x -> HixComponent)
-> Generic HixComponent
forall x. Rep HixComponent x -> HixComponent
forall x. HixComponent -> Rep HixComponent x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. HixComponent -> Rep HixComponent x
from :: forall x. HixComponent -> Rep HixComponent x
$cto :: forall x. Rep HixComponent x -> HixComponent
to :: forall x. Rep HixComponent x -> HixComponent
Generic)
data HixPackage =
HixPackage {
HixPackage -> PackageName
name :: PackageName,
HixPackage -> Path Rel Dir
src :: Path Rel Dir,
HixPackage -> [ExprAttr]
known :: [ExprAttr],
HixPackage -> [ExprAttr]
meta :: [ExprAttr],
HixPackage -> ExprAttr
description :: ExprAttr,
HixPackage -> [HixComponent]
components :: [HixComponent]
}
deriving stock (HixPackage -> HixPackage -> Bool
(HixPackage -> HixPackage -> Bool)
-> (HixPackage -> HixPackage -> Bool) -> Eq HixPackage
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: HixPackage -> HixPackage -> Bool
== :: HixPackage -> HixPackage -> Bool
$c/= :: HixPackage -> HixPackage -> Bool
/= :: HixPackage -> HixPackage -> Bool
Eq, Int -> HixPackage -> ShowS
[HixPackage] -> ShowS
HixPackage -> String
(Int -> HixPackage -> ShowS)
-> (HixPackage -> String)
-> ([HixPackage] -> ShowS)
-> Show HixPackage
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> HixPackage -> ShowS
showsPrec :: Int -> HixPackage -> ShowS
$cshow :: HixPackage -> String
show :: HixPackage -> String
$cshowList :: [HixPackage] -> ShowS
showList :: [HixPackage] -> ShowS
Show, (forall x. HixPackage -> Rep HixPackage x)
-> (forall x. Rep HixPackage x -> HixPackage) -> Generic HixPackage
forall x. Rep HixPackage x -> HixPackage
forall x. HixPackage -> Rep HixPackage x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. HixPackage -> Rep HixPackage x
from :: forall x. HixPackage -> Rep HixPackage x
$cto :: forall x. Rep HixPackage x -> HixPackage
to :: forall x. Rep HixPackage x -> HixPackage
Generic)
readCabal ::
Path Abs Dir ->
Path Rel File ->
M CabalInfo
readCabal :: Path Abs Dir -> Path Rel File -> M CabalInfo
readCabal Path Abs Dir
cwd Path Rel File
path = do
#if MIN_VERSION_Cabal(3,14,0)
GenericPackageDescription
info <- IO GenericPackageDescription -> M GenericPackageDescription
forall a. IO a -> M a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (HasCallStack =>
Verbosity
-> Maybe (SymbolicPath CWD ('Dir Pkg))
-> SymbolicPath Pkg 'File
-> IO GenericPackageDescription
Verbosity
-> Maybe (SymbolicPath CWD ('Dir Pkg))
-> SymbolicPath Pkg 'File
-> IO GenericPackageDescription
readGenericPackageDescription Verbosity
Cabal.verbose Maybe (SymbolicPath CWD ('Dir Pkg))
forall a. Maybe a
Nothing (String -> SymbolicPath Pkg 'File
forall from (to :: FileOrDir). String -> SymbolicPath from to
makeSymbolicPath (Path Abs File -> String
forall b t. Path b t -> String
toFilePath (Path Abs Dir
cwd Path Abs Dir -> Path Rel File -> Path Abs File
forall b t. Path b Dir -> Path Rel t -> Path b t
</> Path Rel File
path))))
#else
info <- liftIO (readGenericPackageDescription Cabal.verbose (toFilePath (cwd </> path)))
#endif
pure CabalInfo {path :: Path Rel Dir
path = Path Rel Dir
dir, GenericPackageDescription
info :: GenericPackageDescription
info :: GenericPackageDescription
info}
where
dir :: Path Rel Dir
dir = Path Rel File -> Path Rel Dir
forall b t. Path b t -> Path b Dir
parent Path Rel File
path
knownPackageKeys :: PackageDescription -> [ExprAttr]
knownPackageKeys :: PackageDescription -> [ExprAttr]
knownPackageKeys =
[PackageDescription -> ExprAttr]
-> PackageDescription -> [ExprAttr]
forall e. [e -> ExprAttr] -> e -> [ExprAttr]
mkAttrs [
Text
-> (PackageDescription -> ShortText)
-> PackageDescription
-> ExprAttr
forall a e. EncodeNix a => Text -> (e -> a) -> e -> ExprAttr
single Text
"author" (.author),
Text
-> (PackageDescription -> Doc) -> PackageDescription -> ExprAttr
forall a e. EncodeNix a => Text -> (e -> a) -> e -> ExprAttr
single Text
"build-type" (BuildType -> Doc
forall a. Pretty a => a -> Doc
pretty (BuildType -> Doc)
-> (PackageDescription -> BuildType) -> PackageDescription -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageDescription -> BuildType
buildType),
Text
-> (PackageDescription -> ShortText)
-> PackageDescription
-> ExprAttr
forall a e. EncodeNix a => Text -> (e -> a) -> e -> ExprAttr
single Text
"copyright" (.copyright),
Text
-> (PackageDescription -> Doc) -> PackageDescription -> ExprAttr
forall a e. EncodeNix a => Text -> (e -> a) -> e -> ExprAttr
single Text
"license" (License -> Doc
forall a. Pretty a => a -> Doc
pretty (License -> Doc)
-> (PackageDescription -> License) -> PackageDescription -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageDescription -> License
license),
Text
-> (PackageDescription -> Maybe Doc)
-> PackageDescription
-> ExprAttr
forall a e. EncodeNix a => Text -> (e -> Maybe a) -> e -> ExprAttr
singleOpt Text
"license-file" ((RelativePath Pkg 'File -> Doc)
-> Maybe (RelativePath Pkg 'File) -> Maybe Doc
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap RelativePath Pkg 'File -> Doc
forall a. Pretty a => a -> Doc
pretty (Maybe (RelativePath Pkg 'File) -> Maybe Doc)
-> (PackageDescription -> Maybe (RelativePath Pkg 'File))
-> PackageDescription
-> Maybe Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [RelativePath Pkg 'File] -> Maybe (RelativePath Pkg 'File)
forall a. [a] -> Maybe a
head ([RelativePath Pkg 'File] -> Maybe (RelativePath Pkg 'File))
-> (PackageDescription -> [RelativePath Pkg 'File])
-> PackageDescription
-> Maybe (RelativePath Pkg 'File)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageDescription -> [RelativePath Pkg 'File]
licenseFiles),
Text
-> (PackageDescription -> Version)
-> PackageDescription
-> ExprAttr
forall a e. EncodeNix a => Text -> (e -> a) -> e -> ExprAttr
single Text
"version" (.package.pkgVersion)
]
metaPackageKeys :: PackageDescription -> [ExprAttr]
metaPackageKeys :: PackageDescription -> [ExprAttr]
metaPackageKeys =
[PackageDescription -> ExprAttr]
-> PackageDescription -> [ExprAttr]
forall e. [e -> ExprAttr] -> e -> [ExprAttr]
mkAttrs [
Text
-> (PackageDescription -> ShortText)
-> PackageDescription
-> ExprAttr
forall a e. EncodeNix a => Text -> (e -> a) -> e -> ExprAttr
single Text
"maintainer" (.maintainer),
Text
-> (PackageDescription -> ShortText)
-> PackageDescription
-> ExprAttr
forall a e. EncodeNix a => Text -> (e -> a) -> e -> ExprAttr
single Text
"homepage" (.homepage),
Text
-> (PackageDescription -> ShortText)
-> PackageDescription
-> ExprAttr
forall a e. EncodeNix a => Text -> (e -> a) -> e -> ExprAttr
single Text
"synopsis" (.synopsis)
]
ghcFlavour :: PerCompilerFlavor a -> a
ghcFlavour :: forall a. PerCompilerFlavor a -> a
ghcFlavour (PerCompilerFlavor a
a a
_) = a
a
notDefaultGhcOption :: String -> Bool
notDefaultGhcOption :: String -> Bool
notDefaultGhcOption = \case
String
"-threaded" -> Bool
False
String
"-rtsopts" -> Bool
False
String
"-with-rtsopts=-N" -> Bool
False
String
_ -> Bool
True
knownComponentKeys :: Maybe Prelude -> BuildInfo -> (Maybe PreludeWithVersion, [ExprAttr])
knownComponentKeys :: Maybe Prelude
-> BuildInfo -> (Maybe PreludeWithVersion, [ExprAttr])
knownComponentKeys Maybe Prelude
prelude BuildInfo
info =
(Maybe PreludeWithVersion
preludeWithVersion, [ExprAttr]
vals)
where
vals :: [ExprAttr]
vals =
[BuildInfo -> ExprAttr] -> BuildInfo -> [ExprAttr]
forall e. [e -> ExprAttr] -> e -> [ExprAttr]
mkAttrs [
Text -> (BuildInfo -> [Doc]) -> BuildInfo -> ExprAttr
forall a e. EncodeNix a => Text -> (e -> [a]) -> e -> ExprAttr
multi Text
"dependencies" ((Dependency -> Doc) -> [Dependency] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Dependency -> Doc
forall a. Pretty a => a -> Doc
pretty ([Dependency] -> [Doc])
-> (BuildInfo -> [Dependency]) -> BuildInfo -> [Doc]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Dependency] -> BuildInfo -> [Dependency]
forall a b. a -> b -> a
const [Dependency]
deps),
Text -> (BuildInfo -> [Doc]) -> BuildInfo -> ExprAttr
forall a e. EncodeNix a => Text -> (e -> [a]) -> e -> ExprAttr
multi Text
"default-extensions" ((Extension -> Doc) -> [Extension] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Extension -> Doc
forall a. Pretty a => a -> Doc
pretty ([Extension] -> [Doc])
-> (BuildInfo -> [Extension]) -> BuildInfo -> [Doc]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (.defaultExtensions)),
Text -> (BuildInfo -> [Doc]) -> BuildInfo -> ExprAttr
forall a e. EncodeNix a => Text -> (e -> [a]) -> e -> ExprAttr
multiOrSingle Text
"source-dirs" ((SymbolicPath Pkg ('Dir Source) -> Doc)
-> [SymbolicPath Pkg ('Dir Source)] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap SymbolicPath Pkg ('Dir Source) -> Doc
forall a. Pretty a => a -> Doc
pretty ([SymbolicPath Pkg ('Dir Source)] -> [Doc])
-> (BuildInfo -> [SymbolicPath Pkg ('Dir Source)])
-> BuildInfo
-> [Doc]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (.hsSourceDirs)),
Text -> (BuildInfo -> Maybe Doc) -> BuildInfo -> ExprAttr
forall a e. EncodeNix a => Text -> (e -> Maybe a) -> e -> ExprAttr
singleOpt Text
"language" ((Language -> Doc) -> Maybe Language -> Maybe Doc
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Language -> Doc
forall a. Pretty a => a -> Doc
pretty (Maybe Language -> Maybe Doc)
-> (BuildInfo -> Maybe Language) -> BuildInfo -> Maybe Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (.defaultLanguage)),
Text -> (BuildInfo -> [Expr]) -> BuildInfo -> ExprAttr
forall a e. EncodeNix a => Text -> (e -> [a]) -> e -> ExprAttr
multi Text
"ghc-options" ((String -> Expr) -> [String] -> [Expr]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Text -> Expr
ExprString (Text -> Expr) -> (String -> Text) -> String -> Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
forall a. ToText a => a -> Text
toText) ([String] -> [Expr])
-> (BuildInfo -> [String]) -> BuildInfo -> [Expr]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> Bool) -> [String] -> [String]
forall a. (a -> Bool) -> [a] -> [a]
filter String -> Bool
notDefaultGhcOption ([String] -> [String])
-> (BuildInfo -> [String]) -> BuildInfo -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PerCompilerFlavor [String] -> [String]
forall a. PerCompilerFlavor a -> a
ghcFlavour (PerCompilerFlavor [String] -> [String])
-> (BuildInfo -> PerCompilerFlavor [String])
-> BuildInfo
-> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (.options)),
Item [BuildInfo -> ExprAttr]
BuildInfo -> ExprAttr
forall {a} {e}.
(Pretty a, HasField "otherModules" e [a]) =>
e -> ExprAttr
misc
] BuildInfo
info
misc :: e -> ExprAttr
misc e
e =
Text -> [ExprAttr] -> ExprAttr
nonEmptyAttrs Text
"component" ([e -> ExprAttr] -> e -> [ExprAttr]
forall e. [e -> ExprAttr] -> e -> [ExprAttr]
mkAttrs [
Text -> (e -> [Doc]) -> e -> ExprAttr
forall a e. EncodeNix a => Text -> (e -> [a]) -> e -> ExprAttr
multi Text
"other-modules" ((a -> Doc) -> [a] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> Doc
forall a. Pretty a => a -> Doc
pretty ([a] -> [Doc]) -> (e -> [a]) -> e -> [Doc]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (.otherModules))
] e
e)
(Maybe PreludeWithVersion
preludeWithVersion, [Dependency]
deps)
| Just Prelude
p <- Maybe Prelude
prelude =
let (Maybe Dependency
v, [Dependency]
res) = ((Maybe Dependency, [Dependency])
-> Dependency -> (Maybe Dependency, [Dependency]))
-> (Maybe Dependency, [Dependency])
-> [Dependency]
-> (Maybe Dependency, [Dependency])
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (Prelude
-> (Maybe Dependency, [Dependency])
-> Dependency
-> (Maybe Dependency, [Dependency])
forall {r}.
HasField "preludePackage" r String =>
r
-> (Maybe Dependency, [Dependency])
-> Dependency
-> (Maybe Dependency, [Dependency])
amendPrelude Prelude
p) (Maybe Dependency
forall a. Maybe a
Nothing, []) BuildInfo
info.targetBuildDepends
in (PreludeWithVersion -> Maybe PreludeWithVersion
forall a. a -> Maybe a
Just (Prelude -> Maybe Dependency -> PreludeWithVersion
PreludeWithVersion Prelude
p Maybe Dependency
v), [Dependency]
res)
| Bool
otherwise =
(Maybe PreludeWithVersion
forall a. Maybe a
Nothing, (Dependency -> Bool) -> [Dependency] -> [Dependency]
forall a. (a -> Bool) -> [a] -> [a]
filter Dependency -> Bool
notBase BuildInfo
info.targetBuildDepends)
amendPrelude :: r
-> (Maybe Dependency, [Dependency])
-> Dependency
-> (Maybe Dependency, [Dependency])
amendPrelude r
p (Maybe Dependency
Nothing, [Dependency]
ds) dep :: Dependency
dep@(Dependency (PackageName -> String
Cabal.unPackageName -> String
dname) VersionRange
_ NonEmptySet LibraryName
_) | String
dname String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== r
p.preludePackage =
(Dependency -> Maybe Dependency
forall a. a -> Maybe a
Just Dependency
dep, [Dependency]
ds)
amendPrelude r
_ (Maybe Dependency
v, [Dependency]
ds) Dependency
d = (Maybe Dependency
v, Dependency
d Dependency -> [Dependency] -> [Dependency]
forall a. a -> [a] -> [a]
: [Dependency]
ds)
notBase :: Cabal.Dependency -> Bool
notBase :: Dependency -> Bool
notBase = \case
Cabal.Dependency PackageName
"base" VersionRange
_ NonEmptySet LibraryName
_ -> Bool
False
Dependency
_ -> Bool
True
convertComponent :: ComponentType -> BuildInfo -> [ExprAttr] -> HixComponent
convertComponent :: ComponentType -> BuildInfo -> [ExprAttr] -> HixComponent
convertComponent ComponentType
special BuildInfo
info [ExprAttr]
extra =
HixComponent {known :: [ExprAttr]
known = [ExprAttr]
knownCommon [ExprAttr] -> [ExprAttr] -> [ExprAttr]
forall a. Semigroup a => a -> a -> a
<> [ExprAttr]
extra, Maybe PreludeWithVersion
ComponentType
special :: ComponentType
prelude :: Maybe PreludeWithVersion
special :: ComponentType
prelude :: Maybe PreludeWithVersion
..}
where
(Maybe PreludeWithVersion
prelude, [ExprAttr]
knownCommon) = Maybe Prelude
-> BuildInfo -> (Maybe PreludeWithVersion, [ExprAttr])
knownComponentKeys Maybe Prelude
preludeBasic BuildInfo
info
preludeBasic :: Maybe Prelude
preludeBasic = [Mixin] -> Maybe Prelude
findPrelude BuildInfo
info.mixins
convertLibrary :: Cabal.Library -> HixComponent
convertLibrary :: Library -> HixComponent
convertLibrary Library
lib =
ComponentType -> BuildInfo -> [ExprAttr] -> HixComponent
convertComponent ComponentType
Library Library
lib.libBuildInfo [ExprAttr]
extra
where
extra :: [ExprAttr]
extra = [Library -> ExprAttr] -> Library -> [ExprAttr]
forall e. [e -> ExprAttr] -> e -> [ExprAttr]
mkAttrs [
Text -> (Library -> [Doc]) -> Library -> ExprAttr
forall a e. EncodeNix a => Text -> (e -> [a]) -> e -> ExprAttr
multi Text
"reexported-modules" ((ModuleReexport -> Doc) -> [ModuleReexport] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ModuleReexport -> Doc
forall a. Pretty a => a -> Doc
pretty ([ModuleReexport] -> [Doc])
-> (Library -> [ModuleReexport]) -> Library -> [Doc]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (.reexportedModules))
] Library
lib
convertExecutable :: UnqualComponentName -> Cabal.Executable -> HixComponent
convertExecutable :: UnqualComponentName -> Executable -> HixComponent
convertExecutable UnqualComponentName
name Executable
exe =
ComponentType -> BuildInfo -> [ExprAttr] -> HixComponent
convertComponent (Text -> ComponentType
Executable (String -> Text
forall a. ToText a => a -> Text
toText (UnqualComponentName -> String
unUnqualComponentName UnqualComponentName
name))) Executable
exe.buildInfo []
convertTestsuite :: UnqualComponentName -> Cabal.TestSuite -> HixComponent
convertTestsuite :: UnqualComponentName -> TestSuite -> HixComponent
convertTestsuite UnqualComponentName
name TestSuite
test =
ComponentType -> BuildInfo -> [ExprAttr] -> HixComponent
convertComponent (Text -> ComponentType
Test (String -> Text
forall a. ToText a => a -> Text
toText (UnqualComponentName -> String
unUnqualComponentName UnqualComponentName
name))) TestSuite
test.testBuildInfo []
convertBenchmark :: UnqualComponentName -> Cabal.Benchmark -> HixComponent
convertBenchmark :: UnqualComponentName -> Benchmark -> HixComponent
convertBenchmark UnqualComponentName
name Benchmark
bench =
ComponentType -> BuildInfo -> [ExprAttr] -> HixComponent
convertComponent (Text -> ComponentType
Benchmark (String -> Text
forall a. ToText a => a -> Text
toText (UnqualComponentName -> String
unUnqualComponentName UnqualComponentName
name))) Benchmark
bench.benchmarkBuildInfo []
convert :: CabalInfo -> HixPackage
convert :: CabalInfo -> HixPackage
convert CabalInfo
cinfo =
HixPackage {
name :: PackageName
name = Text -> PackageName
PackageName (String -> Text
forall a. ToText a => a -> Text
toText (PackageName -> String
unPackageName PackageDescription
pkg.package.pkgName)),
src :: Path Rel Dir
src = CabalInfo
cinfo.path,
known :: [ExprAttr]
known = PackageDescription -> [ExprAttr]
knownPackageKeys PackageDescription
pkg,
meta :: [ExprAttr]
meta = PackageDescription -> [ExprAttr]
metaPackageKeys PackageDescription
pkg,
description :: ExprAttr
description = Text
-> (PackageDescription -> ShortText)
-> PackageDescription
-> ExprAttr
forall a e. EncodeNix a => Text -> (e -> a) -> e -> ExprAttr
single Text
"description" (.description) PackageDescription
pkg,
[HixComponent]
components :: [HixComponent]
components :: [HixComponent]
components
}
where
components :: [HixComponent]
components =
Maybe HixComponent -> [HixComponent]
forall a. Maybe a -> [a]
maybeToList (Library -> HixComponent
convertLibrary (Library -> HixComponent)
-> (CondTree ConfVar [Dependency] Library -> Library)
-> CondTree ConfVar [Dependency] Library
-> HixComponent
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (.condTreeData) (CondTree ConfVar [Dependency] Library -> HixComponent)
-> Maybe (CondTree ConfVar [Dependency] Library)
-> Maybe HixComponent
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GenericPackageDescription
info.condLibrary)
[HixComponent] -> [HixComponent] -> [HixComponent]
forall a. Semigroup a => a -> a -> a
<>
((UnqualComponentName -> Executable -> HixComponent)
-> (UnqualComponentName, Executable) -> HixComponent
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry UnqualComponentName -> Executable -> HixComponent
convertExecutable ((UnqualComponentName, Executable) -> HixComponent)
-> ((UnqualComponentName, CondTree ConfVar [Dependency] Executable)
-> (UnqualComponentName, Executable))
-> (UnqualComponentName, CondTree ConfVar [Dependency] Executable)
-> HixComponent
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CondTree ConfVar [Dependency] Executable -> Executable)
-> (UnqualComponentName, CondTree ConfVar [Dependency] Executable)
-> (UnqualComponentName, Executable)
forall b c a. (b -> c) -> (a, b) -> (a, c)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second (.condTreeData) ((UnqualComponentName, CondTree ConfVar [Dependency] Executable)
-> HixComponent)
-> [(UnqualComponentName,
CondTree ConfVar [Dependency] Executable)]
-> [HixComponent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GenericPackageDescription
info.condExecutables)
[HixComponent] -> [HixComponent] -> [HixComponent]
forall a. Semigroup a => a -> a -> a
<>
((UnqualComponentName -> TestSuite -> HixComponent)
-> (UnqualComponentName, TestSuite) -> HixComponent
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry UnqualComponentName -> TestSuite -> HixComponent
convertTestsuite ((UnqualComponentName, TestSuite) -> HixComponent)
-> ((UnqualComponentName, CondTree ConfVar [Dependency] TestSuite)
-> (UnqualComponentName, TestSuite))
-> (UnqualComponentName, CondTree ConfVar [Dependency] TestSuite)
-> HixComponent
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CondTree ConfVar [Dependency] TestSuite -> TestSuite)
-> (UnqualComponentName, CondTree ConfVar [Dependency] TestSuite)
-> (UnqualComponentName, TestSuite)
forall b c a. (b -> c) -> (a, b) -> (a, c)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second (.condTreeData) ((UnqualComponentName, CondTree ConfVar [Dependency] TestSuite)
-> HixComponent)
-> [(UnqualComponentName, CondTree ConfVar [Dependency] TestSuite)]
-> [HixComponent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GenericPackageDescription
info.condTestSuites)
[HixComponent] -> [HixComponent] -> [HixComponent]
forall a. Semigroup a => a -> a -> a
<>
((UnqualComponentName -> Benchmark -> HixComponent)
-> (UnqualComponentName, Benchmark) -> HixComponent
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry UnqualComponentName -> Benchmark -> HixComponent
convertBenchmark ((UnqualComponentName, Benchmark) -> HixComponent)
-> ((UnqualComponentName, CondTree ConfVar [Dependency] Benchmark)
-> (UnqualComponentName, Benchmark))
-> (UnqualComponentName, CondTree ConfVar [Dependency] Benchmark)
-> HixComponent
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CondTree ConfVar [Dependency] Benchmark -> Benchmark)
-> (UnqualComponentName, CondTree ConfVar [Dependency] Benchmark)
-> (UnqualComponentName, Benchmark)
forall b c a. (b -> c) -> (a, b) -> (a, c)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second (.condTreeData) ((UnqualComponentName, CondTree ConfVar [Dependency] Benchmark)
-> HixComponent)
-> [(UnqualComponentName, CondTree ConfVar [Dependency] Benchmark)]
-> [HixComponent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GenericPackageDescription
info.condBenchmarks)
pkg :: PackageDescription
pkg = GenericPackageDescription
info.packageDescription
info :: GenericPackageDescription
info = CabalInfo
cinfo.info
renderComponent :: HixComponent -> ExprAttr
renderComponent :: HixComponent -> ExprAttr
renderComponent HixComponent {[ExprAttr]
Maybe PreludeWithVersion
ComponentType
special :: HixComponent -> ComponentType
known :: HixComponent -> [ExprAttr]
prelude :: HixComponent -> Maybe PreludeWithVersion
special :: ComponentType
known :: [ExprAttr]
prelude :: Maybe PreludeWithVersion
..} =
Text -> Expr -> ExprAttr
ExprAttr Text
key Expr
cabalConfig
where
cabalConfig :: Expr
cabalConfig = [ExprAttr] -> Expr
ExprAttrs ([ExprAttr]
enable [ExprAttr] -> [ExprAttr] -> [ExprAttr]
forall a. Semigroup a => a -> a -> a
<> (PreludeWithVersion -> [ExprAttr])
-> Maybe PreludeWithVersion -> [ExprAttr]
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap PreludeWithVersion -> [ExprAttr]
forall {l} {a} {a} {r} {r}.
(Item l ~ ExprAttr, ToText a, ToText a, IsList l,
HasField "dep" r (Maybe Dependency), HasField "preludePackage" r a,
HasField "preludeModule" r a, HasField "prelude" r r) =>
r -> l
preludeAttrs Maybe PreludeWithVersion
prelude [ExprAttr] -> [ExprAttr] -> [ExprAttr]
forall a. Semigroup a => a -> a -> a
<> [ExprAttr]
known)
preludeAttrs :: r -> l
preludeAttrs r
p =
[Text -> Expr -> ExprAttr
ExprAttr Text
"prelude" ([ExprAttr] -> Expr
ExprAttrs [
Text -> Expr -> ExprAttr
ExprAttr Text
"package" (r -> Expr
forall {a} {r} {r}.
(ToText a, HasField "dep" r (Maybe Dependency),
HasField "preludePackage" r a, HasField "prelude" r r) =>
r -> Expr
preludePackageAttrs r
p),
Text -> Expr -> ExprAttr
ExprAttr Text
"module" (Text -> Expr
ExprString (a -> Text
forall a. ToText a => a -> Text
toText r
p.prelude.preludeModule))
])]
preludePackageAttrs :: r -> Expr
preludePackageAttrs r
p
| Just Dependency
dep <- r
p.dep =
[ExprAttr] -> Expr
ExprAttrs [
Text -> Expr -> ExprAttr
ExprAttr Text
"name" (Text -> Expr
ExprString (a -> Text
forall a. ToText a => a -> Text
toText r
p.prelude.preludePackage)),
Text -> Expr -> ExprAttr
ExprAttr Text
"version" (Text -> Expr
ExprString (Doc -> Text
forall b a. (Show a, IsString b) => a -> b
show (VersionRange -> Doc
forall a. Pretty a => a -> Doc
pretty (Dependency -> VersionRange
depVerRange Dependency
dep))))
]
| Bool
otherwise = Text -> Expr
ExprString (a -> Text
forall a. ToText a => a -> Text
toText r
p.prelude.preludePackage)
key :: Text
key = case ComponentType
special of
ComponentType
Library -> Text
"library"
Executable Text
name -> [exon|executables.#{name}|]
Test Text
name -> [exon|tests.#{name}|]
Benchmark Text
name -> [exon|benchmarks.#{name}|]
enable :: [ExprAttr]
enable = case ComponentType
special of
ComponentType
Library -> [Text -> Expr -> ExprAttr
ExprAttr Text
"enable" (Text -> Expr
ExprLit Text
"true")]
ComponentType
_ -> []
flakePackage :: HixPackage -> ExprAttr
flakePackage :: HixPackage -> ExprAttr
flakePackage HixPackage
pkg =
Text -> Expr -> ExprAttr
ExprAttr (PackageName -> Text
forall a b. Coercible a b => a -> b
coerce HixPackage
pkg.name) Expr
attrs
where
attrs :: Expr
attrs = [ExprAttr] -> Expr
ExprAttrs (ExprAttr
src ExprAttr -> [ExprAttr] -> [ExprAttr]
forall a. a -> [a] -> [a]
: HixPackage
pkg.description ExprAttr -> [ExprAttr] -> [ExprAttr]
forall a. a -> [a] -> [a]
: Text -> Expr -> ExprAttr
ExprAttr Text
"cabal" Expr
cabalConfig ExprAttr -> [ExprAttr] -> [ExprAttr]
forall a. a -> [a] -> [a]
: [ExprAttr]
comps)
src :: ExprAttr
src = Text -> Expr -> ExprAttr
ExprAttr Text
"src" (Text -> Expr
ExprLit [exon|./#{Text.dropWhileEnd ('/' ==) (pathText pkg.src)}|])
cabalConfig :: Expr
cabalConfig = [ExprAttr] -> Expr
ExprAttrs (HixPackage
pkg.known [ExprAttr] -> [ExprAttr] -> [ExprAttr]
forall a. Semigroup a => a -> a -> a
<> [Text -> Expr -> ExprAttr
ExprAttr Text
"meta" ([ExprAttr] -> Expr
ExprAttrs HixPackage
pkg.meta) | Bool -> Bool
not ([ExprAttr] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null HixPackage
pkg.meta)])
comps :: [ExprAttr]
comps = HixComponent -> ExprAttr
renderComponent (HixComponent -> ExprAttr) -> [HixComponent] -> [ExprAttr]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> HixPackage
pkg.components
mainPackage :: [HixPackage] -> ExprAttr
mainPackage :: [HixPackage] -> ExprAttr
mainPackage = \case
HixPackage
pkg : HixPackage
_ : [HixPackage]
_ -> Text -> Expr -> ExprAttr
ExprAttr Text
"main" (Text -> Expr
ExprString (PackageName -> Text
forall a b. Coercible a b => a -> b
coerce HixPackage
pkg.name))
[HixPackage]
_ -> ExprAttr
ExprAttrNil
flake :: BootstrapProjectConfig -> [HixPackage] -> Expr
flake :: BootstrapProjectConfig -> [HixPackage] -> Expr
flake BootstrapProjectConfig
conf [HixPackage]
pkgs =
[ExprAttr] -> Expr
ExprAttrs [
Text -> Expr -> ExprAttr
ExprAttr Text
"description" (Text -> Expr
ExprString Text
"A Haskell project"),
Text -> Expr -> ExprAttr
ExprAttr Text
"inputs.hix.url" (Text -> Expr
ExprString BootstrapProjectConfig
conf.hixUrl.unHixUrl),
Text -> Expr -> ExprAttr
ExprAttr Text
"outputs" (Text -> Expr -> Expr
ExprPrefix Text
"{hix, ...}: hix.lib.flake" ([ExprAttr] -> Expr
ExprAttrs [
Text -> Expr -> ExprAttr
ExprAttr Text
"packages" ([ExprAttr] -> Expr
ExprAttrs (HixPackage -> ExprAttr
flakePackage (HixPackage -> ExprAttr) -> [HixPackage] -> [ExprAttr]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [HixPackage]
pkgs)),
[HixPackage] -> ExprAttr
mainPackage [HixPackage]
pkgs
]))
]
bootstrapFiles :: BootstrapProjectConfig -> M [ProjectFile]
bootstrapFiles :: BootstrapProjectConfig -> M [ProjectFile]
bootstrapFiles BootstrapProjectConfig
conf = do
AppResources {Path Abs Dir
cwd :: AppResources -> Path Abs Dir
cwd :: Path Abs Dir
cwd} <- ReaderT AppResources (ExceptT Error IO) AppResources
-> M AppResources
forall a. ReaderT AppResources (ExceptT Error IO) a -> M a
M ReaderT AppResources (ExceptT Error IO) AppResources
forall (m :: * -> *) r. Monad m => ReaderT r m r
ask
[Path Rel File]
cabals <- [String] -> M [Path Rel File]
paths ([String] -> M [Path Rel File]) -> M [String] -> M [Path Rel File]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ReaderT AppResources (ExceptT Error IO) [String] -> M [String]
forall a. ReaderT AppResources (ExceptT Error IO) a -> M a
M (ExceptT Error IO [String]
-> ReaderT AppResources (ExceptT Error IO) [String]
forall (m :: * -> *) a. Monad m => m a -> ReaderT AppResources m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO [String] -> ExceptT Error IO [String]
forall a. IO a -> ExceptT Error IO a
tryIO (String -> [String] -> [String] -> IO [String]
getDirectoryFilesIgnore (Path Abs Dir -> String
forall b t. Path b t -> String
toFilePath Path Abs Dir
cwd) [String
Item [String]
"**/*.cabal"] [String
Item [String]
"dist-newstyle/**"])))
[HixPackage]
pkgs <- (CabalInfo -> HixPackage) -> [CabalInfo] -> [HixPackage]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CabalInfo -> HixPackage
convert ([CabalInfo] -> [HixPackage]) -> M [CabalInfo] -> M [HixPackage]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Path Rel File -> M CabalInfo) -> [Path Rel File] -> M [CabalInfo]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse (Path Abs Dir -> Path Rel File -> M CabalInfo
readCabal Path Abs Dir
cwd) [Path Rel File]
cabals
pure [
ProjectFile {path :: Path Rel File
path = [relfile|flake.nix|], content :: Text
content = Expr -> Text
renderRootExpr (BootstrapProjectConfig -> [HixPackage] -> Expr
flake BootstrapProjectConfig
conf [HixPackage]
pkgs)}
]
where
paths :: [String] -> M [Path Rel File]
paths = (String -> M (Path Rel File)) -> [String] -> M [Path Rel File]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse (Text -> Maybe (Path Rel File) -> M (Path Rel File)
forall a. Text -> Maybe a -> M a
noteBootstrap Text
"File path error" (Maybe (Path Rel File) -> M (Path Rel File))
-> (String -> Maybe (Path Rel File)) -> String -> M (Path Rel File)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Maybe (Path Rel File)
forall (m :: * -> *). MonadThrow m => String -> m (Path Rel File)
parseRelFile)
bootstrapProject :: BootstrapProjectConfig -> M ()
bootstrapProject :: BootstrapProjectConfig -> M ()
bootstrapProject BootstrapProjectConfig
conf =
(ProjectFile -> M ()) -> [ProjectFile] -> M ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ ProjectFile -> M ()
createFile ([ProjectFile] -> M ()) -> M [ProjectFile] -> M ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< BootstrapProjectConfig -> M [ProjectFile]
bootstrapFiles BootstrapProjectConfig
conf