Skip to content

REPL command in project requires a target #10684

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

philderbeast
Copy link
Collaborator

@philderbeast philderbeast commented Dec 28, 2024

Fixes #10527 and #9983. Depend-on: #10688.

Doesn't allow an empty list of targets with a project context.

With a project, the REPL command requires a target. If one is not given then a message is shown explaining this and naming the project if the --project-file option was given (but not when the default 'cabal.project' project name is used implicitly). We're not yet able to list project targets so in the meantime, the messages lists the packages of the project.

  • When the implicit default cabal.project is used:
$ cat cabal.project
packages: pkg-one pkg-two

$ cabal repl
Error: [Cabal-7076]
With a project, the REPL command requires a single target. The packages in this
project are:
 - pkg-one
 - pkg-two
  • When the --project-file option is used, the file name is included:
$ cat some.project 
packages: pkg-one pkg-two

$ cabal repl --project-file=some.project
...
Error: [Cabal-7076]
With a project, the REPL command requires a single target. The packages in this
project, 'some.project', are:
 - pkg-one
 - pkg-two
  • When the project has no packages, this is mentioned in the message:
$ cat empty.project

$ cabal repl --project-file=empty.project
...
Error: [Cabal-7076]
There are no packages in 'empty.project'. Please add a package to the project and pick a
single [package:][ctype:]component as target for the REPL command.
  • Before the fix the message mentioned a fake-package-0. This was confusing:
$ ~/.ghcup/bin/cabal-3.12.1.0 repl --project-file=some.project
...
Error: [Cabal-7076]
Internal error when trying to open a repl for the package fake-package-0. The
package is not in the set of available targets for the project plan, which would
suggest an inconsistency between readTargetSelectors and resolveTargets.
  • Earlier cabal-install:exe:cabal versions mentioned using all as the target but this won't work for the REPL command:
$ ~/.ghcup/bin/cabal-3.10.3.0 repl --project-file=some.project
Error: cabal-3.10.3.0: No targets given and there is no package in the current
directory. Use the target 'all' for all packages in the project or specify
packages or components by name or location. See 'cabal build --help' for more
details on target options.

@philderbeast philderbeast marked this pull request as draft December 28, 2024 13:20
@philderbeast philderbeast force-pushed the fix/repl-project-null-target branch 4 times, most recently from 09fcf06 to 6dd178f Compare December 28, 2024 16:31
@philderbeast philderbeast marked this pull request as ready for review December 28, 2024 16:31
@philderbeast philderbeast marked this pull request as draft December 28, 2024 19:48
@philderbeast philderbeast force-pushed the fix/repl-project-null-target branch 2 times, most recently from 2782ef9 to 5a50424 Compare December 29, 2024 16:28
@philderbeast philderbeast force-pushed the fix/repl-project-null-target branch 2 times, most recently from 35477a0 to 1b8edc1 Compare January 12, 2025 12:37
@philderbeast philderbeast force-pushed the fix/repl-project-null-target branch from 1b8edc1 to 2a587e3 Compare March 22, 2025 20:31
@philderbeast philderbeast force-pushed the fix/repl-project-null-target branch from 2a587e3 to 59869f3 Compare April 19, 2025 12:42
@philderbeast philderbeast force-pushed the fix/repl-project-null-target branch from 59869f3 to d34ecf2 Compare June 16, 2025 19:24
@philderbeast philderbeast mentioned this pull request Jun 16, 2025
2 tasks
@philderbeast philderbeast force-pushed the fix/repl-project-null-target branch from d34ecf2 to 80875e2 Compare June 16, 2025 19:52
@philderbeast philderbeast marked this pull request as ready for review June 16, 2025 20:01
@philderbeast
Copy link
Collaborator Author

This pull request will be easier to review once the cfgVerbosity changes are merged.

Copy link
Collaborator

@geekosaur geekosaur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving despite suggestions because they're not functional changes.

@philderbeast philderbeast force-pushed the fix/repl-project-null-target branch 5 times, most recently from 2e359e9 to 88c7a58 Compare June 17, 2025 16:26
Copy link
Collaborator

@ulysses4ever ulysses4ever left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this patch and the test! I have a couple questions...

