From 61208c4f09c049bf02c5177b07c9b32aa4f12fdd Mon Sep 17 00:00:00 2001 From: Jose Lorenzo Rodriguez Date: Wed, 6 Jun 2018 22:36:42 +0200 Subject: [PATCH 1/2] Fixed the parser when there is a newline escape followed by space Also exports more things that I mised in the previous release --- integration-tests/parseFile.hs | 4 +++- integration-tests/parse_files.sh | 7 +++++-- src/Language/Docker.hs | 2 +- src/Language/Docker/Normalize.hs | 12 ++++++++---- src/Language/Docker/Parser.hs | 3 +++ test/Language/Docker/ParserSpec.hs | 12 ++++++++++++ 6 files changed, 32 insertions(+), 8 deletions(-) diff --git a/integration-tests/parseFile.hs b/integration-tests/parseFile.hs index 0ccaceb..970ae44 100755 --- a/integration-tests/parseFile.hs +++ b/integration-tests/parseFile.hs @@ -5,4 +5,6 @@ main :: IO () main = do args <- getArgs output <- parseFile $ head args - print output + case output of + Left err -> error (parseErrorPretty err) + Right ast -> print (prettyPrintDockerfile ast) diff --git a/integration-tests/parse_files.sh b/integration-tests/parse_files.sh index f171f5d..fbe4110 100755 --- a/integration-tests/parse_files.sh +++ b/integration-tests/parse_files.sh @@ -109,8 +109,11 @@ function parse_dockerfiles() { if [[ "$BLACKLIST" == *$dockerfile* ]]; then continue; fi - if ./parseFile "$dockerfile" | grep -a1 unexpected; then - result="false" + + if ./parseFile "$dockerfile" > /dev/null; then + echo "$dockerfile" + else + result="false" fi done if [[ ${result} == "false" ]]; then false; fi diff --git a/src/Language/Docker.hs b/src/Language/Docker.hs index cf3c420..21e1317 100644 --- a/src/Language/Docker.hs +++ b/src/Language/Docker.hs @@ -6,7 +6,7 @@ module Language.Docker , Text.Megaparsec.parseErrorPretty -- * Pretty-printing Dockerfiles (@Language.Docker.PrettyPrint@) , prettyPrint - , prettyPrintInstructionPos + , prettyPrintDockerfile -- * Writting Dockerfiles (@Language.Docker.EDSL@) , Language.Docker.EDSL.toDockerfileText , Language.Docker.EDSL.toDockerfile diff --git a/src/Language/Docker/Normalize.hs b/src/Language/Docker/Normalize.hs index c665faa..ad93934 100644 --- a/src/Language/Docker/Normalize.hs +++ b/src/Language/Docker/Normalize.hs @@ -50,7 +50,7 @@ normalize allLines = -- and we return 'Nothing' as an indication that this line does not form part of the -- final result. transform :: NormalizedLine -> Text -> (NormalizedLine, Maybe Text) - transform (Joined prev times) line + transform (Joined prev times) rawLine -- If we are buffering lines and the next one is empty or it starts with a comment -- we simply ignore the comment and remember to add a newline | Text.null line || isComment line = (Joined prev (times + 1), Nothing) @@ -61,12 +61,16 @@ normalize allLines = -- the concatanation of the buffer and the current line as result, after padding with -- newlines | otherwise = (Continue, Just (toText (prev <> Builder.fromText line <> padNewlines times))) + where + line = Text.stripEnd rawLine -- When not buffering lines, then we just check if we need to start doing it by checking -- whether or not the current line ends with \. If it does not, then we just yield the -- current line as part of the result - transform Continue l - | endsWithEscape l = (Joined (normalizeLast l) 1, Nothing) - | otherwise = (Continue, Just l) + transform Continue rawLine + | endsWithEscape line = (Joined (normalizeLast line) 1, Nothing) + | otherwise = (Continue, Just line) + where + line = Text.stripEnd rawLine -- endsWithEscape t | Text.null t = False diff --git a/src/Language/Docker/Parser.hs b/src/Language/Docker/Parser.hs index eb283ea..bb0e6a2 100644 --- a/src/Language/Docker/Parser.hs +++ b/src/Language/Docker/Parser.hs @@ -5,6 +5,9 @@ module Language.Docker.Parser ( parseText , parseFile + , Parser + , Error + , DockerfileError(..) ) where import Control.Monad (void) diff --git a/test/Language/Docker/ParserSpec.hs b/test/Language/Docker/ParserSpec.hs index 73ee514..d649297 100644 --- a/test/Language/Docker/ParserSpec.hs +++ b/test/Language/Docker/ParserSpec.hs @@ -234,10 +234,12 @@ spec = do , "ENV NODE_VERSION=v5.7.1 DEBIAN_FRONTEND=noninteractive\n" ] in normalizeEscapedLines dockerfile `shouldBe` normalizedDockerfile + it "join escaped lines" $ let dockerfile = Text.unlines ["ENV foo=bar \\", "baz=foz"] normalizedDockerfile = Text.unlines ["ENV foo=bar baz=foz", ""] in normalizeEscapedLines dockerfile `shouldBe` normalizedDockerfile + it "join long CMD" $ let longEscapedCmd = Text.unlines @@ -260,6 +262,16 @@ spec = do , "\n" ] in normalizeEscapedLines longEscapedCmd `shouldBe` longEscapedCmdExpected + + it "tolerates spaces after a newline escape" $ + let dockerfile = Text.unlines [ "FROM busy\\ " + , "box" + , "RUN echo\\ " + , " hello" + ] + in assertAst dockerfile [ From (UntaggedImage "busybox" Nothing) + , Run "echo hello" + ] describe "expose" $ do it "should handle number ports" $ let content = "EXPOSE 8080" From 7333b739e77f1b0a41d9269d4092667104f3869f Mon Sep 17 00:00:00 2001 From: Jose Lorenzo Rodriguez Date: Thu, 7 Jun 2018 10:04:12 +0200 Subject: [PATCH 2/2] fixed indentation --- integration-tests/parse_files.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/integration-tests/parse_files.sh b/integration-tests/parse_files.sh index fbe4110..acb1a1e 100755 --- a/integration-tests/parse_files.sh +++ b/integration-tests/parse_files.sh @@ -106,14 +106,14 @@ function parse_dockerfiles() { stack ghc parseFile.hs --package language-docker dockerfiles=$(find . -name 'Dockerfile') for dockerfile in $dockerfiles; do - if [[ "$BLACKLIST" == *$dockerfile* ]]; then - continue; - fi + if [[ "$BLACKLIST" == *$dockerfile* ]]; then + continue; + fi if ./parseFile "$dockerfile" > /dev/null; then - echo "$dockerfile" + echo "$dockerfile" else - result="false" + result="false" fi done if [[ ${result} == "false" ]]; then false; fi