summaryrefslogtreecommitdiff
path: root/server/Worker.hs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--server/Worker.hs86
1 files changed, 52 insertions, 34 deletions
diff --git a/server/Worker.hs b/server/Worker.hs
index 40a267b..24a774b 100644
--- a/server/Worker.hs
+++ b/server/Worker.hs
@@ -1,22 +1,18 @@
-{-# LANGUAGE DataKinds #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE LambdaCase #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE ScopedTypeVariables #-}
module Worker (linterThread, Job(..)) where
import Universum
-import Bindings.Cli.Git (gitProc)
import CheckDir (recursiveCheckDir)
-import Cli.Extras (CliConfig, ProcessFailure,
- Severity (..),
- callProcessAndLogOutput,
- prettyProcessFailure,
- readProcessAndLogStderr, runCli)
import Control.Concurrent.Async (async, link)
import Control.Concurrent.STM.TQueue
+import Control.Exception (IOException, handle)
import qualified Data.Text as T
import qualified Data.UUID as UUID
import qualified Data.UUID.V4 as UUID
@@ -27,7 +23,7 @@ import Server (Config, JobStatus (..),
tmpdir)
import System.Directory (doesDirectoryExist)
import System.FilePath ((</>))
-
+import System.Process
data Job = Job
@@ -35,20 +31,30 @@ data Job = Job
, jobOrg :: Org True
}
-linterThread :: Config True -> CliConfig -> TQueue Job -> MVar ServerState -> IO Void
-linterThread config cliconfig queue done = forever $ do
+linterThread :: Config True -> TQueue Job -> MVar ServerState -> IO Void
+linterThread config queue done = forever $ do
next <- atomically (readTQueue queue)
-- TODO: this doesn't guard against two jobs running on the same repo!
- job <- async $ runJob config next cliconfig done
- link job -- TODO: is this a good idea? will crash the server if a job fails
+ job <- async $ runJob config next done
+ -- TODO: is this a good idea? will crash the server if a job thread fails
+ link job
--- | the actual check function. forks, calls out to git to update the
+-- | the actual check function. Calls out to git to update the
-- repository, create a new worktree, lints it, then tells git to
--- delete that tree again
-runJob :: Config True -> Job -> CliConfig -> MVar ServerState -> IO (Either ProcessFailure ())
-runJob config Job {..} cliconfig done = runCli cliconfig $ do
- res <- liftIO $ runCli cliconfig $ do
- ifM (liftIO $ doesDirectoryExist gitdir)
+-- delete that tree again.
+--
+-- May occasionally be brittle (if someone else changed files)
+-- TODO: re-add proper fancy (colourful?) logging
+runJob :: Config True -> Job -> MVar ServerState -> IO ()
+runJob config Job {..} done = do
+ rand <- liftIO UUID.nextRandom
+ let workdir = "/tmp" </> ("worktree-" <> UUID.toString rand)
+
+ handle whoops
+ $ finally (lint workdir) (cleanup workdir)
+ where
+ lint workdir = do
+ ifM (doesDirectoryExist gitdir)
-- TODO: these calls fail for dumb http, add some fallback!
(callgit gitdir
[ "fetch", "origin", toString ref, "--depth", "1" ])
@@ -56,22 +62,34 @@ runJob config Job {..} cliconfig done = runCli cliconfig $ do
[ "clone", toString ref, "--bare"
, "--depth", "1", "-b", toString ref])
rev <- map T.strip -- git returns a newline here
- $ readProcessAndLogStderr Error
- $ gitProc gitdir ["rev-parse", toString ref]
- rand <- liftIO UUID.nextRandom
- let workdir = "/tmp" </> ("worktree-" <> UUID.toString rand)
- callgit gitdir [ "worktree", "add", workdir ]
- callgit workdir [ "checkout", toString ref ]
+ $ readgit' gitdir ["rev-parse", toString ref]
+ callgit gitdir [ "worktree", "add", "--force", workdir, toString ref ]
res <- liftIO $ recursiveCheckDir (orgLintconfig jobOrg) workdir (orgEntrypoint jobOrg)
+ setJobStatus done jobOrg jobRef $
+ Linted res rev
+
+ cleanup workdir = do
callgit gitdir [ "worktree", "remove", "-f", "-f", workdir ]
- pure (res, rev)
- liftIO $ setJobStatus done jobOrg jobRef $ case res of
- Right thing -> uncurry Linted thing
- Left err -> Failed (prettyProcessFailure err)
- where
+
+ whoops (error :: IOException) = do
+ -- TODO: should also log this error
+ setJobStatus done jobOrg jobRef $ Failed (show error)
+
url = repourl jobRef
ref = reporef jobRef
- callgit dir = callProcessAndLogOutput (Debug, Debug) . gitProc dir
+ callgit = callgit'
gitdir = view tmpdir config </> toString hashedname
hashedname = T.map escapeSlash url
where escapeSlash = \case { '/' -> '-'; a -> a }
+
+readgit' :: MonadIO m => FilePath -> [String] -> m Text
+readgit' dir args = map toText $
+ liftIO $ do
+ print args
+ readProcess "git" ([ "-C", toString dir ] <> args) ""
+
+callgit' :: MonadIO m => FilePath -> [String] -> m ()
+callgit' dir args =
+ liftIO $ do
+ print args
+ callProcess "git" ([ "-C", toString dir ] <> args)