1 module Distribution
.Client
.CmdHaddockProject
2 ( haddockProjectCommand
6 import Distribution
.Client
.Compat
.Prelude
hiding (get
)
9 import qualified Distribution
.Client
.CmdBuild
as CmdBuild
10 import qualified Distribution
.Client
.CmdHaddock
as CmdHaddock
12 import Distribution
.Client
.DistDirLayout
17 import Distribution
.Client
.InstallPlan
(foldPlanPackage
)
18 import qualified Distribution
.Client
.InstallPlan
as InstallPlan
19 import qualified Distribution
.Client
.NixStyleOptions
as NixStyleOptions
20 import Distribution
.Client
.ProjectOrchestration
21 ( AvailableTarget
(..)
22 , AvailableTargetStatus
(..)
24 , ProjectBaseContext
(..)
25 , ProjectBuildContext
(..)
28 , pruneInstallPlanToTargets
30 , runProjectPreBuildPhase
31 , selectComponentTargetBasic
33 import Distribution
.Client
.ProjectPlanning
34 ( ElaboratedConfiguredPackage
(..)
35 , ElaboratedInstallPlan
36 , ElaboratedSharedConfig
(..)
39 import Distribution
.Client
.ProjectPlanning
.Types
42 import Distribution
.Client
.ScriptUtils
43 ( AcceptNoTargets
(..)
45 , updateContextAndWriteProjectFile
46 , withContextAndSelectors
48 import Distribution
.Client
.Setup
52 import Distribution
.Client
.TargetProblem
(TargetProblem
(..))
54 import Distribution
.Simple
.Command
57 import Distribution
.Simple
.Compiler
60 import Distribution
.Simple
.Flag
65 import Distribution
.Simple
.Haddock
(createHaddockIndex
)
66 import Distribution
.Simple
.InstallDirs
69 import Distribution
.Simple
.Program
.Builtin
72 import Distribution
.Simple
.Program
.Db
75 , requireProgramVersion
77 import Distribution
.Simple
.Setup
79 , HaddockProjectFlags
(..)
82 , haddockProjectCommand
84 import Distribution
.Simple
.Utils
85 ( copyDirectoryRecursive
86 , createDirectoryIfMissingVerbose
90 import Distribution
.Types
.InstalledPackageInfo
(InstalledPackageInfo
(..))
91 import Distribution
.Types
.PackageId
(pkgName
)
92 import Distribution
.Types
.PackageName
(unPackageName
)
93 import Distribution
.Types
.UnitId
(unUnitId
)
94 import Distribution
.Types
.Version
(mkVersion
)
95 import Distribution
.Types
.VersionRange
(orLaterVersion
)
96 import Distribution
.Verbosity
as Verbosity
100 import Distribution
.Client
.Errors
101 import System
.Directory
(doesDirectoryExist, doesFileExist)
102 import System
.FilePath (normalise
, takeDirectory
, (<.>), (</>))
104 haddockProjectAction
:: HaddockProjectFlags
-> [String] -> GlobalFlags
-> IO ()
105 haddockProjectAction flags _extraArgs globalFlags
= do
106 -- create destination directory if it does not exist
107 let outputDir
= normalise
$ fromFlag
(haddockProjectDir flags
)
108 createDirectoryIfMissingVerbose verbosity
True outputDir
110 warn verbosity
"haddock-project command is experimental, it might break in the future"
112 -- build all packages with appropriate haddock flags
115 { haddockHtml
= Flag
True
116 , -- one can either use `--haddock-base-url` or
117 -- `--haddock-html-location`.
122 , haddockProgramPaths
= haddockProjectProgramPaths flags
123 , haddockProgramArgs
= haddockProjectProgramArgs flags
124 , haddockHtmlLocation
=
125 if fromFlagOrDefault
False (haddockProjectHackage flags
)
126 then Flag
"https://hackage.haskell.org/package/$pkg-$version/docs"
127 else haddockProjectHtmlLocation flags
128 , haddockHoogle
= haddockProjectHoogle flags
129 , haddockExecutables
= haddockProjectExecutables flags
130 , haddockTestSuites
= haddockProjectTestSuites flags
131 , haddockBenchmarks
= haddockProjectBenchmarks flags
132 , haddockForeignLibs
= haddockProjectForeignLibs flags
133 , haddockInternal
= haddockProjectInternal flags
134 , haddockCss
= haddockProjectCss flags
135 , haddockLinkedSource
= Flag
True
136 , haddockQuickJump
= Flag
True
137 , haddockHscolourCss
= haddockProjectHscolourCss flags
140 then Flag
(toPathTemplate
"../index.html")
144 then Flag
(toPathTemplate
"../doc-index.html")
146 , haddockKeepTempFiles
= haddockProjectKeepTempFiles flags
147 , haddockVerbosity
= haddockProjectVerbosity flags
148 , haddockLib
= haddockProjectLib flags
149 , haddockOutputDir
= haddockProjectOutputDir flags
152 (commandDefaultFlags CmdHaddock
.haddockCommand
)
153 { NixStyleOptions
.haddockFlags
= haddockFlags
154 , NixStyleOptions
.configFlags
=
155 (NixStyleOptions
.configFlags
(commandDefaultFlags CmdBuild
.buildCommand
))
156 { configVerbosity
= haddockProjectVerbosity flags
161 -- Construct the build plan and infer the list of packages which haddocks
165 withContextAndSelectors
168 (commandDefaultFlags CmdBuild
.buildCommand
)
172 $ \targetCtx ctx targetSelectors
-> do
173 baseCtx
<- case targetCtx
of
174 ProjectContext
-> return ctx
175 GlobalContext
-> return ctx
176 ScriptContext path exemeta
-> updateContextAndWriteProjectFile ctx path exemeta
177 let distLayout
= distDirLayout baseCtx
178 cabalLayout
= cabalDirLayout baseCtx
180 runProjectPreBuildPhase verbosity baseCtx
$ \elaboratedPlan
-> do
181 -- Interpret the targets on the command line as build targets
182 -- (as opposed to say repl or haddock targets).
184 either reportTargetProblems
return $
187 selectComponentTargetBasic
192 let elaboratedPlan
' =
193 pruneInstallPlanToTargets
197 return (elaboratedPlan
', targets
)
199 printPlan verbosity baseCtx buildCtx
201 let elaboratedPlan
:: ElaboratedInstallPlan
202 elaboratedPlan
= elaboratedPlanOriginal buildCtx
204 sharedConfig
:: ElaboratedSharedConfig
205 sharedConfig
= elaboratedShared buildCtx
207 pkgs
:: [Either InstalledPackageInfo ElaboratedConfiguredPackage
]
208 pkgs
= matchingPackages elaboratedPlan
213 (haddockProjectProgramPaths flags
)
214 (haddockProjectProgramArgs flags
)
215 -- we need to insert 'haddockProgram' before we reconfigure it,
217 . addKnownProgram haddockProgram
218 . pkgConfigCompilerProgs
220 let sharedConfig
' = sharedConfig
{pkgConfigCompilerProgs
= progs
}
223 requireProgramVersion
226 (orLaterVersion
(mkVersion
[2, 26, 1]))
230 -- Build project; we need to build dependencies.
236 (commandDefaultFlags CmdBuild
.buildCommand
)
241 -- Build haddocks of each components
244 CmdHaddock
.haddockAction
250 -- Copy haddocks to the destination folder
253 packageInfos
<- fmap (nub . concat) $ for pkgs
$ \pkg
->
259 -- TODO: this might not work for public packages with sublibraries.
261 let packageName
= unPackageName
(pkgName
$ sourcePackageId package
)
262 destDir
= outputDir
</> packageName
263 fmap catMaybes $ for
(haddockInterfaces package
) $ \interfacePath
-> do
264 let docDir
= takeDirectory interfacePath
265 a
<- doesFileExist interfacePath
268 copyDirectoryRecursive verbosity docDir destDir
276 False -> return Nothing
278 case elabLocalToProject package
of
280 let distDirParams
= elabDistDirParams sharedConfig
' package
281 unitId
= unUnitId
(elabUnitId package
)
282 buildDir
= distBuildDirectory distLayout distDirParams
283 packageName
= unPackageName
(pkgName
$ elabPkgSourceId package
)
289 destDir
= outputDir
</> unitId
294 a
<- doesDirectoryExist docDir
297 copyDirectoryRecursive verbosity docDir destDir
310 ++ " not found in the store"
317 let packageName
= unPackageName
(pkgName
$ elabPkgSourceId package
)
318 unitId
= unUnitId
(elabUnitId package
)
320 storePackageDirectory
321 (cabalStoreDirLayout cabalLayout
)
322 (compilerId
(pkgConfigCompiler sharedConfig
'))
324 docDir
= packageDir
</> "share" </> "doc" </> "html"
325 destDir
= outputDir
</> packageName
330 a
<- doesDirectoryExist docDir
333 copyDirectoryRecursive verbosity docDir destDir
334 -- non local packages will be hidden in haddock's
335 -- generated contents page
348 ++ " not found in the store"
353 -- generate index, content, etc.
358 { haddockProjectDir
= Flag outputDir
359 , haddockProjectInterfaces
=
366 |
(name
, interfacePath
, visibility
) <- packageInfos
371 (pkgConfigCompilerProgs sharedConfig
')
372 (pkgConfigCompiler sharedConfig
')
373 (pkgConfigPlatform sharedConfig
')
376 verbosity
= fromFlagOrDefault normal
(haddockProjectVerbosity flags
)
378 -- Build a self contained directory which contains haddocks of all
379 -- transitive dependencies; or depend on `--haddocks-html-location` to
380 -- provide location of the documentation of dependencies.
382 let hackage
= fromFlagOrDefault
False (haddockProjectHackage flags
)
383 location
= fromFlagOrDefault
False (const True <$> haddockProjectHtmlLocation flags
)
384 in not hackage
&& not location
386 reportTargetProblems
:: Show x
=> [x
] -> IO a
387 reportTargetProblems
=
388 dieWithException verbosity
. CmdHaddockReportTargetProblems
. map show
390 -- TODO: this is just a sketch
393 -> [AvailableTarget k
]
394 -> Either (TargetProblem
()) [k
]
395 selectPackageTargets _ ts
=
398 ( \t -> case availableTargetStatus t
of
400 | availableTargetLocalToProject t
->
407 :: ElaboratedInstallPlan
408 -> [Either InstalledPackageInfo ElaboratedConfiguredPackage
]
410 fmap (foldPlanPackage Left Right
)