haskell / cabal

Official upstream development repository for Cabal and cabal-install
https://haskell.org/cabal
Other
1.61k stars 691 forks source link

`cabal new-haddock` produces no documentation for single module executables #5890

Open int-e opened 5 years ago

int-e commented 5 years ago

With the following .cabal file (and any Main.hs),

name: nodoc
version: 0
build-type: Simple
cabal-version: >= 1.2

executable nodoc
  main-is: Main.hs
  other-modules:
  build-depends: base

no documentation is produced by cabal new-haddock --haddock-executables. As soon as one adds at least one module to the other-modules specification, documentation is generated, including the Main module.

$ cabal --version
cabal-install version 2.4.1.0
compiled using version 2.4.1.0 of the Cabal library
$ haddock --version
Haddock version 2.20.0, (c) Simon Marlow 2006
Ported to use the GHC API by David Waern 2006-2008
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 8.4.2
hvr commented 5 years ago

I suspect that the hasValidHaddockTargets predicate in 338c3581db7b83686ce67c6ff9aec0b10cf50f56 might need some tweaking...

cc @typedrat

int-e commented 5 years ago

The hasValidHaddockTargets predicate is defined as

        hasHaddocks = not (null (elabPkgDescription ^. componentModules name))

Arguably, it's the componentModules getter (of which at the time of writing hasHaddocks is the sole user) that is wrong, since it fails to include the main module name. The root cause may be the following misleading comment (and function name) in Distribution.Types.Executable:

-- | Get all the module names from an exe
exeModules :: Executable -> [ModuleName]
exeModules exe = otherModules (buildInfo exe)

Evidently, the function returns neither the main module name, nor the names of any generated modules.

Using the exeModules function, Distribution.Simple.BuildTarget and Distribution.Client.TargetSelector both define identical internal componentModules functions:

componentModules :: Component -> [ModuleName]
-- TODO: Use of 'explicitLibModules' here is a bit wrong:
-- a user could very well ask to build a specific signature
-- that was inherited from other packages.  To fix this
-- we have to plumb 'LocalBuildInfo' through this code.
-- Fortunately, this is only used by 'pkgComponentInfo'
-- Please don't export this function unless you plan on fixing
-- this.

-- [interestingly, there is a different comment D.C.TargetSelector]:
-- I think it's unlikely users will ask to build a requirement
-- which is not mentioned locally.

componentModules (CLib   lib)   = explicitLibModules lib
componentModules (CFLib  flib)  = foreignLibModules flib
componentModules (CExe   exe)   = exeModules exe
componentModules (CTest  test)  = testModules test
componentModules (CBench bench) = benchmarkModules bench

which is the template used for defining componentModules getter in Cabal.Distribution.Types.PackageDescription.Lens.

Btw, it's not so easy to find the actual main module name. It's usually Main, but for ghc, Cabal supports overriding it with ghc's -main-is flag. See exeMainModuleName in Cabal.Distribution.Simple.GHC.

andreasabel commented 2 years ago

Me too, trying @phadej's example at:

cabal v1-haddock --all

leaves the HTML docs in dist/....

cabal v2-haddock --haddock-all

succeeds but does not produce any HTMLs.

To Joe User, this is a regression.

phadej commented 2 years ago

I'd say --haddock-all, --haddock-tests etc are in a way redundant and confusing flags, which shouldn't exist. all and tests are unambiguous targets.

Whether this is a regression or not is semantics, but I hope we can agree that UX is bad.

elldritch commented 2 years ago

I don't think this is merely an issue with all or tests not selecting the nodoc target as expected. I just ran across this bug, and it looks like no documentation is generated even if you explicitly select the executable target with cabal haddock exe:nodoc.