packages feed

hix 0.2.0.0 → 0.4.0.0

raw patch · 26 files changed

+1249/−194 lines, 26 filesdep +casingPVP ok

version bump matches the API change (PVP)

Dependencies added: casing

API changes (from Hackage documentation)

- Hix.Data.GhciConfig: ComponentConfig :: ComponentName -> SourceDirs -> Maybe EnvRunner -> [String] -> String -> [String] -> Maybe PreludeConfig -> ComponentConfig
- Hix.Data.GhciConfig: ComponentName :: Text -> ComponentName
- Hix.Data.GhciConfig: EnvName :: Text -> EnvName
- Hix.Data.GhciConfig: EnvRunner :: Path Abs File -> EnvRunner
- Hix.Data.GhciConfig: ModuleName :: Text -> ModuleName
- Hix.Data.GhciConfig: PackageConfig :: PackageName -> Path Rel Dir -> Map ComponentName ComponentConfig -> PackageConfig
- Hix.Data.GhciConfig: PackageName :: Text -> PackageName
- Hix.Data.GhciConfig: PackagePath :: Path Rel Dir -> PackagePath
- Hix.Data.GhciConfig: PreludeConfig :: PreludePackage -> ModuleName -> PreludeConfig
- Hix.Data.GhciConfig: PreludePackageName :: Text -> PreludePackage
- Hix.Data.GhciConfig: PreludePackageSpec :: Text -> PreludePackage
- Hix.Data.GhciConfig: PreprocConfig :: PackagesConfig -> PreprocConfig
- Hix.Data.GhciConfig: SourceDir :: Path Rel Dir -> SourceDir
- Hix.Data.GhciConfig: SourceDirs :: [SourceDir] -> SourceDirs
- Hix.Data.GhciConfig: Target :: PackageConfig -> ComponentConfig -> Maybe SourceDir -> Target
- Hix.Data.GhciConfig: [$sel:component:Target] :: Target -> ComponentConfig
- Hix.Data.GhciConfig: [$sel:components:PackageConfig] :: PackageConfig -> Map ComponentName ComponentConfig
- Hix.Data.GhciConfig: [$sel:extensions:ComponentConfig] :: ComponentConfig -> [String]
- Hix.Data.GhciConfig: [$sel:ghcOptions:ComponentConfig] :: ComponentConfig -> [String]
- Hix.Data.GhciConfig: [$sel:language:ComponentConfig] :: ComponentConfig -> String
- Hix.Data.GhciConfig: [$sel:module_:PreludeConfig] :: PreludeConfig -> ModuleName
- Hix.Data.GhciConfig: [$sel:name:ComponentConfig] :: ComponentConfig -> ComponentName
- Hix.Data.GhciConfig: [$sel:name:PackageConfig] :: PackageConfig -> PackageName
- Hix.Data.GhciConfig: [$sel:name:PreludePackageName] :: PreludePackage -> Text
- Hix.Data.GhciConfig: [$sel:package:PreludeConfig] :: PreludeConfig -> PreludePackage
- Hix.Data.GhciConfig: [$sel:package:Target] :: Target -> PackageConfig
- Hix.Data.GhciConfig: [$sel:packages:PreprocConfig] :: PreprocConfig -> PackagesConfig
- Hix.Data.GhciConfig: [$sel:prelude:ComponentConfig] :: ComponentConfig -> Maybe PreludeConfig
- Hix.Data.GhciConfig: [$sel:runner:ComponentConfig] :: ComponentConfig -> Maybe EnvRunner
- Hix.Data.GhciConfig: [$sel:sourceDir:Target] :: Target -> Maybe SourceDir
- Hix.Data.GhciConfig: [$sel:sourceDirs:ComponentConfig] :: ComponentConfig -> SourceDirs
- Hix.Data.GhciConfig: [$sel:src:PackageConfig] :: PackageConfig -> Path Rel Dir
- Hix.Data.GhciConfig: [$sel:unComponentName:ComponentName] :: ComponentName -> Text
- Hix.Data.GhciConfig: [$sel:unEnvName:EnvName] :: EnvName -> Text
- Hix.Data.GhciConfig: [$sel:unModuleName:ModuleName] :: ModuleName -> Text
- Hix.Data.GhciConfig: [$sel:unPackageName:PackageName] :: PackageName -> Text
- Hix.Data.GhciConfig: [$sel:unPackagePath:PackagePath] :: PackagePath -> Path Rel Dir
- Hix.Data.GhciConfig: [$sel:unSourceDir:SourceDir] :: SourceDir -> Path Rel Dir
- Hix.Data.GhciConfig: [$sel:unSourceDirs:SourceDirs] :: SourceDirs -> [SourceDir]
- Hix.Data.GhciConfig: data ComponentConfig
- Hix.Data.GhciConfig: data PackageConfig
- Hix.Data.GhciConfig: data PreludeConfig
- Hix.Data.GhciConfig: data PreludePackage
- Hix.Data.GhciConfig: data PreprocConfig
- Hix.Data.GhciConfig: data Target
- Hix.Data.GhciConfig: instance Data.Aeson.Types.FromJSON.FromJSON Hix.Data.GhciConfig.ComponentConfig
- Hix.Data.GhciConfig: instance Data.Aeson.Types.FromJSON.FromJSON Hix.Data.GhciConfig.ComponentName
- Hix.Data.GhciConfig: instance Data.Aeson.Types.FromJSON.FromJSON Hix.Data.GhciConfig.EnvName
- Hix.Data.GhciConfig: instance Data.Aeson.Types.FromJSON.FromJSON Hix.Data.GhciConfig.EnvRunner
- Hix.Data.GhciConfig: instance Data.Aeson.Types.FromJSON.FromJSON Hix.Data.GhciConfig.ModuleName
- Hix.Data.GhciConfig: instance Data.Aeson.Types.FromJSON.FromJSON Hix.Data.GhciConfig.PackageConfig
- Hix.Data.GhciConfig: instance Data.Aeson.Types.FromJSON.FromJSON Hix.Data.GhciConfig.PackageName
- Hix.Data.GhciConfig: instance Data.Aeson.Types.FromJSON.FromJSON Hix.Data.GhciConfig.PackagePath
- Hix.Data.GhciConfig: instance Data.Aeson.Types.FromJSON.FromJSON Hix.Data.GhciConfig.PreludeConfig
- Hix.Data.GhciConfig: instance Data.Aeson.Types.FromJSON.FromJSON Hix.Data.GhciConfig.PreludePackage
- Hix.Data.GhciConfig: instance Data.Aeson.Types.FromJSON.FromJSON Hix.Data.GhciConfig.PreprocConfig
- Hix.Data.GhciConfig: instance Data.Aeson.Types.FromJSON.FromJSON Hix.Data.GhciConfig.SourceDir
- Hix.Data.GhciConfig: instance Data.Aeson.Types.FromJSON.FromJSON Hix.Data.GhciConfig.SourceDirs
- Hix.Data.GhciConfig: instance Data.Aeson.Types.FromJSON.FromJSONKey Hix.Data.GhciConfig.ComponentName
- Hix.Data.GhciConfig: instance Data.Aeson.Types.FromJSON.FromJSONKey Hix.Data.GhciConfig.EnvName
- Hix.Data.GhciConfig: instance Data.Aeson.Types.FromJSON.FromJSONKey Hix.Data.GhciConfig.ModuleName
- Hix.Data.GhciConfig: instance Data.Aeson.Types.FromJSON.FromJSONKey Hix.Data.GhciConfig.PackageName
- Hix.Data.GhciConfig: instance Data.Aeson.Types.FromJSON.FromJSONKey Hix.Data.GhciConfig.PackagePath
- Hix.Data.GhciConfig: instance Data.String.IsString Hix.Data.GhciConfig.ComponentName
- Hix.Data.GhciConfig: instance Data.String.IsString Hix.Data.GhciConfig.EnvName
- Hix.Data.GhciConfig: instance Data.String.IsString Hix.Data.GhciConfig.ModuleName
- Hix.Data.GhciConfig: instance Data.String.IsString Hix.Data.GhciConfig.PackageName
- Hix.Data.GhciConfig: instance GHC.Classes.Eq Hix.Data.GhciConfig.ComponentConfig
- Hix.Data.GhciConfig: instance GHC.Classes.Eq Hix.Data.GhciConfig.ComponentName
- Hix.Data.GhciConfig: instance GHC.Classes.Eq Hix.Data.GhciConfig.EnvName
- Hix.Data.GhciConfig: instance GHC.Classes.Eq Hix.Data.GhciConfig.EnvRunner
- Hix.Data.GhciConfig: instance GHC.Classes.Eq Hix.Data.GhciConfig.ModuleName
- Hix.Data.GhciConfig: instance GHC.Classes.Eq Hix.Data.GhciConfig.PackageConfig
- Hix.Data.GhciConfig: instance GHC.Classes.Eq Hix.Data.GhciConfig.PackageName
- Hix.Data.GhciConfig: instance GHC.Classes.Eq Hix.Data.GhciConfig.PackagePath
- Hix.Data.GhciConfig: instance GHC.Classes.Eq Hix.Data.GhciConfig.PreludeConfig
- Hix.Data.GhciConfig: instance GHC.Classes.Eq Hix.Data.GhciConfig.PreludePackage
- Hix.Data.GhciConfig: instance GHC.Classes.Eq Hix.Data.GhciConfig.PreprocConfig
- Hix.Data.GhciConfig: instance GHC.Classes.Eq Hix.Data.GhciConfig.SourceDir
- Hix.Data.GhciConfig: instance GHC.Classes.Eq Hix.Data.GhciConfig.SourceDirs
- Hix.Data.GhciConfig: instance GHC.Classes.Eq Hix.Data.GhciConfig.Target
- Hix.Data.GhciConfig: instance GHC.Classes.Ord Hix.Data.GhciConfig.ComponentName
- Hix.Data.GhciConfig: instance GHC.Classes.Ord Hix.Data.GhciConfig.EnvName
- Hix.Data.GhciConfig: instance GHC.Classes.Ord Hix.Data.GhciConfig.ModuleName
- Hix.Data.GhciConfig: instance GHC.Classes.Ord Hix.Data.GhciConfig.PackageName
- Hix.Data.GhciConfig: instance GHC.Classes.Ord Hix.Data.GhciConfig.PackagePath
- Hix.Data.GhciConfig: instance GHC.Generics.Generic Hix.Data.GhciConfig.ComponentConfig
- Hix.Data.GhciConfig: instance GHC.Generics.Generic Hix.Data.GhciConfig.ComponentName
- Hix.Data.GhciConfig: instance GHC.Generics.Generic Hix.Data.GhciConfig.EnvName
- Hix.Data.GhciConfig: instance GHC.Generics.Generic Hix.Data.GhciConfig.EnvRunner
- Hix.Data.GhciConfig: instance GHC.Generics.Generic Hix.Data.GhciConfig.ModuleName
- Hix.Data.GhciConfig: instance GHC.Generics.Generic Hix.Data.GhciConfig.PackageConfig
- Hix.Data.GhciConfig: instance GHC.Generics.Generic Hix.Data.GhciConfig.PackageName
- Hix.Data.GhciConfig: instance GHC.Generics.Generic Hix.Data.GhciConfig.PackagePath
- Hix.Data.GhciConfig: instance GHC.Generics.Generic Hix.Data.GhciConfig.PreludeConfig
- Hix.Data.GhciConfig: instance GHC.Generics.Generic Hix.Data.GhciConfig.PreludePackage
- Hix.Data.GhciConfig: instance GHC.Generics.Generic Hix.Data.GhciConfig.PreprocConfig
- Hix.Data.GhciConfig: instance GHC.Generics.Generic Hix.Data.GhciConfig.SourceDir
- Hix.Data.GhciConfig: instance GHC.Generics.Generic Hix.Data.GhciConfig.SourceDirs
- Hix.Data.GhciConfig: instance GHC.Generics.Generic Hix.Data.GhciConfig.Target
- Hix.Data.GhciConfig: instance GHC.Show.Show Hix.Data.GhciConfig.ComponentConfig
- Hix.Data.GhciConfig: instance GHC.Show.Show Hix.Data.GhciConfig.ComponentName
- Hix.Data.GhciConfig: instance GHC.Show.Show Hix.Data.GhciConfig.EnvName
- Hix.Data.GhciConfig: instance GHC.Show.Show Hix.Data.GhciConfig.EnvRunner
- Hix.Data.GhciConfig: instance GHC.Show.Show Hix.Data.GhciConfig.ModuleName
- Hix.Data.GhciConfig: instance GHC.Show.Show Hix.Data.GhciConfig.PackageConfig
- Hix.Data.GhciConfig: instance GHC.Show.Show Hix.Data.GhciConfig.PackageName
- Hix.Data.GhciConfig: instance GHC.Show.Show Hix.Data.GhciConfig.PackagePath
- Hix.Data.GhciConfig: instance GHC.Show.Show Hix.Data.GhciConfig.PreludeConfig
- Hix.Data.GhciConfig: instance GHC.Show.Show Hix.Data.GhciConfig.PreludePackage
- Hix.Data.GhciConfig: instance GHC.Show.Show Hix.Data.GhciConfig.PreprocConfig
- Hix.Data.GhciConfig: instance GHC.Show.Show Hix.Data.GhciConfig.SourceDir
- Hix.Data.GhciConfig: instance GHC.Show.Show Hix.Data.GhciConfig.SourceDirs
- Hix.Data.GhciConfig: instance GHC.Show.Show Hix.Data.GhciConfig.Target
- Hix.Data.GhciConfig: newtype ComponentName
- Hix.Data.GhciConfig: newtype EnvName
- Hix.Data.GhciConfig: newtype EnvRunner
- Hix.Data.GhciConfig: newtype ModuleName
- Hix.Data.GhciConfig: newtype PackageName
- Hix.Data.GhciConfig: newtype PackagePath
- Hix.Data.GhciConfig: newtype SourceDir
- Hix.Data.GhciConfig: newtype SourceDirs
- Hix.Data.GhciConfig: type PackagesConfig = Map PackageName PackageConfig
- Hix.Preproc: Prelude :: ByteString -> ByteString -> Prelude
- Hix.Preproc: [$sel:preludeModule:Prelude] :: Prelude -> ByteString
- Hix.Preproc: [$sel:preludePackage:Prelude] :: Prelude -> ByteString
- Hix.Preproc: data Prelude
- Hix.Preproc: findPrelude :: [Mixin] -> Maybe Prelude
- Hix.Preproc: instance GHC.Show.Show Hix.Preproc.Prelude
- Hix.Preproc: pattern PreludeInclude :: ModuleName -> IncludeRenaming
- Hix.Preproc: pattern PreludeRenaming :: ModuleName -> ModuleRenaming
- Hix.Preproc: preludeRenaming :: [(b, ModuleName)] -> Maybe b
+ Hix.Bootstrap: Benchmark :: Text -> ComponentType
+ Hix.Bootstrap: CabalInfo :: Path Rel Dir -> GenericPackageDescription -> CabalInfo
+ Hix.Bootstrap: Executable :: Text -> ComponentType
+ Hix.Bootstrap: ExprAttr :: Text -> Expr -> ExprAttr
+ Hix.Bootstrap: ExprAttrNil :: ExprAttr
+ Hix.Bootstrap: ExprAttrs :: [ExprAttr] -> Expr
+ Hix.Bootstrap: ExprList :: [Expr] -> Expr
+ Hix.Bootstrap: ExprLit :: Text -> Expr
+ Hix.Bootstrap: ExprPrefix :: Text -> Expr -> Expr
+ Hix.Bootstrap: ExprString :: Text -> Expr
+ Hix.Bootstrap: HixComponent :: ComponentType -> [ExprAttr] -> Maybe PreludeWithVersion -> HixComponent
+ Hix.Bootstrap: HixPackage :: PackageName -> Path Rel Dir -> [ExprAttr] -> [ExprAttr] -> ExprAttr -> [HixComponent] -> HixPackage
+ Hix.Bootstrap: Library :: ComponentType
+ Hix.Bootstrap: PreludeWithVersion :: Prelude -> Maybe Dependency -> PreludeWithVersion
+ Hix.Bootstrap: Test :: Text -> ComponentType
+ Hix.Bootstrap: [$sel:components:HixPackage] :: HixPackage -> [HixComponent]
+ Hix.Bootstrap: [$sel:dep:PreludeWithVersion] :: PreludeWithVersion -> Maybe Dependency
+ Hix.Bootstrap: [$sel:description:HixPackage] :: HixPackage -> ExprAttr
+ Hix.Bootstrap: [$sel:info:CabalInfo] :: CabalInfo -> GenericPackageDescription
+ Hix.Bootstrap: [$sel:known:HixComponent] :: HixComponent -> [ExprAttr]
+ Hix.Bootstrap: [$sel:known:HixPackage] :: HixPackage -> [ExprAttr]
+ Hix.Bootstrap: [$sel:meta:HixPackage] :: HixPackage -> [ExprAttr]
+ Hix.Bootstrap: [$sel:name:ExprAttr] :: ExprAttr -> Text
+ Hix.Bootstrap: [$sel:name:HixPackage] :: HixPackage -> PackageName
+ Hix.Bootstrap: [$sel:path:CabalInfo] :: CabalInfo -> Path Rel Dir
+ Hix.Bootstrap: [$sel:prelude:HixComponent] :: HixComponent -> Maybe PreludeWithVersion
+ Hix.Bootstrap: [$sel:prelude:PreludeWithVersion] :: PreludeWithVersion -> Prelude
+ Hix.Bootstrap: [$sel:special:HixComponent] :: HixComponent -> ComponentType
+ Hix.Bootstrap: [$sel:src:HixPackage] :: HixPackage -> Path Rel Dir
+ Hix.Bootstrap: [$sel:value:ExprAttr] :: ExprAttr -> Expr
+ Hix.Bootstrap: bootstrapFiles :: BootstrapProjectConfig -> M [ProjectFile]
+ Hix.Bootstrap: bootstrapProject :: BootstrapProjectConfig -> M ()
+ Hix.Bootstrap: checkEmpty :: Text -> Expr -> ExprAttr
+ Hix.Bootstrap: class RenderCabalOption a
+ Hix.Bootstrap: convert :: CabalInfo -> HixPackage
+ Hix.Bootstrap: convertBenchmark :: UnqualComponentName -> Benchmark -> HixComponent
+ Hix.Bootstrap: convertComponent :: ComponentType -> BuildInfo -> HixComponent
+ Hix.Bootstrap: convertExecutable :: UnqualComponentName -> Executable -> HixComponent
+ Hix.Bootstrap: convertLibrary :: Library -> HixComponent
+ Hix.Bootstrap: convertTestsuite :: UnqualComponentName -> TestSuite -> HixComponent
+ Hix.Bootstrap: data CabalInfo
+ Hix.Bootstrap: data ComponentType
+ Hix.Bootstrap: data Expr
+ Hix.Bootstrap: data ExprAttr
+ Hix.Bootstrap: data HixComponent
+ Hix.Bootstrap: data HixPackage
+ Hix.Bootstrap: data PreludeWithVersion
+ Hix.Bootstrap: exprStrings :: [Text] -> Expr
+ Hix.Bootstrap: flake :: BootstrapProjectConfig -> [HixPackage] -> Expr
+ Hix.Bootstrap: flakePackage :: HixPackage -> ExprAttr
+ Hix.Bootstrap: ghcFlavour :: PerCompilerFlavor a -> a
+ Hix.Bootstrap: indent :: Functor t => Int -> t Text -> t Text
+ Hix.Bootstrap: instance Distribution.Pretty.Pretty a => Hix.Bootstrap.RenderCabalOption a
+ Hix.Bootstrap: instance GHC.Classes.Eq Hix.Bootstrap.CabalInfo
+ Hix.Bootstrap: instance GHC.Classes.Eq Hix.Bootstrap.ComponentType
+ Hix.Bootstrap: instance GHC.Classes.Eq Hix.Bootstrap.Expr
+ Hix.Bootstrap: instance GHC.Classes.Eq Hix.Bootstrap.ExprAttr
+ Hix.Bootstrap: instance GHC.Classes.Eq Hix.Bootstrap.HixComponent
+ Hix.Bootstrap: instance GHC.Classes.Eq Hix.Bootstrap.HixPackage
+ Hix.Bootstrap: instance GHC.Classes.Eq Hix.Bootstrap.PreludeWithVersion
+ Hix.Bootstrap: instance GHC.Generics.Generic Hix.Bootstrap.CabalInfo
+ Hix.Bootstrap: instance GHC.Generics.Generic Hix.Bootstrap.ComponentType
+ Hix.Bootstrap: instance GHC.Generics.Generic Hix.Bootstrap.Expr
+ Hix.Bootstrap: instance GHC.Generics.Generic Hix.Bootstrap.ExprAttr
+ Hix.Bootstrap: instance GHC.Generics.Generic Hix.Bootstrap.HixComponent
+ Hix.Bootstrap: instance GHC.Generics.Generic Hix.Bootstrap.HixPackage
+ Hix.Bootstrap: instance GHC.Generics.Generic Hix.Bootstrap.PreludeWithVersion
+ Hix.Bootstrap: instance GHC.Show.Show Hix.Bootstrap.CabalInfo
+ Hix.Bootstrap: instance GHC.Show.Show Hix.Bootstrap.ComponentType
+ Hix.Bootstrap: instance GHC.Show.Show Hix.Bootstrap.Expr
+ Hix.Bootstrap: instance GHC.Show.Show Hix.Bootstrap.ExprAttr
+ Hix.Bootstrap: instance GHC.Show.Show Hix.Bootstrap.HixComponent
+ Hix.Bootstrap: instance GHC.Show.Show Hix.Bootstrap.HixPackage
+ Hix.Bootstrap: instance GHC.Show.Show Hix.Bootstrap.PreludeWithVersion
+ Hix.Bootstrap: instance Hix.Bootstrap.RenderCabalOption Distribution.Utils.ShortText.ShortText
+ Hix.Bootstrap: instance Hix.Bootstrap.RenderCabalOption GHC.Base.String
+ Hix.Bootstrap: knownComponentKeys :: Maybe Prelude -> BuildInfo -> (Maybe PreludeWithVersion, [ExprAttr])
+ Hix.Bootstrap: knownPackageKeys :: PackageDescription -> [ExprAttr]
+ Hix.Bootstrap: mainPackage :: [HixPackage] -> ExprAttr
+ Hix.Bootstrap: metaPackageKeys :: PackageDescription -> [ExprAttr]
+ Hix.Bootstrap: mkAttrs :: [e -> ExprAttr] -> e -> [ExprAttr]
+ Hix.Bootstrap: multi :: RenderCabalOption a => Text -> (e -> [a]) -> e -> ExprAttr
+ Hix.Bootstrap: multiOpt :: RenderCabalOption a => Text -> (e -> Maybe [a]) -> e -> ExprAttr
+ Hix.Bootstrap: multiOrSingle :: forall a e. RenderCabalOption a => Text -> (e -> [a]) -> e -> ExprAttr
+ Hix.Bootstrap: notBase :: Dependency -> Bool
+ Hix.Bootstrap: notDefaultGhcOption :: String -> Bool
+ Hix.Bootstrap: readCabal :: Path Abs Dir -> Path Rel File -> M CabalInfo
+ Hix.Bootstrap: renderAttrs :: Int -> [ExprAttr] -> [Text]
+ Hix.Bootstrap: renderCabalOption :: RenderCabalOption a => a -> Text
+ Hix.Bootstrap: renderComponent :: HixComponent -> ExprAttr
+ Hix.Bootstrap: renderExpr :: Int -> Expr -> NonEmpty Text
+ Hix.Bootstrap: renderRootExpr :: Expr -> Text
+ Hix.Bootstrap: single :: RenderCabalOption a => Text -> (e -> a) -> e -> ExprAttr
+ Hix.Bootstrap: singleOpt :: RenderCabalOption a => Text -> (e -> Maybe a) -> e -> ExprAttr
+ Hix.Bootstrap: withSemicolon :: NonEmpty Text -> NonEmpty Text
+ Hix.Compat: parseString :: (ByteString -> ParseResult a) -> Verbosity -> String -> ByteString -> IO a
+ Hix.Compat: readGenericPackageDescription :: Verbosity -> FilePath -> IO GenericPackageDescription
+ Hix.Data.BootstrapProjectConfig: BootstrapProjectConfig :: HixUrl -> BootstrapProjectConfig
+ Hix.Data.BootstrapProjectConfig: [$sel:hixUrl:BootstrapProjectConfig] :: BootstrapProjectConfig -> HixUrl
+ Hix.Data.BootstrapProjectConfig: data BootstrapProjectConfig
+ Hix.Data.BootstrapProjectConfig: instance GHC.Classes.Eq Hix.Data.BootstrapProjectConfig.BootstrapProjectConfig
+ Hix.Data.BootstrapProjectConfig: instance GHC.Generics.Generic Hix.Data.BootstrapProjectConfig.BootstrapProjectConfig
+ Hix.Data.BootstrapProjectConfig: instance GHC.Show.Show Hix.Data.BootstrapProjectConfig.BootstrapProjectConfig
+ Hix.Data.ComponentConfig: ComponentConfig :: ComponentName -> SourceDirs -> Maybe EnvRunner -> [String] -> String -> [String] -> Maybe PreludeConfig -> ComponentConfig
+ Hix.Data.ComponentConfig: ComponentName :: Text -> ComponentName
+ Hix.Data.ComponentConfig: EnvName :: Text -> EnvName
+ Hix.Data.ComponentConfig: EnvRunner :: Path Abs File -> EnvRunner
+ Hix.Data.ComponentConfig: ModuleName :: Text -> ModuleName
+ Hix.Data.ComponentConfig: PackageConfig :: PackageName -> Path Rel Dir -> Map ComponentName ComponentConfig -> PackageConfig
+ Hix.Data.ComponentConfig: PackageName :: Text -> PackageName
+ Hix.Data.ComponentConfig: PackagePath :: Path Rel Dir -> PackagePath
+ Hix.Data.ComponentConfig: PreludeConfig :: PreludePackage -> ModuleName -> PreludeConfig
+ Hix.Data.ComponentConfig: PreludePackageName :: Text -> PreludePackage
+ Hix.Data.ComponentConfig: PreludePackageSpec :: Text -> PreludePackage
+ Hix.Data.ComponentConfig: SourceDir :: Path Rel Dir -> SourceDir
+ Hix.Data.ComponentConfig: SourceDirs :: [SourceDir] -> SourceDirs
+ Hix.Data.ComponentConfig: Target :: PackageConfig -> ComponentConfig -> Maybe SourceDir -> Target
+ Hix.Data.ComponentConfig: [$sel:component:Target] :: Target -> ComponentConfig
+ Hix.Data.ComponentConfig: [$sel:components:PackageConfig] :: PackageConfig -> Map ComponentName ComponentConfig
+ Hix.Data.ComponentConfig: [$sel:extensions:ComponentConfig] :: ComponentConfig -> [String]
+ Hix.Data.ComponentConfig: [$sel:ghcOptions:ComponentConfig] :: ComponentConfig -> [String]
+ Hix.Data.ComponentConfig: [$sel:language:ComponentConfig] :: ComponentConfig -> String
+ Hix.Data.ComponentConfig: [$sel:module_:PreludeConfig] :: PreludeConfig -> ModuleName
+ Hix.Data.ComponentConfig: [$sel:name:ComponentConfig] :: ComponentConfig -> ComponentName
+ Hix.Data.ComponentConfig: [$sel:name:PackageConfig] :: PackageConfig -> PackageName
+ Hix.Data.ComponentConfig: [$sel:name:PreludePackageName] :: PreludePackage -> Text
+ Hix.Data.ComponentConfig: [$sel:package:PreludeConfig] :: PreludeConfig -> PreludePackage
+ Hix.Data.ComponentConfig: [$sel:package:Target] :: Target -> PackageConfig
+ Hix.Data.ComponentConfig: [$sel:prelude:ComponentConfig] :: ComponentConfig -> Maybe PreludeConfig
+ Hix.Data.ComponentConfig: [$sel:runner:ComponentConfig] :: ComponentConfig -> Maybe EnvRunner
+ Hix.Data.ComponentConfig: [$sel:sourceDir:Target] :: Target -> Maybe SourceDir
+ Hix.Data.ComponentConfig: [$sel:sourceDirs:ComponentConfig] :: ComponentConfig -> SourceDirs
+ Hix.Data.ComponentConfig: [$sel:src:PackageConfig] :: PackageConfig -> Path Rel Dir
+ Hix.Data.ComponentConfig: [$sel:unComponentName:ComponentName] :: ComponentName -> Text
+ Hix.Data.ComponentConfig: [$sel:unEnvName:EnvName] :: EnvName -> Text
+ Hix.Data.ComponentConfig: [$sel:unModuleName:ModuleName] :: ModuleName -> Text
+ Hix.Data.ComponentConfig: [$sel:unPackageName:PackageName] :: PackageName -> Text
+ Hix.Data.ComponentConfig: [$sel:unPackagePath:PackagePath] :: PackagePath -> Path Rel Dir
+ Hix.Data.ComponentConfig: [$sel:unSourceDir:SourceDir] :: SourceDir -> Path Rel Dir
+ Hix.Data.ComponentConfig: [$sel:unSourceDirs:SourceDirs] :: SourceDirs -> [SourceDir]
+ Hix.Data.ComponentConfig: data ComponentConfig
+ Hix.Data.ComponentConfig: data PackageConfig
+ Hix.Data.ComponentConfig: data PreludeConfig
+ Hix.Data.ComponentConfig: data PreludePackage
+ Hix.Data.ComponentConfig: data Target
+ Hix.Data.ComponentConfig: instance Data.Aeson.Types.FromJSON.FromJSON Hix.Data.ComponentConfig.ComponentConfig
+ Hix.Data.ComponentConfig: instance Data.Aeson.Types.FromJSON.FromJSON Hix.Data.ComponentConfig.ComponentName
+ Hix.Data.ComponentConfig: instance Data.Aeson.Types.FromJSON.FromJSON Hix.Data.ComponentConfig.EnvName
+ Hix.Data.ComponentConfig: instance Data.Aeson.Types.FromJSON.FromJSON Hix.Data.ComponentConfig.EnvRunner
+ Hix.Data.ComponentConfig: instance Data.Aeson.Types.FromJSON.FromJSON Hix.Data.ComponentConfig.ModuleName
+ Hix.Data.ComponentConfig: instance Data.Aeson.Types.FromJSON.FromJSON Hix.Data.ComponentConfig.PackageConfig
+ Hix.Data.ComponentConfig: instance Data.Aeson.Types.FromJSON.FromJSON Hix.Data.ComponentConfig.PackageName
+ Hix.Data.ComponentConfig: instance Data.Aeson.Types.FromJSON.FromJSON Hix.Data.ComponentConfig.PackagePath
+ Hix.Data.ComponentConfig: instance Data.Aeson.Types.FromJSON.FromJSON Hix.Data.ComponentConfig.PreludeConfig
+ Hix.Data.ComponentConfig: instance Data.Aeson.Types.FromJSON.FromJSON Hix.Data.ComponentConfig.PreludePackage
+ Hix.Data.ComponentConfig: instance Data.Aeson.Types.FromJSON.FromJSON Hix.Data.ComponentConfig.SourceDir
+ Hix.Data.ComponentConfig: instance Data.Aeson.Types.FromJSON.FromJSON Hix.Data.ComponentConfig.SourceDirs
+ Hix.Data.ComponentConfig: instance Data.Aeson.Types.FromJSON.FromJSONKey Hix.Data.ComponentConfig.ComponentName
+ Hix.Data.ComponentConfig: instance Data.Aeson.Types.FromJSON.FromJSONKey Hix.Data.ComponentConfig.EnvName
+ Hix.Data.ComponentConfig: instance Data.Aeson.Types.FromJSON.FromJSONKey Hix.Data.ComponentConfig.ModuleName
+ Hix.Data.ComponentConfig: instance Data.Aeson.Types.FromJSON.FromJSONKey Hix.Data.ComponentConfig.PackageName
+ Hix.Data.ComponentConfig: instance Data.Aeson.Types.FromJSON.FromJSONKey Hix.Data.ComponentConfig.PackagePath
+ Hix.Data.ComponentConfig: instance Data.String.IsString Hix.Data.ComponentConfig.ComponentName
+ Hix.Data.ComponentConfig: instance Data.String.IsString Hix.Data.ComponentConfig.EnvName
+ Hix.Data.ComponentConfig: instance Data.String.IsString Hix.Data.ComponentConfig.ModuleName
+ Hix.Data.ComponentConfig: instance Data.String.IsString Hix.Data.ComponentConfig.PackageName
+ Hix.Data.ComponentConfig: instance GHC.Classes.Eq Hix.Data.ComponentConfig.ComponentConfig
+ Hix.Data.ComponentConfig: instance GHC.Classes.Eq Hix.Data.ComponentConfig.ComponentName
+ Hix.Data.ComponentConfig: instance GHC.Classes.Eq Hix.Data.ComponentConfig.EnvName
+ Hix.Data.ComponentConfig: instance GHC.Classes.Eq Hix.Data.ComponentConfig.EnvRunner
+ Hix.Data.ComponentConfig: instance GHC.Classes.Eq Hix.Data.ComponentConfig.ModuleName
+ Hix.Data.ComponentConfig: instance GHC.Classes.Eq Hix.Data.ComponentConfig.PackageConfig
+ Hix.Data.ComponentConfig: instance GHC.Classes.Eq Hix.Data.ComponentConfig.PackageName
+ Hix.Data.ComponentConfig: instance GHC.Classes.Eq Hix.Data.ComponentConfig.PackagePath
+ Hix.Data.ComponentConfig: instance GHC.Classes.Eq Hix.Data.ComponentConfig.PreludeConfig
+ Hix.Data.ComponentConfig: instance GHC.Classes.Eq Hix.Data.ComponentConfig.PreludePackage
+ Hix.Data.ComponentConfig: instance GHC.Classes.Eq Hix.Data.ComponentConfig.SourceDir
+ Hix.Data.ComponentConfig: instance GHC.Classes.Eq Hix.Data.ComponentConfig.SourceDirs
+ Hix.Data.ComponentConfig: instance GHC.Classes.Eq Hix.Data.ComponentConfig.Target
+ Hix.Data.ComponentConfig: instance GHC.Classes.Ord Hix.Data.ComponentConfig.ComponentName
+ Hix.Data.ComponentConfig: instance GHC.Classes.Ord Hix.Data.ComponentConfig.EnvName
+ Hix.Data.ComponentConfig: instance GHC.Classes.Ord Hix.Data.ComponentConfig.ModuleName
+ Hix.Data.ComponentConfig: instance GHC.Classes.Ord Hix.Data.ComponentConfig.PackageName
+ Hix.Data.ComponentConfig: instance GHC.Classes.Ord Hix.Data.ComponentConfig.PackagePath
+ Hix.Data.ComponentConfig: instance GHC.Generics.Generic Hix.Data.ComponentConfig.ComponentConfig
+ Hix.Data.ComponentConfig: instance GHC.Generics.Generic Hix.Data.ComponentConfig.ComponentName
+ Hix.Data.ComponentConfig: instance GHC.Generics.Generic Hix.Data.ComponentConfig.EnvName
+ Hix.Data.ComponentConfig: instance GHC.Generics.Generic Hix.Data.ComponentConfig.EnvRunner
+ Hix.Data.ComponentConfig: instance GHC.Generics.Generic Hix.Data.ComponentConfig.ModuleName
+ Hix.Data.ComponentConfig: instance GHC.Generics.Generic Hix.Data.ComponentConfig.PackageConfig
+ Hix.Data.ComponentConfig: instance GHC.Generics.Generic Hix.Data.ComponentConfig.PackageName
+ Hix.Data.ComponentConfig: instance GHC.Generics.Generic Hix.Data.ComponentConfig.PackagePath
+ Hix.Data.ComponentConfig: instance GHC.Generics.Generic Hix.Data.ComponentConfig.PreludeConfig
+ Hix.Data.ComponentConfig: instance GHC.Generics.Generic Hix.Data.ComponentConfig.PreludePackage
+ Hix.Data.ComponentConfig: instance GHC.Generics.Generic Hix.Data.ComponentConfig.SourceDir
+ Hix.Data.ComponentConfig: instance GHC.Generics.Generic Hix.Data.ComponentConfig.SourceDirs
+ Hix.Data.ComponentConfig: instance GHC.Generics.Generic Hix.Data.ComponentConfig.Target
+ Hix.Data.ComponentConfig: instance GHC.Show.Show Hix.Data.ComponentConfig.ComponentConfig
+ Hix.Data.ComponentConfig: instance GHC.Show.Show Hix.Data.ComponentConfig.ComponentName
+ Hix.Data.ComponentConfig: instance GHC.Show.Show Hix.Data.ComponentConfig.EnvName
+ Hix.Data.ComponentConfig: instance GHC.Show.Show Hix.Data.ComponentConfig.EnvRunner
+ Hix.Data.ComponentConfig: instance GHC.Show.Show Hix.Data.ComponentConfig.ModuleName
+ Hix.Data.ComponentConfig: instance GHC.Show.Show Hix.Data.ComponentConfig.PackageConfig
+ Hix.Data.ComponentConfig: instance GHC.Show.Show Hix.Data.ComponentConfig.PackageName
+ Hix.Data.ComponentConfig: instance GHC.Show.Show Hix.Data.ComponentConfig.PackagePath
+ Hix.Data.ComponentConfig: instance GHC.Show.Show Hix.Data.ComponentConfig.PreludeConfig
+ Hix.Data.ComponentConfig: instance GHC.Show.Show Hix.Data.ComponentConfig.PreludePackage
+ Hix.Data.ComponentConfig: instance GHC.Show.Show Hix.Data.ComponentConfig.SourceDir
+ Hix.Data.ComponentConfig: instance GHC.Show.Show Hix.Data.ComponentConfig.SourceDirs
+ Hix.Data.ComponentConfig: instance GHC.Show.Show Hix.Data.ComponentConfig.Target
+ Hix.Data.ComponentConfig: newtype ComponentName
+ Hix.Data.ComponentConfig: newtype EnvName
+ Hix.Data.ComponentConfig: newtype EnvRunner
+ Hix.Data.ComponentConfig: newtype ModuleName
+ Hix.Data.ComponentConfig: newtype PackageName
+ Hix.Data.ComponentConfig: newtype PackagePath
+ Hix.Data.ComponentConfig: newtype SourceDir
+ Hix.Data.ComponentConfig: newtype SourceDirs
+ Hix.Data.ComponentConfig: type PackagesConfig = Map PackageName PackageConfig
+ Hix.Data.Error: BootstrapError :: Text -> Error
+ Hix.Data.Error: NewError :: Text -> Error
+ Hix.Data.Error: printBootstrapError :: MonadIO m => Text -> m ()
+ Hix.Data.Error: printNewError :: MonadIO m => Text -> m ()
+ Hix.Data.NewProjectConfig: Author :: Text -> Author
+ Hix.Data.NewProjectConfig: HixUrl :: Text -> HixUrl
+ Hix.Data.NewProjectConfig: NewProjectConfig :: ProjectName -> Bool -> HixUrl -> Author -> NewProjectConfig
+ Hix.Data.NewProjectConfig: ProjectName :: Text -> ProjectName
+ Hix.Data.NewProjectConfig: [$sel:author:NewProjectConfig] :: NewProjectConfig -> Author
+ Hix.Data.NewProjectConfig: [$sel:hixUrl:NewProjectConfig] :: NewProjectConfig -> HixUrl
+ Hix.Data.NewProjectConfig: [$sel:name:NewProjectConfig] :: NewProjectConfig -> ProjectName
+ Hix.Data.NewProjectConfig: [$sel:packages:NewProjectConfig] :: NewProjectConfig -> Bool
+ Hix.Data.NewProjectConfig: [$sel:unAuthor:Author] :: Author -> Text
+ Hix.Data.NewProjectConfig: [$sel:unHixUrl:HixUrl] :: HixUrl -> Text
+ Hix.Data.NewProjectConfig: [$sel:unProjectName:ProjectName] :: ProjectName -> Text
+ Hix.Data.NewProjectConfig: data NewProjectConfig
+ Hix.Data.NewProjectConfig: instance Data.Default.Class.Default Hix.Data.NewProjectConfig.HixUrl
+ Hix.Data.NewProjectConfig: instance Data.String.IsString Hix.Data.NewProjectConfig.Author
+ Hix.Data.NewProjectConfig: instance Data.String.IsString Hix.Data.NewProjectConfig.HixUrl
+ Hix.Data.NewProjectConfig: instance Data.String.IsString Hix.Data.NewProjectConfig.ProjectName
+ Hix.Data.NewProjectConfig: instance GHC.Classes.Eq Hix.Data.NewProjectConfig.Author
+ Hix.Data.NewProjectConfig: instance GHC.Classes.Eq Hix.Data.NewProjectConfig.HixUrl
+ Hix.Data.NewProjectConfig: instance GHC.Classes.Eq Hix.Data.NewProjectConfig.NewProjectConfig
+ Hix.Data.NewProjectConfig: instance GHC.Classes.Eq Hix.Data.NewProjectConfig.ProjectName
+ Hix.Data.NewProjectConfig: instance GHC.Classes.Ord Hix.Data.NewProjectConfig.Author
+ Hix.Data.NewProjectConfig: instance GHC.Classes.Ord Hix.Data.NewProjectConfig.HixUrl
+ Hix.Data.NewProjectConfig: instance GHC.Classes.Ord Hix.Data.NewProjectConfig.ProjectName
+ Hix.Data.NewProjectConfig: instance GHC.Generics.Generic Hix.Data.NewProjectConfig.Author
+ Hix.Data.NewProjectConfig: instance GHC.Generics.Generic Hix.Data.NewProjectConfig.HixUrl
+ Hix.Data.NewProjectConfig: instance GHC.Generics.Generic Hix.Data.NewProjectConfig.NewProjectConfig
+ Hix.Data.NewProjectConfig: instance GHC.Generics.Generic Hix.Data.NewProjectConfig.ProjectName
+ Hix.Data.NewProjectConfig: instance GHC.Show.Show Hix.Data.NewProjectConfig.Author
+ Hix.Data.NewProjectConfig: instance GHC.Show.Show Hix.Data.NewProjectConfig.HixUrl
+ Hix.Data.NewProjectConfig: instance GHC.Show.Show Hix.Data.NewProjectConfig.NewProjectConfig
+ Hix.Data.NewProjectConfig: instance GHC.Show.Show Hix.Data.NewProjectConfig.ProjectName
+ Hix.Data.NewProjectConfig: newtype Author
+ Hix.Data.NewProjectConfig: newtype HixUrl
+ Hix.Data.NewProjectConfig: newtype ProjectName
+ Hix.Data.PreprocConfig: PreprocConfig :: PackagesConfig -> PreprocConfig
+ Hix.Data.PreprocConfig: [$sel:packages:PreprocConfig] :: PreprocConfig -> PackagesConfig
+ Hix.Data.PreprocConfig: data PreprocConfig
+ Hix.Data.PreprocConfig: instance Data.Aeson.Types.FromJSON.FromJSON Hix.Data.PreprocConfig.PreprocConfig
+ Hix.Data.PreprocConfig: instance GHC.Classes.Eq Hix.Data.PreprocConfig.PreprocConfig
+ Hix.Data.PreprocConfig: instance GHC.Generics.Generic Hix.Data.PreprocConfig.PreprocConfig
+ Hix.Data.PreprocConfig: instance GHC.Show.Show Hix.Data.PreprocConfig.PreprocConfig
+ Hix.Data.ProjectFile: ProjectFile :: Path Rel File -> Text -> ProjectFile
+ Hix.Data.ProjectFile: [$sel:content:ProjectFile] :: ProjectFile -> Text
+ Hix.Data.ProjectFile: [$sel:path:ProjectFile] :: ProjectFile -> Path Rel File
+ Hix.Data.ProjectFile: createFile :: ProjectFile -> M ()
+ Hix.Data.ProjectFile: data ProjectFile
+ Hix.Data.ProjectFile: instance GHC.Classes.Eq Hix.Data.ProjectFile.ProjectFile
+ Hix.Data.ProjectFile: instance GHC.Generics.Generic Hix.Data.ProjectFile.ProjectFile
+ Hix.Data.ProjectFile: instance GHC.Show.Show Hix.Data.ProjectFile.ProjectFile
+ Hix.Monad: noteBootstrap :: Text -> Maybe a -> M a
+ Hix.Monad: noteNew :: Text -> Maybe a -> M a
+ Hix.New: appMainModule :: Text -> Text
+ Hix.New: flake :: NewProjectConfig -> Text
+ Hix.New: libModule :: NewProjectConfig -> Text -> Text
+ Hix.New: license :: Author -> Text
+ Hix.New: nameTestModule :: NewProjectConfig -> Text -> Text
+ Hix.New: newProject :: NewProjectConfig -> M ()
+ Hix.New: newProjectFiles :: NewProjectConfig -> M [ProjectFile]
+ Hix.New: testMainModule :: Text -> Text
+ Hix.Options: BootstrapCmd :: BootstrapOptions -> Command
+ Hix.Options: BootstrapOptions :: BootstrapProjectConfig -> BootstrapOptions
+ Hix.Options: NewCmd :: NewOptions -> Command
+ Hix.Options: NewOptions :: NewProjectConfig -> NewOptions
+ Hix.Options: [$sel:config:BootstrapOptions] :: BootstrapOptions -> BootstrapProjectConfig
+ Hix.Options: [$sel:config:NewOptions] :: NewOptions -> NewProjectConfig
+ Hix.Options: bootstrapParser :: Parser BootstrapOptions
+ Hix.Options: data BootstrapOptions
+ Hix.Options: data NewOptions
+ Hix.Options: instance GHC.Classes.Eq Hix.Options.BootstrapOptions
+ Hix.Options: instance GHC.Classes.Eq Hix.Options.NewOptions
+ Hix.Options: instance GHC.Generics.Generic Hix.Options.BootstrapOptions
+ Hix.Options: instance GHC.Generics.Generic Hix.Options.NewOptions
+ Hix.Options: instance GHC.Show.Show Hix.Options.BootstrapOptions
+ Hix.Options: instance GHC.Show.Show Hix.Options.NewOptions
+ Hix.Options: newParser :: Parser NewOptions
+ Hix.Prelude: Prelude :: String -> String -> Prelude
+ Hix.Prelude: [$sel:preludeModule:Prelude] :: Prelude -> String
+ Hix.Prelude: [$sel:preludePackage:Prelude] :: Prelude -> String
+ Hix.Prelude: data Prelude
+ Hix.Prelude: findPrelude :: [Mixin] -> Maybe Prelude
+ Hix.Prelude: instance GHC.Classes.Eq Hix.Prelude.Prelude
+ Hix.Prelude: instance GHC.Show.Show Hix.Prelude.Prelude
+ Hix.Prelude: pattern PreludeInclude :: ModuleName -> IncludeRenaming
+ Hix.Prelude: pattern PreludeRenaming :: ModuleName -> ModuleRenaming
+ Hix.Prelude: preludeRenaming :: [(b, ModuleName)] -> Maybe b

