packages feed

hix 0.6.2 → 0.6.7

raw patch · 10 files changed

+174/−60 lines, 10 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ Hix.Bootstrap: nonEmptyAttrs :: Text -> [ExprAttr] -> ExprAttr
+ Hix.Bootstrap: notNil :: ExprAttr -> Bool
+ Hix.Data.GhciConfig: [$sel:mainPackage:EnvConfig] :: EnvConfig -> Maybe PackageName
+ Hix.Data.GhciConfig: [$sel:mainPackage:GhciConfig] :: GhciConfig -> Maybe PackageName
+ Hix.Data.GhciTest: [$sel:cmdline:GhciRun] :: GhciRun -> Text
+ Hix.Ghci: argFrag :: Text -> Text
+ Hix.Ghci: optArg :: Maybe Text -> Text
- Hix.Bootstrap: convertComponent :: ComponentType -> BuildInfo -> HixComponent
+ Hix.Bootstrap: convertComponent :: ComponentType -> BuildInfo -> [ExprAttr] -> HixComponent
- Hix.Component: packageDefault :: PackagesConfig -> ResolvedPackage
+ Hix.Component: packageDefault :: Maybe PackageName -> PackagesConfig -> ResolvedPackage
- Hix.Component: packageForSpecOrDefault :: Path Abs Dir -> PackagesConfig -> Maybe PackageSpec -> M ResolvedPackage
+ Hix.Component: packageForSpecOrDefault :: Path Abs Dir -> Maybe PackageName -> PackagesConfig -> Maybe PackageSpec -> M ResolvedPackage
- Hix.Component: targetComponent :: Maybe (Path Abs Dir) -> PackagesConfig -> TargetSpec -> M TargetOrDefault
+ Hix.Component: targetComponent :: Maybe (Path Abs Dir) -> Maybe PackageName -> PackagesConfig -> TargetSpec -> M TargetOrDefault
- Hix.Component: targetComponentIn :: Path Abs Dir -> PackagesConfig -> TargetSpec -> M TargetOrDefault
+ Hix.Component: targetComponentIn :: Path Abs Dir -> Maybe PackageName -> PackagesConfig -> TargetSpec -> M TargetOrDefault
- Hix.Component: targetComponentOrError :: Maybe (Path Abs Dir) -> PackagesConfig -> TargetSpec -> M Target
+ Hix.Component: targetComponentOrError :: Maybe (Path Abs Dir) -> Maybe PackageName -> PackagesConfig -> TargetSpec -> M Target
- Hix.Component: targetForComponent :: Path Abs Dir -> PackagesConfig -> ComponentCoords -> M TargetOrDefault
+ Hix.Component: targetForComponent :: Path Abs Dir -> Maybe PackageName -> PackagesConfig -> ComponentCoords -> M TargetOrDefault
- Hix.Data.GhciConfig: EnvConfig :: PackagesConfig -> EnvRunner -> EnvConfig
+ Hix.Data.GhciConfig: EnvConfig :: PackagesConfig -> EnvRunner -> Maybe PackageName -> EnvConfig
- Hix.Data.GhciConfig: GhciConfig :: PackagesConfig -> Map RunnerName GhciSetupCode -> Map RunnerName GhciRunExpr -> GhciArgs -> GhciConfig
+ Hix.Data.GhciConfig: GhciConfig :: PackagesConfig -> Maybe PackageName -> Map RunnerName GhciSetupCode -> Map RunnerName GhciRunExpr -> GhciArgs -> GhciConfig
- Hix.Data.GhciTest: GhciRun :: GhciTest -> Text -> Maybe Text -> Path Abs File -> GhciRun
+ Hix.Data.GhciTest: GhciRun :: GhciTest -> Text -> Maybe Text -> Path Abs File -> Text -> GhciRun
- Hix.Env: componentRunner :: Maybe (Path Abs Dir) -> PackagesConfig -> TargetSpec -> M (Maybe EnvRunner)
+ Hix.Env: componentRunner :: Maybe (Path Abs Dir) -> Maybe PackageName -> PackagesConfig -> TargetSpec -> M (Maybe EnvRunner)

