Skip to content

Commit

Permalink
Haddock: Generate haddock for components
Browse files Browse the repository at this point in the history
Currently settings `documentation: true` enables documentation
generation via haddock for your whole package, including tests and benchmarks.
However, there are additional flags to control generation of
documentation for this "second class" documentation targets, which are
currently not honored at the cabal-install side of things. Namely,
`tests`, `benchmarks`, `executables`, etc. provided under the
`haddock` section in your `$CABAL_HOME/config`.

This patch adds a more sensible approach to documentation generation
via haddock. Also enabling `new-haddock` to generate documentation for
single components instead whole packages.

The behaviour works like this:

    - Setting `documentation: true` or passing
      `--enable-documentation` to cabal-install enable documentation
      for any component in the build plan honoring the respective
      flags for tests, benchmarks, exes, foreignlibs, etc.

    - Invoking new-haddock with a target selector will make sure
      the respective flags for "second class" doc targets are set
      correctly. E.g.

      $ new-haddock tests

      Will generate documentation for the testsuite of your package
      event if you have `tests: false` in your haddock section.
  • Loading branch information
alexbiehl committed Mar 22, 2018
1 parent 85f31c8 commit 43310a7
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 18 deletions.
2 changes: 1 addition & 1 deletion Cabal/Distribution/Simple.hs
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ haddockAction hooks flags args = do

hookedAction preHaddock haddockHook postHaddock
(return lbi { withPrograms = progs })
hooks flags' args
hooks flags' { haddockArgs = args } args

cleanAction :: UserHooks -> CleanFlags -> Args -> IO ()
cleanAction hooks flags args = do
Expand Down
16 changes: 15 additions & 1 deletion Cabal/Distribution/Simple/Haddock.hs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ import Distribution.Types.ForeignLib
import Distribution.Types.UnqualComponentName
import Distribution.Types.ComponentLocalBuildInfo
import Distribution.Types.ExecutableScope
import Distribution.Types.LocalBuildInfo
import Distribution.Types.TargetInfo
import Distribution.Package
import qualified Distribution.ModuleName as ModuleName
import Distribution.PackageDescription as PD hiding (Flag)
Expand All @@ -46,6 +48,7 @@ import Distribution.Simple.Program
import Distribution.Simple.PreProcess
import Distribution.Simple.Setup
import Distribution.Simple.Build
import Distribution.Simple.BuildTarget
import Distribution.Simple.InstallDirs
import Distribution.Simple.LocalBuildInfo hiding (substPathTemplate)
import Distribution.Simple.BuildPaths
Expand Down Expand Up @@ -199,7 +202,18 @@ haddock pkg_descr lbi suffixes flags' = do
, fromFlags (haddockTemplateEnv lbi (packageId pkg_descr)) flags
, fromPackageDescription haddockTarget pkg_descr ]

withAllComponentsInBuildOrder pkg_descr lbi $ \component clbi -> do
targets <- readTargetInfos verbosity pkg_descr lbi (haddockArgs flags)

let
targets' =
case targets of
[] -> allTargetsInBuildOrder' pkg_descr lbi
_ -> targets

for_ targets' $ \target -> do
let component = targetComponent target
clbi = targetCLBI target

componentInitialBuildSteps (flag haddockDistPref) pkg_descr lbi clbi verbosity
preprocessComponent pkg_descr component lbi clbi False verbosity suffixes
let
Expand Down
12 changes: 8 additions & 4 deletions Cabal/Distribution/Simple/Setup.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1470,7 +1470,8 @@ data HaddockFlags = HaddockFlags {
haddockDistPref :: Flag FilePath,
haddockKeepTempFiles:: Flag Bool,
haddockVerbosity :: Flag Verbosity,
haddockCabalFilePath :: Flag FilePath
haddockCabalFilePath :: Flag FilePath,
haddockArgs :: [String]
}
deriving (Show, Generic)

Expand All @@ -1494,7 +1495,8 @@ defaultHaddockFlags = HaddockFlags {
haddockDistPref = NoFlag,
haddockKeepTempFiles= Flag False,
haddockVerbosity = Flag normal,
haddockCabalFilePath = mempty
haddockCabalFilePath = mempty,
haddockArgs = mempty
}

