docker2nix: inprocWithErr -> procStrictWithErr (#57)

* docker2nix: `inprocWithErr` -> `procStrictWithErr`

... because `nix` utilities will sometimes return warnings and other
information to `stderr`. The type of `inprocWithErr` makes it pretty
clear that we should expect a result of _either_ the stderr text _or_
the stdout text. Not both! Normally, this is fine because errors will
be returned on `stderr`, however this is problematic when nix outputs
warnings as the utility will end up treating them as errors.

So we need a function that will give us both and that's
`procStrictWithErr`.

* Fix CI

* Cleanup a lot of annoying compiler warnings

* Fixup prettyprinter deprecation warnings

* One more prettyprinter fix

* Swap the stdout and stderr return field bindings...

* s/Prettyprint/Prettyprinter/

* Strip whitespace from result
This commit is contained in:
Parnell Springmeyer 2023-05-05 11:21:47 -07:00 committed by GitHub
parent 43d8e6cb8e
commit 14fa8ec148
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 23 additions and 37 deletions

View File

@ -10,11 +10,11 @@ jobs:
steps: steps:
- uses: actions/checkout@v3.0.2 - uses: actions/checkout@v3.0.2
name: Checkout name: Checkout
- uses: cachix/install-nix-action@v17 - uses: cachix/install-nix-action@v20
name: Install Nix name: Install Nix
with: with:
nix_path: nixpkgs=./nix/pkgs.nix nix_path: nixpkgs=./nix/pkgs.nix
- uses: cachix/cachix-action@v10 - uses: cachix/cachix-action@v12
name: Set up Cachix name: Set up Cachix
with: with:
name: awakesecurity name: awakesecurity
@ -27,11 +27,11 @@ jobs:
steps: steps:
- uses: actions/checkout@v3.0.2 - uses: actions/checkout@v3.0.2
name: Checkout name: Checkout
- uses: cachix/install-nix-action@v17 - uses: cachix/install-nix-action@v20
name: Install Nix name: Install Nix
with: with:
nix_path: nixpkgs=./nix/pkgs.nix nix_path: nixpkgs=./nix/pkgs.nix
- uses: cachix/cachix-action@v10 - uses: cachix/cachix-action@v12
name: Set up Cachix name: Set up Cachix
with: with:
name: awakesecurity name: awakesecurity

View File

@ -24,7 +24,6 @@ import qualified Data.Bifunctor as Bifunctor
import Data.Coerce import Data.Coerce
import Data.Fix import Data.Fix
import Data.Maybe import Data.Maybe
import Data.Semigroup ((<>))
import Data.Text (Text) import Data.Text (Text)
import qualified Data.Text as Text import qualified Data.Text as Text
import Data.Text.Encoding (decodeUtf8') import Data.Text.Encoding (decodeUtf8')
@ -40,7 +39,7 @@ import Network.Wreq.Docker.Registry (pluckLayersFrom)
import Hocker.Types import Hocker.Types
import Hocker.Types.Exceptions import Hocker.Types.Exceptions
import Hocker.Types.ImageTag import Hocker.Types.ImageTag
import Text.Megaparsec.Pos (Pos, mkPos) import Text.Megaparsec.Pos (Pos)
-- | @hnix-0.5.0:inherit@ requires a source location as its final argument. -- | @hnix-0.5.0:inherit@ requires a source location as its final argument.
inheritAdapter :: FilePath -> Pos -> Pos -> [NKeyName e] -> Binding e inheritAdapter :: FilePath -> Pos -> Pos -> [NKeyName e] -> Binding e

View File

@ -42,7 +42,7 @@ toBase32Nix (Base16Digest d16) = do
let nixhash = Nix.Paths.nixHash let nixhash = Nix.Paths.nixHash
let hockerExc m = HockerException m Nothing Nothing let hockerExc m = HockerException m Nothing Nothing
let convertDigest = let convertDigest =
inprocWithErr procStrictWithErr
(Text.pack nixhash) (Text.pack nixhash)
[ "--type" [ "--type"
, "sha256" , "sha256"
@ -58,8 +58,7 @@ toBase32Nix (Base16Digest d16) = do
"nothing was returned by `nix-hash', not even an error" "nothing was returned by `nix-hash', not even an error"
Nothing Nothing
Nothing) Nothing)
Just result -> Just (ExitFailure _, _, errorText) ->
either throwError (hockerExc (Text.unpack errorText))
(throwError . hockerExc . Text.unpack . lineToText) Just (ExitSuccess, resultText, _) ->
(return . Base32Digest . lineToText) return (Base32Digest (Text.strip resultText))
result

View File

@ -28,13 +28,12 @@ import Data.Aeson.Lens
import qualified Data.ByteString.Char8 as C8 import qualified Data.ByteString.Char8 as C8
import Data.ByteString.Lazy.Char8 as C8L import Data.ByteString.Lazy.Char8 as C8L
import Data.Coerce import Data.Coerce
import Data.Semigroup ((<>))
import Data.Text (Text) import Data.Text (Text)
import qualified Data.Text as Text import qualified Data.Text as Text
import Data.Text.Prettyprint.Doc (LayoutOptions(..), import Prettyprinter (LayoutOptions(..),
PageWidth(..), SimpleDocStream) PageWidth(..), SimpleDocStream)
import qualified Data.Text.Prettyprint.Doc import qualified Prettyprinter
import qualified Data.Text.Prettyprint.Doc.Render.Text import qualified Prettyprinter.Render.Text
import Data.Text.Encoding (encodeUtf8) import Data.Text.Encoding (encodeUtf8)
import qualified Network.Wreq as Wreq import qualified Network.Wreq as Wreq
import Nix.Expr (NExpr) import Nix.Expr (NExpr)
@ -173,7 +172,7 @@ splitRepository (ImageName (Text.pack -> n)) = over _2 Text.tail $ Text.break (=
-- | Given a nix expression AST, produce a pretty printer document. -- | Given a nix expression AST, produce a pretty printer document.
renderNixExpr :: NExpr -> SimpleDocStream ann renderNixExpr :: NExpr -> SimpleDocStream ann
renderNixExpr = renderNixExpr =
Data.Text.Prettyprint.Doc.layoutSmart layoutOptions . prettyNix Prettyprinter.layoutSmart layoutOptions . prettyNix
where where
layoutOptions = LayoutOptions { layoutPageWidth = AvailablePerLine 120 0.4 } layoutOptions = LayoutOptions { layoutPageWidth = AvailablePerLine 120 0.4 }
@ -181,7 +180,7 @@ renderNixExpr =
-- printing renderer. -- printing renderer.
pprintNixExpr :: NExpr -> IO () pprintNixExpr :: NExpr -> IO ()
pprintNixExpr expr = pprintNixExpr expr =
Data.Text.Prettyprint.Doc.Render.Text.renderIO System.IO.stdout stream Prettyprinter.Render.Text.renderIO System.IO.stdout stream
where where
stream = renderNixExpr expr stream = renderNixExpr expr

View File

@ -31,8 +31,6 @@ import Control.Monad.Reader.Class
import qualified Crypto.Hash as Hash import qualified Crypto.Hash as Hash
import qualified Data.ByteString.Lazy import qualified Data.ByteString.Lazy
import Data.Char (toUpper) import Data.Char (toUpper)
import Data.Semigroup ((<>))
import Data.Text (Text)
import qualified Data.Text as Text import qualified Data.Text as Text
import qualified Network.Wreq as Wreq import qualified Network.Wreq as Wreq
import Network.Wreq.ErrorHandling import Network.Wreq.ErrorHandling

View File

@ -19,7 +19,6 @@ module Hocker.Types.Exceptions where
import Control.DeepSeq import Control.DeepSeq
import Control.Exception import Control.Exception
import Data.Semigroup ((<>))
import GHC.Generics import GHC.Generics
data HockerException = HockerException data HockerException = HockerException

View File

@ -17,7 +17,6 @@ import qualified Crypto.Hash as Hash
import qualified Data.ByteArray as BA import qualified Data.ByteArray as BA
import qualified Data.ByteArray.Encoding as BA import qualified Data.ByteArray.Encoding as BA
import qualified Data.ByteString.Char8 as C8 import qualified Data.ByteString.Char8 as C8
import Data.Semigroup ((<>))
import qualified Data.Text import qualified Data.Text
import qualified Options.Applicative as Options import qualified Options.Applicative as Options
import Options.Generic import Options.Generic

View File

@ -15,7 +15,6 @@
module Hocker.Types.ImageName where module Hocker.Types.ImageName where
import Control.DeepSeq import Control.DeepSeq
import Data.Semigroup ((<>))
import qualified Options.Applicative as Options import qualified Options.Applicative as Options
import Options.Generic import Options.Generic

View File

@ -15,7 +15,6 @@
module Hocker.Types.ImageTag where module Hocker.Types.ImageTag where
import Control.DeepSeq import Control.DeepSeq
import Data.Semigroup ((<>))
import qualified Options.Applicative as Options import qualified Options.Applicative as Options
import Options.Generic import Options.Generic

View File

@ -16,7 +16,6 @@ module Hocker.Types.URI where
import Control.Lens import Control.Lens
import qualified Data.ByteString.Char8 as C8 import qualified Data.ByteString.Char8 as C8
import Data.Semigroup ((<>))
import qualified Data.Text as Text import qualified Data.Text as Text
import qualified Options.Applicative as Options import qualified Options.Applicative as Options
import Options.Applicative.Builder import Options.Applicative.Builder
@ -32,12 +31,12 @@ uriReader = Options.eitherReader parseURIArg
instance ParseField (URIRef Absolute) where instance ParseField (URIRef Absolute) where
readField = uriReader readField = uriReader
parseField help long short _value = parseField helpMsg longStr shortStr _value =
(Options.option uriReader $ (Options.option uriReader $
( Options.metavar "URI" ( Options.metavar "URI"
<> foldMap (Options.long . Text.unpack) long <> foldMap (Options.long . Text.unpack) longStr
<> foldMap Options.short short <> foldMap Options.short shortStr
<> foldMap (Options.help . Text.unpack) help <> foldMap (Options.help . Text.unpack) helpMsg
) )
) )

View File

@ -25,7 +25,6 @@ import Data.ByteString.Lazy.Char8 as C8L
import Data.Coerce import Data.Coerce
import Data.Either import Data.Either
import Data.HashSet as Set import Data.HashSet as Set
import Data.Semigroup ((<>))
import Data.Text (Text) import Data.Text (Text)
import qualified Data.Text as Text import qualified Data.Text as Text
import Data.Text.Encoding (decodeUtf8') import Data.Text.Encoding (decodeUtf8')
@ -129,7 +128,7 @@ fetchLayer =
-- docker registry. -- docker registry.
fetchConfig :: HockerMeta -> IO (Either HockerException C8L.ByteString) fetchConfig :: HockerMeta -> IO (Either HockerException C8L.ByteString)
fetchConfig = fetchConfig =
runHocker $ ask >>= \HockerMeta{..} -> do runHocker $ ask >>= \HockerMeta{} -> do
configDigest <- configDigest <-
fetchManifest fetchManifest
>>= getConfigDigest . view Wreq.responseBody >>= getConfigDigest . view Wreq.responseBody

View File

@ -24,7 +24,6 @@ import Control.Monad.Reader
import qualified Data.ByteString.Lazy.Char8 as C8L import qualified Data.ByteString.Lazy.Char8 as C8L
import Data.Coerce import Data.Coerce
import qualified Data.HashMap.Strict as HashMap import qualified Data.HashMap.Strict as HashMap
import Data.Semigroup ((<>))
import qualified Data.Text as Text import qualified Data.Text as Text
import qualified Network.Wreq as Wreq import qualified Network.Wreq as Wreq
import qualified System.Directory as Directory import qualified System.Directory as Directory

View File

@ -34,7 +34,6 @@ import qualified Data.ByteString.Char8 as C8
import Data.Text.Encoding (decodeUtf8, encodeUtf8) import Data.Text.Encoding (decodeUtf8, encodeUtf8)
import URI.ByteString import URI.ByteString
import NeatInterpolation import NeatInterpolation
import Data.Semigroup ((<>))
import qualified Data.Text as Text import qualified Data.Text as Text
import qualified Network.Wreq as Wreq import qualified Network.Wreq as Wreq
import System.Directory import System.Directory

View File

@ -21,7 +21,6 @@ import Control.Exception.Lifted as Lifted
import Control.Lens import Control.Lens
import Control.Monad.Except import Control.Monad.Except
import Data.ByteString.Char8 as C8 import Data.ByteString.Char8 as C8
import Data.Semigroup ((<>))
import Network.HTTP.Client import Network.HTTP.Client
import Network.HTTP.Types.Status import Network.HTTP.Types.Status

View File

@ -19,7 +19,7 @@ import Data.ByteString as BS
import Data.ByteString.Lazy.Char8 as C8L import Data.ByteString.Lazy.Char8 as C8L
import Data.Either (either) import Data.Either (either)
import qualified Data.Text as Text import qualified Data.Text as Text
import qualified Data.Text.Prettyprint.Doc.Render.String import qualified Prettyprinter.Render.String
import Data.Word8 as W8 import Data.Word8 as W8
import Network.URI import Network.URI
@ -105,7 +105,7 @@ generateFetchDockerNix = do
, altImageName = Nothing , altImageName = Nothing
} }
let display = Data.Text.Prettyprint.Doc.Render.String.renderString let display = Prettyprinter.Render.String.renderString
either either
(Hocker.Lib.die . Text.pack . show) (Hocker.Lib.die . Text.pack . show)