Files

hix.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           hix-version:        0.6.2+version:        0.6.7 synopsis:       Haskell/Nix development build tools description:    See https://hackage.haskell.org/package/hix/docs/Hix.html category:       Build
lib/Hix/Bootstrap.hs view
@@ -133,11 +133,11 @@  renderExpr :: Int -> Expr -> NonEmpty Text renderExpr ind = \case-  ExprString s -> indent ind [[exon|"#{s}"|]]+  ExprString s -> indent ind [[exon|"#{Text.replace "\"" "\\\"" 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@@ -235,6 +235,17 @@ mkAttrs a e =   (fmap ($ e) a) +notNil :: ExprAttr -> Bool+notNil = \case+  ExprAttrNil -> False+  _ -> True++nonEmptyAttrs :: Text -> [ExprAttr] -> ExprAttr+nonEmptyAttrs key =+  filter notNil >>> \case+    [] -> ExprAttrNil+    as -> ExprAttr key (ExprAttrs as)+ -- TODO extract version and put it in a file knownPackageKeys :: PackageDescription -> [ExprAttr] knownPackageKeys =@@ -243,7 +254,8 @@     single "build-type" buildType,     single "copyright" (.copyright),     single "license" license,-    singleOpt "license-file" (head . licenseFiles)+    singleOpt "license-file" (head . licenseFiles),+    single "version" (.package.pkgVersion)   ]  metaPackageKeys :: PackageDescription -> [ExprAttr]@@ -274,14 +286,22 @@         multi "default-extensions" (.defaultExtensions),         multiOrSingle "source-dirs" (.hsSourceDirs),         singleOpt "language" (.defaultLanguage),-        multi "ghc-options" (filter notDefaultGhcOption . ghcFlavour . (.options))+        multi "ghc-options" (filter notDefaultGhcOption . ghcFlavour . (.options)),+        misc       ] info++    misc e =+      nonEmptyAttrs "component" (mkAttrs [+        multi "other-modules" (.otherModules)+      ] e)+     (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))+        (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)@@ -291,28 +311,32 @@   Cabal.Dependency "base" _ _ -> False   _ -> True -convertComponent :: ComponentType -> BuildInfo -> HixComponent-convertComponent special info =-  HixComponent {..}+convertComponent :: ComponentType -> BuildInfo -> [ExprAttr] -> HixComponent+convertComponent special info extra =+  HixComponent {known = knownCommon <> extra, ..}   where-    (prelude, known) = knownComponentKeys preludeBasic info+    (prelude, knownCommon) = knownComponentKeys preludeBasic info     preludeBasic = findPrelude info.mixins  convertLibrary :: Cabal.Library -> HixComponent convertLibrary lib =-  convertComponent Library lib.libBuildInfo+  convertComponent Library lib.libBuildInfo extra+  where+    extra = mkAttrs [+      multi "reexported-modules" (.reexportedModules)+      ] lib  convertExecutable :: UnqualComponentName -> Cabal.Executable -> HixComponent convertExecutable name exe =-  convertComponent (Executable (toText (unUnqualComponentName name))) exe.buildInfo+  convertComponent (Executable (toText (unUnqualComponentName name))) exe.buildInfo []  convertTestsuite :: UnqualComponentName -> Cabal.TestSuite -> HixComponent convertTestsuite name test =-  convertComponent (Test (toText (unUnqualComponentName name))) test.testBuildInfo+  convertComponent (Test (toText (unUnqualComponentName name))) test.testBuildInfo []  convertBenchmark :: UnqualComponentName -> Cabal.Benchmark -> HixComponent convertBenchmark name bench =-  convertComponent (Benchmark (toText (unUnqualComponentName name))) bench.benchmarkBuildInfo+  convertComponent (Benchmark (toText (unUnqualComponentName name))) bench.benchmarkBuildInfo []  convert :: CabalInfo -> HixPackage convert cinfo =@@ -340,7 +364,7 @@ renderComponent HixComponent {..} =   ExprAttr key cabalConfig   where-    cabalConfig = ExprAttrs (known <> foldMap preludeAttrs prelude)+    cabalConfig = ExprAttrs (enable <> foldMap preludeAttrs prelude <> known)     preludeAttrs p =       [ExprAttr "prelude" (ExprAttrs [         ExprAttr "package" (preludePackageAttrs p),@@ -358,6 +382,9 @@       Executable name -> [exon|executables.#{name}|]       Test name -> [exon|tests.#{name}|]       Benchmark name -> [exon|benchmarks.#{name}|]+    enable = case special of+      Library -> [ExprAttr "enable" (ExprLit "true")]+      _ -> []  flakePackage :: HixPackage -> ExprAttr flakePackage pkg =
lib/Hix/Component.hs view
@@ -50,9 +50,19 @@ packageByDir config dir =   noteEnv [exon|No package at this directory: #{pathText dir}|] (tryPackageByDir config dir) -packageDefault :: PackagesConfig -> ResolvedPackage-packageDefault = \case+packageDefault :: Maybe PackageName -> PackagesConfig -> ResolvedPackage+packageDefault mainPkg = \case+  [] -> NoPackage "Project has no packages."   [(_, pkg)] -> ResolvedPackage False pkg+  pkgs | Just name <- mainPkg ->+    case Map.lookup name pkgs of+      Just pkg ->+        ResolvedPackage False pkg+      Nothing ->+        NoPackage (+          [exon|Project has multiple packages and the main package '##{name}' is not among them. |] <>+          "Specify -p or -f to choose one explicitly."+        )   _ -> NoPackage "Project has more than one package, specify -p or -f."  packageForSpec ::@@ -75,12 +85,13 @@  packageForSpecOrDefault ::   Path Abs Dir ->+  Maybe PackageName ->   PackagesConfig ->   Maybe PackageSpec ->   M ResolvedPackage-packageForSpecOrDefault root config = \case+packageForSpecOrDefault root mainPkg config = \case   Just pkg -> ResolvedPackage True <$> packageForSpec root config pkg-  Nothing -> pure (packageDefault config)+  Nothing -> pure (packageDefault mainPkg config)  matchComponent :: ComponentConfig -> ComponentSpec -> Bool matchComponent candidate (ComponentSpec name dir) =@@ -126,11 +137,12 @@  targetForComponent ::   Path Abs Dir ->+  Maybe PackageName ->   PackagesConfig ->   ComponentCoords ->   M TargetOrDefault-targetForComponent root config spec = do-  package <- packageForSpecOrDefault root config spec.package+targetForComponent root mainPkg config spec = do+  package <- packageForSpecOrDefault root mainPkg config spec.package   targetInPackage package spec.component  targetForFile ::@@ -156,31 +168,34 @@  targetComponentIn ::   Path Abs Dir ->+  Maybe PackageName ->   PackagesConfig ->   TargetSpec ->   M TargetOrDefault-targetComponentIn root config = \case+targetComponentIn root mainPkg config = \case   TargetForComponent spec ->-    targetForComponent root config spec+    targetForComponent root mainPkg config spec   TargetForFile spec ->     ExplicitTarget <$> targetForFile root config spec  targetComponent ::   Maybe (Path Abs Dir) ->+  Maybe PackageName ->   PackagesConfig ->   TargetSpec ->   M TargetOrDefault-targetComponent cliRoot config spec = do+targetComponent cliRoot mainPkg config spec = do   root <- rootDir cliRoot-  targetComponentIn root config spec+  targetComponentIn root mainPkg config spec  targetComponentOrError ::   Maybe (Path Abs Dir) ->+  Maybe PackageName ->   PackagesConfig ->   TargetSpec ->   M Target-targetComponentOrError cliRoot config spec =-  targetComponent cliRoot config spec >>= \case+targetComponentOrError cliRoot mainPkg config spec =+  targetComponent cliRoot mainPkg config spec >>= \case     ExplicitTarget t -> pure t     DefaultTarget t -> pure t     NoDefaultTarget err -> throwM (EnvError err)
lib/Hix/Data/GhciConfig.hs view
@@ -3,7 +3,7 @@ import Data.Aeson (FromJSON, FromJSONKey) import GHC.Exts (IsList) -import Hix.Data.ComponentConfig (EnvRunner, PackagesConfig)+import Hix.Data.ComponentConfig (EnvRunner, PackageName, PackagesConfig)  newtype RunnerName =   RunnerName { unRunnerName :: Text }@@ -32,7 +32,8 @@ data EnvConfig =   EnvConfig {     packages :: PackagesConfig,-    defaultEnv :: EnvRunner+    defaultEnv :: EnvRunner,+    mainPackage :: Maybe PackageName   }   deriving stock (Eq, Show, Generic)   deriving anyclass (FromJSON)@@ -40,6 +41,7 @@ data GhciConfig =   GhciConfig {     packages :: PackagesConfig,+    mainPackage :: Maybe PackageName,     setup :: Map RunnerName GhciSetupCode,     run :: Map RunnerName GhciRunExpr,     args :: GhciArgs
lib/Hix/Data/GhciTest.hs view
@@ -18,7 +18,8 @@     test :: GhciTest,     shell :: Text,     run :: Maybe Text,-    scriptFile :: Path Abs File+    scriptFile :: Path Abs File,+    cmdline :: Text   }   deriving stock (Eq, Show, Generic) 
lib/Hix/Env.hs view
@@ -5,7 +5,12 @@  import Hix.Component (targetComponent) import qualified Hix.Data.ComponentConfig-import Hix.Data.ComponentConfig (EnvRunner (EnvRunner), PackagesConfig, TargetOrDefault (DefaultTarget, ExplicitTarget))+import Hix.Data.ComponentConfig (+  EnvRunner (EnvRunner),+  PackageName,+  PackagesConfig,+  TargetOrDefault (DefaultTarget, ExplicitTarget),+  ) import Hix.Data.Error (pathText) import qualified Hix.Data.GhciConfig import Hix.Json (jsonConfig)@@ -17,11 +22,12 @@ -- Nothing when the config requests it componentRunner ::   Maybe (Path Abs Dir) ->+  Maybe PackageName ->   PackagesConfig ->   TargetSpec ->   M (Maybe EnvRunner)-componentRunner cliRoot config spec =-  targetComponent cliRoot config spec <&> \case+componentRunner cliRoot defaultPkg config spec =+  targetComponent cliRoot defaultPkg config spec <&> \case     ExplicitTarget t -> t.component.runner     DefaultTarget t -> t.component.runner     _ -> Nothing@@ -29,7 +35,8 @@ envRunner :: EnvRunnerOptions -> M EnvRunner envRunner opts = do   config <- either pure jsonConfig opts.config-  fromMaybe config.defaultEnv . join <$> traverse (componentRunner opts.root config.packages) opts.component+  let runner = componentRunner opts.root config.mainPackage config.packages+  fromMaybe config.defaultEnv . join <$> traverse runner opts.component  printEnvRunner :: EnvRunnerOptions -> M () printEnvRunner opts = do
lib/Hix/Ghci.hs view
@@ -32,7 +32,7 @@ import Hix.Monad (M, noteGhci) import qualified Hix.Options as Options import Hix.Options (-  ExtraGhciOptions,+  ExtraGhciOptions (ExtraGhciOptions),   ExtraGhcidOptions (ExtraGhcidOptions),   GhciOptions (GhciOptions),   GhcidOptions,@@ -110,7 +110,7 @@ assemble opt = do   config <- either pure jsonConfig opt.config   root <- rootDir opt.root-  Target {..} <- targetComponentOrError opt.root config.packages opt.component+  Target {..} <- targetComponentOrError opt.root config.mainPackage config.packages opt.component   script <- ghciScript config package sourceDir opt   pure GhciTest {     script,@@ -139,9 +139,16 @@     hClose handle     pure path +argFrag :: Text -> Text+argFrag "" = ""+argFrag s = [exon| #{s}|]++optArg :: Maybe Text -> Text+optArg = foldMap argFrag+ searchPathArg :: NonEmpty (Path Abs Dir) -> Text searchPathArg paths =-  [exon| -i#{colonSeparated}|]+  [exon|-i#{colonSeparated}|]   where     colonSeparated = Text.intercalate ":" (pathText <$> toList paths) @@ -154,10 +161,12 @@ ghciCmdline test extra scriptFile runScriptFile =   GhciRun {..}   where-    shell = [exon|##{Text.unwords (coerce test.args)}#{sp} -ghci-script=##{toFilePath scriptFile}#{extraOpts}|]+    cmdline = [exon|ghci#{shell}#{optArg run}|]+    shell = [exon|#{argFrag args}#{argFrag sp} -ghci-script=##{toFilePath scriptFile}#{argFrag extraOpts}|]+    args = Text.unwords (coerce test.args)     run = runScriptFile <&> \ f -> [exon|-ghci-script=##{toFilePath f}|]     sp = foldMap searchPathArg (nonEmpty test.searchPath)-    extraOpts | Just o <- extra = [exon| ##{o}|]+    extraOpts | Just (ExtraGhciOptions o) <- extra = o               | otherwise = ""  ghciCmdlineFromOptions ::@@ -178,7 +187,7 @@   ghci <- ghciCmdlineFromOptions tmp opt.ghci   let     test = fromMaybe "main" ghci.test.test-  pure (GhcidRun [exon|ghcid --command="ghci #{ghci.shell}" --test='##{test}'#{foldMap extra opt.extra}|] ghci)+  pure (GhcidRun [exon|ghcid --command="ghci#{ghci.shell}" --test='##{test}'#{foldMap extra opt.extra}|] ghci)   where     extra (ExtraGhcidOptions o) = [exon| ##{o}|] 
lib/Hix/Preproc.hs view
@@ -9,6 +9,7 @@ import qualified Data.ByteString.Builder as ByteStringBuilder import Data.ByteString.Builder (Builder, byteString, charUtf8, stringUtf8) import Data.Generics.Labels ()+import qualified Data.Map.Strict as Map import Distribution.PackageDescription (BuildInfo (..)) import Distribution.Simple (PerCompilerFlavor (PerCompilerFlavor)) import qualified Exon@@ -34,7 +35,6 @@ import Hix.Optparse (JsonConfig) import qualified Hix.Prelude as Prelude import Hix.Prelude (Prelude (Prelude), findPrelude)-import qualified Data.Map.Strict as Map  type Regex = IndexedTraversal' Int ByteString Match @@ -461,7 +461,7 @@   M CabalConfig fromConfig cliRoot source pconf = do   conf <- either pure jsonConfig pconf-  target <- targetComponentOrError cliRoot conf.packages (TargetForFile source)+  target <- targetComponentOrError cliRoot Nothing conf.packages (TargetForFile source)   pure CabalConfig {     extensions = stringUtf8 <$> target.component.language : target.component.extensions,     ghcOptions = stringUtf8 <$> target.component.ghcOptions,
test/Hix/Test/BootstrapTest.hs view
@@ -19,7 +19,7 @@  name:           red-panda version:        0.1.0.0-synopsis:       A Haskell project+synopsis:       A Haskell "project" description:    See https://hackage.haskell.org/package/red-panda/docs/RedPanda.html author:         Panda maintainer:     Panda@@ -31,6 +31,7 @@   exposed-modules:       RedPanda   other-modules:+      NormalPanda       Paths_red_panda   autogen-modules:       Paths_red_panda@@ -49,13 +50,12 @@       base hiding (Prelude)     , incipit-base (IncipitBase as Prelude)     , incipit-base hiding (IncipitBase)+  reexported-modules:+      Control.Monad+    , Data.Maybe  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@@ -69,9 +69,6 @@   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@@ -103,12 +100,21 @@           build-type = "Simple";           license = "BSD-2-Clause-Patent";           license-file = "LICENSE";+          version = "0.1.0.0";           meta = {             maintainer = "Panda";-            synopsis = "A Haskell project";+            synopsis = "A Haskell \"project\"";           };         };         library = {+          enable = true;+          prelude = {+            package = {+              name = "incipit-base";+              version = ">=0.4 && <0.6";+            };+            module = "IncipitBase";+          };           dependencies = [             "containers"             "base >=4 && <5"@@ -122,13 +128,16 @@           ghc-options = [             "-Wall"           ];-          prelude = {-            package = {-              name = "incipit-base";-              version = ">=0.4 && <0.6";-            };-            module = "IncipitBase";+          component = {+            other-modules = [+              "NormalPanda"+              "Paths_red_panda"+            ];           };+          reexported-modules = [+            "Control.Monad"+            "Data.Maybe"+          ];         };         executables.red-panda = {           dependencies = [@@ -152,6 +161,11 @@           ghc-options = [             "-Wall"           ];+          component = {+            other-modules = [+              "RedPanda.Test.NameTest"+            ];+          };         };       };     };
test/Hix/Test/GhciTest.hs view
@@ -19,7 +19,7 @@ import Hix.Data.GhciConfig (ChangeDir (ChangeDir), EnvConfig (EnvConfig), GhciConfig (..)) import qualified Hix.Data.GhciTest as GhciTest import Hix.Env (envRunner)-import Hix.Ghci (assemble, ghcidCmdlineFromOptions)+import Hix.Ghci (assemble, ghciCmdlineFromOptions, ghcidCmdlineFromOptions) import Hix.Monad (runM) import qualified Hix.Options as Options import Hix.Options (@@ -95,8 +95,9 @@   GhciOptions {     config = Left GhciConfig {       packages,+      mainPackage = Nothing,       setup = [("generic", "import Test.Tasty")],-      run = [("generic", ("check . property . test"))],+      run = [("generic", "check . property . test")],       args = ["-Werror"]     },     root = Nothing,@@ -132,6 +133,44 @@   cmdline <- evalEither res   ghcidTarget root cmdline.ghci.scriptFile === cmdline.cmdline +mainOptions :: GhciOptions+mainOptions =+  GhciOptions {+    config = Left GhciConfig {+      packages,+      mainPackage = Just "core",+      setup = [("generic", "import Test.Tasty")],+      run = [("generic", "")],+      args = []+    },+    root = Nothing,+    component = TargetForComponent (ComponentCoords Nothing Nothing),+    test = TestOptions {+      mod = "Main",+      test = Nothing,+      runner = Nothing,+      cd = ChangeDir True+    },+    extra = Nothing+  }++mainPackageTarget ::+  Path Abs Dir ->+  Path Abs File ->+  Text+mainPackageTarget cwd scriptFile =+  [exon|ghci -i#{path} -ghci-script=#{pathText scriptFile}|]+  where+    path = [exon|#{dir}packages/core/test/:#{dir}packages/api/lib/:#{dir}packages/core/lib/|]+    dir = pathText cwd++test_mainPackage :: TestT IO ()+test_mainPackage = do+  res <- lift $ withSystemTempDir "hix-test" \ tmp ->+    runM root (ghciCmdlineFromOptions tmp mainOptions)+  cmdline <- evalEither res+  mainPackageTarget root cmdline.scriptFile === cmdline.cmdline+ spec2 :: TargetSpec spec2 =   TargetForFile (root </> [relfile|packages/core/test/Main.hs|])@@ -148,7 +187,7 @@   res <- evalEither =<< liftIO (runM root (envRunner conf))   target === res   where-    conf = EnvRunnerOptions (Left (EnvConfig packages defaultRunner)) Nothing (Just spec)+    conf = EnvRunnerOptions (Left (EnvConfig packages defaultRunner Nothing)) Nothing (Just spec)  test_componentEnv :: TestT IO () test_componentEnv = do