packages feed

hix 0.1.1.0 → 0.2.0.0

raw patch · 10 files changed

+152/−48 lines, 10 filesdep ~aesondep ~hedgehogdep ~lensPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: aeson, hedgehog, lens, tasty-hedgehog

API changes (from Hackage documentation)

- Hix.Options: instance GHC.Classes.Eq Hix.Options.PreprocOptions
+ 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: [$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:PreludePackageName] :: PreludePackage -> Text
+ Hix.Data.GhciConfig: [$sel:package:PreludeConfig] :: PreludeConfig -> PreludePackage
+ Hix.Data.GhciConfig: [$sel:packages:PreprocConfig] :: PreprocConfig -> PackagesConfig
+ Hix.Data.GhciConfig: [$sel:prelude:ComponentConfig] :: ComponentConfig -> Maybe PreludeConfig
+ Hix.Data.GhciConfig: data PreludeConfig
+ Hix.Data.GhciConfig: data PreludePackage
+ Hix.Data.GhciConfig: data PreprocConfig
+ 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 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.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.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.Options: [$sel:config:PreprocOptions] :: PreprocOptions -> Maybe (Either PreprocConfig JsonConfig)
+ Hix.Preproc: CabalConfig :: [Builder] -> [Builder] -> Maybe Prelude -> CabalConfig
+ Hix.Preproc: [$sel:extensions:CabalConfig] :: CabalConfig -> [Builder]
+ Hix.Preproc: [$sel:ghcOptions:CabalConfig] :: CabalConfig -> [Builder]
+ Hix.Preproc: [$sel:prelude:CabalConfig] :: CabalConfig -> Maybe Prelude
+ Hix.Preproc: data CabalConfig
+ Hix.Preproc: fromCabal :: BuildInfo -> CabalConfig
+ Hix.Preproc: fromCabalFile :: Path Abs File -> M CabalConfig
+ Hix.Preproc: fromConfig :: Path Abs File -> Either PreprocConfig JsonConfig -> M CabalConfig
+ Hix.Preproc: fromPreludeConfig :: PreludeConfig -> Prelude
+ Hix.Preproc: instance GHC.Generics.Generic Hix.Preproc.CabalConfig
+ Hix.Preproc: instance GHC.Show.Show Hix.Preproc.CabalConfig
+ Hix.Preproc: preprocessWith :: PreprocOptions -> CabalConfig -> M ()
- Hix.Data.GhciConfig: ComponentConfig :: ComponentName -> SourceDirs -> Maybe EnvRunner -> ComponentConfig
+ Hix.Data.GhciConfig: ComponentConfig :: ComponentName -> SourceDirs -> Maybe EnvRunner -> [String] -> String -> [String] -> Maybe PreludeConfig -> ComponentConfig
- Hix.Options: PreprocOptions :: Path Abs File -> Path Abs File -> Path Abs File -> PreprocOptions
+ Hix.Options: PreprocOptions :: Maybe (Either PreprocConfig JsonConfig) -> Path Abs File -> Path Abs File -> Path Abs File -> PreprocOptions
- Hix.Preproc: extensionsPragma :: BuildInfo -> Maybe Builder
+ Hix.Preproc: extensionsPragma :: CabalConfig -> Maybe Builder
- Hix.Preproc: preprocess :: PreprocOptions -> ExceptT Error IO ()
+ Hix.Preproc: preprocess :: PreprocOptions -> M ()
- Hix.Preproc: preprocessModule :: Path Abs File -> BuildInfo -> DummyExportName -> ByteString -> Builder
+ Hix.Preproc: preprocessModule :: Path Abs File -> CabalConfig -> DummyExportName -> ByteString -> Builder

Files

