packages feed

language-dockerfile 0.3.5.0 → 0.3.6.0

raw patch · 4 files changed

+184/−14 lines, 4 filesdep +aesondep +textdep +unordered-containersPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: aeson, text, unordered-containers, yaml

API changes (from Hackage documentation)

+ Language.Dockerfile.Predef: addGlob :: (MonadIO m, MonadFree EInstruction m) => String -> Destination -> m ()
+ Language.Dockerfile.Predef: appendLnIfMissing :: FilePath -> Text -> IO ()
+ Language.Dockerfile.Predef: copyGlob :: (MonadIO m, MonadFree EInstruction m) => String -> Destination -> m ()
+ Language.Dockerfile.Predef: dockerIgnore :: Text -> IO ()
+ Language.Dockerfile.Predef: nodejs :: (Monad m, MonadIO m, MonadFree EInstruction m) => m ()
+ Language.Dockerfile.Predef: nodejs' :: (Monad m, MonadIO m, MonadFree EInstruction m) => String -> m () -> m ()
+ Language.Dockerfile.Predef: stackBuild :: (Monad m, MonadIO m, MonadFree EInstruction m) => m ()
+ Language.Dockerfile.Predef: stackBuild' :: (Monad m, MonadIO m, MonadFree EInstruction m) => String -> m () -> m ()
- Language.Dockerfile: add :: forall m_asPi. MonadFree EInstruction m_asPi => Source -> Destination -> m_asPi ()
+ Language.Dockerfile: add :: forall m_atJ6. MonadFree EInstruction m_atJ6 => Source -> Destination -> m_atJ6 ()
- Language.Dockerfile: arg :: forall m_asPX. MonadFree EInstruction m_asPX => String -> m_asPX ()
+ Language.Dockerfile: arg :: forall m_atJL. MonadFree EInstruction m_atJL => String -> m_atJL ()
- Language.Dockerfile: cmdArgs :: forall m_asPC. MonadFree EInstruction m_asPC => Arguments -> m_asPC ()
+ Language.Dockerfile: cmdArgs :: forall m_atJq. MonadFree EInstruction m_atJq => Arguments -> m_atJq ()
- Language.Dockerfile: comment :: forall m_asQ0. MonadFree EInstruction m_asQ0 => String -> m_asQ0 ()
+ Language.Dockerfile: comment :: forall m_atJO. MonadFree EInstruction m_atJO => String -> m_atJO ()
- Language.Dockerfile: copy :: forall m_asPv. MonadFree EInstruction m_asPv => Source -> Destination -> m_asPv ()
+ Language.Dockerfile: copy :: forall m_atJj. MonadFree EInstruction m_atJj => Source -> Destination -> m_atJj ()
- Language.Dockerfile: embed :: forall m_asQ6. MonadFree EInstruction m_asQ6 => [InstructionPos] -> m_asQ6 ()
+ Language.Dockerfile: embed :: forall m_atJU. MonadFree EInstruction m_atJU => [InstructionPos] -> m_atJU ()
- Language.Dockerfile: entrypointArgs :: forall m_asPO. MonadFree EInstruction m_asPO => Arguments -> m_asPO ()
+ Language.Dockerfile: entrypointArgs :: forall m_atJC. MonadFree EInstruction m_atJC => Arguments -> m_atJC ()
- Language.Dockerfile: env :: forall m_asPU. MonadFree EInstruction m_asPU => Pairs -> m_asPU ()
+ Language.Dockerfile: env :: forall m_atJI. MonadFree EInstruction m_atJI => Pairs -> m_atJI ()
- Language.Dockerfile: expose :: forall m_asPI. MonadFree EInstruction m_asPI => Ports -> m_asPI ()
+ Language.Dockerfile: expose :: forall m_atJw. MonadFree EInstruction m_atJw => Ports -> m_atJw ()
- Language.Dockerfile: from :: forall m_asOB. MonadFree EInstruction m_asOB => EBaseImage -> m_asOB ()
+ Language.Dockerfile: from :: forall m_atIp. MonadFree EInstruction m_atIp => EBaseImage -> m_atIp ()
- Language.Dockerfile: label :: forall m_asPp. MonadFree EInstruction m_asPp => Pairs -> m_asPp ()
+ Language.Dockerfile: label :: forall m_atJd. MonadFree EInstruction m_atJd => Pairs -> m_atJd ()
- Language.Dockerfile: maintainer :: forall m_asPR. MonadFree EInstruction m_asPR => String -> m_asPR ()
+ Language.Dockerfile: maintainer :: forall m_atJF. MonadFree EInstruction m_atJF => String -> m_atJF ()
- Language.Dockerfile: onBuildRaw :: forall m_asQ3. MonadFree EInstruction m_asQ3 => Instruction -> m_asQ3 ()
+ Language.Dockerfile: onBuildRaw :: forall m_atJR. MonadFree EInstruction m_atJR => Instruction -> m_atJR ()
- Language.Dockerfile: runArgs :: forall m_asPz. MonadFree EInstruction m_asPz => Arguments -> m_asPz ()
+ Language.Dockerfile: runArgs :: forall m_atJn. MonadFree EInstruction m_atJn => Arguments -> m_atJn ()
- Language.Dockerfile: stopSignal :: forall m_asPs. MonadFree EInstruction m_asPs => String -> m_asPs ()
+ Language.Dockerfile: stopSignal :: forall m_atJg. MonadFree EInstruction m_atJg => String -> m_atJg ()
- Language.Dockerfile: user :: forall m_asPm. MonadFree EInstruction m_asPm => String -> m_asPm ()
+ Language.Dockerfile: user :: forall m_atJa. MonadFree EInstruction m_atJa => String -> m_atJa ()
- Language.Dockerfile: volume :: forall m_asPL. MonadFree EInstruction m_asPL => String -> m_asPL ()
+ Language.Dockerfile: volume :: forall m_atJz. MonadFree EInstruction m_atJz => String -> m_atJz ()
- Language.Dockerfile: workdir :: forall m_asPF. MonadFree EInstruction m_asPF => Directory -> m_asPF ()
+ Language.Dockerfile: workdir :: forall m_atJt. MonadFree EInstruction m_atJt => Directory -> m_atJt ()
- Language.Dockerfile.EDSL: add :: forall m_asPi. MonadFree EInstruction m_asPi => Source -> Destination -> m_asPi ()
+ Language.Dockerfile.EDSL: add :: forall m_atJ6. MonadFree EInstruction m_atJ6 => Source -> Destination -> m_atJ6 ()
- Language.Dockerfile.EDSL: arg :: forall m_asPX. MonadFree EInstruction m_asPX => String -> m_asPX ()
+ Language.Dockerfile.EDSL: arg :: forall m_atJL. MonadFree EInstruction m_atJL => String -> m_atJL ()
- Language.Dockerfile.EDSL: cmdArgs :: forall m_asPC. MonadFree EInstruction m_asPC => Arguments -> m_asPC ()
+ Language.Dockerfile.EDSL: cmdArgs :: forall m_atJq. MonadFree EInstruction m_atJq => Arguments -> m_atJq ()
- Language.Dockerfile.EDSL: comment :: forall m_asQ0. MonadFree EInstruction m_asQ0 => String -> m_asQ0 ()
+ Language.Dockerfile.EDSL: comment :: forall m_atJO. MonadFree EInstruction m_atJO => String -> m_atJO ()
- Language.Dockerfile.EDSL: copy :: forall m_asPv. MonadFree EInstruction m_asPv => Source -> Destination -> m_asPv ()
+ Language.Dockerfile.EDSL: copy :: forall m_atJj. MonadFree EInstruction m_atJj => Source -> Destination -> m_atJj ()
- Language.Dockerfile.EDSL: embed :: forall m_asQ6. MonadFree EInstruction m_asQ6 => [InstructionPos] -> m_asQ6 ()
+ Language.Dockerfile.EDSL: embed :: forall m_atJU. MonadFree EInstruction m_atJU => [InstructionPos] -> m_atJU ()
- Language.Dockerfile.EDSL: entrypointArgs :: forall m_asPO. MonadFree EInstruction m_asPO => Arguments -> m_asPO ()
+ Language.Dockerfile.EDSL: entrypointArgs :: forall m_atJC. MonadFree EInstruction m_atJC => Arguments -> m_atJC ()
- Language.Dockerfile.EDSL: env :: forall m_asPU. MonadFree EInstruction m_asPU => Pairs -> m_asPU ()
+ Language.Dockerfile.EDSL: env :: forall m_atJI. MonadFree EInstruction m_atJI => Pairs -> m_atJI ()
- Language.Dockerfile.EDSL: expose :: forall m_asPI. MonadFree EInstruction m_asPI => Ports -> m_asPI ()
+ Language.Dockerfile.EDSL: expose :: forall m_atJw. MonadFree EInstruction m_atJw => Ports -> m_atJw ()
- Language.Dockerfile.EDSL: from :: forall m_asOB. MonadFree EInstruction m_asOB => EBaseImage -> m_asOB ()
+ Language.Dockerfile.EDSL: from :: forall m_atIp. MonadFree EInstruction m_atIp => EBaseImage -> m_atIp ()
- Language.Dockerfile.EDSL: label :: forall m_asPp. MonadFree EInstruction m_asPp => Pairs -> m_asPp ()
+ Language.Dockerfile.EDSL: label :: forall m_atJd. MonadFree EInstruction m_atJd => Pairs -> m_atJd ()
- Language.Dockerfile.EDSL: maintainer :: forall m_asPR. MonadFree EInstruction m_asPR => String -> m_asPR ()
+ Language.Dockerfile.EDSL: maintainer :: forall m_atJF. MonadFree EInstruction m_atJF => String -> m_atJF ()
- Language.Dockerfile.EDSL: onBuildRaw :: forall m_asQ3. MonadFree EInstruction m_asQ3 => Instruction -> m_asQ3 ()
+ Language.Dockerfile.EDSL: onBuildRaw :: forall m_atJR. MonadFree EInstruction m_atJR => Instruction -> m_atJR ()
- Language.Dockerfile.EDSL: runArgs :: forall m_asPz. MonadFree EInstruction m_asPz => Arguments -> m_asPz ()
+ Language.Dockerfile.EDSL: runArgs :: forall m_atJn. MonadFree EInstruction m_atJn => Arguments -> m_atJn ()
- Language.Dockerfile.EDSL: stopSignal :: forall m_asPs. MonadFree EInstruction m_asPs => String -> m_asPs ()
+ Language.Dockerfile.EDSL: stopSignal :: forall m_atJg. MonadFree EInstruction m_atJg => String -> m_atJg ()
- Language.Dockerfile.EDSL: user :: forall m_asPm. MonadFree EInstruction m_asPm => String -> m_asPm ()
+ Language.Dockerfile.EDSL: user :: forall m_atJa. MonadFree EInstruction m_atJa => String -> m_atJa ()
- Language.Dockerfile.EDSL: volume :: forall m_asPL. MonadFree EInstruction m_asPL => String -> m_asPL ()
+ Language.Dockerfile.EDSL: volume :: forall m_atJz. MonadFree EInstruction m_atJz => String -> m_atJz ()
- Language.Dockerfile.EDSL: workdir :: forall m_asPF. MonadFree EInstruction m_asPF => Directory -> m_asPF ()
+ Language.Dockerfile.EDSL: workdir :: forall m_atJt. MonadFree EInstruction m_atJt => Directory -> m_atJt ()

