1
0
Fork 0

Make checks pass

This commit is contained in:
Malte 2023-01-16 03:57:11 +01:00
parent cf82d34507
commit 6b7bc306a8
36 changed files with 150 additions and 140 deletions

View file

@ -5,7 +5,7 @@ module Backend (
import Backend.Config (BackendConfig, readConfig, users) import Backend.Config (BackendConfig, readConfig, users)
import Control.Concurrent.STM.TQueue (TQueue, newTQueueIO, writeTQueue) import Control.Concurrent.STM.TQueue (TQueue, newTQueueIO, writeTQueue)
import Control.Exception (try) import Control.Exception (try)
import qualified Data.Aeson as Aeson import Data.Aeson qualified as Aeson
import Data.Map (lookup) import Data.Map (lookup)
import Data.Password.Argon2 import Data.Password.Argon2
import Frontend.Route (BackendRoute (..), FrontendRoute, fullRouteEncoder) import Frontend.Route (BackendRoute (..), FrontendRoute, fullRouteEncoder)

View file

@ -14,7 +14,7 @@ import Kassandra.RemoteBackendWidget (
remoteBackendWidget, remoteBackendWidget,
) )
import Kassandra.Types import Kassandra.Types
import qualified Reflex.Dom as D import Reflex.Dom qualified as D
import Relude.Extra.Newtype import Relude.Extra.Newtype
-- This runs in a monad that can be run on the client or the server. -- This runs in a monad that can be run on the client or the server.

View file

@ -9,7 +9,7 @@ import Prelude hiding (id, (.))
import Control.Category import Control.Category
-} -}
import qualified Control.Category import Control.Category qualified
import Data.Text (Text) import Data.Text (Text)
-- import Data.Functor.Identity -- import Data.Functor.Identity

View file

@ -2,8 +2,8 @@
module Kassandra.AgendaWidget (agendaWidget) where module Kassandra.AgendaWidget (agendaWidget) where
import qualified Data.Sequence as Seq import Data.Sequence qualified as Seq
import qualified Data.Sequence.NonEmpty as NESeq import Data.Sequence.NonEmpty qualified as NESeq
import Kassandra.BaseWidgets (br, button, icon) import Kassandra.BaseWidgets (br, button, icon)
import Kassandra.Calendar ( import Kassandra.Calendar (
CalendarEvent ( CalendarEvent (
@ -26,8 +26,8 @@ import Kassandra.ListElementWidget (AdhocContext (..), definitionElementWidget,
import Kassandra.ReflexUtil (listWithGaps) import Kassandra.ReflexUtil (listWithGaps)
import Kassandra.TextEditWidget (createTextWidget) import Kassandra.TextEditWidget (createTextWidget)
import Kassandra.Types (StandardWidget, Widget, getAppState) import Kassandra.Types (StandardWidget, Widget, getAppState)
import qualified Reflex as R import Reflex qualified as R
import qualified Reflex.Dom as D import Reflex.Dom qualified as D
agendaWidget :: StandardWidget t m r e => m () agendaWidget :: StandardWidget t m r e => m ()
agendaWidget = do agendaWidget = do

View file

@ -6,8 +6,8 @@ module Kassandra.BaseWidgets (
) where ) where
import Kassandra.Types (Widget) import Kassandra.Types (Widget)
import qualified Reflex as R import Reflex qualified as R
import qualified Reflex.Dom as D import Reflex.Dom qualified as D
import Relude.Extra.Bifunctor (secondF) import Relude.Extra.Bifunctor (secondF)
br :: D.DomBuilder t m => m () br :: D.DomBuilder t m => m ()

View file

@ -20,7 +20,7 @@ import GHC.Stack (
import Reflex as R import Reflex as R
import System.IO.Unsafe (unsafePerformIO) import System.IO.Unsafe (unsafePerformIO)
import qualified Debug.Trace as Trace import Debug.Trace qualified as Trace
import Relude.Extra.Bifunctor import Relude.Extra.Bifunctor
import Relude.Extra.Enum import Relude.Extra.Enum
import Say import Say

View file

@ -28,8 +28,8 @@ import Kassandra.Util (
lookupTask, lookupTask,
tellSingleton, tellSingleton,
) )
import qualified Reflex as R import Reflex qualified as R
import qualified Reflex.Dom as D import Reflex.Dom qualified as D
tellSelected :: (MonadIO m, WriteApp t m e) => R.Event t (Seq DefinitionElement) -> m () tellSelected :: (MonadIO m, WriteApp t m e) => R.Event t (Seq DefinitionElement) -> m ()
tellSelected = tellSingleton . fmap (_Typed @AppStateChange % _Typed @SelectState #) <=< logRShow Info tellSelected = tellSingleton . fmap (_Typed @AppStateChange % _Typed @SelectState #) <=< logRShow Info

View file

@ -9,9 +9,9 @@ module Kassandra.ListElementWidget (
selectWidget, selectWidget,
) where ) where
import qualified Data.HashMap.Strict as HashMap import Data.HashMap.Strict qualified as HashMap
import qualified Data.Sequence as Seq import Data.Sequence qualified as Seq
import qualified Data.Set as Set import Data.Set qualified as Set
import Kassandra.BaseWidgets (br, button, icon) import Kassandra.BaseWidgets (br, button, icon)
import Kassandra.Calendar (CalendarList, completed) import Kassandra.Calendar (CalendarList, completed)
import Kassandra.Config ( import Kassandra.Config (
@ -40,8 +40,8 @@ import Kassandra.TaskWidget (
import Kassandra.TextEditWidget (createTextWidget) import Kassandra.TextEditWidget (createTextWidget)
import Kassandra.Types (AppStateChange, DataChange (SetEventList), StandardWidget, TaskInfos, TaskState, getAppState, getSelectState, getTasks) import Kassandra.Types (AppStateChange, DataChange (SetEventList), StandardWidget, TaskInfos, TaskState, getAppState, getSelectState, getTasks)
import Kassandra.Util (tellNewTask, tellSingleton) import Kassandra.Util (tellNewTask, tellSingleton)
import qualified Reflex as R import Reflex qualified as R
import qualified Reflex.Dom as D import Reflex.Dom qualified as D
data AdhocContext = NoContext | AgendaEvent Text CalendarList | AgendaList Text (Set Text) data AdhocContext = NoContext | AgendaEvent Text CalendarList | AgendaList Text (Set Text)

View file

@ -3,7 +3,7 @@ module Kassandra.ListWidget (
listWidget, listWidget,
) where ) where
import qualified Data.HashMap.Strict as HashMap import Data.HashMap.Strict qualified as HashMap
import Kassandra.Config (DefinitionElement (TagList)) import Kassandra.Config (DefinitionElement (TagList))
import Kassandra.ListElementWidget (AdhocContext (NoContext), definitionElementWidget) import Kassandra.ListElementWidget (AdhocContext (NoContext), definitionElementWidget)
import Kassandra.Types ( import Kassandra.Types (
@ -12,8 +12,8 @@ import Kassandra.Types (
Widget, Widget,
getTasks, getTasks,
) )
import qualified Reflex as R import Reflex qualified as R
import qualified Reflex.Dom as D import Reflex.Dom qualified as D
listsWidget :: (StandardWidget t m r e) => m () listsWidget :: (StandardWidget t m r e) => m ()
listsWidget = do listsWidget = do

View file

@ -9,7 +9,7 @@ import Kassandra.Api (SocketMessage, SocketRequest)
import Kassandra.Config (UserConfig) import Kassandra.Config (UserConfig)
import Kassandra.State (ClientSocket) import Kassandra.State (ClientSocket)
import Kassandra.Types (WidgetIO) import Kassandra.Types (WidgetIO)
import qualified Reflex as R import Reflex qualified as R
data LocalSocketState = LocalError Text | SettingUp deriving (Show) data LocalSocketState = LocalError Text | SettingUp deriving (Show)
makePrismLabels ''LocalSocketState makePrismLabels ''LocalSocketState

View file

@ -10,7 +10,7 @@ import Kassandra.Config (
import Kassandra.LocalBackend (LocalBackendRequest, localClientSocket) import Kassandra.LocalBackend (LocalBackendRequest, localClientSocket)
import Kassandra.State (StateProvider, makeStateProvider) import Kassandra.State (StateProvider, makeStateProvider)
import Kassandra.Types (WidgetIO) import Kassandra.Types (WidgetIO)
import qualified Reflex as R import Reflex qualified as R
localBackendWidget :: localBackendWidget ::
WidgetIO t m => WidgetIO t m =>

View file

@ -4,10 +4,10 @@ module Kassandra.MainWidget (
mainWidget, mainWidget,
) where ) where
import qualified Data.HashMap.Strict as HashMap import Data.HashMap.Strict qualified as HashMap
import qualified Data.Sequence as Seq import Data.Sequence qualified as Seq
import qualified Data.Sequence.NonEmpty as NESeq import Data.Sequence.NonEmpty qualified as NESeq
import qualified Data.Set as Set import Data.Set qualified as Set
import Kassandra.AgendaWidget (agendaWidget) import Kassandra.AgendaWidget (agendaWidget)
import Kassandra.BaseWidgets (br, button) import Kassandra.BaseWidgets (br, button)
import Kassandra.Calendar (CalendarEvent) import Kassandra.Calendar (CalendarEvent)
@ -37,8 +37,8 @@ import Kassandra.Types (
getTime, getTime,
) )
import Kassandra.Util (lookupTasks, stillTodo, tellNewTask) import Kassandra.Util (lookupTasks, stillTodo, tellNewTask)
import qualified Reflex as R import Reflex qualified as R
import qualified Reflex.Dom as D import Reflex.Dom qualified as D
mainWidget :: WidgetIO t m => StateProvider t m -> m () mainWidget :: WidgetIO t m => StateProvider t m -> m ()
mainWidget stateProvider = do mainWidget stateProvider = do

View file

@ -8,13 +8,13 @@ module Kassandra.ReflexUtil (
keyDynamic, keyDynamic,
) where ) where
import qualified Data.Map as Map import Data.Map qualified as Map
import qualified Data.Patch.Map as Patch import Data.Patch.Map qualified as Patch
-- import qualified Data.Patch.MapWithMove as Patch -- import qualified Data.Patch.MapWithMove as Patch
import qualified Data.Sequence as Seq import Data.Sequence qualified as Seq
import qualified Reflex as R import Reflex qualified as R
import qualified Reflex.Dom as D import Reflex.Dom qualified as D
{- | Renders a list of widgets depending on a Dynamic list of inputs. This will {- | Renders a list of widgets depending on a Dynamic list of inputs. This will
call the widget constructor once per value in the list. call the widget constructor once per value in the list.

View file

@ -26,8 +26,8 @@ import Kassandra.State (
) )
import Kassandra.Types (WidgetJSM) import Kassandra.Types (WidgetJSM)
import Language.Javascript.JSaddle (liftJSM) import Language.Javascript.JSaddle (liftJSM)
import qualified Reflex as R import Reflex qualified as R
import qualified Reflex.Dom as D import Reflex.Dom qualified as D
import Relude.Extra.Newtype (un, wrap) import Relude.Extra.Newtype (un, wrap)
import System.Process (readCreateProcess, shell) import System.Process (readCreateProcess, shell)

View file

@ -4,8 +4,8 @@ module Kassandra.SelectorWidget (
import Kassandra.Config (NamedBackend (..)) import Kassandra.Config (NamedBackend (..))
import Kassandra.Types (Widget) import Kassandra.Types (Widget)
import qualified Reflex as R import Reflex qualified as R
import qualified Reflex.Dom as D import Reflex.Dom qualified as D
backendSelector :: backendSelector ::
Widget t m => NonEmpty (NamedBackend a) -> m (R.Dynamic t (NamedBackend a)) Widget t m => NonEmpty (NamedBackend a) -> m (R.Dynamic t (NamedBackend a))

View file

@ -5,14 +5,14 @@ module Kassandra.Sorting (
SortMode (SortModePartof, SortModeTag), SortMode (SortModePartof, SortModeTag),
) where ) where
import qualified Data.Aeson as Aeson import Data.Aeson qualified as Aeson
import Data.Scientific (toRealFloat) import Data.Scientific (toRealFloat)
import qualified Data.Sequence as Seq import Data.Sequence qualified as Seq
import Data.Set (member) import Data.Set (member)
import Kassandra.Types (TaskInfos) import Kassandra.Types (TaskInfos)
import qualified Reflex as R import Reflex qualified as R
import Relude.Extra.Foldable1 (maximum1) import Relude.Extra.Foldable1 (maximum1)
import qualified Taskwarrior.Task as Task import Taskwarrior.Task qualified as Task
data SortMode = SortModePartof UUID | SortModeTag Task.Tag data SortMode = SortModePartof UUID | SortModeTag Task.Tag
deriving stock (Show, Eq, Ord, Generic) deriving stock (Show, Eq, Ord, Generic)

View file

@ -5,8 +5,8 @@ module Kassandra.State (
DataState (..), DataState (..),
) where ) where
import qualified Data.HashMap.Strict as HashMap import Data.HashMap.Strict qualified as HashMap
import qualified Data.Sequence as Seq import Data.Sequence qualified as Seq
import Kassandra.Api (SocketMessage (..), SocketRequest (..)) import Kassandra.Api (SocketMessage (..), SocketRequest (..))
import Kassandra.Calendar import Kassandra.Calendar
import Kassandra.Config (UIConfig) import Kassandra.Config (UIConfig)
@ -16,8 +16,8 @@ import Kassandra.Types (
TaskState, TaskState,
WidgetIO, WidgetIO,
) )
import qualified Reflex as R import Reflex qualified as R
import qualified Reflex.Dom as D import Reflex.Dom qualified as D
import Taskwarrior.IO (createTask) import Taskwarrior.IO (createTask)
getParents :: HashMap UUID Task -> UUID -> Seq UUID getParents :: HashMap UUID Task -> UUID -> Seq UUID

View file

@ -4,11 +4,11 @@ module Kassandra.TaskWidget (
uuidWidget, uuidWidget,
) where ) where
import qualified Data.HashSet as HashSet import Data.HashSet qualified as HashSet
import qualified Data.Sequence as Seq import Data.Sequence qualified as Seq
import qualified Data.Sequence.NonEmpty as NESeq import Data.Sequence.NonEmpty qualified as NESeq
import qualified Data.Set as Set import Data.Set qualified as Set
import qualified Data.Text as Text import Data.Text qualified as Text
import Kassandra.BaseWidgets ( import Kassandra.BaseWidgets (
br, br,
button, button,
@ -51,10 +51,10 @@ import Kassandra.Types (
getTime, getTime,
) )
import Kassandra.Util (lookupTaskM, lookupTasksDynM, lookupTasksM, stillTodo, tellNewTask, tellTask, tellToggle) import Kassandra.Util (lookupTaskM, lookupTasksDynM, lookupTasksM, stillTodo, tellNewTask, tellTask, tellToggle)
import qualified Reflex as R import Reflex qualified as R
import Reflex.Dom ((=:)) import Reflex.Dom ((=:))
import qualified Reflex.Dom as D import Reflex.Dom qualified as D
import qualified Taskwarrior.Status as Status import Taskwarrior.Status qualified as Status
import Taskwarrior.UDA (UDA) import Taskwarrior.UDA (UDA)
type TaskWidget t m r e = (TaskTreeWidget t m r e, HaveTask m r) type TaskWidget t m r e = (TaskTreeWidget t m r e, HaveTask m r)

View file

@ -11,8 +11,8 @@ import Kassandra.BaseWidgets (
stateWidget, stateWidget,
) )
import Kassandra.Types (Widget) import Kassandra.Types (Widget)
import qualified Reflex as R import Reflex qualified as R
import qualified Reflex.Dom as D import Reflex.Dom qualified as D
lineWidget :: Widget t m => Text -> m (R.Event t Text) lineWidget :: Widget t m => Text -> m (R.Event t Text)
lineWidget text = enterTextWidget text (showText text) lineWidget text = enterTextWidget text (showText text)

View file

@ -13,8 +13,8 @@ import Kassandra.Types (
Widget, Widget,
getTime, getTime,
) )
import qualified Reflex as R import Reflex qualified as R
import qualified Reflex.Dom as D import Reflex.Dom qualified as D
myFormatTime :: ZonedTime -> Text myFormatTime :: ZonedTime -> Text
myFormatTime = toText . formatTime defaultTimeLocale "%Y-%m-%d %H:%M" myFormatTime = toText . formatTime defaultTimeLocale "%Y-%m-%d %H:%M"

View file

@ -27,15 +27,15 @@ module Kassandra.Types (
getExpandedTasks, getExpandedTasks,
) where ) where
import qualified Data.Aeson as Aeson import Data.Aeson qualified as Aeson
import Data.HashSet (member) import Data.HashSet (member)
import Kassandra.Calendar import Kassandra.Calendar
import Kassandra.Config (DefinitionElement, UIConfig) import Kassandra.Config (DefinitionElement, UIConfig)
import Language.Javascript.JSaddle (MonadJSM) import Language.Javascript.JSaddle (MonadJSM)
import qualified Reflex as R import Reflex qualified as R
import qualified Reflex.Dom as D import Reflex.Dom qualified as D
import qualified Taskwarrior.Status import Taskwarrior.Status qualified
import qualified Taskwarrior.Task import Taskwarrior.Task qualified
import Text.Show import Text.Show
type Widget t m = type Widget t m =

View file

@ -30,8 +30,8 @@ import Kassandra.Types (
getExpandedTasks, getExpandedTasks,
getTasks, getTasks,
) )
import qualified Reflex as R import Reflex qualified as R
import qualified Reflex.Dom as D import Reflex.Dom qualified as D
stillTodo :: TaskInfos -> Bool stillTodo :: TaskInfos -> Bool
stillTodo = has (#status % #_Pending) stillTodo = has (#status % #_Pending)

View file

@ -75,7 +75,7 @@ import Data.Aeson (
fromJSON, fromJSON,
toJSON, toJSON,
) )
import qualified Data.Aeson as Aeson import Data.Aeson qualified as Aeson
import Data.Generics.Product.Any (HasAny (the)) import Data.Generics.Product.Any (HasAny (the))
import Data.Generics.Product.Fields (HasField' (field')) import Data.Generics.Product.Fields (HasField' (field'))
import Data.Generics.Product.Typed (HasType (typed)) import Data.Generics.Product.Typed (HasType (typed))