haddockCommand :: CommandUI HaddockFlags
Expand All @@ -1504,8 +1506,10 @@ haddockCommand = CommandUI
, commandDescription = Just $ \_ ->
"Requires the program haddock, version 2.x.\n"
, commandNotes = Nothing
, commandUsage = \pname ->
"Usage: " ++ pname ++ " haddock [FLAGS]\n"
, commandUsage = usageAlternatives "haddock" $
[ "[FLAGS]"
, "COMPONENTS [FLAGS]"
]
, commandDefaultFlags = defaultHaddockFlags
, commandOptions = \showOrParseArgs ->
haddockOptions showOrParseArgs
Expand Down
2 changes: 1 addition & 1 deletion Cabal/Distribution/Simple/UserHooks.hs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ emptyUserHooks
preDoctest = rn,
doctestHook = ru,
postDoctest = ru,
preHaddock = rn,
preHaddock = rn',
haddockHook = ru,
postHaddock = ru,
preTest = rn',
Expand Down
3 changes: 2 additions & 1 deletion cabal-install/Distribution/Client/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,8 @@ instance Semigroup SavedConfig where
haddockDistPref = combine haddockDistPref,
haddockKeepTempFiles = combine haddockKeepTempFiles,
haddockVerbosity = combine haddockVerbosity,
haddockCabalFilePath = combine haddockCabalFilePath
haddockCabalFilePath = combine haddockCabalFilePath,
haddockArgs = lastNonEmpty haddockArgs
}
where
combine = combine' savedHaddockFlags
Expand Down
12 changes: 7 additions & 5 deletions cabal-install/Distribution/Client/ProjectBuilding.hs
Original file line number Diff line number Diff line change
Expand Up @@ -366,11 +366,12 @@ packageFileMonitorKeyValues elab =
--
elab_config =
elab {
elabBuildTargets = [],
elabTestTargets = [],
elabBuildTargets = [],
elabTestTargets = [],
elabBenchTargets = [],
elabReplTarget = Nothing,
elabBuildHaddocks = False
elabReplTarget = Nothing,
elabHaddockTargets = [],
elabBuildHaddocks = False
}

-- The second part is the value used to guard the build step. So this is
Expand Down Expand Up @@ -1217,7 +1218,7 @@ buildInplaceUnpackedPackage verbosity
-- Haddock phase
whenHaddock $
annotateFailureNoLog HaddocksFailed $ do
setup haddockCommand haddockFlags []
setup haddockCommand haddockFlags haddockArgs
let haddockTarget = elabHaddockForHackage pkg
when (haddockTarget == Cabal.ForHackage) $ do
let dest = distDirectory </> name <.> "tar.gz"
Expand Down Expand Up @@ -1304,6 +1305,7 @@ buildInplaceUnpackedPackage verbosity
haddockCommand = Cabal.haddockCommand
haddockFlags _ = setupHsHaddockFlags pkg pkgshared
verbosity builddir
haddockArgs = setupHsHaddockArgs pkg

scriptOptions = setupHsScriptOptions rpkg pkgshared
srcdir builddir
Expand Down
3 changes: 2 additions & 1 deletion cabal-install/Distribution/Client/ProjectConfig/Legacy.hs
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,8 @@ convertToLegacyPerPackageConfig PackageConfig {..} =
haddockDistPref = mempty,
haddockKeepTempFiles = mempty,
haddockVerbosity = mempty,
haddockCabalFilePath = mempty
haddockCabalFilePath = mempty,
haddockArgs = mempty
}


Expand Down
49 changes: 45 additions & 4 deletions cabal-install/Distribution/Client/ProjectPlanning.hs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ module Distribution.Client.ProjectPlanning (
setupHsCopyFlags,
setupHsRegisterFlags,
setupHsHaddockFlags,
setupHsHaddockArgs,

packageHashInputs,

Expand Down Expand Up @@ -1727,6 +1728,8 @@ elaborateInstallPlan verbosity platform compiler compilerprogdb pkgConfigDB
elabTestTargets = []
elabBenchTargets = []
elabReplTarget = Nothing
elabHaddockTargets = []

elabBuildHaddocks =
perPkgOptionFlag pkgid False packageConfigDocumentation

Expand Down Expand Up @@ -2536,10 +2539,20 @@ setRootTargets targetAction perPkgTargetsMap =
(Just tgts, TargetActionTest) -> elab { elabTestTargets = tgts }
(Just tgts, TargetActionBench) -> elab { elabBenchTargets = tgts }
(Just [tgt], TargetActionRepl) -> elab { elabReplTarget = Just tgt }
(Just _, TargetActionHaddock) -> elab { elabBuildHaddocks = True }
(Just tgts, TargetActionHaddock) ->
foldr setElabHaddockTargets (elab { elabHaddockTargets = tgts
, elabBuildHaddocks = True }) tgts
(Just _, TargetActionRepl) ->
error "pruneInstallPlanToTargets: multiple repl targets"

setElabHaddockTargets tgt elab
| isTestComponentTarget tgt = elab { elabHaddockTestSuites = True }
| isBenchComponentTarget tgt = elab { elabHaddockBenchmarks = True }
| isForeignLibComponentTarget tgt = elab { elabHaddockForeignLibs = True }
| isExeComponentTarget tgt = elab { elabHaddockExecutables = True }
| isSubLibComponentTarget tgt = elab { elabHaddockInternal = True }
| otherwise = elab

-- | Assuming we have previously set the root build targets (i.e. the user
-- targets but not rev deps yet), the first pruning pass does two things:
--
Expand All @@ -2560,14 +2573,16 @@ pruneInstallPlanPass1 pkgs =
roots = mapMaybe find_root pkgs'

prune elab = PrunedPackage elab' (pruneOptionalDependencies elab')
where elab' = addOptionalStanzas elab
where elab' =
setDocumentation
$ addOptionalStanzas elab

