packages feed

hocker 1.0.5 → 1.0.6

raw patch · 17 files changed

+132/−53 lines, 17 filesdep +megaparsecdep +prettyprinterdep +word8dep −ansi-wl-pprintdep ~asyncdep ~hnixdep ~turtle

Dependencies added: megaparsec, prettyprinter, word8

Dependencies removed: ansi-wl-pprint

Dependency ranges changed: async, hnix, turtle

Files

CHANGELOG.md view
@@ -1,5 +1,12 @@ # Changelog +## 1.0.6+### Changed+- Support and require hnix-0.7.0 or higher.+- Support GHC 8.10.1.+- Use nixpkgs 20.03 in Nix builds.+- Discard support for Nix versions < 1.12.+ ## 1.0.5 ### Fixed - Add the golden test data to the source distribution by using `data-files`
hocker.cabal view
@@ -1,5 +1,5 @@ name:                hocker-version:             1.0.5+version:             1.0.6 synopsis:            Interact with the docker registry and generate nix build instructions homepage:            https://github.com/awakesecurity/hocker#readme Bug-Reports:         https://github.com/awakesecurity/hocker/issues@@ -68,8 +68,7 @@                 base                 >= 4.9 && < 5,                 aeson                >= 1.0.0.0,                 aeson-pretty         >= 0.8,-                ansi-wl-pprint       >= 0.6.7.3,-                async                >= 2.0.0.0 && < 2.2,+                async                >= 2.0.0.0 && < 2.3,                 bytestring           >= 0.10,                 concurrentoutput     >= 0.2,                 containers           >= 0.5,@@ -80,12 +79,13 @@                 exceptions           >= 0.8,                 filepath             >= 1.4,                 foldl                >= 1.0,-                hnix                 >= 0.3.4,+                hnix                 >= 0.7.0,                 http-client          >= 0.4,                 http-types           >= 0.9.1,                 lens                 >= 4.0,                 lens-aeson           >= 1.0,                 lifted-base          >= 0.2.3.8,+                megaparsec           >= 7.0.0,                 memory               >= 0.11,                 mtl                  >= 2.2,                 neat-interpolation   >= 0.3.2,@@ -93,6 +93,7 @@                 network-uri          >= 2.6,                 optparse-applicative >= 0.13,                 optparse-generic     >= 1.2.0,+                prettyprinter        >= 1.1.1,                 pooled-io            >= 0.0.2,                 pureMD5              >= 2.1,                 scientific           >= 0.3,@@ -101,7 +102,7 @@                 text                 >= 1.2,                 time                 >= 1.4,                 transformers         >= 0.4,-                turtle               >= 1.3.0 && < 1.5,+                turtle               >= 1.3.0 && < 1.6,                 unordered-containers >= 0.2,                 uri-bytestring       >= 0.2,                 vector               >= 0.11,@@ -201,7 +202,7 @@                bytestring           >= 0.10,                data-fix             >= 0.0.3,                filepath             >= 1.4,-               hnix                 >= 0.3.4,+               hnix                 >= 0.5.2,                hocker,                lens                 >= 4.0,                mtl                  >= 2.2,@@ -225,7 +226,6 @@   build-depends:                 base                 >= 4.9 && < 5,                 aeson                >= 0.9.0.1,-                ansi-wl-pprint       >= 0.6.7.3,                 bytestring           >= 0.10,                 containers           >= 0.5,                 cryptonite           >= 0.13,@@ -233,13 +233,15 @@                 mtl                  >= 2.2,                 network              >= 2.6,                 network-uri          >= 2.6,+                prettyprinter        >= 1.1.1,                 tasty                >= 0.11,                 tasty-golden         >= 2.3,                 tasty-hunit          >= 0.9,                 tasty-quickcheck     >= 0.8,                 tasty-smallcheck     >= 0.8,                 text                 >= 1.2,-                unordered-containers >= 0.2+                unordered-containers >= 0.2,+                word8                >= 0.1.0     ghc-options:         -threaded -rtsopts -with-rtsopts=-N
src/Data/Docker/Nix/FetchDocker.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP               #-} {-# LANGUAGE FlexibleContexts  #-} {-# LANGUAGE LambdaCase        #-} {-# LANGUAGE OverloadedStrings #-}@@ -23,12 +24,13 @@ import           Data.Coerce import           Data.Fix import           Data.Maybe-import           Data.Monoid+import           Data.Semigroup               ((<>)) import           Data.Text                    (Text) import qualified Data.Text                    as Text import           Data.Text.Encoding           (decodeUtf8') import           Data.Text.Encoding.Error-import           Nix.Expr+import           Nix.Expr                     hiding (inherit)+import qualified Nix.Expr                     (inherit) import           URI.ByteString  import           Data.Docker.Image.Types@@ -38,7 +40,21 @@ import           Hocker.Types import           Hocker.Types.Exceptions import           Hocker.Types.ImageTag+import           Text.Megaparsec.Pos          (Pos, mkPos) +-- | @hnix-0.5.0:inherit@ requires a source location as its final argument.+inheritAdapter :: FilePath -> Pos -> Pos -> [NKeyName e] -> Binding e+inheritAdapter sourceName sourceLine sourceColumn ks = Nix.Expr.inherit ks+#if MIN_VERSION_hnix(0,5,0)+                                                         SourcePos{..}+#endif++-- | @hnix-0.5.0@ omits mkApp.+#if MIN_VERSION_hnix(0,5,0)+mkApp :: NExpr -> NExpr -> NExpr+mkApp e = Fix . NBinary NApp e+#endif+ {- Example output of the pretty-printed, generated Nix expression AST. { fetchdocker, fetchDockerConfig, fetchDockerLayer }: fetchdocker rec {@@ -99,8 +115,6 @@     pluckedConfigDigest = Hocker.Lib.stripHashId $ manifestJSON ^. key "config" . key "digest" . _String     pluckedLayerDigests = Hocker.Lib.stripHashId <$> pluckLayersFrom manifestJSON -- {-| Generate a top-level Nix Expression AST from a 'HockerImageMeta' record, a config digest, and a list of layer digests. @@ -134,19 +148,24 @@         , StaticKey "imageName"         ]   let genLayerId i = mkSym . Text.pack $ "layer" <> show i-  let fetchconfig = mkFetchDockerConfig (inherit $ ((StaticKey "tag"):commonInherits)) configDigest+  let fetchconfig = mkFetchDockerConfig (inheritAdapter ("generated for " ++ show imageName) (mkPos 1) (mkPos 1) $ ((StaticKey "tag"):commonInherits)) configDigest       fetchlayers =         mkLets-         (mkFetchDockerLayers (inherit commonInherits) layerDigests)+         (mkFetchDockerLayers (inheritAdapter "common inherits" (mkPos 1) (mkPos 1) commonInherits) layerDigests)          (mkList $ fmap genLayerId [0..(Prelude.length layerDigests)-1])   fetchDockerExpr <- mkFetchDocker dim fetchconfig fetchlayers   pure     (mkFunction       (mkParamset-        [ ("fetchdocker",       Nothing)-        , ("fetchDockerConfig", Nothing)+        [ ("fetchDockerConfig", Nothing)         , ("fetchDockerLayer",  Nothing)-        ]) fetchDockerExpr)+        , ("fetchdocker",       Nothing)+        ] -- List keys in sorted order so that we do not care+          -- whether hnix sorts keys or preserves this order.+#if MIN_VERSION_hnix(0,5,0)+        False  -- not variadic+#endif+      ) fetchDockerExpr)  -- | Generate a @fetchdocker { ... }@ function call and argument -- attribute set. Please see 'generateFetchDockerExpr' documentation@@ -155,7 +174,8 @@ mkFetchDocker HockerImageMeta{..} fetchconfig fetchlayers = do   registry <- Bifunctor.first mkHockerException serializedRegistry   pure-    (mkApp (mkSym constFetchdocker)+    (mkSym constFetchdocker+     @@      (recAttrsE       [ ("name",        mkStr $ fromMaybe imageName altImageName)       , ("registry",    mkStr registry)@@ -172,7 +192,6 @@     mkHockerException err =       HockerException (show err) Nothing Nothing - -- | Generate a @fetchDockerConfig { ... }@ function call and -- argument attrset. --@@ -181,8 +200,8 @@ -- the output expression. mkFetchDockerConfig :: Binding NExpr -> Base32Digest -> NExpr mkFetchDockerConfig inherits (Base32Digest digest) =-    mkApp (mkSym constFetchDockerConfig)-          (Fix $ NSet [ inherits, "sha256" $= (mkStr digest) ])+    mkSym constFetchDockerConfig @@+          (Fix $ NSet NNonRecursive [ inherits, "sha256" $= (mkStr digest) ])  -- | Generate a list of Nix expression ASTs representing -- @fetchDockerLayer { ... }@ function calls.@@ -208,9 +227,9 @@   where     mkLayerId i = Text.pack $ "layer" <> show i     mkFetchLayer (i, ((Base16Digest d16), (Base32Digest d32))) =-      (mkLayerId i) $= mkApp (mkSym constFetchDockerLayer)-                             (Fix $ NSet+      (mkLayerId i) $= (mkSym constFetchDockerLayer @@+                             (Fix $ NSet NNonRecursive                                 [ inherits                                 , "layerDigest" $= (mkStr d16) -- Required in order to perform a registry request                                 , "sha256"      $= (mkStr d32) -- Required by Nix for fixed output derivations-                                ])+                                ]))
src/Data/Docker/Nix/Lib.hs view
@@ -15,7 +15,7 @@  module Data.Docker.Nix.Lib where -import           Control.Foldl        as Foldl+import qualified Control.Foldl        as Foldl import           Turtle import           Control.Monad.Except as Except import qualified Data.Text            as Text
src/Hocker/Lib.hs view
@@ -28,9 +28,13 @@ import qualified Data.ByteString.Char8        as C8 import           Data.ByteString.Lazy.Char8   as C8L import           Data.Coerce-import           Data.Monoid+import           Data.Semigroup               ((<>)) import           Data.Text                    (Text) import qualified Data.Text                    as Text+import           Data.Text.Prettyprint.Doc    (LayoutOptions(..),+                                               PageWidth(..), SimpleDocStream)+import qualified Data.Text.Prettyprint.Doc+import qualified Data.Text.Prettyprint.Doc.Render.Text import           Data.Text.Encoding           (encodeUtf8) import qualified Network.Wreq                 as Wreq import           Nix.Expr                     (NExpr)@@ -39,9 +43,7 @@ import           System.Environment           (getProgName) import           System.Exit                  as Exit import           System.FilePath.Posix        as File-import           Text.PrettyPrint.ANSI.Leijen as Text.PrettyPrint (SimpleDoc,-                                                                   displayS,-                                                                   renderPretty)+import qualified System.IO import           URI.ByteString  import           Data.Docker.Image.Types@@ -169,13 +171,19 @@ splitRepository (ImageName (Text.pack -> n)) = over _2 Text.tail $ Text.break (=='/') n  -- | Given a nix expression AST, produce a pretty printer document.-renderNixExpr :: NExpr -> Text.PrettyPrint.SimpleDoc-renderNixExpr = renderPretty 0.4 120 . prettyNix+renderNixExpr :: NExpr -> SimpleDocStream ann+renderNixExpr =+    Data.Text.Prettyprint.Doc.layoutSmart layoutOptions . prettyNix+  where+    layoutOptions = LayoutOptions { layoutPageWidth = AvailablePerLine 120 0.4 }  -- | Print a nix expression AST using the 'renderNixExpr' pretty -- printing renderer. pprintNixExpr :: NExpr -> IO ()-pprintNixExpr expr = Prelude.putStrLn (displayS (renderNixExpr expr) "")+pprintNixExpr expr =+    Data.Text.Prettyprint.Doc.Render.Text.renderIO System.IO.stdout stream+  where+    stream = renderNixExpr expr  -- | Given an executable's name, try to find it in the PATH. findExec :: (MonadIO m, Except.MonadError HockerException m)
src/Hocker/Types.hs view
@@ -31,7 +31,7 @@ import qualified Crypto.Hash                as Hash import qualified Data.ByteString.Lazy import           Data.Char                  (toUpper)-import           Data.Monoid+import           Data.Semigroup             ((<>)) import           Data.Text                  (Text) import qualified Data.Text                  as Text import qualified Network.Wreq               as Wreq
src/Hocker/Types/Exceptions.hs view
@@ -19,7 +19,7 @@  import           Control.DeepSeq import           Control.Exception-import           Data.Monoid+import           Data.Semigroup     ((<>)) import           GHC.Generics  data HockerException = HockerException
src/Hocker/Types/Hash.hs view
@@ -17,7 +17,7 @@ import qualified Data.ByteArray          as BA import qualified Data.ByteArray.Encoding as BA import qualified Data.ByteString.Char8   as C8-import           Data.Monoid+import           Data.Semigroup          ((<>)) import qualified Data.Text import qualified Options.Applicative     as Options import           Options.Generic
src/Hocker/Types/ImageName.hs view
@@ -15,7 +15,7 @@ module Hocker.Types.ImageName where  import           Control.DeepSeq-import           Data.Monoid+import           Data.Semigroup      ((<>)) import qualified Options.Applicative as Options import           Options.Generic 
src/Hocker/Types/ImageTag.hs view
@@ -15,7 +15,7 @@ module Hocker.Types.ImageTag where  import           Control.DeepSeq-import           Data.Monoid+import           Data.Semigroup      ((<>)) import qualified Options.Applicative as Options import           Options.Generic 
src/Hocker/Types/URI.hs view
@@ -16,7 +16,7 @@  import           Control.Lens import qualified Data.ByteString.Char8       as C8-import           Data.Monoid+import           Data.Semigroup              ((<>)) import qualified Data.Text                   as Text import qualified Options.Applicative         as Options import           Options.Applicative.Builder
src/Network/Wreq/Docker/Image.hs view
@@ -25,7 +25,7 @@ import           Data.Coerce import           Data.Either import           Data.HashSet                  as Set-import           Data.Monoid+import           Data.Semigroup                ((<>)) import           Data.Text                     (Text) import qualified Data.Text                     as Text import           Data.Text.Encoding            (decodeUtf8')
src/Network/Wreq/Docker/Image/Lib.hs view
@@ -24,7 +24,7 @@ import qualified Data.ByteString.Lazy.Char8        as C8L import           Data.Coerce import qualified Data.HashMap.Strict               as HashMap-import           Data.Monoid+import           Data.Semigroup                    ((<>)) import qualified Data.Text                         as Text import qualified Network.Wreq                      as Wreq import qualified System.Directory                  as Directory
src/Network/Wreq/Docker/Registry.hs view
@@ -27,7 +27,6 @@ import           Control.Lens import qualified Control.Monad.Except       as Except import           Control.Monad.Reader-import           Data.Monoid import qualified Crypto.Hash                as Hash import           Data.Aeson.Lens import           Data.ByteString.Lazy.Char8 as C8L@@ -35,6 +34,7 @@ import           Data.Text.Encoding         (decodeUtf8, encodeUtf8) import           URI.ByteString import           NeatInterpolation+import           Data.Semigroup             ((<>)) import qualified Data.Text                  as Text import qualified Network.Wreq               as Wreq import           System.Directory@@ -64,7 +64,7 @@ -- -- If 'Credentials' is either 'BearerToken' or 'Basic' then produce a -- 'Wreq.Auth' value for that type of credential.--- +-- -- If @Nothing@ is provided _and_ the provided 'RegistryURI' matches -- the default registry, make a request to -- @https://auth.docker.io/token@ for a temporary pull-only bearer@@ -131,7 +131,7 @@     mkURL (ImageName n) r = C8.unpack (serializeURIRef' $ Hocker.Lib.joinURIPath [n, "blobs", digest] r)  -- | Retrieve a compressed layer blob by its hash digest.--- +-- -- TODO: take advantage of registry's support for the Range header so -- we can stream downloads. fetchLayer :: Layer -> Hocker RspBS
src/Network/Wreq/ErrorHandling.hs view
@@ -21,7 +21,7 @@ import           Control.Lens import           Control.Monad.Except import           Data.ByteString.Char8     as C8-import           Data.Monoid+import           Data.Semigroup            ((<>)) import           Network.HTTP.Client import           Network.HTTP.Types.Status 
test/Tests/Data/Docker/Nix/FetchDocker.hs view
@@ -15,15 +15,19 @@  import           Control.Exception            as CE import           Control.Monad.Except         as Except+import           Data.ByteString              as BS import           Data.ByteString.Lazy.Char8   as C8L import           Data.Either                  (either) import qualified Data.Text                    as Text+import qualified Data.Text.Prettyprint.Doc.Render.String+import           Data.Word8                   as W8 import           Network.URI  import           Test.Tasty import           Test.Tasty.Golden+import           Test.Tasty.Golden.Advanced   (goldenTest) import           Test.Tasty.HUnit-import           Text.PrettyPrint.ANSI.Leijen as Text.PrettyPrint (displayS)+import           Text.Printf                  (printf)  import           Data.Docker.Image.Types import           Data.Docker.Nix.FetchDocker  as Nix.FetchDocker@@ -33,8 +37,43 @@ import           Hocker.Types import           Hocker.Types.ImageTag +-- | Compare a given string against the golden file contents,+-- ignoring differences in contiguous nonempty spans of whitespace,+-- and the presence or absence of whitespace before or after a comma.+goldenVsStringCanonicalize+  :: TestName -- ^ test name+  -> FilePath -- ^ path to golden file+  -> IO C8L.ByteString -- ^ action that returns string to compare+  -> TestTree -- ^ the test verifies that the returned string equals the+              -- golden file contents when ignoring differences in whitespace+goldenVsStringCanonicalize name ref act =+  goldenTest+    name+    (BS.readFile ref)+    (C8L.toStrict <$> act)+    cmp+    upd+  where+  cmp x y = cmpCanonicalize msg x y+    where+    msg = printf "Test output was different from '%s'. It was: %s" ref (show y)+  upd = BS.writeFile ref++cmpCanonicalize ::+  String -> BS.ByteString -> BS.ByteString -> IO (Maybe String)+cmpCanonicalize e x y =+    return $ if canonicalize x == canonicalize y then Nothing else Just e+  where+    canonicalize = BS.pack . BS.foldr op []+    op x acc+      | W8.isSpace x, y : _ <- acc, y == W8._space = acc+      | W8.isSpace x, y : _ <- acc, y == W8._comma = acc+      | W8.isSpace x = W8._space : acc+      | x == W8._comma, y : ys <- acc, y == W8._space = W8._comma : ys+      | otherwise = x : acc+ tests = testGroup "FetchDocker Nix Generation Tests"-  [ goldenVsString+  [ goldenVsStringCanonicalize       "Golden vs. Generated `fetchDocker' Nix Expression"       "test/data/golden-debian_jessie.nix"       generateFetchDockerNix@@ -66,7 +105,9 @@       , altImageName   = Nothing       } +  let display = Data.Text.Prettyprint.Doc.Render.String.renderString+   either     (Hocker.Lib.die . Text.pack . show)-    (return . C8L.pack . (flip displayS "") . Hocker.Lib.renderNixExpr)+    (return . C8L.pack . display . Hocker.Lib.renderNixExpr)     nixExpression
test/data/golden-debian_jessie.nix view
@@ -1,5 +1,7 @@-{ fetchDockerConfig, fetchDockerLayer, fetchdocker }:-fetchdocker rec {+{ fetchDockerConfig+  , fetchDockerLayer+  , fetchdocker }:+  fetchdocker rec {     name = "debian";     registry = "https://registry-1.docker.io/v2/";     repository = "library";@@ -8,12 +10,12 @@     imageConfig = fetchDockerConfig {       inherit tag registry repository imageName;       sha256 = "1rwinmvfc8jxn54y7qnj82acrc97y7xcnn22zaz67y76n4wbwjh5";-    };+      };     imageLayers = let       layer0 = fetchDockerLayer {         inherit registry repository imageName;         layerDigest = "cd0a524342efac6edff500c17e625735bbe479c926439b263bbe3c8518a0849c";         sha256 = "1744l0c8ag5y7ck9nhr6r5wy9frmaxi7xh80ypgnxb7g891m42nd";-      };-      in [ layer0 ];-  }+        };+    in [ layer0 ];+    }