Skip to content

Commit

Permalink
Add --haddock-odir flag to cabal haddock.
Browse files Browse the repository at this point in the history
This flag gives the user full control over the directory where the documentation is placed.
  • Loading branch information
LiisiKerik committed Mar 17, 2023
1 parent 6870def commit ea5fe9d
Show file tree
Hide file tree
Showing 34 changed files with 198 additions and 35 deletions.
14 changes: 12 additions & 2 deletions Cabal/src/Distribution/Simple/Flag.hs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE FlexibleContexts #-}
-----------------------------------------------------------------------------
-- |
Expand Down Expand Up @@ -53,7 +55,7 @@ import Distribution.Compat.Stack
-- Its monoid instance gives us the behaviour where it starts out as
-- 'NoFlag' and later flags override earlier ones.
--
data Flag a = Flag a | NoFlag deriving (Eq, Generic, Show, Read, Typeable)
data Flag a = Flag a | NoFlag deriving (Eq, Generic, Show, Read, Typeable, Foldable, Traversable)

instance Binary a => Binary (Flag a)
instance Structured a => Structured (Flag a)
Expand All @@ -67,6 +69,14 @@ instance Applicative Flag where
NoFlag <*> _ = NoFlag
pure = Flag

{-instance Foldable Flag where
foldMap _ NoFlag = mempty
foldMap f (Flag x) = f x
instance Traversable Flag where
sequenceA NoFlag = pure NoFlag
sequenceA (Flag x) = Flag <$> x-}

instance Monoid (Flag a) where
mempty = NoFlag
mappend = (<>)
Expand Down
11 changes: 8 additions & 3 deletions Cabal/src/Distribution/Simple/Haddock.hs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ data HaddockArgs = HaddockArgs {
-- ^ Modules to process.
argLib :: Flag String
-- ^ haddock's static \/ auxiliary files.
} deriving Generic
} deriving (Generic, Show)

-- | The FilePath of a directory, it's a monoid under '(</>)'.
newtype Directory = Dir { unDir' :: FilePath } deriving (Read,Show,Eq,Ord)
Expand All @@ -150,7 +150,7 @@ unDir = normalise . unDir'
type Template = String

data Output = Html | Hoogle
deriving Eq
deriving (Eq, Show)

-- ------------------------------------------------------------------------------
-- Haddock support
Expand Down Expand Up @@ -243,7 +243,12 @@ haddock pkg_descr lbi suffixes flags' = do
fromFlagOrDefault ForDevelopment (haddockForHackage flags')

libdirArgs <- getGhcLibDir verbosity lbi
let commonArgs = mconcat
-- The haddock-odir flag overrides any other documentation placement concerns.
-- The point is to give the user full freedom over the location if they need it.
let overrideWithOdir args = case haddockOdir flags of
NoFlag -> args
Flag dir -> args { argOutputDir = Dir dir }
let commonArgs = overrideWithOdir $ mconcat
[ libdirArgs
, fromFlags (haddockTemplateEnv lbi (packageId pkg_descr)) flags
, fromPackageDescription haddockTarget pkg_descr ]
Expand Down
16 changes: 15 additions & 1 deletion Cabal/src/Distribution/Simple/Setup/Haddock.hs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ data HaddockFlags = HaddockFlags {
haddockCabalFilePath :: Flag FilePath,
haddockBaseUrl :: Flag String,
haddockLib :: Flag String,
haddockOdir :: Flag String,
haddockArgs :: [String]
}
deriving (Show, Generic, Typeable)
Expand Down Expand Up @@ -123,6 +124,7 @@ defaultHaddockFlags = HaddockFlags {
haddockIndex = NoFlag,
haddockBaseUrl = NoFlag,
haddockLib = NoFlag,
haddockOdir = NoFlag,
haddockArgs = mempty
}

Expand Down Expand Up @@ -267,6 +269,11 @@ haddockOptions showOrParseArgs =
"location of Haddocks static / auxiliary files"
haddockLib (\v flags -> flags { haddockLib = v})
(reqArgFlag "DIR")

,option "" ["odir"]
"Generate haddock documentation into this directory."
haddockOdir (\v flags -> flags { haddockOdir = v })
(reqArgFlag "DIR")
]

emptyHaddockFlags :: HaddockFlags
Expand Down Expand Up @@ -343,7 +350,8 @@ data HaddockProjectFlags = HaddockProjectFlags {
haddockProjectKeepTempFiles:: Flag Bool,
haddockProjectVerbosity :: Flag Verbosity,
-- haddockBaseUrl is not supported, a fixed value is provided
haddockProjectLib :: Flag String
haddockProjectLib :: Flag String,
haddockProjectOdir :: Flag String
}
deriving (Show, Generic, Typeable)

Expand Down Expand Up @@ -371,6 +379,7 @@ defaultHaddockProjectFlags = HaddockProjectFlags {
haddockProjectKeepTempFiles= Flag False,
haddockProjectVerbosity = Flag normal,
haddockProjectLib = NoFlag,
haddockProjectOdir = NoFlag,
haddockProjectInterfaces = NoFlag
}

Expand Down Expand Up @@ -505,6 +514,11 @@ haddockProjectOptions _showOrParseArgs =
"location of Haddocks static / auxiliary files"
haddockProjectLib (\v flags -> flags { haddockProjectLib = v})
(reqArgFlag "DIR")

,option "" ["odir"]
"Generate haddock documentation into this directory."
haddockProjectOdir (\v flags -> flags { haddockProjectOdir = v})
(reqArgFlag "DIR")
]


