hadolint 1.2.5 → 1.2.6
raw patch · 3 files changed
+85/−13 lines, 3 filesdep +directorydep +filepathdep +yamlPVP ok
version bump matches the API change (PVP)
Dependencies added: directory, filepath, yaml
API changes (from Hackage documentation)
Files
- README.md +26/−6
- app/Main.hs +54/−5
- hadolint.cabal +5/−2
README.md view
@@ -55,6 +55,30 @@ stack install ``` +## Configure++hadolint supports specifying the ignored rules using a configuration file. The configuration+file should be in `yaml` format. This is one valid configuration file as an example:++```yaml+ignored:+ - DL3000+ - SC1010+```++Configuration files can be used globally or per project. By default, hadolint will look for+a configuration file in the current directory with the name `.hadolint.yaml`++The global configuration file should be placed in the folder specified by `XDG_CONFIG_HOME`,+with the name `hadolint.yaml`. In summary, the following locations are valid for the configuration+file, in order or preference:++- `$PWD/.hadolint.yaml`+- `$XDG_CONFIG_HOME/hadolint.yaml`+- `~/.config/hadolint.yaml`++In windows, the `%LOCALAPPDATA%` environment variable is used instead of `XDG_CONFIG_HOME`+ ## Integrations To get most of `hadolint` it is useful to integrate it as a check to your CI@@ -178,15 +202,11 @@ ./integration_test.sh ``` -### Parsing--The Dockerfile is parsed using [Parsec](https://wiki.haskell.org/Parsec) and is-using the lexer `Lexer.hs` and parser `Parser.hs`.- ### AST Dockerfile syntax is fully described in the [Dockerfile reference][]. Just take-a look at `Syntax.hs` to see the AST definition.+a look at [Syntax.hs](https://www.stackage.org/haddock/nightly-2018-01-07/language-docker-2.0.1/Language-Docker-Syntax.html)+in the `language-docker` project to see the AST definition. ## Alternatives
app/Main.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE DeriveGeneric #-} module Main where @@ -8,14 +9,22 @@ import Language.Docker.Syntax import Control.Applicative+import Control.Monad (filterM) import Data.List (sort)+import Data.Maybe (listToMaybe) import Data.Semigroup import qualified Data.Version as V (showVersion)+import qualified Data.Yaml as Yaml import Development.GitRev (gitDescribe)+import GHC.Generics import Options.Applicative hiding (ParseError) import Paths_hadolint (version) -- version from hadolint.cabal file+import System.Directory+ (XdgDirectory(..), doesFileExist, getCurrentDirectory,+ getXdgDirectory) import System.Environment (getArgs) import System.Exit hiding (die)+import System.FilePath ((</>)) import Text.Parsec (ParseError) type IgnoreRule = String@@ -24,8 +33,14 @@ { showVersion :: Bool , ignoreRules :: [IgnoreRule] , dockerfiles :: [String]- }+ } deriving (Show) +newtype ConfigFile = ConfigFile+ { ignored :: [IgnoreRule]+ } deriving (Show, Eq, Generic)++instance Yaml.FromJSON ConfigFile+ ignoreFilter :: [IgnoreRule] -> RuleCheck -> Bool ignoreFilter ignoredRules (RuleCheck (Metadata code _ _) _ _ _) = code `notElem` ignoredRules @@ -38,12 +53,16 @@ parseOptions :: Parser LintOptions parseOptions =- LintOptions <$> switch (long "version" <> short 'v' <> help "Show version") <*>- many (strOption (long "ignore" <> help "Ignore rule" <> metavar "RULECODE")) <*>+ LintOptions <$> -- CLI options parser definition+ switch (long "version" <> short 'v' <> help "Show version") <*>+ many+ (strOption+ (long "ignore" <> help "Ignore rule. If present, config file is ignored" <>+ metavar "RULECODE")) <*> many (argument str (metavar "DOCKERFILE...")) main :: IO ()-main = execParser opts >>= lint+main = execParser opts >>= applyConfig >>= lint where opts = info@@ -51,6 +70,36 @@ (fullDesc <> progDesc "Lint Dockerfile for errors and best practices" <> header "hadolint - Dockerfile Linter written in Haskell") +applyConfig :: LintOptions -> IO LintOptions+applyConfig o@(LintOptions _ (_:_) _) = return o+applyConfig o = do+ theConfig <- findConfig+ case theConfig of+ Nothing -> return o+ Just config -> parseAndApply config+ where+ findConfig = do+ localConfigFile <- (</> ".hadolint.yaml") <$> getCurrentDirectory+ configFile <- getXdgDirectory XdgConfig "hadolint.yaml"+ listToMaybe <$> filterM doesFileExist [localConfigFile, configFile]+ parseAndApply config = do+ result <- Yaml.decodeFileEither config+ case result of+ Left err -> printError err config+ Right (ConfigFile ignore) -> return o {ignoreRules = ignore}+ printError err config =+ case err of+ Yaml.AesonException _ ->+ error $+ "Error parsing your config file in '" +++ config +++ "':\nIt should contain an 'ignored' key with a list of strings. For example:\n\n" +++ unlines ["ignored:", "\t- DL3000", "\t- SC1099"]+ _ ->+ error $+ "Error parsing your config file in '" +++ config ++ "': " ++ Yaml.prettyPrintParseException err+ -- | Support UNIX convention of passing "-" instead of "/dev/stdin" parseFilename :: String -> String parseFilename "-" = "/dev/stdin"@@ -70,7 +119,7 @@ lint :: LintOptions -> IO () lint (LintOptions True _ _) = putStrLn getVersion >> exitSuccess lint (LintOptions _ _ []) = putStrLn "Please provide a Dockerfile" >> exitFailure-lint (LintOptions _ ignored dfiles) = mapM_ (lintDockerfile ignored) dfiles+lint (LintOptions _ ignore dfiles) = mapM_ (lintDockerfile ignore) dfiles checkAst :: (RuleCheck -> Bool) -> Either ParseError Dockerfile -> IO () checkAst checkFilter ast =
hadolint.cabal view
@@ -2,10 +2,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 12b5c22d1b02f401b49c4ddf5c4493e77538d2e3d78e138808e187953593aebe+-- hash: b7ec9fd2a32901585b1deea9c996ddfae7761f1993dcb550b22499da35d8706a name: hadolint-version: 1.2.5+version: 1.2.6 synopsis: Dockerfile Linter JavaScript API description: A smarter Dockerfile linter that helps you build best practice Docker images. category: Development@@ -49,11 +49,14 @@ app build-depends: base >=4.8 && <5+ , directory >=1.3.0+ , filepath , gitrev >=1.3.1 , hadolint , language-docker >=2.0.0 , optparse-applicative <=0.14.0.0 , parsec >=3.1+ , yaml if !(os(osx)) ld-options: -static -pthread other-modules: