Some cleanup and refactoring
parent
7f31362300
commit
200cc93e1b
3
Main.hs
3
Main.hs
|
@ -1,7 +1,4 @@
|
||||||
{-# LANGUAGE NoImplicitPrelude #-}
|
|
||||||
{-# LANGUAGE OverlappingInstances #-}
|
{-# LANGUAGE OverlappingInstances #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
|
||||||
{-# LANGUAGE ScopedTypeVariables #-}
|
|
||||||
|
|
||||||
module Main (main) where
|
module Main (main) where
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
{-# LANGUAGE BangPatterns #-}
|
|
||||||
{-# LANGUAGE NoImplicitPrelude #-}
|
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
|
||||||
{-# LANGUAGE RecordWildCards #-}
|
|
||||||
{-# LANGUAGE ScopedTypeVariables #-}
|
|
||||||
{-# LANGUAGE TemplateHaskell #-}
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
|
|
||||||
module Network.IRC.Bot
|
module Network.IRC.Bot
|
||||||
|
@ -126,7 +121,7 @@ messageProcessLoop lineChan commandChan !idleFor = do
|
||||||
|
|
||||||
where
|
where
|
||||||
dispatchHandlers Bot { .. } message =
|
dispatchHandlers Bot { .. } message =
|
||||||
forM_ (mapValues msgHandlers) $ \msgHandler -> fork $
|
forM_ (mapValues msgHandlers) $ \msgHandler -> void . fork $
|
||||||
handle (\(e :: SomeException) ->
|
handle (\(e :: SomeException) ->
|
||||||
errorM $ "Exception while processing message: " ++ show e) $ do
|
errorM $ "Exception while processing message: " ++ show e) $ do
|
||||||
mCmd <- handleMessage msgHandler botConfig message
|
mCmd <- handleMessage msgHandler botConfig message
|
||||||
|
@ -139,7 +134,7 @@ eventProcessLoop (eventChan, latch) lineChan commandChan bot@Bot {.. } = do
|
||||||
Just (QuitEvent, _) -> latchIt latch
|
Just (QuitEvent, _) -> latchIt latch
|
||||||
_ -> do
|
_ -> do
|
||||||
debugM $ "Event: " ++ show event
|
debugM $ "Event: " ++ show event
|
||||||
forM_ (mapValues msgHandlers) $ \msgHandler -> fork $
|
forM_ (mapValues msgHandlers) $ \msgHandler -> void . fork $
|
||||||
handle (\(ex :: SomeException) ->
|
handle (\(ex :: SomeException) ->
|
||||||
errorM $ "Exception while processing event: " ++ show ex) $ do
|
errorM $ "Exception while processing event: " ++ show ex) $ do
|
||||||
resp <- handleEvent msgHandler botConfig event
|
resp <- handleEvent msgHandler botConfig event
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
{-# LANGUAGE NoImplicitPrelude #-}
|
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
|
||||||
{-# LANGUAGE RecordWildCards #-}
|
|
||||||
{-# LANGUAGE ScopedTypeVariables #-}
|
|
||||||
{-# LANGUAGE TemplateHaskell #-}
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
|
|
||||||
module Network.IRC.Client (runBot) where
|
module Network.IRC.Client (runBot) where
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
{-# LANGUAGE FlexibleContexts #-}
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
{-# LANGUAGE NoImplicitPrelude #-}
|
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
|
||||||
{-# LANGUAGE RecordWildCards #-}
|
|
||||||
|
|
||||||
module Network.IRC.Handlers (coreMsgHandlerNames, mkMsgHandler) where
|
module Network.IRC.Handlers (coreMsgHandlerNames, mkMsgHandler) where
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
{-# LANGUAGE DeriveDataTypeable #-}
|
{-# LANGUAGE DeriveDataTypeable #-}
|
||||||
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
||||||
{-# LANGUAGE NoImplicitPrelude #-}
|
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
|
||||||
{-# LANGUAGE RecordWildCards #-}
|
|
||||||
{-# LANGUAGE TemplateHaskell #-}
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
{-# LANGUAGE TypeFamilies #-}
|
{-# LANGUAGE TypeFamilies #-}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
{-# LANGUAGE FlexibleContexts #-}
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
{-# LANGUAGE NoImplicitPrelude #-}
|
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
|
||||||
{-# LANGUAGE RecordWildCards #-}
|
|
||||||
{-# LANGUAGE ScopedTypeVariables #-}
|
|
||||||
|
|
||||||
module Network.IRC.Handlers.MessageLogger (mkMsgHandler) where
|
module Network.IRC.Handlers.MessageLogger (mkMsgHandler) where
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
{-# LANGUAGE DeriveDataTypeable #-}
|
{-# LANGUAGE DeriveDataTypeable #-}
|
||||||
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
||||||
{-# LANGUAGE NoImplicitPrelude #-}
|
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
|
||||||
{-# LANGUAGE RecordWildCards #-}
|
|
||||||
{-# LANGUAGE TemplateHaskell #-}
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
{-# LANGUAGE TypeFamilies #-}
|
{-# LANGUAGE TypeFamilies #-}
|
||||||
|
|
||||||
|
@ -43,58 +40,60 @@ saveNickTrack nt = do
|
||||||
$(makeAcidic ''NickTracking ['getByNick, 'getByCanonicalNick, 'saveNickTrack])
|
$(makeAcidic ''NickTracking ['getByNick, 'getByCanonicalNick, 'saveNickTrack])
|
||||||
|
|
||||||
nickTrackerMsg :: MonadMsgHandler m => IORef (AcidState NickTracking) -> Message -> m (Maybe Command)
|
nickTrackerMsg :: MonadMsgHandler m => IORef (AcidState NickTracking) -> Message -> m (Maybe Command)
|
||||||
nickTrackerMsg state = go
|
nickTrackerMsg state message = case message of
|
||||||
|
ChannelMsg { .. } -> updateNickTrack state user msg msgTime >> handleCommands msg
|
||||||
|
ActionMsg { .. } -> updateNickTrack state user msg msgTime >> return Nothing
|
||||||
|
JoinMsg { .. } -> updateNickTrack state user "" msgTime >> return Nothing
|
||||||
|
PartMsg { .. } -> updateNickTrack state user msg msgTime >> return Nothing
|
||||||
|
QuitMsg { .. } -> updateNickTrack state user msg msgTime >> return Nothing
|
||||||
|
NickMsg { .. } -> handleNickChange state user newNick msgTime >> return Nothing
|
||||||
|
NamesMsg { .. } ->
|
||||||
|
mapM_ (\n -> updateNickTrack state (User n "") "" msgTime) nicks >> return Nothing
|
||||||
|
_ -> return Nothing
|
||||||
where
|
where
|
||||||
go ChannelMsg { .. } = updateNickTrack user msg msgTime >> handleCommands msg
|
|
||||||
go ActionMsg { .. } = updateNickTrack user msg msgTime >> return Nothing
|
|
||||||
go JoinMsg { .. } = updateNickTrack user "" msgTime >> return Nothing
|
|
||||||
go PartMsg { .. } = updateNickTrack user msg msgTime >> return Nothing
|
|
||||||
go QuitMsg { .. } = updateNickTrack user msg msgTime >> return Nothing
|
|
||||||
go NickMsg { .. } = handleNickChange user newNick msgTime >> return Nothing
|
|
||||||
go NamesMsg { .. } =
|
|
||||||
mapM_ (\n -> updateNickTrack (User n "") "" msgTime) nicks >> return Nothing
|
|
||||||
go _ = return Nothing
|
|
||||||
|
|
||||||
updateNickTrack user message msgTime = io $ do
|
|
||||||
acid <- readIORef state
|
|
||||||
let nck = userNick user
|
|
||||||
mnt <- query acid . GetByNick $ Nick nck
|
|
||||||
(message', lastMessageOn', cn) <- case (message, mnt) of
|
|
||||||
("", Just (NickTrack { .. })) -> return (lastMessage, lastMessageOn, canonicalNick)
|
|
||||||
(_, Just (NickTrack { .. })) -> return (message, msgTime, canonicalNick)
|
|
||||||
_ -> do
|
|
||||||
cn <- newCanonicalNick
|
|
||||||
return (message, msgTime, cn)
|
|
||||||
|
|
||||||
update acid . SaveNickTrack $
|
|
||||||
NickTrack (Nick nck) cn (LastSeenOn msgTime) lastMessageOn' message'
|
|
||||||
|
|
||||||
handleNickChange user newNick msgTime = io $ do
|
|
||||||
acid <- readIORef state
|
|
||||||
let prevNick = userNick user
|
|
||||||
mpnt <- query acid . GetByNick $ Nick prevNick
|
|
||||||
mnt <- query acid . GetByNick $ Nick newNick
|
|
||||||
mInfo <- case (mpnt, mnt) of
|
|
||||||
(Nothing, _) -> newCanonicalNick >>= \cn -> return $ Just ("", cn, msgTime)
|
|
||||||
(Just pnt, Nothing) ->
|
|
||||||
return $ Just (lastMessage pnt, canonicalNick pnt, lastMessageOn pnt)
|
|
||||||
(Just pnt, Just nt) | canonicalNick pnt == canonicalNick nt -> do
|
|
||||||
let nt' = maximumByEx (comparing lastMessageOn) [pnt, nt]
|
|
||||||
return $ Just (lastMessage nt', canonicalNick nt', lastMessageOn nt')
|
|
||||||
_ -> return Nothing
|
|
||||||
|
|
||||||
whenJust mInfo $ \(message, cn, lastMessageOn') ->
|
|
||||||
update acid . SaveNickTrack $
|
|
||||||
NickTrack (Nick newNick) cn (LastSeenOn msgTime) lastMessageOn' message
|
|
||||||
|
|
||||||
newCanonicalNick = map (CanonicalNick . pack . U.toString) U.nextRandom
|
|
||||||
|
|
||||||
commands = [ ("!nick", handleNickCommand)
|
commands = [ ("!nick", handleNickCommand)
|
||||||
, ("!seen", handleSeenCommand) ]
|
, ("!seen", handleSeenCommand) ]
|
||||||
|
|
||||||
handleCommands message = case find ((`isPrefixOf` message) . fst) commands of
|
handleCommands msg = case find ((`isPrefixOf` msg) . fst) commands of
|
||||||
Nothing -> return Nothing
|
Nothing -> return Nothing
|
||||||
Just (_, handler) -> handler state message
|
Just (_, handler) -> handler state msg
|
||||||
|
|
||||||
|
updateNickTrack :: MonadMsgHandler m => IORef (AcidState NickTracking) -> User -> Text -> UTCTime -> m ()
|
||||||
|
updateNickTrack state user message msgTime = io $ do
|
||||||
|
acid <- readIORef state
|
||||||
|
let nck = userNick user
|
||||||
|
mnt <- query acid . GetByNick $ Nick nck
|
||||||
|
(message', lastMessageOn', cn) <- case (message, mnt) of
|
||||||
|
("", Just (NickTrack { .. })) -> return (lastMessage, lastMessageOn, canonicalNick)
|
||||||
|
(_, Just (NickTrack { .. })) -> return (message, msgTime, canonicalNick)
|
||||||
|
_ -> do
|
||||||
|
cn <- newCanonicalNick
|
||||||
|
return (message, msgTime, cn)
|
||||||
|
|
||||||
|
update acid . SaveNickTrack $
|
||||||
|
NickTrack (Nick nck) cn (LastSeenOn msgTime) lastMessageOn' message'
|
||||||
|
|
||||||
|
handleNickChange :: MonadMsgHandler m => IORef (AcidState NickTracking) -> User -> Text -> UTCTime -> m ()
|
||||||
|
handleNickChange state user newNick msgTime = io $ do
|
||||||
|
acid <- readIORef state
|
||||||
|
let prevNick = userNick user
|
||||||
|
mpnt <- query acid . GetByNick $ Nick prevNick
|
||||||
|
mnt <- query acid . GetByNick $ Nick newNick
|
||||||
|
mInfo <- case (mpnt, mnt) of
|
||||||
|
(Nothing, _) -> newCanonicalNick >>= \cn -> return $ Just ("", cn, msgTime)
|
||||||
|
(Just pnt, Nothing) ->
|
||||||
|
return $ Just (lastMessage pnt, canonicalNick pnt, lastMessageOn pnt)
|
||||||
|
(Just pnt, Just nt) | canonicalNick pnt == canonicalNick nt -> do
|
||||||
|
let nt' = maximumByEx (comparing lastMessageOn) [pnt, nt]
|
||||||
|
return $ Just (lastMessage nt', canonicalNick nt', lastMessageOn nt')
|
||||||
|
_ -> return Nothing
|
||||||
|
|
||||||
|
whenJust mInfo $ \(message, cn, lastMessageOn') ->
|
||||||
|
update acid . SaveNickTrack $
|
||||||
|
NickTrack (Nick newNick) cn (LastSeenOn msgTime) lastMessageOn' message
|
||||||
|
|
||||||
|
newCanonicalNick :: IO CanonicalNick
|
||||||
|
newCanonicalNick = map (CanonicalNick . pack . U.toString) U.nextRandom
|
||||||
|
|
||||||
withNickTracks :: MonadMsgHandler m
|
withNickTracks :: MonadMsgHandler m
|
||||||
=> (Text -> [NickTrack] -> IO Text) -> IORef (AcidState NickTracking) -> Text
|
=> (Text -> [NickTrack] -> IO Text) -> IORef (AcidState NickTracking) -> Text
|
||||||
|
@ -142,7 +141,7 @@ mkMsgHandler BotConfig { .. } _ "nicktracker" = do
|
||||||
state <- io (openLocalState emptyNickTracking >>= newIORef)
|
state <- io (openLocalState emptyNickTracking >>= newIORef)
|
||||||
return . Just $ newMsgHandler { onMessage = nickTrackerMsg state
|
return . Just $ newMsgHandler { onMessage = nickTrackerMsg state
|
||||||
, onStop = stopNickTracker state
|
, onStop = stopNickTracker state
|
||||||
, onHelp = return $ mapFromList helpMsgs}
|
, onHelp = return helpMsgs }
|
||||||
where
|
where
|
||||||
helpMsgs = mapFromList [
|
helpMsgs = mapFromList [
|
||||||
("!nick", "Shows the user's other nicks. !nick <user nick>"),
|
("!nick", "Shows the user's other nicks. !nick <user nick>"),
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
{-# LANGUAGE DeriveDataTypeable #-}
|
{-# LANGUAGE DeriveDataTypeable #-}
|
||||||
{-# LANGUAGE NoImplicitPrelude #-}
|
|
||||||
{-# LANGUAGE TemplateHaskell #-}
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
|
|
||||||
module Network.IRC.Handlers.NickTracker.Types where
|
module Network.IRC.Handlers.NickTracker.Types where
|
||||||
|
@ -14,11 +13,11 @@ newtype CanonicalNick = CanonicalNick Text deriving (Eq, Ord, Show, Data, Typeab
|
||||||
newtype LastSeenOn = LastSeenOn UTCTime deriving (Eq, Ord, Show, Data, Typeable)
|
newtype LastSeenOn = LastSeenOn UTCTime deriving (Eq, Ord, Show, Data, Typeable)
|
||||||
|
|
||||||
data NickTrack = NickTrack {
|
data NickTrack = NickTrack {
|
||||||
nick :: Nick,
|
nick :: !Nick,
|
||||||
canonicalNick :: CanonicalNick,
|
canonicalNick :: !CanonicalNick,
|
||||||
lastSeenOn :: LastSeenOn,
|
lastSeenOn :: !LastSeenOn,
|
||||||
lastMessageOn :: UTCTime,
|
lastMessageOn :: !UTCTime,
|
||||||
lastMessage :: Text
|
lastMessage :: !Text
|
||||||
} deriving (Eq, Ord, Show, Data, Typeable)
|
} deriving (Eq, Ord, Show, Data, Typeable)
|
||||||
|
|
||||||
instance Indexable NickTrack where
|
instance Indexable NickTrack where
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
{-# LANGUAGE NoImplicitPrelude #-}
|
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
|
||||||
{-# LANGUAGE RecordWildCards #-}
|
|
||||||
|
|
||||||
module Network.IRC.Protocol (msgFromLine, lineFromCommand) where
|
module Network.IRC.Protocol (msgFromLine, lineFromCommand) where
|
||||||
|
|
||||||
import ClassyPrelude
|
import ClassyPrelude
|
||||||
|
|
|
@ -3,10 +3,7 @@
|
||||||
{-# LANGUAGE FlexibleContexts #-}
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
||||||
{-# LANGUAGE MultiParamTypeClasses #-}
|
{-# LANGUAGE MultiParamTypeClasses #-}
|
||||||
{-# LANGUAGE NoImplicitPrelude #-}
|
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
|
||||||
{-# LANGUAGE RankNTypes #-}
|
{-# LANGUAGE RankNTypes #-}
|
||||||
{-# LANGUAGE RecordWildCards #-}
|
|
||||||
|
|
||||||
module Network.IRC.Types
|
module Network.IRC.Types
|
||||||
( Nick
|
( Nick
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
{-# LANGUAGE NoImplicitPrelude #-}
|
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
|
||||||
{-# LANGUAGE ScopedTypeVariables #-}
|
|
||||||
|
|
||||||
module Network.IRC.Util where
|
module Network.IRC.Util where
|
||||||
|
|
||||||
import ClassyPrelude
|
import ClassyPrelude
|
||||||
|
|
|
@ -49,31 +49,32 @@ build-type: Simple
|
||||||
cabal-version: >=1.10
|
cabal-version: >=1.10
|
||||||
|
|
||||||
library
|
library
|
||||||
other-extensions: Safe
|
default-extensions: NoImplicitPrelude, OverloadedStrings, RecordWildCards, ScopedTypeVariables,
|
||||||
|
BangPatterns, TupleSections
|
||||||
|
|
||||||
build-depends: base >=4.5 && <4.8,
|
build-depends: base >=4.5 && <4.8,
|
||||||
text >=0.11 && <0.12,
|
text >=0.11 && <0.12,
|
||||||
mtl >=2.1 && <2.2,
|
mtl >=2.1 && <2.2,
|
||||||
network >=2.3 && <2.5,
|
network >=2.3 && <2.5,
|
||||||
configurator >=0.2,
|
configurator >=0.2 && <0.3,
|
||||||
time >=1.4.0,
|
time >=1.4 && <1.5,
|
||||||
curl-aeson ==0.0.3,
|
curl-aeson >=0.0.3 && <0.1,
|
||||||
aeson >=0.6.0.0,
|
aeson >=0.6.0.0 && <0.7,
|
||||||
HTTP >=4000,
|
HTTP >=4000 && <5000,
|
||||||
transformers >=0.3,
|
transformers >=0.3 && <0.4,
|
||||||
classy-prelude ==0.9.1,
|
classy-prelude >=0.9 && <1.0,
|
||||||
text-format >=0.3.1,
|
text-format >=0.3 && <0.4,
|
||||||
filepath >=1.3,
|
filepath >=1.3 && <1.4,
|
||||||
directory >=1.2,
|
directory >=1.2 && <1.3,
|
||||||
lifted-base >=0.2,
|
lifted-base >=0.2 && <0.3,
|
||||||
unix >=2.7,
|
unix >=2.7 && <2.8,
|
||||||
convertible >=1.1,
|
convertible >=1.1 && <1.2,
|
||||||
hslogger >=1.2.4,
|
hslogger >=1.2 && <1.3,
|
||||||
hslogger-template >=2.0,
|
hslogger-template >=2.0 && <2.1,
|
||||||
ixset >=1.0,
|
ixset >=1.0 && <1.1,
|
||||||
acid-state >=0.12,
|
acid-state >=0.12 && <0.13,
|
||||||
safecopy >=0.8,
|
safecopy >=0.8 && <0.9,
|
||||||
uuid >=1.3
|
uuid >=1.3 && <1.4
|
||||||
|
|
||||||
exposed-modules: Network.IRC.Types, Network.IRC.Protocol,
|
exposed-modules: Network.IRC.Types, Network.IRC.Protocol,
|
||||||
Network.IRC.Handlers, Network.IRC.Client
|
Network.IRC.Handlers, Network.IRC.Client
|
||||||
|
@ -91,32 +92,33 @@ executable hask-irc
|
||||||
-- other-modules:
|
-- other-modules:
|
||||||
|
|
||||||
-- LANGUAGE extensions used by modules in this package.
|
-- LANGUAGE extensions used by modules in this package.
|
||||||
other-extensions: Safe
|
default-extensions: NoImplicitPrelude, OverloadedStrings, RecordWildCards, ScopedTypeVariables,
|
||||||
|
BangPatterns, TupleSections
|
||||||
|
|
||||||
-- Other library packages from which modules are imported.
|
-- Other library packages from which modules are imported.
|
||||||
build-depends: base >=4.5 && <4.8,
|
build-depends: base >=4.5 && <4.8,
|
||||||
text >=0.11 && <0.12,
|
text >=0.11 && <0.12,
|
||||||
mtl >=2.1 && <2.2,
|
mtl >=2.1 && <2.2,
|
||||||
network >=2.3 && <2.5,
|
network >=2.3 && <2.5,
|
||||||
configurator >=0.2,
|
configurator >=0.2 && <0.3,
|
||||||
time >=1.4.0,
|
time >=1.4 && <1.5,
|
||||||
curl-aeson ==0.0.3,
|
curl-aeson >=0.0.3 && <0.1,
|
||||||
aeson >=0.6.0.0,
|
aeson >=0.6.0.0 && <0.7,
|
||||||
HTTP >=4000,
|
HTTP >=4000 && <5000,
|
||||||
transformers >=0.3,
|
transformers >=0.3 && <0.4,
|
||||||
classy-prelude ==0.9.1,
|
classy-prelude >=0.9 && <1.0,
|
||||||
text-format >=0.3.1,
|
text-format >=0.3 && <0.4,
|
||||||
filepath >=1.3,
|
filepath >=1.3 && <1.4,
|
||||||
directory >=1.2,
|
directory >=1.2 && <1.3,
|
||||||
lifted-base >=0.2,
|
lifted-base >=0.2 && <0.3,
|
||||||
unix >=2.7,
|
unix >=2.7 && <2.8,
|
||||||
convertible >=1.1,
|
convertible >=1.1 && <1.2,
|
||||||
hslogger >=1.2.4,
|
hslogger >=1.2 && <1.3,
|
||||||
hslogger-template >=2.0,
|
hslogger-template >=2.0 && <2.1,
|
||||||
ixset >=1.0,
|
ixset >=1.0 && <1.1,
|
||||||
acid-state >=0.12,
|
acid-state >=0.12 && <0.13,
|
||||||
safecopy >=0.8,
|
safecopy >=0.8 && <0.9,
|
||||||
uuid >=1.3
|
uuid >=1.3 && <1.4
|
||||||
|
|
||||||
-- Directories containing source files.
|
-- Directories containing source files.
|
||||||
-- hs-source-dirs:
|
-- hs-source-dirs:
|
||||||
|
|
Loading…
Reference in New Issue