Expand Down
2 changes: 1 addition & 1 deletion cabal-install/src/Distribution/Client/CmdClean.hs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ cleanAction CleanFlags{..} extraArgs _ = do

projectRoot <- either throwIO return =<< findProjectRoot verbosity mprojectDir mprojectFile

let distLayout = defaultDistDirLayout projectRoot mdistDirectory
let distLayout = defaultDistDirLayout projectRoot mdistDirectory Nothing

-- Do not clean a project if just running a script in it's directory
when (null extraArgs || isJust mdistDirectory) $ do
Expand Down
37 changes: 29 additions & 8 deletions cabal-install/src/Distribution/Client/CmdHaddock.hs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ module Distribution.Client.CmdHaddock (

import Distribution.Client.Compat.Prelude
import Prelude ()
import System.Directory (makeAbsolute)

import Distribution.Client.ProjectConfig.Types
(PackageConfig (..), ProjectConfig (..))
import Distribution.Client.ProjectOrchestration
import Distribution.Client.ProjectPlanning
( ElaboratedSharedConfig(..) )
Expand All @@ -43,7 +46,7 @@ import Distribution.Simple.Flag (Flag(..))

import qualified System.Exit (exitSuccess)

newtype ClientHaddockFlags = ClientHaddockFlags { openInBrowser :: Flag Bool }
newtype ClientHaddockFlags = ClientHaddockFlags { openInBrowser :: Flag Bool } deriving Show

haddockCommand :: CommandUI (NixStyleFlags ClientHaddockFlags)
haddockCommand = CommandUI {
Expand Down Expand Up @@ -83,20 +86,43 @@ haddockOptions _ =
openInBrowser (\v f -> f { openInBrowser = v}) trueArg
]

mkConfigAbsolute :: ProjectConfig -> IO ProjectConfig
mkConfigAbsolute relConfig = do
let relPackageConfig = projectConfigLocalPackages relConfig
absHaddockOdir <- traverse makeAbsolute (packageConfigHaddockOdir relPackageConfig)
return (relConfig { projectConfigLocalPackages = relPackageConfig { packageConfigHaddockOdir = absHaddockOdir } })

mkFlagsAbsolute :: NixStyleFlags ClientHaddockFlags -> IO (NixStyleFlags ClientHaddockFlags)
mkFlagsAbsolute relFlags = do
let relHaddockFlags = haddockFlags relFlags
absHaddockOdir <- traverse makeAbsolute (haddockOdir relHaddockFlags)
return (relFlags { haddockFlags = relHaddockFlags { haddockOdir = absHaddockOdir } })

-- | The @haddock@ command is TODO.
--
-- For more details on how this works, see the module
-- "Distribution.Client.ProjectOrchestration"
--
haddockAction :: NixStyleFlags ClientHaddockFlags -> [String] -> GlobalFlags -> IO ()
haddockAction flags@NixStyleFlags {..} targetStrings globalFlags = do
haddockAction relFlags targetStrings globalFlags = do
-- It's important to make --haddock-odir absolute since we change the working directory later.
flags@NixStyleFlags {..} <- mkFlagsAbsolute relFlags

let
verbosity = fromFlagOrDefault normal (configVerbosity configFlags)
installDoc = fromFlagOrDefault True (installDocumentation installFlags)
flags' = flags { installFlags = installFlags { installDocumentation = Flag installDoc } }
cliConfig = commandLineFlagsToProjectConfig globalFlags flags' mempty -- ClientInstallFlags, not needed here

projCtx <- establishProjectBaseContext verbosity cliConfig HaddockCommand

let baseCtx
let relBaseCtx@ProjectBaseContext { projectConfig = relProjectConfig }
| fromFlagOrDefault False (openInBrowser extraFlags)
= projCtx { buildSettings = (buildSettings projCtx) { buildSettingHaddockOpen = True } }
| otherwise
= projCtx
absProjectConfig <- mkConfigAbsolute relProjectConfig
let baseCtx = relBaseCtx { projectConfig = absProjectConfig }

targetSelectors <- either (reportTargetSelectorProblems verbosity) return
=<< readTargetSelectors (localPackages baseCtx) Nothing targetStrings
Expand Down Expand Up @@ -141,11 +167,6 @@ haddockAction flags@NixStyleFlags {..} targetStrings globalFlags = do

buildOutcomes <- runProjectBuildPhase verbosity baseCtx buildCtx'
runProjectPostBuildPhase verbosity baseCtx buildCtx' buildOutcomes
where
verbosity = fromFlagOrDefault normal (configVerbosity configFlags)
installDoc = fromFlagOrDefault True (installDocumentation installFlags)
flags' = flags { installFlags = installFlags { installDocumentation = Flag installDoc } }
cliConfig = commandLineFlagsToProjectConfig globalFlags flags' mempty -- ClientInstallFlags, not needed here

-- | This defines what a 'TargetSelector' means for the @haddock@ command.
-- It selects the 'AvailableTarget's that the 'TargetSelector' refers to,
Expand Down
1 change: 1 addition & 0 deletions cabal-install/src/Distribution/Client/CmdHaddockProject.hs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ haddockProjectAction flags _extraArgs globalFlags = do
, haddockKeepTempFiles= haddockProjectKeepTempFiles flags
, haddockVerbosity = haddockProjectVerbosity flags
, haddockLib = haddockProjectLib flags
, haddockOdir = haddockProjectOdir flags
}
nixFlags = (commandDefaultFlags CmdHaddock.haddockCommand)
{ NixStyleOptions.haddockFlags = haddockFlags
Expand Down
2 changes: 1 addition & 1 deletion cabal-install/src/Distribution/Client/CmdOutdated.hs
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ depsFromNewFreezeFile verbosity httpTransport compiler (Platform arch os) mproje
projectRoot <- either throwIO return =<<
findProjectRoot verbosity mprojectDir mprojectFile
let distDirLayout = defaultDistDirLayout projectRoot
{- TODO: Support dist dir override -} Nothing
{- TODO: Support dist dir override -} Nothing Nothing
projectConfig <- runRebuild (distProjectRootDirectory distDirLayout) $ do
pcs <- readProjectLocalFreezeConfig verbosity httpTransport distDirLayout
pure $ instantiateProjectConfigSkeletonWithCompiler os arch (compilerInfo compiler) mempty pcs
Expand Down
1 change: 1 addition & 0 deletions cabal-install/src/Distribution/Client/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,7 @@ instance Semigroup SavedConfig where
haddockIndex = combine haddockIndex,
haddockBaseUrl = combine haddockBaseUrl,
haddockLib = combine haddockLib,
haddockOdir = combine haddockOdir,
haddockArgs = lastNonEmpty haddockArgs
}
where
Expand Down
14 changes: 10 additions & 4 deletions cabal-install/src/Distribution/Client/DistDirLayout.hs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,10 @@ data DistDirLayout = DistDirLayout {
distTempDirectory :: FilePath,
distBinDirectory :: FilePath,

distPackageDB :: CompilerId -> PackageDB
distPackageDB :: CompilerId -> PackageDB,

-- | Is needed when `--haddock-odir` flag is used.
distHaddockOdir :: Maybe FilePath
}


