packages feed

language-docker 12.0.0 → 12.1.0

raw patch · 8 files changed

+198/−71 lines, 8 files

Files

language-docker.cabal view
@@ -1,13 +1,13 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.34.7.+-- This file has been generated from package.yaml by hpack version 0.35.0. -- -- see: https://github.com/sol/hpack ----- hash: f800aba94b9f6bbf2894ac78e2f4a135d3e9e89e04d9a7b0549bdd0941e97cbd+-- hash: 37c989b46891ef750c66b64a1dcbdfc30c1ee22a0ed4821aeb27c7c63c02d2a9  name:           language-docker-version:        12.0.0+version:        12.1.0 synopsis:       Dockerfile parser, pretty-printer and embedded DSL description:    All functions for parsing and pretty-printing 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.@@ -94,6 +94,7 @@       Language.Docker.ParseCmdSpec       Language.Docker.ParseCopySpec       Language.Docker.ParseExposeSpec+      Language.Docker.ParseHealthcheckSpec       Language.Docker.ParsePragmaSpec       Language.Docker.ParserSpec       Language.Docker.ParseRunSpec
src/Language/Docker/Parser/Arguments.hs view
@@ -22,7 +22,7 @@     toEnd = untilEol "the shell arguments"  -- Parse arguments of a command in the heredoc format-argumentsHeredoc :: Parser (Arguments Text)+argumentsHeredoc :: (?esc :: Char) => Parser (Arguments Text) argumentsHeredoc = ArgumentsText <$> heredoc  arguments :: (?esc :: Char) => Parser (Arguments Text)
src/Language/Docker/Parser/Healthcheck.hs view
@@ -70,12 +70,14 @@ durationFlag :: Text -> Parser Duration durationFlag flagName = do   void $ try (string flagName)-  scale <- natural+  value <- try ( fromRational . realToFrac <$> fractional )+              <|> ( secondsToDiffTime . fromInteger <$> natural )+              <?> "a natural or fractional number"   unit <- char 's' <|> char 'm' <|> char 'h' <?> "either 's', 'm' or 'h' as the unit"   case unit of-    's' -> return $ Duration (secondsToDiffTime scale)-    'm' -> return $ Duration (secondsToDiffTime (scale * 60))-    'h' -> return $ Duration (secondsToDiffTime (scale * 60 * 60))+    's' -> return $ Duration value+    'm' -> return $ Duration (value * 60)+    'h' -> return $ Duration (value * 60 * 60)     _ -> fail "only 's', 'm' or 'h' are allowed as the duration"  retriesFlag :: Parser Retries
src/Language/Docker/Parser/Prelude.hs view
@@ -14,6 +14,8 @@     doubleQuotedString,     doubleQuotedStringEscaped,     eol,+    escapedLineBreaks',+    fractional,     heredoc,     heredocContent,     heredocMarker,@@ -133,6 +135,9 @@ natural :: Parser Integer natural = L.decimal <?> "positive number" +fractional :: Parser Float+fractional = L.float <?> "fractional number"+ commaSep :: (?esc :: Char) => Parser a -> Parser [a] commaSep p = sepBy (p <* whitespace) (symbol ",") @@ -170,7 +175,7 @@   s <- manyTill anySingle spaceChar   return $ T.pack s -heredocMarker :: Parser Text+heredocMarker :: (?esc :: Char) => Parser Text heredocMarker = do   void $ string "<<"   void $ takeWhileP (Just "dash") (== '-')@@ -178,11 +183,14 @@   optional heredocRedirect   pure m -heredocRedirect :: Parser Text+heredocRedirect :: (?esc :: Char) => Parser Text heredocRedirect = do-  void $ char '>'-  takeWhileP (Just "heredoc path") (/= '\n')+  void $ ( string "|" <|> string ">" <|> string ">>" ) *> onlySpaces+  untilEol "heredoc path" +-- | This tries to parse everything until there is the just the heredoc marker+-- on its own on a line. Making provisions for the case that the marker is+-- followed by the end of the file rather than another newline. heredocContent :: Text -> Parser Text heredocContent marker = do   emptyHeredoc <- observing delimiter@@ -215,17 +223,24 @@       hidden eof       pure t -heredoc :: Parser Text+heredoc :: (?esc :: Char) => Parser Text heredoc = do   m <- heredocMarker   heredocContent m  -- | Parses text until a heredoc or newline is found. Will also consume the--- heredoc.-untilHeredoc :: Parser Text+-- heredoc. It will however respect escaped newlines.+untilHeredoc :: (?esc :: Char) => Parser Text untilHeredoc = do-  txt <- manyTill (anySingleBut '\n') heredoc-  return $ T.strip $ T.pack txt+  txt <- manyTill chars heredoc+  return $ T.strip $ mconcat txt+  where+    chars =+      choice+        [ castToSpace <$> escapedLineBreaks,+          charToTxt <$> anySingleBut '\n'+        ]+    charToTxt c = T.pack [c]  onlySpaces :: Parser Text onlySpaces = takeWhileP (Just "spaces") (\c -> c == ' ' || c == '\t')@@ -248,6 +263,17 @@         -- Spaces before the next '\' have a special significance         -- so we remembeer the fact that we found some         FoundWhitespace <$ onlySpaces1 <|> pure MissingWhitespace+    newlines = takeWhile1P Nothing isNl++-- | This converts escaped line breaks, but keeps _all_ spaces before and after+escapedLineBreaks' :: (?esc :: Char) => Parser Text+escapedLineBreaks' = mconcat <$> breaks+  where+    breaks =+      some $ do+        try ( char ?esc *> onlySpaces *> newlines )+        skipMany . try $ onlySpaces *> comment *> newlines+        onlySpaces1     newlines = takeWhile1P Nothing isNl  foundWhitespace :: (?esc :: Char) => Parser FoundWhitespace
src/Language/Docker/Syntax.hs view
@@ -161,7 +161,7 @@   = Duration       { durationTime :: DiffTime       }-  deriving (Show, Eq, Ord, Num)+  deriving (Show, Eq, Ord, Num, Fractional)  newtype Retries   = Retries
+ test/Language/Docker/ParseHealthcheckSpec.hs view
@@ -0,0 +1,81 @@+module Language.Docker.ParseHealthcheckSpec where++import Data.Default.Class (def)+import Language.Docker.Syntax+import Test.Hspec+import TestHelper+import qualified Data.Set as Set+import qualified Data.Text as Text+++spec :: Spec+spec = do+  describe "parse HEALTHCHECK" $ do+    it "parse healthcheck with interval" $+      assertAst+        "HEALTHCHECK --interval=5m \\\nCMD curl -f http://localhost/"+        [ Healthcheck $+            Check $+              CheckArgs "curl -f http://localhost/" (Just 300) Nothing Nothing Nothing+        ]+    it "parse healthcheck with retries" $+      assertAst+        "HEALTHCHECK --retries=10 CMD curl -f http://localhost/"+        [ Healthcheck $+            Check $+              CheckArgs "curl -f http://localhost/" Nothing Nothing Nothing (Just $ Retries 10)+        ]+    it "parse healthcheck with timeout" $+      assertAst+        "HEALTHCHECK --timeout=10s CMD curl -f http://localhost/"+        [ Healthcheck $+            Check $+              CheckArgs "curl -f http://localhost/" Nothing (Just 10) Nothing Nothing+        ]+    it "parse healthcheck with start-period" $+      assertAst+        "HEALTHCHECK --start-period=2m CMD curl -f http://localhost/"+        [ Healthcheck $+            Check $+              CheckArgs "curl -f http://localhost/" Nothing Nothing (Just 120) Nothing+        ]+    it "parse healthcheck with all flags" $+      assertAst+        "HEALTHCHECK --start-period=2s --timeout=1m --retries=3 --interval=5s    CMD curl -f http://localhost/"+        [ Healthcheck $+            Check $+              CheckArgs+                "curl -f http://localhost/"+                (Just 5)+                (Just 60)+                (Just 2)+                (Just $ Retries 3)+        ]+    it "parse healthcheck with no flags" $+      assertAst+        "HEALTHCHECK CMD curl -f http://localhost/"+        [ Healthcheck $+            Check $+              CheckArgs "curl -f http://localhost/" Nothing Nothing Nothing Nothing+        ]++    it "fractional arguments to flags" $+      let file =+            Text.unlines+              [ "HEALTHCHECK \\",+                "  --interval=0.5s \\",+                "  --timeout=0.1s \\",+                "  --start-period=0.2s \\",+                "  CMD curl -f http://localhost"+              ]+       in assertAst+            file+            [ Healthcheck $+                Check $+                  CheckArgs+                    "curl -f http://localhost"+                    ( Just 0.5 )+                    ( Just 0.10000000149 )+                    ( Just 0.20000000298 )+                    Nothing+            ]
test/Language/Docker/ParseRunSpec.hs view
@@ -14,6 +14,9 @@     it "escaped with space before" $       let dockerfile = Text.unlines ["RUN yum install -y \\", "imagemagick \\", "mysql"]        in assertAst dockerfile [Run "yum install -y imagemagick mysql"]+    it "escaped linebreak, indented" $+      let file = Text.unlines [ "RUN foo ; \\", "    bar" ]+       in assertAst file [ Run "foo ;  bar" ]     it "does not choke on unmatched brackets" $       let dockerfile = Text.unlines ["RUN [foo"]        in assertAst dockerfile [Run "[foo"]@@ -501,17 +504,25 @@        in assertAst file [ Run $ RunArgs (ArgumentsText "foo\nbar EOF") flags ]     it "heredoc with redirection to file" $       let file = Text.unlines [ "RUN <<EOF > /file", "foo", "EOF" ]-          flags = def {security = Nothing }+          flags = def { security = Nothing }        in assertAst file [ Run $ RunArgs (ArgumentsText "foo") flags ]     it "heredoc to program stdin" $       let file = Text.unlines [ "RUN python <<EOF", "print(\"foo\")", "EOF" ]-          flags = def {security = Nothing }+          flags = def { security = Nothing }        in assertAst file [ Run $ RunArgs (ArgumentsText "python") flags ]-    it "heredoc to program stdin with redirect to file" $+    it "heredoc to program stdin with redirect to file with '>'" $       let file = Text.unlines [ "RUN python <<EOF > /file", "print(\"foo\")", "EOF" ]-          flags = def {security = Nothing }+          flags = def { security = Nothing }        in assertAst file [ Run $ RunArgs (ArgumentsText "python") flags ]-    it "heredoc with line continuation" $+    it "heredoc to program stdin with redirect to file with '>>'" $+      let file = Text.unlines [ "RUN python <<EOF >> /file", "print(\"foo\")", "EOF" ]+          flags = def { security = Nothing }+       in assertAst file [ Run $ RunArgs (ArgumentsText "python") flags ]+    it "heredoc pipe to program" $+      let file = Text.unlines [ "RUN cat <<EOF | sh", "echo foo", "EOF" ]+          flags = def { security = Nothing }+       in assertAst file [ Run $ RunArgs ( ArgumentsText "cat" ) flags ]+    it "heredoc with line continuation in the heredoc" $       let file = Text.unlines [ "RUN <<EOF", "apt-get update", "apt-get install foo bar \\", "  buzz bar", "EOF" ]           flags = def {security = Nothing }        in assertAst@@ -571,4 +582,58 @@                     (TargetPath "/foobar.sh")                 )                 ( def :: CopyFlags )+            ]++    -- See https://github.com/hadolint/hadolint/issues/923 for the following+    -- tests+    it "heredoc in command chain with escaped newlines after redirect" $+      let file =+            Text.unlines+              [ "RUN ls && cat <<EOF >> go.mod && \\",+                "    tac go.mod",+                "replace (",+                "    github.com/user/repo => ../dir",+                ")",+                "EOF"+              ]+          flags = def++       in assertAst+            file+            [ Run $ RunArgs ( ArgumentsText "ls && cat" ) flags+            ]++    it "heredoc in command chain with escaped newlines before heredoc" $+      let file =+            Text.unlines+              [ "RUN ls && \\",+                "    cat <<EOF >> go.mod && tac go.mod",+                "replace (",+                "    github.com/user/repo => ../dir",+                ")",+                "EOF"+              ]+          flags = def++       in assertAst+            file+            [ Run $ RunArgs ( ArgumentsText "ls &&  cat" ) flags+            ]++    it "heredoc in command chain with escaped newlines before and after heredoc" $+      let file =+            Text.unlines+              [ "RUN ls && \\",+                "    cat <<EOF >> go.mod && \\",+                "    tac go.mod",+                "replace (",+                "    github.com/user/repo => ../dir",+                ")",+                "EOF"+              ]+          flags = def++       in assertAst+            file+            [ Run $ RunArgs ( ArgumentsText "ls &&  cat" ) flags             ]
test/Language/Docker/ParserSpec.hs view
@@ -174,54 +174,6 @@   describe "parse SHELL" $     it "quoted shell params" $       assertAst "SHELL [\"/bin/bash\",  \"-c\"]" [Shell ["/bin/bash", "-c"]]-  describe "parse HEALTHCHECK" $ do-    it "parse healthcheck with interval" $-      assertAst-        "HEALTHCHECK --interval=5m \\\nCMD curl -f http://localhost/"-        [ Healthcheck $-            Check $-              CheckArgs "curl -f http://localhost/" (Just 300) Nothing Nothing Nothing-        ]-    it "parse healthcheck with retries" $-      assertAst-        "HEALTHCHECK --retries=10 CMD curl -f http://localhost/"-        [ Healthcheck $-            Check $-              CheckArgs "curl -f http://localhost/" Nothing Nothing Nothing (Just $ Retries 10)-        ]-    it "parse healthcheck with timeout" $-      assertAst-        "HEALTHCHECK --timeout=10s CMD curl -f http://localhost/"-        [ Healthcheck $-            Check $-              CheckArgs "curl -f http://localhost/" Nothing (Just 10) Nothing Nothing-        ]-    it "parse healthcheck with start-period" $-      assertAst-        "HEALTHCHECK --start-period=2m CMD curl -f http://localhost/"-        [ Healthcheck $-            Check $-              CheckArgs "curl -f http://localhost/" Nothing Nothing (Just 120) Nothing-        ]-    it "parse healthcheck with all flags" $-      assertAst-        "HEALTHCHECK --start-period=2s --timeout=1m --retries=3 --interval=5s    CMD curl -f http://localhost/"-        [ Healthcheck $-            Check $-              CheckArgs-                "curl -f http://localhost/"-                (Just 5)-                (Just 60)-                (Just 2)-                (Just $ Retries 3)-        ]-    it "parse healthcheck with no flags" $-      assertAst-        "HEALTHCHECK CMD curl -f http://localhost/"-        [ Healthcheck $-            Check $-              CheckArgs "curl -f http://localhost/" Nothing Nothing Nothing Nothing-        ]   describe "parse MAINTAINER" $ do     it "maintainer of untagged scratch image" $       assertAst