commercialhaskell / stack

The Haskell Tool Stack
http://haskellstack.org
BSD 3-Clause "New" or "Revised" License
3.95k stars 842 forks source link

Understand relationship between `stack repl` and Cabal (the library) `repl` #6548

Open mpilgrem opened 2 months ago

mpilgrem commented 2 months ago

Motivation:

Is there a reason that Stack avoids the use of Cabal (the library) repl (from Cabal >= 2.2)?

Context: Stack.Build.ExecutePackage.realConfigAndBuild (extracts):

        case ( ee.buildOptsCLI.onlyConfigure
             , ee.buildOptsCLI.initialBuildSteps && taskIsTarget task
             ) of
          ...
          (_, True) | null ac.downstream || installedMapHasThisPkg -> do
            initialBuildSteps cabal announce
...
 where
  ...
  initialBuildSteps cabal announce = do
    announce ("initial-build-steps" <> display annSuffix)
    cabal KeepTHLoading ["repl", "stack-initial-build-steps"]

Stack.GhciCmd.ghciCmd (extracts):

ghciCmd ghciOpts =
  let boptsCLI = defaultBuildOptsCLI
        { ...
        , initialBuildSteps = True
        ...
        }
  in  withConfig YesReexec $ withEnvConfig AllowNoTargets boptsCLI $ do
        bopts <- view buildOptsL
        -- override env so running of tests and benchmarks is disabled
        let boptsLocal = bopts
              { testOpts = bopts.testOpts { TestOpts.disableRun = True }
              , benchmarkOpts =
                  bopts.benchmarkOpts { BenchmarkOpts.disableRun = True }
              }
        local (set buildOptsL boptsLocal) (ghci ghciOpts)

Stack.GhciCmd.ghci (extracts):

-- | Launch a GHCi session for the given project package targets with the given
-- options and configure it with the load paths and extensions of those targets.
ghci :: HasEnvConfig env => GhciOpts -> RIO env ()
ghci opts = do
  ...  
  -- Build required dependencies and setup project packages.
  buildDepsAndInitialSteps opts $
    concatMap (\(pn, (_, t)) -> pkgTargets pn t) localTargets
  ...
  -- Finally, do the invocation of ghci
  runGhci
    opts
    localTargets
    mainFile
    pkgs
    (maybe [] snd mfileTargets)
    (nonLocalTargets ++ addPkgs)
    relevantDependencies

History:

mpilgrem commented 2 months ago

In respect of Cabal (the library) repl, it is undocumented (https://github.com/haskell/cabal/issues/8906) at https://cabal.readthedocs.io/en/stable/setup-commands.html. At the command line:

> stack --snapshot lts-12.0 runghc -- Setup.hs repl --help
Open an interpreter session for the given component.

Usage: Setup.hs repl [COMPONENT] [FLAGS]

If the current directory contains no package, ignores COMPONENT parameters and
opens an interactive interpreter session; if a sandbox is present, its package
database will be used.

Otherwise, (re)configures with the given or default flags, and loads the
interpreter with the relevant modules. For executables, tests and benchmarks,
loads the main module (and its dependencies); for libraries all exposed/other
modules.

The default component is the library itself, or the executable if that is the
only component.

Support for loading specific modules is planned but not implemented yet. For
certain scenarios, `Setup.hs exec -- ghci :l Foo` may be used instead. Note
that `exec` will not (re)configure and you will have to specify the location
of other modules, if required.

Flags for repl:
 -h --help              Show this help text
 -v --verbose[=n]       Control verbosity (n is 0--3, default verbosity level
                        is 1)
    --builddir=DIR      The directory where Cabal puts generated build files
                        (default dist)
    --with-PROG=PATH    give the path to PROG
    --PROG-option=OPT   give an extra option to PROG (no need to quote options
                        containing spaces)
    --PROG-options=OPTS give extra options to PROG

Examples:
  Setup.hs repl               The first component in the package
  Setup.hs repl foo           A named component (i.e. lib, exe, test suite)
  Setup.hs repl --ghc-options="-lstdc++"  Specifying flags for interpreter

stack --snapshot nightly-2024-04-03 runghc -- Setup.hs repl --help (GHC 9.8.2, Cabal-3.10.2.0) is the same, except for:

--repl-no-load                 Disable loading of project modules at REPL
                               startup.
--repl-options=FLAG            Use the option(s) for the repl