View file

@ -7,13 +7,13 @@ module Kassandra.Backend.Calendar (
saveCache, saveCache,
) where ) where
import qualified Control.Concurrent.STM as STM import Control.Concurrent.STM qualified as STM
import qualified Data.Aeson as JSON import Data.Aeson qualified as JSON
import qualified Data.ByteString.Lazy as LBS import Data.ByteString.Lazy qualified as LBS
import Data.Default (Default (def)) import Data.Default (Default (def))
import qualified Data.Map as Map import Data.Map qualified as Map
import qualified Data.Set as Set import Data.Set qualified as Set
import qualified Data.Text as Text import Data.Text qualified as Text
import Data.Time (ZonedTime (ZonedTime), addDays, getCurrentTime, nominalDay, utc) import Data.Time (ZonedTime (ZonedTime), addDays, getCurrentTime, nominalDay, utc)
import Data.Time.Zones ( import Data.Time.Zones (
TZ, TZ,
@ -22,9 +22,9 @@ import Data.Time.Zones (
localTimeToUTCTZ, localTimeToUTCTZ,
timeZoneForUTCTime, timeZoneForUTCTime,
) )
import qualified StmContainers.Map as STM import StmContainers.Map qualified as STM
import Streamly (IsStream, SerialT, async, asyncly, maxThreads) import Streamly (IsStream, SerialT, async, asyncly, maxThreads)
import qualified Streamly.Prelude as S import Streamly.Prelude qualified as S
import System.Directory ( import System.Directory (
XdgDirectory (XdgCache), XdgDirectory (XdgCache),
createDirectoryIfMissing, createDirectoryIfMissing,
@ -60,7 +60,7 @@ import Text.ICalendar (
import Control.Exception (onException) import Control.Exception (onException)
import Data.Aeson (decodeStrict', encode) import Data.Aeson (decodeStrict', encode)
import qualified DeferredFolds.UnfoldlM as UnfoldlM import DeferredFolds.UnfoldlM qualified as UnfoldlM
import Kassandra.Calendar ( import Kassandra.Calendar (
CalendarEvent (..), CalendarEvent (..),
CalendarList (CalendarList), CalendarList (CalendarList),
@ -70,11 +70,11 @@ import Kassandra.Calendar (
zonedDay, zonedDay,
) )
import Kassandra.Debug (Severity (..), log) import Kassandra.Debug (Severity (..), log)
import qualified Streamly.Data.Fold as FL import Streamly.Data.Fold qualified as FL
import Streamly.External.ByteString (fromArray, toArray) import Streamly.External.ByteString (fromArray, toArray)
import qualified Streamly.FileSystem.Handle as FS import Streamly.FileSystem.Handle qualified as FS
import Streamly.Internal.Data.Array.Stream.Foreign (splitOn) import Streamly.Internal.Data.Array.Stream.Foreign (splitOn)
import qualified Streamly.Internal.FileSystem.File as FSFile import Streamly.Internal.FileSystem.File qualified as FSFile
import Streamly.Memory.Array as Mem (fromList) import Streamly.Memory.Array as Mem (fromList)
dirName :: FilePath dirName :: FilePath

View file

@ -8,7 +8,7 @@ import Data.Password.Argon2 (
Argon2, Argon2,
PasswordHash (PasswordHash), PasswordHash (PasswordHash),
) )
import qualified Data.UUID as UUID import Data.UUID qualified as UUID
import Dhall ( import Dhall (
Decoder, Decoder,
FromDhall, FromDhall,
@ -20,7 +20,7 @@ import Dhall (
input, input,
toMonadic, toMonadic,
) )
import qualified Dhall import Dhall qualified
import Dhall.Core (pretty) import Dhall.Core (pretty)
import System.Environment () import System.Environment ()

View file

@ -23,8 +23,8 @@ import Kassandra.Standalone.State (localBackendProvider)
import Kassandra.State (StateProvider) import Kassandra.State (StateProvider)
import Kassandra.Types (WidgetJSM) import Kassandra.Types (WidgetJSM)
import Kassandra.Util (defDynDyn) import Kassandra.Util (defDynDyn)
import qualified Reflex as R import Reflex qualified as R
import qualified Reflex.Dom as D import Reflex.Dom qualified as D
import Relude.Extra.Newtype (wrap) import Relude.Extra.Newtype (wrap)
import Say (say) import Say (say)
import System.Exit (ExitCode (ExitFailure)) import System.Exit (ExitCode (ExitFailure))

View file

@ -7,11 +7,11 @@ module Kassandra.Standalone.State (
import Control.Concurrent.STM (TQueue, readTQueue) import Control.Concurrent.STM (TQueue, readTQueue)
import Control.Concurrent.STM.TVar (stateTVar) import Control.Concurrent.STM.TVar (stateTVar)
import Control.Monad.STM (retry) import Control.Monad.STM (retry)
import qualified Data.Aeson as Aeson import Data.Aeson qualified as Aeson
import qualified Data.Map as Map import Data.Map qualified as Map
import qualified Data.Sequence as Seq import Data.Sequence qualified as Seq
import qualified Data.Sequence.NonEmpty as NESeq import Data.Sequence.NonEmpty qualified as NESeq
import qualified Network.Simple.TCP as Net import Network.Simple.TCP qualified as Net
import Say (say, sayErr) import Say (say, sayErr)
import Streamly ( import Streamly (
SerialT, SerialT,
@ -21,7 +21,7 @@ import Streamly (
parallely, parallely,
serial, serial,
) )
import qualified Streamly.Prelude as S import Streamly.Prelude qualified as S
import Taskwarrior.IO (getTasks, saveTasks) import Taskwarrior.IO (getTasks, saveTasks)
import Kassandra.Api ( import Kassandra.Api (

View file

@ -9,7 +9,7 @@
module Main where module Main where
import qualified Data.List.Extra as L import Data.List.Extra qualified as L
import Data.List.NonEmpty ( import Data.List.NonEmpty (
groupBy, groupBy,
zip, zip,
@ -19,10 +19,10 @@ import Data.Text (
intercalate, intercalate,
replace, replace,
) )
import qualified Data.Text as Text import Data.Text qualified as Text
import qualified Data.Time.Calendar as T import Data.Time.Calendar qualified as T
import qualified Data.Time.Clock as T import Data.Time.Clock qualified as T
import qualified Data.Time.Format as T import Data.Time.Format qualified as T
import Relude hiding ( import Relude hiding (
intercalate, intercalate,
zip, zip,
@ -31,10 +31,10 @@ import System.Environment ()
import System.FilePattern.Directory (getDirectoryFiles) import System.FilePattern.Directory (getDirectoryFiles)
import Text.Atom.Feed import Text.Atom.Feed
import Text.Atom.Feed.Export (textFeed) import Text.Atom.Feed.Export (textFeed)
import qualified Text.Megaparsec as MP import Text.Megaparsec qualified as MP
import qualified Text.Megaparsec.Char as MP import Text.Megaparsec.Char qualified as MP
import qualified Text.Megaparsec.Char as MPC import Text.Megaparsec.Char qualified as MPC
import qualified Text.Megaparsec.Char.Lexer as MP import Text.Megaparsec.Char.Lexer qualified as MP
-- TODO: use Text instead of linked lists of chars -- TODO: use Text instead of linked lists of chars

View file

@ -1,2 +1 @@
- [ ] Choose which branches you care about - [ ] Choose which branches you care about
- [ ] Accept multiline commands

View file

@ -2,33 +2,33 @@
module Main (main) where module Main (main) where
import qualified Control.Exception as Exception import Control.Exception qualified as Exception
import Control.Monad.Catch (MonadMask) import Control.Monad.Catch (MonadMask)
import qualified Control.Monad.Catch as MonadCatch import Control.Monad.Catch qualified as MonadCatch
import qualified Control.Monad.Except as Except import Control.Monad.Except qualified as Except
import qualified Control.Monad.Logger as MonadLogger import Control.Monad.Logger qualified as MonadLogger
import qualified Control.Monad.Trans.Resource as ResourceT import Control.Monad.Trans.Resource qualified as ResourceT
import Data.GraphQL (get) import Data.GraphQL (get)
import qualified Data.GraphQL as GraphQL import Data.GraphQL qualified as GraphQL
import qualified Data.List.NonEmpty as NonEmpty import Data.List.NonEmpty qualified as NonEmpty
import qualified Data.Map.Strict as Map import Data.Map.Strict qualified as Map
import qualified Data.Text as Text import Data.Text qualified as Text
import qualified Data.Time as Time import Data.Time qualified as Time
import Data.Yaml (FromJSON) import Data.Yaml (FromJSON)
import qualified Data.Yaml as Yaml import Data.Yaml qualified as Yaml
import Database.Esqueleto.Experimental (notIn, (&&.), (<.), (==.), (^.)) import Database.Esqueleto.Experimental (notIn, (&&.), (<.), (==.), (^.))
import qualified Database.Esqueleto.Experimental as SQL import Database.Esqueleto.Experimental qualified as SQL
import qualified Database.Persist as Persist import Database.Persist qualified as Persist
import qualified Database.Persist.Sqlite as Persist.Sqlite import Database.Persist.Sqlite qualified as Persist.Sqlite
import qualified Database.Persist.TH as Persist import Database.Persist.TH qualified as Persist
import qualified Network.HTTP.Client as HTTP import Network.HTTP.Client qualified as HTTP
import qualified Network.Matrix.Client as Matrix import Network.Matrix.Client qualified as Matrix
import qualified NixpkgsBot.GraphQL.API as GraphQL.API import NixpkgsBot.GraphQL.API qualified as GraphQL.API
import Relude hiding (get) import Relude hiding (get)
import qualified System.Clock as Clock import System.Clock qualified as Clock
import qualified System.Environment as System import System.Environment qualified as System
import qualified System.Process.Typed as Process import System.Process.Typed qualified as Process
import qualified System.Random as Random import System.Random qualified as Random
data Repo = MkRepo data Repo = MkRepo
{ localPath :: FilePath { localPath :: FilePath
@ -517,8 +517,8 @@ getCommands roomId events = do
session <- getEnv matrixSession session <- getEnv matrixSession
members <- unwrapMatrixError $ Matrix.getRoomMembers session roomId members <- unwrapMatrixError $ Matrix.getRoomMembers session roomId
let isQuery = Map.size members <= 2 let isQuery = Map.size members <= 2
forM (toList messages) \(author, message) -> do join <$> forM (toList messages) \(author, message) -> forM (Text.lines message) \line -> do
let (cmd, args) = second (Text.drop 1) $ Text.breakOn " " $ Text.strip message let (cmd, args) = second (Text.drop 1) $ Text.breakOn " " $ Text.strip line
pure $ MkCommand{command = Text.toLower cmd, args, author, isQuery, roomId} pure $ MkCommand{command = Text.toLower cmd, args, author, isQuery, roomId}
where where
getCommand Matrix.RoomEvent{Matrix.reSender = Matrix.Author author, Matrix.reContent = Matrix.EventRoomMessage (Matrix.RoomMessageText (Matrix.MessageText{Matrix.mtBody, Matrix.mtType = Matrix.TextType}))} = Just (author, mtBody) getCommand Matrix.RoomEvent{Matrix.reSender = Matrix.Author author, Matrix.reContent = Matrix.EventRoomMessage (Matrix.RoomMessageText (Matrix.MessageText{Matrix.mtBody, Matrix.mtType = Matrix.TextType}))} = Just (author, mtBody)
@ -697,7 +697,7 @@ helpMessage = do
, m "I will inform you, when one of the pull requests you subscribed to reaches one of these branches: " <> branchList , m "I will inform you, when one of the pull requests you subscribed to reaches one of these branches: " <> branchList
, mempty , mempty
, m "I have been programmed and am being hosted by " <> mention "@maralorn:maralorn.de" <> m ". Feel free to reach out to him, if you have any problems or suggestions." , m "I have been programmed and am being hosted by " <> mention "@maralorn:maralorn.de" <> m ". Feel free to reach out to him, if you have any problems or suggestions."
, m "My code is written in Haskell, is open source under the AGPL license and can be found at " <> link "https://git.maralorn.de/nixpkgs-bot" "git.maralorn.de/nixpkgs-bot" <> m "." , m "My code is written in Haskell, is open source under the AGPL license and can be found at " <> link "https://git.maralorn.de/nixos-config/tree/apps/nixpkgs-bot" "git.maralorn.de/nixos-config/tree/apps/nixpkgs-bot" <> m "."
] ]
whenTimeIsUp :: (Environment -> IORef Clock.TimeSpec) -> Int64 -> App () -> App () whenTimeIsUp :: (Environment -> IORef Clock.TimeSpec) -> Int64 -> App () -> App ()

View file

@ -38,6 +38,7 @@ common common-config
TypeApplications TypeApplications
TypeFamilies TypeFamilies
UndecidableInstances UndecidableInstances
ImportQualifiedPost
build-depends: build-depends:
, aeson-schemas , aeson-schemas

View file

@ -8,10 +8,10 @@ import Relude
import Witch import Witch
import Data.Aeson (FromJSON (..), Value (Array, String), withObject) import Data.Aeson (FromJSON (..), Value (Array, String), withObject)
import qualified Data.Aeson.Key as Key import Data.Aeson.Key qualified as Key
import qualified Data.Aeson.KeyMap as Aeson import Data.Aeson.KeyMap qualified as Aeson
import qualified Data.Foldable as Foldable import Data.Foldable qualified as Foldable
import qualified Data.Text as Text import Data.Text qualified as Text
import Data.Yaml (decodeFileEither) import Data.Yaml (decodeFileEither)
import System.Posix.Daemon (Redirection (DevNull), runDetached) import System.Posix.Daemon (Redirection (DevNull), runDetached)

View file

@ -32,13 +32,21 @@
}; };
pre-commit = { pre-commit = {
check.enable = true; check.enable = true;
settings.hooks = { settings = {
hlint.enable = true; settings.ormolu.defaultExtensions = [
alejandra.enable = true; "TypeApplications"
nix-linter.enable = false; # Too many false positives for now "BangPatterns"
statix.enable = true; "ImportQualifiedPost"
fourmolu.enable = true; "BlockArguments"
shellcheck.enable = true; ];
hooks = {
hlint.enable = true;
alejandra.enable = true;
nix-linter.enable = false; # Too many false positives for now
statix.enable = true;
fourmolu.enable = true;
shellcheck.enable = true;
};
}; };
}; };
}; };

View file

@ -7,14 +7,14 @@
{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE NoImplicitPrelude #-}
import qualified Control.Concurrent import Control.Concurrent qualified
import qualified Control.Concurrent as Concurrent import Control.Concurrent qualified as Concurrent
import qualified Control.Concurrent.Async as Async import Control.Concurrent.Async qualified as Async
import qualified Control.Concurrent.STM as STM import Control.Concurrent.STM qualified as STM
import Control.Exception (catch, onException) import Control.Exception (catch, onException)
import qualified Data.ByteString.Lazy as LBS import Data.ByteString.Lazy qualified as LBS
import Data.String.Interpolate (i) import Data.String.Interpolate (i)
import qualified Data.Text as Text import Data.Text qualified as Text
import Relude import Relude
import Say (sayErr) import Say (sayErr)
import Shh (ExecReference (Absolute), captureTrim, exe, ignoreFailure, load, (|>)) import Shh (ExecReference (Absolute), captureTrim, exe, ignoreFailure, load, (|>))

View file

@ -1,6 +1,7 @@
{-# LANGUAGE BlockArguments #-} {-# LANGUAGE BlockArguments #-}
{-# LANGUAGE ExtendedDefaultRules #-} {-# LANGUAGE ExtendedDefaultRules #-}
{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE ScopedTypeVariables #-}
@ -10,7 +11,7 @@
{-# OPTIONS_GHC -Wall -Werror -Wno-missing-signatures -Wno-type-defaults -Wno-orphans #-} {-# OPTIONS_GHC -Wall -Werror -Wno-missing-signatures -Wno-type-defaults -Wno-orphans #-}
import Data.String.Interpolate import Data.String.Interpolate
import qualified Data.Text as Text import Data.Text qualified as Text
import Language.Haskell.TH import Language.Haskell.TH
import Language.Haskell.TH.Syntax import Language.Haskell.TH.Syntax
import Relude import Relude

View file

@ -70,6 +70,7 @@ in {
{-# LANGUAGE TupleSections #-} {-# LANGUAGE TupleSections #-}
{-# LANGUAGE PartialTypeSignatures #-} {-# LANGUAGE PartialTypeSignatures #-}
{-# LANGUAGE BlockArguments #-} {-# LANGUAGE BlockArguments #-}
{-# LANGUAGE ImportQualifiedPost #-}
import Shh import Shh
import Relude import Relude