Visitar URL original
--no-main is deprecated · Issue #837 · hspec/hspec · GitHub
Skip to content

--no-main is deprecated #837

Open
Open

Description

@tonyalaribe

I get this warning while compiling:

hspec-discover: WARNING - The `--no-main' option is deprecated and will be removed in a future release!

But my setup doesn't work if the generated spec file contains a main function, because then I would have 2 main functions, which confuses ghcid.

My question is, is there a a different way of enforcing this functionality? Especially if --no-main gets taken out.

Activity

  1. sol commented on May 18, 2023

    @sol
    Member

    Is the issue, that you want to load both the test suite and an executable into a GHCi session?

    If yes, you can put the main of your executable into a driver module like so: https://github.com/sol/markdown-unlit/blob/main/driver/Main.hs

    It should then be possible to load everything into GHCi, except for that driver module.

    If this doesn't work, can you share more details about your exact setup?

    Do you currently run your tests with ghcid?

    Other things that might be relevant:

  2. supki commented on Oct 31, 2024

    @supki
    Contributor

    So, I'm also interested in the alternative to --no-main.

    My usual setup includes a library in src/ and a test-suite in test/ that depends on this library. For some projects, I have to perform certain setup rituals before the tests have any chance to run successfully. These generally amount to a variation of main = bracket_ acquireResources releaseResources (hspec spec) which goes to test/Main.hs which is now the main-is module of the test-suite.

    Now, I'd like to load the test-suite in ghci. Previously, I used stack exec -- ghci test/Main.hs for this, which actually works surprisingly well most of time and doesn't require --no-main at all. Unfortunately, it actually works a bit too well, leading to minor inconsistencies between ghci and hls (and other tooling) that are mildly annoying. But, if I use stack ghci package:lib package:test:spec (which in my experience is less inconsistent with hls), then running main understandably results in Ambiguous occurrence ‘main’, which then means I need the --no-main option.

    I briefly skimmed https://hspec.github.io/hspec-discover.html#spec-hooks and I think it might be a solution to my problem, but I'd rather not add more magic to my tests, there is usually enough as it is :)

    Sorry for the essay; I'd just be sad to see --no-main go away, I found it to be a useful option. :)

  3. sol commented on Nov 7, 2024

    @sol
    Member

    @supki it's still not clear to me what exact code layout you're using.

    Previously, I used stack exec -- ghci test/Main.hs for this, which actually works surprisingly well most of time and doesn't require --no-main at all.

    1. Where exactly would you put your custom setup in this scenario? Can you provide example code?

    if I use stack ghci package:lib package:test:spec (which in my experience is less inconsistent with hls), then running main understandably results in Ambiguous occurrence ‘main’, which then means I need the --no-main option.

    1. Where is the second main defined? Again, can you provide example code?
    2. Personally, I prefer stack exec -- ghci / cabal exec -- ghci over stack ghci / cabal repl in most situations.
  4. supki commented on Nov 7, 2024

    @supki
    Contributor

    Yeah, sure, I actually noticed the warning while working on https://github.com/supki/relocant. The project uses a typical layout (for me). It is pretty small so I think it can be used as an example as is.

    The setup is in https://github.com/supki/relocant/blob/ac9032c4c0ec2e2b1aa1686d8a2ebb7305f975d1/test/Main.hs. This module defines main and is the entry point into the test-suite (https://github.com/supki/relocant/blob/ac9032c4c0ec2e2b1aa1686d8a2ebb7305f975d1/package.yaml#L89). The Spec module (https://github.com/supki/relocant/blob/ac9032c4c0ec2e2b1aa1686d8a2ebb7305f975d1/test/Spec.hs) requires -optF --no-main for me to be able to run :main after stack ghci relocant:lib relocant:test:spec.

    (I generally agree on stack exec -- ghci, but that just trades one set of annoyances for another (e.g., ghci defaulting to -XGHC2021 recently))

  5. sol commented on Nov 8, 2024

    @sol
    Member

    I'm still confused why this wouldn't work.

    Can you please try:

    $ stack ghci relocant:lib relocant:test:spec
    ghci> :module Main
    ghci> main
    1. Does this work?
    2. Can you try if there are any differences between :main and main in that regard?
    3. Also, can you check the output of :show imports?
  6. supki commented on Nov 8, 2024

    @supki
    Contributor
    1. It does.
    2. Both work, I don't see any differences, but I also don't use :main much beyond the --match option. It seems unlikely that some specific functionality is broken but not :main itself? I'm not sure.
    3. Here's the log:
    %  stack ghci relocant:lib relocant:test:spec --ghci-options -ignore-dot-ghci
    ...
    ghci> :show imports
    import Meta_relocant
    import Paths_relocant
    import Relocant
    import Relocant.App
    import Relocant.App.Env
    import Relocant.App.Log
    import Relocant.App.Opts
    import Relocant.App.Opts.Fmt
    import Relocant.App.Opts.Internal
    import Relocant.App.Opts.Option
    import Relocant.App.ToText
    import Relocant.App.ToTextSpec
    import Relocant.Applied
    import Relocant.AppliedSpec
    import Relocant.At
    import Relocant.Checksum
    import Relocant.Content
    import Relocant.DB
    import Relocant.DB.Table
    import Relocant.Duration
    import Relocant.DurationSpec
    import Relocant.ID
    import Relocant.Merge
    import Relocant.MergeSpec
    import Relocant.Name
    import Relocant.Script
    import Relocant.ScriptSpec
    import Spec
    import SpecHelper.DB
    :module +*Main -- added automatically
    ghci> :module Main
    ghci> :show imports
    import Main
    import Prelude -- implicit
    

    So, not exactly convenient as a solution, but it can be used as a fallback, if --no-main disappears tomorrow.

  7. sol commented on Nov 8, 2024

    @sol
    Member

    OK, at least it's now clear what's happening.

    stack ghci imports all your modules unqualified. That's why both Main.main and Spec.main are in scope, resulting in the name clash.

    As a workaround you have the following options:

    1. Use --no-main, which is deprecated. I am not in a rush to remove it, but I am also not eager to jump through hoops if it gets inconvenient.
    2. Use Main.main instead of main (this will probably not work with :main, but you could use System.Environment.withArgs [...] Main.main if you're inclined)
    3. Initially issue :module Main. This should survive a :reload, so you will only have to issue it once. It should also be possible to add it to a project local .ghci file.

    But what I really recommend is adding something along the lines of:

    -- file test/SpecHook.hs
    module SpecHook where
    
    import Test.Hspec
    import Control.Exception (bracket_)
    import SpecHelper.DB qualified as DB
    
    withTemplate :: IO () -> IO ()
    withTemplate = bracket_ DB.createTemplate DB.dropTemplate
    
    hook :: Spec -> Spec
    hook = aroundAll_ withTemplate

    This approach also has the advantage that e.g. --dry-run does not hit the database.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions