From e1e0a15ac1905a52346eb77443d1aaa677a0387c Mon Sep 17 00:00:00 2001 From: Paolo Pettinato Date: Tue, 30 Jan 2024 12:05:47 +0000 Subject: [PATCH 1/6] Add Checksum parser (WIP) --- src/Language/Docker/Parser/Copy.hs | 31 +++++++++++++++++++++--------- src/Language/Docker/PrettyPrint.hs | 9 ++++++++- src/Language/Docker/Syntax.hs | 16 +++++++++++++-- 3 files changed, 44 insertions(+), 12 deletions(-) diff --git a/src/Language/Docker/Parser/Copy.hs b/src/Language/Docker/Parser/Copy.hs index 89b75f2..ff0ec93 100644 --- a/src/Language/Docker/Parser/Copy.hs +++ b/src/Language/Docker/Parser/Copy.hs @@ -10,7 +10,8 @@ import Language.Docker.Parser.Prelude import Language.Docker.Syntax data Flag - = FlagChown Chown + = FlagChecksum Checksum + | FlagChown Chown | FlagChmod Chmod | FlagLink Link | FlagSource CopySource @@ -56,18 +57,23 @@ parseAdd :: (?esc :: Char) => Parser (Instruction Text) parseAdd = do reserved "ADD" flags <- addFlag `sepEndBy` requiredWhitespace + let checksumFlags = [c | FlagChecksum c <- flags] let chownFlags = [c | FlagChown c <- flags] let chmodFlags = [c | FlagChmod c <- flags] let linkFlags = [l | FlagLink l <- flags] let invalidFlags = [i | FlagInvalid i <- flags] notFollowedBy (string "--") - "only the --chown flag, the --chmod flag or the src and dest paths" - case (invalidFlags, chownFlags, linkFlags, chmodFlags) of - ((k, v) : _, _, _, _) -> unexpectedFlag k v - (_, _ : _ : _, _, _) -> customError $ DuplicateFlagError "--chown" - (_, _, _ : _ : _, _) -> customError $ DuplicateFlagError "--chmod" - (_, _, _, _ : _ : _) -> customError $ DuplicateFlagError "--link" + "only the --checksum, --chown, --chmod, --link flags or the src and dest paths" + case (invalidFlags, checksumFlags, chownFlags, linkFlags, chmodFlags) of + ((k, v) : _, _, _, _, _) -> unexpectedFlag k v + (_, _ : _ : _, _, _, _) -> customError $ DuplicateFlagError "--checksum" + (_, _, _ : _ : _, _, _) -> customError $ DuplicateFlagError "--chown" + (_, _, _, _ : _ : _, _) -> customError $ DuplicateFlagError "--chmod" + (_, _, _, _, _ : _ : _) -> customError $ DuplicateFlagError "--link" _ -> do + let chk = case checksumFlags of + [] -> NoChecksum + c : _ -> c let cho = case chownFlags of [] -> NoChown c : _ -> c @@ -78,7 +84,7 @@ parseAdd = do case linkFlags of [] -> NoLink l : _ -> l - fileList "ADD" (\src dest -> Add (AddArgs src dest) (AddFlags cho chm lnk)) + fileList "ADD" (\src dest -> Add (AddArgs src dest) (AddFlags chk cho chm lnk)) heredocList :: (?esc :: Char) => (NonEmpty SourcePath -> TargetPath -> Instruction Text) -> @@ -114,11 +120,18 @@ copyFlag :: (?esc :: Char) => Parser Flag copyFlag = (FlagSource <$> try copySource "only one --from") <|> addFlag addFlag :: (?esc :: Char) => Parser Flag -addFlag = (FlagChown <$> try chown "--chown") +addFlag = (FlagChecksum <$> try checksum "--checksum") + <|> (FlagChown <$> try chown "--chown") <|> (FlagChmod <$> try chmod "--chmod") <|> (FlagLink <$> try link "--link") <|> (FlagInvalid <$> try anyFlag "other flag") +checksum :: (?esc :: Char) => Parser Checksum +checksum = do + void $ string "--checksum=" + chk <- someUnless "the remote file checksum" (== ' ') + return $ Checksum chk + chown :: (?esc :: Char) => Parser Chown chown = do void $ string "--chown=" diff --git a/src/Language/Docker/PrettyPrint.hs b/src/Language/Docker/PrettyPrint.hs index a0d6a37..a0a1bc9 100644 --- a/src/Language/Docker/PrettyPrint.hs +++ b/src/Language/Docker/PrettyPrint.hs @@ -136,6 +136,12 @@ prettyPrintFileList sources (TargetPath dest) = _ -> "" in hsep $ [pretty s | SourcePath s <- toList sources] ++ [pretty dest <> ending] +prettyPrintChecksum :: Checksum -> Doc ann +prettyPrintChecksum checksum = + case checksum of + Checksum c -> "--checksum=" <> pretty c + NoChecksum -> mempty + prettyPrintChown :: Chown -> Doc ann prettyPrintChown chown = case chown of @@ -315,8 +321,9 @@ prettyPrintInstruction i = prettyPrintBaseImage b Add AddArgs {sourcePaths, targetPath} - AddFlags {chownFlag, chmodFlag, linkFlag} -> do + AddFlags {checksumFlag, chownFlag, chmodFlag, linkFlag} -> do "ADD" + prettyPrintChecksum checksumFlag prettyPrintChown chownFlag prettyPrintChmod chmodFlag prettyPrintLink linkFlag diff --git a/src/Language/Docker/Syntax.hs b/src/Language/Docker/Syntax.hs index e26c012..58588f1 100644 --- a/src/Language/Docker/Syntax.hs +++ b/src/Language/Docker/Syntax.hs @@ -119,6 +119,17 @@ newtype TargetPath } deriving (Show, Eq, Ord, IsString) +data Checksum + = Checksum !Text + | NoChecksum + deriving (Show, Eq, Ord) + +instance IsString Checksum where + fromString ch = + case ch of + "" -> NoChecksum + _ -> Checksum (Text.pack ch) + data Chown = Chown !Text | NoChown @@ -197,14 +208,15 @@ data AddArgs data AddFlags = AddFlags - { chownFlag :: !Chown, + { checksumFlag :: !Checksum, + chownFlag :: !Chown, chmodFlag :: !Chmod, linkFlag :: !Link } deriving (Show, Eq, Ord) instance Default AddFlags where - def = AddFlags NoChown NoChmod NoLink + def = AddFlags NoChecksum NoChown NoChmod NoLink data Check args = Check !(CheckArgs args) From 14cad93e6c21e0d11587b6f236f036a8d4ce2d26 Mon Sep 17 00:00:00 2001 From: Paolo Pettinato Date: Tue, 30 Jan 2024 12:59:53 +0000 Subject: [PATCH 2/6] Add some tests for --checksum --- test/Language/Docker/ParseAddSpec.hs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/test/Language/Docker/ParseAddSpec.hs b/test/Language/Docker/ParseAddSpec.hs index 6b64590..b8d12fc 100644 --- a/test/Language/Docker/ParseAddSpec.hs +++ b/test/Language/Docker/ParseAddSpec.hs @@ -41,6 +41,14 @@ spec = do ) def ] + it "with checksum flag" $ + let file = Text.unlines ["ADD --checksum=sha256:24454f830cdd http://www.example.com/foo foo"] + in assertAst + file + [ Add + ( AddArgs (fmap SourcePath ["foo"]) (TargetPath "bar") ) + ( AddFlags (Chown "root:root") NoChmod NoLink ) + ] it "with chown flag" $ let file = Text.unlines ["ADD --chown=root:root foo bar"] in assertAst @@ -83,7 +91,7 @@ spec = do ] it "with all flags" $ let file = - Text.unlines ["ADD --chmod=640 --chown=root:root --link foo bar"] + Text.unlines ["ADD --chmod=640 --chown=root:root --checksum=sha256:24454f830cdd --link foo bar"] in assertAst file [ Add From 6f1fd0effdaf4472b4c55e496e04c6c7ee5d39ce Mon Sep 17 00:00:00 2001 From: Paolo Pettinato Date: Tue, 30 Jan 2024 13:33:34 +0000 Subject: [PATCH 3/6] Add integration repo with --checksum --- integration-tests/parse_files.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/integration-tests/parse_files.sh b/integration-tests/parse_files.sh index 05ae21a..d4815fe 100755 --- a/integration-tests/parse_files.sh +++ b/integration-tests/parse_files.sh @@ -77,6 +77,7 @@ function clone_repos() { git_clone https://github.com/ArchiveTeam/warrior-dockerfile.git & git_clone https://github.com/wckr/wocker-dockerfile.git & git_clone https://github.com/kartoza/docker-postgis.git & + git_clone https://github.com/andrericardo/docker-subtitleedit & # colliding names git_named_clone https://github.com/yaronr/dockerfile.git yaronr-dockerfile & From 76a75cb2f2ed837db72a52198a4e9f0a1e628f1d Mon Sep 17 00:00:00 2001 From: Paolo Pettinato Date: Tue, 30 Jan 2024 13:38:08 +0000 Subject: [PATCH 4/6] Bump version --- package.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.yaml b/package.yaml index d70bc21..b8e4216 100644 --- a/package.yaml +++ b/package.yaml @@ -1,6 +1,6 @@ --- name: language-docker -version: '12.1.0' +version: '12.2.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 From 756385d461b79451e93acd4d6fab019676825064 Mon Sep 17 00:00:00 2001 From: Paolo Pettinato Date: Tue, 30 Jan 2024 14:15:21 +0000 Subject: [PATCH 5/6] Fix tests --- test/Language/Docker/ParseAddSpec.hs | 20 ++++++++++---------- test/Language/Docker/PrettyPrintSpec.hs | 13 +++++++++---- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/test/Language/Docker/ParseAddSpec.hs b/test/Language/Docker/ParseAddSpec.hs index b8d12fc..31c6953 100644 --- a/test/Language/Docker/ParseAddSpec.hs +++ b/test/Language/Docker/ParseAddSpec.hs @@ -42,12 +42,12 @@ spec = do def ] it "with checksum flag" $ - let file = Text.unlines ["ADD --checksum=sha256:24454f830cdd http://www.example.com/foo foo"] + let file = Text.unlines ["ADD --checksum=sha256:24454f830cdd http://www.example.com/foo bar"] in assertAst file [ Add - ( AddArgs (fmap SourcePath ["foo"]) (TargetPath "bar") ) - ( AddFlags (Chown "root:root") NoChmod NoLink ) + ( AddArgs (fmap SourcePath ["http://www.example.com/foo"]) (TargetPath "bar") ) + ( AddFlags (Checksum "sha256:24454f830cdd") NoChown NoChmod NoLink ) ] it "with chown flag" $ let file = Text.unlines ["ADD --chown=root:root foo bar"] @@ -55,7 +55,7 @@ spec = do file [ Add ( AddArgs (fmap SourcePath ["foo"]) (TargetPath "bar") ) - ( AddFlags (Chown "root:root") NoChmod NoLink ) + ( AddFlags NoChecksum (Chown "root:root") NoChmod NoLink ) ] it "with chmod flag" $ let file = Text.unlines ["ADD --chmod=640 foo bar"] @@ -63,7 +63,7 @@ spec = do file [ Add ( AddArgs (fmap SourcePath ["foo"]) (TargetPath "bar") ) - ( AddFlags NoChown (Chmod "640") NoLink ) + ( AddFlags NoChecksum NoChown (Chmod "640") NoLink ) ] it "with link flag" $ let file = Text.unlines ["ADD --link foo bar"] @@ -71,7 +71,7 @@ spec = do file [ Add ( AddArgs (fmap SourcePath ["foo"]) (TargetPath "bar") ) - ( AddFlags NoChown NoChmod Link ) + ( AddFlags NoChecksum NoChown NoChmod Link ) ] it "with chown and chmod flag" $ let file = Text.unlines ["ADD --chown=root:root --chmod=640 foo bar"] @@ -79,7 +79,7 @@ spec = do file [ Add ( AddArgs (fmap SourcePath ["foo"]) (TargetPath "bar") ) - ( AddFlags (Chown "root:root") (Chmod "640") NoLink ) + ( AddFlags NoChecksum (Chown "root:root") (Chmod "640") NoLink ) ] it "with chown and chmod flag other order" $ let file = Text.unlines ["ADD --chmod=640 --chown=root:root foo bar"] @@ -87,7 +87,7 @@ spec = do file [ Add ( AddArgs (fmap SourcePath ["foo"]) (TargetPath "bar") ) - ( AddFlags (Chown "root:root") (Chmod "640") NoLink ) + ( AddFlags NoChecksum (Chown "root:root") (Chmod "640") NoLink ) ] it "with all flags" $ let file = @@ -96,7 +96,7 @@ spec = do file [ Add ( AddArgs (fmap SourcePath ["foo"]) (TargetPath "bar") ) - ( AddFlags (Chown "root:root") (Chmod "640") Link ) + ( AddFlags (Checksum "sha256:24454f830cdd") (Chown "root:root") (Chmod "640") Link ) ] it "list of quoted files and chown" $ let file = @@ -109,5 +109,5 @@ spec = do (fmap SourcePath ["foo", "bar", "baz"]) (TargetPath "/app") ) - ( AddFlags (Chown "user:group") NoChmod NoLink ) + ( AddFlags NoChecksum (Chown "user:group") NoChmod NoLink ) ] diff --git a/test/Language/Docker/PrettyPrintSpec.hs b/test/Language/Docker/PrettyPrintSpec.hs index 76319f1..329c3f9 100644 --- a/test/Language/Docker/PrettyPrintSpec.hs +++ b/test/Language/Docker/PrettyPrintSpec.hs @@ -21,25 +21,30 @@ spec = do ( AddArgs [SourcePath "foo"] (TargetPath "bar") ) ( def :: AddFlags ) in assertPretty "ADD foo bar" add + it "with just checksum" $ do + let add = Add + ( AddArgs [SourcePath "http://www.example.com/foo"] (TargetPath "bar") ) + ( AddFlags ( Checksum "sha256:24454f830cdd" ) NoChown NoChmod NoLink ) + in assertPretty "ADD --checksum=sha256:24454f830cdd http://www.example.com/foo bar" add it "with just chown" $ do let add = Add ( AddArgs [SourcePath "foo"] (TargetPath "bar") ) - ( AddFlags ( Chown "root:root" ) NoChmod NoLink ) + ( AddFlags NoChecksum ( Chown "root:root" ) NoChmod NoLink ) in assertPretty "ADD --chown=root:root foo bar" add it "with just chmod" $ do let add = Add ( AddArgs [SourcePath "foo"] (TargetPath "bar") ) - ( AddFlags NoChown ( Chmod "751" ) NoLink ) + ( AddFlags NoChecksum NoChown ( Chmod "751" ) NoLink ) in assertPretty "ADD --chmod=751 foo bar" add it "with just link" $ do let add = Add ( AddArgs [SourcePath "foo"] (TargetPath "bar") ) - ( AddFlags NoChown NoChmod Link ) + ( AddFlags NoChecksum NoChown NoChmod Link ) in assertPretty "ADD --link foo bar" add it "with chown, chmod and link" $ do let add = Add ( AddArgs [SourcePath "foo"] (TargetPath "bar") ) - ( AddFlags ( Chown "root:root" ) ( Chmod "751" ) Link ) + ( AddFlags NoChecksum ( Chown "root:root" ) ( Chmod "751" ) Link ) in assertPretty "ADD --chown=root:root --chmod=751 --link foo bar" add describe "pretty print COPY" $ do From 325be8aeecf6463f9618e018f6d2fdc59ddc0382 Mon Sep 17 00:00:00 2001 From: Paolo Pettinato Date: Tue, 30 Jan 2024 14:16:01 +0000 Subject: [PATCH 6/6] Commit cabal file --- language-docker.cabal | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/language-docker.cabal b/language-docker.cabal index ed4da1a..ea8ac19 100644 --- a/language-docker.cabal +++ b/language-docker.cabal @@ -1,13 +1,13 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.35.0. +-- This file has been generated from package.yaml by hpack version 0.36.0. -- -- see: https://github.com/sol/hpack -- --- hash: 37c989b46891ef750c66b64a1dcbdfc30c1ee22a0ed4821aeb27c7c63c02d2a9 +-- hash: 528820a99687ed9372038487df42e487d63b867ed312d39e8e51b6d1bf4cf7d9 name: language-docker -version: 12.1.0 +version: 12.2.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 for the source-code and examples.