Files

LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2020 Torsten Schmits+Copyright (c) 2023 Torsten Schmits  Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
hix.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           hix-version:        0.2.0.0+version:        0.4.0.0 synopsis:       Haskell/Nix development build tools description:    See https://hackage.haskell.org/package/hix/docs/Hix.html category:       Build@@ -25,17 +25,26 @@ library   exposed-modules:       Hix+      Hix.Bootstrap       Hix.Cabal+      Hix.Compat       Hix.Component+      Hix.Data.BootstrapProjectConfig+      Hix.Data.ComponentConfig       Hix.Data.Error       Hix.Data.GhciConfig       Hix.Data.GhciTest+      Hix.Data.NewProjectConfig+      Hix.Data.PreprocConfig+      Hix.Data.ProjectFile       Hix.Env       Hix.Ghci       Hix.Json       Hix.Monad+      Hix.New       Hix.Options       Hix.Optparse+      Hix.Prelude       Hix.Preproc   hs-source-dirs:       lib@@ -79,6 +88,7 @@       Cabal     , aeson >=2.0 && <2.2     , base ==4.*+    , casing >=0.1.4 && <0.2     , exon ==1.4.*     , extra ==1.7.*     , filepattern ==0.1.*@@ -152,9 +162,11 @@   type: exitcode-stdio-1.0   main-is: Main.hs   other-modules:+      Hix.Test.BootstrapTest       Hix.Test.CabalFile       Hix.Test.CabalTest       Hix.Test.GhciTest+      Hix.Test.NewTest       Hix.Test.PreprocTest   hs-source-dirs:       test
lib/Hix.hs view
@@ -2,13 +2,23 @@  import Path.IO (getCurrentDir) -import Hix.Data.Error (Error (..), printEnvError, printFatalError, printGhciError, printPreprocError)+import Hix.Bootstrap (bootstrapProject)+import Hix.Data.Error (+  Error (..),+  printBootstrapError,+  printEnvError,+  printFatalError,+  printGhciError,+  printNewError,+  printPreprocError,+  ) import Hix.Env (printEnvRunner) import Hix.Ghci (printGhciCmdline, printGhcidCmdline) import Hix.Monad (M, runM)+import Hix.New (newProject) import qualified Hix.Options as Options import Hix.Options (-  Command (EnvRunner, GhciCmd, GhcidCmd, Preproc),+  Command (BootstrapCmd, EnvRunner, GhciCmd, GhcidCmd, NewCmd, Preproc),   GlobalOptions (GlobalOptions),   Options (Options),   parseCli,@@ -24,6 +34,8 @@   PreprocError err -> printPreprocError err   EnvError err -> printEnvError err   GhciError err -> printGhciError err+  NewError err -> printNewError err+  BootstrapError err -> printBootstrapError err   NoMatch msg | fromMaybe False verbose -> printPreprocError msg   NoMatch _ -> unit   Fatal err -> printFatalError err@@ -34,6 +46,8 @@   EnvRunner opts -> printEnvRunner opts.options   GhcidCmd opts -> printGhcidCmdline opts   GhciCmd opts -> printGhciCmdline opts+  NewCmd opts -> newProject opts.config+  BootstrapCmd opts -> bootstrapProject opts.config  main :: IO () main = do
+ lib/Hix/Bootstrap.hs view
@@ -0,0 +1,401 @@+module Hix.Bootstrap where++import Control.Monad.Trans.Class (lift)+import Control.Monad.Trans.Reader (ask)+import Data.List.NonEmpty ((<|))+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, pretty)+import Distribution.Simple (Dependency (Dependency), depVerRange)+import Distribution.Types.PackageDescription (license)+import Distribution.Utils.ShortText (ShortText, fromShortText)+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.ComponentConfig+import Hix.Data.ComponentConfig (PackageName (PackageName))+import Hix.Data.Error (pathText, tryIO)+import qualified Hix.Data.NewProjectConfig+import qualified Hix.Data.ProjectFile+import Hix.Data.ProjectFile (ProjectFile (ProjectFile), createFile)+import qualified Hix.Monad+import Hix.Monad (Env (Env), M, noteBootstrap)+import qualified Hix.Prelude+import Hix.Prelude (Prelude, findPrelude)++data ExprAttr =+  ExprAttr {+    name :: Text,+    value :: Expr+  }+  |+  ExprAttrNil+  deriving stock (Eq, Show, Generic)++data Expr =+  ExprString Text+  |+  ExprLit Text+  |+  ExprList [Expr]+  |+  ExprAttrs [ExprAttr]+  |+  ExprPrefix Text Expr+  deriving stock (Eq, Show, Generic)++exprStrings :: [Text] -> Expr+exprStrings =+  ExprList . fmap ExprString++data CabalInfo =+  CabalInfo {+    path :: Path Rel Dir,+    info :: GenericPackageDescription+  }+  deriving stock (Eq, Show, Generic)++data ComponentType =+  Library+  |+  Executable Text+  |+  Benchmark Text+  |+  Test Text+  deriving stock (Eq, Show, Generic)++data PreludeWithVersion =+  PreludeWithVersion {+    prelude :: Prelude,+    dep :: Maybe Dependency+  }+  deriving stock (Eq, Show, Generic)++data HixComponent =+  HixComponent {+    special :: ComponentType,+    known :: [ExprAttr],+    prelude :: Maybe PreludeWithVersion+  }+  deriving stock (Eq, Show, Generic)++data HixPackage =+  HixPackage {+    name :: PackageName,+    src :: Path Rel Dir,+    known :: [ExprAttr],+    meta :: [ExprAttr],+    description :: ExprAttr,+    components :: [HixComponent]+  }+  deriving stock (Eq, Show, Generic)++indent ::+  Functor t =>+  Int ->+  t Text ->+  t Text+indent n =+  fmap (Text.replicate n " " <>)++withSemicolon :: NonEmpty Text -> NonEmpty Text+withSemicolon = \case+  e :| [] ->+    [e <> ";"]+  h :| h1 : t -> h <| withSemicolon (h1 :| t)++renderAttrs :: Int -> [ExprAttr] -> [Text]+renderAttrs ind attrs =+  attrs >>= \case+    ExprAttr k v ->+      case renderExpr ind v of+        e :| [] -> [[exon|#{k} = #{e};|]]+        h :| (h1 : t) -> [exon|#{k} = #{h}|] : toList (withSemicolon (h1 :| t))+    ExprAttrNil ->+      []++renderExpr :: Int -> Expr -> NonEmpty Text+renderExpr ind = \case+  ExprString s -> indent ind [[exon|"#{s}"|]]+  ExprLit e -> [e]+  ExprList l -> "[" :| (indent (ind + 2) (toList . renderExpr ind =<< l)) ++ ["]"]+  ExprAttrs a -> case renderAttrs ind a of+    [] -> ["{};"]+    as -> "{" :| indent (ind + 2) as ++ ["}"]+  ExprPrefix p (renderExpr ind -> h :| t) ->+    [exon|#{p} #{h}|] :| t++renderRootExpr :: Expr -> Text+renderRootExpr =+  Text.unlines . toList . renderExpr 0++readCabal ::+  Path Abs Dir ->+  Path Rel File ->+  M CabalInfo+readCabal root path = do+  info <- liftIO (readGenericPackageDescription Cabal.verbose (toFilePath (root </> path)))+  pure CabalInfo {path = dir, info}+  where+    dir = parent path++class RenderCabalOption a where+  renderCabalOption :: a -> Text++instance {-# overlappable #-} Pretty a => RenderCabalOption a where+  renderCabalOption = show . pretty++instance RenderCabalOption ShortText where+  renderCabalOption = toText . fromShortText++instance RenderCabalOption String where+  renderCabalOption = toText++checkEmpty ::+  Text ->+  Expr ->+  ExprAttr+checkEmpty key = \case+  ExprString value | Text.null value ->+    ExprAttrNil+  ExprList value | null value ->+    ExprAttrNil+  value ->+    ExprAttr key value++singleOpt ::+  RenderCabalOption a =>+  Text ->+  (e -> Maybe a) ->+  e ->+  ExprAttr+singleOpt key get entity =+  maybe ExprAttrNil (checkEmpty key . ExprString) (renderCabalOption <$> get entity)++single ::+  RenderCabalOption a =>+  Text ->+  (e -> a) ->+  e ->+  ExprAttr+single key get =+  singleOpt key (Just . get)++multiOpt ::+  RenderCabalOption a =>+  Text ->+  (e -> Maybe [a]) ->+  e ->+  ExprAttr+multiOpt key get entity =+  maybe ExprAttrNil (checkEmpty key . exprStrings) (fmap renderCabalOption <$> get entity)++multi ::+  RenderCabalOption a =>+  Text ->+  (e -> [a]) ->+  e ->+  ExprAttr+multi key get =+  multiOpt key (Just . get)++multiOrSingle ::+  ∀ a e .+  RenderCabalOption a =>+  Text ->+  (e -> [a]) ->+  e ->+  ExprAttr+multiOrSingle key get entity =+  check (renderCabalOption <$> get entity)+  where+    check :: [Text] -> ExprAttr+    check [] = ExprAttrNil+    check [sing] = ExprAttr key (ExprString sing)+    check values = ExprAttr key (exprStrings values)++mkAttrs :: [e -> ExprAttr] -> e -> [ExprAttr]+mkAttrs a e =+  (fmap ($ e) a)++-- TODO extract version and put it in a file+knownPackageKeys :: PackageDescription -> [ExprAttr]+knownPackageKeys =+  mkAttrs [+    single "author" (.author),+    single "build-type" buildType,+    single "copyright" (.copyright),+    single "license" license,+    singleOpt "license-file" (head . licenseFiles)+  ]++metaPackageKeys :: PackageDescription -> [ExprAttr]+metaPackageKeys =+  mkAttrs [+    single "maintainer" (.maintainer),+    single "homepage" (.homepage),+    single "synopsis" (.synopsis)+  ]++ghcFlavour :: PerCompilerFlavor a -> a+ghcFlavour (PerCompilerFlavor a _) = a++notDefaultGhcOption :: String -> Bool+notDefaultGhcOption = \case+  "-threaded" -> False+  "-rtsopts" -> False+  "-with-rtsopts=-N" -> False+  _ -> True++knownComponentKeys :: Maybe Prelude -> BuildInfo -> (Maybe PreludeWithVersion, [ExprAttr])+knownComponentKeys prelude info =+  (preludeWithVersion, vals)+  where+    vals =+      mkAttrs [+        multi "dependencies" (const deps),+        multi "default-extensions" (.defaultExtensions),+        multiOrSingle "source-dirs" (.hsSourceDirs),+        singleOpt "language" (.defaultLanguage),+        multi "ghc-options" (filter notDefaultGhcOption . ghcFlavour . (.options))+      ] info+    (preludeWithVersion, deps)+      | Just p <- prelude =+        let (v, res) = foldl (amendPrelude p) (Nothing, []) info.targetBuildDepends+        in (Just (PreludeWithVersion p v), res)+      | otherwise =+        (Nothing, filter notBase (info.targetBuildDepends))+    amendPrelude p (Nothing, ds) dep@(Dependency (Cabal.unPackageName -> dname) _ _) | dname == p.preludePackage =+      (Just dep, ds)+    amendPrelude _ (v, ds) d = (v, d : ds)++notBase :: Cabal.Dependency -> Bool+notBase = \case+  Cabal.Dependency "base" _ _ -> False+  _ -> True++convertComponent :: ComponentType -> BuildInfo -> HixComponent+convertComponent special info =+  HixComponent {..}+  where+    (prelude, known) = knownComponentKeys preludeBasic info+    preludeBasic = findPrelude info.mixins++convertLibrary :: Cabal.Library -> HixComponent+convertLibrary lib =+  convertComponent Library lib.libBuildInfo++convertExecutable :: UnqualComponentName -> Cabal.Executable -> HixComponent+convertExecutable name exe =+  convertComponent (Executable (toText (unUnqualComponentName name))) exe.buildInfo++convertTestsuite :: UnqualComponentName -> Cabal.TestSuite -> HixComponent+convertTestsuite name test =+  convertComponent (Test (toText (unUnqualComponentName name))) test.testBuildInfo++convertBenchmark :: UnqualComponentName -> Cabal.Benchmark -> HixComponent+convertBenchmark name bench =+  convertComponent (Benchmark (toText (unUnqualComponentName name))) bench.benchmarkBuildInfo++convert :: CabalInfo -> HixPackage+convert cinfo =+  HixPackage {+    name = PackageName (toText (unPackageName pkg.package.pkgName)),+    src = cinfo.path,+    known = knownPackageKeys pkg,+    meta = metaPackageKeys pkg,+    description = single "description" (.description) pkg,+    components+  }+  where+    components =+      maybeToList (convertLibrary . (.condTreeData) <$> info.condLibrary)+      <>+      (uncurry convertExecutable . second (.condTreeData) <$> info.condExecutables)+      <>+      (uncurry convertTestsuite . second (.condTreeData) <$> info.condTestSuites)+      <>+      (uncurry convertBenchmark . second (.condTreeData) <$> info.condBenchmarks)+    pkg = info.packageDescription+    info = cinfo.info++renderComponent :: HixComponent -> ExprAttr+renderComponent HixComponent {..} =+  ExprAttr key cabalConfig+  where+    cabalConfig = ExprAttrs (known <> foldMap preludeAttrs prelude)+    preludeAttrs p =+      [ExprAttr "prelude" (ExprAttrs [+        ExprAttr "package" (preludePackageAttrs p),+        ExprAttr "module" (ExprString (toText p.prelude.preludeModule))+      ])]+    preludePackageAttrs p+      | Just dep <- p.dep =+        ExprAttrs [+          (ExprAttr "name" (ExprString (toText p.prelude.preludePackage))),+          (ExprAttr "version" (ExprString (show (pretty (depVerRange dep)))))+        ]+      | otherwise = ExprString (toText p.prelude.preludePackage)+    key = case special of+      Library -> "library"+      Executable name -> [exon|executables.#{name}|]+      Test name -> [exon|tests.#{name}|]+      Benchmark name -> [exon|benchmarks.#{name}|]++flakePackage :: HixPackage -> ExprAttr+flakePackage pkg =+  ExprAttr name attrs+  where+    attrs = ExprAttrs (src : pkg.description : (ExprAttr "cabal" cabalConfig : comps))+    name = pkg.name.unPackageName+    src = ExprAttr "src" (ExprLit [exon|./#{Text.dropWhileEnd ('/' ==) (pathText pkg.src)}|])+    cabalConfig = ExprAttrs (pkg.known <> (if null pkg.meta then [] else [ExprAttr "meta" (ExprAttrs pkg.meta)]))+    comps = renderComponent <$> pkg.components++mainPackage :: [HixPackage] -> ExprAttr+mainPackage = \case+  pkg : _ : _ -> ExprAttr "main" (ExprString pkg.name.unPackageName)+  _ -> ExprAttrNil++flake :: BootstrapProjectConfig -> [HixPackage] -> Expr+flake conf pkgs =+  ExprAttrs [+    (ExprAttr "description" (ExprString "A Haskell project")),+    (ExprAttr "inputs.hix.url" (ExprString conf.hixUrl.unHixUrl)),+    (ExprAttr "outputs" (ExprPrefix "{hix, ...}: hix.lib.flake" (ExprAttrs [+      (ExprAttr "packages" (ExprAttrs (flakePackage <$> pkgs))),+      mainPackage pkgs+    ])))+  ]++bootstrapFiles :: BootstrapProjectConfig -> M [ProjectFile]+bootstrapFiles conf = do+  Env {root} <- ask+  cabals <- paths =<< lift (tryIO (getDirectoryFilesIgnore (toFilePath root) ["**/*.cabal"] ["dist-newstyle/**"]))+  pkgs <- fmap convert <$> traverse (readCabal root) cabals+  pure [+    ProjectFile {path = [relfile|flake.nix|], content = renderRootExpr (flake conf pkgs)}+    ]+  where+    paths = traverse (noteBootstrap "File path error" . parseRelFile)++bootstrapProject :: BootstrapProjectConfig -> M ()+bootstrapProject conf =+  traverse_ createFile =<< bootstrapFiles conf
lib/Hix/Cabal.hs view
@@ -1,14 +1,7 @@-{-# language CPP #-}- module Hix.Cabal where  import Control.Monad.Trans.Except (ExceptT (ExceptT), throwE) import Distribution.PackageDescription (BuildInfo (..), GenericPackageDescription (..))-#if MIN_VERSION_Cabal(3,8,0)-import Distribution.Simple.PackageDescription (readGenericPackageDescription)-#else-import Distribution.PackageDescription.Parsec (readGenericPackageDescription)-#endif import Distribution.Types.Benchmark (benchmarkBuildInfo) import Distribution.Types.CondTree (CondTree (..)) import qualified Distribution.Types.Executable as Executable@@ -17,7 +10,6 @@ import Distribution.Utils.Path (getSymbolicPath) import qualified Distribution.Verbosity as Cabal import Exon (exon)-import Hix.Data.Error (Error (..), pathText, sourceError) import Path (   Abs,   Dir,@@ -35,6 +27,9 @@   ) import System.FilePattern.Directory (getDirectoryFiles) import System.IO.Error (tryIOError)++import Hix.Compat (readGenericPackageDescription)+import Hix.Data.Error (Error (..), pathText, sourceError)  noMatch :: Text -> Path b File -> ExceptT Error IO a noMatch reason source =
+ lib/Hix/Compat.hs view
@@ -0,0 +1,18 @@+{-# language CPP #-}++module Hix.Compat (+  parseString,+  readGenericPackageDescription,+) where++#if MIN_VERSION_Cabal(3,8,0)+import Distribution.Simple.PackageDescription (readGenericPackageDescription)+#else+import Distribution.PackageDescription.Parsec (readGenericPackageDescription)+#endif++#if MIN_VERSION_Cabal(3,8,0)+import Distribution.Simple.PackageDescription (parseString)+#else+import Distribution.Fields.ParseResult (parseString)+#endif
lib/Hix/Component.hs view
@@ -8,9 +8,8 @@ import Exon (exon) import Path (Abs, Dir, File, Path, Rel, SomeBase (Abs, Rel), isProperPrefixOf, stripProperPrefix) -import Hix.Data.Error (pathText)-import qualified Hix.Data.GhciConfig as GhciConfig-import Hix.Data.GhciConfig (+import qualified Hix.Data.ComponentConfig+import Hix.Data.ComponentConfig (   ComponentConfig,   PackageConfig (PackageConfig),   PackageName (PackageName),@@ -18,6 +17,7 @@   SourceDir (SourceDir),   Target (Target),   )+import Hix.Data.Error (pathText) import qualified Hix.Monad as Monad import Hix.Monad (Env (Env), M, noteEnv) import qualified Hix.Options as Options
+ lib/Hix/Data/BootstrapProjectConfig.hs view
@@ -0,0 +1,9 @@+module Hix.Data.BootstrapProjectConfig where++import Hix.Data.NewProjectConfig (HixUrl)++data BootstrapProjectConfig =+  BootstrapProjectConfig {+    hixUrl :: HixUrl+  }+  deriving stock (Eq, Show, Generic)
+ lib/Hix/Data/ComponentConfig.hs view
@@ -0,0 +1,108 @@+module Hix.Data.ComponentConfig where++import Data.Aeson (FromJSON (parseJSON), FromJSONKey, withObject, (.:))+import Path (Abs, Dir, File, Path, Rel)++newtype PackagePath =+  PackagePath { unPackagePath :: Path Rel Dir }+  deriving stock (Eq, Show, Ord, Generic)+  deriving newtype (FromJSON, FromJSONKey)++newtype SourceDir =+  SourceDir { unSourceDir :: Path Rel Dir }+  deriving stock (Eq, Show, Generic)+  deriving newtype (FromJSON)++newtype SourceDirs =+  SourceDirs { unSourceDirs :: [SourceDir] }+  deriving stock (Eq, Show, Generic)++instance FromJSON SourceDirs where+  parseJSON v =+    (SourceDirs <$> parseJSON v)+    <|>+    (SourceDirs . pure <$> parseJSON v)++newtype PackageName =+  PackageName { unPackageName :: Text }+  deriving stock (Eq, Show, Generic)+  deriving newtype (IsString, Ord, FromJSON, FromJSONKey)++newtype ModuleName =+  ModuleName { unModuleName :: Text }+  deriving stock (Eq, Show, Generic)+  deriving newtype (IsString, Ord, FromJSON, FromJSONKey)++newtype ComponentName =+  ComponentName { unComponentName :: Text }+  deriving stock (Eq, Show, Generic)+  deriving newtype (IsString, Ord, FromJSON, FromJSONKey)++newtype EnvName =+  EnvName { unEnvName :: Text }+  deriving stock (Eq, Show, Generic)+  deriving newtype (IsString, Ord, FromJSON, FromJSONKey)++newtype EnvRunner =+  EnvRunner (Path Abs File)+  deriving stock (Eq, Show, Generic)+  deriving newtype (FromJSON)++data PreludePackage =+  PreludePackageName Text+  |+  PreludePackageSpec { name :: Text }+  deriving stock (Eq, Show, Generic)++instance FromJSON PreludePackage where+  parseJSON v =+    hpackStruct v <|> plainName+    where+      hpackStruct = withObject "PreludePackageSpec" \ o -> o .: "name"+      plainName = PreludePackageName <$> parseJSON v++data PreludeConfig =+  PreludeConfig {+    package :: PreludePackage,+    module_ :: ModuleName+  }+  deriving stock (Eq, Show, Generic)++instance FromJSON PreludeConfig where+  parseJSON =+    withObject "PreludeConfig" \ o -> do+      package <- o .: "package"+      module_ <- o .: "module"+      pure PreludeConfig {..}++data ComponentConfig =+  ComponentConfig {+    name :: ComponentName,+    sourceDirs :: SourceDirs,+    runner :: Maybe EnvRunner,+    extensions :: [String],+    language :: String,+    ghcOptions :: [String],+    prelude :: Maybe PreludeConfig+  }+  deriving stock (Eq, Show, Generic)+  deriving anyclass (FromJSON)++data PackageConfig =+  PackageConfig {+    name :: PackageName,+    src :: Path Rel Dir,+    components :: Map ComponentName ComponentConfig+  }+  deriving stock (Eq, Show, Generic)+  deriving anyclass (FromJSON)++type PackagesConfig = Map PackageName PackageConfig++data Target =+  Target {+    package :: PackageConfig,+    component :: ComponentConfig,+    sourceDir :: Maybe SourceDir+  }+  deriving stock (Eq, Show, Generic)
lib/Hix/Data/Error.hs view
@@ -14,6 +14,10 @@   |   GhciError Text   |+  NewError Text+  |+  BootstrapError Text+  |   NoMatch Text   |   Fatal Text@@ -43,6 +47,20 @@   m () printGhciError msg =   liftIO (Text.hPutStrLn stderr [exon|>>> Invalid ghci config: #{msg}|])++printNewError ::+  MonadIO m =>+  Text ->+  m ()+printNewError msg =+  liftIO (Text.hPutStrLn stderr [exon|>>> Can't create new project: #{msg}|])++printBootstrapError ::+  MonadIO m =>+  Text ->+  m ()+printBootstrapError msg =+  liftIO (Text.hPutStrLn stderr [exon|>>> Can't bootstrap project: #{msg}|])  printFatalError ::   MonadIO m =>
lib/Hix/Data/GhciConfig.hs view
@@ -1,110 +1,9 @@ module Hix.Data.GhciConfig where -import Data.Aeson (FromJSON (parseJSON), FromJSONKey, withObject, (.:))+import Data.Aeson (FromJSON, FromJSONKey) import GHC.Exts (IsList)-import Path (Abs, Dir, File, Path, Rel) -newtype PackagePath =-  PackagePath { unPackagePath :: Path Rel Dir }-  deriving stock (Eq, Show, Ord, Generic)-  deriving newtype (FromJSON, FromJSONKey)--newtype SourceDir =-  SourceDir { unSourceDir :: Path Rel Dir }-  deriving stock (Eq, Show, Generic)-  deriving newtype (FromJSON)--newtype SourceDirs =-  SourceDirs { unSourceDirs :: [SourceDir] }-  deriving stock (Eq, Show, Generic)--instance FromJSON SourceDirs where-  parseJSON v =-    (SourceDirs <$> parseJSON v)-    <|>-    (SourceDirs . pure <$> parseJSON v)--newtype PackageName =-  PackageName { unPackageName :: Text }-  deriving stock (Eq, Show, Generic)-  deriving newtype (IsString, Ord, FromJSON, FromJSONKey)--newtype ModuleName =-  ModuleName { unModuleName :: Text }-  deriving stock (Eq, Show, Generic)-  deriving newtype (IsString, Ord, FromJSON, FromJSONKey)--newtype ComponentName =-  ComponentName { unComponentName :: Text }-  deriving stock (Eq, Show, Generic)-  deriving newtype (IsString, Ord, FromJSON, FromJSONKey)--newtype EnvName =-  EnvName { unEnvName :: Text }-  deriving stock (Eq, Show, Generic)-  deriving newtype (IsString, Ord, FromJSON, FromJSONKey)--newtype EnvRunner =-  EnvRunner (Path Abs File)-  deriving stock (Eq, Show, Generic)-  deriving newtype (FromJSON)--data PreludePackage =-  PreludePackageName Text-  |-  PreludePackageSpec { name :: Text }-  deriving stock (Eq, Show, Generic)--instance FromJSON PreludePackage where-  parseJSON v =-    hpackStruct v <|> plainName-    where-      hpackStruct = withObject "PreludePackageSpec" \ o -> o .: "name"-      plainName = PreludePackageName <$> parseJSON v--data PreludeConfig =-  PreludeConfig {-    package :: PreludePackage,-    module_ :: ModuleName-  }-  deriving stock (Eq, Show, Generic)--instance FromJSON PreludeConfig where-  parseJSON =-    withObject "PreludeConfig" \ o -> do-      package <- o .: "package"-      module_ <- o .: "module"-      pure PreludeConfig {..}--data ComponentConfig =-  ComponentConfig {-    name :: ComponentName,-    sourceDirs :: SourceDirs,-    runner :: Maybe EnvRunner,-    extensions :: [String],-    language :: String,-    ghcOptions :: [String],-    prelude :: Maybe PreludeConfig-  }-  deriving stock (Eq, Show, Generic)-  deriving anyclass (FromJSON)--data PackageConfig =-  PackageConfig {-    name :: PackageName,-    src :: Path Rel Dir,-    components :: Map ComponentName ComponentConfig-  }-  deriving stock (Eq, Show, Generic)-  deriving anyclass (FromJSON)--data Target =-  Target {-    package :: PackageConfig,-    component :: ComponentConfig,-    sourceDir :: Maybe SourceDir-  }-  deriving stock (Eq, Show, Generic)+import Hix.Data.ComponentConfig (EnvRunner, PackagesConfig)  newtype RunnerName =   RunnerName { unRunnerName :: Text }@@ -126,8 +25,6 @@   deriving stock (Eq, Show, Generic)   deriving newtype (IsList, Ord, FromJSON) -type PackagesConfig = Map PackageName PackageConfig- data EnvConfig =   EnvConfig {     packages :: PackagesConfig,@@ -142,13 +39,6 @@     setup :: Map RunnerName GhciSetupCode,     run :: Map RunnerName GhciRunExpr,     args :: GhciArgs-  }-  deriving stock (Eq, Show, Generic)-  deriving anyclass (FromJSON)--data PreprocConfig =-  PreprocConfig {-    packages :: PackagesConfig   }   deriving stock (Eq, Show, Generic)   deriving anyclass (FromJSON)
+ lib/Hix/Data/NewProjectConfig.hs view
@@ -0,0 +1,28 @@+module Hix.Data.NewProjectConfig where++newtype ProjectName =+  ProjectName { unProjectName :: Text }+  deriving stock (Eq, Show, Generic)+  deriving newtype (IsString, Ord)++newtype HixUrl =+  HixUrl { unHixUrl :: Text }+  deriving stock (Eq, Show, Generic)+  deriving newtype (IsString, Ord)++instance Default HixUrl where+  def = "github:tek/hix"++newtype Author =+  Author { unAuthor :: Text }+  deriving stock (Eq, Show, Generic)+  deriving newtype (IsString, Ord)++data NewProjectConfig =+  NewProjectConfig {+    name :: ProjectName,+    packages :: Bool,+    hixUrl :: HixUrl,+    author :: Author+  }+  deriving stock (Eq, Show, Generic)
+ lib/Hix/Data/PreprocConfig.hs view
@@ -0,0 +1,12 @@+module Hix.Data.PreprocConfig where++import Data.Aeson (FromJSON)++import Hix.Data.ComponentConfig (PackagesConfig)++data PreprocConfig =+  PreprocConfig {+    packages :: PackagesConfig+  }+  deriving stock (Eq, Show, Generic)+  deriving anyclass (FromJSON)
+ lib/Hix/Data/ProjectFile.hs view
@@ -0,0 +1,27 @@+module Hix.Data.ProjectFile where++import Control.Monad.Trans.Class (lift)+import Control.Monad.Trans.Reader (ask)+import qualified Data.Text.IO as Text+import Path (File, Path, Rel, parent, toFilePath, (</>))+import Path.IO (createDirIfMissing)++import Hix.Data.Error (tryIO)+import qualified Hix.Monad+import Hix.Monad (Env (Env), M)++data ProjectFile =+  ProjectFile {+    path :: Path Rel File,+    content :: Text+  }+  deriving stock (Eq, Show, Generic)++createFile :: ProjectFile -> M ()+createFile f = do+  Env {root} <- ask+  let+    file = root </> f.path+  lift $ tryIO do+    createDirIfMissing True (parent file)+    Text.writeFile (toFilePath file) f.content
lib/Hix/Env.hs view
@@ -3,9 +3,10 @@ import qualified Data.Text.IO as Text  import Hix.Component (targetComponent)+import qualified Hix.Data.ComponentConfig+import Hix.Data.ComponentConfig (EnvRunner (EnvRunner), PackagesConfig, Target (Target)) import Hix.Data.Error (pathText)-import qualified Hix.Data.GhciConfig as GhciConfig-import Hix.Data.GhciConfig (EnvRunner (EnvRunner), PackagesConfig, Target (Target))+import qualified Hix.Data.GhciConfig import Hix.Json (jsonConfig) import Hix.Monad (M) import qualified Hix.Options as Options
lib/Hix/Ghci.hs view
@@ -15,19 +15,18 @@ import System.Posix.User (getLoginName)  import Hix.Component (targetComponent)-import Hix.Data.Error (Error, note, pathText, tryIO)-import qualified Hix.Data.GhciConfig as GhciConfig-import Hix.Data.GhciConfig (+import qualified Hix.Data.ComponentConfig+import Hix.Data.ComponentConfig (   ComponentConfig,-  GhciConfig,-  GhciRunExpr (GhciRunExpr),-  GhciSetupCode (GhciSetupCode),   ModuleName (ModuleName),   PackageConfig,   PackageName,   SourceDir (SourceDir),   Target (Target),   )+import Hix.Data.Error (Error, note, pathText, tryIO)+import qualified Hix.Data.GhciConfig+import Hix.Data.GhciConfig (GhciConfig, GhciRunExpr (GhciRunExpr), GhciSetupCode (GhciSetupCode)) import qualified Hix.Data.GhciTest as GhciTest import Hix.Data.GhciTest (GhciRun (GhciRun), GhciTest (GhciTest), GhcidRun (GhcidRun)) import Hix.Json (jsonConfig)
lib/Hix/Monad.hs view
@@ -5,7 +5,7 @@ import Control.Monad.Trans.Reader (ReaderT (runReaderT)) import Path (Abs, Dir, Path) -import Hix.Data.Error (Error (EnvError, GhciError), tryIO)+import Hix.Data.Error (Error (BootstrapError, EnvError, GhciError, NewError), tryIO)  data Env =   Env {@@ -22,6 +22,14 @@ noteGhci :: Text -> Maybe a -> M a noteGhci err =   maybe (lift (throwE (GhciError err))) pure++noteNew :: Text -> Maybe a -> M a+noteNew err =+  maybe (lift (throwE (NewError err))) pure++noteBootstrap :: Text -> Maybe a -> M a+noteBootstrap err =+  maybe (lift (throwE (BootstrapError err))) pure  runM :: Path Abs Dir -> M a -> IO (Either Error a) runM root ma =
+ lib/Hix/New.hs view
@@ -0,0 +1,176 @@+module Hix.New where++import Exon (exon)+import Path (parseRelDir, parseRelFile, reldir, relfile, (</>))+import Text.Casing (pascal)++import qualified Hix.Data.NewProjectConfig+import Hix.Data.NewProjectConfig (+  Author,+  HixUrl (HixUrl),+  NewProjectConfig (NewProjectConfig),+  ProjectName (ProjectName),+  )+import qualified Hix.Data.ProjectFile+import Hix.Data.ProjectFile (ProjectFile (ProjectFile), createFile)+import Hix.Monad (M, noteEnv)++license :: Author -> Text+license author =+  [exon|Copyright (c) 2023 ##{author}++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.++Subject to the terms and conditions of this license, each copyright holder and contributor hereby grants to those+receiving rights under this license a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except+for failure to satisfy the conditions of this license) patent license to make, have made, use, offer to sell, sell,+import, and otherwise transfer this software, where such license applies only to those patent claims, already acquired+or hereafter acquired, licensable by such copyright holder or contributor that are necessarily infringed by:++  (a) their Contribution(s) (the licensed copyrights of copyright holders and non-copyrightable additions of+  contributors, in source or binary form) alone; or+  (b) combination of their Contribution(s) with the work of authorship to which such Contribution(s) was added by such+  copyright holder or contributor, if, at the time the Contribution is added, such addition causes such combination to+  be necessarily infringed. The patent license shall not apply to any other combinations which include the Contribution.++Except as expressly stated above, no rights or licenses from any copyright holder or contributor is granted under this+license, whether expressly, by implication, estoppel or otherwise.++DISCLAIMER++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 HOLDERS 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.+|]++flake :: NewProjectConfig -> Text+flake NewProjectConfig {name = ProjectName name, hixUrl = HixUrl url, ..} =+  [exon|{+  description = "A Haskell project";++  inputs.hix.url = "#{url}";++  outputs = {hix, ...}: hix.lib.flake {+    hackage.versionFile = "ops/version.nix";++    cabal = {+      license = "BSD-2-Clause-Patent";+      license-file = "LICENSE";+      author = "##{author}";+      ghc-options = ["-Wall"];+    };++    packages.#{name} = {+      src = ./#{src};+      cabal.meta.synopsis = "A Haskell project";++      library = {+        enable = true;+        dependencies = [+          "containers"+        ];+      };++      executable.enable = true;++      test = {+        enable = true;+        dependencies = [+          "hedgehog >= 1.1 && < 1.3"+          "tasty ^>= 1.4"+          "tasty-hedgehog >= 1.3 && < 1.5"+        ];+      };++    };+  };+}+|]+  where+    src | packages = [exon|packages/#{name}|]+        | otherwise = "."++libModule :: NewProjectConfig -> Text -> Text+libModule conf modName =+  [exon|module #{modName} where++name :: String+name = "#{conf.name.unProjectName}"+|]++appMainModule :: Text -> Text+appMainModule modName =+  [exon|module Main where++import #{modName} (name)++main :: IO ()+main = putStrLn ("Hello " <> name)+|]++testMainModule :: Text -> Text+testMainModule modName =+  [exon|module Main where++import Hedgehog (property, test, withTests)+import Test.Tasty (TestTree, defaultMain, testGroup)+import Test.Tasty.Hedgehog (testProperty)+import #{modName}.Test.NameTest (test_name)++tests :: TestTree+tests =+  testGroup "all" [+    testProperty "name" (withTests 1 (property (test test_name)))+  ]++main :: IO ()+main = defaultMain tests+|]++nameTestModule :: NewProjectConfig -> Text -> Text+nameTestModule conf modName =+  [exon|module #{modName}.Test.NameTest where++import Hedgehog (TestT, (===))++import #{modName} (name)++test_name :: TestT IO ()+test_name = "#{conf.name.unProjectName}" === name+|]++newProjectFiles :: NewProjectConfig -> M [ProjectFile]+newProjectFiles conf = do+  nameDir <- pathError (parseRelDir modNameS)+  let packageDir = if conf.packages then [reldir|packages|] </> nameDir else [reldir|.|]+  libFile <- pathError (parseRelFile [exon|#{modNameS}.hs|])+  pure [+    ProjectFile {path = [relfile|flake.nix|], content = flake conf},+    ProjectFile {path = packageDir </> [relfile|LICENSE|], content = license conf.author},+    ProjectFile {path = packageDir </> [relfile|ops/version.nix|], content = [exon|"0.1.0.0"|]},+    ProjectFile {path = packageDir </> [reldir|lib|] </> libFile, content = libModule conf modName},+    ProjectFile {path = packageDir </> [relfile|app/Main.hs|], content = appMainModule modName},+    ProjectFile {path = packageDir </> [relfile|test/Main.hs|], content = testMainModule modName},+    ProjectFile {+      path = packageDir </> [reldir|test|] </> nameDir </> [relfile|Test/NameTest.hs|],+      content = nameTestModule conf modName+    }+    ]+  where+    pathError = noteEnv "Can't convert project name to file path"+    modName = toText modNameS+    modNameS = pascal (toString conf.name.unProjectName)++newProject :: NewProjectConfig -> M ()+newProject conf = do+  traverse_ createFile =<< newProjectFiles conf
lib/Hix/Options.hs view
@@ -28,17 +28,19 @@ import Path (Abs, Dir, File, Path, SomeBase, parseRelDir, parseSomeDir) import Prelude hiding (Mod, mod) -import Hix.Data.GhciConfig (+import qualified Hix.Data.BootstrapProjectConfig+import Hix.Data.BootstrapProjectConfig (BootstrapProjectConfig (BootstrapProjectConfig))+import Hix.Data.ComponentConfig (   ComponentName (ComponentName),-  EnvConfig,   EnvName,-  GhciConfig,   ModuleName,   PackageName (PackageName),-  PreprocConfig,-  RunnerName,   SourceDir (SourceDir),   )+import Hix.Data.GhciConfig (EnvConfig, GhciConfig, RunnerName)+import qualified Hix.Data.NewProjectConfig+import Hix.Data.NewProjectConfig (NewProjectConfig (NewProjectConfig))+import Hix.Data.PreprocConfig (PreprocConfig) import Hix.Optparse (JsonConfig, absFileOption, jsonOption)  data PreprocOptions =@@ -100,6 +102,18 @@   }   deriving stock (Show, Generic) +data NewOptions =+  NewOptions {+    config :: NewProjectConfig+  }+  deriving stock (Eq, Show, Generic)++data BootstrapOptions =+  BootstrapOptions {+    config :: BootstrapProjectConfig+  }+  deriving stock (Eq, Show, Generic)+ data EnvRunnerCommandOptions =   EnvRunnerCommandOptions {     options :: EnvRunnerOptions,@@ -115,6 +129,10 @@   GhcidCmd GhciOptions   |   GhciCmd GhciOptions+  |+  NewCmd NewOptions+  |+  BootstrapCmd BootstrapOptions   deriving stock (Show)  data GlobalOptions =@@ -232,6 +250,19 @@   test <- testOptionsParser   pure GhciOptions {..} +newParser :: Parser NewOptions+newParser = do+  name <- strOption (long "name" <> short 'n' <> help "The name of the new project and its main package")+  packages <- switch (long "packages" <> short 'p' <> help "Store packages in the 'packages/' subdirectory")+  hixUrl <- strOption (long "hix-url" <> help "The URL to the Hix repository" <> value def)+  author <- strOption (long "author" <> short 'a' <> help "Your name")+  pure NewOptions {config = NewProjectConfig {..}}++bootstrapParser :: Parser BootstrapOptions+bootstrapParser = do+  hixUrl <- strOption (long "hix-url" <> help "The URL to the Hix repository" <> value def)+  pure BootstrapOptions {config = BootstrapProjectConfig {..}}+ commands ::   Mod CommandFields Command commands =@@ -242,6 +273,10 @@   command "ghci-cmd" (GhciCmd <$> info ghciParser (progDesc "Print a ghci cmdline to load a module in a Hix env"))   <>   command "ghcid-cmd" (GhcidCmd <$> info ghciParser (progDesc "Print a ghcid cmdline to run a function in a Hix env"))+  <>+  command "new" (NewCmd <$> info newParser (progDesc "Create a new Hix project in the current directory"))+  <>+  command "bootstrap" (BootstrapCmd <$> info bootstrapParser (progDesc "Bootstrap an existing Cabal project in the current directory"))  globalParser :: Parser GlobalOptions globalParser = do
+ lib/Hix/Prelude.hs view
@@ -0,0 +1,39 @@+module Hix.Prelude where++import Data.Generics.Labels ()+import Data.List.Extra (firstJust)+import qualified Distribution.ModuleName as ModuleName+import Distribution.ModuleName (ModuleName)+import Distribution.PackageDescription (ModuleRenaming (..), unPackageName)+import Distribution.Types.IncludeRenaming (IncludeRenaming (..))+import Distribution.Types.Mixin (Mixin (..))+import qualified Exon++data Prelude =+  Prelude {+    preludePackage :: String,+    preludeModule :: String+  }+  deriving stock (Eq, Show)++preludeRenaming :: [(b, ModuleName)] -> Maybe b+preludeRenaming =+  firstJust \case+    (real, "Prelude") -> Just real+    _ -> Nothing++pattern PreludeRenaming :: ModuleName -> ModuleRenaming+pattern PreludeRenaming p <- ModuleRenaming (preludeRenaming -> Just p)++pattern PreludeInclude :: ModuleName -> IncludeRenaming+pattern PreludeInclude p <- IncludeRenaming {includeProvidesRn = PreludeRenaming p}++findPrelude :: [Mixin] -> Maybe Prelude+findPrelude =+  firstJust \case+    Mixin {mixinIncludeRenaming = PreludeInclude real, ..} ->+      let+        preludePackage = unPackageName mixinPackageName+        preludeModule = Exon.intercalate "." (ModuleName.components real)+      in Just Prelude {..}+    _ -> Nothing
lib/Hix/Preproc.hs view
@@ -9,13 +9,8 @@ import qualified Data.ByteString.Builder as ByteStringBuilder import Data.ByteString.Builder (Builder, byteString, charUtf8, stringUtf8) import Data.Generics.Labels ()-import Data.List.Extra (firstJust)-import qualified Distribution.ModuleName as ModuleName-import Distribution.ModuleName (ModuleName)-import Distribution.PackageDescription (BuildInfo (..), ModuleRenaming (..), unPackageName)+import Distribution.PackageDescription (BuildInfo (..)) import Distribution.Simple (PerCompilerFlavor (PerCompilerFlavor))-import Distribution.Types.IncludeRenaming (IncludeRenaming (..))-import Distribution.Types.Mixin (Mixin (..)) import qualified Exon import Exon (exon) import Language.Haskell.Extension (@@ -28,26 +23,23 @@  import Hix.Cabal (buildInfoForFile) import Hix.Component (targetComponent)+import qualified Hix.Data.ComponentConfig+import Hix.Data.ComponentConfig (PreludeConfig, PreludePackage (PreludePackageName, PreludePackageSpec)) import Hix.Data.Error (Error (..), sourceError, tryIO)-import qualified Hix.Data.GhciConfig-import Hix.Data.GhciConfig (PreludeConfig, PreludePackage (PreludePackageName, PreludePackageSpec), PreprocConfig)+import qualified Hix.Data.PreprocConfig+import Hix.Data.PreprocConfig (PreprocConfig) import Hix.Json (jsonConfig) import Hix.Monad (M) import Hix.Options (PreprocOptions (..), TargetSpec (TargetForFile)) import Hix.Optparse (JsonConfig)+import qualified Hix.Prelude as Prelude+import Hix.Prelude (Prelude (Prelude), findPrelude)  type Regex = IndexedTraversal' Int ByteString Match -data Prelude =-  Prelude {-    preludePackage :: ByteString,-    preludeModule :: ByteString-  }-  deriving stock (Show)- fromPreludeConfig :: PreludeConfig -> Prelude fromPreludeConfig conf =-  Prelude (encodeUtf8 (name conf.package)) (encodeUtf8 conf.module_.unModuleName)+  Prelude (toString (name conf.package)) (toString conf.module_.unModuleName)   where     name = \case       PreludePackageName n -> n@@ -219,9 +211,9 @@     Nothing   where     insertPrelude =-      (ix 0 .~ [exon|"#{preludePackage}" |])+      (ix 0 .~ [exon|"#{encodeUtf8 preludePackage}" |])       .-      (ix 1 .~ preludeModule)+      (ix 1 .~ encodeUtf8 preludeModule)  parenRegex :: Regex parenRegex =@@ -354,31 +346,9 @@         ..       } -preludeRenaming :: [(b, ModuleName)] -> Maybe b-preludeRenaming =-  firstJust \case-    (real, "Prelude") -> Just real-    _ -> Nothing--pattern PreludeRenaming :: ModuleName -> ModuleRenaming-pattern PreludeRenaming p <- ModuleRenaming (preludeRenaming -> Just p)--pattern PreludeInclude :: ModuleName -> IncludeRenaming-pattern PreludeInclude p <- IncludeRenaming {includeProvidesRn = PreludeRenaming p}--findPrelude :: [Mixin] -> Maybe Prelude-findPrelude =-  firstJust \case-    Mixin {mixinIncludeRenaming = PreludeInclude real, ..} ->-      let-        preludePackage = encodeUtf8 (unPackageName mixinPackageName)-        preludeModule = Exon.intercalate "." (encodeUtf8 <$> ModuleName.components real)-      in Just Prelude {..}-    _ -> Nothing- customPreludeImport :: Prelude -> Builder customPreludeImport Prelude {..} =-  lineB [exon|import "#{byteString preludePackage}" #{byteString preludeModule} as Prelude|]+  lineB [exon|import "#{stringUtf8 preludePackage}" #{stringUtf8 preludeModule} as Prelude|]  needPreludeExtensions :: PreludeAction -> Bool needPreludeExtensions = \case
+ test/Hix/Test/BootstrapTest.hs view
@@ -0,0 +1,172 @@+module Hix.Test.BootstrapTest where++import qualified Data.Text.IO as Text+import Exon (exon)+import Hedgehog (TestT, evalEither, (===))+import Path (parent, reldir, relfile, toFilePath, (</>))+import Path.IO (createDirIfMissing, withSystemTempDir)++import Hix.Bootstrap (bootstrapFiles)+import qualified Hix.Data.BootstrapProjectConfig+import Hix.Data.BootstrapProjectConfig (BootstrapProjectConfig (BootstrapProjectConfig))+import qualified Hix.Data.ProjectFile as ProjectFile+import Hix.Monad (runM)+import qualified Data.Text as Text++cabal :: Text+cabal =+  [exon|cabal-version: 2.2++name:           red-panda+version:        0.1.0.0+synopsis:       A Haskell project+description:    See https://hackage.haskell.org/package/red-panda/docs/RedPanda.html+author:         Panda+maintainer:     Panda+license:        BSD-2-Clause-Patent+license-file:   LICENSE+build-type:     Simple++library+  exposed-modules:+      RedPanda+  other-modules:+      Paths_red_panda+  autogen-modules:+      Paths_red_panda+  hs-source-dirs:+      lib+  ghc-options: -Wall+  build-depends:+      base ==4.*+    , incipit-base >= 0.4 && < 0.6+    , containers+  default-language: Haskell2010+  default-extensions:+      OverloadedStrings+    , OverloadedRecordDot+  mixins:+      base hiding (Prelude)+    , incipit-base (IncipitBase as Prelude)+    , incipit-base hiding (IncipitBase)++executable red-panda+  main-is: Main.hs+  other-modules:+      Paths_red_panda+  autogen-modules:+      Paths_red_panda+  hs-source-dirs:+      app+  ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall+  build-depends:+      base ==4.*+    , red-panda+  default-language: Haskell2010++test-suite red-panda-test+  type: exitcode-stdio-1.0+  main-is: Main.hs+  other-modules:+      RedPanda.Test.NameTest+      Paths_red_panda+  autogen-modules:+      Paths_red_panda+  hs-source-dirs:+      test+  ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall+  build-depends:+      base ==4.*+    , hedgehog >=1.1 && <1.3+    , red-panda+    , tasty ==1.4.*+    , tasty-hedgehog >=1.3 && <1.5+  default-language: Haskell2010+|]++conf :: BootstrapProjectConfig+conf =+  BootstrapProjectConfig {hixUrl = def}++flakeTarget :: Text+flakeTarget =+  [exon|{+  description = "A Haskell project";+  inputs.hix.url = "github:tek/hix";+  outputs = {hix, ...}: hix.lib.flake {+    packages = {+      red-panda = {+        src = ./packages/red-panda;+        description = "See https://hackage.haskell.org/package/red-panda/docs/RedPanda.html";+        cabal = {+          author = "Panda";+          build-type = "Simple";+          license = "BSD-2-Clause-Patent";+          license-file = "LICENSE";+          meta = {+            maintainer = "Panda";+            synopsis = "A Haskell project";+          };+        };+        library = {+          dependencies = [+            "containers"+            "base >=4 && <5"+          ];+          default-extensions = [+            "OverloadedStrings"+            "OverloadedRecordDot"+          ];+          source-dirs = "lib";+          language = "Haskell2010";+          ghc-options = [+            "-Wall"+          ];+          prelude = {+            package = {+              name = "incipit-base";+              version = ">=0.4 && <0.6";+            };+            module = "IncipitBase";+          };+        };+        executables.red-panda = {+          dependencies = [+            "red-panda"+          ];+          source-dirs = "app";+          language = "Haskell2010";+          ghc-options = [+            "-Wall"+          ];+        };+        tests.red-panda-test = {+          dependencies = [+            "hedgehog >=1.1 && <1.3"+            "red-panda"+            "tasty >=1.4 && <1.5"+            "tasty-hedgehog >=1.3 && <1.5"+          ];+          source-dirs = "test";+          language = "Haskell2010";+          ghc-options = [+            "-Wall"+          ];+        };+      };+    };+  };+}+|]++test_bootstrap :: TestT IO ()+test_bootstrap = do+  result <- liftIO $ withSystemTempDir "hix-unit" \ tmp -> do+    let+      root = tmp </> [reldir|red-panda|]+      cabalFile = root </> [relfile|packages/red-panda/red-panda.cabal|]+    createDirIfMissing True (parent cabalFile)+    Text.writeFile (toFilePath cabalFile) cabal+    runM root (bootstrapFiles conf)+  [flake] <- evalEither result+  Text.lines flakeTarget === Text.lines flake.content
test/Hix/Test/CabalFile.hs view
@@ -1,16 +1,11 @@-{-# language CPP #-}- module Hix.Test.CabalFile where -#if MIN_VERSION_Cabal(3,8,0)-import Distribution.Simple.PackageDescription (parseString)-#else-import Distribution.Fields.ParseResult (parseString)-#endif import Distribution.PackageDescription (GenericPackageDescription) import Distribution.PackageDescription.Parsec (parseGenericPackageDescription) import Distribution.Verbosity (silent) import Exon (exon)++import Hix.Compat (parseString)  testCabal :: ByteString testCabal =
test/Hix/Test/GhciTest.hs view
@@ -6,18 +6,17 @@ import Path (Abs, Dir, File, Path, Rel, SomeBase (Rel), absdir, absfile, reldir, relfile, (</>)) import Path.IO (getCurrentDir, withSystemTempDir) -import Hix.Data.Error (pathText)-import Hix.Data.GhciConfig (+import Hix.Data.ComponentConfig (   ComponentConfig (..),   ComponentName,-  EnvConfig (EnvConfig),   EnvRunner (EnvRunner),-  GhciConfig (..),   PackageConfig (..),   PackagesConfig,   SourceDir (SourceDir),   SourceDirs (SourceDirs),   )+import Hix.Data.Error (pathText)+import Hix.Data.GhciConfig (EnvConfig (EnvConfig), GhciConfig (..)) import qualified Hix.Data.GhciTest as GhciTest import Hix.Env (envRunner) import Hix.Ghci (assemble, ghcidCmdlineFromOptions)
+ test/Hix/Test/NewTest.hs view
@@ -0,0 +1,125 @@+module Hix.Test.NewTest where++import Exon (exon)+import Hedgehog (TestT, evalEither, (===))+import Path (absdir, relfile)++import qualified Hix.Data.NewProjectConfig+import Hix.Data.NewProjectConfig (HixUrl, NewProjectConfig (NewProjectConfig))+import Hix.Data.ProjectFile (ProjectFile (ProjectFile))+import Hix.Monad (runM)+import Hix.New (license, newProjectFiles)++conf :: NewProjectConfig+conf =+  NewProjectConfig {name = "spider", packages = False, hixUrl = def, author = "Me"}++flake :: Text+flake =+  [exon|{+  description = "A Haskell project";++  inputs.hix.url = "#{(def :: HixUrl).unHixUrl}";++  outputs = {hix, ...}: hix.lib.flake {+    hackage.versionFile = "ops/version.nix";++    cabal = {+      license = "BSD-2-Clause-Patent";+      license-file = "LICENSE";+      author = "Me";+      ghc-options = ["-Wall"];+    };++    packages.spider = {+      src = ./.;+      cabal.meta.synopsis = "A Haskell project";++      library = {+        enable = true;+        dependencies = [+          "containers"+        ];+      };++      executable.enable = true;++      test = {+        enable = true;+        dependencies = [+          "hedgehog >= 1.1 && < 1.3"+          "tasty ^>= 1.4"+          "tasty-hedgehog >= 1.3 && < 1.5"+        ];+      };++    };+  };+}+|]++libModule :: Text+libModule =+  [exon|module Spider where++name :: String+name = "spider"+|]++appMainModule :: Text+appMainModule =+  [exon|module Main where++import Spider (name)++main :: IO ()+main = putStrLn ("Hello " <> name)+|]++testMainModule :: Text+testMainModule =+  [exon|module Main where++import Hedgehog (property, test, withTests)+import Test.Tasty (TestTree, defaultMain, testGroup)+import Test.Tasty.Hedgehog (testProperty)+import Spider.Test.NameTest (test_name)++tests :: TestTree+tests =+  testGroup "all" [+    testProperty "name" (withTests 1 (property (test test_name)))+  ]++main :: IO ()+main = defaultMain tests+|]++nameTestModule :: Text+nameTestModule =+  [exon|module Spider.Test.NameTest where++import Hedgehog (TestT, (===))++import Spider (name)++test_name :: TestT IO ()+test_name = "spider" === name+|]++target :: [ProjectFile]+target =+  [+    ProjectFile [relfile|flake.nix|] flake,+    ProjectFile [relfile|LICENSE|] (license "Me"),+    ProjectFile [relfile|ops/version.nix|] [exon|"0.1.0.0"|],+    ProjectFile [relfile|lib/Spider.hs|] libModule,+    ProjectFile [relfile|app/Main.hs|] appMainModule,+    ProjectFile [relfile|test/Main.hs|] testMainModule,+    ProjectFile [relfile|test/Spider/Test/NameTest.hs|] nameTestModule+  ]++test_new :: TestT IO ()+test_new = do+  res <- evalEither =<< liftIO (runM [absdir|/project|] (newProjectFiles conf))+  target === res
test/Main.hs view
@@ -1,8 +1,10 @@ module Main where  import Hedgehog (TestT, property, test, withTests)+import Hix.Test.BootstrapTest (test_bootstrap) import Hix.Test.CabalTest (test_cabal) import Hix.Test.GhciTest (test_componentEnv, test_ghcid, test_moduleName)+import Hix.Test.NewTest (test_new) import Hix.Test.PreprocTest (   test_preprocInsertPrelude,   test_preprocNoPrelude,@@ -36,7 +38,9 @@       unitTest "self exporting module, separate line" test_preprocNoPrelude,       unitTest "run ghcid" test_ghcid,       unitTest "component env" test_componentEnv,-      unitTest "extract module name from path" test_moduleName+      unitTest "extract module name from path" test_moduleName,+      unitTest "generate a project" test_new,+      unitTest "bootstrap a project" test_bootstrap     ]   ]