nix-helpers: ba56e269853da53549414a223a4dda1afdbbd9e5
1: {-# LANGUAGE OverloadedStrings #-}
2: module Main where
3:
4: import qualified Codec.Archive.Tar as Tar
5: import qualified Codec.Archive.Tar.Entry as Tar
6: import Control.Exception (throw)
7: import qualified Data.Aeson as A
8: import qualified Data.Aeson.Encoding as A
9: import qualified Data.Aeson.Types as A
10: import Data.Aeson ((.=), (.:))
11: import qualified Data.ByteString.Lazy.Char8 as LB
12: import Data.List (isSuffixOf)
13: import Data.String (fromString)
14: import Data.String.Utils (join, split)
15:
16: -- Pipe stdio through Tar.read/Tar.write, running fixEntry on each entry
17: main = LB.interact pipeTar
18: pipeTar = Tar.write . (Tar.foldEntries fixEntry [] throw) . Tar.read
19:
20: -- Use these to abort the process if any error occurs
21: err = either error id
22: tarPath = err . Tar.toTarPath False
23:
24: fixEntry x xs = case (Tar.entryContent x, path) of
25: -- Keep NormalFiles, but change their path and possibly content
26: (Tar.NormalFile f _, _ : n : v : _) | ".json" `isSuffixOf` last path ->
27: fixFile n v f : xs
28:
29: -- Keep other files as-is, but drop the leading dir from their path
30: (Tar.NormalFile _ _, _) ->
31: x { Tar.entryTarPath = tarPath (join "/" (tail path)) } : xs
32:
33: -- Anything other than NormalFile gets dropped (directories, etc.)
34: _ -> xs
35: where path = split "/" (Tar.fromTarPath (Tar.entryTarPath x))
36:
37: -- Parse JSON for source metadata, then use that to write a package.json
38: fixFile name version bytes = Tar.fileEntry path (A.encode pkg)
39: where
40: -- Replace all-cabal-hashes-xxx/p/v/p.json with p/v/package.json
41: path = tarPath (name ++ "/" ++ version ++ "/package.json")
42: location = concat [ "<repo>/package/", name, "-", version, ".tar.gz"]
43: existing = err (A.eitherDecode bytes)
44: -- Parse required metadata from existing .json entry
45: (size :: Int, md5 :: String, sha :: String) =
46: err . ($ existing) . A.parseEither $ \obj -> do
47: hashes <- obj .: "package-hashes"
48: (,,) <$> obj .: "package-size"
49: <*> hashes .: "MD5"
50: <*> hashes .: "SHA256"
51: -- Construct a new .json entry from the existing metadata
52: pkg = A.object
53: [ "signatures" .= ([] :: [Int])
54: , "signed" .= A.object
55: [ "_type" .= ("Targets" :: String)
56: , "expires" .= A.Null
57: , "version" .= (0 :: Int )
58: , "targets" .= A.object
59: [ fromString location .= A.object
60: [ "length" .= size
61: , "hashes" .= A.object ["md5" .= md5, "sha256" .= sha]]]]]
Generated by git2html.