freckle-app 1.18.0.0 → 1.18.1.0
raw patch · 60 files changed
+303/−247 lines, 60 filesdep +asyncPVP ok
version bump matches the API change (PVP)
Dependencies added: async
API changes (from Hackage documentation)
+ Freckle.App.Async: ThreadContext :: KeyMap Value -> Maybe Context -> ThreadContext
+ Freckle.App.Async: [blammoContext] :: ThreadContext -> KeyMap Value
+ Freckle.App.Async: [openTelemetryContext] :: ThreadContext -> Maybe Context
+ Freckle.App.Async: data ThreadContext
+ Freckle.App.Async: foldConcurrently :: (MonadUnliftIO m, MonadMask m, Monoid a, Foldable t) => t (m a) -> m a
+ Freckle.App.Async: getThreadContext :: MonadIO m => m ThreadContext
+ Freckle.App.Async: withThreadContext :: (MonadIO m, MonadMask m) => ThreadContext -> m a -> m a
+ Freckle.App.Http: CONNECT :: StdMethod
+ Freckle.App.Http: DELETE :: StdMethod
+ Freckle.App.Http: GET :: StdMethod
+ Freckle.App.Http: HEAD :: StdMethod
+ Freckle.App.Http: OPTIONS :: StdMethod
+ Freckle.App.Http: PATCH :: StdMethod
+ Freckle.App.Http: POST :: StdMethod
+ Freckle.App.Http: PUT :: StdMethod
+ Freckle.App.Http: TRACE :: StdMethod
+ Freckle.App.Http: data () => StdMethod
+ Freckle.App.Http: setRequestMethod :: StdMethod -> Request -> Request
Files
- CHANGELOG.md +9/−1
- freckle-app.cabal +33/−47
- library/Freckle/App/Async.hs +46/−12
- library/Freckle/App/Bugsnag.hs +3/−3
- library/Freckle/App/Bugsnag/HttpException.hs +2/−2
- library/Freckle/App/Bugsnag/MetaData.hs +1/−1
- library/Freckle/App/Bugsnag/SqlError.hs +1/−1
- library/Freckle/App/Csv.hs +10/−10
- library/Freckle/App/Database.hs +8/−8
- library/Freckle/App/Dotenv.hs +1/−1
- library/Freckle/App/Env.hs +3/−3
- library/Freckle/App/Exception.hs +1/−1
- library/Freckle/App/Exception/MonadThrow.hs +2/−2
- library/Freckle/App/Exception/MonadUnliftIO.hs +2/−2
- library/Freckle/App/Faktory/ProducerPool.hs +3/−3
- library/Freckle/App/Ghci.hs +1/−1
- library/Freckle/App/Http.hs +13/−7
- library/Freckle/App/Http/Cache.hs +4/−4
- library/Freckle/App/Http/Cache/Gzip.hs +2/−2
- library/Freckle/App/Http/Cache/Memcached.hs +4/−4
- library/Freckle/App/Http/Cache/State.hs +1/−1
- library/Freckle/App/Http/Header.hs +1/−1
- library/Freckle/App/Http/Retry.hs +1/−1
- library/Freckle/App/Json/Empty.hs +6/−1
- library/Freckle/App/Kafka/Consumer.hs +5/−5
- library/Freckle/App/Kafka/Producer.hs +13/−13
- library/Freckle/App/Memcached.hs +2/−2
- library/Freckle/App/Memcached/CacheKey.hs +1/−1
- library/Freckle/App/Memcached/Client.hs +3/−3
- library/Freckle/App/Memcached/MD5.hs +2/−2
- library/Freckle/App/Memcached/Servers.hs +2/−2
- library/Freckle/App/OpenTelemetry.hs +2/−2
- library/Freckle/App/OpenTelemetry/Context.hs +1/−1
- library/Freckle/App/OpenTelemetry/Http.hs +4/−4
- library/Freckle/App/OpenTelemetry/ThreadContext.hs +1/−1
- library/Freckle/App/Prelude.hs +5/−5
- library/Freckle/App/Random.hs +1/−1
- library/Freckle/App/Scientist.hs +1/−1
- library/Freckle/App/Stats.hs +6/−6
- library/Freckle/App/Stats/Rts.hs +5/−5
- library/Freckle/App/Test.hs +7/−7
- library/Freckle/App/Test/DocTest.hs +3/−3
- library/Freckle/App/Test/Hspec/Runner.hs +1/−1
- library/Freckle/App/Test/Http.hs +6/−6
- library/Freckle/App/Test/Http/MatchRequest.hs +10/−10
- library/Freckle/App/Test/Yesod.hs +6/−6
- library/Freckle/App/Yesod.hs +2/−2
- library/Freckle/App/Yesod/Routes.hs +1/−1
- library/Network/Wai/Middleware/Cors.hs +2/−2
- library/Network/Wai/Middleware/Stats.hs +2/−2
- package.yaml +6/−18
- tests/Freckle/App/AsyncSpec.hs +29/−0
- tests/Freckle/App/Bugsnag/MetaDataSpec.hs +1/−1
- tests/Freckle/App/CsvSpec.hs +3/−3
- tests/Freckle/App/Http/CacheSpec.hs +3/−3
- tests/Freckle/App/HttpSpec.hs +1/−1
- tests/Freckle/App/Memcached/ServersSpec.hs +1/−1
- tests/Freckle/App/MemcachedSpec.hs +4/−4
- tests/Freckle/App/OpenTelemetry/ContextSpec.hs +2/−2
- tests/Main.hs +1/−1
CHANGELOG.md view
@@ -1,4 +1,12 @@-## [_Unreleased_](https://github.com/freckle/freckle-app/compare/v1.17.0.0...main)+## [_Unreleased_](https://github.com/freckle/freckle-app/compare/v1.18.1.0...main)++## [v1.18.1.0](https://github.com/freckle/freckle-app/compare/v1.18.0.0...v1.18.1.0)++- Add `Freckle.App.Http (setRequestMethod)`+- Add `Freckle.App.Async` (`foldConcurrently`, `ThreadContext (..)`,+ `getThreadContext`, `withThreadContext`)+- Bugfix: Utilities in `Freckle.App.Async` now preserve OpenTelemetry context+ (previously were only passing along Blammo logging context) ## [v1.18.0.0](https://github.com/freckle/freckle-app/compare/v1.17.1.0...v1.18.0.0)
freckle-app.cabal view
@@ -1,6 +1,6 @@ cabal-version: 1.18 name: freckle-app-version: 1.18.0.0+version: 1.18.1.0 license: MIT license-file: LICENSE maintainer: Freckle Education@@ -83,22 +83,19 @@ hs-source-dirs: library other-modules: Paths_freckle_app- default-language: Haskell2010+ default-language: GHC2021 default-extensions:- BangPatterns DataKinds DeriveAnyClass DeriveFoldable DeriveFunctor- DeriveGeneric DeriveLift DeriveTraversable DerivingVia- DerivingStrategies FlexibleContexts FlexibleInstances GADTs- GeneralizedNewtypeDeriving LambdaCase MultiParamTypeClasses- NoImplicitPrelude NoMonomorphismRestriction OverloadedStrings- RankNTypes RecordWildCards ScopedTypeVariables StandaloneDeriving- TypeApplications TypeFamilies+ DataKinds DeriveAnyClass DerivingVia DerivingStrategies GADTs+ LambdaCase NoImplicitPrelude NoMonomorphismRestriction+ OverloadedStrings RecordWildCards TypeFamilies ghc-options: -fignore-optim-changes -fwrite-ide-info -Weverything -Wno-all-missed-specialisations -Wno-missing-exported-signatures- -Wno-missing-import-lists -Wno-missing-local-signatures- -Wno-missing-safe-haskell-mode -Wno-monomorphism-restriction- -Wno-prepositive-qualified-module -Wno-safe -Wno-unsafe+ -Wno-missing-import-lists -Wno-missing-kind-signatures+ -Wno-missing-local-signatures -Wno-missing-safe-haskell-mode+ -Wno-monomorphism-restriction -Wno-prepositive-qualified-module+ -Wno-safe -Wno-unsafe build-depends: Blammo >=1.2.0.0,@@ -184,48 +181,42 @@ yesod-test >=1.6.15 if impl(ghc >=9.8)- ghc-options: -Wno-missing-role-annotations-- if impl(ghc >=9.2)- ghc-options: -Wno-missing-kind-signatures+ ghc-options:+ -Wno-missing-role-annotations -Wno-missing-poly-kind-signatures test-suite doctest type: exitcode-stdio-1.0 main-is: Main.hs hs-source-dirs: doctest other-modules: Paths_freckle_app- default-language: Haskell2010+ default-language: GHC2021 default-extensions:- BangPatterns DataKinds DeriveAnyClass DeriveFoldable DeriveFunctor- DeriveGeneric DeriveLift DeriveTraversable DerivingVia- DerivingStrategies FlexibleContexts FlexibleInstances GADTs- GeneralizedNewtypeDeriving LambdaCase MultiParamTypeClasses- NoImplicitPrelude NoMonomorphismRestriction OverloadedStrings- RankNTypes RecordWildCards ScopedTypeVariables StandaloneDeriving- TypeApplications TypeFamilies+ DataKinds DeriveAnyClass DerivingVia DerivingStrategies GADTs+ LambdaCase NoImplicitPrelude NoMonomorphismRestriction+ OverloadedStrings RecordWildCards TypeFamilies ghc-options: -fignore-optim-changes -fwrite-ide-info -Weverything -Wno-all-missed-specialisations -Wno-missing-exported-signatures- -Wno-missing-import-lists -Wno-missing-local-signatures- -Wno-missing-safe-haskell-mode -Wno-monomorphism-restriction- -Wno-prepositive-qualified-module -Wno-safe -Wno-unsafe+ -Wno-missing-import-lists -Wno-missing-kind-signatures+ -Wno-missing-local-signatures -Wno-missing-safe-haskell-mode+ -Wno-monomorphism-restriction -Wno-prepositive-qualified-module+ -Wno-safe -Wno-unsafe build-depends: base >=4.16.4.0 && <5, freckle-app if impl(ghc >=9.8)- ghc-options: -Wno-missing-role-annotations-- if impl(ghc >=9.2)- ghc-options: -Wno-missing-kind-signatures+ ghc-options:+ -Wno-missing-role-annotations -Wno-missing-poly-kind-signatures test-suite spec type: exitcode-stdio-1.0 main-is: Main.hs hs-source-dirs: tests other-modules:+ Freckle.App.AsyncSpec Freckle.App.Bugsnag.MetaDataSpec Freckle.App.BugsnagSpec Freckle.App.CsvSpec@@ -241,28 +232,25 @@ Spec Paths_freckle_app - default-language: Haskell2010+ default-language: GHC2021 default-extensions:- BangPatterns DataKinds DeriveAnyClass DeriveFoldable DeriveFunctor- DeriveGeneric DeriveLift DeriveTraversable DerivingVia- DerivingStrategies FlexibleContexts FlexibleInstances GADTs- GeneralizedNewtypeDeriving LambdaCase MultiParamTypeClasses- NoImplicitPrelude NoMonomorphismRestriction OverloadedStrings- RankNTypes RecordWildCards ScopedTypeVariables StandaloneDeriving- TypeApplications TypeFamilies+ DataKinds DeriveAnyClass DerivingVia DerivingStrategies GADTs+ LambdaCase NoImplicitPrelude NoMonomorphismRestriction+ OverloadedStrings RecordWildCards TypeFamilies ghc-options: -fignore-optim-changes -fwrite-ide-info -Weverything -Wno-all-missed-specialisations -Wno-missing-exported-signatures- -Wno-missing-import-lists -Wno-missing-local-signatures- -Wno-missing-safe-haskell-mode -Wno-monomorphism-restriction- -Wno-prepositive-qualified-module -Wno-safe -Wno-unsafe -threaded- -rtsopts -with-rtsopts=-N+ -Wno-missing-import-lists -Wno-missing-kind-signatures+ -Wno-missing-local-signatures -Wno-missing-safe-haskell-mode+ -Wno-monomorphism-restriction -Wno-prepositive-qualified-module+ -Wno-safe -Wno-unsafe -threaded -rtsopts -with-rtsopts=-N build-depends: Blammo >=1.2.0.0, QuickCheck >=2.14.3, aeson >=2.0.3.0,+ async >=2.2.4, base >=4.16.4.0 && <5, bugsnag >=1.1.0.0, bytestring >=0.11.4.0,@@ -291,7 +279,5 @@ zlib >=0.6.3.0 if impl(ghc >=9.8)- ghc-options: -Wno-missing-role-annotations-- if impl(ghc >=9.2)- ghc-options: -Wno-missing-kind-signatures+ ghc-options:+ -Wno-missing-role-annotations -Wno-missing-poly-kind-signatures
library/Freckle/App/Async.hs view
@@ -1,26 +1,43 @@ module Freckle.App.Async ( async+ , foldConcurrently , immortalCreate , immortalCreateLogged- )-where+ , ThreadContext (..)+ , getThreadContext+ , withThreadContext+ ) where import Freckle.App.Prelude -import Blammo.Logging-import qualified Control.Immortal as Immortal+import Blammo.Logging (Message (..), MonadLogger, MonadMask, logError, (.=))+import Blammo.Logging qualified as Blammo+import Control.Immortal qualified as Immortal import Control.Monad (forever)-import qualified Data.Aeson.Compat as KeyMap-import UnliftIO.Async (Async)-import qualified UnliftIO.Async as UnliftIO+import Data.Aeson (Value)+import Data.Aeson.Compat (KeyMap)+import Data.Aeson.Compat qualified as KeyMap+import OpenTelemetry.Context qualified as OpenTelemetry+import OpenTelemetry.Context.ThreadLocal qualified as OpenTelemetry+import UnliftIO.Async (Async, conc, runConc)+import UnliftIO.Async qualified as UnliftIO import UnliftIO.Concurrent (threadDelay) -- | 'UnliftIO.Async.async' but passing the thread context along async :: (MonadMask m, MonadUnliftIO m) => m a -> m (Async a) async f = do- tc <- liftIO $ KeyMap.toList <$> myThreadContext- UnliftIO.async $ withThreadContext tc f+ context <- getThreadContext+ UnliftIO.async $ withThreadContext context f +-- | Run a list of actions concurrently+--+-- The forked threads will have the current thread context copied to them.+foldConcurrently+ :: (MonadUnliftIO m, MonadMask m, Monoid a, Foldable t) => t (m a) -> m a+foldConcurrently xs = do+ context <- getThreadContext+ runConc $ foldMap (conc . withThreadContext context) xs+ -- | Wrapper around creating "Control.Immortal" processes -- -- Features:@@ -36,11 +53,11 @@ -- ^ The action to run persistently -> m a immortalCreate onUnexpected act = do- tc <- liftIO $ KeyMap.toList <$> myThreadContext+ context <- getThreadContext let- act' = withThreadContext tc act- onUnexpected' = withThreadContext tc . onUnexpected+ act' = withThreadContext context act+ onUnexpected' = withThreadContext context . onUnexpected void $ Immortal.create $ \thread -> do Immortal.onUnexpectedFinish thread onUnexpected' act'@@ -53,3 +70,20 @@ immortalCreateLogged = immortalCreate $ either logEx pure where logEx ex = logError $ "Unexpected Finish" :# ["exception" .= displayException ex]++data ThreadContext = ThreadContext+ { blammoContext :: KeyMap Value+ , openTelemetryContext :: Maybe OpenTelemetry.Context+ }++getThreadContext :: MonadIO m => m ThreadContext+getThreadContext =+ ThreadContext+ <$> liftIO Blammo.myThreadContext+ <*> OpenTelemetry.lookupContext++withThreadContext :: (MonadIO m, MonadMask m) => ThreadContext -> m a -> m a+withThreadContext ThreadContext {blammoContext, openTelemetryContext} continue =+ Blammo.withThreadContext (KeyMap.toList blammoContext) $ do+ traverse_ @Maybe OpenTelemetry.attachContext openTelemetryContext+ continue
library/Freckle/App/Bugsnag.hs view
@@ -19,7 +19,7 @@ import Freckle.App.Prelude -import qualified Control.Exception as Base (Exception)+import Control.Exception qualified as Base (Exception) import Control.Lens (Lens', view) import Control.Monad.Catch (MonadMask) import Control.Monad.Reader (runReaderT)@@ -29,9 +29,9 @@ import Freckle.App.Async (async) import Freckle.App.Bugsnag.HttpException (httpExceptionBeforeNotify) import Freckle.App.Bugsnag.SqlError (sqlErrorBeforeNotify)-import qualified Freckle.App.Env as Env+import Freckle.App.Env qualified as Env import Network.Bugsnag hiding (notifyBugsnag, notifyBugsnagWith)-import qualified Network.Bugsnag as Bugsnag+import Network.Bugsnag qualified as Bugsnag import Yesod.Core.Lens (envL, siteL) import Yesod.Core.Types (HandlerData)
library/Freckle/App/Bugsnag/HttpException.hs view
@@ -8,9 +8,9 @@ import Freckle.App.Prelude import Data.Bugsnag (Exception (..))-import qualified Data.ByteString.Char8 as BS8+import Data.ByteString.Char8 qualified as BS8 import Freckle.App.Exception.Types (AnnotatedException)-import qualified Freckle.App.Exception.Types as Annotated+import Freckle.App.Exception.Types qualified as Annotated import Network.Bugsnag ( BeforeNotify , setGroupingHash
library/Freckle/App/Bugsnag/MetaData.hs view
@@ -18,7 +18,7 @@ import Blammo.Logging (myThreadContext) import Control.Lens (Lens', lens, to, view, (<>~)) import Data.Aeson (Value (..))-import qualified Data.Aeson.KeyMap as KeyMap+import Data.Aeson.KeyMap qualified as KeyMap import Data.Bugsnag (Event (..)) import Data.String (fromString) import Freckle.App.Stats (HasStatsClient (..), tagsL)
library/Freckle/App/Bugsnag/SqlError.hs view
@@ -17,7 +17,7 @@ , constraintViolation ) import Freckle.App.Exception.Types (AnnotatedException)-import qualified Freckle.App.Exception.Types as Annotated+import Freckle.App.Exception.Types qualified as Annotated import Network.Bugsnag ( BeforeNotify , setGroupingHash
library/Freckle/App/Csv.hs view
@@ -40,9 +40,9 @@ ) import Data.Aeson (KeyValue (..), ToJSON (..), object, pairs, (.=)) import Data.ByteString (ByteString)-import qualified Data.ByteString.Char8 as BS8-import qualified Data.Conduit.Combinators as Conduit-import qualified Data.Conduit.Text as Conduit+import Data.ByteString.Char8 qualified as BS8+import Data.Conduit.Combinators qualified as Conduit+import Data.Conduit.Text qualified as Conduit import Data.Csv ( DefaultOrdered , FromNamedRecord (..)@@ -54,17 +54,17 @@ , defaultOptions , headerOrder )-import qualified Data.Csv.Incremental as CsvI+import Data.Csv.Incremental qualified as CsvI import Data.Functor.Bind (Bind)-import qualified Data.HashMap.Strict as HashMap-import qualified Data.List.NonEmpty as NE+import Data.HashMap.Strict qualified as HashMap+import Data.List.NonEmpty qualified as NE import Data.Proxy (Proxy (Proxy)) import Data.Sequence (Seq)-import qualified Data.Sequence as Seq+import Data.Sequence qualified as Seq import Data.Sequence.NonEmpty (NESeq)-import qualified Data.Text as T-import qualified Data.Text.Encoding as T-import qualified Data.Vector as V+import Data.Text qualified as T+import Data.Text.Encoding qualified as T+import Data.Vector qualified as V -- | Treat CSV header line as 1 --
library/Freckle/App/Database.hs view
@@ -39,14 +39,14 @@ import Freckle.App.Prelude import Blammo.Logging-import qualified Control.Immortal as Immortal+import Control.Immortal qualified as Immortal import Control.Monad.Reader import Data.ByteString (ByteString)-import qualified Data.ByteString.Char8 as BS8-import qualified Data.ByteString.Lazy as BSL-import qualified Data.HashMap.Strict as HashMap+import Data.ByteString.Char8 qualified as BS8+import Data.ByteString.Lazy qualified as BSL+import Data.HashMap.Strict qualified as HashMap import Data.Pool-import qualified Data.Text as T+import Data.Text qualified as T import Database.Persist.Postgresql ( SqlBackend , SqlPersistT@@ -66,13 +66,13 @@ ) import Database.PostgreSQL.Simple.SqlQQ (sql) import Freckle.App.Env (Timeout (..))-import qualified Freckle.App.Env as Env+import Freckle.App.Env qualified as Env import Freckle.App.Exception.MonadUnliftIO import Freckle.App.OpenTelemetry import Freckle.App.Stats (HasStatsClient)-import qualified Freckle.App.Stats as Stats+import Freckle.App.Stats qualified as Stats import OpenTelemetry.Instrumentation.Persistent-import qualified OpenTelemetry.Trace as Trace+import OpenTelemetry.Trace qualified as Trace import System.Process.Typed (proc, readProcessStdout_) import UnliftIO.Concurrent (threadDelay) import UnliftIO.IORef
library/Freckle/App/Dotenv.hs view
@@ -7,7 +7,7 @@ import Freckle.App.Prelude -import qualified Configuration.Dotenv as Dotenv+import Configuration.Dotenv qualified as Dotenv import System.FilePath (takeDirectory, (</>)) import UnliftIO.Directory (doesFileExist, getCurrentDirectory)
library/Freckle/App/Env.hs view
@@ -39,11 +39,11 @@ import Control.Error.Util (note) import Data.Char (isDigit)-import qualified Data.Text as T+import Data.Text qualified as T import Data.Time (defaultTimeLocale, parseTimeM) import Env hiding (flag)-import qualified Env-import qualified Prelude as Unsafe (read)+import Env qualified+import Prelude qualified as Unsafe (read) -- | Designates the value of a parameter when a flag is not provided. newtype Off a = Off a
library/Freckle/App/Exception.hs view
@@ -12,7 +12,7 @@ import Prelude import Control.Exception.Annotated (annotatedExceptionCallStack)-import qualified Control.Exception.Annotated as AnnotatedException+import Control.Exception.Annotated qualified as AnnotatedException import Control.Monad.Logger.Aeson (Message (..), (.=)) import Data.Aeson (object) import Freckle.App.Exception.MonadUnliftIO
library/Freckle/App/Exception/MonadThrow.hs view
@@ -34,8 +34,8 @@ import GHC.IO.Exception (userError) import GHC.Stack (withFrozenCallStack) -import qualified Control.Exception.Annotated as Annotated-import qualified Control.Monad.Catch+import Control.Exception.Annotated qualified as Annotated+import Control.Monad.Catch qualified -- Throws an exception, wrapped in 'AnnotatedException' which includes a call stack throwM :: forall e m a. (Exception e, MonadThrow m, HasCallStack) => e -> m a
library/Freckle/App/Exception/MonadUnliftIO.hs view
@@ -35,8 +35,8 @@ import System.IO (IO) import UnliftIO (MonadIO, MonadUnliftIO) -import qualified Control.Exception.Annotated.UnliftIO as Annotated-import qualified UnliftIO.Exception+import Control.Exception.Annotated.UnliftIO qualified as Annotated+import UnliftIO.Exception qualified -- Throws an exception, wrapped in 'AnnotatedException' which includes a call stack throwM :: forall e m a. (Exception e, MonadIO m, HasCallStack) => e -> m a
library/Freckle/App/Faktory/ProducerPool.hs view
@@ -17,9 +17,9 @@ , newPool , setNumStripes )-import qualified Faktory.Producer as Faktory-import qualified Faktory.Settings as Faktory-import qualified Freckle.App.Env as Env+import Faktory.Producer qualified as Faktory+import Faktory.Settings qualified as Faktory+import Freckle.App.Env qualified as Env import Yesod.Core.Lens (envL, siteL) import Yesod.Core.Types (HandlerData)
library/Freckle/App/Ghci.hs view
@@ -9,7 +9,7 @@ import Database.Persist.Postgresql (runSqlPool) import Database.Persist.Sql (SqlBackend) import Freckle.App.Database (makePostgresPool)-import qualified Freckle.App.Dotenv as Dotenv+import Freckle.App.Dotenv qualified as Dotenv -- | Run a db action against .env runDB :: ReaderT SqlBackend IO b -> IO b
library/Freckle/App/Http.hs view
@@ -32,6 +32,7 @@ , setRequestBodyJSON , setRequestBodyURLEncoded , setRequestCheckStatus+ , setRequestMethod , setRequestPath , disableRequestDecompress @@ -71,6 +72,7 @@ , statusIsRedirection , statusIsClientError , statusIsServerError+ , StdMethod (..) ) where import Freckle.App.Prelude@@ -82,17 +84,18 @@ import Control.Monad.Validate (ValidateT) import Control.Monad.Writer (WriterT) import Data.Aeson (FromJSON)-import qualified Data.Aeson as Aeson-import qualified Data.ByteString as BS+import Data.Aeson qualified as Aeson+import Data.ByteString qualified as BS import Data.ByteString.Lazy (ByteString)-import qualified Data.ByteString.Lazy.Char8 as BSL8-import qualified Data.List.NonEmpty as NE+import Data.ByteString.Lazy.Char8 qualified as BSL8+import Data.List.NonEmpty qualified as NE import Freckle.App.Http.Paginate import Freckle.App.Http.Retry-import qualified Network.HTTP.Client as HTTP (Request (..))+import Network.HTTP.Client qualified as HTTP (Request (..)) import Network.HTTP.Conduit (HttpExceptionContent (..))-import Network.HTTP.Simple hiding (httpLbs, httpNoBody)-import qualified Network.HTTP.Simple as HTTP+import Network.HTTP.Simple hiding (httpLbs, httpNoBody, setRequestMethod)+import Network.HTTP.Simple qualified as HTTP+import Network.HTTP.Types (StdMethod (..), renderStdMethod) import Network.HTTP.Types.Header (hAccept, hAuthorization) import Network.HTTP.Types.Status ( Status@@ -250,6 +253,9 @@ addBearerAuthorizationHeader :: BS.ByteString -> Request -> Request addBearerAuthorizationHeader = addRequestHeader hAuthorization . ("Bearer " <>)++setRequestMethod :: StdMethod -> Request -> Request+setRequestMethod method req = req {HTTP.method = renderStdMethod method} disableRequestDecompress :: Request -> Request disableRequestDecompress req =
library/Freckle/App/Http/Cache.hs view
@@ -16,9 +16,9 @@ import Blammo.Logging (Message (..), (.=)) import Data.ByteString (ByteString)-import qualified Data.ByteString.Char8 as BS8-import qualified Data.ByteString.Lazy as BSL-import qualified Data.CaseInsensitive as CI+import Data.ByteString.Char8 qualified as BS8+import Data.ByteString.Lazy qualified as BSL+import Data.CaseInsensitive qualified as CI import Data.List.Extra (firstJust) import Data.Text.Encoding (decodeUtf8With) import Data.Text.Encoding.Error (lenientDecode)@@ -28,7 +28,7 @@ import Freckle.App.Http.Header import Freckle.App.Memcached import Network.HTTP.Client (Request, Response)-import qualified Network.HTTP.Client as HTTP+import Network.HTTP.Client qualified as HTTP import Network.HTTP.Simple ( addRequestHeader , getRequestHeader
library/Freckle/App/Http/Cache/Gzip.hs view
@@ -23,11 +23,11 @@ import Codec.Serialise (Serialise) import Data.ByteString.Lazy (ByteString)-import qualified Data.ByteString.Lazy as BSL+import Data.ByteString.Lazy qualified as BSL import Freckle.App.Http (disableRequestDecompress) import Freckle.App.Http.Header import Network.HTTP.Client (Request, Response)-import qualified Network.HTTP.Client.Internal as HTTP+import Network.HTTP.Client.Internal qualified as HTTP newtype PotentiallyGzipped a = PotentiallyGzipped { unwrap :: a
library/Freckle/App/Http/Cache/Memcached.hs view
@@ -13,16 +13,16 @@ import Blammo.Logging (MonadLogger, logDebugNS, logWarnNS) import Codec.Serialise (Serialise (..), deserialiseOrFail, serialise)-import qualified Data.ByteString.Lazy as BSL+import Data.ByteString.Lazy qualified as BSL import Data.CaseInsensitive (CI)-import qualified Data.CaseInsensitive as CI+import Data.CaseInsensitive qualified as CI import Database.Memcache.Types (Value) import Freckle.App.Http.Cache import Freckle.App.Memcached-import qualified Freckle.App.Memcached.Client as Memcached+import Freckle.App.Memcached.Client qualified as Memcached import Freckle.App.OpenTelemetry (MonadTracer) import Network.HTTP.Client (Request)-import qualified Network.HTTP.Client.Internal as HTTP+import Network.HTTP.Client.Internal qualified as HTTP import Network.HTTP.Types.Header (ResponseHeaders) import Network.HTTP.Types.Status (Status (..)) import Network.HTTP.Types.Version (HttpVersion (..))
library/Freckle/App/Http/Cache/State.hs view
@@ -22,7 +22,7 @@ import Control.Monad.State import Data.Text.Encoding (decodeUtf8With) import Data.Text.Encoding.Error (lenientDecode)-import qualified Data.Text.IO as T+import Data.Text.IO qualified as T import Freckle.App.Http.Cache import Freckle.App.Memcached.CacheKey import Freckle.App.Memcached.CacheTTL
library/Freckle/App/Http/Header.hs view
@@ -10,7 +10,7 @@ import Freckle.App.Prelude import Data.ByteString (ByteString)-import qualified Data.ByteString.Char8 as BS8+import Data.ByteString.Char8 qualified as BS8 import Data.Char (isSpace) import Network.HTTP.Client (Request, Response, requestHeaders, responseHeaders) import Network.HTTP.Simple (getRequestHeader, getResponseHeader)
library/Freckle/App/Http/Retry.hs view
@@ -7,7 +7,7 @@ import Freckle.App.Prelude import Control.Retry-import qualified Data.ByteString.Char8 as BS8+import Data.ByteString.Char8 qualified as BS8 import Network.HTTP.Client (Request (..)) import Network.HTTP.Simple import Network.HTTP.Types.Status (status429)
library/Freckle/App/Json/Empty.hs view
@@ -5,7 +5,12 @@ import Freckle.App.Prelude -import Autodocodec (Autodocodec (..), HasCodec (..), HasObjectCodec (..), object)+import Autodocodec+ ( Autodocodec (..)+ , HasCodec (..)+ , HasObjectCodec (..)+ , object+ ) import Autodocodec.OpenAPI () import Data.Aeson (FromJSON, ToJSON) import Data.OpenApi (ToSchema (..))
library/Freckle/App/Kafka/Consumer.hs view
@@ -15,10 +15,10 @@ import Control.Monad (forever) import Data.Aeson import Data.ByteString (ByteString)-import qualified Data.List.NonEmpty as NE-import qualified Data.Map.Strict as Map-import qualified Data.Text as T-import qualified Env+import Data.List.NonEmpty qualified as NE+import Data.Map.Strict qualified as Map+import Data.Text qualified as T+import Env qualified import Freckle.App.Async import Freckle.App.Env import Freckle.App.Exception (annotatedExceptionMessageFrom)@@ -32,7 +32,7 @@ , runConsumer , subscription )-import qualified Kafka.Consumer as Kafka+import Kafka.Consumer qualified as Kafka import UnliftIO.Exception (bracket) data KafkaConsumerConfig = KafkaConsumerConfig
library/Freckle/App/Kafka/Producer.hs view
@@ -18,16 +18,16 @@ import Control.Lens (Lens', view) import Data.Aeson (ToJSON, encode) import Data.ByteString.Lazy (toStrict)-import qualified Data.HashMap.Strict as HashMap-import qualified Data.List.NonEmpty as NE+import Data.HashMap.Strict qualified as HashMap+import Data.List.NonEmpty qualified as NE import Data.Pool (Pool)-import qualified Data.Pool as Pool-import qualified Data.Text as T+import Data.Pool qualified as Pool+import Data.Text qualified as T import Freckle.App.Async (async)-import qualified Freckle.App.Env as Env+import Freckle.App.Env qualified as Env import Freckle.App.OpenTelemetry import Kafka.Producer-import qualified OpenTelemetry.Trace as Trace+import OpenTelemetry.Trace qualified as Trace import UnliftIO (withRunInIO) import Yesod.Core.Lens import Yesod.Core.Types (HandlerData)@@ -92,13 +92,13 @@ -> KafkaProducerPoolConfig -> IO (Pool KafkaProducer) createKafkaProducerPool addresses KafkaProducerPoolConfig {..} =- Pool.newPool- $ Pool.setNumStripes (Just kafkaProducerPoolConfigStripes)- $ Pool.defaultPoolConfig- mkProducer- closeProducer- (realToFrac kafkaProducerPoolConfigIdleTimeout)- kafkaProducerPoolConfigSize+ Pool.newPool $+ Pool.setNumStripes (Just kafkaProducerPoolConfigStripes) $+ Pool.defaultPoolConfig+ mkProducer+ closeProducer+ (realToFrac kafkaProducerPoolConfigIdleTimeout)+ kafkaProducerPoolConfigSize where mkProducer = either
library/Freckle/App/Memcached.hs view
@@ -28,14 +28,14 @@ import Codec.Serialise (Serialise, deserialiseOrFail, serialise) import Data.Aeson import Data.ByteString (ByteString)-import qualified Data.ByteString.Lazy as BSL+import Data.ByteString.Lazy qualified as BSL import Data.Text.Encoding (decodeUtf8With) import Data.Text.Encoding.Error (lenientDecode) import Freckle.App.Exception (annotatedExceptionMessage) import Freckle.App.Memcached.CacheKey import Freckle.App.Memcached.CacheTTL import Freckle.App.Memcached.Client (HasMemcachedClient (..))-import qualified Freckle.App.Memcached.Client as Memcached+import Freckle.App.Memcached.Client qualified as Memcached import Freckle.App.Memcached.MD5 import Freckle.App.OpenTelemetry
library/Freckle/App/Memcached/CacheKey.hs view
@@ -8,7 +8,7 @@ import Freckle.App.Prelude import Data.Char (isControl, isSpace)-import qualified Data.Text as T+import Data.Text qualified as T import Database.Memcache.Types (Key) import OpenTelemetry.Trace (ToAttribute (..))
library/Freckle/App/Memcached/Client.hs view
@@ -12,14 +12,14 @@ import Freckle.App.Prelude import Control.Lens (Lens', view, _1)-import qualified Data.HashMap.Strict as HashMap-import qualified Database.Memcache.Client as Memcache+import Data.HashMap.Strict qualified as HashMap+import Database.Memcache.Client qualified as Memcache import Database.Memcache.Types (Value, Version) import Freckle.App.Memcached.CacheKey import Freckle.App.Memcached.CacheTTL import Freckle.App.Memcached.Servers import Freckle.App.OpenTelemetry-import qualified OpenTelemetry.Trace as Trace+import OpenTelemetry.Trace qualified as Trace import UnliftIO.Exception (finally) import Yesod.Core.Lens import Yesod.Core.Types (HandlerData)
library/Freckle/App/Memcached/MD5.hs view
@@ -6,8 +6,8 @@ import Freckle.App.Prelude -import qualified Data.ByteString.Lazy as BSL-import qualified Data.Digest.Pure.MD5 as Digest+import Data.ByteString.Lazy qualified as BSL+import Data.Digest.Pure.MD5 qualified as Digest import Freckle.App.Memcached.CacheKey md5CacheKey :: Show a => a -> CacheKey
library/Freckle/App/Memcached/Servers.hs view
@@ -29,8 +29,8 @@ import Freckle.App.Prelude import Control.Error.Util (note)-import qualified Data.Text as T-import qualified Database.Memcache.Client as Memcache+import Data.Text qualified as T+import Database.Memcache.Client qualified as Memcache import Network.URI (URI (..), URIAuth (..), parseAbsoluteURI) newtype MemcachedServers = MemcachedServers
library/Freckle/App/OpenTelemetry.hs view
@@ -67,14 +67,14 @@ import Freckle.App.Prelude import Data.ByteString (ByteString)-import qualified Data.Text as T+import Data.Text qualified as T import Data.Text.Encoding (decodeUtf8With) import Data.Text.Encoding.Error (lenientDecode) import OpenTelemetry.Context (lookupSpan) import OpenTelemetry.Context.ThreadLocal (getContext) import OpenTelemetry.Trace hiding (inSpan) import OpenTelemetry.Trace.Core (getSpanContext)-import qualified OpenTelemetry.Trace.Core as Trace (SpanContext (..))+import OpenTelemetry.Trace.Core qualified as Trace (SpanContext (..)) import OpenTelemetry.Trace.Id ( Base (..) , SpanId
library/Freckle/App/OpenTelemetry/Context.hs view
@@ -14,7 +14,7 @@ import Data.Aeson (FromJSON, ToJSON) import Data.ByteString (ByteString) import Data.CaseInsensitive (CI)-import qualified Data.CaseInsensitive as CI+import Data.CaseInsensitive qualified as CI import Faktory.Job (Job, custom, jobOptions) import Faktory.Job.Custom (fromCustom, toCustom) import Faktory.JobOptions (JobOptions (..))
library/Freckle/App/OpenTelemetry/Http.hs view
@@ -7,9 +7,9 @@ import Freckle.App.Prelude -import qualified Data.CaseInsensitive as CI-import qualified Data.HashMap.Strict as HashMap-import qualified Data.Text as T+import Data.CaseInsensitive qualified as CI+import Data.HashMap.Strict qualified as HashMap+import Data.Text qualified as T import Data.Text.Encoding (decodeUtf8With) import Data.Text.Encoding.Error (lenientDecode) import Freckle.App.OpenTelemetry@@ -18,7 +18,7 @@ , clientSpanArguments ) import Network.HTTP.Client (Request, Response)-import qualified Network.HTTP.Client as HTTP+import Network.HTTP.Client qualified as HTTP import Network.HTTP.Types.Status (statusCode) import OpenTelemetry.Attributes (Attribute, ToAttribute (..))
library/Freckle/App/OpenTelemetry/ThreadContext.hs view
@@ -8,7 +8,7 @@ import Blammo.Logging (MonadMask, withThreadContext) import Data.Aeson ((.=))-import qualified Data.Aeson.Key as Key+import Data.Aeson.Key qualified as Key import Data.Aeson.Types (Pair) import Freckle.App.OpenTelemetry (getCurrentSpanContext) import OpenTelemetry.Trace.Core (SpanContext (..))
library/Freckle/App/Prelude.hs view
@@ -88,7 +88,7 @@ -- ** 'UTCTime' , getCurrentTime - -- * Exceptions+ -- * Exceptions , throwM , throwString , fromJustNoteM@@ -112,14 +112,14 @@ , head , init , last+#if MIN_VERSION_base(4,18,0)+ , liftA2+#endif , maximum , minimum , read , tail , (!!)-#if MIN_VERSION_base(4,18,0)- , liftA2-#endif ) -- Commonly used types (and their commonly used functions)@@ -135,10 +135,10 @@ import Data.List.NonEmpty (NonEmpty) import Data.Map.Strict (Map) import Data.Set (Set)-import Freckle.App.Exception import Data.Text (Text, pack, unpack) import Data.Time (NominalDiffTime, UTCTime, getCurrentTime) import Data.Vector (Vector)+import Freckle.App.Exception import GHC.Generics (Generic) -- Safe alternatives to prelude functions
library/Freckle/App/Random.hs view
@@ -16,7 +16,7 @@ import Data.STRef (newSTRef, readSTRef, writeSTRef) import Numeric.Natural (Natural) -import qualified Data.Set as Set+import Data.Set qualified as Set -- | A possibly-empty contiguous range of integers data Range i
library/Freckle/App/Scientist.hs view
@@ -5,7 +5,7 @@ import Freckle.App.Prelude import Freckle.App.Stats (HasStatsClient)-import qualified Freckle.App.Stats as Stats+import Freckle.App.Stats qualified as Stats import Scientist import Scientist.Duration
library/Freckle/App/Stats.hs view
@@ -44,10 +44,10 @@ import Data.String import Data.Time (diffUTCTime) import Freckle.App.Ecs-import qualified Freckle.App.Env as Env-import qualified Network.StatsD.Datadog as Datadog+import Freckle.App.Env qualified as Env+import Network.StatsD.Datadog qualified as Datadog import System.IO (hPutStrLn, stderr)-import qualified System.Metrics.Gauge as EKG+import System.Metrics.Gauge qualified as EKG import UnliftIO.Exception (bracket_) import Yesod.Core.Lens import Yesod.Core.Types (HandlerData)@@ -178,9 +178,9 @@ withGauge getGauge f = do gauge' <- lookupGauge getGauge bracket_ (inc gauge') (dec gauge') f- where- inc = incGauge- dec = decGauge+ where+ inc = incGauge+ dec = decGauge lookupGauge :: (MonadReader app m, HasStatsClient app)
library/Freckle/App/Stats/Rts.hs view
@@ -5,12 +5,12 @@ import Freckle.App.Prelude -import qualified Control.Immortal as Immortal-import qualified Data.HashMap.Strict as HashMap+import Control.Immortal qualified as Immortal+import Data.HashMap.Strict qualified as HashMap import Freckle.App.Stats (HasStatsClient)-import qualified Freckle.App.Stats as Stats-import qualified System.Metrics as Ekg-import qualified System.Metrics.Distribution.Internal as Ekg+import Freckle.App.Stats qualified as Stats+import System.Metrics qualified as Ekg+import System.Metrics.Distribution.Internal qualified as Ekg import UnliftIO.Concurrent (threadDelay) -- | Initialize a thread to poll RTS stats
library/Freckle/App/Test.hs view
@@ -37,8 +37,8 @@ import Control.Lens (view) import Control.Monad.Base import Control.Monad.Catch (ExitCase (..), MonadCatch, MonadThrow, mask)-import qualified Control.Monad.Catch-import qualified Control.Monad.Fail as Fail+import Control.Monad.Catch qualified+import Control.Monad.Fail qualified as Fail import Control.Monad.Primitive import Control.Monad.Random (MonadRandom (..)) import Control.Monad.Reader@@ -50,13 +50,13 @@ , MonadSqlTx (..) , runDB )-import qualified Freckle.App.Dotenv as Dotenv-import qualified Freckle.App.Exception.MonadThrow as MonadThrow+import Freckle.App.Dotenv qualified as Dotenv+import Freckle.App.Exception.MonadThrow qualified as MonadThrow import Freckle.App.OpenTelemetry-import qualified Test.Hspec as Hspec hiding (expectationFailure)+import Test.Hspec qualified as Hspec hiding (expectationFailure) import Test.Hspec.Core.Spec (Arg, Example, SpecWith, evaluateExample)-import qualified Test.Hspec.Expectations.Lifted as Hspec (expectationFailure)-import qualified UnliftIO.Exception as UnliftIO+import Test.Hspec.Expectations.Lifted qualified as Hspec (expectationFailure)+import UnliftIO.Exception qualified as UnliftIO -- | An Hspec example over some @App@ value --
library/Freckle/App/Test/DocTest.hs view
@@ -13,10 +13,10 @@ import Control.Monad (filterM) import Data.Aeson-import qualified Data.Text as T-import qualified Data.Text.IO as T+import Data.Text qualified as T+import Data.Text.IO qualified as T import Data.Yaml (decodeFileThrow)-import qualified Test.DocTest as DocTest+import Test.DocTest qualified as DocTest import "Glob" System.FilePath.Glob (globDir1) -- | Run doctest on files in the given directory
library/Freckle/App/Test/Hspec/Runner.hs view
@@ -29,7 +29,7 @@ , hspecWithResult , readConfig )-import qualified Prelude as Unsafe (read)+import Prelude qualified as Unsafe (read) run :: String -> Spec -> IO () run = runWith defaultConfig
library/Freckle/App/Test/Http.hs view
@@ -49,13 +49,13 @@ import Control.Monad (filterM) import Control.Monad.Reader (runReaderT) import Data.Aeson (ToJSON, encode)-import qualified Data.ByteString.Lazy as BSL+import Data.ByteString.Lazy qualified as BSL import Data.List (stripPrefix) import Data.String (IsString (..)) import Freckle.App.Http (MonadHttp (..)) import Freckle.App.Test.Http.MatchRequest import Network.HTTP.Client (Request, Response)-import qualified Network.HTTP.Client.Internal as HTTP+import Network.HTTP.Client.Internal qualified as HTTP import Network.HTTP.Types.Header (ResponseHeaders, hAccept, hContentType) import Network.HTTP.Types.Status (Status, status200) import System.Directory (doesFileExist)@@ -86,11 +86,11 @@ maybe (error errorMessage) (toResponse req) $ headMay matched where (unmatched, matched) =- partitionEithers $- map+ partitionEithers+ $ map ( \stub ->- bimap (stub,) (const stub.response) $- matchRequest req stub.match+ bimap (stub,) (const stub.response)+ $ matchRequest req stub.match ) stubs
library/Freckle/App/Test/Http/MatchRequest.hs view
@@ -24,13 +24,13 @@ import Freckle.App.Prelude import Data.ByteString (ByteString)-import qualified Data.ByteString.Char8 as BS8-import qualified Data.ByteString.Lazy as BSL+import Data.ByteString.Char8 qualified as BS8+import Data.ByteString.Lazy qualified as BSL import Data.List (isPrefixOf) import Data.List.NonEmpty (NonEmpty (..))-import qualified Data.List.NonEmpty as NE+import Data.List.NonEmpty qualified as NE import Network.HTTP.Client (Request, RequestBody (..), parseRequest_)-import qualified Network.HTTP.Client.Internal as HTTP+import Network.HTTP.Client.Internal qualified as HTTP import Network.HTTP.Types.Header (Header, RequestHeaders) import Network.HTTP.Types.Method (Method) @@ -80,12 +80,12 @@ hasExplicitPath :: Bool -> ByteString -> Int -> String -> Bool hasExplicitPath secure host port url =- any ((`isPrefixOf` url) . toUrlPrefix) $- concat- [ [Just port]- , Nothing <$ guard (secure && port == 443)- , Nothing <$ guard (not secure && port == 80)- ]+ any+ (any ((`isPrefixOf` url) . toUrlPrefix))+ [ [Just port]+ , Nothing <$ guard (secure && port == 443)+ , Nothing <$ guard (not secure && port == 80)+ ] where toUrlPrefix mport = mconcat
library/Freckle/App/Test/Yesod.hs view
@@ -81,14 +81,14 @@ import Control.Monad.Validate (ValidateT) import Data.Aeson (FromJSON, eitherDecode) import Data.BCP47 (BCP47)-import qualified Data.BCP47 as BCP47+import Data.BCP47 qualified as BCP47 import Data.ByteString (ByteString)-import qualified Data.ByteString as BS-import qualified Data.ByteString.Lazy as BSL+import Data.ByteString qualified as BS+import Data.ByteString.Lazy qualified as BSL import Data.CaseInsensitive (CI) import Data.Csv (FromNamedRecord, decodeByName)-import qualified Data.Text as T-import qualified Data.Vector as V+import Data.Text qualified as T+import Data.Vector qualified as V import Network.HTTP.Types.Header (hAccept, hAcceptLanguage, hContentType) import Network.Wai.Test (SResponse (..)) import Test.Hspec.Expectations.Lifted (expectationFailure)@@ -110,7 +110,7 @@ , setUrl , withResponse )-import qualified Yesod.Test+import Yesod.Test qualified class (MonadIO m, Yesod site) => MonadYesodExample site m | m -> site where liftYesodExample :: YesodExample site a -> m a
library/Freckle/App/Yesod.hs view
@@ -16,9 +16,9 @@ , withException ) import Freckle.App.Stats (HasStatsClient)-import qualified Freckle.App.Stats as Stats+import Freckle.App.Stats qualified as Stats import Network.HTTP.Types (ResponseHeaders, status503)-import qualified Network.Wai as W+import Network.Wai qualified as W import Yesod.Core.Handler (HandlerFor, sendWaiResponse) import Yesod.Core.Types (HandlerContents)
library/Freckle/App/Yesod/Routes.hs view
@@ -4,7 +4,7 @@ import Freckle.App.Prelude -import qualified Language.Haskell.TH as TH+import Language.Haskell.TH qualified as TH import Yesod.Routes.TH.Types -- | Lambdacase expression to print route names
library/Network/Wai/Middleware/Cors.hs view
@@ -6,8 +6,8 @@ import Freckle.App.Prelude import Data.ByteString (ByteString)-import qualified Data.ByteString as BS-import qualified Data.CaseInsensitive as CI+import Data.ByteString qualified as BS+import Data.CaseInsensitive qualified as CI import Network.HTTP.Types (ResponseHeaders) import Network.HTTP.Types.Status (status200) import Network.Wai
library/Network/Wai/Middleware/Stats.hs view
@@ -9,9 +9,9 @@ import Control.Lens ((^.)) import Control.Monad.Reader (runReaderT) import Data.Aeson ((.=))-import qualified Data.Aeson.Key as Key+import Data.Aeson.Key qualified as Key import Freckle.App.Stats (HasStatsClient (..), tagsL)-import qualified Freckle.App.Stats as Stats+import Freckle.App.Stats qualified as Stats import Network.HTTP.Types.Status (Status (..)) import Network.Wai (Middleware, Request, requestMethod, responseStatus)
package.yaml view
@@ -1,5 +1,5 @@ name: freckle-app-version: 1.18.0.0+version: 1.18.1.0 maintainer: Freckle Education category: Utils github: freckle/freckle-app@@ -13,6 +13,8 @@ extra-source-files: - package.yaml +language: GHC2021+ ghc-options: - -fignore-optim-changes - -fwrite-ide-info@@ -20,6 +22,7 @@ - -Wno-all-missed-specialisations - -Wno-missing-exported-signatures # re-enables missing-signatures - -Wno-missing-import-lists+ - -Wno-missing-kind-signatures - -Wno-missing-local-signatures - -Wno-missing-safe-haskell-mode - -Wno-monomorphism-restriction@@ -31,38 +34,22 @@ - condition: "impl(ghc >= 9.8)" ghc-options: - -Wno-missing-role-annotations- - condition: "impl(ghc >= 9.2)"- ghc-options:- - -Wno-missing-kind-signatures+ - -Wno-missing-poly-kind-signatures dependencies: - base < 5 default-extensions:- - BangPatterns - DataKinds - DeriveAnyClass- - DeriveFoldable- - DeriveFunctor- - DeriveGeneric- - DeriveLift- - DeriveTraversable - DerivingVia - DerivingStrategies- - FlexibleContexts- - FlexibleInstances - GADTs- - GeneralizedNewtypeDeriving - LambdaCase- - MultiParamTypeClasses - NoImplicitPrelude - NoMonomorphismRestriction - OverloadedStrings- - RankNTypes - RecordWildCards- - ScopedTypeVariables- - StandaloneDeriving- - TypeApplications - TypeFamilies library:@@ -158,6 +145,7 @@ - Blammo - QuickCheck - aeson+ - async - bugsnag - bytestring - cassava
+ tests/Freckle/App/AsyncSpec.hs view
@@ -0,0 +1,29 @@+module Freckle.App.AsyncSpec+ ( spec+ ) where++import Freckle.App.Prelude++import Blammo.Logging+import Blammo.Logging qualified as Blammo+import Control.Concurrent.Async (wait)+import Data.Aeson.KeyMap qualified as KeyMap+import Freckle.App.Async (async)+import OpenTelemetry.Context qualified as OpenTelemetry+import OpenTelemetry.Context.ThreadLocal qualified as OpenTelemetry+import Test.Hspec++spec :: Spec+spec = do+ describe "async" $ do+ it @(IO ()) "preserves Blammo context" $ do+ let kvs = ["a" .= ("xyz" :: Text)]+ Blammo.withThreadContext kvs $+ (wait =<< async Blammo.myThreadContext)+ `shouldReturn` KeyMap.fromList kvs+ it @(IO ()) "preserves OpenTelemetry context" $ do+ k <- OpenTelemetry.newKey "a"+ let v = "xyz" :: Text+ OpenTelemetry.adjustContext $ OpenTelemetry.insert k v+ (wait =<< async (OpenTelemetry.lookup k <$> OpenTelemetry.getContext))+ `shouldReturn` Just v
tests/Freckle/App/Bugsnag/MetaDataSpec.hs view
@@ -10,7 +10,7 @@ import Freckle.App.Bugsnag import Freckle.App.Bugsnag.MetaData import Freckle.App.Stats-import qualified Freckle.App.Stats as Stats+import Freckle.App.Stats qualified as Stats spec :: Spec spec = do
tests/Freckle/App/CsvSpec.hs view
@@ -7,11 +7,11 @@ import Conduit (ConduitT, MonadThrow, ResourceT, yieldMany) import Control.Monad.Validate (Validate, refute, runValidate) import Data.ByteString (ByteString)-import qualified Data.ByteString as BS+import Data.ByteString qualified as BS import Data.Csv hiding (header)-import qualified Data.List.NonEmpty as NE+import Data.List.NonEmpty qualified as NE import Data.Sequence.NonEmpty (NESeq)-import qualified Data.Vector as V+import Data.Vector qualified as V import Data.Void (Void) import Freckle.App.Csv import Test.Hspec
tests/Freckle/App/Http/CacheSpec.hs view
@@ -7,13 +7,13 @@ import Freckle.App.Prelude -import qualified Codec.Compression.GZip as GZip+import Codec.Compression.GZip qualified as GZip import Control.Lens ((&), (.~), (<>~)) import Control.Monad.State (StateT, execStateT) import Data.Aeson (FromJSON, eitherDecode) import Data.ByteString.Lazy (ByteString)-import qualified Data.ByteString.Lazy as BSL-import qualified Data.HashMap.Strict as HashMap+import Data.ByteString.Lazy qualified as BSL+import Data.HashMap.Strict qualified as HashMap import Data.Time (addUTCTime) import Freckle.App.Http import Freckle.App.Http.Cache
tests/Freckle/App/HttpSpec.hs view
@@ -7,7 +7,7 @@ import Control.Lens (to, (^?), _Left, _Right) import Data.Aeson import Data.Aeson.Lens-import qualified Data.List.NonEmpty as NE+import Data.List.NonEmpty qualified as NE import Freckle.App.Http import Freckle.App.Test.Http import Network.HTTP.Types.Status (status200)
tests/Freckle/App/Memcached/ServersSpec.hs view
@@ -6,7 +6,7 @@ import Control.Error.Util (hush) import Data.Either (isLeft, isRight)-import qualified Database.Memcache.Client as Memcache+import Database.Memcache.Client qualified as Memcache import Freckle.App.Memcached.Servers import Freckle.App.Test
tests/Freckle/App/MemcachedSpec.hs view
@@ -11,12 +11,12 @@ import Control.Lens (lens, to, (^?)) import Data.Aeson (Value (..)) import Data.Aeson.Lens-import qualified Data.List.NonEmpty as NE-import qualified Data.Text as T-import qualified Freckle.App.Env as Env+import Data.List.NonEmpty qualified as NE+import Data.Text qualified as T+import Freckle.App.Env qualified as Env import Freckle.App.Memcached import Freckle.App.Memcached.Client (MemcachedClient, withMemcachedClient)-import qualified Freckle.App.Memcached.Client as Memcached+import Freckle.App.Memcached.Client qualified as Memcached import Freckle.App.Memcached.Servers import Freckle.App.OpenTelemetry
tests/Freckle/App/OpenTelemetry/ContextSpec.hs view
@@ -7,11 +7,11 @@ import Blammo.Logging import Blammo.Logging.Logger (newTestLogger) import Control.Lens (lens)-import qualified Data.Text as T+import Data.Text qualified as T import Freckle.App.OpenTelemetry import Freckle.App.OpenTelemetry.Context import Network.HTTP.Types.Header (Header)-import qualified OpenTelemetry.Trace.Core as Trace+import OpenTelemetry.Trace.Core qualified as Trace data App = App { appLogger :: Logger
tests/Main.hs view
@@ -5,7 +5,7 @@ import Prelude import Freckle.App.Test.Hspec.Runner (runParConfig)-import qualified Spec+import Spec qualified import Test.Hspec main :: IO ()