find_root (InstallPlan.Configured (PrunedPackage elab _)) =
if not (null (elabBuildTargets elab)
&& null (elabTestTargets elab)
&& null (elabBenchTargets elab)
&& isNothing (elabReplTarget elab)
&& not (elabBuildHaddocks elab))
&& null (elabHaddockTargets elab))
then Just (installedUnitId elab)
else Nothing
find_root _ = Nothing
Expand Down Expand Up @@ -2613,6 +2628,26 @@ pruneInstallPlanPass1 pkgs =
<> optionalStanzasWithDepsAvailable availablePkgs elab pkg
addOptionalStanzas elab = elab

setDocumentation :: ElaboratedConfiguredPackage -> ElaboratedConfiguredPackage
setDocumentation elab@ElaboratedConfiguredPackage { elabPkgOrComp = ElabComponent comp } =
elab {
elabBuildHaddocks =
elabBuildHaddocks elab && documentationEnabled (compSolverName comp) elab
}

where
documentationEnabled c =
case c of
CD.ComponentLib -> const True
CD.ComponentSubLib _ -> elabHaddockInternal
CD.ComponentFLib _ -> elabHaddockForeignLibs
CD.ComponentExe _ -> elabHaddockExecutables
CD.ComponentTest _ -> elabHaddockTestSuites
CD.ComponentBench _ -> elabHaddockBenchmarks
CD.ComponentSetup -> const False

setDocumentation elab = elab

-- Calculate package dependencies but cut out those needed only by
-- optional stanzas that we've determined we will not enable.
-- These pruned deps are not persisted in this pass since they're based on
Expand Down Expand Up @@ -3391,9 +3426,15 @@ setupHsHaddockFlags (ElaboratedConfiguredPackage{..}) _ verbosity builddir =
haddockDistPref = toFlag builddir,
haddockKeepTempFiles = mempty, --TODO: from build settings
haddockVerbosity = toFlag verbosity,
haddockCabalFilePath = mempty
haddockCabalFilePath = mempty,
haddockArgs = mempty
}

setupHsHaddockArgs :: ElaboratedConfiguredPackage -> [String]
-- TODO: Does the issue #3335 affects test as well
setupHsHaddockArgs elab =
map (showComponentTarget (packageId elab)) (elabHaddockTargets elab)

{-
setupHsTestFlags :: ElaboratedConfiguredPackage
-> ElaboratedSharedConfig
Expand Down
22 changes: 22 additions & 0 deletions cabal-install/Distribution/Client/ProjectPlanning/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ module Distribution.Client.ProjectPlanning.Types (
showBenchComponentTarget,
SubComponentTarget(..),

isSubLibComponentTarget,
isForeignLibComponentTarget,
isExeComponentTarget,
isTestComponentTarget,
isBenchComponentTarget,

-- * Setup script
SetupScriptStyle(..),
Expand Down Expand Up @@ -289,6 +293,8 @@ data ElaboratedConfiguredPackage
elabTestTargets :: [ComponentTarget],
elabBenchTargets :: [ComponentTarget],
elabReplTarget :: Maybe ComponentTarget,
elabHaddockTargets :: [ComponentTarget],

elabBuildHaddocks :: Bool,

--pkgSourceDir ? -- currently passed in later because they can use temp locations
Expand Down Expand Up @@ -667,6 +673,22 @@ showBenchComponentTarget :: PackageId -> ComponentTarget -> Maybe String
showBenchComponentTarget _ (ComponentTarget (CBenchName n) _) = Just $ display n
showBenchComponentTarget _ _ = Nothing

isBenchComponentTarget :: ComponentTarget -> Bool
isBenchComponentTarget (ComponentTarget (CBenchName _) _) = True
isBenchComponentTarget _ = False

isForeignLibComponentTarget :: ComponentTarget -> Bool
isForeignLibComponentTarget (ComponentTarget (CFLibName _) _) = True
isForeignLibComponentTarget _ = False

isExeComponentTarget :: ComponentTarget -> Bool
isExeComponentTarget (ComponentTarget (CExeName _) _ ) = True
isExeComponentTarget _ = False

isSubLibComponentTarget :: ComponentTarget -> Bool
isSubLibComponentTarget (ComponentTarget (CSubLibName _) _) = True
isSubLibComponentTarget _ = False

---------------------------
-- Setup.hs script policy
--
Expand Down

0 comments on commit 43310a7

Please sign in to comment.