language-docker 6.0.1 → 6.0.2
raw patch · 4 files changed
+55/−7 lines, 4 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Language.Docker: data Tag
+ Language.Docker: Tag :: Text -> Tag
+ Language.Docker: [$sel:unTag:Tag] :: Tag -> Text
+ Language.Docker: newtype Tag
+ Language.Docker.PrettyPrint: EscapeAccum :: !Builder -> !Int -> !Bool -> EscapeAccum
+ Language.Docker.PrettyPrint: [$sel:buffer:EscapeAccum] :: EscapeAccum -> !Builder
+ Language.Docker.PrettyPrint: [$sel:count:EscapeAccum] :: EscapeAccum -> !Int
+ Language.Docker.PrettyPrint: [$sel:escaping:EscapeAccum] :: EscapeAccum -> !Bool
+ Language.Docker.PrettyPrint: data EscapeAccum
+ Language.Docker.PrettyPrint: doubleQoute :: Text -> Doc ann
+ Language.Docker.PrettyPrint: escapeQuotes :: Text -> Text
- Language.Docker: arg :: forall m_aPd2. MonadFree EInstruction m_aPd2 => Text -> Maybe Text -> m_aPd2 ()
+ Language.Docker: arg :: forall m_aPBn. MonadFree EInstruction m_aPBn => Text -> Maybe Text -> m_aPBn ()
- Language.Docker: cmdArgs :: forall m_aPcE. MonadFree EInstruction m_aPcE => Arguments Text -> m_aPcE ()
+ Language.Docker: cmdArgs :: forall m_aPAZ. MonadFree EInstruction m_aPAZ => Arguments Text -> m_aPAZ ()
- Language.Docker: comment :: forall m_aPd6. MonadFree EInstruction m_aPd6 => Text -> m_aPd6 ()
+ Language.Docker: comment :: forall m_aPBr. MonadFree EInstruction m_aPBr => Text -> m_aPBr ()
- Language.Docker: embed :: forall m_aPdf. MonadFree EInstruction m_aPdf => [InstructionPos Text] -> m_aPdf ()
+ Language.Docker: embed :: forall m_aPBA. MonadFree EInstruction m_aPBA => [InstructionPos Text] -> m_aPBA ()
- Language.Docker: entrypointArgs :: forall m_aPcT. MonadFree EInstruction m_aPcT => Arguments Text -> m_aPcT ()
+ Language.Docker: entrypointArgs :: forall m_aPBe. MonadFree EInstruction m_aPBe => Arguments Text -> m_aPBe ()
- Language.Docker: env :: forall m_aPcZ. MonadFree EInstruction m_aPcZ => Pairs -> m_aPcZ ()
+ Language.Docker: env :: forall m_aPBk. MonadFree EInstruction m_aPBk => Pairs -> m_aPBk ()
- Language.Docker: expose :: forall m_aPcN. MonadFree EInstruction m_aPcN => Ports -> m_aPcN ()
+ Language.Docker: expose :: forall m_aPB8. MonadFree EInstruction m_aPB8 => Ports -> m_aPB8 ()
- Language.Docker: from :: forall m_aPbC. MonadFree EInstruction m_aPbC => EBaseImage -> m_aPbC ()
+ Language.Docker: from :: forall m_aPzX. MonadFree EInstruction m_aPzX => EBaseImage -> m_aPzX ()
- Language.Docker: healthcheck :: forall m_aPd9. MonadFree EInstruction m_aPd9 => Check Text -> m_aPd9 ()
+ Language.Docker: healthcheck :: forall m_aPBu. MonadFree EInstruction m_aPBu => Check Text -> m_aPBu ()
- Language.Docker: label :: forall m_aPcp. MonadFree EInstruction m_aPcp => Pairs -> m_aPcp ()
+ Language.Docker: label :: forall m_aPAK. MonadFree EInstruction m_aPAK => Pairs -> m_aPAK ()
- Language.Docker: maintainer :: forall m_aPcW. MonadFree EInstruction m_aPcW => Text -> m_aPcW ()
+ Language.Docker: maintainer :: forall m_aPBh. MonadFree EInstruction m_aPBh => Text -> m_aPBh ()
- Language.Docker: onBuildRaw :: forall m_aPdc. MonadFree EInstruction m_aPdc => Instruction Text -> m_aPdc ()
+ Language.Docker: onBuildRaw :: forall m_aPBx. MonadFree EInstruction m_aPBx => Instruction Text -> m_aPBx ()
- Language.Docker: runArgs :: forall m_aPcB. MonadFree EInstruction m_aPcB => Arguments Text -> m_aPcB ()
+ Language.Docker: runArgs :: forall m_aPAW. MonadFree EInstruction m_aPAW => Arguments Text -> m_aPAW ()
- Language.Docker: stopSignal :: forall m_aPcs. MonadFree EInstruction m_aPcs => Text -> m_aPcs ()
+ Language.Docker: stopSignal :: forall m_aPAN. MonadFree EInstruction m_aPAN => Text -> m_aPAN ()
- Language.Docker: user :: forall m_aPcm. MonadFree EInstruction m_aPcm => Text -> m_aPcm ()
+ Language.Docker: user :: forall m_aPAH. MonadFree EInstruction m_aPAH => Text -> m_aPAH ()
- Language.Docker: volume :: forall m_aPcQ. MonadFree EInstruction m_aPcQ => Text -> m_aPcQ ()
+ Language.Docker: volume :: forall m_aPBb. MonadFree EInstruction m_aPBb => Text -> m_aPBb ()
- Language.Docker: workdir :: forall m_aPcK. MonadFree EInstruction m_aPcK => Directory -> m_aPcK ()
+ Language.Docker: workdir :: forall m_aPB5. MonadFree EInstruction m_aPB5 => Directory -> m_aPB5 ()
- Language.Docker.EDSL: addArgs :: forall m_aPch. MonadFree EInstruction m_aPch => NonEmpty SourcePath -> TargetPath -> Chown -> m_aPch ()
+ Language.Docker.EDSL: addArgs :: forall m_aPAC. MonadFree EInstruction m_aPAC => NonEmpty SourcePath -> TargetPath -> Chown -> m_aPAC ()
- Language.Docker.EDSL: arg :: forall m_aPd2. MonadFree EInstruction m_aPd2 => Text -> Maybe Text -> m_aPd2 ()
+ Language.Docker.EDSL: arg :: forall m_aPBn. MonadFree EInstruction m_aPBn => Text -> Maybe Text -> m_aPBn ()
- Language.Docker.EDSL: cmdArgs :: forall m_aPcE. MonadFree EInstruction m_aPcE => Arguments Text -> m_aPcE ()
+ Language.Docker.EDSL: cmdArgs :: forall m_aPAZ. MonadFree EInstruction m_aPAZ => Arguments Text -> m_aPAZ ()
- Language.Docker.EDSL: comment :: forall m_aPd6. MonadFree EInstruction m_aPd6 => Text -> m_aPd6 ()
+ Language.Docker.EDSL: comment :: forall m_aPBr. MonadFree EInstruction m_aPBr => Text -> m_aPBr ()
- Language.Docker.EDSL: copyArgs :: forall m_aPcv. MonadFree EInstruction m_aPcv => NonEmpty SourcePath -> TargetPath -> Chown -> CopySource -> m_aPcv ()
+ Language.Docker.EDSL: copyArgs :: forall m_aPAQ. MonadFree EInstruction m_aPAQ => NonEmpty SourcePath -> TargetPath -> Chown -> CopySource -> m_aPAQ ()
- Language.Docker.EDSL: embed :: forall m_aPdf. MonadFree EInstruction m_aPdf => [InstructionPos Text] -> m_aPdf ()
+ Language.Docker.EDSL: embed :: forall m_aPBA. MonadFree EInstruction m_aPBA => [InstructionPos Text] -> m_aPBA ()
- Language.Docker.EDSL: entrypointArgs :: forall m_aPcT. MonadFree EInstruction m_aPcT => Arguments Text -> m_aPcT ()
+ Language.Docker.EDSL: entrypointArgs :: forall m_aPBe. MonadFree EInstruction m_aPBe => Arguments Text -> m_aPBe ()
- Language.Docker.EDSL: env :: forall m_aPcZ. MonadFree EInstruction m_aPcZ => Pairs -> m_aPcZ ()
+ Language.Docker.EDSL: env :: forall m_aPBk. MonadFree EInstruction m_aPBk => Pairs -> m_aPBk ()
- Language.Docker.EDSL: expose :: forall m_aPcN. MonadFree EInstruction m_aPcN => Ports -> m_aPcN ()
+ Language.Docker.EDSL: expose :: forall m_aPB8. MonadFree EInstruction m_aPB8 => Ports -> m_aPB8 ()
- Language.Docker.EDSL: from :: forall m_aPbC. MonadFree EInstruction m_aPbC => EBaseImage -> m_aPbC ()
+ Language.Docker.EDSL: from :: forall m_aPzX. MonadFree EInstruction m_aPzX => EBaseImage -> m_aPzX ()
- Language.Docker.EDSL: healthcheck :: forall m_aPd9. MonadFree EInstruction m_aPd9 => Check Text -> m_aPd9 ()
+ Language.Docker.EDSL: healthcheck :: forall m_aPBu. MonadFree EInstruction m_aPBu => Check Text -> m_aPBu ()
- Language.Docker.EDSL: label :: forall m_aPcp. MonadFree EInstruction m_aPcp => Pairs -> m_aPcp ()
+ Language.Docker.EDSL: label :: forall m_aPAK. MonadFree EInstruction m_aPAK => Pairs -> m_aPAK ()
- Language.Docker.EDSL: maintainer :: forall m_aPcW. MonadFree EInstruction m_aPcW => Text -> m_aPcW ()
+ Language.Docker.EDSL: maintainer :: forall m_aPBh. MonadFree EInstruction m_aPBh => Text -> m_aPBh ()
- Language.Docker.EDSL: onBuildRaw :: forall m_aPdc. MonadFree EInstruction m_aPdc => Instruction Text -> m_aPdc ()
+ Language.Docker.EDSL: onBuildRaw :: forall m_aPBx. MonadFree EInstruction m_aPBx => Instruction Text -> m_aPBx ()
- Language.Docker.EDSL: runArgs :: forall m_aPcB. MonadFree EInstruction m_aPcB => Arguments Text -> m_aPcB ()
+ Language.Docker.EDSL: runArgs :: forall m_aPAW. MonadFree EInstruction m_aPAW => Arguments Text -> m_aPAW ()
- Language.Docker.EDSL: shell :: forall m_aPcH. MonadFree EInstruction m_aPcH => Arguments Text -> m_aPcH ()
+ Language.Docker.EDSL: shell :: forall m_aPB2. MonadFree EInstruction m_aPB2 => Arguments Text -> m_aPB2 ()
- Language.Docker.EDSL: stopSignal :: forall m_aPcs. MonadFree EInstruction m_aPcs => Text -> m_aPcs ()
+ Language.Docker.EDSL: stopSignal :: forall m_aPAN. MonadFree EInstruction m_aPAN => Text -> m_aPAN ()
- Language.Docker.EDSL: user :: forall m_aPcm. MonadFree EInstruction m_aPcm => Text -> m_aPcm ()
+ Language.Docker.EDSL: user :: forall m_aPAH. MonadFree EInstruction m_aPAH => Text -> m_aPAH ()
- Language.Docker.EDSL: volume :: forall m_aPcQ. MonadFree EInstruction m_aPcQ => Text -> m_aPcQ ()
+ Language.Docker.EDSL: volume :: forall m_aPBb. MonadFree EInstruction m_aPBb => Text -> m_aPBb ()
- Language.Docker.EDSL: workdir :: forall m_aPcK. MonadFree EInstruction m_aPcK => Directory -> m_aPcK ()
+ Language.Docker.EDSL: workdir :: forall m_aPB5. MonadFree EInstruction m_aPB5 => Directory -> m_aPB5 ()
Files
- language-docker.cabal +2/−2
- src/Language/Docker.hs +1/−1
- src/Language/Docker/PrettyPrint.hs +31/−4
- test/Language/Docker/EDSLSpec.hs +21/−0
language-docker.cabal view
@@ -2,10 +2,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: dcb1ee69fa5273343e855a6671c943851c7dfe672278f892ef306e15a0362a21+-- hash: e09dfb596ffa0aad47ade030ba31bd3d1fc4cb6395d7abef6290649bdedff1f6 name: language-docker-version: 6.0.1+version: 6.0.2 synopsis: Dockerfile parser, pretty-printer and embedded DSL description: All functions for parsing, printing and writting Dockerfiles are exported through @Language.Docker@. For more fine-grained operations look for specific modules that implement a certain functionality. See the <https://github.com/hadolint/language-docker GitHub project> for the source-code and examples.
src/Language/Docker.hs view
@@ -85,7 +85,7 @@ , Language.Docker.Syntax.Image(..) , Language.Docker.Syntax.Registry(..) , Language.Docker.Syntax.ImageAlias(..)- , Language.Docker.Syntax.Tag+ , Language.Docker.Syntax.Tag(..) , Language.Docker.Syntax.Ports , Language.Docker.Syntax.Directory , Language.Docker.Syntax.Arguments
src/Language/Docker/PrettyPrint.hs view
@@ -17,12 +17,19 @@ import Data.Text (Text) import qualified Data.Text as Text import qualified Data.Text.Lazy as L+import qualified Data.Text.Lazy.Builder as B import Data.Text.Prettyprint.Doc import Data.Text.Prettyprint.Doc.Internal (Doc(Empty)) import Data.Text.Prettyprint.Doc.Render.Text (renderLazy) import Language.Docker.Syntax import Prelude hiding ((<>), (>>), return) +data EscapeAccum = EscapeAccum+ { buffer :: !B.Builder+ , count :: !Int+ , escaping :: !Bool+ }+ instance Pretty (Arguments Text) where pretty = prettyPrintArguments @@ -53,8 +60,8 @@ pretty '@' pretty digest prettyAlias alias- UntaggedImage (Image _ name) alias -> do- pretty name+ UntaggedImage img alias -> do+ prettyPrintImage img prettyAlias alias TaggedImage img (Tag tag) alias -> do prettyPrintImage img@@ -73,7 +80,7 @@ prettyPrintPairs ps = hsep $ fmap prettyPrintPair ps prettyPrintPair :: (Text, Text) -> Doc ann-prettyPrintPair (k, v) = pretty k <> pretty '=' <> pretty v+prettyPrintPair (k, v) = pretty k <> pretty '=' <> doubleQoute v prettyPrintArguments :: Arguments Text -> Doc ann prettyPrintArguments (ArgumentsList as) = prettyPrintJSON (Text.words as)@@ -84,8 +91,28 @@ prettyPrintJSON :: [Text] -> Doc ann prettyPrintJSON args = list (fmap doubleQoute args)++doubleQoute :: Text -> Doc ann+doubleQoute w = enclose dquote dquote (pretty (escapeQuotes w))++escapeQuotes :: Text -> L.Text+escapeQuotes text =+ case Text.foldr accumulate (EscapeAccum mempty 0 False) text of+ EscapeAccum buffer _ False -> B.toLazyText buffer+ EscapeAccum buffer count True ->+ case count `mod` 2 of+ 0 -> B.toLazyText (B.singleton '\\' <> buffer)+ _ -> B.toLazyText buffer where- doubleQoute w = enclose dquote dquote (pretty w)+ accumulate '"' EscapeAccum {buffer, escaping = False} =+ EscapeAccum (B.singleton '"' <> buffer) 0 True+ accumulate '\\' EscapeAccum {buffer, escaping = True, count} =+ EscapeAccum (B.singleton '\\' <> buffer) (count + 1) True+ accumulate c EscapeAccum {buffer, escaping = True, count}+ | count `mod` 2 == 0 = EscapeAccum (B.singleton c <> B.singleton '\\' <> buffer) 0 False+ | otherwise = EscapeAccum (B.singleton c <> buffer) 0 False -- It was already escaped+ accumulate c EscapeAccum {buffer, escaping = False} =+ EscapeAccum (B.singleton c <> buffer) 0 False prettyPrintPort :: Port -> Doc ann prettyPrintPort (PortStr str) = pretty str
test/Language/Docker/EDSLSpec.hs view
@@ -78,6 +78,14 @@ , "RUN echo foo" ] + it "parses and prints from with a registry" $ do+ let r = prettyPrint $ toDockerfile $ do+ from "opensuse/tumbleweed"+ run "echo foo"+ r `shouldBe` printed [ "FROM opensuse/tumbleweed"+ , "RUN echo foo"+ ]+ it "parses and prints copy instructions" $ do let r = prettyPrint $ toDockerfile $ do from "scratch"@@ -92,6 +100,19 @@ , "COPY foo.js bar.js baz/" , "COPY --from=builder something crazy" , "COPY --chown=www-data --from=builder this that"+ ]+ it "quotes label and env correctly" $ do+ let r = prettyPrint $ toDockerfile $ do+ from "scratch"+ label [("email", "Example <example@example.com>")]+ label [("escape", "Escape this\" thing")]+ env [("foo", "bar baz")]+ env [("double_escape", "escape this \\\"")]+ r `shouldBe` printed [ "FROM scratch"+ , "LABEL email=\"Example <example@example.com>\""+ , "LABEL escape=\"Escape this\\\" thing\""+ , "ENV foo=\"bar baz\""+ , "ENV double_escape=\"escape this \\\"\"" ] describe "toDockerfileTextIO" $