summaryrefslogtreecommitdiff
path: root/server/Server.hs
blob: 93bfb30b78659eba7a9fcd8da147c97eed1d5d8b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
{-# LANGUAGE DataKinds           #-}
{-# LANGUAGE DeriveAnyClass      #-}
{-# LANGUAGE DeriveGeneric       #-}
{-# LANGUAGE KindSignatures      #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell     #-}
{-# LANGUAGE TypeApplications    #-}
{-# LANGUAGE TypeFamilies        #-}
{-# LANGUAGE TypeOperators       #-}

module Server (loadConfig, Config(..), RemoteRef(..), State, registry, jobs, JobStatus(..),
                    setJobStatus,defaultState,setRegistry) where

import           CheckDir             (DirResult)
import           Control.Concurrent   (MVar, modifyMVar_)
import           Data.Aeson           (FromJSON, ToJSON, eitherDecode)
import qualified Data.ByteString.Lazy as LB
import           Data.Map             (Map)
import qualified Data.Map             as M
import           Data.Text            (Text)
import           Data.UUID            (UUID)
import           GHC.Generics         (Generic)
import           Lens.Micro           (over)
import           Lens.Micro.TH
import           LintConfig           (LintConfig')


-- | a reference in a remote git repository
data RemoteRef = RemoteRef
  { repourl :: Text
  , reporef :: Text
  } deriving (Generic, FromJSON, Eq, Ord)

type family ConfigRes (b :: Bool) a where
  ConfigRes True a = a
  ConfigRes False a = FilePath

-- | the server's configuration
data Config l = Config
  { tmpdir     :: FilePath
  -- ^ dir to clone git things in
  , port       :: Int
  -- ^ port to bind to
  , entrypoint :: FilePath
  , lintconfig :: ConfigRes l LintConfig'
  }

data JobStatus =
  Pending | Linted DirResult | Failed Text
  deriving (Generic, ToJSON)

data State = State
  { _jobs     :: Map RemoteRef JobStatus
  , _registry :: Map UUID RemoteRef
  }

makeLenses ''State

defaultState :: State
defaultState = State mempty mempty


loadConfig :: Config False -> IO (Config True)
loadConfig config = do
  loaded <- LB.readFile (lintconfig config) >>= \res ->
      case eitherDecode res :: Either String LintConfig' of
        Left err   -> error $ "config file invalid: " <> err
        Right file -> pure file
  pure $ config { lintconfig = loaded }


setJobStatus :: MVar State -> RemoteRef -> JobStatus -> IO ()
setJobStatus mvar ref status = modifyMVar_ mvar
  $ pure . over jobs (M.insert ref status)

setRegistry :: MVar State -> UUID -> RemoteRef -> IO ()
setRegistry mvar uuid ref = modifyMVar_ mvar
  $ pure . over registry (M.insert uuid ref)