cabal
cabal copied to clipboard
`cabal new-haddock` produces no documentation for single module executables
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
I suspect that the hasValidHaddockTargets predicate in 338c3581db7b83686ce67c6ff9aec0b10cf50f56 might need some tweaking...
cc @typedrat
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.
Me too, trying @phadej's example at:
- https://github.com/haskell-CI/haskell-ci/pull/582#issuecomment-1113991712
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.
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.
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.