Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/Language/Docker/Parser/Prelude.hs
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,11 @@ heredocContent marker = do
termination :: Parser Text
termination = try terEOL <|> terEOF

-- The line break that follows the terminating marker is not part of the
-- heredoc: it is the line break that separates this instruction from
-- whatever comes next, so it is left for the caller to consume.
terEOL :: Parser Text
terEOL = string $ "\n" <> marker <> "\n"
terEOL = string ("\n" <> marker) <* lookAhead (char '\n')

terEOF :: Parser Text
terEOF = do
Expand All @@ -215,7 +218,7 @@ heredocContent marker = do
delimiter = try delEOL <|> delEOF

delEOL :: Parser Text
delEOL = string $ marker <> "\n"
delEOL = string marker <* lookAhead (char '\n')

delEOF :: Parser Text
delEOF = do
Expand Down
20 changes: 20 additions & 0 deletions test/Language/Docker/ParseCopySpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -314,3 +314,23 @@ spec = do
( CopyArgs [ SourcePath "FOO" ] ( TargetPath "/target" ) )
def
]
it "heredoc followed by another instruction" $
let file = Text.unlines ["COPY <<EOF /target", "content", "EOF", "COPY a b"]
in assertAst
file
[ Copy
( CopyArgs [ SourcePath "EOF" ] ( TargetPath "/target" ) )
def,
Copy
( CopyArgs [ SourcePath "a" ] ( TargetPath "b" ) )
def
]
it "empty heredoc followed by a comment" $
let file = Text.unlines ["COPY <<EOF /target", "EOF", "# comment"]
in assertAst
file
[ Copy
( CopyArgs [ SourcePath "EOF" ] ( TargetPath "/target" ) )
def,
Comment " comment"
]
24 changes: 24 additions & 0 deletions test/Language/Docker/ParseRunSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,30 @@ spec = do
let file = "RUN <<EOF\nEOF"
flags = def { security = Nothing }
in assertAst file [ Run $ RunArgs (ArgumentsText "") flags ]
it "heredoc followed by a comment" $
let file = Text.unlines [ "RUN <<EOF", "echo foo", "EOF", "# comment" ]
flags = def { security = Nothing }
in assertAst
file
[ Run $ RunArgs (ArgumentsText "echo foo") flags,
Comment " comment"
]
it "heredoc followed by another instruction" $
let file = Text.unlines [ "RUN <<EOF", "echo foo", "EOF", "RUN echo bar" ]
flags = def { security = Nothing }
in assertAst
file
[ Run $ RunArgs (ArgumentsText "echo foo") flags,
Run $ RunArgs (ArgumentsText "echo bar") flags
]
it "empty heredoc followed by a comment" $
let file = Text.unlines [ "RUN <<EOF", "EOF", "# comment" ]
flags = def { security = Nothing }
in assertAst
file
[ Run $ RunArgs (ArgumentsText "") flags,
Comment " comment"
]
it "evil heredoc" $
let file = Text.unlines [ "RUN <<EOF foo", "bar EOF", "EOF"]
flags = def { security = Nothing }
Expand Down
Loading