diff --git a/changelog.md b/changelog.md index d9c33ee..eba1d8c 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,8 @@ # Unreleased * Add a reusable workflow for managed bounds updates. +* Parse Nix json output messages to diagnose problems; add overrides for installed packages that fail with a bounds + error printed by Cabal. # 0.7.0: Hix Unbound: Majors Apart diff --git a/packages/hix/hix.cabal b/packages/hix/hix.cabal index 5e59c43..924e3e3 100644 --- a/packages/hix/hix.cabal +++ b/packages/hix/hix.cabal @@ -334,6 +334,7 @@ test-suite hix-test Hix.Test.Managed.BuildOutputTest Hix.Test.Managed.Bump.CandidatesTest Hix.Test.Managed.Bump.MutationTest + Hix.Test.Managed.BumpNativeTest Hix.Test.Managed.DiffTest Hix.Test.Managed.LowerAuto.MutationOptimizeTest Hix.Test.Managed.LowerAuto.MutationStabilizeTest diff --git a/packages/hix/test/Hix/Test/Managed/BumpNativeTest.hs b/packages/hix/test/Hix/Test/Managed/BumpNativeTest.hs new file mode 100644 index 0000000..3398fe8 --- /dev/null +++ b/packages/hix/test/Hix/Test/Managed/BumpNativeTest.hs @@ -0,0 +1,135 @@ +module Hix.Test.Managed.BumpNativeTest where + +import Control.Monad.Trans.Reader (ask) +import qualified Data.Text.IO as Text +import Exon (exon) +import Hedgehog (evalEither) +import Path (Abs, Dir, File, Path, Rel, parent, reldir, relfile, toFilePath, ()) +import Path.IO (createDirIfMissing, getCurrentDir) + +import qualified Hix.Data.Monad +import Hix.Data.Monad (AppResources (AppResources), M (M)) +import Hix.Data.Options (ProjectOptions (query), projectOptions) +import Hix.Error (pathText) +import Hix.Managed.Bump.Optimize (bumpOptimizeMain) +import Hix.Managed.Cabal.Data.Config (GhcDb (GhcDbSystem)) +import qualified Hix.Managed.Data.EnvConfig +import Hix.Managed.Data.EnvConfig (EnvConfig (EnvConfig)) +import Hix.Managed.Data.ManagedPackageProto (ManagedPackageProto, managedPackages) +import Hix.Managed.Data.Packages (Packages) +import qualified Hix.Managed.Data.ProjectContext +import qualified Hix.Managed.Data.ProjectContextProto +import Hix.Managed.Data.ProjectContextProto (ProjectContextProto (ProjectContextProto)) +import qualified Hix.Managed.Data.ProjectResult +import Hix.Managed.Data.ProjectStateProto (ProjectStateProto (ProjectStateProto)) +import qualified Hix.Managed.Data.StateFileConfig +import Hix.Managed.Data.StateFileConfig (StateFileConfig (StateFileConfig)) +import qualified Hix.Managed.Handlers.Build.Prod as Build +import Hix.Managed.ProjectContext (updateProject) +import qualified Hix.Managed.ProjectContextProto as ProjectContextProto +import Hix.Test.Hedgehog (eqLines) +import Hix.Test.Utils (UnitTest, runMTest) + +packages :: Packages ManagedPackageProto +packages = + managedPackages [ + (("root", "1.0"), ["tasty <1.5", "criterion <1.7"]) + ] + +flake :: Path Abs Dir -> Text +flake hixRoot = + [exon|{ + description = "hix test project"; + inputs.hix.url = "path:#{pathText hixRoot}"; + outputs = {self, hix, ...}: hix.lib.flake ({config, lib, ...}: { + managed = { + enable = true; + latest.compiler = "ghc98"; + }; + compat.enable = false; + ghcVersions = []; + packages = { + root = { + src = ./.; + library = { + enable = true; + dependencies = ["tasty" "criterion"]; + }; + }; + }; + envs.latest.localPackage = api: api.minimal; + }); +}|] + +libMod :: Text +libMod = + [exon|module Root where +-- import Test.Tasty (blarkh) +string :: String +string = "hello" +|] + +addFile :: Path Abs Dir -> Path Rel File -> Text -> M () +addFile root path content = do + createDirIfMissing True (parent file) + liftIO (Text.writeFile (toFilePath file) content) + where + file = root path + +setupProject :: M (Path Abs Dir) +setupProject = do + AppResources {tmp} <- M ask + cwd <- getCurrentDir + let projectRoot = tmp [reldir|project|] + let hixRoot = parent (parent cwd) + createDirIfMissing True projectRoot + addFile projectRoot [relfile|flake.nix|] (flake hixRoot) + addFile projectRoot [relfile|lib/Root.hs|] libMod + pure projectRoot + +targetStateFile :: Text +targetStateFile = + [exon|{ + resolving = false; +} +|] + +bumpNativeTest :: M Text +bumpNativeTest = do + root <- setupProject + let + stateFileConf = StateFileConfig { + file = [relfile|ops/managed.nix|], + projectRoot = Just root + } + envsConfig = [("latest", EnvConfig {targets = ["root"], ghc = GhcDbSystem Nothing})] + buildConfig = def + handlers <- Build.handlersProd stateFileConf envsConfig Nothing buildConfig def False + let + opts = (projectOptions ["latest"]) {query = ["tasty"]} + + proto0 = + ProjectContextProto { + packages, + state = ProjectStateProto [] [] mempty mempty False, + envs = envsConfig, + buildOutputsPrefix = Nothing + } + + stateFile = root [relfile|ops/managed.nix|] + + run context process = do + result <- process handlers context + updateProject handlers context.build result + stateFileContent <- liftIO (Text.readFile (toFilePath stateFile)) + pure (result.state, stateFileContent) + + context0 <- ProjectContextProto.validate opts proto0 + (_, stateFileContent) <- run context0 bumpOptimizeMain + pure stateFileContent + +test_bumpNative :: UnitTest +test_bumpNative = do + stateFileContent <- evalEither =<< liftIO do + runMTest True bumpNativeTest + eqLines targetStateFile stateFileContent