Stack: Stack ghci should start with a project, even if there are two

Created on 28 Sep 2015  ·  19Comments  ·  Source: commercialhaskell/stack

C:\Neil\ghcid>stack ghci
* * * * * * * *
The main module to load is ambiguous. Candidates are:
Package `ghcid' component exe:ghcid with main-is file: C:\Neil\ghcid\src\Ghcid.hs
Package `ghcid' component test:ghcid_test with main-is file: C:\Neil\ghcid\src\Test.hs
None will be loaded. You can specify which one to pick by:
 1) Specifying targets to stack ghci e.g. stack ghci ghcid:exe:ghcid
 2) Specifying what the main is e.g. stack ghci --main-is ghcid:exe:ghcid
* * * * * * * *

This error is a little annoying - it says it's not going to do anything useful, and the two ways of picking the useful behaviours are both quite annoying - they require me to remember command line flags every time. Instead, how about:

  • Always default to whichever is first in the .cabal file lexically, then people can reorder their .cabal file to indicate a preference.
  • Add a facility to add an entry to stack.yaml to record a default.
awaiting pull request ghci newcomer friendly discuss enhancement

Most helpful comment

I restart ghci maybe every 10 mins. I drop in and out of it quickly. I also use ghcid which runs it headless. Anything which requires interactive behaviour on every start up is unworkable for me.

Starting with nothing loaded is also problematic - I now have to :load the right thing, which is complex user interaction, and often different per project. With my existing .ghci scripts all this works out nicely.

All 19 comments

I think a PR to make this a nicer would be welcome, although should probably have a bit of discussion before deciding on the exact solution.

I'll take a stab at a possible solution: (the wording here would obviously need some retooling:

$ stack ghci
* * * * * * * *
The main module to load is ambiguous. Candidates are:
[0] Package `ghcid' component exe:ghcid with main-is file: C:\Neil\ghcid\src\Ghcid.hs
 1  Package `ghcid' component test:ghcid_test with main-is file: C:\Neil\ghcid\src\Test.hs
 You can specify which one to pick by:
 1) Specifying targets to stack ghci e.g. stack ghci ghcid:exe:ghcid
 2) Specifying what the main is e.g. stack ghci --main-is ghcid:exe:ghcid
 3) Choose (0, 1): 

Effectively communicate the same information and supply a prompt to choose between the options, with empty string defaulting to the first.

@gambogi, for things like ghcid that doesn't really help. I'd still like it to not require user interaction - if it does I'll still have to write a separate script to start ghci.

@ndmitchell I liked your original idea of setting the default in stack.yaml. I think we should modify the message to let the user know that they can set a default in stack.yaml too.

@gambogi If you have not started working on this yet, I would definitely be willing to give this one a shot.

@achernyak all yours

It seems a bit magical to me to add default targets for ghci. If such a thing is added, maybe it'd make sense to also have it affect stack build. I.e. default-targets: pkg1 pkg2, would affect both build and ghci.

I like @gambogi 's suggestion, since GHCi is interactive, it seems fine to me to ask the user for input. If the user doesn't enter (0) or (1) and just presses enter, then we should get the current behavior (load neither). The main issue with adding this interactivity is if editor integrations don't expect it. Could be good to have a flag that disables the behavior..

So, feel free to implement @gambogi 's idea, and possibly open an issue about having a default-targets setting.

Also, from the original issue:

This error is a little annoying - it says it's not going to do anything useful, and the two ways of picking the useful behaviours are both quite annoying - they require me to remember command line flags every time.

It isn't true that it isn't going to do anything useful. It's just not going to load any Main modules. So, I don't think there should be a magic default - I don't like picking something random just because the choice is ambiguous. This leads to circumstances where users aren't sure why one thing works and another does not.

@mgsloan Thanks for the direction. I will work towards your proposed solution.

I restart ghci maybe every 10 mins. I drop in and out of it quickly. I also use ghcid which runs it headless. Anything which requires interactive behaviour on every start up is unworkable for me.

Starting with nothing loaded is also problematic - I now have to :load the right thing, which is complex user interaction, and often different per project. With my existing .ghci scripts all this works out nicely.

@mgsloan if that's the enter behavior it should probably appear first in the list of options (with its status as the default noted).

I don't like the arbitrary feeling of "pick the first viable Main.hs". I do see the value of a sensible default, though. How about this approach to picking one:

1) If there's only one executable component among stack ghci's targets. In other words, even if you're compiling benchmarks and tests, it will default to loading the executable Main.hs, if there's only one.

2) Failing that, if there's only one non-library component among stack ghci's targets, pick that. I think the current logic already does this.

@gambogi In that case, how would the user ask for "don't load any Main.hs"?

I'm thinking the list should be ordered such that executable components come before test / benchmark.

@mgsloan I agree with you that "don't load any Main.hs" should be an option. My point was it should be clear from the presented dialog that it is the first (and default on Enter) option.

Ohh, I see! Yes, I agree with that.

If we do add the defaulting, one issue is how to get back to having an interactive option. Might need a flag like --pick-main for this, argh! So, leaning towards not having a default.. But I would like to support @ndmitchell 's usecase well.

Maybe we're going about this the wrong way. There is already a great place to put ghci specific options, namely a .ghci file. The problem is that GHC loads the .ghci file from the current directory first, so anything it does gets clobbered by the Stack .ghci file. Maybe stack ghci could run your .ghci file last, rather than first, which probably involves passing the option to ignore the .ghci file and then copying the contents onto the end of the Stack generated .ghci file. That gives me the extra-info free way of getting at what I want. Alternatively maybe the stack.yaml could have a .ghci-post section?

For the time being I am going to add interactivity with the default being do nothing. If we decide to add additional flags later, that can be part of a separate issue.

@ndmitchell I am trying to reproduce this right now, but can't seem to get the same message you got.

I tried both in a freshly created repo and directly in ghcid. Could you share anything extra that you did to get this behavior?

I think it no longer reproduces directly due to the resolution of https://github.com/commercialhaskell/stack/issues/1186#issuecomment-151724839. Now, it only defaults to loading the same things that stack build defaults to building (libraries and executables). So, to get the old behavior where Main.hs is ambiguous, you need to specify both, like stack ghci :ghcid :ghcid_test, or stack ghci --test.

Thanks, stack ghci --test did the trick.

@ndmitchell There's a remaining bug before stack ghci works perfectly with ghcid: https://github.com/commercialhaskell/stack/issues/1606

Was this page helpful?
0 / 5 - 0 ratings