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 +1/−1
- hix.cabal +13/−1
- lib/Hix.hs +16/−2
- lib/Hix/Bootstrap.hs +401/−0
- lib/Hix/Cabal.hs +3/−8
- lib/Hix/Compat.hs +18/−0
- lib/Hix/Component.hs +3/−3
- lib/Hix/Data/BootstrapProjectConfig.hs +9/−0
- lib/Hix/Data/ComponentConfig.hs +108/−0
- lib/Hix/Data/Error.hs +18/−0
- lib/Hix/Data/GhciConfig.hs +2/−112
- lib/Hix/Data/NewProjectConfig.hs +28/−0
- lib/Hix/Data/PreprocConfig.hs +12/−0
- lib/Hix/Data/ProjectFile.hs +27/−0
- lib/Hix/Env.hs +3/−2
- lib/Hix/Ghci.hs +5/−6
- lib/Hix/Monad.hs +9/−1
- lib/Hix/New.hs +176/−0
- lib/Hix/Options.hs +40/−5
- lib/Hix/Prelude.hs +39/−0
- lib/Hix/Preproc.hs +11/−41
- test/Hix/Test/BootstrapTest.hs +172/−0
- test/Hix/Test/CabalFile.hs +2/−7
- test/Hix/Test/GhciTest.hs +3/−4
- test/Hix/Test/NewTest.hs +125/−0
- test/Main.hs +5/−1
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 ] ]