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
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 when (flag haddockLinkedSource
&& version
< mkVersion
[2, 17]) $
279 (defaultHscolourFlags `mappend` haddockToHscolour flags
)
281 targets
<- readTargetInfos verbosity pkg_descr lbi
(haddockArgs flags
)
286 [] -> allTargetsInBuildOrder
' pkg_descr lbi
290 createInternalPackageDB verbosity lbi
(flag haddockDistPref
)
292 (\f -> foldM_ f
(installedPkgs lbi
) targets
') $ \index target
-> do
293 let component
= targetComponent target
294 clbi
= targetCLBI target
296 componentInitialBuildSteps
(flag haddockDistPref
) pkg_descr lbi clbi verbosity
301 { withPackageDB
= withPackageDB lbi
++ [internalPackageDB
]
302 , installedPkgs
= index
305 preprocessComponent pkg_descr component lbi
' clbi
False verbosity suffixes
307 doExe com
= case (compToExe com
) of
309 withTempDirectoryEx verbosity tmpFileOpts
(buildDir lbi
') "tmp" $
320 let exeArgs
' = commonArgs `mappend` exeArgs
331 (fromFlag
$ haddockVerbosity flags
)
332 "Unsupported component, skipping..."
334 -- We define 'smsg' once and then reuse it inside the case, so that
335 -- we don't say we are running Haddock when we actually aren't
336 -- (e.g., Haddock is not run on non-libraries)
342 (packageId pkg_descr
)
343 (componentLocalName clbi
)
344 (maybeComponentInstantiatedWith clbi
)
347 withTempDirectoryEx verbosity tmpFileOpts
(buildDir lbi
) "tmp" $
359 let libArgs
' = commonArgs `mappend` libArgs
360 runHaddock verbosity tmpFileOpts comp platform haddockProg
True libArgs
'
362 pwd
<- getCurrentDirectory
366 inplaceInstalledPackageInfo
368 (flag haddockDistPref
)
370 (mkAbiHash
"inplace")
376 "Registering inplace:\n"
377 ++ (InstalledPackageInfo
.showInstalledPackageInfo ipi
)
385 HcPkg
.defaultRegisterOptions
386 { HcPkg
.registerMultiInstance
= True
389 return $ PackageIndex
.insert ipi
index
392 (flag haddockForeignLibs
)
394 withTempDirectoryEx verbosity tmpFileOpts
(buildDir lbi
') "tmp" $
406 let libArgs
' = commonArgs `mappend` flibArgs
407 runHaddock verbosity tmpFileOpts comp platform haddockProg
True libArgs
'
410 CExe _
-> when (flag haddockExecutables
) (smsg
>> doExe component
) >> return index
411 CTest _
-> when (flag haddockTestSuites
) (smsg
>> doExe component
) >> return index
412 CBench _
-> when (flag haddockBenchmarks
) (smsg
>> doExe component
) >> return index
414 for_
(extraDocFiles pkg_descr
) $ \fpath
-> do
415 files
<- matchDirFileGlob verbosity
(specVersion pkg_descr
) "." fpath
416 for_ files
$ copyFileTo verbosity
(unDir
$ argOutputDir commonArgs
)
418 -- | Execute 'Haddock' configured with 'HaddocksFlags'. It is used to build
419 -- index and contents for documentation of multiple packages.
425 -> HaddockProjectFlags
427 createHaddockIndex verbosity programDb comp platform flags
= do
428 let args
= fromHaddockProjectFlags flags
429 (haddockProg
, _version
) <-
430 getHaddockProg verbosity programDb comp args
(Flag
True)
431 runHaddock verbosity defaultTempFileOptions comp platform haddockProg
False args
433 -- ------------------------------------------------------------------------------
434 -- Contributions to HaddockArgs (see also Doctest.hs for very similar code).
436 fromFlags
:: PathTemplateEnv
-> HaddockFlags
-> HaddockArgs
437 fromFlags env flags
=
440 ( maybe mempty
(All
. not) $
441 flagToMaybe
(haddockInternal flags
)
445 if fromFlag
(haddockLinkedSource flags
)
448 ( "src/%{MODULE/./-}.html"
449 , "src/%{MODULE/./-}.html#%{NAME}"
450 , "src/%{MODULE/./-}.html#line-%{LINE}"
453 , argLinkedSource
= haddockLinkedSource flags
454 , argQuickJump
= haddockQuickJump flags
455 , argCssFile
= haddockCss flags
458 (fromPathTemplate
. substPathTemplate env
)
459 (haddockContents flags
)
460 , argGenContents
= Flag
False
463 (fromPathTemplate
. substPathTemplate env
)
465 , argGenIndex
= Flag
False
466 , argBaseUrl
= haddockBaseUrl flags
467 , argLib
= haddockLib flags
469 maybe mempty
(Any
. (>= deafening
))
471 $ haddockVerbosity flags
473 Flag
$ case [Html | Flag
True <- [haddockHtml flags
]]
474 ++ [Hoogle | Flag
True <- [haddockHoogle flags
]] of
477 , argOutputDir
= maybe mempty Dir
. flagToMaybe
$ haddockDistPref flags
478 , argGhcOptions
= mempty
{ghcOptExtra
= ghcArgs
}
481 ghcArgs
= fromMaybe [] . lookup "ghc" . haddockProgramArgs
$ flags
483 fromHaddockProjectFlags
:: HaddockProjectFlags
-> HaddockArgs
484 fromHaddockProjectFlags flags
=
486 { argOutputDir
= Dir
(fromFlag
$ haddockProjectDir flags
)
487 , argQuickJump
= Flag
True
488 , argGenContents
= Flag
True
489 , argGenIndex
= Flag
True
490 , argPrologueFile
= haddockProjectPrologue flags
491 , argInterfaces
= fromFlagOrDefault
[] (haddockProjectInterfaces flags
)
492 , argLinkedSource
= Flag
True
493 , argLib
= haddockProjectLib flags
496 fromPackageDescription
:: HaddockTarget
-> PackageDescription
-> HaddockArgs
497 fromPackageDescription haddockTarget pkg_descr
=
499 { argInterfaceFile
= Flag
$ haddockName pkg_descr
500 , argPackageName
= Flag
$ packageId
$ pkg_descr
503 "doc" </> "html" </> haddockDirName haddockTarget pkg_descr
506 ShortText
.fromShortText
$
507 if ShortText
.null desc
508 then synopsis pkg_descr
510 , argTitle
= Flag
$ showPkg
++ subtitle
513 desc
= description pkg_descr
514 showPkg
= prettyShow
(packageId pkg_descr
)
516 | ShortText
.null (synopsis pkg_descr
) = ""
517 |
otherwise = ": " ++ ShortText
.fromShortText
(synopsis pkg_descr
)
523 -> ComponentLocalBuildInfo
526 componentGhcOptions verbosity lbi bi clbi odir
=
527 let f
= case compilerFlavor
(compiler lbi
) of
528 GHC
-> GHC
.componentGhcOptions
529 GHCJS
-> GHCJS
.componentGhcOptions
532 "Distribution.Simple.Haddock.componentGhcOptions:"
533 ++ "haddock only supports GHC and GHCJS"
534 in f verbosity lbi bi clbi odir
540 -> ComponentLocalBuildInfo
541 -> Maybe PathTemplate
542 -- ^ template for HTML location
547 mkHaddockArgs verbosity tmp lbi clbi htmlTemplate haddockVersion inFiles bi
= do
548 ifaceArgs
<- getInterfaces verbosity lbi clbi htmlTemplate
550 (componentGhcOptions normal lbi bi clbi
(buildDir lbi
))
551 { -- Noooooooooo!!!!!111
552 -- haddock stomps on our precious .hi
553 -- and .o files. Workaround by telling
554 -- haddock to write them elsewhere.
555 ghcOptObjDir
= toFlag tmp
556 , ghcOptHiDir
= toFlag tmp
557 , ghcOptStubDir
= toFlag tmp
559 `mappend` getGhcCppOpts haddockVersion bi
562 { ghcOptDynLinkMode
= toFlag GhcDynamicOnly
563 , ghcOptFPic
= toFlag
True
564 , ghcOptHiSuffix
= toFlag
"dyn_hi"
565 , ghcOptObjSuffix
= toFlag
"dyn_o"
566 , ghcOptExtra
= hcSharedOptions GHC bi
569 if withVanillaLib lbi
570 then return vanillaOpts
573 then return sharedOpts
574 else dieWithException verbosity MustHaveSharedLibraries
578 { argGhcOptions
= opts
579 , argTargets
= inFiles
580 , argReexports
= getReexports clbi
587 -> ComponentLocalBuildInfo
588 -> Maybe PathTemplate
589 -- ^ template for HTML location
593 fromLibrary verbosity tmp lbi clbi htmlTemplate haddockVersion lib
= do
594 inFiles
<- map snd `
fmap` getLibSourceFiles verbosity lbi lib clbi
607 { argHideModules
= (mempty
, otherModules
(libBuildInfo lib
))
614 -> ComponentLocalBuildInfo
615 -> Maybe PathTemplate
616 -- ^ template for HTML location
620 fromExecutable verbosity tmp lbi clbi htmlTemplate haddockVersion exe
= do
621 inFiles
<- map snd `
fmap` getExeSourceFiles verbosity lbi exe clbi
634 { argOutputDir
= Dir
$ unUnqualComponentName
$ exeName exe
635 , argTitle
= Flag
$ unUnqualComponentName
$ exeName exe
642 -> ComponentLocalBuildInfo
643 -> Maybe PathTemplate
644 -- ^ template for HTML location
648 fromForeignLib verbosity tmp lbi clbi htmlTemplate haddockVersion flib
= do
649 inFiles
<- map snd `
fmap` getFLibSourceFiles verbosity lbi flib clbi
659 (foreignLibBuildInfo flib
)
662 { argOutputDir
= Dir
$ unUnqualComponentName
$ foreignLibName flib
663 , argTitle
= Flag
$ unUnqualComponentName
$ foreignLibName flib
666 compToExe
:: Component
-> Maybe Executable
669 CTest test
@TestSuite
{testInterface
= TestSuiteExeV10 _ f
} ->
672 { exeName
= testName test
674 , exeScope
= ExecutablePublic
675 , buildInfo
= testBuildInfo test
677 CBench bench
@Benchmark
{benchmarkInterface
= BenchmarkExeV10 _ f
} ->
680 { exeName
= benchmarkName bench
682 , exeScope
= ExecutablePublic
683 , buildInfo
= benchmarkBuildInfo bench
691 -> ComponentLocalBuildInfo
692 -> Maybe PathTemplate
693 -- ^ template for HTML location
695 getInterfaces verbosity lbi clbi htmlTemplate
= do
696 (packageFlags
, warnings
) <- haddockPackageFlags verbosity lbi clbi htmlTemplate
697 traverse_
(warn
(verboseUnmarkOutput verbosity
)) warnings
700 { argInterfaces
= packageFlags
703 getReexports
:: ComponentLocalBuildInfo
-> [OpenModule
]
704 getReexports LibComponentLocalBuildInfo
{componentExposedModules
= mods
} =
705 mapMaybe exposedReexport mods
712 getGhcCppOpts haddockVersion bi
=
714 { ghcOptExtensions
= toNubListR
[EnableExtension CPP | needsCpp
]
715 , ghcOptCppOptions
= defines
718 needsCpp
= EnableExtension CPP `
elem` usedExtensions bi
719 defines
= [haddockVersionMacro
]
720 haddockVersionMacro
=
721 "-D__HADDOCK_VERSION__="
722 ++ show (v1
* 1000 + v2
* 10 + v3
)
724 (v1
, v2
, v3
) = case versionNumbers haddockVersion
of
728 (x
: y
: z
: _
) -> (x
, y
, z
)
734 getGhcLibDir verbosity lbi
= do
735 l
<- case compilerFlavor
(compiler lbi
) of
736 GHC
-> GHC
.getLibDir verbosity lbi
737 GHCJS
-> GHCJS
.getLibDir verbosity lbi
738 _
-> error "haddock only supports GHC and GHCJS"
739 return $ mempty
{argGhcLibDir
= Flag l
}
741 -- ------------------------------------------------------------------------------
743 -- | Call haddock with the specified arguments.
754 runHaddock verbosity tmpFileOpts comp platform haddockProg requireTargets args
755 | requireTargets
&& null (argTargets args
) =
757 "Haddocks are being requested, but there aren't any modules given "
758 ++ "to create documentation for."
762 (error "unable to determine haddock version")
763 (programVersion haddockProg
)
764 renderArgs verbosity tmpFileOpts haddockVersion comp platform args
$
765 \(flags
, result
) -> do
766 runProgram verbosity haddockProg flags
768 notice verbosity
$ "Documentation created: " ++ result
777 -> (([String], FilePath) -> IO a
)
779 renderArgs verbosity tmpFileOpts version comp platform args k
= do
780 let haddockSupportsUTF8
= version
>= mkVersion
[2, 14, 4]
781 haddockSupportsResponseFiles
= version
> mkVersion
[2, 16, 2]
782 createDirectoryIfMissingVerbose verbosity
True outputDir
783 case argPrologue args
of
785 withTempFileEx tmpFileOpts outputDir
"haddock-prologue.txt" $
786 \prologueFileName h
-> do
788 when haddockSupportsUTF8
(hSetEncoding h utf8
)
789 hPutStrLn h prologueText
791 let pflag
= "--prologue=" ++ prologueFileName
792 renderedArgs
= pflag
: renderPureArgs version comp platform args
793 if haddockSupportsResponseFiles
799 "haddock-response.txt"
800 (if haddockSupportsUTF8
then Just utf8
else Nothing
)
802 (\responseFileName
-> k
(["@" ++ responseFileName
], result
))
803 else k
(renderedArgs
, result
)
806 ( case argPrologueFile args
of
807 Flag pfile
-> ["--prologue=" ++ pfile
]
810 <> renderPureArgs version comp platform args
811 if haddockSupportsResponseFiles
817 "haddock-response.txt"
818 (if haddockSupportsUTF8
then Just utf8
else Nothing
)
820 (\responseFileName
-> k
(["@" ++ responseFileName
], result
))
821 else k
(renderedArgs
, result
)
823 outputDir
= (unDir
$ argOutputDir args
)
824 isNotArgContents
= isNothing (flagToMaybe
$ argContents args
)
825 isNotArgIndex
= isNothing (flagToMaybe
$ argIndex args
)
826 isArgGenIndex
= fromFlagOrDefault
False (argGenIndex args
)
827 -- Haddock, when generating HTML, does not generate an index if the options
828 -- --use-contents or --use-index are passed to it. See
829 -- https://haskell-haddock.readthedocs.io/en/latest/invoking.html#cmdoption-use-contents
830 isIndexGenerated
= isArgGenIndex
&& isNotArgContents
&& isNotArgIndex
838 | isIndexGenerated
->
843 Hoogle
-> pkgstr
<.> "txt"
845 . fromFlagOrDefault
[Html
]
849 pkgstr
= prettyShow
$ packageName pkgid
850 pkgid
= arg argPackageName
851 arg f
= fromFlag
$ f args
853 renderPureArgs
:: Version
-> Compiler
-> Platform
-> HaddockArgs
-> [String]
854 renderPureArgs version comp platform args
=
856 [ map (\f -> "--dump-interface=" ++ unDir
(argOutputDir args
) </> f
)
860 , if haddockSupportsPackageName
865 [ "--package-name=" ++ prettyShow
(pkgName pkg
)
866 , "--package-version=" ++ prettyShow
(pkgVersion pkg
)
873 , ["--since-qual=external" | isVersion
2 20]
874 , [ "--quickjump" | isVersion
2 19, True <- flagToList
. argQuickJump
$ args
876 , ["--hyperlinked-source" | isHyperlinkedSource
]
877 , (\(All b
, xs
) -> bool
(map (("--hide=" ++) . prettyShow
) xs
) [] b
)
880 , bool
["--ignore-all-exports"] [] . getAny
. argIgnoreExports
$ args
881 , -- Haddock's --source-* options are ignored once --hyperlinked-source is
883 -- See https://haskell-haddock.readthedocs.io/en/latest/invoking.html#cmdoption-hyperlinked-source
884 -- To avoid Haddock's warning, we only set --source-* options if
885 -- --hyperlinked-source is not set.
886 if isHyperlinkedSource
892 [ "--source-module=" ++ m
893 , "--source-entity=" ++ e
896 then ["--source-entity-line=" ++ l
]
902 , maybe [] ((: []) . ("--css=" ++)) . flagToMaybe
. argCssFile
$ args
903 , maybe [] ((: []) . ("--use-contents=" ++)) . flagToMaybe
. argContents
$ args
904 , bool
["--gen-contents"] [] . fromFlagOrDefault
False . argGenContents
$ args
905 , maybe [] ((: []) . ("--use-index=" ++)) . flagToMaybe
. argIndex
$ args
906 , bool
["--gen-index"] [] . fromFlagOrDefault
False . argGenIndex
$ args
907 , maybe [] ((: []) . ("--base-url=" ++)) . flagToMaybe
. argBaseUrl
$ args
908 , bool
[] [verbosityFlag
] . getAny
. argVerbose
$ args
909 , map (\o
-> case o
of Hoogle
-> "--hoogle"; Html
-> "--html")
910 . fromFlagOrDefault
[]
913 , renderInterfaces
. argInterfaces
$ args
914 , (: []) . ("--odir=" ++) . unDir
. argOutputDir
$ args
920 (++ " (internal documentation)")
922 (getAny
$ argIgnoreExports args
)
928 , [ "--optghc=" ++ opt |
let opts
= argGhcOptions args
, opt
<- renderGhcOptions comp platform opts
930 , maybe [] (\l
-> ["-B" ++ l
]) $
931 flagToMaybe
(argGhcLibDir args
) -- error if Nothing?
932 , -- https://github.com/haskell/haddock/pull/547
933 [ "--reexport=" ++ prettyShow r
934 | r
<- argReexports args
938 , maybe [] ((: []) . ("--lib=" ++)) . flagToMaybe
. argLib
$ args
941 renderInterfaces
= map renderInterface
943 renderInterface
:: (FilePath, Maybe FilePath, Maybe FilePath, Visibility
) -> String
944 renderInterface
(i
, html
, hypsrc
, visibility
) =
949 [ [fromMaybe "" html
]
950 , -- only render hypsrc path if html path
951 -- is given and hyperlinked-source is
954 [ case (html
, hypsrc
) of
959 , fromFlagOrDefault
False . argLinkedSource
$ args
->
964 , if haddockSupportsVisibility
975 bool a b c
= if c
then a
else b
976 isVersion major minor
= version
>= mkVersion
[major
, minor
]
978 | isVersion
2 5 = "--verbosity=1"
979 |
otherwise = "--verbose"
980 haddockSupportsVisibility
= version
>= mkVersion
[2, 26, 1]
981 haddockSupportsPackageName
= version
> mkVersion
[2, 16]
982 haddockSupportsHyperlinkedSource
= isVersion
2 17
983 isHyperlinkedSource
=
984 haddockSupportsHyperlinkedSource
985 && fromFlagOrDefault
False (argLinkedSource args
)
987 ---------------------------------------------------------------------------------
989 -- | Given a list of 'InstalledPackageInfo's, return a list of interfaces and
990 -- HTML paths, and an optional warning for packages with missing documentation.
992 :: [InstalledPackageInfo
]
993 -> Maybe (InstalledPackageInfo
-> FilePath)
995 ( [ ( FilePath -- path to interface
997 , Maybe FilePath -- url to html
999 , Maybe FilePath -- url to hyperlinked
1004 , Maybe String -- warning about
1005 -- missing documentation
1007 haddockPackagePaths ipkgs mkHtmlPath
= do
1010 [ case interfaceAndHtmlPath ipkg
of
1011 Nothing
-> return (Left
(packageId ipkg
))
1012 Just
(interface
, html
) -> do
1016 let hypSrcPath
= htmlPath
</> defaultHyperlinkedSourceDirectory
1017 hypSrcExists
<- doesDirectoryExist hypSrcPath
1019 ( Just
(fixFileUrl htmlPath
)
1021 then Just
(fixFileUrl hypSrcPath
)
1024 Nothing
-> return (Nothing
, Nothing
)
1026 exists
<- doesFileExist interface
1028 then return (Right
(interface
, html
', hypsrc
', Visible
))
1029 else return (Left pkgid
)
1031 , let pkgid
= packageId ipkg
1032 , pkgName pkgid `
notElem` noHaddockWhitelist
1035 let missing
= [pkgid | Left pkgid
<- interfaces
]
1037 "The documentation for the following packages are not "
1038 ++ "installed. No links will be generated to these packages: "
1039 ++ intercalate
", " (map prettyShow missing
)
1040 flags
= rights interfaces
1042 return (flags
, if null missing
then Nothing
else Just warning
)
1044 -- Don't warn about missing documentation for these packages. See #1231.
1045 noHaddockWhitelist
= map mkPackageName
["rts"]
1047 -- Actually extract interface and HTML paths from an 'InstalledPackageInfo'.
1048 interfaceAndHtmlPath
1049 :: InstalledPackageInfo
1050 -> Maybe (FilePath, Maybe FilePath)
1051 interfaceAndHtmlPath pkg
= do
1052 interface
<- listToMaybe (InstalledPackageInfo
.haddockInterfaces pkg
)
1053 html
<- case mkHtmlPath
of
1054 Nothing
-> listToMaybe (InstalledPackageInfo
.haddockHTMLs pkg
)
1055 Just mkPath
-> Just
(mkPath pkg
)
1056 return (interface
, if null html
then Nothing
else Just html
)
1058 -- The 'haddock-html' field in the hc-pkg output is often set as a
1059 -- native path, but we need it as a URL. See #1064. Also don't "fix"
1060 -- the path if it is an interpolated one.
1062 | Nothing
<- mkHtmlPath
1067 -- 'src' is the default hyperlinked source directory ever since. It is
1068 -- not possible to configure that directory in any way in haddock.
1069 defaultHyperlinkedSourceDirectory
= "src"
1074 -> ComponentLocalBuildInfo
1075 -> Maybe PathTemplate
1077 ( [ ( FilePath -- path to interface
1079 , Maybe FilePath -- url to html
1081 , Maybe FilePath -- url to hyperlinked
1086 , Maybe String -- warning about
1087 -- missing documentation
1089 haddockPackageFlags verbosity lbi clbi htmlTemplate
= do
1090 let allPkgs
= installedPkgs lbi
1091 directDeps
= map fst (componentPackageDeps clbi
)
1092 transitiveDeps
<- case PackageIndex
.dependencyClosure allPkgs directDeps
of
1095 dieWithException verbosity
$ HaddockPackageFlags inf
1097 haddockPackagePaths
(PackageIndex
.allPackages transitiveDeps
) mkHtmlPath
1099 mkHtmlPath
= fmap expandTemplateVars htmlTemplate
1100 expandTemplateVars tmpl pkg
=
1101 fromPathTemplate
. substPathTemplate
(env pkg
) $ tmpl
1102 env pkg
= haddockTemplateEnv lbi
(packageId pkg
)
1104 haddockTemplateEnv
:: LocalBuildInfo
-> PackageIdentifier
-> PathTemplateEnv
1105 haddockTemplateEnv lbi pkg_id
=
1106 (PrefixVar
, prefix
(installDirTemplates lbi
))
1107 -- We want the legacy unit ID here, because it gives us nice paths
1108 -- (Haddock people don't care about the dependencies)
1109 : initialPathTemplateEnv
1111 (mkLegacyUnitId pkg_id
)
1112 (compilerInfo
(compiler lbi
))
1115 -- ------------------------------------------------------------------------------
1116 -- hscolour support.
1119 :: PackageDescription
1121 -> [PPSuffixHandler
]
1124 hscolour
= hscolour
' dieNoVerbosity ForDevelopment
1127 :: (String -> IO ())
1128 -- ^ Called when the 'hscolour' exe is not found.
1130 -> PackageDescription
1132 -> [PPSuffixHandler
]
1135 hscolour
' onNoHsColour haddockTarget pkg_descr lbi suffixes flags
=
1136 either (\excep
-> onNoHsColour
$ exceptionMessage excep
) (\(hscolourProg
, _
, _
) -> go hscolourProg
)
1137 =<< lookupProgramVersion
1140 (orLaterVersion
(mkVersion
[1, 8]))
1143 go
:: ConfiguredProgram
-> IO ()
1144 go hscolourProg
= do
1146 "the 'cabal hscolour' command is deprecated in favour of 'cabal "
1147 ++ "haddock --hyperlink-source' and will be removed in the next major "
1150 setupMessage verbosity
"Running hscolour for" (packageId pkg_descr
)
1151 createDirectoryIfMissingVerbose verbosity
True $
1152 hscolourPref haddockTarget distPref pkg_descr
1154 withAllComponentsInBuildOrder pkg_descr lbi
$ \comp clbi
-> do
1155 componentInitialBuildSteps distPref pkg_descr lbi clbi verbosity
1156 preprocessComponent pkg_descr comp lbi clbi
False verbosity suffixes
1158 doExe com
= case (compToExe com
) of
1161 hscolourPref haddockTarget distPref pkg_descr
1162 </> unUnqualComponentName
(exeName exe
)
1164 runHsColour hscolourProg outputDir
=<< getExeSourceFiles verbosity lbi exe clbi
1167 (fromFlag
$ hscolourVerbosity flags
)
1168 "Unsupported component, skipping..."
1172 let outputDir
= hscolourPref haddockTarget distPref pkg_descr
</> "src"
1173 runHsColour hscolourProg outputDir
=<< getLibSourceFiles verbosity lbi lib clbi
1176 hscolourPref haddockTarget distPref pkg_descr
1177 </> unUnqualComponentName
(foreignLibName flib
)
1179 runHsColour hscolourProg outputDir
=<< getFLibSourceFiles verbosity lbi flib clbi
1180 CExe _
-> when (fromFlag
(hscolourExecutables flags
)) $ doExe comp
1181 CTest _
-> when (fromFlag
(hscolourTestSuites flags
)) $ doExe comp
1182 CBench _
-> when (fromFlag
(hscolourBenchmarks flags
)) $ doExe comp
1184 stylesheet
= flagToMaybe
(hscolourCSS flags
)
1186 verbosity
= fromFlag
(hscolourVerbosity flags
)
1187 distPref
= fromFlag
(hscolourDistPref flags
)
1189 runHsColour prog outputDir moduleFiles
= do
1190 createDirectoryIfMissingVerbose verbosity
True outputDir
1192 case stylesheet
of -- copy the CSS file
1194 | programVersion prog
>= Just
(mkVersion
[1, 9]) ->
1198 ["-print-css", "-o" ++ outputDir
</> "hscolour.css"]
1199 |
otherwise -> return ()
1200 Just s
-> copyFileVerbose verbosity s
(outputDir
</> "hscolour.css")
1202 for_ moduleFiles
$ \(m
, inFile
) ->
1206 ["-css", "-anchor", "-o" ++ outFile m
, inFile
]
1210 </> intercalate
"-" (ModuleName
.components m
) <.> "html"
1212 haddockToHscolour
:: HaddockFlags
-> HscolourFlags
1213 haddockToHscolour flags
=
1215 { hscolourCSS
= haddockHscolourCss flags
1216 , hscolourExecutables
= haddockExecutables flags
1217 , hscolourTestSuites
= haddockTestSuites flags
1218 , hscolourBenchmarks
= haddockBenchmarks flags
1219 , hscolourForeignLibs
= haddockForeignLibs flags
1220 , hscolourVerbosity
= haddockVerbosity flags
1221 , hscolourDistPref
= haddockDistPref flags
1222 , hscolourCabalFilePath
= haddockCabalFilePath flags
1225 -- ------------------------------------------------------------------------------
1226 -- Boilerplate Monoid instance.
1227 instance Monoid HaddockArgs
where
1231 instance Semigroup HaddockArgs
where
1234 instance Monoid Directory
where
1238 instance Semigroup Directory
where
1239 Dir m
<> Dir n
= Dir
$ m
</> n