Skip to content

Commit b7179b6

Browse files
amesgenmrkkrp
authored andcommitted
extract-hackage-info: allow to dump as JSON
1 parent b2e2a6b commit b7179b6

File tree

4 files changed

+74
-11
lines changed

4 files changed

+74
-11
lines changed

extract-hackage-info.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ cleanup()
1616
mkdir "$HOOGLE_DATABASE"
1717
curl "https://hackage.haskell.org/packages/hoogle.tar.gz" | tar -xz -C "$HOOGLE_DATABASE"
1818

19-
nix run .#extract-hackage-info -- "$HOOGLE_DATABASE" -o "$OUTPUT"
19+
nix run .#extract-hackage-info -- generate "$HOOGLE_DATABASE" -o "$OUTPUT"
2020

2121
cp "$OUTPUT" "extract-hackage-info/hackage-info.bin"
2222

extract-hackage-info/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,9 @@ newtype HackageInfo
5151
## How to use `extract-hackage-info`
5252

5353
Run `extract-hackage-info.sh` from the root of the repository.
54+
55+
You can also dump the Hackage info database as JSON via
56+
57+
```console
58+
cabal run extract-hackage-info -- dump extract-hackage-info/hackage-info.bin
59+
```

extract-hackage-info/extract-hackage-info.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ executable extract-hackage-info
1212
ghc-options: -O2 -Wall -rtsopts -Wunused-packages
1313
build-depends:
1414
Cabal-syntax >=3.12 && <3.13,
15+
aeson >=2.2 && <3,
1516
base >=4.12 && <5,
1617
binary >=0.8 && <0.9,
1718
bytestring >=0.10 && <0.13,

extract-hackage-info/src/Main.hs

Lines changed: 66 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
{-# LANGUAGE BlockArguments #-}
22
{-# LANGUAGE DataKinds #-}
3+
{-# LANGUAGE DeriveAnyClass #-}
4+
{-# LANGUAGE DerivingStrategies #-}
35
{-# LANGUAGE LambdaCase #-}
46
{-# LANGUAGE OverloadedStrings #-}
57
{-# LANGUAGE RecordWildCards #-}
8+
{-# OPTIONS_GHC -Wno-orphans #-}
69

710
module Main (main) where
811

912
import Control.Exception
1013
import Control.Monad
14+
import Data.Aeson qualified as A
1115
import Data.Binary qualified as Binary
16+
import Data.Binary.Get qualified as Binary
1217
import Data.Binary.Put qualified as Binary
1318
import Data.ByteString qualified as ByteString
1419
import Data.ByteString.Lazy qualified as BL
@@ -21,7 +26,9 @@ import Data.Text.Encoding (decodeLatin1)
2126
import Data.Text.Encoding.Error (UnicodeException)
2227
import Data.Text.IO.Utf8 qualified as T.Utf8
2328
import Distribution.ModuleName (ModuleName)
29+
import Distribution.ModuleName qualified as ModuleName
2430
import Distribution.Types.PackageName (PackageName)
31+
import Distribution.Types.PackageName qualified as PackageName
2532
import Formatting
2633
import Hoogle qualified
2734
import Options.Applicative
@@ -175,18 +182,54 @@ displayFixityStats packages =
175182
declarationsPerModule = concatMap Map.elems modulesPerPackage
176183
declarationCount = sum (Map.size <$> declarationsPerModule)
177184

178-
data Config = Config
179-
{ cfgHoogleDatabasePath :: FilePath,
180-
cfgOutputPath :: FilePath
181-
}
185+
-- ToJSON orphan instances
186+
187+
deriving anyclass instance A.ToJSON FixityInfo
188+
189+
deriving anyclass instance A.ToJSON FixityDirection
190+
191+
instance A.ToJSON OpName where
192+
toJSON = A.toJSON . unOpName
193+
194+
deriving anyclass instance A.ToJSONKey OpName
195+
196+
instance A.ToJSON ModuleName where
197+
toJSON = A.toJSON . ModuleName.toFilePath
198+
199+
deriving anyclass instance A.ToJSONKey ModuleName
200+
201+
instance A.ToJSON PackageName where
202+
toJSON = A.toJSON . PackageName.unPackageName
203+
204+
deriving anyclass instance A.ToJSONKey PackageName
205+
206+
-- CLI config
207+
208+
data Config
209+
= Generate
210+
{ cfgHoogleDatabasePath :: FilePath,
211+
cfgOutputPath :: FilePath
212+
}
213+
| Dump
214+
{ cfgPath :: FilePath
215+
}
182216
deriving (Eq, Show)
183217

184218
configParserInfo :: ParserInfo Config
185219
configParserInfo = info (helper <*> configParser) fullDesc
186220
where
187221
configParser :: Parser Config
188222
configParser =
189-
Config
223+
subparser . mconcat $
224+
[ command "generate" . info (helper <*> generateParser) $
225+
fullDesc <> progDesc "Generate a Hackage info database.",
226+
command "dump" . info (helper <*> dumpParser) $
227+
fullDesc <> progDesc "Dump a generated Hackage info database to JSON."
228+
]
229+
230+
generateParser :: Parser Config
231+
generateParser =
232+
Generate
190233
<$> (strArgument . mconcat)
191234
[ metavar "HOOGLE_DATABASE_PATH",
192235
help
@@ -201,9 +244,22 @@ configParserInfo = info (helper <*> configParser) fullDesc
201244
value defaultOutputPath
202245
]
203246

247+
dumpParser :: Parser Config
248+
dumpParser =
249+
Dump
250+
<$> (strArgument . mconcat)
251+
[ metavar "HACKAGE_INFO_PATH",
252+
help "A generated Hackage info database"
253+
]
254+
204255
main :: IO ()
205-
main = do
206-
Config {..} <- execParser configParserInfo
207-
hackageInfo' <- extractHoogleInfo cfgHoogleDatabasePath
208-
BL.writeFile cfgOutputPath . Binary.runPut . Binary.put $
209-
HackageInfo hackageInfo'
256+
main =
257+
execParser configParserInfo >>= \case
258+
Generate {..} -> do
259+
hackageInfo' <- extractHoogleInfo cfgHoogleDatabasePath
260+
BL.writeFile cfgOutputPath . Binary.runPut . Binary.put $
261+
HackageInfo hackageInfo'
262+
Dump {..} -> do
263+
HackageInfo hackageInfo' <-
264+
Binary.runGet Binary.get <$> BL.readFile cfgPath
265+
BL.putStr $ A.encode hackageInfo'

0 commit comments

Comments
 (0)