1 {-# LANGUAGE DeriveGeneric #-}
2 {-# LANGUAGE FlexibleContexts #-}
3 {-# LANGUAGE NamedFieldPuns #-}
4 {-# LANGUAGE RankNTypes #-}
6 -----------------------------------------------------------------------------
9 -- Module : Distribution.Simple.Haddock
10 -- Copyright : Isaac Jones 2003-2005
13 -- Maintainer : cabal-devel@haskell.org
14 -- Portability : portable
16 -- This module deals with the @haddock@ and @hscolour@ commands.
17 -- It uses information about installed packages (from @ghc-pkg@) to find the
18 -- locations of documentation for dependent packages, so it can create links.
20 -- The @hscolour@ support allows generating HTML versions of the original
21 -- source, with coloured syntax highlighting.
22 module Distribution
.Simple
.Haddock
30 import Distribution
.Compat
.Prelude
33 import qualified Distribution
.Simple
.GHC
as GHC
34 import qualified Distribution
.Simple
.GHCJS
as GHCJS
38 import Distribution
.Backpack
(OpenModule
)
39 import Distribution
.Backpack
.DescribeUnitId
40 import Distribution
.InstalledPackageInfo
(InstalledPackageInfo
)
41 import qualified Distribution
.InstalledPackageInfo
as InstalledPackageInfo
42 import qualified Distribution
.ModuleName
as ModuleName
43 import Distribution
.Package
44 import Distribution
.PackageDescription
45 import Distribution
.Parsec
(simpleParsec
)
46 import Distribution
.Pretty
47 import Distribution
.Simple
.Build
48 import Distribution
.Simple
.BuildPaths
49 import Distribution
.Simple
.BuildTarget
50 import Distribution
.Simple
.Compiler
51 import Distribution
.Simple
.Flag
52 import Distribution
.Simple
.Glob
(matchDirFileGlob
)
53 import Distribution
.Simple
.InstallDirs
54 import Distribution
.Simple
.LocalBuildInfo
hiding (substPathTemplate
)
55 import qualified Distribution
.Simple
.PackageIndex
as PackageIndex
56 import Distribution
.Simple
.PreProcess
57 import Distribution
.Simple
.Program
58 import Distribution
.Simple
.Program
.GHC
59 import qualified Distribution
.Simple
.Program
.HcPkg
as HcPkg
60 import Distribution
.Simple
.Program
.ResponseFile
61 import Distribution
.Simple
.Register
62 import Distribution
.Simple
.Setup
.Haddock
63 import Distribution
.Simple
.Setup
.Hscolour
64 import Distribution
.Simple
.Utils
65 import Distribution
.System
66 import Distribution
.Types
.ComponentLocalBuildInfo
67 import Distribution
.Types
.ExposedModule
68 import Distribution
.Types
.LocalBuildInfo
69 import Distribution
.Types
.TargetInfo
70 import Distribution
.Utils
.NubList
71 import qualified Distribution
.Utils
.ShortText
as ShortText
72 import Distribution
.Version
74 import Distribution
.Verbosity
75 import Language
.Haskell
.Extension
77 import Distribution
.Compat
.Semigroup
(All
(..), Any
(..))
80 import Data
.Either (rights
)
82 import Distribution
.Simple
.Errors
83 import System
.Directory
(doesDirectoryExist, doesFileExist, getCurrentDirectory)
84 import System
.FilePath (isAbsolute
, normalise
, (<.>), (</>))
85 import System
.IO (hClose, hPutStrLn, hSetEncoding
, utf8
)
87 -- ------------------------------------------------------------------------------
90 -- | A record that represents the arguments to the haddock executable, a product
92 data HaddockArgs
= HaddockArgs
93 { argInterfaceFile
:: Flag
FilePath
94 -- ^ Path to the interface file, relative to argOutputDir, required.
95 , argPackageName
:: Flag PackageIdentifier
96 -- ^ Package name, required.
97 , argHideModules
:: (All
, [ModuleName
.ModuleName
])
98 -- ^ (Hide modules ?, modules to hide)
99 , argIgnoreExports
:: Any
100 -- ^ Ignore export lists in modules?
101 , argLinkSource
:: Flag
(Template
, Template
, Template
)
102 -- ^ (Template for modules, template for symbols, template for lines).
103 , argLinkedSource
:: Flag
Bool
104 -- ^ Generate hyperlinked sources
105 , argQuickJump
:: Flag
Bool
106 -- ^ Generate quickjump index
107 , argCssFile
:: Flag
FilePath
108 -- ^ Optional custom CSS file.
109 , argContents
:: Flag
String
110 -- ^ Optional URL to contents page.
111 , argGenContents
:: Flag
Bool
112 -- ^ Generate contents
113 , argIndex
:: Flag
String
114 -- ^ Optional URL to index page.
115 , argGenIndex
:: Flag
Bool
117 , argBaseUrl
:: Flag
String
118 -- ^ Optional base url from which static files will be loaded.
120 , argOutput
:: Flag
[Output
]
121 -- ^ HTML or Hoogle doc or both? Required.
122 , argInterfaces
:: [(FilePath, Maybe String, Maybe String, Visibility
)]
123 -- ^ [(Interface file, URL to the HTML docs and hyperlinked-source for links)].
124 , argOutputDir
:: Directory
125 -- ^ Where to generate the documentation.
126 , argTitle
:: Flag
String
127 -- ^ Page title, required.
128 , argPrologue
:: Flag
String
129 -- ^ Prologue text, required for 'haddock', ignored by 'haddocks'.
130 , argPrologueFile
:: Flag
FilePath
131 -- ^ Prologue file name, ignored by 'haddock', optional for 'haddocks'.
132 , argGhcOptions
:: GhcOptions
133 -- ^ Additional flags to pass to GHC.
134 , argGhcLibDir
:: Flag
FilePath
135 -- ^ To find the correct GHC, required.
136 , argReexports
:: [OpenModule
]
137 -- ^ Re-exported modules
138 , argTargets
:: [FilePath]
139 -- ^ Modules to process.
140 , argLib
:: Flag
String
141 -- ^ haddock's static \/ auxiliary files.
145 -- | The FilePath of a directory, it's a monoid under '(</>)'.
146 newtype Directory
= Dir
{unDir
' :: FilePath} deriving (Read, Show, Eq
, Ord
)
148 unDir
:: Directory
-> FilePath
149 unDir
= normalise
. unDir
'
151 type Template
= String
153 data Output
= Html | Hoogle
156 -- ------------------------------------------------------------------------------
159 -- | Get Haddock program and check if it matches the request
166 -- ^ quickjump feature
167 -> IO (ConfiguredProgram
, Version
)
168 getHaddockProg verbosity programDb comp args quickJumpFlag
= do
173 hoogle
= Hoogle `
elem` fromFlagOrDefault
[] argOutput
175 (haddockProg
, version
, _
) <-
176 requireProgramVersion
179 (orLaterVersion
(mkVersion
[2, 0]))
182 -- various sanity checks
183 when (hoogle
&& version
< mkVersion
[2, 2]) $
184 dieWithException verbosity NoSupportForHoogle
186 when (fromFlag argQuickJump
&& version
< mkVersion
[2, 19]) $ do
187 let msg
= "Haddock prior to 2.19 does not support the --quickjump flag."
188 alt
= "The generated documentation won't have the QuickJump feature."
189 if Flag
True == quickJumpFlag
190 then dieWithException verbosity NoSupportForQuickJumpFlag
191 else warn verbosity
(msg
++ "\n" ++ alt
)
193 haddockGhcVersionStr
<-
198 case (simpleParsec haddockGhcVersionStr
, compilerCompatVersion GHC comp
) of
199 (Nothing
, _
) -> dieWithException verbosity NoGHCVersionFromHaddock
200 (_
, Nothing
) -> dieWithException verbosity NoGHCVersionFromCompiler
201 (Just haddockGhcVersion
, Just ghcVersion
)
202 | haddockGhcVersion
== ghcVersion
-> return ()
203 |
otherwise -> dieWithException verbosity
$ HaddockAndGHCVersionDoesntMatch ghcVersion haddockGhcVersion
205 return (haddockProg
, version
)
208 :: PackageDescription
213 haddock pkg_descr _ _ haddockFlags
214 |
not (hasLibs pkg_descr
)
215 && not (fromFlag
$ haddockExecutables haddockFlags
)
216 && not (fromFlag
$ haddockTestSuites haddockFlags
)
217 && not (fromFlag
$ haddockBenchmarks haddockFlags
)
218 && not (fromFlag
$ haddockForeignLibs haddockFlags
) =
219 warn
(fromFlag
$ haddockVerbosity haddockFlags
) $
220 "No documentation was generated as this package does not contain "
221 ++ "a library. Perhaps you want to use the --executables, --tests,"
222 ++ " --benchmarks or --foreign-libraries flags."
223 haddock pkg_descr lbi suffixes flags
' = do
224 let verbosity
= flag haddockVerbosity
226 platform
= hostPlatform lbi
228 quickJmpFlag
= haddockQuickJump flags
'
229 flags
= case haddockTarget
of
230 ForDevelopment
-> flags
'
233 { haddockHoogle
= Flag
True
234 , haddockHtml
= Flag
True
235 , haddockHtmlLocation
= Flag
(pkg_url
++ "/docs")
236 , haddockContents
= Flag
(toPathTemplate pkg_url
)
237 , haddockLinkedSource
= Flag
True
238 , haddockQuickJump
= Flag
True
240 pkg_url
= "/package/$pkg-$version"
241 flag f
= fromFlag
$ f flags
244 defaultTempFileOptions
245 { optKeepTempFiles
= flag haddockKeepTempFiles
248 fmap toPathTemplate
. flagToMaybe
. haddockHtmlLocation
$
251 fromFlagOrDefault ForDevelopment
(haddockForHackage flags
')
253 libdirArgs
<- getGhcLibDir verbosity lbi
254 -- The haddock-output-dir flag overrides any other documentation placement concerns.
255 -- The point is to give the user full freedom over the location if they need it.
256 let overrideWithOutputDir args
= case haddockOutputDir flags
of
258 Flag dir
-> args
{argOutputDir
= Dir dir
}
260 overrideWithOutputDir
$
263 , fromFlags
(haddockTemplateEnv lbi
(packageId pkg_descr
)) flags
264 , fromPackageDescription haddockTarget pkg_descr
267 (haddockProg
, version
) <-
268 getHaddockProg verbosity
(withPrograms lbi
) comp commonArgs quickJmpFlag
270 -- We fall back to using HsColour only for versions of Haddock which don't
271 -- support '--hyperlinked-sources'.
272 let using_hscolour
= flag haddockLinkedSource
&& version
< mkVersion
[2, 17]
273 when using_hscolour
$
280 (defaultHscolourFlags `mappend` haddockToHscolour flags
)
282 targets
<- readTargetInfos verbosity pkg_descr lbi
(haddockArgs flags
)
287 [] -> allTargetsInBuildOrder
' pkg_descr lbi
291 createInternalPackageDB verbosity lbi
(flag haddockDistPref
)
293 (\f -> foldM_ f
(installedPkgs lbi
) targets
') $ \index target
-> do
294 let component
= targetComponent target
295 clbi
= targetCLBI target
297 preBuildComponent verbosity lbi target
302 { withPackageDB
= withPackageDB lbi
++ [internalPackageDB
]
303 , installedPkgs
= index
306 preprocessComponent pkg_descr component lbi
' clbi
False verbosity suffixes
308 doExe com
= case (compToExe com
) of
310 withTempDirectoryEx verbosity tmpFileOpts
(buildDir lbi
') "tmp" $
321 let exeArgs
' = commonArgs `mappend` exeArgs
332 (fromFlag
$ haddockVerbosity flags
)
333 "Unsupported component, skipping..."
335 -- We define 'smsg' once and then reuse it inside the case, so that
336 -- we don't say we are running Haddock when we actually aren't
337 -- (e.g., Haddock is not run on non-libraries)
343 (packageId pkg_descr
)
344 (componentLocalName clbi
)
345 (maybeComponentInstantiatedWith clbi
)
348 withTempDirectoryEx verbosity tmpFileOpts
(buildDir lbi
) "tmp" $
360 let libArgs
' = commonArgs `mappend` libArgs
361 runHaddock verbosity tmpFileOpts comp platform haddockProg
True libArgs
'
363 pwd
<- getCurrentDirectory
367 inplaceInstalledPackageInfo
369 (flag haddockDistPref
)
371 (mkAbiHash
"inplace")
377 "Registering inplace:\n"
378 ++ (InstalledPackageInfo
.showInstalledPackageInfo ipi
)
386 HcPkg
.defaultRegisterOptions
387 { HcPkg
.registerMultiInstance
= True
390 return $ PackageIndex
.insert ipi
index
393 (flag haddockForeignLibs
)
395 withTempDirectoryEx verbosity tmpFileOpts
(buildDir lbi
') "tmp" $
407 let libArgs
' = commonArgs `mappend` flibArgs
408 runHaddock verbosity tmpFileOpts comp platform haddockProg
True libArgs
'
411 CExe _
-> when (flag haddockExecutables
) (smsg
>> doExe component
) >> return index
412 CTest _
-> when (flag haddockTestSuites
) (smsg
>> doExe component
) >> return index
413 CBench _
-> when (flag haddockBenchmarks
) (smsg
>> doExe component
) >> return index
415 for_
(extraDocFiles pkg_descr
) $ \fpath
-> do
416 files
<- matchDirFileGlob verbosity
(specVersion pkg_descr
) "." fpath
417 for_ files
$ copyFileTo verbosity
(unDir
$ argOutputDir commonArgs
)
419 -- | Execute 'Haddock' configured with 'HaddocksFlags'. It is used to build
420 -- index and contents for documentation of multiple packages.
426 -> HaddockProjectFlags
428 createHaddockIndex verbosity programDb comp platform flags
= do
429 let args
= fromHaddockProjectFlags flags
430 (haddockProg
, _version
) <-
431 getHaddockProg verbosity programDb comp args
(Flag
True)
432 runHaddock verbosity defaultTempFileOptions comp platform haddockProg
False args
434 -- ------------------------------------------------------------------------------
435 -- Contributions to HaddockArgs (see also Doctest.hs for very similar code).
437 fromFlags
:: PathTemplateEnv
-> HaddockFlags
-> HaddockArgs
438 fromFlags env flags
=
441 ( maybe mempty
(All
. not) $
442 flagToMaybe
(haddockInternal flags
)
446 if fromFlag
(haddockLinkedSource flags
)
449 ( "src/%{MODULE/./-}.html"
450 , "src/%{MODULE/./-}.html#%{NAME}"
451 , "src/%{MODULE/./-}.html#line-%{LINE}"
454 , argLinkedSource
= haddockLinkedSource flags
455 , argQuickJump
= haddockQuickJump flags
456 , argCssFile
= haddockCss flags
459 (fromPathTemplate
. substPathTemplate env
)
460 (haddockContents flags
)
461 , argGenContents
= Flag
False
464 (fromPathTemplate
. substPathTemplate env
)
466 , argGenIndex
= Flag
False
467 , argBaseUrl
= haddockBaseUrl flags
468 , argLib
= haddockLib flags
470 maybe mempty
(Any
. (>= deafening
))
472 $ haddockVerbosity flags
474 Flag
$ case [Html | Flag
True <- [haddockHtml flags
]]
475 ++ [Hoogle | Flag
True <- [haddockHoogle flags
]] of
478 , argOutputDir
= maybe mempty Dir
. flagToMaybe
$ haddockDistPref flags
479 , argGhcOptions
= mempty
{ghcOptExtra
= ghcArgs
}
482 ghcArgs
= fromMaybe [] . lookup "ghc" . haddockProgramArgs
$ flags
484 fromHaddockProjectFlags
:: HaddockProjectFlags
-> HaddockArgs
485 fromHaddockProjectFlags flags
=
487 { argOutputDir
= Dir
(fromFlag
$ haddockProjectDir flags
)
488 , argQuickJump
= Flag
True
489 , argGenContents
= Flag
True
490 , argGenIndex
= Flag
True
491 , argPrologueFile
= haddockProjectPrologue flags
492 , argInterfaces
= fromFlagOrDefault
[] (haddockProjectInterfaces flags
)
493 , argLinkedSource
= Flag
True
494 , argLib
= haddockProjectLib flags
497 fromPackageDescription
:: HaddockTarget
-> PackageDescription
-> HaddockArgs
498 fromPackageDescription haddockTarget pkg_descr
=
500 { argInterfaceFile
= Flag
$ haddockName pkg_descr
501 , argPackageName
= Flag
$ packageId
$ pkg_descr
504 "doc" </> "html" </> haddockDirName haddockTarget pkg_descr
507 ShortText
.fromShortText
$
508 if ShortText
.null desc
509 then synopsis pkg_descr
511 , argTitle
= Flag
$ showPkg
++ subtitle
514 desc
= description pkg_descr
515 showPkg
= prettyShow
(packageId pkg_descr
)
517 | ShortText
.null (synopsis pkg_descr
) = ""
518 |
otherwise = ": " ++ ShortText
.fromShortText
(synopsis pkg_descr
)
524 -> ComponentLocalBuildInfo
527 componentGhcOptions verbosity lbi bi clbi odir
=
528 let f
= case compilerFlavor
(compiler lbi
) of
529 GHC
-> GHC
.componentGhcOptions
530 GHCJS
-> GHCJS
.componentGhcOptions
533 "Distribution.Simple.Haddock.componentGhcOptions:"
534 ++ "haddock only supports GHC and GHCJS"
535 in f verbosity lbi bi clbi odir
541 -> ComponentLocalBuildInfo
542 -> Maybe PathTemplate
543 -- ^ template for HTML location
548 mkHaddockArgs verbosity tmp lbi clbi htmlTemplate haddockVersion inFiles bi
= do
549 ifaceArgs
<- getInterfaces verbosity lbi clbi htmlTemplate
551 (componentGhcOptions normal lbi bi clbi
(buildDir lbi
))
552 { -- Noooooooooo!!!!!111
553 -- haddock stomps on our precious .hi
554 -- and .o files. Workaround by telling
555 -- haddock to write them elsewhere.
556 ghcOptObjDir
= toFlag tmp
557 , ghcOptHiDir
= toFlag tmp
558 , ghcOptStubDir
= toFlag tmp
560 `mappend` getGhcCppOpts haddockVersion bi
563 { ghcOptDynLinkMode
= toFlag GhcDynamicOnly
564 , ghcOptFPic
= toFlag
True
565 , ghcOptHiSuffix
= toFlag
"dyn_hi"
566 , ghcOptObjSuffix
= toFlag
"dyn_o"
567 , ghcOptExtra
= hcSharedOptions GHC bi
570 if withVanillaLib lbi
571 then return vanillaOpts
574 then return sharedOpts
575 else dieWithException verbosity MustHaveSharedLibraries
579 { argGhcOptions
= opts
580 , argTargets
= inFiles
581 , argReexports
= getReexports clbi
588 -> ComponentLocalBuildInfo
589 -> Maybe PathTemplate
590 -- ^ template for HTML location
594 fromLibrary verbosity tmp lbi clbi htmlTemplate haddockVersion lib
= do
595 inFiles
<- map snd `
fmap` getLibSourceFiles verbosity lbi lib clbi
608 { argHideModules
= (mempty
, otherModules
(libBuildInfo lib
))
615 -> ComponentLocalBuildInfo
616 -> Maybe PathTemplate
617 -- ^ template for HTML location
621 fromExecutable verbosity tmp lbi clbi htmlTemplate haddockVersion exe
= do
622 inFiles
<- map snd `
fmap` getExeSourceFiles verbosity lbi exe clbi
635 { argOutputDir
= Dir
$ unUnqualComponentName
$ exeName exe
636 , argTitle
= Flag
$ unUnqualComponentName
$ exeName exe
643 -> ComponentLocalBuildInfo
644 -> Maybe PathTemplate
645 -- ^ template for HTML location
649 fromForeignLib verbosity tmp lbi clbi htmlTemplate haddockVersion flib
= do
650 inFiles
<- map snd `
fmap` getFLibSourceFiles verbosity lbi flib clbi
660 (foreignLibBuildInfo flib
)
663 { argOutputDir
= Dir
$ unUnqualComponentName
$ foreignLibName flib
664 , argTitle
= Flag
$ unUnqualComponentName
$ foreignLibName flib
667 compToExe
:: Component
-> Maybe Executable
670 CTest test
@TestSuite
{testInterface
= TestSuiteExeV10 _ f
} ->
673 { exeName
= testName test
675 , exeScope
= ExecutablePublic
676 , buildInfo
= testBuildInfo test
678 CBench bench
@Benchmark
{benchmarkInterface
= BenchmarkExeV10 _ f
} ->
681 { exeName
= benchmarkName bench
683 , exeScope
= ExecutablePublic
684 , buildInfo
= benchmarkBuildInfo bench
692 -> ComponentLocalBuildInfo
693 -> Maybe PathTemplate
694 -- ^ template for HTML location
696 getInterfaces verbosity lbi clbi htmlTemplate
= do
697 (packageFlags
, warnings
) <- haddockPackageFlags verbosity lbi clbi htmlTemplate
698 traverse_
(warn
(verboseUnmarkOutput verbosity
)) warnings
701 { argInterfaces
= packageFlags
704 getReexports
:: ComponentLocalBuildInfo
-> [OpenModule
]
705 getReexports LibComponentLocalBuildInfo
{componentExposedModules
= mods
} =
706 mapMaybe exposedReexport mods
713 getGhcCppOpts haddockVersion bi
=
715 { ghcOptExtensions
= toNubListR
[EnableExtension CPP | needsCpp
]
716 , ghcOptCppOptions
= defines
719 needsCpp
= EnableExtension CPP `
elem` usedExtensions bi
720 defines
= [haddockVersionMacro
]
721 haddockVersionMacro
=
722 "-D__HADDOCK_VERSION__="
723 ++ show (v1
* 1000 + v2
* 10 + v3
)
725 (v1
, v2
, v3
) = case versionNumbers haddockVersion
of
729 (x
: y
: z
: _
) -> (x
, y
, z
)
735 getGhcLibDir verbosity lbi
= do
736 l
<- case compilerFlavor
(compiler lbi
) of
737 GHC
-> GHC
.getLibDir verbosity lbi
738 GHCJS
-> GHCJS
.getLibDir verbosity lbi
739 _
-> error "haddock only supports GHC and GHCJS"
740 return $ mempty
{argGhcLibDir
= Flag l
}
742 -- ------------------------------------------------------------------------------
744 -- | Call haddock with the specified arguments.
755 runHaddock verbosity tmpFileOpts comp platform haddockProg requireTargets args
756 | requireTargets
&& null (argTargets args
) =
758 "Haddocks are being requested, but there aren't any modules given "
759 ++ "to create documentation for."
763 (error "unable to determine haddock version")
764 (programVersion haddockProg
)
765 renderArgs verbosity tmpFileOpts haddockVersion comp platform args
$
766 \(flags
, result
) -> do
767 runProgram verbosity haddockProg flags
769 notice verbosity
$ "Documentation created: " ++ result
778 -> (([String], FilePath) -> IO a
)
780 renderArgs verbosity tmpFileOpts version comp platform args k
= do
781 let haddockSupportsUTF8
= version
>= mkVersion
[2, 14, 4]
782 haddockSupportsResponseFiles
= version
> mkVersion
[2, 16, 2]
783 createDirectoryIfMissingVerbose verbosity
True outputDir
784 case argPrologue args
of
786 withTempFileEx tmpFileOpts outputDir
"haddock-prologue.txt" $
787 \prologueFileName h
-> do
789 when haddockSupportsUTF8
(hSetEncoding h utf8
)
790 hPutStrLn h prologueText
792 let pflag
= "--prologue=" ++ prologueFileName
793 renderedArgs
= pflag
: renderPureArgs version comp platform args
794 if haddockSupportsResponseFiles
800 "haddock-response.txt"
801 (if haddockSupportsUTF8
then Just utf8
else Nothing
)
803 (\responseFileName
-> k
(["@" ++ responseFileName
], result
))
804 else k
(renderedArgs
, result
)
807 ( case argPrologueFile args
of
808 Flag pfile
-> ["--prologue=" ++ pfile
]
811 <> renderPureArgs version comp platform args
812 if haddockSupportsResponseFiles
818 "haddock-response.txt"
819 (if haddockSupportsUTF8
then Just utf8
else Nothing
)
821 (\responseFileName
-> k
(["@" ++ responseFileName
], result
))
822 else k
(renderedArgs
, result
)
824 outputDir
= (unDir
$ argOutputDir args
)
825 isNotArgContents
= isNothing (flagToMaybe
$ argContents args
)
826 isNotArgIndex
= isNothing (flagToMaybe
$ argIndex args
)
827 isArgGenIndex
= fromFlagOrDefault
False (argGenIndex args
)
828 -- Haddock, when generating HTML, does not generate an index if the options
829 -- --use-contents or --use-index are passed to it. See
830 -- https://haskell-haddock.readthedocs.io/en/latest/invoking.html#cmdoption-use-contents
831 isIndexGenerated
= isArgGenIndex
&& isNotArgContents
&& isNotArgIndex
839 | isIndexGenerated
->
844 Hoogle
-> pkgstr
<.> "txt"
846 . fromFlagOrDefault
[Html
]
850 pkgstr
= prettyShow
$ packageName pkgid
851 pkgid
= arg argPackageName
852 arg f
= fromFlag
$ f args
854 renderPureArgs
:: Version
-> Compiler
-> Platform
-> HaddockArgs
-> [String]
855 renderPureArgs version comp platform args
=
857 [ map (\f -> "--dump-interface=" ++ unDir
(argOutputDir args
) </> f
)
861 , if haddockSupportsPackageName
866 [ "--package-name=" ++ prettyShow
(pkgName pkg
)
867 , "--package-version=" ++ prettyShow
(pkgVersion pkg
)
874 , ["--since-qual=external" | isVersion
2 20]
875 , [ "--quickjump" | isVersion
2 19, True <- flagToList
. argQuickJump
$ args
877 , ["--hyperlinked-source" | isHyperlinkedSource
]
878 , (\(All b
, xs
) -> bool
(map (("--hide=" ++) . prettyShow
) xs
) [] b
)
881 , bool
["--ignore-all-exports"] [] . getAny
. argIgnoreExports
$ args
882 , -- Haddock's --source-* options are ignored once --hyperlinked-source is
884 -- See https://haskell-haddock.readthedocs.io/en/latest/invoking.html#cmdoption-hyperlinked-source
885 -- To avoid Haddock's warning, we only set --source-* options if
886 -- --hyperlinked-source is not set.
887 if isHyperlinkedSource
893 [ "--source-module=" ++ m
894 , "--source-entity=" ++ e
897 then ["--source-entity-line=" ++ l
]
903 , maybe [] ((: []) . ("--css=" ++)) . flagToMaybe
. argCssFile
$ args
904 , maybe [] ((: []) . ("--use-contents=" ++)) . flagToMaybe
. argContents
$ args
905 , bool
["--gen-contents"] [] . fromFlagOrDefault
False . argGenContents
$ args
906 , maybe [] ((: []) . ("--use-index=" ++)) . flagToMaybe
. argIndex
$ args
907 , bool
["--gen-index"] [] . fromFlagOrDefault
False . argGenIndex
$ args
908 , maybe [] ((: []) . ("--base-url=" ++)) . flagToMaybe
. argBaseUrl
$ args
909 , bool
[] [verbosityFlag
] . getAny
. argVerbose
$ args
910 , map (\o
-> case o
of Hoogle
-> "--hoogle"; Html
-> "--html")
911 . fromFlagOrDefault
[]
914 , renderInterfaces
. argInterfaces
$ args
915 , (: []) . ("--odir=" ++) . unDir
. argOutputDir
$ args
921 (++ " (internal documentation)")
923 (getAny
$ argIgnoreExports args
)
929 , [ "--optghc=" ++ opt |
let opts
= argGhcOptions args
, opt
<- renderGhcOptions comp platform opts
931 , maybe [] (\l
-> ["-B" ++ l
]) $
932 flagToMaybe
(argGhcLibDir args
) -- error if Nothing?
933 , -- https://github.com/haskell/haddock/pull/547
934 [ "--reexport=" ++ prettyShow r
935 | r
<- argReexports args
939 , maybe [] ((: []) . ("--lib=" ++)) . flagToMaybe
. argLib
$ args
942 renderInterfaces
= map renderInterface
944 renderInterface
:: (FilePath, Maybe FilePath, Maybe FilePath, Visibility
) -> String
945 renderInterface
(i
, html
, hypsrc
, visibility
) =
950 [ [fromMaybe "" html
]
951 , -- only render hypsrc path if html path
952 -- is given and hyperlinked-source is
955 [ case (html
, hypsrc
) of
960 , fromFlagOrDefault
False . argLinkedSource
$ args
->
965 , if haddockSupportsVisibility
976 bool a b c
= if c
then a
else b
977 isVersion major minor
= version
>= mkVersion
[major
, minor
]
979 | isVersion
2 5 = "--verbosity=1"
980 |
otherwise = "--verbose"
981 haddockSupportsVisibility
= version
>= mkVersion
[2, 26, 1]
982 haddockSupportsPackageName
= version
> mkVersion
[2, 16]
983 haddockSupportsHyperlinkedSource
= isVersion
2 17
984 isHyperlinkedSource
=
985 haddockSupportsHyperlinkedSource
986 && fromFlagOrDefault
False (argLinkedSource args
)
988 ---------------------------------------------------------------------------------
990 -- | Given a list of 'InstalledPackageInfo's, return a list of interfaces and
991 -- HTML paths, and an optional warning for packages with missing documentation.
993 :: [InstalledPackageInfo
]
994 -> Maybe (InstalledPackageInfo
-> FilePath)
996 ( [ ( FilePath -- path to interface
998 , Maybe FilePath -- url to html
1000 , Maybe FilePath -- url to hyperlinked
1005 , Maybe String -- warning about
1006 -- missing documentation
1008 haddockPackagePaths ipkgs mkHtmlPath
= do
1011 [ case interfaceAndHtmlPath ipkg
of
1012 Nothing
-> return (Left
(packageId ipkg
))
1013 Just
(interface
, html
) -> do
1017 let hypSrcPath
= htmlPath
</> defaultHyperlinkedSourceDirectory
1018 hypSrcExists
<- doesDirectoryExist hypSrcPath
1020 ( Just
(fixFileUrl htmlPath
)
1022 then Just
(fixFileUrl hypSrcPath
)
1025 Nothing
-> return (Nothing
, Nothing
)
1027 exists
<- doesFileExist interface
1029 then return (Right
(interface
, html
', hypsrc
', Visible
))
1030 else return (Left pkgid
)
1032 , let pkgid
= packageId ipkg
1033 , pkgName pkgid `
notElem` noHaddockWhitelist
1036 let missing
= [pkgid | Left pkgid
<- interfaces
]
1038 "The documentation for the following packages are not "
1039 ++ "installed. No links will be generated to these packages: "
1040 ++ intercalate
", " (map prettyShow missing
)
1041 flags
= rights interfaces
1043 return (flags
, if null missing
then Nothing
else Just warning
)
1045 -- Don't warn about missing documentation for these packages. See #1231.
1046 noHaddockWhitelist
= map mkPackageName
["rts"]
1048 -- Actually extract interface and HTML paths from an 'InstalledPackageInfo'.
1049 interfaceAndHtmlPath
1050 :: InstalledPackageInfo
1051 -> Maybe (FilePath, Maybe FilePath)
1052 interfaceAndHtmlPath pkg
= do
1053 interface
<- listToMaybe (InstalledPackageInfo
.haddockInterfaces pkg
)
1054 html
<- case mkHtmlPath
of
1055 Nothing
-> listToMaybe (InstalledPackageInfo
.haddockHTMLs pkg
)
1056 Just mkPath
-> Just
(mkPath pkg
)
1057 return (interface
, if null html
then Nothing
else Just html
)
1059 -- The 'haddock-html' field in the hc-pkg output is often set as a
1060 -- native path, but we need it as a URL. See #1064. Also don't "fix"
1061 -- the path if it is an interpolated one.
1063 | Nothing
<- mkHtmlPath
1068 -- 'src' is the default hyperlinked source directory ever since. It is
1069 -- not possible to configure that directory in any way in haddock.
1070 defaultHyperlinkedSourceDirectory
= "src"
1075 -> ComponentLocalBuildInfo
1076 -> Maybe PathTemplate
1078 ( [ ( FilePath -- path to interface
1080 , Maybe FilePath -- url to html
1082 , Maybe FilePath -- url to hyperlinked
1087 , Maybe String -- warning about
1088 -- missing documentation
1090 haddockPackageFlags verbosity lbi clbi htmlTemplate
= do
1091 let allPkgs
= installedPkgs lbi
1092 directDeps
= map fst (componentPackageDeps clbi
)
1093 transitiveDeps
<- case PackageIndex
.dependencyClosure allPkgs directDeps
of
1096 dieWithException verbosity
$ HaddockPackageFlags inf
1098 haddockPackagePaths
(PackageIndex
.allPackages transitiveDeps
) mkHtmlPath
1100 mkHtmlPath
= fmap expandTemplateVars htmlTemplate
1101 expandTemplateVars tmpl pkg
=
1102 fromPathTemplate
. substPathTemplate
(env pkg
) $ tmpl
1103 env pkg
= haddockTemplateEnv lbi
(packageId pkg
)
1105 haddockTemplateEnv
:: LocalBuildInfo
-> PackageIdentifier
-> PathTemplateEnv
1106 haddockTemplateEnv lbi pkg_id
=
1107 (PrefixVar
, prefix
(installDirTemplates lbi
))
1108 -- We want the legacy unit ID here, because it gives us nice paths
1109 -- (Haddock people don't care about the dependencies)
1110 : initialPathTemplateEnv
1112 (mkLegacyUnitId pkg_id
)
1113 (compilerInfo
(compiler lbi
))
1116 -- ------------------------------------------------------------------------------
1117 -- hscolour support.
1120 :: PackageDescription
1122 -> [PPSuffixHandler
]
1125 hscolour
= hscolour
' dieNoVerbosity ForDevelopment
1128 :: (String -> IO ())
1129 -- ^ Called when the 'hscolour' exe is not found.
1131 -> PackageDescription
1133 -> [PPSuffixHandler
]
1136 hscolour
' onNoHsColour haddockTarget pkg_descr lbi suffixes flags
=
1137 either (\excep
-> onNoHsColour
$ exceptionMessage excep
) (\(hscolourProg
, _
, _
) -> go hscolourProg
)
1138 =<< lookupProgramVersion
1141 (orLaterVersion
(mkVersion
[1, 8]))
1144 go
:: ConfiguredProgram
-> IO ()
1145 go hscolourProg
= do
1147 "the 'cabal hscolour' command is deprecated in favour of 'cabal "
1148 ++ "haddock --hyperlink-source' and will be removed in the next major "
1151 setupMessage verbosity
"Running hscolour for" (packageId pkg_descr
)
1152 createDirectoryIfMissingVerbose verbosity
True $
1153 hscolourPref haddockTarget distPref pkg_descr
1155 withAllComponentsInBuildOrder pkg_descr lbi
$ \comp clbi
-> do
1156 let tgt
= TargetInfo clbi comp
1157 preBuildComponent verbosity lbi tgt
1158 preprocessComponent pkg_descr comp lbi clbi
False verbosity suffixes
1160 doExe com
= case (compToExe com
) of
1163 hscolourPref haddockTarget distPref pkg_descr
1164 </> unUnqualComponentName
(exeName exe
)
1166 runHsColour hscolourProg outputDir
=<< getExeSourceFiles verbosity lbi exe clbi
1169 (fromFlag
$ hscolourVerbosity flags
)
1170 "Unsupported component, skipping..."
1174 let outputDir
= hscolourPref haddockTarget distPref pkg_descr
</> "src"
1175 runHsColour hscolourProg outputDir
=<< getLibSourceFiles verbosity lbi lib clbi
1178 hscolourPref haddockTarget distPref pkg_descr
1179 </> unUnqualComponentName
(foreignLibName flib
)
1181 runHsColour hscolourProg outputDir
=<< getFLibSourceFiles verbosity lbi flib clbi
1182 CExe _
-> when (fromFlag
(hscolourExecutables flags
)) $ doExe comp
1183 CTest _
-> when (fromFlag
(hscolourTestSuites flags
)) $ doExe comp
1184 CBench _
-> when (fromFlag
(hscolourBenchmarks flags
)) $ doExe comp
1186 stylesheet
= flagToMaybe
(hscolourCSS flags
)
1188 verbosity
= fromFlag
(hscolourVerbosity flags
)
1189 distPref
= fromFlag
(hscolourDistPref flags
)
1191 runHsColour prog outputDir moduleFiles
= do
1192 createDirectoryIfMissingVerbose verbosity
True outputDir
1194 case stylesheet
of -- copy the CSS file
1196 | programVersion prog
>= Just
(mkVersion
[1, 9]) ->
1200 ["-print-css", "-o" ++ outputDir
</> "hscolour.css"]
1201 |
otherwise -> return ()
1202 Just s
-> copyFileVerbose verbosity s
(outputDir
</> "hscolour.css")
1204 for_ moduleFiles
$ \(m
, inFile
) ->
1208 ["-css", "-anchor", "-o" ++ outFile m
, inFile
]
1212 </> intercalate
"-" (ModuleName
.components m
) <.> "html"
1214 haddockToHscolour
:: HaddockFlags
-> HscolourFlags
1215 haddockToHscolour flags
=
1217 { hscolourCSS
= haddockHscolourCss flags
1218 , hscolourExecutables
= haddockExecutables flags
1219 , hscolourTestSuites
= haddockTestSuites flags
1220 , hscolourBenchmarks
= haddockBenchmarks flags
1221 , hscolourForeignLibs
= haddockForeignLibs flags
1222 , hscolourVerbosity
= haddockVerbosity flags
1223 , hscolourDistPref
= haddockDistPref flags
1224 , hscolourCabalFilePath
= haddockCabalFilePath flags
1227 -- ------------------------------------------------------------------------------
1228 -- Boilerplate Monoid instance.
1229 instance Monoid HaddockArgs
where
1233 instance Semigroup HaddockArgs
where
1236 instance Monoid Directory
where
1240 instance Semigroup Directory
where
1241 Dir m
<> Dir n
= Dir
$ m
</> n