Skip to content

Commit 9b8be6f

Browse files
authored
Merge pull request #1279 from 414owen/os/support-sublibrary-mods-sigs
feat: Add support for sublibrary module listings
2 parents 8e36558 + f939e97 commit 9b8be6f

File tree

3 files changed

+62
-26
lines changed

3 files changed

+62
-26
lines changed

datafiles/static/hackage.css

+8
Original file line numberDiff line numberDiff line change
@@ -1146,6 +1146,14 @@ a.deprecated[href]:visited {
11461146
color: #61B01E;
11471147
}
11481148

1149+
.lib-contents {
1150+
margin-left: 20px;
1151+
}
1152+
1153+
.lib-contents > h3 {
1154+
margin: 0.7em 0;
1155+
}
1156+
11491157
/* Paginator */
11501158
#paginatorContainer {
11511159
display: flex;

src/Distribution/Server/Packages/Render.hs

+29-15
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
-- TODO: Review and possibly move elsewhere. This code was part of the
22
-- RecentPackages (formerly "Check") feature, but that caused some cyclic
33
-- dependencies.
4+
{-# LANGUAGE TupleSections #-}
45
module Distribution.Server.Packages.Render (
56
-- * Package render
67
PackageRender(..)
@@ -53,6 +54,7 @@ import Distribution.Utils.ShortText (fromShortText)
5354

5455
import qualified Data.TarIndex as TarIndex
5556
import Data.TarIndex (TarIndex, TarEntryOffset)
57+
import Data.Bifunctor (first, Bifunctor (..))
5658

5759
data ModSigIndex = ModSigIndex {
5860
modIndex :: ModuleForest,
@@ -64,10 +66,10 @@ data ModSigIndex = ModSigIndex {
6466
-- This is why some fields of PackageDescription are preprocessed, and others aren't.
6567
data PackageRender = PackageRender {
6668
rendPkgId :: PackageIdentifier,
69+
rendLibName :: LibraryName -> String,
6770
rendDepends :: [Dependency],
6871
rendExecNames :: [String],
69-
rendLibraryDeps :: Maybe DependencyTree,
70-
rendSublibraryDeps :: [(String, DependencyTree)],
72+
rendLibraryDeps :: [(LibraryName, DependencyTree)],
7173
rendExecutableDeps :: [(String, DependencyTree)],
7274
rendLicenseName :: String,
7375
rendLicenseFiles :: [FilePath],
@@ -78,7 +80,7 @@ data PackageRender = PackageRender {
7880
-- to test if a module actually has a corresponding documentation HTML
7981
-- file we can link to. If no 'TarIndex' is provided, it is assumed
8082
-- all links are dead.
81-
rendModules :: Maybe TarIndex -> Maybe ModSigIndex,
83+
rendModules :: Maybe TarIndex -> [(LibraryName, ModSigIndex)],
8284
rendHasTarball :: Bool,
8385
rendChangeLog :: Maybe (FilePath, ETag, TarEntryOffset, FilePath),
8486
rendReadme :: Maybe (FilePath, ETag, TarEntryOffset, FilePath),
@@ -95,14 +97,13 @@ data PackageRender = PackageRender {
9597

9698
doPackageRender :: Users.Users -> PkgInfo -> PackageRender
9799
doPackageRender users info = PackageRender
98-
{ rendPkgId = pkgInfoId info
100+
{ rendPkgId = packageId'
99101
, rendDepends = flatDependencies genDesc
102+
, rendLibName = renderLibName
100103
, rendExecNames = map (unUnqualComponentName . exeName) (executables flatDesc)
101-
, rendLibraryDeps = depTree libBuildInfo `fmap` condLibrary genDesc
102104
, rendExecutableDeps = (unUnqualComponentName *** depTree buildInfo)
103105
`map` condExecutables genDesc
104-
, rendSublibraryDeps = (unUnqualComponentName *** depTree libBuildInfo)
105-
`map` condSubLibraries genDesc
106+
, rendLibraryDeps = second (depTree libBuildInfo) <$> allCondLibs genDesc
106107
, rendLicenseName = prettyShow (license desc) -- maybe make this a bit more human-readable
107108
, rendLicenseFiles = map getSymbolicPath $ licenseFiles desc
108109
, rendMaintainer = case fromShortText $ maintainer desc of
@@ -144,17 +145,15 @@ doPackageRender users info = PackageRender
144145
then Buildable
145146
else NotBuildable
146147

147-
renderModules docindex
148-
| Just lib <- library flatDesc
149-
= let mod_ix = mkForest $ exposedModules lib
148+
renderModules :: Maybe TarIndex -> [(LibraryName, ModSigIndex)]
149+
renderModules docindex = flip fmap (allLibraries flatDesc) $ \lib ->
150+
let mod_ix = mkForest $ exposedModules lib
150151
-- Assumes that there is an HTML per reexport
151152
++ map moduleReexportName (reexportedModules lib)
152153
++ virtualModules (libBuildInfo lib)
153-
sig_ix = mkForest $ signatures lib
154-
mkForest = moduleForest . map (\m -> (m, moduleHasDocs docindex m))
155-
in Just (ModSigIndex { modIndex = mod_ix, sigIndex = sig_ix })
156-
| otherwise
157-
= Nothing
154+
sig_ix = mkForest $ signatures lib
155+
mkForest = moduleForest . map (\m -> (m, moduleHasDocs docindex m))
156+
in (libName lib, ModSigIndex { modIndex = mod_ix, sigIndex = sig_ix })
158157

159158
moduleHasDocs :: Maybe TarIndex -> ModuleName -> Bool
160159
moduleHasDocs Nothing = const False
@@ -172,6 +171,21 @@ doPackageRender users info = PackageRender
172171
loc <- repoLocation r
173172
return (ty, loc, r)
174173

174+
packageId' :: PackageIdentifier
175+
packageId' = pkgInfoId info
176+
177+
packageName' :: String
178+
packageName' = unPackageName $ pkgName packageId'
179+
180+
renderLibName :: LibraryName -> String
181+
renderLibName LMainLibName = packageName'
182+
renderLibName (LSubLibName name) =
183+
packageName' ++ ":" ++ unUnqualComponentName name
184+
185+
allCondLibs :: GenericPackageDescription -> [(LibraryName, CondTree ConfVar [Dependency] Library)]
186+
allCondLibs desc = maybeToList ((LMainLibName,) <$> condLibrary desc)
187+
++ (first LSubLibName <$> condSubLibraries desc)
188+
175189
type DependencyTree = CondTree ConfVar [Dependency] IsBuildable
176190

177191
data IsBuildable = Buildable

src/Distribution/Server/Pages/Package.hs

+25-11
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,10 @@ import Distribution.Utils.ShortText (fromShortText, ShortText)
3434
import Text.XHtml.Strict hiding (p, name, title, content)
3535
import qualified Text.XHtml.Strict
3636

37-
import Data.Maybe (fromMaybe, maybeToList, isJust, mapMaybe, catMaybes)
37+
import Data.Bool (bool)
38+
import Data.Maybe (fromMaybe, isJust, mapMaybe, catMaybes)
3839
import Data.List (intersperse, intercalate, partition)
39-
import Control.Arrow (second)
40+
import Control.Arrow (second, Arrow (..))
4041
import System.FilePath.Posix ((</>), (<.>))
4142

4243
import qualified Documentation.Haddock.Markup as Haddock
@@ -152,15 +153,19 @@ renderPackageFlags render docURL =
152153
whenNotNull xs a = if null xs then [] else a
153154

154155
moduleSection :: PackageRender -> Maybe TarIndex -> URL -> Maybe PackageId -> Bool -> [Html]
155-
moduleSection render mdocIndex docURL mPkgId quickNav =
156-
maybeToList $ fmap msect (rendModules render mdocIndex)
157-
where msect ModSigIndex{ modIndex = m, sigIndex = s } = toHtml $
156+
moduleSection render mdocIndex docURL mPkgId quickNav = case renderedModules of
157+
[(LMainLibName, mods)] -> [msect mods]
158+
renderedLibs -> concatMap renderNamedLib renderedLibs
159+
160+
where msect (ModSigIndex{ modIndex = m, sigIndex = s }) =
161+
let heading = bool h3 h2 containsSubLibraries in
162+
toHtml $
158163
(if not (null s)
159-
then [ h2 << "Signatures"
164+
then [ heading << "Signatures"
160165
, renderModuleForest docURL s ]
161166
else []) ++
162167
(if not (null m)
163-
then [ h2 << "Modules"] ++
168+
then [ heading << "Modules"] ++
164169
[renderDocIndexLink] ++
165170
[renderModuleForest docURL m ]
166171
else [])
@@ -184,6 +189,18 @@ moduleSection render mdocIndex docURL mPkgId quickNav =
184189
concatLinks [h] = Just h
185190
concatLinks (h:hs) = (h +++) . ("] [" +++) <$> concatLinks hs
186191

192+
renderNamedLib :: (LibraryName, ModSigIndex) -> [Html]
193+
renderNamedLib (name, mods) =
194+
[ h2 << ("library " ++ rendLibName render name)
195+
, thediv ! [theclass "lib-contents"] << msect mods
196+
]
197+
198+
containsSubLibraries :: Bool
199+
containsSubLibraries = map fst renderedModules == [LMainLibName]
200+
201+
renderedModules :: [(LibraryName, ModSigIndex)]
202+
renderedModules = rendModules render mdocIndex
203+
187204
tabulate :: [(String, Html)] -> Html
188205
tabulate items = table ! [theclass "properties"] <<
189206
[tr << [th << t, td << d] | (t, d) <- items]
@@ -223,11 +240,8 @@ renderDetailedDependencies pkgRender =
223240
tabulate $ map (second (fromMaybe noDeps . render)) targets
224241
where
225242
targets :: [(String, DependencyTree)]
226-
targets = maybeToList library
227-
++ rendSublibraryDeps pkgRender
243+
targets = (first (rendLibName pkgRender) <$> rendLibraryDeps pkgRender)
228244
++ rendExecutableDeps pkgRender
229-
where
230-
library = (\lib -> ("library", lib)) `fmap` rendLibraryDeps pkgRender
231245

232246
noDeps = list [toHtml "No dependencies"]
233247

0 commit comments

Comments
 (0)