Expand Down Expand Up @@ -180,14 +183,15 @@ defaultProjectFile :: FilePath
defaultProjectFile = "cabal.project"

-- | Make the default 'DistDirLayout' based on the project root dir and
-- optional overrides for the location of the @dist@ directory and the
-- @cabal.project@ file.
-- optional overrides for the location of the @dist@ directory, the
-- @cabal.project@ file and the documentation directory.
--
defaultDistDirLayout :: ProjectRoot -- ^ the project root
-> Maybe FilePath -- ^ the @dist@ directory or default
-- (absolute or relative to the root)
-> Maybe FilePath -- ^ the documentation directory
-> DistDirLayout
defaultDistDirLayout projectRoot mdistDirectory =
defaultDistDirLayout projectRoot mdistDirectory haddockOdir =
DistDirLayout {..}
where
(projectRootDir, projectFile) = case projectRoot of
Expand Down Expand Up @@ -272,6 +276,8 @@ defaultDistDirLayout projectRoot mdistDirectory =
distPackageDB :: CompilerId -> PackageDB
distPackageDB = SpecificPackageDB . distPackageDBPath

distHaddockOdir :: Maybe FilePath
distHaddockOdir = haddockOdir

defaultStoreDirLayout :: FilePath -> StoreDirLayout
defaultStoreDirLayout storeRoot =
Expand Down
3 changes: 3 additions & 0 deletions cabal-install/src/Distribution/Client/NixStyleOptions.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{-# LANGUAGE StandaloneDeriving #-}

-- | Command line options for nix-style / v2 commands.
--
-- The commands take a lot of the same options, which affect how install plan
Expand Down Expand Up @@ -31,6 +33,7 @@ data NixStyleFlags a = NixStyleFlags
, projectFlags :: ProjectFlags
, extraFlags :: a
}
deriving instance Show a => Show (NixStyleFlags a)

