{-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE FlexibleContexts #-} ----------------------------------------------------------------------------- -- | -- Module : Data.Docker.Nix.Lib -- Copyright : (C) 2016 Awake Networks -- License : Apache-2.0 -- Maintainer : Awake Networks -- Stability : stable ---------------------------------------------------------------------------- module Data.Docker.Nix.Lib where import Control.Foldl as Foldl import Turtle import Control.Monad.Except as Except import qualified Data.Text as Text import Hocker.Types import Hocker.Types.Exceptions -- | Convert a 'Base16Digest' to a 'Base32Digest' using the @nix-hash@ -- utility. -- -- NB: Nix implements its own custom base32 encoding function for -- hashes that is not compatible with other more standard and native -- implementations in Haskell. I opted to call out to @nix-hash@ -- instead of re-implementing their algorithm because it's -- non-standard and may change, creating a maintenance headache and -- surprise behavior. toBase32Nix :: (MonadIO m, Except.MonadError HockerException m) => Prelude.FilePath -- ^ Path to the @nix-hash@ executable, see 'Lib.findExec' -> Base16Digest -- ^ 'Base16Digest' to @base32@ encode -> m Base32Digest toBase32Nix nixhash (Base16Digest d16) = do let hockerExc m = HockerException m Nothing Nothing let convertDigest = inprocWithErr (Text.pack nixhash) [ "--type" , "sha256" , "--to-base32" , d16 ] Turtle.empty Turtle.fold convertDigest Foldl.head >>= \case Nothing -> throwError (HockerException "nothing was returned by `nix-hash', not even an error" Nothing Nothing) Just result -> either (throwError . hockerExc . Text.unpack . lineToText) (return . Base32Digest . lineToText) result