language-docker 13.0.0 → 14.0.0
raw patch · 11 files changed
+313/−169 lines, 11 filesdep ~bytestringdep ~containersdep ~data-defaultPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: bytestring, containers, data-default, data-default-class, megaparsec, prettyprinter, split, text, time
API changes (from Hackage documentation)
- Language.Docker.Syntax: instance Data.Default.Class.Default Language.Docker.Syntax.AddFlags
- Language.Docker.Syntax: instance Data.Default.Class.Default Language.Docker.Syntax.BindOpts
- Language.Docker.Syntax: instance Data.Default.Class.Default Language.Docker.Syntax.CacheOpts
- Language.Docker.Syntax: instance Data.Default.Class.Default Language.Docker.Syntax.CopyFlags
- Language.Docker.Syntax: instance Data.Default.Class.Default Language.Docker.Syntax.RunFlags
- Language.Docker.Syntax: instance Data.Default.Class.Default Language.Docker.Syntax.SecretOpts
- Language.Docker.Syntax: instance Data.Default.Class.Default Language.Docker.Syntax.TmpOpts
+ Language.Docker: [$sel:startInterval:CheckArgs] :: CheckArgs args -> !Maybe Duration
+ Language.Docker.PrettyPrint: prettyPrintExclude :: Exclude -> Doc ann
+ Language.Docker.PrettyPrint: prettyPrintExcludes :: [Exclude] -> Doc ann
+ Language.Docker.Syntax: Exclude :: Text -> Exclude
+ Language.Docker.Syntax: [$sel:excludeFlags:AddFlags] :: AddFlags -> ![Exclude]
+ Language.Docker.Syntax: [$sel:excludeFlags:CopyFlags] :: CopyFlags -> ![Exclude]
+ Language.Docker.Syntax: [$sel:sEnv:SecretOpts] :: SecretOpts -> !Maybe Text
+ Language.Docker.Syntax: [$sel:startInterval:CheckArgs] :: CheckArgs args -> !Maybe Duration
+ Language.Docker.Syntax: [$sel:unExclude:Exclude] :: Exclude -> Text
+ Language.Docker.Syntax: instance Data.Default.Internal.Default Language.Docker.Syntax.AddFlags
+ Language.Docker.Syntax: instance Data.Default.Internal.Default Language.Docker.Syntax.BindOpts
+ Language.Docker.Syntax: instance Data.Default.Internal.Default Language.Docker.Syntax.CacheOpts
+ Language.Docker.Syntax: instance Data.Default.Internal.Default Language.Docker.Syntax.CopyFlags
+ Language.Docker.Syntax: instance Data.Default.Internal.Default Language.Docker.Syntax.RunFlags
+ Language.Docker.Syntax: instance Data.Default.Internal.Default Language.Docker.Syntax.SecretOpts
+ Language.Docker.Syntax: instance Data.Default.Internal.Default Language.Docker.Syntax.TmpOpts
+ Language.Docker.Syntax: instance Data.String.IsString Language.Docker.Syntax.Exclude
+ Language.Docker.Syntax: instance GHC.Classes.Eq Language.Docker.Syntax.Exclude
+ Language.Docker.Syntax: instance GHC.Classes.Ord Language.Docker.Syntax.Exclude
+ Language.Docker.Syntax: instance GHC.Show.Show Language.Docker.Syntax.Exclude
+ Language.Docker.Syntax: newtype Exclude
- Language.Docker: CheckArgs :: !Arguments args -> !Maybe Duration -> !Maybe Duration -> !Maybe Duration -> !Maybe Retries -> CheckArgs args
+ Language.Docker: CheckArgs :: !Arguments args -> !Maybe Duration -> !Maybe Duration -> !Maybe Duration -> !Maybe Duration -> !Maybe Retries -> CheckArgs args
- Language.Docker.Syntax: AddFlags :: !Checksum -> !Chown -> !Chmod -> !Link -> AddFlags
+ Language.Docker.Syntax: AddFlags :: !Checksum -> !Chown -> !Chmod -> !Link -> ![Exclude] -> AddFlags
- Language.Docker.Syntax: CheckArgs :: !Arguments args -> !Maybe Duration -> !Maybe Duration -> !Maybe Duration -> !Maybe Retries -> CheckArgs args
+ Language.Docker.Syntax: CheckArgs :: !Arguments args -> !Maybe Duration -> !Maybe Duration -> !Maybe Duration -> !Maybe Duration -> !Maybe Retries -> CheckArgs args
- Language.Docker.Syntax: CopyFlags :: !Chown -> !Chmod -> !Link -> !CopySource -> CopyFlags
+ Language.Docker.Syntax: CopyFlags :: !Chown -> !Chmod -> !Link -> !CopySource -> ![Exclude] -> CopyFlags
- Language.Docker.Syntax: SecretOpts :: !Maybe TargetPath -> !Maybe Text -> !Maybe Bool -> !Maybe SourcePath -> !Maybe Text -> !Maybe Text -> !Maybe Text -> SecretOpts
+ Language.Docker.Syntax: SecretOpts :: !Maybe TargetPath -> !Maybe Text -> !Maybe Bool -> !Maybe SourcePath -> !Maybe Text -> !Maybe Text -> !Maybe Text -> !Maybe Text -> SecretOpts
Files
- language-docker.cabal +114/−103
- src/Language/Docker/Parser/Copy.hs +29/−20
- src/Language/Docker/Parser/Healthcheck.hs +11/−6
- src/Language/Docker/Parser/Run.hs +10/−3
- src/Language/Docker/PrettyPrint.hs +11/−2
- src/Language/Docker/Syntax.hs +15/−5
- test/Language/Docker/ParseAddSpec.hs +32/−8
- test/Language/Docker/ParseCopySpec.hs +30/−4
- test/Language/Docker/ParseHealthcheckSpec.hs +16/−6
- test/Language/Docker/ParseRunSpec.hs +4/−2
- test/Language/Docker/PrettyPrintSpec.hs +41/−10
language-docker.cabal view
@@ -1,121 +1,132 @@-cabal-version: 2.0+cabal-version: 3.4+name: language-docker+version: 14.0.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. -name: language-docker-version: 13.0.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.-category: Development-homepage: https://github.com/hadolint/language-docker#readme-bug-reports: https://github.com/hadolint/language-docker/issues-author: Lukas Martinelli,- Pedro Tacla Yamada,- José Lorenzo Rodríguez-maintainer: lorenzo@seatgeek.com-copyright: Lukas Martinelli, Copyright (c) 2016,- Pedro Tacla Yamada, Copyright (c) 2016,- José Lorenzo Rodríguez, Copyright (c) 2017-license: GPL-3-license-file: LICENSE-build-type: Simple+category: Development+homepage: https://github.com/hadolint/language-docker#readme+bug-reports: https://github.com/hadolint/language-docker/issues+author:+ Lukas Martinelli,+ Pedro Tacla Yamada,+ José Lorenzo Rodríguez++maintainer: lorenzo@seatgeek.com+copyright:+ Lukas Martinelli, Copyright (c) 2016,+ Pedro Tacla Yamada, Copyright (c) 2016,+ José Lorenzo Rodríguez, Copyright (c) 2017++license: GPL-3.0-or-later+license-file: LICENSE+build-type: Simple extra-source-files:- README.md- test/fixtures/1.Dockerfile- test/fixtures/2.Dockerfile- test/fixtures/3.Dockerfile- test/fixtures/4.Dockerfile- test/fixtures/5.Dockerfile- test/fixtures/6.Dockerfile- test/fixtures/7.Dockerfile- test/fixtures/8.Dockerfile- test/fixtures/Dockerfile.bom.utf32be- test/fixtures/Dockerfile.bom.utf32le- test/fixtures/Dockerfile.bom.utf16be- test/fixtures/Dockerfile.bom.utf16le- test/fixtures/Dockerfile.bom.utf8+ README.md+ test/fixtures/1.Dockerfile+ test/fixtures/2.Dockerfile+ test/fixtures/3.Dockerfile+ test/fixtures/4.Dockerfile+ test/fixtures/5.Dockerfile+ test/fixtures/6.Dockerfile+ test/fixtures/7.Dockerfile+ test/fixtures/8.Dockerfile+ test/fixtures/Dockerfile.bom.utf16be+ test/fixtures/Dockerfile.bom.utf16le+ test/fixtures/Dockerfile.bom.utf32be+ test/fixtures/Dockerfile.bom.utf32le+ test/fixtures/Dockerfile.bom.utf8 source-repository head- type: git+ type: git location: https://github.com/hadolint/language-docker +common deps+ build-depends:+ , base >=4.8 && <5+ , bytestring >=0.11.5 && <0.12+ , containers >=0.6.7 && <0.7+ , data-default >=0.8.0 && <0.9+ , data-default-class >=0.2.0 && <0.3+ , megaparsec >=9.7.0 && <9.8+ , prettyprinter >=1.7.1 && <1.8+ , split >=0.2.5 && <0.3+ , text >=2.0.2 && <2.1+ , time >=1.12.2 && <1.13+ library+ import: deps exposed-modules:- Language.Docker- Language.Docker.Parser- Language.Docker.PrettyPrint- Language.Docker.Syntax+ Language.Docker+ Language.Docker.Parser+ Language.Docker.PrettyPrint+ Language.Docker.Syntax+ other-modules:- Language.Docker.Parser.Arguments- Language.Docker.Parser.Cmd- Language.Docker.Parser.Copy- Language.Docker.Parser.Expose- Language.Docker.Parser.From- Language.Docker.Parser.Healthcheck- Language.Docker.Parser.Instruction- Language.Docker.Parser.Pairs- Language.Docker.Parser.Prelude- Language.Docker.Parser.Run- Language.Docker.Syntax.Port- Language.Docker.Syntax.PortRange- Language.Docker.Syntax.Protocol- hs-source-dirs:- src+ Language.Docker.Parser.Arguments+ Language.Docker.Parser.Cmd+ Language.Docker.Parser.Copy+ Language.Docker.Parser.Expose+ Language.Docker.Parser.From+ Language.Docker.Parser.Healthcheck+ Language.Docker.Parser.Instruction+ Language.Docker.Parser.Pairs+ Language.Docker.Parser.Prelude+ Language.Docker.Parser.Run+ Language.Docker.Syntax.Port+ Language.Docker.Syntax.PortRange+ Language.Docker.Syntax.Protocol++ hs-source-dirs: src default-extensions:- OverloadedStrings- ImplicitParams- Rank2Types- ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints -fno-warn-unused-do-bind -fno-warn-orphans- build-depends:- base >=4.8 && <5- , bytestring >=0.10- , containers- , data-default- , data-default-class- , megaparsec >=9.0.0- , prettyprinter- , split >=0.2- , text- , time- default-language: GHC2021+ ImplicitParams+ OverloadedStrings+ Rank2Types + ghc-options:+ -Wall -Wcompat -Wincomplete-record-updates+ -Wincomplete-uni-patterns -Wredundant-constraints+ -fno-warn-unused-do-bind -fno-warn-orphans++ default-language: GHC2021+ test-suite hspec- type: exitcode-stdio-1.0- main-is: Spec.hs+ import: deps+ type: exitcode-stdio-1.0+ main-is: Spec.hs other-modules:- Language.Docker.IntegrationSpec- Language.Docker.ParseAddSpec- Language.Docker.ParseCmdSpec- Language.Docker.ParseCopySpec- Language.Docker.ParseExposeSpec- Language.Docker.ParseHealthcheckSpec- Language.Docker.ParsePragmaSpec- Language.Docker.ParserSpec- Language.Docker.ParseRunSpec- Language.Docker.PrettyPrintSpec- TestHelper- hs-source-dirs:- test+ Language.Docker.IntegrationSpec+ Language.Docker.ParseAddSpec+ Language.Docker.ParseCmdSpec+ Language.Docker.ParseCopySpec+ Language.Docker.ParseExposeSpec+ Language.Docker.ParseHealthcheckSpec+ Language.Docker.ParsePragmaSpec+ Language.Docker.ParserSpec+ Language.Docker.ParseRunSpec+ Language.Docker.PrettyPrintSpec+ TestHelper++ hs-source-dirs: test default-extensions:- OverloadedStrings- ImplicitParams- Rank2Types- OverloadedLists- ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints -fno-warn-unused-do-bind -fno-warn-orphans+ ImplicitParams+ OverloadedLists+ OverloadedStrings+ Rank2Types++ ghc-options:+ -Wall -Wcompat -Wincomplete-record-updates+ -Wincomplete-uni-patterns -Wredundant-constraints+ -fno-warn-unused-do-bind -fno-warn-orphans+ build-depends:- HUnit >=1.2- , QuickCheck- , base >=4.8 && <5- , bytestring >=0.10- , containers- , data-default- , data-default-class , hspec , hspec-megaparsec+ , HUnit >=1.2 , language-docker- , megaparsec >=9.0.0- , prettyprinter- , split >=0.2- , text- , time- default-language: GHC2021- build-tool-depends: hspec-discover:hspec-discover == 2.*+ , QuickCheck++ default-language: GHC2021+ build-tool-depends: hspec-discover:hspec-discover >=2 && <3
src/Language/Docker/Parser/Copy.hs view
@@ -15,6 +15,7 @@ | FlagChmod Chmod | FlagLink Link | FlagSource CopySource+ | FlagExclude Exclude | FlagInvalid (Text, Text) parseCopy :: (?esc :: Char) => Parser (Instruction Text)@@ -25,14 +26,15 @@ let chmodFlags = [c | FlagChmod c <- flags] let linkFlags = [l | FlagLink l <- flags] let sourceFlags = [f | FlagSource f <- flags]+ let excludeFlags = [e | FlagExclude e <- flags] let invalid = [i | FlagInvalid i <- flags] -- Let's do some validation on the flags- case (invalid, chownFlags, chmodFlags, linkFlags, sourceFlags) of- ((k, v) : _, _, _, _, _) -> unexpectedFlag k v- (_, _ : _ : _, _, _, _) -> customError $ DuplicateFlagError "--chown"- (_, _, _ : _ : _, _, _) -> customError $ DuplicateFlagError "--chmod"- (_, _, _, _ : _ : _, _) -> customError $ DuplicateFlagError "--link"- (_, _, _, _, _ : _ : _) -> customError $ DuplicateFlagError "--from"+ case (invalid, chownFlags, chmodFlags, linkFlags, sourceFlags, excludeFlags) of+ ((k, v) : _, _, _, _, _, _) -> unexpectedFlag k v+ (_, _ : _ : _, _, _, _, _) -> customError $ DuplicateFlagError "--chown"+ (_, _, _ : _ : _, _, _, _) -> customError $ DuplicateFlagError "--chmod"+ (_, _, _, _ : _ : _, _, _) -> customError $ DuplicateFlagError "--link"+ (_, _, _, _, _ : _ : _, _) -> customError $ DuplicateFlagError "--from" _ -> do let cho = case chownFlags of@@ -50,8 +52,8 @@ case sourceFlags of [] -> NoSource f : _ -> f- try (heredocList (\src dest -> Copy (CopyArgs src dest) (CopyFlags cho chm lnk fr)))- <|> fileList "COPY" (\src dest -> Copy (CopyArgs src dest) (CopyFlags cho chm lnk fr))+ try (heredocList (\src dest -> Copy (CopyArgs src dest) (CopyFlags cho chm lnk fr excludeFlags)))+ <|> fileList "COPY" (\src dest -> Copy (CopyArgs src dest) (CopyFlags cho chm lnk fr excludeFlags)) parseAdd :: (?esc :: Char) => Parser (Instruction Text) parseAdd = do@@ -61,15 +63,16 @@ let chownFlags = [c | FlagChown c <- flags] let chmodFlags = [c | FlagChmod c <- flags] let linkFlags = [l | FlagLink l <- flags]+ let excludeFlags = [e | FlagExclude e <- flags] let invalidFlags = [i | FlagInvalid i <- flags] notFollowedBy (string "--") <?>- "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"+ "only the --checksum, --chown, --chmod, --link, --exclude flags or the src and dest paths"+ case (invalidFlags, checksumFlags, chownFlags, linkFlags, chmodFlags, excludeFlags) 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@@ -80,11 +83,10 @@ let chm = case chmodFlags of [] -> NoChmod c : _ -> c- let lnk =- case linkFlags of- [] -> NoLink- l : _ -> l- fileList "ADD" (\src dest -> Add (AddArgs src dest) (AddFlags chk cho chm lnk))+ let lnk = case linkFlags of+ [] -> NoLink+ l : _ -> l+ fileList "ADD" (\src dest -> Add (AddArgs src dest) (AddFlags chk cho chm lnk excludeFlags)) heredocList :: (?esc :: Char) => (NonEmpty SourcePath -> TargetPath -> Instruction Text) ->@@ -124,6 +126,7 @@ <|> (FlagChown <$> try chown <?> "--chown") <|> (FlagChmod <$> try chmod <?> "--chmod") <|> (FlagLink <$> try link <?> "--link")+ <|> (FlagExclude <$> try exclude <?> "--exclude") <|> (FlagInvalid <$> try anyFlag <?> "other flag") checksum :: (?esc :: Char) => Parser Checksum@@ -154,6 +157,12 @@ void $ string "--from=" src <- someUnless "the copy source path" isNl return $ CopySource src++exclude :: (?esc :: Char) => Parser Exclude+exclude = do+ void $ string "--exclude="+ exc <- someUnless "the exclude pattern" (== ' ')+ return $ Exclude exc anyFlag :: (?esc :: Char) => Parser (Text, Text) anyFlag = do
src/Language/Docker/Parser/Healthcheck.hs view
@@ -16,6 +16,7 @@ = FlagInterval Duration | FlagTimeout Duration | FlagStartPeriod Duration+ | FlagStartInterval Duration | FlagRetries Retries | CFlagInvalid (Text, Text) @@ -42,20 +43,23 @@ let intervals = [x | FlagInterval x <- flags] let timeouts = [x | FlagTimeout x <- flags] let startPeriods = [x | FlagStartPeriod x <- flags]+ let startIntervals = [x | FlagStartInterval x <- flags] let retriesD = [x | FlagRetries x <- flags] let invalid = [x | CFlagInvalid x <- flags] -- Let's do some validation on the flags- case (invalid, intervals, timeouts, startPeriods, retriesD) of- ((k, v) : _, _, _, _, _) -> unexpectedFlag k v- (_, _ : _ : _, _, _, _) -> customError $ DuplicateFlagError "--interval"- (_, _, _ : _ : _, _, _) -> customError $ DuplicateFlagError "--timeout"- (_, _, _, _ : _ : _, _) -> customError $ DuplicateFlagError "--start-period"- (_, _, _, _, _ : _ : _) -> customError $ DuplicateFlagError "--retries"+ case (invalid, intervals, timeouts, startPeriods, startIntervals, retriesD) of+ ((k, v) : _, _, _, _, _, _) -> unexpectedFlag k v+ (_, _ : _ : _, _, _, _, _) -> customError $ DuplicateFlagError "--interval"+ (_, _, _ : _ : _, _, _, _) -> customError $ DuplicateFlagError "--timeout"+ (_, _, _, _ : _ : _, _, _) -> customError $ DuplicateFlagError "--start-period"+ (_, _, _, _, _ : _ : _, _) -> customError $ DuplicateFlagError "--start-interval"+ (_, _, _, _, _, _ : _ : _) -> customError $ DuplicateFlagError "--retries" _ -> do Cmd checkCommand <- parseCmd let interval = listToMaybe intervals let timeout = listToMaybe timeouts let startPeriod = listToMaybe startPeriods+ let startInterval = listToMaybe startIntervals let retries = listToMaybe retriesD return $ Check CheckArgs {..} @@ -64,6 +68,7 @@ (FlagInterval <$> durationFlag "--interval=" <?> "--interval") <|> (FlagTimeout <$> durationFlag "--timeout=" <?> "--timeout") <|> (FlagStartPeriod <$> durationFlag "--start-period=" <?> "--start-period")+ <|> (FlagStartInterval <$> durationFlag "--start-interval=" <?> "--start-interval") <|> (FlagRetries <$> retriesFlag <?> "--retries") <|> (CFlagInvalid <$> anyFlag <?> "no flags")
src/Language/Docker/Parser/Run.hs view
@@ -19,7 +19,8 @@ deriving (Show) data RunMountArg- = MountArgFromImage Text+ = MountArgEnv Text+ | MountArgFromImage Text | MountArgId Text | MountArgMode Text | MountArgReadOnly Bool@@ -161,13 +162,14 @@ Left e -> customError e Right as -> return $ foldr secretOpts def as where- allowed = Set.fromList ["target", "id", "required", "source", "mode", "uid", "gid"]+ allowed = Set.fromList ["target", "id", "required", "source", "mode", "uid", "gid", "env"] required = Set.empty secretOpts :: RunMountArg -> SecretOpts -> SecretOpts secretOpts (MountArgTarget path) co = co {sTarget = Just path} secretOpts (MountArgId i) co = co {sCacheId = Just i} secretOpts (MountArgRequired r) co = co {sIsRequired = Just r} secretOpts (MountArgSource path) co = co {sSource = Just path}+ secretOpts (MountArgEnv e) co = co {sEnv = Just e} secretOpts (MountArgMode m) co = co {sMode = Just m} secretOpts (MountArgUid u) co = co {sUid = Just u} secretOpts (MountArgGid g) co = co {sGid = Just g}@@ -223,7 +225,8 @@ mountArgSource, mountArgMode, mountArgUid,- mountArgGid+ mountArgGid,+ mountArgEnv ] stringArg :: (?esc :: Char) => Parser Text@@ -239,6 +242,9 @@ cacheSharing = choice [Private <$ string "private", Shared <$ string "shared", Locked <$ string "locked"] +mountArgEnv :: (?esc :: Char) => Parser RunMountArg+mountArgEnv = MountArgEnv <$> key "env" stringArg+ mountArgFromImage :: (?esc :: Char) => Parser RunMountArg mountArgFromImage = MountArgFromImage <$> key "from" stringArg @@ -317,6 +323,7 @@ mountArgUid = MountArgUid <$> key "uid" stringArg toArgName :: RunMountArg -> Text+toArgName (MountArgEnv _) = "env" toArgName (MountArgFromImage _) = "from" toArgName (MountArgGid _) = "gid" toArgName (MountArgId _) = "id"
src/Language/Docker/PrettyPrint.hs view
@@ -288,12 +288,13 @@ prettyPrintArguments c Copy CopyArgs {sourcePaths, targetPath}- CopyFlags {chmodFlag, chownFlag, linkFlag, sourceFlag} -> do+ CopyFlags {chmodFlag, chownFlag, linkFlag, sourceFlag, excludeFlags} -> do "COPY" prettyPrintChown chownFlag prettyPrintChmod chmodFlag prettyPrintLink linkFlag prettyPrintCopySource sourceFlag+ prettyPrintExcludes excludeFlags prettyPrintFileList sourcePaths targetPath Cmd c -> do "CMD"@@ -321,12 +322,13 @@ prettyPrintBaseImage b Add AddArgs {sourcePaths, targetPath}- AddFlags {checksumFlag, chownFlag, chmodFlag, linkFlag} -> do+ AddFlags {checksumFlag, chownFlag, chmodFlag, linkFlag, excludeFlags} -> do "ADD" prettyPrintChecksum checksumFlag prettyPrintChown chownFlag prettyPrintChmod chmodFlag prettyPrintLink linkFlag+ prettyPrintExcludes excludeFlags prettyPrintFileList sourcePaths targetPath Shell args -> do "SHELL"@@ -337,11 +339,18 @@ prettyPrintDuration "--interval=" interval prettyPrintDuration "--timeout=" timeout prettyPrintDuration "--start-period=" startPeriod+ prettyPrintDuration "--start-interval" startInterval prettyPrintRetries retries "CMD" prettyPrintArguments checkCommand where (>>) = spaceCat++prettyPrintExcludes :: [Exclude] -> Doc ann+prettyPrintExcludes excludes = hsep (fmap prettyPrintExclude excludes)++prettyPrintExclude :: Exclude -> Doc ann+prettyPrintExclude (Exclude e) = "--exclude=" <> pretty e spaceCat :: Doc ann -> Doc ann -> Doc ann spaceCat a Empty = a
src/Language/Docker/Syntax.hs view
@@ -192,12 +192,13 @@ { chownFlag :: !Chown, chmodFlag :: !Chmod, linkFlag :: !Link,- sourceFlag :: !CopySource+ sourceFlag :: !CopySource,+ excludeFlags :: ![Exclude] } deriving (Show, Eq, Ord) instance Default CopyFlags where- def = CopyFlags NoChown NoChmod NoLink NoSource+ def = CopyFlags NoChown NoChmod NoLink NoSource [] data AddArgs = AddArgs@@ -211,13 +212,20 @@ { checksumFlag :: !Checksum, chownFlag :: !Chown, chmodFlag :: !Chmod,- linkFlag :: !Link+ linkFlag :: !Link,+ excludeFlags :: ![Exclude] } deriving (Show, Eq, Ord) instance Default AddFlags where- def = AddFlags NoChecksum NoChown NoChmod NoLink+ def = AddFlags NoChecksum NoChown NoChmod NoLink [] +newtype Exclude+ = Exclude+ { unExclude :: Text+ }+ deriving (Show, Eq, Ord, IsString)+ data Check args = Check !(CheckArgs args) | NoCheck@@ -243,6 +251,7 @@ interval :: !(Maybe Duration), timeout :: !(Maybe Duration), startPeriod :: !(Maybe Duration),+ startInterval :: !(Maybe Duration), retries :: !(Maybe Retries) } deriving (Show, Eq, Ord, Functor)@@ -297,6 +306,7 @@ sCacheId :: !(Maybe Text), sIsRequired :: !(Maybe Bool), sSource :: !(Maybe SourcePath),+ sEnv :: !(Maybe Text), sMode :: !(Maybe Text), sUid :: !(Maybe Text), sGid :: !(Maybe Text)@@ -304,7 +314,7 @@ deriving (Eq, Show, Ord) instance Default SecretOpts where- def = SecretOpts Nothing Nothing Nothing Nothing Nothing Nothing Nothing+ def = SecretOpts Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing data CacheSharing = Shared
test/Language/Docker/ParseAddSpec.hs view
@@ -47,7 +47,7 @@ file [ Add ( AddArgs (fmap SourcePath ["http://www.example.com/foo"]) (TargetPath "bar") )- ( AddFlags (Checksum "sha256:24454f830cdd") NoChown NoChmod NoLink )+ ( 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 @@ file [ Add ( AddArgs (fmap SourcePath ["foo"]) (TargetPath "bar") )- ( AddFlags NoChecksum (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 @@ file [ Add ( AddArgs (fmap SourcePath ["foo"]) (TargetPath "bar") )- ( AddFlags NoChecksum 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 @@ file [ Add ( AddArgs (fmap SourcePath ["foo"]) (TargetPath "bar") )- ( AddFlags NoChecksum 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 @@ file [ Add ( AddArgs (fmap SourcePath ["foo"]) (TargetPath "bar") )- ( AddFlags NoChecksum (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 @@ file [ Add ( AddArgs (fmap SourcePath ["foo"]) (TargetPath "bar") )- ( AddFlags NoChecksum (Chown "root:root") (Chmod "640") NoLink )+ ( AddFlags NoChecksum (Chown "root:root") (Chmod "640") NoLink [] ) ] it "with all flags" $ let file =@@ -96,7 +96,7 @@ file [ Add ( AddArgs (fmap SourcePath ["foo"]) (TargetPath "bar") )- ( AddFlags (Checksum "sha256:24454f830cdd") (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,29 @@ (fmap SourcePath ["foo", "bar", "baz"]) (TargetPath "/app") )- ( AddFlags NoChecksum (Chown "user:group") NoChmod NoLink )+ ( AddFlags NoChecksum (Chown "user:group") NoChmod NoLink [] )+ ]+ it "with exclude flag" $+ let file = Text.unlines ["ADD --exclude=*.tmp foo bar"]+ in assertAst+ file+ [ Add+ ( AddArgs (fmap SourcePath ["foo"]) (TargetPath "bar") )+ ( AddFlags NoChecksum NoChown NoChmod NoLink [Exclude "*.tmp"] )+ ]+ it "with multiple exclude flags" $+ let file = Text.unlines ["ADD --exclude=*.tmp --exclude=*.log foo bar"]+ in assertAst+ file+ [ Add+ ( AddArgs (fmap SourcePath ["foo"]) (TargetPath "bar") )+ ( AddFlags NoChecksum NoChown NoChmod NoLink [Exclude "*.tmp", Exclude "*.log"] )+ ]+ it "with exclude and other flags" $+ let file = Text.unlines ["ADD --chown=root:root --exclude=*.tmp foo bar"]+ in assertAst+ file+ [ Add+ ( AddArgs (fmap SourcePath ["foo"]) (TargetPath "bar") )+ ( AddFlags NoChecksum (Chown "root:root") NoChmod NoLink [Exclude "*.tmp"] ) ]
test/Language/Docker/ParseCopySpec.hs view
@@ -68,7 +68,7 @@ file [ Copy ( CopyArgs [ SourcePath "foo" ] (TargetPath "bar") )- ( CopyFlags ( Chown "user:group" ) NoChmod NoLink NoSource )+ ( CopyFlags ( Chown "user:group" ) NoChmod NoLink NoSource []) ] it "with chmod flag" $ let file = Text.unlines ["COPY --chmod=777 foo bar"]@@ -76,7 +76,7 @@ file [ Copy ( CopyArgs [ SourcePath "foo" ] (TargetPath "bar") )- ( CopyFlags NoChown ( Chmod "777" ) NoLink NoSource )+ ( CopyFlags NoChown ( Chmod "777" ) NoLink NoSource []) ] it "with link flag" $ let file = Text.unlines [ "COPY --link source /target" ]@@ -84,7 +84,7 @@ file [ Copy ( CopyArgs [ SourcePath "source" ] ( TargetPath "/target" ) )- ( CopyFlags NoChown NoChmod Link NoSource )+ ( CopyFlags NoChown NoChmod Link NoSource []) ] it "with from flag" $ let file = Text.unlines ["COPY --from=node foo bar"]@@ -92,7 +92,7 @@ file [ Copy ( CopyArgs [ SourcePath "foo" ] (TargetPath "bar") )- ( CopyFlags NoChown NoChmod NoLink ( CopySource "node" ) )+ ( CopyFlags NoChown NoChmod NoLink ( CopySource "node" ) []) ] it "with all flags" $ let file =@@ -107,6 +107,7 @@ (Chmod "751") Link (CopySource "node")+ [] ) ] it "with all flags in different order" $@@ -122,7 +123,32 @@ (Chmod "644") Link (CopySource "node")+ [] )+ ]+ it "with exclude flag" $+ let file = Text.unlines ["COPY --exclude=*.tmp foo bar"]+ in assertAst+ file+ [ Copy+ ( CopyArgs [ SourcePath "foo" ] (TargetPath "bar") )+ ( CopyFlags NoChown NoChmod NoLink NoSource [Exclude "*.tmp"] )+ ]+ it "with multiple exclude flags" $+ let file = Text.unlines ["COPY --exclude=*.tmp --exclude=*.log foo bar"]+ in assertAst+ file+ [ Copy+ ( CopyArgs [ SourcePath "foo" ] (TargetPath "bar") )+ ( CopyFlags NoChown NoChmod NoLink NoSource [Exclude "*.tmp", Exclude "*.log"] )+ ]+ it "with exclude and other flags" $+ let file = Text.unlines ["COPY --chown=root:root --exclude=*.tmp foo bar"]+ in assertAst+ file+ [ Copy+ ( CopyArgs [ SourcePath "foo" ] (TargetPath "bar") )+ ( CopyFlags (Chown "root:root") NoChmod NoLink NoSource [Exclude "*.tmp"] ) ] describe "Copy with Heredocs" $ do
test/Language/Docker/ParseHealthcheckSpec.hs view
@@ -16,32 +16,39 @@ "HEALTHCHECK --interval=5m \\\nCMD curl -f http://localhost/" [ Healthcheck $ Check $- CheckArgs "curl -f http://localhost/" (Just 300) Nothing Nothing Nothing+ CheckArgs "curl -f http://localhost/" (Just 300) Nothing 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)+ CheckArgs "curl -f http://localhost/" Nothing 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+ CheckArgs "curl -f http://localhost/" Nothing (Just 10) Nothing 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+ CheckArgs "curl -f http://localhost/" Nothing Nothing (Just 120) Nothing Nothing ]+ it "parse healthcheck with start-interval" $+ assertAst+ "HEALTHCHECK --start-interval=4m CMD curl -f http://localhost/"+ [ Healthcheck $+ Check $+ CheckArgs "curl -f http://localhost/" Nothing Nothing Nothing (Just 240) Nothing+ ] it "parse healthcheck with all flags" $ assertAst- "HEALTHCHECK --start-period=2s --timeout=1m --retries=3 --interval=5s CMD curl -f http://localhost/"+ "HEALTHCHECK --start-period=2s --start-interval=10s --timeout=1m --retries=3 --interval=5s CMD curl -f http://localhost/" [ Healthcheck $ Check $ CheckArgs@@ -49,6 +56,7 @@ (Just 5) (Just 60) (Just 2)+ (Just 10) (Just $ Retries 3) ] it "parse healthcheck with no flags" $@@ -56,7 +64,7 @@ "HEALTHCHECK CMD curl -f http://localhost/" [ Healthcheck $ Check $- CheckArgs "curl -f http://localhost/" Nothing Nothing Nothing Nothing+ CheckArgs "curl -f http://localhost/" Nothing Nothing Nothing Nothing Nothing ] it "fractional arguments to flags" $@@ -66,6 +74,7 @@ " --interval=0.5s \\", " --timeout=0.1s \\", " --start-period=0.2s \\",+ " --start-interval=0.5s \\", " CMD curl -f http://localhost" ] in assertAst@@ -77,5 +86,6 @@ ( Just 0.5 ) ( Just 0.10000000149 ) ( Just 0.20000000298 )+ ( Just 0.5 ) Nothing ]
test/Language/Docker/ParseRunSpec.hs view
@@ -186,7 +186,7 @@ [ Run $ RunArgs (ArgumentsText "echo foo") flags ] it "--mount=type=secret all modifiers" $- let file = Text.unlines ["RUN --mount=type=secret,target=/foo,id=a,required,source=/bar,mode=0700,uid=0,gid=0 echo foo"]+ let file = Text.unlines ["RUN --mount=type=secret,target=/foo,env=baz,id=a,required,source=/bar,mode=0700,uid=0,gid=0 echo foo"] flags = def { mount =@@ -194,6 +194,7 @@ SecretMount ( def { sTarget = Just "/foo",+ sEnv = Just "baz", sCacheId = Just "a", sIsRequired = Just True, sSource = Just "/bar",@@ -208,7 +209,7 @@ [ Run $ RunArgs (ArgumentsText "echo foo") flags ] it "--mount=type=secret all modifiers, required explicit" $- let file = Text.unlines ["RUN --mount=type=secret,target=/foo,id=a,required=true,source=/bar,mode=0700,uid=0,gid=0 echo foo"]+ let file = Text.unlines ["RUN --mount=type=secret,target=/foo,env=baz,id=a,required=true,source=/bar,mode=0700,uid=0,gid=0 echo foo"] flags = def { mount =@@ -216,6 +217,7 @@ SecretMount ( def { sTarget = Just "/foo",+ sEnv = Just "baz", sCacheId = Just "a", sIsRequired = Just True, sSource = Just "/bar",
test/Language/Docker/PrettyPrintSpec.hs view
@@ -24,28 +24,43 @@ it "with just checksum" $ do let add = Add ( AddArgs [SourcePath "http://www.example.com/foo"] (TargetPath "bar") )- ( AddFlags ( Checksum "sha256:24454f830cdd" ) NoChown NoChmod NoLink )+ ( 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 NoChecksum ( 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 NoChecksum 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 NoChecksum 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 NoChecksum ( 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+ it "with just exclude" $ do+ let add = Add+ ( AddArgs [SourcePath "foo"] (TargetPath "bar") )+ ( AddFlags NoChecksum NoChown NoChmod NoLink [Exclude "*.tmp"] )+ in assertPretty "ADD --exclude=*.tmp foo bar" add+ it "with multiple exclude flags" $ do+ let add = Add+ ( AddArgs [SourcePath "foo"] (TargetPath "bar") )+ ( AddFlags NoChecksum NoChown NoChmod NoLink [Exclude "*.tmp", Exclude "*.log"] )+ in assertPretty "ADD --exclude=*.tmp --exclude=*.log foo bar" add+ it "with exclude and other flags" $ do+ let add = Add+ ( AddArgs [SourcePath "foo"] (TargetPath "bar") )+ ( AddFlags NoChecksum (Chown "root:root") NoChmod NoLink [Exclude "*.tmp"] )+ in assertPretty "ADD --chown=root:root --exclude=*.tmp foo bar" add describe "pretty print COPY" $ do it "with just copy" $ do@@ -56,30 +71,30 @@ it "with just chown" $ do let copy = Copy ( CopyArgs [SourcePath "foo"] (TargetPath "bar") )- ( CopyFlags ( Chown "root:root" ) NoChmod NoLink NoSource )+ ( CopyFlags ( Chown "root:root" ) NoChmod NoLink NoSource [] ) in assertPretty "COPY --chown=root:root foo bar" copy it "with just chmod" $ do let copy = Copy ( CopyArgs [SourcePath "foo"] (TargetPath "bar") )- ( CopyFlags NoChown ( Chmod "751" ) NoLink NoSource )+ ( CopyFlags NoChown ( Chmod "751" ) NoLink NoSource [] ) in assertPretty "COPY --chmod=751 foo bar" copy it "with just link" $ do let copy = Copy ( CopyArgs [SourcePath "foo"] (TargetPath "bar") )- ( CopyFlags NoChown NoChmod Link NoSource )+ ( CopyFlags NoChown NoChmod Link NoSource [] ) in assertPretty "COPY --link foo bar" copy it "with source baseimage" $ do let copy = Copy ( CopyArgs [SourcePath "foo"] (TargetPath "bar") )- ( CopyFlags NoChown NoChmod NoLink ( CopySource "baseimage" ) )+ ( CopyFlags NoChown NoChmod NoLink ( CopySource "baseimage" ) []) in assertPretty "COPY --from=baseimage foo bar" copy it "with both chown and chmod" $ do let copy = Copy ( CopyArgs [SourcePath "foo"] (TargetPath "bar") ) ( CopyFlags- ( Chown "root:root" ) ( Chmod "751" ) NoLink NoSource+ ( Chown "root:root" ) ( Chmod "751" ) NoLink NoSource [] ) in assertPretty "COPY --chown=root:root --chmod=751 foo bar" copy it "with all flags" $ do@@ -91,10 +106,26 @@ ( Chmod "751") Link ( CopySource "baseimage" )+ [] ) in assertPretty "COPY --chown=root:root --chmod=751 --link --from=baseimage foo bar" copy+ it "with just exclude" $ do+ let copy = Copy+ ( CopyArgs [SourcePath "foo"] (TargetPath "bar") )+ ( CopyFlags NoChown NoChmod NoLink NoSource [Exclude "*.tmp"] )+ in assertPretty "COPY --exclude=*.tmp foo bar" copy+ it "with multiple exclude flags" $ do+ let copy = Copy+ ( CopyArgs [SourcePath "foo"] (TargetPath "bar") )+ ( CopyFlags NoChown NoChmod NoLink NoSource [Exclude "*.tmp", Exclude "*.log"] )+ in assertPretty "COPY --exclude=*.tmp --exclude=*.log foo bar" copy+ it "with exclude and other flags" $ do+ let copy = Copy+ ( CopyArgs [SourcePath "foo"] (TargetPath "bar") )+ ( CopyFlags (Chown "root:root") NoChmod NoLink NoSource [Exclude "*.tmp"] )+ in assertPretty "COPY --chown=root:root --exclude=*.tmp foo bar" copy describe "pretty print # escape" $ do it "# escape = \\" $ do