hix.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           hix-version:        0.1.1.0+version:        0.2.0.0 synopsis:       Haskell/Nix development build tools description:    See https://hackage.haskell.org/package/hix/docs/Hix.html category:       Build@@ -77,14 +77,14 @@   ghc-options: -Wall -Widentities -Wincomplete-uni-patterns -Wmissing-deriving-strategies -Wredundant-constraints -Wunused-type-patterns -Wunused-packages   build-depends:       Cabal-    , aeson ==2.0.*+    , aeson >=2.0 && <2.2     , base ==4.*     , exon ==1.4.*     , extra ==1.7.*     , filepattern ==0.1.*     , generic-lens ==2.2.*     , incipit-base ==0.5.*-    , lens ==5.1.*+    , lens >=5.1 && <5.3     , lens-regex-pcre ==1.1.*     , optparse-applicative ==0.17.*     , path ==0.9.*@@ -198,13 +198,13 @@       Cabal     , base ==4.*     , exon ==1.4.*-    , hedgehog ==1.1.*+    , hedgehog >=1.1 && <1.3     , hix     , incipit-base ==0.5.*     , path ==0.9.*     , path-io ==1.7.*     , tasty ==1.4.*-    , tasty-hedgehog ==1.3.*+    , tasty-hedgehog >=1.3 && <1.5     , transformers   mixins:       base hiding (Prelude)
lib/Hix.hs view
@@ -1,9 +1,8 @@ module Hix where -import Control.Monad.Trans.Class (lift) import Path.IO (getCurrentDir) -import Hix.Data.Error (Error (..), printEnvError, printGhciError, printPreprocError, printFatalError)+import Hix.Data.Error (Error (..), printEnvError, printFatalError, printGhciError, printPreprocError) import Hix.Env (printEnvRunner) import Hix.Ghci (printGhciCmdline, printGhcidCmdline) import Hix.Monad (M, runM)@@ -31,7 +30,7 @@  runCommand :: Command -> M () runCommand = \case-  Preproc opts -> lift (preprocess opts)+  Preproc opts -> preprocess opts   EnvRunner opts -> printEnvRunner opts.options   GhcidCmd opts -> printGhcidCmdline opts   GhciCmd opts -> printGhciCmdline opts
lib/Hix/Cabal.hs view
@@ -1,8 +1,14 @@+{-# 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
lib/Hix/Data/GhciConfig.hs view
@@ -1,6 +1,6 @@ module Hix.Data.GhciConfig where -import Data.Aeson (FromJSON (parseJSON), FromJSONKey)+import Data.Aeson (FromJSON (parseJSON), FromJSONKey, withObject, (.:)) import GHC.Exts (IsList) import Path (Abs, Dir, File, Path, Rel) @@ -49,11 +49,42 @@   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+    runner :: Maybe EnvRunner,+    extensions :: [String],+    language :: String,+    ghcOptions :: [String],+    prelude :: Maybe PreludeConfig   }   deriving stock (Eq, Show, Generic)   deriving anyclass (FromJSON)@@ -111,6 +142,13 @@     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/Monad.hs view
@@ -5,7 +5,7 @@ import Control.Monad.Trans.Reader (ReaderT (runReaderT)) import Path (Abs, Dir, Path) -import Hix.Data.Error (Error (GhciError), tryIO)+import Hix.Data.Error (Error (EnvError, GhciError), tryIO)  data Env =   Env {@@ -17,7 +17,7 @@  noteEnv :: Text -> Maybe a -> M a noteEnv err =-  maybe (lift (throwE (GhciError err))) pure+  maybe (lift (throwE (EnvError err))) pure  noteGhci :: Text -> Maybe a -> M a noteGhci err =
lib/Hix/Options.hs view
@@ -35,6 +35,7 @@   GhciConfig,   ModuleName,   PackageName (PackageName),+  PreprocConfig,   RunnerName,   SourceDir (SourceDir),   )@@ -42,11 +43,12 @@  data PreprocOptions =   PreprocOptions {+    config :: Maybe (Either PreprocConfig JsonConfig),     source :: Path Abs File,     inFile :: Path Abs File,     outFile :: Path Abs File   }-  deriving stock (Eq, Show, Generic)+  deriving stock (Show, Generic)  data PackageSpec =   PackageSpec {@@ -136,10 +138,17 @@ fileParser longName helpText =   option absFileOption (long longName <> completer (bashCompleter "file") <> help helpText) +jsonConfigParser ::+  Parser JsonConfig+jsonConfigParser =+  option jsonOption (long "config" <> short 'c' <> help "The Hix-generated config, file or text")+ preprocParser :: Parser PreprocOptions preprocParser =   PreprocOptions   <$>+  (fmap Right <$> optional jsonConfigParser)+  <*>   fileParser "source" "The original source file"   <*>   fileParser "in" "The prepared input file"@@ -199,11 +208,6 @@ moduleParser :: Parser ModuleName moduleParser =   strOption (long "module" <> short 'm' <> help "The module containing the test function" <> value "Main")--jsonConfigParser ::-  Parser JsonConfig-jsonConfigParser =-  option jsonOption (long "config" <> short 'c' <> help "The Hix-generated config, file or text")  testOptionsParser :: Parser TestOptions testOptionsParser = do
lib/Hix/Preproc.hs view
@@ -2,6 +2,7 @@  import Control.Lens (IndexedTraversal', has, index, ix, preview, (%~), (.~), (^..)) import Control.Lens.Regex.ByteString (Match, group, groups, match, regex)+import Control.Monad.Trans.Class (lift) import Control.Monad.Trans.Except (ExceptT, throwE) import qualified Data.ByteString as ByteString import Data.ByteString (elemIndex)@@ -26,8 +27,14 @@ import System.Random (randomRIO)  import Hix.Cabal (buildInfoForFile)+import Hix.Component (targetComponent) import Hix.Data.Error (Error (..), sourceError, tryIO)-import Hix.Options (PreprocOptions (..))+import qualified Hix.Data.GhciConfig+import Hix.Data.GhciConfig (PreludeConfig, PreludePackage (PreludePackageName, PreludePackageSpec), PreprocConfig)+import Hix.Json (jsonConfig)+import Hix.Monad (M)+import Hix.Options (PreprocOptions (..), TargetSpec (TargetForFile))+import Hix.Optparse (JsonConfig)  type Regex = IndexedTraversal' Int ByteString Match @@ -38,6 +45,22 @@   }   deriving stock (Show) +fromPreludeConfig :: PreludeConfig -> Prelude+fromPreludeConfig conf =+  Prelude (encodeUtf8 (name conf.package)) (encodeUtf8 conf.module_.unModuleName)+  where+    name = \case+      PreludePackageName n -> n+      PreludePackageSpec n -> n++data CabalConfig =+  CabalConfig {+    extensions :: [Builder],+    ghcOptions :: [Builder],+    prelude :: Maybe Prelude+  }+  deriving stock (Show, Generic)+ newtype DummyExportName =   DummyExportName { unDummyExportName :: ByteString }   deriving stock (Eq, Show, Generic)@@ -86,15 +109,10 @@ languagePragma exts =   [exon|{-# language #{Exon.intercalate ", " exts} #-}|] -extensionsPragma :: BuildInfo -> Maybe Builder-extensionsPragma info-  | null exts = Nothing-  | otherwise = Just (languagePragma exts)-  where-    exts = maybeToList (dlExtension =<< info.defaultLanguage) ++ mapMaybe extension info.defaultExtensions-    dlExtension = \case-      UnknownLanguage _ -> Nothing-      lang -> Just (stringUtf8 (show lang))+extensionsPragma :: CabalConfig -> Maybe Builder+extensionsPragma conf+  | null conf.extensions = Nothing+  | otherwise = Just (languagePragma conf.extensions)  optionsPragma :: Builder -> Builder optionsPragma opts =@@ -440,24 +458,53 @@  preprocessModule ::   Path Abs File ->-  BuildInfo ->+  CabalConfig ->   DummyExportName ->   ByteString ->   Builder-preprocessModule source info dummyExportName inLines =-  assemble source header (extensionsPragma info) options dummyExportName+preprocessModule source conf dummyExportName inLines =+  assemble source header (extensionsPragma conf) options dummyExportName   where-    options = Exon.intercalate " " <$> nonEmpty (stringUtf8 <$> ghcOptions)-    PerCompilerFlavor ghcOptions _ = info.options-    customPrelude = findPrelude info.mixins-    header = scanHeader customPrelude inLines+    options = Exon.intercalate " " <$> nonEmpty conf.ghcOptions+    header = scanHeader conf.prelude inLines --- TODO add common stanzas-preprocess :: PreprocOptions -> ExceptT Error IO ()-preprocess PreprocOptions {..} = do-  info <- buildInfoForFile source-  inLines <- tryIO (ByteString.readFile (toFilePath inFile))+preprocessWith :: PreprocOptions -> CabalConfig -> M ()+preprocessWith opt conf = do+  inLines <- lift (tryIO (ByteString.readFile (toFilePath opt.inFile)))   dummyNumber :: Int <- randomRIO (10000, 10000000)   let dummyExportName = DummyExportName [exon|Hix_Dummy_#{show dummyNumber}|]-  let result = preprocessModule source info dummyExportName inLines-  tryIO (ByteStringBuilder.writeFile (toFilePath outFile) result)+  let result = preprocessModule opt.source conf dummyExportName inLines+  lift (tryIO (ByteStringBuilder.writeFile (toFilePath opt.outFile) result))++fromConfig :: Path Abs File -> Either PreprocConfig JsonConfig -> M CabalConfig+fromConfig source pconf = do+  conf <- either pure jsonConfig pconf+  target <- targetComponent conf.packages (TargetForFile source)+  pure CabalConfig {+    extensions = stringUtf8 <$> target.component.language : target.component.extensions,+    ghcOptions = stringUtf8 <$> target.component.ghcOptions,+    prelude = fromPreludeConfig <$> target.component.prelude+    }++fromCabal :: BuildInfo -> CabalConfig+fromCabal info =+  CabalConfig {+    extensions = maybeToList (dlExtension =<< info.defaultLanguage) <> mapMaybe extension info.defaultExtensions,+    ghcOptions = stringUtf8 <$> ghcOptions,+    prelude = findPrelude info.mixins+    }+  where+    PerCompilerFlavor ghcOptions _ = info.options+    dlExtension = \case+      UnknownLanguage _ -> Nothing+      lang -> Just (stringUtf8 (show lang))++fromCabalFile :: Path Abs File -> M CabalConfig+fromCabalFile source =+  fromCabal <$> lift (buildInfoForFile source)++-- TODO add common stanzas+preprocess :: PreprocOptions -> M ()+preprocess opt = do+  conf <- maybe (fromCabalFile opt.source) (fromConfig opt.source) opt.config+  preprocessWith opt conf
test/Hix/Test/CabalFile.hs view
@@ -1,6 +1,12 @@+{-# 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)
test/Hix/Test/GhciTest.hs view
@@ -54,7 +54,11 @@   ComponentConfig {     name,     sourceDirs = SourceDirs [SourceDir dir],-    runner = Just runner+    runner = Just runner,+    extensions = [],+    language = "GHC2021",+    ghcOptions = [],+    prelude = Nothing   }  packages :: PackagesConfig
test/Hix/Test/PreprocTest.hs view
@@ -11,7 +11,7 @@ import Hedgehog (TestT, evalMaybe, (===)) import Path (absfile) -import Hix.Preproc (preprocessModule)+import Hix.Preproc (fromCabal, preprocessModule) import Hix.Test.CabalFile (testPackage, testPackageNoPrelude)  pragmas :: Text@@ -27,8 +27,8 @@ preprocTestNoPrelude module_ target =   withFrozenCallStack do     pkg <- liftIO testPackageNoPrelude-    info <- evalMaybe (pkg.condLibrary <&> \ l -> l.condTreeData.libBuildInfo)-    let result = toLazyByteString (preprocessModule [absfile|/foo/bar/Foo.hs|] info "Hix_Dummy" module_)+    conf <- evalMaybe (pkg.condLibrary <&> \ l -> fromCabal l.condTreeData.libBuildInfo)+    let result = toLazyByteString (preprocessModule [absfile|/foo/bar/Foo.hs|] conf "Hix_Dummy" module_)     Text.lines target === Text.lines (decodeUtf8 result)  preprocTest ::@@ -39,8 +39,8 @@ preprocTest module_ target =   withFrozenCallStack do     pkg <- liftIO testPackage-    info <- evalMaybe (pkg.condLibrary <&> \ l -> l.condTreeData.libBuildInfo)-    let result = toLazyByteString (preprocessModule [absfile|/foo/bar/Foo.hs|] info "Hix_Dummy" module_)+    conf <- evalMaybe (pkg.condLibrary <&> \ l -> fromCabal l.condTreeData.libBuildInfo)+    let result = toLazyByteString (preprocessModule [absfile|/foo/bar/Foo.hs|] conf "Hix_Dummy" module_)     Text.lines target === Text.lines (decodeUtf8 result)  moduleInsert :: ByteString