hix 0.5.0 → 0.5.2
raw patch · 9 files changed
+117/−59 lines, 9 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ Hix.Component: NoPackage :: Text -> ResolvedPackage
+ Hix.Component: ResolvedPackage :: Bool -> PackageConfig -> ResolvedPackage
+ Hix.Component: data ResolvedPackage
+ Hix.Component: defaultComponent :: PackageConfig -> Either Text Target
+ Hix.Component: instance GHC.Classes.Eq Hix.Component.ResolvedPackage
+ Hix.Component: instance GHC.Generics.Generic Hix.Component.ResolvedPackage
+ Hix.Component: instance GHC.Show.Show Hix.Component.ResolvedPackage
+ Hix.Component: targetComponentOrError :: Maybe (Path Abs Dir) -> PackagesConfig -> TargetSpec -> M Target
+ Hix.Data.ComponentConfig: DefaultTarget :: Target -> TargetOrDefault
+ Hix.Data.ComponentConfig: ExplicitTarget :: Target -> TargetOrDefault
+ Hix.Data.ComponentConfig: NoDefaultTarget :: Text -> TargetOrDefault
+ Hix.Data.ComponentConfig: data TargetOrDefault
+ Hix.Data.ComponentConfig: instance GHC.Classes.Eq Hix.Data.ComponentConfig.TargetOrDefault
+ Hix.Data.ComponentConfig: instance GHC.Generics.Generic Hix.Data.ComponentConfig.TargetOrDefault
+ Hix.Data.ComponentConfig: instance GHC.Show.Show Hix.Data.ComponentConfig.TargetOrDefault
+ Hix.Monad: throwM :: Error -> M a
- Hix.Component: packageDefault :: PackagesConfig -> M PackageConfig
+ Hix.Component: packageDefault :: PackagesConfig -> ResolvedPackage
- Hix.Component: packageForSpecOrDefault :: Path Abs Dir -> PackagesConfig -> Maybe PackageSpec -> M PackageConfig
+ Hix.Component: packageForSpecOrDefault :: Path Abs Dir -> PackagesConfig -> Maybe PackageSpec -> M ResolvedPackage
- Hix.Component: targetComponent :: Maybe (Path Abs Dir) -> PackagesConfig -> TargetSpec -> M Target
+ Hix.Component: targetComponent :: Maybe (Path Abs Dir) -> PackagesConfig -> TargetSpec -> M TargetOrDefault
- Hix.Component: targetComponentIn :: Path Abs Dir -> PackagesConfig -> TargetSpec -> M Target
+ Hix.Component: targetComponentIn :: Path Abs Dir -> PackagesConfig -> TargetSpec -> M TargetOrDefault
- Hix.Component: targetForComponent :: Path Abs Dir -> PackagesConfig -> ComponentCoords -> M Target
+ Hix.Component: targetForComponent :: Path Abs Dir -> PackagesConfig -> ComponentCoords -> M TargetOrDefault
- Hix.Component: targetInPackage :: PackageConfig -> Maybe ComponentSpec -> M Target
+ Hix.Component: targetInPackage :: ResolvedPackage -> Maybe ComponentSpec -> M TargetOrDefault
Files
- hix.cabal +1/−1
- lib/Hix/Component.hs +50/−28
- lib/Hix/Data/ComponentConfig.hs +8/−0
- lib/Hix/Env.hs +8/−4
- lib/Hix/Ghci.hs +2/−2
- lib/Hix/Monad.hs +8/−4
- lib/Hix/Preproc.hs +3/−3
- test/Hix/Test/PreprocTest.hs +35/−17
- test/Main.hs +2/−0
hix.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: hix-version: 0.5.0+version: 0.5.2 synopsis: Haskell/Nix development build tools description: See https://hackage.haskell.org/package/hix/docs/Hix.html category: Build
lib/Hix/Component.hs view
@@ -1,7 +1,5 @@ module Hix.Component where -import Control.Monad.Trans.Class (lift)-import Control.Monad.Trans.Except (throwE) import Data.List.Extra (firstJust) import qualified Data.Map.Strict as Map import Data.Map.Strict ((!?))@@ -17,9 +15,10 @@ PackagesConfig, SourceDir (SourceDir), Target (Target),+ TargetOrDefault (DefaultTarget, ExplicitTarget, NoDefaultTarget), ) import Hix.Data.Error (Error (EnvError), pathText)-import Hix.Monad (M, noteEnv)+import Hix.Monad (M, noteEnv, throwM) import qualified Hix.Options as Options import Hix.Options ( ComponentCoords,@@ -29,6 +28,12 @@ ) import Hix.Path (rootDir) +data ResolvedPackage =+ ResolvedPackage Bool PackageConfig+ |+ NoPackage Text+ deriving stock (Eq, Show, Generic)+ tryPackageByDir :: PackagesConfig -> Path Rel Dir ->@@ -45,10 +50,10 @@ packageByDir config dir = noteEnv [exon|No package at this directory: #{pathText dir}|] (tryPackageByDir config dir) -packageDefault :: PackagesConfig -> M PackageConfig+packageDefault :: PackagesConfig -> ResolvedPackage packageDefault = \case- [(_, pkg)] -> pure pkg- _ -> lift (throwE (EnvError "Project has more than one package, specify -p or -f."))+ [(_, pkg)] -> ResolvedPackage False pkg+ _ -> NoPackage "Project has more than one package, specify -p or -f." packageForSpec :: Path Abs Dir ->@@ -72,10 +77,10 @@ Path Abs Dir -> PackagesConfig -> Maybe PackageSpec ->- M PackageConfig+ M ResolvedPackage packageForSpecOrDefault root config = \case- Just pkg -> packageForSpec root config pkg- Nothing -> packageDefault config+ Just pkg -> ResolvedPackage True <$> packageForSpec root config pkg+ Nothing -> pure (packageDefault config) matchComponent :: ComponentConfig -> ComponentSpec -> Bool matchComponent candidate (ComponentSpec name dir) =@@ -95,29 +100,35 @@ testComponent = ComponentSpec "test" (Just (SourceDir [reldir|test|])) +defaultComponent :: PackageConfig -> Either Text Target+defaultComponent package = do+ component <- maybeToRight (undecidableComponentError package.name) (selectComponent package.components)+ pure Target {sourceDir = Nothing, ..}+ where+ selectComponent [(_, comp)] = Just comp+ selectComponent (Map.elems -> comps) = find (match testComponent) comps+ match = flip matchComponent+ targetInPackage ::- PackageConfig ->+ ResolvedPackage -> Maybe ComponentSpec ->- M Target-targetInPackage package = \case- Just comp -> do- component <- noteEnv (componentError package.name comp) (find match (Map.elems package.components))- pure Target {sourceDir = Nothing, ..}- where- match cand = matchComponent cand comp- Nothing -> do- component <- noteEnv (undecidableComponentError package.name) (selectComponent package.components)- pure Target {sourceDir = Nothing, ..}- where- selectComponent [(_, comp)] = Just comp- selectComponent (Map.elems -> comps) = find (match testComponent) comps- match = flip matchComponent+ M TargetOrDefault+targetInPackage (ResolvedPackage _ package) (Just comp) = do+ component <- noteEnv (componentError package.name comp) (find match (Map.elems package.components))+ pure (ExplicitTarget (Target {sourceDir = Nothing, ..}))+ where+ match cand = matchComponent cand comp+targetInPackage (ResolvedPackage True package) Nothing =+ either (throwM . EnvError) pure (ExplicitTarget <$> defaultComponent package)+targetInPackage (ResolvedPackage False package) Nothing = do+ either (pure . NoDefaultTarget) pure (DefaultTarget <$> defaultComponent package)+targetInPackage (NoPackage err) _ = pure (NoDefaultTarget err) targetForComponent :: Path Abs Dir -> PackagesConfig -> ComponentCoords ->- M Target+ M TargetOrDefault targetForComponent root config spec = do package <- packageForSpecOrDefault root config spec.package targetInPackage package spec.component@@ -147,18 +158,29 @@ Path Abs Dir -> PackagesConfig -> TargetSpec ->- M Target+ M TargetOrDefault targetComponentIn root config = \case TargetForComponent spec -> targetForComponent root config spec TargetForFile spec ->- targetForFile root config spec+ ExplicitTarget <$> targetForFile root config spec targetComponent :: Maybe (Path Abs Dir) -> PackagesConfig -> TargetSpec ->- M Target+ M TargetOrDefault targetComponent cliRoot config spec = do root <- rootDir cliRoot targetComponentIn root config spec++targetComponentOrError ::+ Maybe (Path Abs Dir) ->+ PackagesConfig ->+ TargetSpec ->+ M Target+targetComponentOrError cliRoot config spec =+ targetComponent cliRoot config spec >>= \case+ ExplicitTarget t -> pure t+ DefaultTarget t -> pure t+ NoDefaultTarget err -> throwM (EnvError err)
lib/Hix/Data/ComponentConfig.hs view
@@ -106,3 +106,11 @@ sourceDir :: Maybe SourceDir } deriving stock (Eq, Show, Generic)++data TargetOrDefault =+ ExplicitTarget Target+ |+ DefaultTarget Target+ |+ NoDefaultTarget Text+ deriving stock (Eq, Show, Generic)
lib/Hix/Env.hs view
@@ -5,7 +5,7 @@ import Hix.Component (targetComponent) import qualified Hix.Data.ComponentConfig-import Hix.Data.ComponentConfig (EnvRunner (EnvRunner), PackagesConfig, Target (Target))+import Hix.Data.ComponentConfig (EnvRunner (EnvRunner), PackagesConfig, TargetOrDefault (DefaultTarget, ExplicitTarget)) import Hix.Data.Error (pathText) import qualified Hix.Data.GhciConfig import Hix.Json (jsonConfig)@@ -13,14 +13,18 @@ import qualified Hix.Options as Options import Hix.Options (EnvRunnerOptions, TargetSpec) +-- TODO when there is a solution for default command env fallback configuration, the DefaultTarget case must return+-- Nothing when the config requests it componentRunner :: Maybe (Path Abs Dir) -> PackagesConfig -> TargetSpec -> M (Maybe EnvRunner)-componentRunner cliRoot config spec = do- Target {component} <- targetComponent cliRoot config spec- pure component.runner+componentRunner cliRoot config spec =+ targetComponent cliRoot config spec <&> \case+ ExplicitTarget t -> t.component.runner+ DefaultTarget t -> t.component.runner+ _ -> Nothing envRunner :: EnvRunnerOptions -> M EnvRunner envRunner opts = do
lib/Hix/Ghci.hs view
@@ -13,7 +13,7 @@ import System.IO (hClose) import System.Posix.User (getLoginName) -import Hix.Component (targetComponent)+import Hix.Component (targetComponentOrError) import qualified Hix.Data.ComponentConfig import Hix.Data.ComponentConfig ( ComponentConfig,@@ -103,7 +103,7 @@ assemble opt = do config <- either pure jsonConfig opt.config root <- rootDir opt.root- Target {..} <- targetComponent opt.root config.packages opt.component+ Target {..} <- targetComponentOrError opt.root config.packages opt.component script <- ghciScript config package sourceDir opt pure GhciTest { script,
lib/Hix/Monad.hs view
@@ -15,21 +15,25 @@ type M a = ReaderT Env (ExceptT Error IO) a +throwM :: Error -> M a+throwM =+ lift . throwE+ noteEnv :: Text -> Maybe a -> M a noteEnv err =- maybe (lift (throwE (EnvError err))) pure+ maybe (throwM (EnvError err)) pure noteGhci :: Text -> Maybe a -> M a noteGhci err =- maybe (lift (throwE (GhciError err))) pure+ maybe (throwM (GhciError err)) pure noteNew :: Text -> Maybe a -> M a noteNew err =- maybe (lift (throwE (NewError err))) pure+ maybe (throwM (NewError err)) pure noteBootstrap :: Text -> Maybe a -> M a noteBootstrap err =- maybe (lift (throwE (BootstrapError err))) pure+ maybe (throwM (BootstrapError err)) pure runM :: Path Abs Dir -> M a -> IO (Either Error a) runM root ma =
lib/Hix/Preproc.hs view
@@ -22,7 +22,7 @@ import System.Random (randomRIO) import Hix.Cabal (buildInfoForFile)-import Hix.Component (targetComponent)+import Hix.Component (targetComponentOrError) import qualified Hix.Data.ComponentConfig import Hix.Data.ComponentConfig (PreludeConfig, PreludePackage (PreludePackageName, PreludePackageSpec)) import Hix.Data.Error (Error (..), sourceError, tryIO)@@ -201,7 +201,7 @@ preludeRegex :: Regex preludeRegex =- [regex|^import\s+(?:qualified\s+)?((?:"[^"]+"\s+)?)(Prelude)|]+ [regex|^import\s+(?:qualified\s+)?((?:"[^"]+"\s+)?)(Prelude\b)(?:$|[^.])|] replacePrelude :: ByteString -> Prelude -> Maybe ByteString replacePrelude l Prelude {..}@@ -453,7 +453,7 @@ M CabalConfig fromConfig cliRoot source pconf = do conf <- either pure jsonConfig pconf- target <- targetComponent cliRoot conf.packages (TargetForFile source)+ target <- targetComponentOrError cliRoot conf.packages (TargetForFile source) pure CabalConfig { extensions = stringUtf8 <$> target.component.language : target.component.extensions, ghcOptions = stringUtf8 <$> target.component.ghcOptions,
test/Hix/Test/PreprocTest.hs view
@@ -9,16 +9,21 @@ ) import Exon (exon) import Hedgehog (TestT, evalMaybe, (===))-import Path (absfile)- import Hix.Preproc (fromCabal, preprocessModule) import Hix.Test.CabalFile (testPackage, testPackageNoPrelude)+import Path (absfile) pragmas :: Text pragmas = [exon|{-# options_ghc -Wall -Wunused-imports #-} {-# language Haskell2010, AllowAmbiguousTypes, NoApplicativeDo #-}|] +header :: Text+header =+ [exon|#{pragmas}+{-# language PackageImports, NoImplicitPrelude #-}+{-# line 1 "/foo/bar/Foo.hs" #-}|]+ preprocTestNoPrelude :: HasCallStack => ByteString ->@@ -61,9 +66,7 @@ targetInsert :: Text targetInsert =- [exon|#{pragmas}-{-# language PackageImports, NoImplicitPrelude #-}-{-# line 1 "/foo/bar/Foo.hs" #-}+ [exon|#{header} {-# language OverloadedLabels #-} module Foo (Hix_Dummy,@@ -109,9 +112,7 @@ targetReplace :: Text targetReplace =- [exon|#{pragmas}-{-# language PackageImports, NoImplicitPrelude #-}-{-# line 1 "/foo/bar/Foo.hs" #-}+ [exon|#{header} {-# language OverloadedLabels #-} module Foo (Hix_Dummy,@@ -147,9 +148,7 @@ targetSingleLineModule :: Text targetSingleLineModule =- [exon|#{pragmas}-{-# language PackageImports, NoImplicitPrelude #-}-{-# line 1 "/foo/bar/Foo.hs" #-}+ [exon|#{header} module Foo where import "incipit-base" IncipitBase as Prelude {-# line 2 "/foo/bar/Foo.hs" #-}@@ -174,9 +173,7 @@ targetSelfExport :: Text targetSelfExport =- [exon|#{pragmas}-{-# language PackageImports, NoImplicitPrelude #-}-{-# line 1 "/foo/bar/Foo.hs" #-}+ [exon|#{header} module Foo (module Foo) where import "incipit-base" IncipitBase as Prelude {-# line 2 "/foo/bar/Foo.hs" #-}@@ -205,9 +202,7 @@ targetSelfExport2 :: Text targetSelfExport2 =- [exon|#{pragmas}-{-# language PackageImports, NoImplicitPrelude #-}-{-# line 1 "/foo/bar/Foo.hs" #-}+ [exon|#{header} module Foo ( module Bar, module Foo,@@ -243,3 +238,26 @@ test_preprocNoPrelude :: TestT IO () test_preprocNoPrelude = preprocTestNoPrelude moduleNoPrelude targetNoPrelude++modulePreludePrefix :: ByteString+modulePreludePrefix =+ [exon|module Main where+import Preludes+import Prelude.Foo+|]++targetPreludePrefix :: Text+targetPreludePrefix =+ [exon|#{header}+module Main where+import "incipit-base" IncipitBase as Prelude+{-# line 2 "/foo/bar/Foo.hs" #-}+import Preludes+import Prelude.Foo+type Hix_Dummy = Int+{-# line 4 "/foo/bar/Foo.hs" #-}+|]++test_preprocPreludePrefix :: TestT IO ()+test_preprocPreludePrefix =+ preprocTest modulePreludePrefix targetPreludePrefix
test/Main.hs view
@@ -8,6 +8,7 @@ import Hix.Test.PreprocTest ( test_preprocInsertPrelude, test_preprocNoPrelude,+ test_preprocPreludePrefix, test_preprocReplacePrelude, test_preprocSelfExport, test_preprocSelfExport2,@@ -36,6 +37,7 @@ unitTest "self exporting module, inline" test_preprocSelfExport, unitTest "self exporting module, separate line" test_preprocSelfExport2, unitTest "self exporting module, separate line" test_preprocNoPrelude,+ unitTest "modules starting with 'Prelude'" test_preprocPreludePrefix, unitTest "run ghcid" test_ghcid, unitTest "component env" test_componentEnv, unitTest "extract module name from path" test_moduleName,