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.