Skip to content

Commit

Permalink
Major refactor for maintainability (#565)
Browse files Browse the repository at this point in the history
* Refactoring hadolint to use as single pass check

The single pass is provided by the foldl library

* Fixing some bugs intruced after the refactor

* performance tweaks and code simplification

* minor tweaks for clarity

* bumping version to 2.0 as the refactor is a pretty major API change

* documentation and applying hlint suggestions
  • Loading branch information
lorenzo committed Mar 14, 2021
1 parent 6eaea2a commit 4db396c
Show file tree
Hide file tree
Showing 72 changed files with 3,049 additions and 2,239 deletions.
50 changes: 25 additions & 25 deletions app/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
module Main where

import Control.Applicative
import Data.String (IsString (fromString))
import qualified Data.List.NonEmpty as NonEmpty
import Data.Maybe
import qualified Data.Sequence as Seq
import qualified Data.Set as Set
import Data.String (IsString (fromString))
import qualified Data.Version
import qualified Development.GitRev
import qualified Hadolint
import Data.Maybe
import Options.Applicative
( Parser,
action,
Expand Down Expand Up @@ -108,37 +108,37 @@ parseOptions =
errorList =
many
( strOption
( long "error"
<> help "Make the rule `RULECODE` have the level `error`"
<> metavar "RULECODE"
)
( long "error"
<> help "Make the rule `RULECODE` have the level `error`"
<> metavar "RULECODE"
)
)

warningList =
many
( strOption
( long "warning"
<> help "Make the rule `RULECODE` have the level `warning`"
<> metavar "RULECODE"
)
( long "warning"
<> help "Make the rule `RULECODE` have the level `warning`"
<> metavar "RULECODE"
)
)

infoList =
many
( strOption
( long "info"
<> help "Make the rule `RULECODE` have the level `info`"
<> metavar "RULECODE"
)
( long "info"
<> help "Make the rule `RULECODE` have the level `info`"
<> metavar "RULECODE"
)
)

styleList =
many
( strOption
( long "style"
<> help "Make the rule `RULECODE` have the level `style`"
<> metavar "RULECODE"
)
( long "style"
<> help "Make the rule `RULECODE` have the level `style`"
<> metavar "RULECODE"
)
)

ignoreList =
Expand Down Expand Up @@ -172,19 +172,19 @@ parseOptions =
)

noFailure :: Hadolint.Result s e -> Bool
noFailure (Hadolint.Result Seq.Empty Seq.Empty) = True
noFailure (Hadolint.Result _ Seq.Empty Seq.Empty) = True
noFailure _ = False

exitProgram :: CommandOptions -> Hadolint.Result s e -> IO()
exitProgram :: Foldable f => CommandOptions -> f (Hadolint.Result s e) -> IO ()
exitProgram cmd res
| noFail cmd = exitSuccess
| noFail cmd = exitSuccess
| Hadolint.shallSkipErrorStatus (format cmd) = exitSuccess
| noFailure res = exitSuccess
| otherwise = exitFailure
| all noFailure res = exitSuccess
| otherwise = exitFailure

runLint :: CommandOptions -> Hadolint.LintOptions -> NonEmpty.NonEmpty String -> IO()
runLint :: CommandOptions -> Hadolint.LintOptions -> NonEmpty.NonEmpty String -> IO ()
runLint cmd conf files = do
res <- Hadolint.lint conf files
res <- Hadolint.lintIO conf files
noColorEnv <- lookupEnv "NO_COLOR"
let noColor = nocolor cmd || isJust noColorEnv
Hadolint.printResults (format cmd) noColor res
Expand Down
74 changes: 67 additions & 7 deletions hadolint.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ cabal-version: 2.0
--
-- see: https://github.com/sol/hpack
--
-- hash: 86f9cfdca9eaa4b16ecd3292135ace357a7834b995350e9ce3b70acf1f9cfa63
-- hash: 0894de2541e49590657147243a298ff0585a0acb41aa2dbaf9cf5666f1b25348

name: hadolint
version: 1.23.0
version: 2.0.0
synopsis: Dockerfile Linter JavaScript API
description: A smarter Dockerfile linter that helps you build best practice Docker images.
category: Development
Expand Down Expand Up @@ -40,21 +40,76 @@ library
Hadolint.Formatter.Format
Hadolint.Formatter.Json
Hadolint.Formatter.TTY
Hadolint.Ignore
Hadolint.Lint
Hadolint.Rules
Hadolint.Process
Hadolint.Rule
Hadolint.Rule.DL3000
Hadolint.Rule.DL3001
Hadolint.Rule.DL3002
Hadolint.Rule.DL3003
Hadolint.Rule.DL3004
Hadolint.Rule.DL3005
Hadolint.Rule.DL3006
Hadolint.Rule.DL3007
Hadolint.Rule.DL3008
Hadolint.Rule.DL3009
Hadolint.Rule.DL3010
Hadolint.Rule.DL3011
Hadolint.Rule.DL3013
Hadolint.Rule.DL3014
Hadolint.Rule.DL3015
Hadolint.Rule.DL3016
Hadolint.Rule.DL3017
Hadolint.Rule.DL3018
Hadolint.Rule.DL3019
Hadolint.Rule.DL3020
Hadolint.Rule.DL3021
Hadolint.Rule.DL3022
Hadolint.Rule.DL3023
Hadolint.Rule.DL3024
Hadolint.Rule.DL3025
Hadolint.Rule.DL3026
Hadolint.Rule.DL3027
Hadolint.Rule.DL3028
Hadolint.Rule.DL3029
Hadolint.Rule.DL3030
Hadolint.Rule.DL3031
Hadolint.Rule.DL3032
Hadolint.Rule.DL3033
Hadolint.Rule.DL3034
Hadolint.Rule.DL3035
Hadolint.Rule.DL3036
Hadolint.Rule.DL3037
Hadolint.Rule.DL3038
Hadolint.Rule.DL3039
Hadolint.Rule.DL3040
Hadolint.Rule.DL3041
Hadolint.Rule.DL3042
Hadolint.Rule.DL3043
Hadolint.Rule.DL3044
Hadolint.Rule.DL3045
Hadolint.Rule.DL3046
Hadolint.Rule.DL4000
Hadolint.Rule.DL4001
Hadolint.Rule.DL4003
Hadolint.Rule.DL4004
Hadolint.Rule.DL4005
Hadolint.Rule.DL4006
Hadolint.Rule.Shellcheck
Hadolint.Shell
other-modules:
Paths_hadolint
autogen-modules:
Paths_hadolint
hs-source-dirs:
src
ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints -optP-Wno-nonportable-include-path
default-extensions: OverloadedStrings NamedFieldPuns DeriveGeneric DeriveAnyClass RecordWildCards StrictData ScopedTypeVariables PatternSynonyms
ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints -optP-Wno-nonportable-include-path -flate-dmd-anal
build-depends:
HsYAML
, ShellCheck >=0.7.1
, aeson
, async
, base >=4.8 && <5
, bytestring
, colourista
Expand All @@ -63,6 +118,7 @@ library
, deepseq ==1.4.4.*
, directory >=1.3.0
, filepath
, foldl
, ilist
, language-docker >=9.1.3 && <10
, megaparsec >=9.0.0
Expand All @@ -79,7 +135,8 @@ executable hadolint
Paths_hadolint
hs-source-dirs:
app
ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints -optP-Wno-nonportable-include-path -O2 -threaded -rtsopts "-with-rtsopts=-N5 -A4m"
default-extensions: OverloadedStrings NamedFieldPuns DeriveGeneric DeriveAnyClass RecordWildCards StrictData ScopedTypeVariables PatternSynonyms
ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints -optP-Wno-nonportable-include-path -flate-dmd-anal -O2 -threaded -rtsopts "-with-rtsopts=-N5 -A4m"
build-depends:
base >=4.8 && <5
, containers
Expand All @@ -102,14 +159,17 @@ test-suite hadolint-unit-tests
Paths_hadolint
hs-source-dirs:
test
ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints -optP-Wno-nonportable-include-path
default-extensions: OverloadedStrings NamedFieldPuns DeriveGeneric DeriveAnyClass RecordWildCards StrictData ScopedTypeVariables PatternSynonyms
ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints -optP-Wno-nonportable-include-path -flate-dmd-anal
build-depends:
HUnit >=1.2
, HsYAML
, ShellCheck >=0.7.1
, aeson
, base >=4.8 && <5
, bytestring >=0.10
, containers
, foldl
, hadolint
, hspec
, language-docker >=9.1.3 && <10
Expand Down
16 changes: 14 additions & 2 deletions package.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: hadolint
version: "1.23.0"
version: "2.0.0"
synopsis: Dockerfile Linter JavaScript API
description: A smarter Dockerfile linter that helps you build best practice Docker images.
category: Development
Expand All @@ -22,10 +22,20 @@ ghc-options:
- -Wincomplete-uni-patterns
- -Wredundant-constraints
- -optP-Wno-nonportable-include-path
- -flate-dmd-anal
dependencies:
- base >=4.8 && <5
- megaparsec >= 9.0.0
- language-docker >=9.1.3 && < 10
default-extensions:
- OverloadedStrings
- NamedFieldPuns
- DeriveGeneric
- DeriveAnyClass
- RecordWildCards
- StrictData
- ScopedTypeVariables
- PatternSynonyms
library:
source-dirs: src
generated-other-modules:
Expand All @@ -36,7 +46,6 @@ library:
- &split split >=0.2
- HsYAML
- aeson
- async
- bytestring
- colourista
- containers
Expand All @@ -49,6 +58,7 @@ library:
- parallel
- text
- void
- foldl
executables:
hadolint:
main: Main.hs
Expand Down Expand Up @@ -80,3 +90,5 @@ tests:
- hspec
- hadolint
- HsYAML
- foldl
- containers
40 changes: 36 additions & 4 deletions src/Hadolint.hs
Original file line number Diff line number Diff line change
@@ -1,12 +1,44 @@
module Hadolint
( module Hadolint.Lint,
module Hadolint.Rules,
module Hadolint.Process,
module Hadolint.Config,
Result (..)
Result (..),
OutputFormat (..),
shallSkipErrorStatus,
printResults,
)
where

import Data.Text (Text)
import Hadolint.Config
import Hadolint.Lint
import Hadolint.Rules
import qualified Hadolint.Formatter.Checkstyle
import qualified Hadolint.Formatter.Codacy
import qualified Hadolint.Formatter.Codeclimate
import Hadolint.Formatter.Format (Result (..))
import qualified Hadolint.Formatter.Json
import qualified Hadolint.Formatter.TTY
import Hadolint.Lint
import Hadolint.Process
import Language.Docker.Parser (DockerfileError)

data OutputFormat
= Json
| TTY
| CodeclimateJson
| GitlabCodeclimateJson
| Checkstyle
| Codacy
deriving (Show, Eq)

shallSkipErrorStatus :: OutputFormat -> Bool
shallSkipErrorStatus format = format `elem` [CodeclimateJson, Codacy]

printResults :: Foldable f => OutputFormat -> Bool -> f (Result Text DockerfileError) -> IO ()
printResults format nocolor allResults =
case format of
TTY -> Hadolint.Formatter.TTY.printResults allResults nocolor
Json -> Hadolint.Formatter.Json.printResults allResults
Checkstyle -> Hadolint.Formatter.Checkstyle.printResults allResults
CodeclimateJson -> Hadolint.Formatter.Codeclimate.printResults allResults
GitlabCodeclimateJson -> Hadolint.Formatter.Codeclimate.printGitlabResults allResults
Codacy -> Hadolint.Formatter.Codacy.printResults allResults
Loading

0 comments on commit 4db396c

Please sign in to comment.