nixStyleOptions
:: (ShowOrParseArgs -> [OptionField a])
Expand Down
4 changes: 3 additions & 1 deletion cabal-install/src/Distribution/Client/PackageHash.hs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,8 @@ data PackageHashConfigInputs = PackageHashConfigInputs {
pkgHashHaddockContents :: Maybe PathTemplate,
pkgHashHaddockIndex :: Maybe PathTemplate,
pkgHashHaddockBaseUrl :: Maybe String,
pkgHashHaddockLib :: Maybe String
pkgHashHaddockLib :: Maybe String,
pkgHashHaddockOdir :: Maybe String

-- TODO: [required eventually] pkgHashToolsVersions ?
-- TODO: [required eventually] pkgHashToolsExtraOptions ?
Expand Down Expand Up @@ -317,6 +318,7 @@ renderPackageHashInputs PackageHashInputs{
, opt "haddock-index-location" Nothing (maybe "" fromPathTemplate) pkgHashHaddockIndex
, opt "haddock-base-url" Nothing (fromMaybe "") pkgHashHaddockBaseUrl
, opt "haddock-lib" Nothing (fromMaybe "") pkgHashHaddockLib
, opt "haddock-odir" Nothing (fromMaybe "") pkgHashHaddockOdir

] ++ Map.foldrWithKey (\prog args acc -> opt (prog ++ "-options") [] unwords args : acc) [] pkgHashProgramArgs
where
Expand Down
10 changes: 6 additions & 4 deletions cabal-install/src/Distribution/Client/ProjectBuilding.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1266,7 +1266,8 @@ buildInplaceUnpackedPackage verbosity
distDirLayout@DistDirLayout {
distTempDirectory,
distPackageCacheDirectory,
distDirectory
distDirectory,
distHaddockOdir
}
BuildTimeSettings{buildSettingNumJobs, buildSettingHaddockOpen}
registerLock cacheLock
Expand Down Expand Up @@ -1390,10 +1391,11 @@ buildInplaceUnpackedPackage verbosity
notice verbosity $ "Documentation tarball created: " ++ dest

when (buildSettingHaddockOpen && haddockTarget /= Cabal.ForHackage) $ do
let dest = docDir </> name </> "index.html"
let dest = docDir </> "index.html"
name = haddockDirName haddockTarget (elabPkgDescription pkg)
docDir = distBuildDirectory distDirLayout dparams
</> "doc" </> "html"
docDir = case distHaddockOdir of
Nothing -> distBuildDirectory distDirLayout dparams </> "doc" </> "html" </> name
Just dir -> dir
exe <- findOpenProgramLocation platform
case exe of
Right open -> runProgramInvocation verbosity (simpleProgramInvocation open [dest])
Expand Down
6 changes: 4 additions & 2 deletions cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,8 @@ convertLegacyPerPackageFlags configFlags installFlags
haddockContents = packageConfigHaddockContents,
haddockIndex = packageConfigHaddockIndex,
haddockBaseUrl = packageConfigHaddockBaseUrl,
haddockLib = packageConfigHaddockLib
haddockLib = packageConfigHaddockLib,
haddockOdir = packageConfigHaddockOdir
} = haddockFlags

TestFlags {
Expand Down Expand Up @@ -985,6 +986,7 @@ convertToLegacyPerPackageConfig PackageConfig {..} =
haddockIndex = packageConfigHaddockIndex,
haddockBaseUrl = packageConfigHaddockBaseUrl,
haddockLib = packageConfigHaddockLib,
haddockOdir = packageConfigHaddockOdir,
haddockArgs = mempty
}

Expand Down Expand Up @@ -1305,7 +1307,7 @@ legacyPackageConfigFieldDescrs =
, "executables", "tests", "benchmarks", "all", "internal", "css"
, "hyperlink-source", "quickjump", "hscolour-css"
, "contents-location", "index-location", "keep-temp-files", "base-url"
, "lib"
, "lib", "odir"
]
. commandOptionsToFields
) (haddockOptions ParseArgs)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ data PackageConfig
packageConfigHaddockIndex :: Flag PathTemplate, --TODO: [required eventually] use this
packageConfigHaddockBaseUrl :: Flag String, --TODO: [required eventually] use this
packageConfigHaddockLib :: Flag String, --TODO: [required eventually] use this
packageConfigHaddockOdir :: Flag String, --TODO: [required eventually] use this
packageConfigHaddockForHackage :: Flag HaddockTarget,
-- Test options
packageConfigTestHumanLog :: Flag PathTemplate,
Expand Down
5 changes: 3 additions & 2 deletions cabal-install/src/Distribution/Client/ProjectOrchestration.hs
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,8 @@ establishProjectBaseContextWithRoot
-> CurrentCommand
-> IO ProjectBaseContext
establishProjectBaseContextWithRoot verbosity cliConfig projectRoot currentCommand = do
let distDirLayout = defaultDistDirLayout projectRoot mdistDirectory
let haddockOdir = flagToMaybe (packageConfigHaddockOdir (projectConfigLocalPackages cliConfig))
let distDirLayout = defaultDistDirLayout projectRoot mdistDirectory haddockOdir

httpTransport <- configureTransport verbosity
(fromNubList . projectConfigProgPathExtra $ projectConfigShared cliConfig)
Expand Down Expand Up @@ -1359,7 +1360,7 @@ establishDummyProjectBaseContext verbosity projectConfig distDirLayout localPack

establishDummyDistDirLayout :: Verbosity -> ProjectConfig -> FilePath -> IO DistDirLayout
establishDummyDistDirLayout verbosity cliConfig tmpDir = do
let distDirLayout = defaultDistDirLayout projectRoot mdistDirectory
let distDirLayout = defaultDistDirLayout projectRoot mdistDirectory Nothing

-- Create the dist directories
createDirectoryIfMissingVerbose verbosity True $ distDirectory distDirLayout
Expand Down
Loading

0 comments on commit ea5fe9d

Please sign in to comment.