diff options
| author | Roman Smrž <roman.smrz@seznam.cz> | 2022-11-30 21:30:26 +0100 | 
|---|---|---|
| committer | Roman Smrž <roman.smrz@seznam.cz> | 2022-12-02 21:25:24 +0100 | 
| commit | 55cead7b8d31f5e5fe09df0588abf736a465c0eb (patch) | |
| tree | e32319e97ea5dacb0f052a464fe3f1bdfb3ce504 | |
| parent | 3005c10b971856862a51cfa18dc42c79b272952d (diff) | |
First build test using cabal
| -rw-r--r-- | minici.cabal | 17 | ||||
| -rw-r--r-- | src/Main.hs | 90 | 
2 files changed, 105 insertions, 2 deletions
| diff --git a/minici.cabal b/minici.cabal index 55bad96..1dce029 100644 --- a/minici.cabal +++ b/minici.cabal @@ -21,12 +21,29 @@ maintainer:         roman.smrz@seznam.cz  executable minici      main-is:          Main.hs +    ghc-options:      -Wall      -- Modules included in this executable, other than Main.      -- other-modules:      -- LANGUAGE extensions used by modules in this package. +    default-extensions:  ExistentialQuantification +                         FlexibleContexts +                         FlexibleInstances +                         GADTs +                         GeneralizedNewtypeDeriving +                         ImportQualifiedPost +                         LambdaCase +                         MultiParamTypeClasses +                         OverloadedStrings +                         ScopedTypeVariables +                         TupleSections +                         TypeApplications      -- other-extensions:      build-depends:    base ^>=4.15.1.0 +                    , directory >=1.3 && <1.4 +                    , mtl >=2.2 && <2.3 +                    , process >=1.6 && <1.7 +                    , text >=1.2 && <1.3      hs-source-dirs:   src      default-language: Haskell2010 diff --git a/src/Main.hs b/src/Main.hs index 65ae4a0..32c0288 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -1,4 +1,90 @@ -module Main where +module Main (main) where + +import Control.Monad +import Control.Monad.Except + +import Data.Text (Text) +import Data.Text qualified as T + +import System.Directory +import System.Exit +import System.IO +import System.Process + +data Job = Job +    { jobName :: JobName +    , jobRecipe :: [CreateProcess] +    , jobArtifacts :: [(ArtifactName, CreateProcess)] +    } + +data JobOutput = JobOutput +    { outName :: JobName +    , outStatus :: Bool +    , outArtifacts :: [(ArtifactName, FilePath)] +    } +    deriving (Show) + +data JobName = JobName Text +    deriving (Eq, Ord, Show) + +data ArtifactName = ArtifactName Text +    deriving (Eq, Ord, Show) + + +runJob :: String -> Job -> IO JobOutput +runJob cid job = do +    [path] <- lines <$> readProcess "mktemp" ["-d", "-t", "minici.XXXXXXXXXX"] "" + +    "" <- readProcess "git" ["--work-tree=" <> path, "restore", "--source=" <> cid, "--", "."] "" + +    res <- runExceptT $ do +        forM_ (jobRecipe job) $ \p -> do +            (Just hin, Just hout, Just herr, hp) <- liftIO $ createProcess p +                { cwd = Just path +                , std_in = CreatePipe +                , std_out = CreatePipe +                , std_err = CreatePipe +                } +            liftIO $ hClose hin +            exit <- liftIO $ waitForProcess hp +            liftIO $ hClose hout +            liftIO $ hClose herr + +            when (exit /= ExitSuccess) $ +                throwError () + +    removeDirectoryRecursive $ path + +    return JobOutput +        { outName = jobName job +        , outStatus = res == Right () +        , outArtifacts = [] +        } + + +cabalJob :: JobName -> [ArtifactName] -> Job +cabalJob name artifacts = Job +    { jobName = name +    , jobRecipe = [ proc "cabal" ["build", "--ghc-option=-Werror"] ] +    , jobArtifacts = map (\(ArtifactName aname) -> (ArtifactName "bin", proc "cabal" ["list-bin", T.unpack aname])) artifacts +    }  main :: IO () -main = putStrLn "Hello, Haskell!" +main = do +    commits <- map (fmap (drop 1) . (span (/=' '))) . lines <$> +        readProcess "git" ["log", "--pretty=oneline", "--first-parent", "--reverse", "origin/master..HEAD"] "" +    forM_ commits $ \(cid, desc) -> do +        let descLen = length desc +            desc' = if descLen <= 50 then desc <> replicate (50 - descLen) ' ' +                                     else take 49 desc <> "…" +            shortCid = take 7 cid + +        putStr $ shortCid <> " " <> desc' <> " " +        hFlush stdout +        runJob cid (cabalJob (JobName "build") $ map (ArtifactName . T.pack) []) >>= \case +            out | outStatus out -> do +                putStr "\ESC[92m✓\ESC[0m" +            _ -> do +                putStr "\ESC[91m✗\ESC[0m" +                putStr $ "\r\ESC[91m" <> shortCid <> "\ESC[0m" +        putStrLn "" |