@mpickering could you take a brief look at this (it's a small patch)? Especially my comment under the -- NOTE:.

Comment on lines 323 to 325
text "There are no packages in"
<+> (project <> char '.')
<+> text "Please add a package to the project and pick a component to use as the target of the REPL command."
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the no-packages case is certainly already handled in other places today, right? (people keep forgetting packages:... and get an error message.) Is it possible to not duplicate this logic?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After removing the target string manipulation, the current behaviour (#9983) is bad and doesn't cover this case:

$ ~/.ghcup/bin/cabal --numeric-version
3.14.2.0

$ ~/.ghcup/bin/cabal repl --project-dir=cabal-testsuite/PackageTests/ReplProjectTarget --project-file=empty.project
Configuration is affected by the following files:
- empty.project
Warning: There are no packages or optional-packages in the project
Resolving dependencies...
Error: [Cabal-7076]
Internal error when trying to open a repl for the package fake-package-0. The package is not in the set of available targets for the project plan, which would suggest an inconsistency between readTargetSelectors and resolveTargets.

Also I'd be curious to know how to get better output from a debug build of cabal-install with assertions enabled because that version gives me a poorer error report with no line number:

$ cabal repl --project-dir=cabal-testsuite/PackageTests/ReplProjectTarget --project-file=empty.project
Warning: this is a debug build of cabal-install with assertions enabled.
Configuration is affected by the following files:
- empty.project
Warning: There are no packages or optional-packages in the project
Resolving dependencies...
Assertion failed

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning: There are no packages or optional-packages in the project

is a different issue, I think, (#8679 probably) so it may be wise to try to avoid solving it here.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assertion failure is bad but also looks like a future work. We're minutes from cutting the 3.16 branch and all backporting will have to go through extra careful consideration (mostly deciding the tradeoff: scarse resource for the release vs profit from performing the backport)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The assertion bothers me. I could cut back on the scope of this pull request or dig in more about the assertion.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the no-packages case is certainly already handled in other places today, right? (people keep forgetting packages:... and get an error message.) Is it possible to not duplicate this logic?

@ulysses4ever, it is handled elsewhere but as a warning:

-- https://github.com/haskell/cabal/issues/6013
when (null (projectPackages projectConfig) && null (projectPackagesOptional projectConfig)) $
warn verbosity "There are no packages or optional-packages in the project"

So in the meantime (as I'm not suppressing the warning) we get both a warning and an error:

$ cabal repl --project-file=empty.project
Warning: this is a debug build of cabal-install with assertions enabled.
Warning: There are no packages or optional-packages in the project
Error: [Cabal-7076]
There are no packages in 'empty.project'. Please add a package to the project and pick a
single [package:][ctype:]component as target for the REPL command.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the warning (unless there's already some way to suppress it, shouldn't the error message change to be a follow-on to it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm OK with the warning and then the error. Scolding, I warned you and now look what has happened, an error!

I feel the better way to fix this would be to suppress the warning.

@mpickering
Copy link
Collaborator

Let me know if you need some help with this @philderbeast

@philderbeast philderbeast force-pushed the fix/repl-project-null-target branch from a49a505 to c9d2b55 Compare July 6, 2025 20:08
@philderbeast
Copy link
Collaborator Author

Thanks @mpickering. I'd like to be able to get a line number for the assertion I'm triggering here on this branch. Is that possible?

Assertion failed with backtrace for cabal init generated package

I'm able to run cabal init for a new package, alter the generated main as follows, add -fno-ignore-asserts to the executable in the .cabal file and then trigger the assertion and get a line number with the stack backtrace.

main :: IO ()
main = do
+   assert False (pure ())
    putStrLn "Hello, Haskell!"
$ cabal run assert
Resolving dependencies...
Build profile: -w ghc-9.12.2 -O1
In order, the following will be built (use -v for more details):
 - assert-0.1.0.0 (exe:assert) (configuration changed)
Configuring executable 'assert' for assert-0.1.0.0...
Preprocessing executable 'assert' for assert-0.1.0.0...
Building executable 'assert' for assert-0.1.0.0...
[1 of 1] Compiling Main             ( app/Main.hs, dist-newstyle/build/x86_64-linux/ghc-9.12.2/assert-0.1.0.0/x/assert/build/assert/assert-tmp/Main.o ) [Optimisation flags changed]
[2 of 2] Linking dist-newstyle/build/x86_64-linux/ghc-9.12.2/assert-0.1.0.0/x/assert/build/assert/assert [Objects changed]
assert: Uncaught exception ghc-internal:GHC.Internal.IO.Exception.AssertionFailed:

Assertion failed

HasCallStack backtrace:
  throwIO, called at libraries/ghc-internal/src/GHC/Internal/IO/Exception.hs:444:5 in ghc-internal:GHC.Internal.IO.Exception
  assert, called at app/Main.hs:7:5 in assert-0.1.0.0-inplace-assert:Main

Assertion failed (without backtrace so far 😢) for cabal-install

On wip/assertion-failed, I've added an assertion to warnIfAssertionsAreEnabled to see if I can trigger an assertion and get back a line number for cabal-install but no luck so far.

$ cabal run cabal-install:exe:cabal -- build all --dry-run
Configuration is affected by the following files:
- cabal.project
Build profile: -w ghc-9.12.2 -O1
In order, the following will be built (use -v for more details):
 - cabal-install-3.17.0.0 (exe:cabal) (configuration changed)
Configuring executable 'cabal' for cabal-install-3.17.0.0...
Preprocessing executable 'cabal' for cabal-install-3.17.0.0...
Building executable 'cabal' for cabal-install-3.17.0.0...
Warning: this is a debug build of cabal-install with assertions enabled.
Assertion failed
Assertion failed

@mpickering
Copy link
Collaborator

@philderbeast I run the test which is failing

-----BEGIN CABAL OUTPUT-----
Resolving dependencies...
-----END CABAL OUTPUT-----
Assertion failed
CallStack (from HasCallStack):
  assert, called at src/Distribution/Client/ProjectOrchestration.hs:1061:3 in cabal-install-3.17.0.0-inplace:Distribution.Client.ProjectOrchestration

which points to this code:

1053 -- | Wrapper around 'ProjectPlanning.pruneInstallPlanToTargets' that adjusts    
1054 -- for the extra unneeded info in the 'TargetsMap'.                             
1055 pruneInstallPlanToTargets                                                       
1056   :: TargetAction                                                               
1057   -> TargetsMap                                                                 
1058   -> ElaboratedInstallPlan                                                      
1059   -> ElaboratedInstallPlan                                                      
1060 pruneInstallPlanToTargets targetActionType targetsMap elaboratedPlan =          
1061   assert (Map.size targetsMap > 0) $                                            
1062     ProjectPlanning.pruneInstallPlanToTargets                                   
1063       targetActionType                                                          
1064       (Map.map (map fst) targetsMap)                                            
1065       elaboratedPlan 

Is that what you are looking for?

@philderbeast philderbeast force-pushed the fix/repl-project-null-target branch from c9d2b55 to 354f434 Compare July 10, 2025 11:35
@philderbeast
Copy link
Collaborator Author

I run the test which is failing

Interesting. Shouldn't all CI runs have a backtrace that points to the same location for the failing assertion?

Validate ubuntu-22.04 ghc-9.8.4 has the backtrace location you shared @mpickering but Validate ubuntu-22.04 ghc-9.12.2 doesn't.

Here's a quick diff of a snippet of the output from those above CI runs (ghc-9.8.4 first in red).

- Assertion failed
- CallStack (from HasCallStack):
-   assert, called at src/Distribution/Client/ProjectOrchestration.hs:1061:3 in cabal-install-3.17.0.0-inplace:Distribution.Client.ProjectOrchestration
+   | Assertion failed
+   |
+ 
+ HasCallStack backtrace:
+   throwIO, called at src/Test/Cabal/Server.hs:213:21 in cabal-testsuite-3-inplace:Test.Cabal.Server

@philderbeast philderbeast force-pushed the fix/repl-project-null-target branch from 354f434 to 9daf2b5 Compare July 15, 2025 14:24
@mpickering
Copy link
Collaborator

I run the test which is failing

Interesting. Shouldn't all CI runs have a backtrace that points to the same location for the failing assertion?

Validate ubuntu-22.04 ghc-9.8.4 has the backtrace location you shared @mpickering but Validate ubuntu-22.04 ghc-9.12.2 doesn't.

Here's a quick diff of a snippet of the output from those above CI runs (ghc-9.8.4 first in red).

- Assertion failed
- CallStack (from HasCallStack):
-   assert, called at src/Distribution/Client/ProjectOrchestration.hs:1061:3 in cabal-install-3.17.0.0-inplace:Distribution.Client.ProjectOrchestration
+   | Assertion failed
+   |
+ 
+ HasCallStack backtrace:
+   throwIO, called at src/Test/Cabal/Server.hs:213:21 in cabal-testsuite-3-inplace:Test.Cabal.Server

Interesting.. I will try when I have a moment to see why this is. I wonder if it's to do with the callstack propagation changes in 9.12.2.

@mpickering
Copy link
Collaborator

@philderbeast I reproduced and fixed the issue with assertions not showing a source location

 {-# LANGUAGE LambdaCase #-}
 {-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE ImplicitParams #-}
 #ifdef GIT_REV
 {-# LANGUAGE TemplateHaskell #-}
 #endif
@@ -301,6 +302,8 @@ import GitHash
   )
 #endif
 
+import Control.Exception.Context
+
 -- We only get our own version number when we're building with ourselves
 cabalVersion :: Version
 #if defined(BOOTSTRAPPED_CABAL)
@@ -535,7 +538,7 @@ topHandlerWith cont prog = do
       cont se
 
     message :: String -> Exception.SomeException -> String
-    message pname (Exception.SomeException se) =
+    message pname e@(Exception.SomeException se) =
       case cast se :: Maybe Exception.IOException of
         Just ioe
           | ioeGetVerbatim ioe ->
@@ -551,11 +554,16 @@ topHandlerWith cont prog = do
                   detail = ioeGetErrorString ioe
                in wrapText $ addErrorPrefix $ pname ++ ": " ++ file ++ detail
         _ ->
-          displaySomeException se ++ "\n"
+          displaySomeException e ++ "\n"
 
 -- | BC wrapper around 'Exception.displayException'.
-displaySomeException :: Exception.Exception e => e -> String
-displaySomeException se = Exception.displayException se
+displaySomeException :: SomeException -> String
+displaySomeException (SomeException e) =
+  case displayExceptionContext ?exceptionContext of
+    "" -> msg
+    dc -> msg ++ "\n\n" ++ dc
+  where
+    msg = displayException e

I can make a ticket and PR next week.

@philderbeast
Copy link
Collaborator Author

I can make a ticket and PR next week.

Awesome thanks @mpickering.

@philderbeast philderbeast force-pushed the fix/repl-project-null-target branch 2 times, most recently from cd67791 to 5271f81 Compare July 25, 2025 12:28
@ulysses4ever
Copy link
Collaborator

@mpickering @philderbeast this patch may fix a regression that people are actively noticing in 3.16.0.0. What's needed to make progress on it, do you have an idea?

@ulysses4ever ulysses4ever linked an issue Jul 29, 2025 that may be closed by this pull request
@philderbeast philderbeast force-pushed the fix/repl-project-null-target branch 2 times, most recently from 396add4 to 0f39587 Compare July 29, 2025 19:20
@philderbeast
Copy link
Collaborator Author

What's needed to make progress on it, do you have an idea?

@ulysses4ever I've pushed an update where I guard against triggering the assertion.

philderbeast and others added 2 commits July 29, 2025 15:58
- Show packages when no --project-file is given
- Handle the case with no packages in the project
- Add a changelog
- Add tests
- Satisfy hlint
- Satisfy fourmolu
- Don't need a target when there is one package
- Adjust target strings for sole package
- Add alt.project tests for ReplOptions
- Silence the 1st withCtx call's verbosity
- Don't repeat configuration is affected by
- Satisfy whitespace
- Fixups after rebase
- Remove punct variable
- Comma with but joining indep' clauses
- Use single package

Co-Authored-By: brandon s allbery kf8nh <[email protected]>
@philderbeast philderbeast force-pushed the fix/repl-project-null-target branch from 01140ec to 8d8d6d6 Compare July 29, 2025 19:58
@ulysses4ever
Copy link
Collaborator

Cool, thanks! Let's see what CI says.

Any chance you could squash some of those commits?

@philderbeast philderbeast force-pushed the fix/repl-project-null-target branch from 8d8d6d6 to 6f3f178 Compare July 29, 2025 20:07
@philderbeast
Copy link
Collaborator Author

I missed updating a test. The update in the test output is:

$ git diff
...
 # checking repl command with an 'empty.project' with no packages
 # cabal repl
 Warning: There are no packages or optional-packages in the project
-Resolving dependencies...
+Error: [Cabal-7076]
+There are no packages in 'empty.project'. Please add a package to the project and pick a
+ single [package:][ctype:]component as target for the REPL command.

@philderbeast philderbeast force-pushed the fix/repl-project-null-target branch from 6f3f178 to f23c5be Compare July 30, 2025 11:12
- Improve test descriptions
- Mention [package:][ctype:]component
- Don't repeat [package:][ctype:]component
- Lift validatedTargets, rename r as replFlags
- Don't use -XRecordWildCards for configFlags
- Add a one.project one pkg test
- Remove target string manipulation
- Make reportProjectNoTarget a function
- Redo ReplProjectTarget tests
- Redo ReplProjectNoneTarget tests
- Satisfy fix-whitespace
- Error whether or not project has packages
- Guard against triggering an assertion if targets are null
@philderbeast philderbeast force-pushed the fix/repl-project-null-target branch from f23c5be to b16a443 Compare July 30, 2025 11:52
@philderbeast philderbeast requested a review from mpickering July 31, 2025 14:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

cabal repl (3.16.0.0) silently fails Internal error message for cabal repl within project scope
4 participants