cabal icon indicating copy to clipboard operation
cabal copied to clipboard

"configuration changed" is way too vague

Open 9999years opened this issue 1 year ago • 10 comments

In order, the following will be built:
 - my-0.1 (lib:my) (configuration changed)

What do you mean the configuration changed? How did the configuration change?

Notes

I've investigated this problem a bit. Here are my notes; they'll be useful to anyone interested in fixing this. Producing a diff of the ElaboratedConfiguredPackages (and keeping the code to do so up-to-date when that record gets a new field) is the hard part.

"configuration changed" comes from showBuildStatus in cabal-install/src/Distribution/Client/ProjectOrchestration.hs.

Ultimately it comes when the ElaboratedConfiguredPackage changes. ElaboratedConfiguredPackage is defined in cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs.

Equality of file monitors determined in newPackageFileMonitor in cabal-install/src/Distribution/Client/ProjectBuilding/PackageFileMonitor.hs.

FileMonitor's fileMonitorKeyValid field should return a Maybe ChangedReason or something like that. (I'm making up ChangedReason, could be a String, could be a structured diff...)

IMO the tricky part is keeping the diff display code up-to-date when someone adds or changes a field to ElaboratedConfiguredPackage (or any type contained in ElaboratedConfiguredPackage!).

We don't have tree-diff in scope RN (maybe we could vendor some minimal subset of it?), so we can't automatically generate a diff

9999years avatar Dec 06 '24 22:12 9999years

The ghost of #9476 walks again!

geekosaur avatar Dec 06 '24 23:12 geekosaur

This is the error I'm seeing in a CI run, https://github.com/haskell/cabal/actions/runs/12138982850/job/33845593860?pr=10546, that I'm not seeing when I run the same test locally (on Windows):

Actual output differs from expected:

stderr:
--- "D:\\a\\_temp\\cabal-testsuite-9832\\cabal.dist\\cabal.out.normalized"	2024-12-03 12:34:26.194758500 +0000
+++ "D:\\a\\_temp\\cabal-testsuite-9832\\cabal.dist\\cabal.comp.out.normalized"	2024-12-03 12:34:26.193763000 +0000
@@ -651,7 +651,12 @@
     imported by: woops/woops-1.config
     imported by: woops-0.project
 Resolving dependencies...
-Up to date
+Build profile: -w ghc-<GHCVER> -O1
+In order, the following will be built:
+ - my-0.1 (lib:my) (configuration changed)
+Configuring my-0.1...
+Preprocessing library for my-0.1...
+Building library for my-0.1...
 # checking "using config from message" without URI imports
 # cabal v2-build
 # checking "using config from message" with URI imports

*** unexpected failure for PackageTests\ConditionalAndImport\cabal.test.hs

philderbeast avatar Dec 07 '24 00:12 philderbeast

And that's pretty much what I was thinking of; I've seen it in CI as well.

geekosaur avatar Dec 07 '24 01:12 geekosaur

@geekosaur, I was seeing this with #10546. I was using the same project twice in cabal-testsuite/PackageTests/ConditionalAndImport/cabal.test.hs. Using the project only once avoids the problem.

I was accessing the same project from two different directories:

  log "checking if we detect when the same config is imported via many different paths (we don't)"
  woopping <- cabal' "v2-build" [ "--project-file=woops-0.project" ]
  log "checking \"using config from message\" with URI imports"
  withDirectory "woops" $ do
    woopping <- fails $ cabal' "v2-build" [ "--dry-run", "--project-file=../woops-0.project" ]

    -- Use assertRegex when the output is tainted by the temp directory, like
    -- this:
    --
    --   When using configuration from:
    --   - /tmp/cabal-testsuite-282695/woops-0.project
    --   - /tmp/cabal-testsuite-282695/woops-2.config etc
    assertRegex
      "Project configuration with URI imports is listed in full"
      "When using configuration from:(\n|\r\n) \
        \ .*woops-0\\.project(\n|\r\n) \
        \ .*with-ghc\\.config(\n|\r\n) \
        \ .*woops-2\\.config(\n|\r\n) \
        \ .*woops-4\\.config(\n|\r\n) \
        \ .*woops-6\\.config(\n|\r\n) \
        \ .*woops-8\\.config(\n|\r\n) \
        \ .*woops-1\\.config(\n|\r\n) \
        \ .*woops-3\\.config(\n|\r\n) \
        \ .*woops-5\\.config(\n|\r\n) \
        \ .*woops-7\\.config(\n|\r\n) \
        \ .*woops-9\\.config(\n|\r\n) \
        \ .*https://www.stackage.org/lts-21.25/cabal.config(\n|\r\n)"
      woopping

    assertOutputContains
      "The following errors occurred: \
      \  - The package directory '.' does not contain any .cabal file."
      woopping

    return ()

philderbeast avatar Dec 09 '24 13:12 philderbeast

Thing is, I occasionally see it with tests that weren't changed by the PR, and generally on only one platform.

geekosaur avatar Dec 09 '24 14:12 geekosaur

@philderbeast For an example spurious 'configuration changed', see: https://github.com/haskell/cabal/pull/10524#discussion_r1874086603.

Excerpt (NB this is about code in #10524, not code on master):

The package configuration now includes the project file path:

ElaboratedConfiguredPackage
    { elabUnitId = UnitId "my-0.1-inplace"
    -- ...
    , elabPkgSourceLocation = WithConstraintSource
        { constraintInner = LocalUnpackedPackage "<ROOT>/."
        , constraintSource = ConstraintSourceProjectConfig
            ( ProjectConfigPath
                ( "noncyclical-same-filename-a.project" :| [] )
            )
        }
    -- ...
    }

Therefore, when we rebuild with a different --project-file, it changes the configuration.

9999years avatar Dec 09 '24 17:12 9999years

Thanks @9999years. Putting related tests in the same folder using projects seems risky.

philderbeast avatar Dec 09 '24 17:12 philderbeast

So this happens when the full, expanded configuration changes. This could mean a lot of things! Here's an easy solution: we write an ediff of the old and new values to a file under dist-newstyle and print the path to that file so anyone interested in debugging "configuration changed" can cat it.

Or we could just write a "describe configured package diff" function, which maybe wouldn't be too hard?

9999years avatar Dec 17 '24 05:12 9999years

It's been almost a year but IIRC I tried the "easy solution" I suggested in the previous comment and found it wasn't easy because getting the tree-diff stuff in scope to use ediff or similar was very challenging.

9999years avatar Nov 20 '25 00:11 9999years

using cabal build -v3 gives more information about what changed, e.g. File monitor 'compiler' changed clued me in that I had a .ghc.environment.* file from the wrong version of ghc lying around.

the other possible explanations seem to be File monitor 'config' changed, File monitor 'improved-plan' changed, and File monitor 'elaborated-plan' changed. I renamed a module in my my-package.cabal files, but I did not touch the list of dependencies, so I don't quite understand how that caused the "improved" or "elaborated" plan to change in a way which causes the dependencies of my-package (I'm in a multi-package project) to need a rebuild 🤷

edit: I found the documentation of the monitors.

In my case, it turns out it was because I was running VS Code and cabal build with two different configurations. When I was running cabal build, my $CABAL_CONFIG was set a /nix/store/.../cabal.config path from my nix environment, while HLS was configured (via "haskell.serverEnvironment" in settings.json) with "CABAL_CONFIG" set to /home/<my-username>/.cabal/config.