Files

language-dockerfile.cabal view
@@ -1,9 +1,9 @@--- This file has been generated from package.yaml by hpack version 0.14.0.+-- This file has been generated from package.yaml by hpack version 0.17.0. -- -- see: https://github.com/sol/hpack  name:           language-dockerfile-version:        0.3.5.0+version:        0.3.6.0 synopsis:       Dockerfile linter, parser, pretty-printer and embedded DSL description:     Forked from @hadolint@.                 .@@ -61,9 +61,17 @@     , template-haskell     , th-lift     , th-lift-instances+    , text+    , yaml+    , aeson+    , Glob+    , unordered-containers+    , directory+    , filepath   exposed-modules:       Language.Dockerfile       Language.Dockerfile.Parser+      Language.Dockerfile.Predef       Language.Dockerfile.PrettyPrint       Language.Dockerfile.Normalize       Language.Dockerfile.Rules@@ -97,6 +105,13 @@     , template-haskell     , th-lift     , th-lift-instances+    , text+    , yaml+    , aeson+    , Glob+    , unordered-containers+    , directory+    , filepath     , language-dockerfile   buildable: False   if flag(dockerfmt)@@ -122,6 +137,13 @@     , template-haskell     , th-lift     , th-lift-instances+    , text+    , yaml+    , aeson+    , Glob+    , unordered-containers+    , directory+    , filepath     , language-dockerfile   buildable: False   if flag(hadolint)@@ -135,7 +157,7 @@   main-is: Test.hs   hs-source-dirs:       src-    , test+      test   build-depends:       ShellCheck     , base >=4.8 && <5@@ -149,6 +171,13 @@     , template-haskell     , th-lift     , th-lift-instances+    , text+    , yaml+    , aeson+    , Glob+    , unordered-containers+    , directory+    , filepath     , HUnit >=1.2     , test-framework     , test-framework-hunit@@ -163,6 +192,7 @@       Language.Dockerfile.Lexer       Language.Dockerfile.Normalize       Language.Dockerfile.Parser+      Language.Dockerfile.Predef       Language.Dockerfile.PrettyPrint       Language.Dockerfile.Rules       Language.Dockerfile.Syntax@@ -194,6 +224,13 @@     , template-haskell     , th-lift     , th-lift-instances+    , text+    , yaml+    , aeson+    , Glob+    , unordered-containers+    , directory+    , filepath     , hspec     , QuickCheck     , language-dockerfile
src/Language/Dockerfile/Lexer.hs view
@@ -7,12 +7,24 @@ lexer :: Token.TokenParser () lexer = Token.makeTokenParser style -- style   where-    names = ["FROM","ADD","RUN","WORKDIR","EXPOSE","VOLUME","ENTRYPOINT","MAINTAINER","ENV","LABEL","USER","STOPSIGNAL","CMD", "ONBUILD", "ARG"]-    style = emptyDef {-        -- Token.commentLine = "#",-             -- ,-             Token.reservedNames = names-             }+    names =+      [ "FROM"+      , "ADD"+      , "RUN"+      , "WORKDIR"+      , "EXPOSE"+      , "VOLUME"+      , "ENTRYPOINT"+      , "MAINTAINER"+      , "ENV"+      , "LABEL"+      , "USER"+      , "STOPSIGNAL"+      , "CMD"+      , "ONBUILD"+      , "ARG"+      ]+    style = emptyDef {Token.caseSensitive = False, Token.reservedNames = names}  reserved :: String -> Parser () reserved = Token.reserved lexer
+ src/Language/Dockerfile/Predef.hs view
@@ -0,0 +1,115 @@+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings     #-}+module Language.Dockerfile.Predef+  where++import           Control.Monad+import           Control.Monad.Free.Class+import           Control.Monad.IO.Class+import           Data.Aeson                     (Value (..))+import qualified Data.HashMap.Strict            as HashMap+import           Data.Maybe+import           Data.Monoid+import           Data.Text                      (Text)+import qualified Data.Text                      as Text+import qualified Data.Text.IO                   as Text+import qualified Data.Yaml                      as Yaml+import           System.Directory+import           System.FilePath+import qualified System.FilePath.Glob           as Glob++import           Language.Dockerfile+import           Language.Dockerfile.EDSL.Types++appendLnIfMissing :: FilePath -> Text -> IO ()+appendLnIfMissing fp cts = do+    e <- doesFileExist fp+    unless e (Text.writeFile fp "")+    txt <- Text.lines <$> Text.readFile fp+    unless (cts `elem` txt) $+        Text.writeFile fp (Text.unlines (txt <> [cts]))++dockerIgnore :: Text -> IO ()+dockerIgnore = appendLnIfMissing ".dockerignore"++addGlob+  :: (MonadIO m, MonadFree EInstruction m) =>+     String -> Destination -> m ()+addGlob pattern dest = do+    fs <- liftIO $ do+        fs <- Glob.glob pattern+        cwd <- getCurrentDirectory+        let fs' = map (makeRelative cwd . normalise) fs+        forM fs' $ \f -> do+             isdir <- doesDirectoryExist f+             return $ if isdir+                 then (f <> "/", dest <> takeBaseName f)+                 else (f, dest <> takeBaseName f)+    forM_ fs (uncurry add)++copyGlob+  :: (MonadIO m, MonadFree EInstruction m) =>+     String -> Destination -> m ()+copyGlob = addGlob++stackBuild+  :: (Monad m, MonadIO m,+      MonadFree EInstruction m) =>+     m ()+stackBuild = do+    sts <- liftIO getStackYamlResolver+    stackBuild' sts (return ())+  where+    getStackYamlResolver = do+        mhm <- Yaml.decodeFile "./stack.yaml" :: IO (Maybe Value)+        return $ fromMaybe "latest" $ do+            hm <- mhm+            o <- case hm of+                Object o -> return o+                _ -> Nothing+            rs <- HashMap.lookup "resolver" o+            toString rs+      where+        toString (String m) = Just (Text.unpack m)+        toString _ = Nothing++stackBuild'+  :: (Monad m, MonadIO m,+      MonadFree EInstruction m) =>+     String -> m () -> m ()+stackBuild' tag extra = do+    liftIO $ dockerIgnore ".stack-work"+    liftIO $ dockerIgnore ".cabal-sandbox"++    from ("fpco" `tagged` tag)+    extra+    add "./package.yaml" "/app/package.yaml"+    addGlob "./*.cabal" "/app/"+    add "./stack.yaml" "/app/stack.yaml"+    workdir "/app/"+    run "stack build --only-dependencies"+    add "." "/app/stack.yaml"+    run "stack build"++nodejs+  :: (Monad m, MonadIO m,+      MonadFree EInstruction m) =>+     m ()+nodejs = nodejs' "6" (return ())++nodejs'+  :: (Monad m, MonadIO m,+      MonadFree EInstruction m) =>+     String -> m () -> m ()+nodejs' tag extra = do+    liftIO $ dockerIgnore "node_modules"+    liftIO $ dockerIgnore "bower_components"++    from ("node" `tagged` tag)+    extra+    add "./package.json" "/app/package.json"+    workdir "/app/"+    run "npm install"+    add "." "/app/"+    cmd "npm start"
test/Language/Dockerfile/ParserSpec.hs view
@@ -7,8 +7,14 @@ import           Text.Parsec  spec :: Spec-spec =-    describe "expose" $ do-        it "should handle number ports" $ do-            let content = "EXPOSE 8080"-            parse expose "" content `shouldBe` Right (Expose (Ports [8080]))+spec = do+  describe "expose" $ do+    it "should handle number ports" $ do+      let content = "EXPOSE 8080"+      parse expose "" content `shouldBe` Right (Expose (Ports [8080]))+  describe "syntax" $ do+    it+      "should handle lowercase instructions (#7 - https://github.com/beijaflor-io/haskell-language-dockerfile/issues/7)" $ do+      let content = "from ubuntu"+      parse dockerfile "" content `shouldBe`+        Right [InstructionPos (From (UntaggedImage "ubuntu")) "" 1]