hadolint 2.11.0 → 2.12.0
raw patch · 12 files changed
+105/−34 lines, 12 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Hadolint.Pragma: globalIgnored :: Fold (InstructionPos Text) (Set RuleCode)
Files
- README.md +19/−6
- hadolint.cabal +4/−2
- src/Hadolint/Pragma.hs +30/−21
- src/Hadolint/Process.hs +4/−0
- src/Hadolint/Rule/DL3029.hs +2/−1
- src/Hadolint/Rule/DL3032.hs +2/−1
- src/Hadolint/Rule/DL3040.hs +2/−1
- src/Hadolint/Rule/DL3047.hs +1/−1
- test/Hadolint/PragmaSpec.hs +27/−0
- test/Hadolint/Rule/DL3029Spec.hs +6/−1
- test/Hadolint/Rule/DL3032Spec.hs +3/−0
- test/Hadolint/Rule/DL3040Spec.hs +5/−0
README.md view
@@ -333,6 +333,19 @@ The comment "inline ignores" applies only to the statement following it. +## Global ignores++Rules can also be ignored on a per-file basis using the global ignore pragma.+It works just like inline ignores, excep that it applies to the whole file+instead of just the next line.++```dockerfile+# hadolint global ignore=DL3003,DL3006,SC1035+FROM ubuntu++RUN cd /tmp && echo "foo"+```+ ## Linting Labels Hadolint is able to check if specific labels are present and conform@@ -439,16 +452,16 @@ | [DL3005](https://github.com/hadolint/hadolint/wiki/DL3005) | Error | Do not use apt-get dist-upgrade. | | [DL3006](https://github.com/hadolint/hadolint/wiki/DL3006) | Warning | Always tag the version of an image explicitly. | | [DL3007](https://github.com/hadolint/hadolint/wiki/DL3007) | Warning | Using latest is prone to errors if the image will ever update. Pin the version explicitly to a release tag. |-| [DL3008](https://github.com/hadolint/hadolint/wiki/DL3008) | Warning | Pin versions in apt-get install. |+| [DL3008](https://github.com/hadolint/hadolint/wiki/DL3008) | Warning | Pin versions in `apt-get install`. | | [DL3009](https://github.com/hadolint/hadolint/wiki/DL3009) | Info | Delete the apt-get lists after installing something. | | [DL3010](https://github.com/hadolint/hadolint/wiki/DL3010) | Info | Use ADD for extracting archives into an image. | | [DL3011](https://github.com/hadolint/hadolint/wiki/DL3011) | Error | Valid UNIX ports range from 0 to 65535. | | [DL3012](https://github.com/hadolint/hadolint/wiki/DL3012) | Error | Multiple `HEALTHCHECK` instructions. | | [DL3013](https://github.com/hadolint/hadolint/wiki/DL3013) | Warning | Pin versions in pip. | | [DL3014](https://github.com/hadolint/hadolint/wiki/DL3014) | Warning | Use the `-y` switch. |-| [DL3015](https://github.com/hadolint/hadolint/wiki/DL3015) | Info | Avoid additional packages by specifying --no-install-recommends. |+| [DL3015](https://github.com/hadolint/hadolint/wiki/DL3015) | Info | Avoid additional packages by specifying `--no-install-recommends`. | | [DL3016](https://github.com/hadolint/hadolint/wiki/DL3016) | Warning | Pin versions in `npm`. |-| [DL3018](https://github.com/hadolint/hadolint/wiki/DL3018) | Warning | Pin versions in apk add. Instead of `apk add <package>` use `apk add <package>=<version>`. |+| [DL3018](https://github.com/hadolint/hadolint/wiki/DL3018) | Warning | Pin versions in `apk add`. Instead of `apk add <package>` use `apk add <package>=<version>`. | | [DL3019](https://github.com/hadolint/hadolint/wiki/DL3019) | Info | Use the `--no-cache` switch to avoid the need to use `--update` and remove `/var/cache/apk/*` when done installing packages. | | [DL3020](https://github.com/hadolint/hadolint/wiki/DL3020) | Error | Use `COPY` instead of `ADD` for files and folders. | | [DL3021](https://github.com/hadolint/hadolint/wiki/DL3021) | Error | `COPY` with more than 2 arguments requires the last argument to end with `/` |@@ -456,7 +469,7 @@ | [DL3023](https://github.com/hadolint/hadolint/wiki/DL3023) | Error | `COPY --from` cannot reference its own `FROM` alias | | [DL3024](https://github.com/hadolint/hadolint/wiki/DL3024) | Error | `FROM` aliases (stage names) must be unique | | [DL3025](https://github.com/hadolint/hadolint/wiki/DL3025) | Warning | Use arguments JSON notation for CMD and ENTRYPOINT arguments |-| [DL3026](https://github.com/hadolint/hadolint/wiki/DL3026) | Error | Use only an allowed registry in the FROM image |+| [DL3026](https://github.com/hadolint/hadolint/wiki/DL3026) | Error | Use only an allowed registry in the `FROM image` | | [DL3027](https://github.com/hadolint/hadolint/wiki/DL3027) | Warning | Do not use `apt` as it is meant to be a end-user tool, use `apt-get` or `apt-cache` instead | | [DL3028](https://github.com/hadolint/hadolint/wiki/DL3028) | Warning | Pin versions in gem install. Instead of `gem install <gem>` use `gem install <gem>:<version>` | | [DL3029](https://github.com/hadolint/hadolint/wiki/DL3029) | Warning | Do not use --platform flag with FROM. |@@ -490,7 +503,7 @@ | [DL3059](https://github.com/hadolint/hadolint/wiki/DL3059) | Info | Multiple consecutive `RUN` instructions. Consider consolidation. | | [DL3060](https://github.com/hadolint/hadolint/wiki/DL3060) | Info | `yarn cache clean` missing after `yarn install` was run. | | [DL3061](https://github.com/hadolint/hadolint/wiki/DL3061) | Error | Invalid instruction order. Dockerfile must begin with `FROM`, `ARG` or comment. |-| [DL4000](https://github.com/hadolint/hadolint/wiki/DL4000) | Error | MAINTAINER is deprecated. |+| [DL4000](https://github.com/hadolint/hadolint/wiki/DL4000) | Error | `MAINTAINER` is deprecated. | | [DL4001](https://github.com/hadolint/hadolint/wiki/DL4001) | Warning | Either use Wget or Curl but not both. | | [DL4003](https://github.com/hadolint/hadolint/wiki/DL4003) | Warning | Multiple `CMD` instructions found. | | [DL4004](https://github.com/hadolint/hadolint/wiki/DL4004) | Error | Multiple `ENTRYPOINT` instructions found. |@@ -640,7 +653,7 @@ [best practice]: https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices [shellcheck]: https://github.com/koalaman/shellcheck [release page]: https://github.com/hadolint/hadolint/releases/latest-[haskell]: https://www.haskell.org/platform/+[haskell]: https://www.haskell.org/downloads/ [stack]: http://docs.haskellstack.org/en/stable/install_and_upgrade.html [integration]: docs/INTEGRATION.md [code review platform integrations]: docs/INTEGRATION.md#code-review
hadolint.cabal view
@@ -1,11 +1,11 @@ cabal-version: 2.0 --- This file has been generated from package.yaml by hpack version 0.34.6.+-- This file has been generated from package.yaml by hpack version 0.34.7. -- -- see: https://github.com/sol/hpack name: hadolint-version: 2.11.0+version: 2.12.0 synopsis: Dockerfile Linter JavaScript API description: A smarter Dockerfile linter that helps you build best practice Docker images. category: Development@@ -309,6 +309,8 @@ ImplicitParams OverloadedLists ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints -optP-Wno-nonportable-include-path -flate-dmd-anal+ build-tool-depends:+ hspec-discover:hspec-discover ==2.* build-depends: HUnit >=1.2 , HsYAML
src/Hadolint/Pragma.hs view
@@ -1,5 +1,6 @@ module Hadolint.Pragma ( ignored,+ globalIgnored, parseIgnorePragma, parseShell )@@ -26,20 +27,33 @@ _ -> acc parse acc _ = acc +globalIgnored :: Foldl.Fold (InstructionPos Text) (Set.Set RuleCode)+globalIgnored = Foldl.Fold parse mempty id+ where+ parse acc InstructionPos { instruction = Comment comment } =+ case parseGlobalIgnorePragma comment of+ Just ignores@(_ : _) -> Set.union ( Set.fromList . fmap RuleCode $ ignores ) acc+ _ -> acc+ parse acc _ = acc+ parseIgnorePragma :: Text -> Maybe [Text]-parseIgnorePragma =- Megaparsec.parseMaybe commentParser+parseIgnorePragma = Megaparsec.parseMaybe ignoreParser -commentParser :: Megaparsec.Parsec Void Text [Text]-commentParser =- do- spaces- >> string "hadolint"- >> spaces1- >> string "ignore="- >> spaces- >> Megaparsec.sepBy1 ruleName (spaces >> string "," >> spaces)+parseGlobalIgnorePragma :: Text -> Maybe [Text]+parseGlobalIgnorePragma = Megaparsec.parseMaybe globalIgnoreParser +ignoreParser :: Megaparsec.Parsec Void Text [Text]+ignoreParser = hadolintPragma >> ignore++globalIgnoreParser :: Megaparsec.Parsec Void Text [Text]+globalIgnoreParser = hadolintPragma >> string "global" >> spaces1 >> ignore++ignore :: Megaparsec.Parsec Void Text [Text]+ignore = string "ignore" >> spaces >> string "=" >> spaces >> ruleList++ruleList :: Megaparsec.Parsec Void Text [Text]+ruleList = Megaparsec.sepBy1 ruleName ( spaces >> string "," >> spaces )+ ruleName :: Megaparsec.ParsecT Void Text Identity (Megaparsec.Tokens Text) ruleName = Megaparsec.takeWhile1P Nothing (\c -> c `elem` Set.fromList "DLSC0123456789") @@ -48,19 +62,14 @@ parseShell = Megaparsec.parseMaybe shellParser shellParser :: Megaparsec.Parsec Void Text Text-shellParser =- do- spaces- >> string "hadolint"- >> spaces1- >> string "shell"- >> spaces- >> string "="- >> spaces- >> shellName+shellParser = hadolintPragma >> string "shell" >> spaces >> string "=" >> spaces >> shellName shellName :: Megaparsec.ParsecT Void Text Identity (Megaparsec.Tokens Text) shellName = Megaparsec.takeWhile1P Nothing (/= '\n')+++hadolintPragma :: Megaparsec.Parsec Void Text Text+hadolintPragma = spaces >> string "hadolint" >> spaces1 string :: Megaparsec.Tokens Text
src/Hadolint/Process.hs view
@@ -82,6 +82,8 @@ data AnalisisResult = AnalisisResult { -- | The set of ignored rules per line ignored :: SMap.IntMap (Set.Set RuleCode),+ -- | The set of globally ignored rules+ globalIgnored :: Set.Set RuleCode, -- | A set of failures collected for reach rule failed :: Failures }@@ -93,6 +95,7 @@ shouldKeep CheckFailure {line, code} | disableIgnorePragma config = True+ | code `Set.member` globalIgnored = False | otherwise = Just True /= do ignoreList <- SMap.lookup line ignored return $ code `Set.member` ignoreList@@ -103,6 +106,7 @@ analyze config = AnalisisResult <$> Hadolint.Pragma.ignored+ <*> Hadolint.Pragma.globalIgnored <*> Foldl.premap parseShell (failures config) parseShell :: InstructionPos Text.Text -> InstructionPos Shell.ParsedShell
src/Hadolint/Rule/DL3029.hs view
@@ -1,5 +1,6 @@ module Hadolint.Rule.DL3029 (rule) where +import qualified Data.Text as Text import Hadolint.Rule import Language.Docker.Syntax @@ -10,6 +11,6 @@ severity = DLWarningC message = "Do not use --platform flag with FROM" - check (From BaseImage {platform = Just p}) = p == "$BUILDPLATFORM"+ check (From BaseImage {platform = Just p}) = "BUILDPLATFORM" `Text.isInfixOf` p || "TARGETPLATFORM" `Text.isInfixOf` p check _ = True {-# INLINEABLE rule #-}
src/Hadolint/Rule/DL3032.hs view
@@ -24,5 +24,6 @@ check _ = True yumInstall = Shell.cmdHasArgs "yum" ["install"]- yumClean = Shell.cmdHasArgs "yum" ["clean", "all"]+ yumClean args = Shell.cmdHasArgs "yum" ["clean", "all"] args+ || Shell.cmdHasArgs "rm" ["-rf", "/var/cache/yum/*"] args {-# INLINEABLE dl3032 #-}
src/Hadolint/Rule/DL3040.hs view
@@ -26,6 +26,7 @@ ) dnfInstall cmdName = Shell.cmdHasArgs cmdName ["install"]- dnfClean cmdName = Shell.cmdHasArgs cmdName ["clean", "all"]+ dnfClean cmdName args = Shell.cmdHasArgs cmdName ["clean", "all"] args + || Shell.cmdHasArgs "rm" ["-rf", "/var/cache/yum/*"] args dnfCmds = ["dnf", "microdnf"] {-# INLINEABLE dl3040 #-}
src/Hadolint/Rule/DL3047.hs view
@@ -16,7 +16,7 @@ code = "DL3047" severity = DLInfoC message =- "Avoid use of wget without progress bar. Use `wget --progress=dot:giga <url>`.\+ "Avoid use of wget without progress bar. Use `wget --progress=dot:giga <url>`. \ \Or consider using `-q` or `-nv` (shorthands for `--quiet` or `--no-verbose`)." check (Run (RunArgs args _)) = foldArguments (Shell.noCommands forgotProgress) args
test/Hadolint/PragmaSpec.hs view
@@ -11,6 +11,7 @@ let ?config = def describe "Rules can be ignored with inline comments" $ do+ it "ignores single rule" $ let dockerFile = [ "FROM ubuntu",@@ -18,6 +19,7 @@ "USER root" ] in ruleCatchesNot "DL3002" $ Text.unlines dockerFile+ it "ignores only the given rule" $ let dockerFile = [ "FROM scratch",@@ -25,6 +27,7 @@ "USER root" ] in ruleCatches "DL3002" $ Text.unlines dockerFile+ it "ignores only the given rule, when multiple passed" $ let dockerFile = [ "FROM scratch",@@ -32,6 +35,7 @@ "USER root" ] in ruleCatchesNot "DL3002" $ Text.unlines dockerFile+ it "ignores the rule only if directly above the instruction" $ let dockerFile = [ "# hadolint ignore=DL3001,DL3002",@@ -39,6 +43,7 @@ "USER root" ] in ruleCatches "DL3002" $ Text.unlines dockerFile+ it "won't ignore the rule if passed invalid rule names" $ let dockerFile = [ "FROM scratch",@@ -46,10 +51,32 @@ "USER root" ] in ruleCatches "DL3002" $ Text.unlines dockerFile+ it "ignores multiple rules correctly, even with some extra whitespace" $ let dockerFile = [ "FROM node as foo", "# hadolint ignore=DL3023, DL3021",+ "COPY --from=foo bar baz ."+ ]+ in do+ ruleCatchesNot "DL3023" $ Text.unlines dockerFile+ ruleCatchesNot "DL3021" $ Text.unlines dockerFile+++ describe "Rules can be ignored globally with global ignore pragma" $ do++ it "ignores single rule" $+ let dockerFile =+ [ "# hadolint global ignore=DL3002",+ "FROM ubuntu",+ "USER root"+ ]+ in ruleCatchesNot "DL3002" $ Text.unlines dockerFile++ it "ignores multiple rules correctly, even with some extra whitespace" $+ let dockerFile =+ [ "# hadolint global ignore = DL3023 , DL3021",+ "FROM node as foo", "COPY --from=foo bar baz ." ] in do
test/Hadolint/Rule/DL3029Spec.hs view
@@ -12,4 +12,9 @@ describe "DL3029 - Do not use --platform flag with FROM." $ do it "explicit platform flag" $ ruleCatches "DL3029" "FROM --platform=linux debian:jessie" it "no platform flag" $ ruleCatchesNot "DL3029" "FROM debian:jessie"- it "allow platform $BUILDPLATFORM flag" $ ruleCatchesNot "DL3029" "FROM --platform=$BUILDPLATFORM debian:jessie"+ it "allows platform $BUILDPLATFORM flag" $ ruleCatchesNot "DL3029" "FROM --platform=$BUILDPLATFORM debian:jessie"+ it "allows platform \"$BUILDPLATFORM\" flag" $ ruleCatchesNot "DL3029" "FROM --platform=\"$BUILDPLATFORM\" debian:jessie"+ it "allows platform ${BUILDPLATFORM} flag" $ ruleCatchesNot "DL3029" "FROM --platform=${BUILDPLATFORM} debian:jessie"+ it "allows platform ${BUILDPLATFORM:-} flag" $ ruleCatchesNot "DL3029" "FROM --platform=${BUILDPLATFORM:-} debian:jessie"+ it "allows platform \"${BUILDPLATFORM:-}\" flag" $ ruleCatchesNot "DL3029" "FROM --platform=\"${BUILDPLATFORM:-}\" debian:jessie"+ it "allows platform $TARGETPLATFORM flag" $ ruleCatchesNot "DL3029" "FROM --platform=$TARGETPLATFORM debian:jessie"
test/Hadolint/Rule/DL3032Spec.hs view
@@ -18,3 +18,6 @@ ruleCatchesNot "DL3032" "RUN bash -c `# not even a yum command`" onBuildRuleCatchesNot "DL3032" "RUN yum install -y mariadb-10.4 && yum clean all" onBuildRuleCatchesNot "DL3032" "RUN bash -c `# not even a yum command`"+ it "ok with rm -rf /var/cache/yum/*" $ do+ ruleCatchesNot "DL3032" "RUN yum install -y mariadb-10.4 && rm -rf /var/cache/yum/*"+ onBuildRuleCatchesNot "DL3032" "RUN yum install -y mariadb-10.4 && rm -rf /var/cache/yum/*"
test/Hadolint/Rule/DL3040Spec.hs view
@@ -23,3 +23,8 @@ onBuildRuleCatchesNot "DL3040" "RUN dnf install -y mariadb-10.4 && dnf clean all" onBuildRuleCatchesNot "DL3040" "RUN microdnf install -y mariadb-10.4 && microdnf clean all" onBuildRuleCatchesNot "DL3040" "RUN notdnf install mariadb"+ it "ok with rm /var/cache/yum" $ do+ ruleCatchesNot "DL3040" "RUN dnf install -y mariadb-10.4 && rm -rf /var/cache/yum/*"+ ruleCatchesNot "DL3040" "RUN microdnf install -y mariadb-10.4 && rm -rf /var/cache/yum/*"+ onBuildRuleCatchesNot "DL3040" "RUN dnf install -y mariadb-10.4 && rm -rf /var/cache/yum/*"+ onBuildRuleCatchesNot "DL3040" "RUN microdnf install -y mariadb-10.4 && rm -rf /var/cache/yum/*"