Switch from ClassyPrelude to Relude

[?]
May 29, 2020, 2:05 PM
4R7XIYK3BP664CO3YJ2VM64ES2JYN27UTQG5KS34OTEPAIODSZLQC

Dependencies

  • [2] GMYPBCWE Make docker-compose work.
  • [3] 4IQVQL4T Added client for payouts endpoint.
  • [4] DXIGERDT Change order of Docker build to avoid rebuilding the universe.
  • [5] 4ZLEDBK7 Initial attempts at dockerizing, cabal isn't cooperating.
  • [6] MJ6R42RC Utility methods for reading key & cert data.
  • [7] EQXRXRZD Changed to use tasty instead of test-framework
  • [8] PBD7LZYQ Postgres & auth are beginning to function.
  • [9] TJEUE7TY Added OverloadedStrings to eliminate Text fiddling.
  • [10] AL37SVTC Implement payments service endpoints.
  • [11] 7KZP4RHZ Switch from Data.Time to Data.Thyme
  • [12] 6L5BK5EH Use generic SMTP rather than Sendmail-specific mail client.
  • [13] A6HKMINB Attempting to improve JSON handling.
  • [14] HBULCDN6 Add tests for auction winner determination algorithm.
  • [15] Z3MK2PJ5 Add GET handler for retrieving auction data.
  • [16] BSIUHCGF Add payment response handler.
  • [17] 2MNO5FUY Upgrade LTS version
  • [18] RSEB2NFG Replacing Snap with Scotty.
  • [19] 64C6AWH6 Rename Ananke -> Quixotic, project reboot.
  • [20] OBFPJS2G Project successfully builds and tests under nix.
  • [21] B6HWAPDP Modularize & update to recent haskoin.
  • [22] 5XFJNUAZ Start of addition of project infrastructure.
  • [23] 2XQD6KKK Add invitation logic and clean up DBProg error handling.
  • [24] BROSTG5K Beginning of modularization of server.
  • [25] Z7KS5XHH Very WIP. Wow.
  • [26] WZUHEZSB Start of migration back toward snap.
  • [27] 2G3GNDDU Event logging is now functioning in postgres.
  • [28] SCXG6TJW Make log reduction safer in presence of overlapping events.
  • [29] N4NDAZYT Initial implementation of payouts.
  • [30] EKI57EJR Add alternative implementation of auction winner determination.
  • [31] O227CEAV Adds storage of original event JSON for some DBOp constructors.
  • [32] JFOEOFGA stylish-haskell formatting.
  • [33] NAS4BFL4 Trivial stylish-haskell reformat.
  • [34] HALRDT2F Added initial auction create route.
  • [35] TCOAKCGG Completed conversion to snap.
  • [36] 64VI73NP Server now compiles using abstracted SQLite
  • [37] 73NDXDEZ Begin implementation of billing event persistence.
  • [38] ASF3UPJL Add auction creation and bid handlers
  • [39] 5DRIWGLU Improving TimeLog specs
  • [40] DFOBMSAO Initial work on payments API
  • [41] FXJQACES Ensure that auction is not ended at the time of bid
  • [42] SEWTRB6S Implement payment request creation functions.
  • [43] O5FVTOM6 Undo JSON silliness, enable a couple more routes.
  • [44] 5W5M56VJ Move library code to 'lib'
  • [45] GCVQD44V Create amends endpoint, switch to UUID primary keys
  • [46] 7VGYLTMU Clean up schema version handling.
  • [47] NVOCQVAS Initial failing tests.
  • [48] IZEVQF62 Work in progress replacing sqlite with postgres.
  • [49] PGZJ736C Update aftok.cfg.example and revise INSTALL instructions
  • [50] NLZ3JXLO Fix formatting with stylish-haskell.
  • [51] V2VDN77H Enable postgres configuration via environment variable for Heroku.
  • [52] LHJ2HFXV Add property test for auction algorithm.
  • [53] 5ZSKPQ3K Add created_at and auction_start timestamps to auction
  • [54] 7HPY3QPF Fix linting errors. (yay hlint!)
  • [55] WZFQDWW4 Add retrieval/storage of current exchange rate data to payment recording.
  • [56] 4FDQGIXN Make payment request retrieval key an opaque 32-bit hash.
  • [57] NMWWP4ZN Trying out Hspec
  • [58] 7XN3I3QJ Add 'loggedIntervals' endpoint.
  • [59] 4U7F3CPI THE GREAT RENAMING OF THINGS!
  • [60] UUR6SMCA Add start of specs for auctions.
  • [61] I2KHGVD4 Require project permissions for access to most data.
  • [62] EKY7U7SK Finish conversion to stack.
  • [63] WO2MINIF Auctions now compile!
  • [64] RN7EI6IN Update database layer to use CreditTo
  • [65] QADKFHAR Adds CreatePayment handler implementation.
  • [66] RPAJLHMT Change to use UUIDs instead of ints for primary keys.
  • [67] KEP5WUFJ Convert project to stack-based build.
  • [68] TNR3TEHK Switch to Postgres + snaplet arch compiles.
  • [69] TZQJVHBA Add auction functions to ADB.
  • [70] O722AOKE Add route to allow crediting of events to users/projects.
  • [71] Y35QCWYW Minor improvement in WorkIndex type to eliminate duplicated information.
  • [72] IPG33FAW Add billing daemon
  • [73] EMVTF2IW WIP moving back to snap.
  • [74] UILI6PIL The route-based logStart/logStop is nicer.
  • [75] VJPT6HDR Fix remaining type errors after addition of login handler.
  • [76] ADMKQQGC Initial empty Snap project.
  • [77] Z3M53KTL Adrift.
  • [78] Q5X5RYQL stylish-haskell reformatting
  • [79] HMDM3B55 Implement core of payments/billing infrastructure.
  • [80] 3GBSDS5P Fix out-of-date test code, add skeleton for payments spec.
  • [81] MB5SHULB Add route for accepting an invitation with an existing account
  • [82] GLFF5ZDK Factor winningBids for easier testing.
  • [83] NEDDHXUK Reformat via stylish-haskell
  • [84] LAROLAYU WIP
  • [85] QMRKFEPG Refactor QDB to use a free monad algebra instead.
  • [86] W35DDBFY Factor common JSON conversions up into client lib module.
  • [87] EW2XN7KU Update docker build, clean up migration for payments tables.
  • [*] Y3LIJ5US Add handler for CreatePaymentRequest

Change contents

  • edit in aftok.cabal at line 1
    [3.1]
    [3.37]
    cabal-version: 2.4
  • replacement in aftok.cabal at line 7
    [3.1008][3.262:295](),[3.262][3.262:295]()
    License: AllRightsReserved
    [3.1008]
    [3.295]
    License: NONE
  • edit in aftok.cabal at line 13
    [3.426][3.95:117]()
    Cabal-version: >= 2.0
  • replacement in aftok.cabal at line 14
    [3.450][3.450:458]()
    library
    [3.450]
    [3.458]
    common buildenv
  • replacement in aftok.cabal at line 17
    [3.528][3.244:270](),[3.270][3.4:44]()
    hs-source-dirs: lib
    default-extensions: NoImplicitPrelude
    [3.528]
    [3.44]
    default-extensions: KindSignatures
    , LambdaCase
  • edit in aftok.cabal at line 20
    [3.84][3.84:122]()
    , RecordWildCards
  • replacement in aftok.cabal at line 21
    [3.164][3.80:117]()
    , KindSignatures
    [3.164]
    [3.118]
    build-depends:
    base
    , relude
    mixins: base hiding (Prelude)
    , relude (Relude as Prelude)
    library
    import: buildenv
    hs-source-dirs: lib
  • edit in aftok.cabal at line 49
    [3.1607][3.45:72]()
    base
  • edit in aftok.cabal at line 51
    [3.14][3.99:126](),[3.99][3.99:126]()
    , classy-prelude
  • edit in aftok.cabal at line 78
    [89.30]
    [3.456]
    , relude
  • replacement in aftok.cabal at line 95
    [3.1328][3.1328:1362]()
    default-language: Haskell2010
    [3.1328]
    [3.1362]
    import: buildenv
  • edit in aftok.cabal at line 97
    [3.1403][3.1403:1439]()
    ghc-options: -Wall -Werror
  • edit in aftok.cabal at line 99
    [3.1496][3.165:325](),[3.325][3.376:413]()
    default-extensions: NoImplicitPrelude
    , OverloadedStrings
    , RecordWildCards
    , ScopedTypeVariables
    , KindSignatures
  • edit in aftok.cabal at line 107
    [3.480][3.2148:2159](),[3.2148][3.2148:2159](),[3.2931][3.3090:3111](),[3.2159][3.3090:3111]()
    , base
    , classy-prelude
  • replacement in aftok.cabal at line 125
    [3.505][3.1734:1768](),[3.1734][3.1734:1768]()
    default-language: Haskell2010
    [3.505]
    [3.1768]
    import: buildenv
  • edit in aftok.cabal at line 128
    [3.1833][3.326:486](),[3.486][3.414:451]()
    default-extensions: NoImplicitPrelude
    , OverloadedStrings
    , RecordWildCards
    , ScopedTypeVariables
    , KindSignatures
  • edit in aftok.cabal at line 144
    [3.518][3.1266:1277](),[3.71][3.1266:1277]()
    , base
  • edit in aftok.cabal at line 150
    [3.55][3.1144:1177](),[3.758][3.1144:1177](),[3.504][3.1144:1177]()
    , classy-prelude
  • replacement in aftok.cabal at line 184
    [3.396][3.396:466]()
    default-language: Haskell2010
    ghc-options: -Wall -Werror
    [3.396]
    [3.466]
    import: buildenv
  • edit in aftok.cabal at line 186
    [3.495][3.495:692]()
    default-extensions: NoImplicitPrelude
    , OverloadedStrings
    , RecordWildCards
    , ScopedTypeVariables
    , KindSignatures
  • edit in aftok.cabal at line 192
    [3.823][3.823:834]()
    , base
  • edit in aftok.cabal at line 198
    [3.929][3.929:962]()
    , classy-prelude
  • edit in daemon/AftokD/AftokM.hs at line 7
    [3.1643][3.405:426]()
    import ClassyPrelude
  • edit in daemon/AftokD/AftokM.hs at line 8
    [3.1666]
    [3.1666]
  • replacement in daemon/AftokD/AftokM.hs at line 21
    [3.2209][3.2209:2238]()
    import Data.Thyme.Time as T
    [3.2209]
    [3.427]
    import Data.Thyme.Time as C
    import qualified Data.Text as T
  • replacement in daemon/AftokD/AftokM.hs at line 124
    [3.6219][3.6219:6326]()
    let billTemplate = (newSTMP . unpack) <$> req ^. (subscription . billable . paymentRequestEmailTemplate)
    [3.6219]
    [3.6326]
    let billTemplate = (newSTMP . T.unpack) <$> req ^. (subscription . billable . paymentRequestEmailTemplate)
  • replacement in daemon/AftokD/AftokM.hs at line 137
    [3.6975][3.6975:7078]()
    , ("amount_due", tshow $ total ^. satoshi)
    , ("payment_url", tshow paymentUrl)
    [3.6975]
    [3.7078]
    , ("amount_due", show $ total ^. satoshi)
    , ("payment_url", show paymentUrl)
  • replacement in daemon/AftokD/AftokM.hs at line 147
    [3.1645][3.1645:1662]()
    -> T.Day
    [3.1645]
    [3.1662]
    -> C.Day
  • replacement in daemon/AftokD/AftokM.hs at line 152
    [3.7639][3.7639:7728]()
    let template = (newSTMP . unpack) <$> (sub ^. (billable . paymentRequestMemoTemplate))
    [3.7639]
    [3.1684]
    let template = (newSTMP . T.unpack) <$> (sub ^. (billable . paymentRequestMemoTemplate))
  • replacement in daemon/AftokD/AftokM.hs at line 156
    [3.7883][3.7883:7973]()
    , ("billing_date", tshow billingDate)
    , ("issue_time", tshow requestTime)
    [3.7883]
    [3.7973]
    , ("billing_date", show billingDate)
    , ("issue_time", show requestTime)
  • replacement in daemon/AftokD/AftokM.hs at line 173
    [3.8505][3.8505:8606]()
    payloadGen :: Monad m => Subscription' UserId Billable -> T.Day -> C.UTCTime -> m (Maybe ByteString)
    [3.8505]
    [3.8606]
    payloadGen :: Monad m => Subscription' UserId Billable -> C.Day -> C.UTCTime -> m (Maybe ByteString)
  • edit in daemon/AftokD.hs at line 4
    [3.8729][3.8729:8769]()
    import ClassyPrelude hiding (FilePath)
  • replacement in daemon/AftokD.hs at line 10
    [3.8947][3.8947:9015]()
    import Filesystem.Path.CurrentOS (FilePath, fromText, encodeString)
    [3.8947]
    [3.9015]
    import Filesystem.Path.CurrentOS (fromText, encodeString)
    import qualified Filesystem.Path.CurrentOS as P
  • replacement in daemon/AftokD.hs at line 18
    [3.9150][3.9150:9180]()
    , _templatePath :: FilePath
    [3.9150]
    [3.9180]
    , _templatePath :: P.FilePath
  • replacement in daemon/AftokD.hs at line 31
    [3.9458][3.9458:9494]()
    loadConfig :: FilePath -> IO Config
    [3.9458]
    [3.1749]
    loadConfig :: P.FilePath -> IO Config
  • edit in daemon/Main.hs at line 2
    [3.10199]
    [3.10199]
    {-# LANGUAGE TypeApplications #-}
  • replacement in daemon/Main.hs at line 5
    [3.10225][3.10225:10246]()
    import ClassyPrelude
    [3.10225]
    [3.10246]
  • edit in daemon/Main.hs at line 7
    [3.10247]
    [3.10247]
    import Control.Exception (try)
  • edit in daemon/Main.hs at line 9
    [3.10293]
    [3.10293]
    import System.IO.Error (IOError)
  • replacement in daemon/Main.hs at line 15
    [3.10420][3.10420:10435]()
    main :: IO ()
    [3.10420]
    [3.10435]
    main :: IO ()
  • replacement in daemon/Main.hs at line 17
    [3.10445][3.10445:10513]()
    cfgPath <- try $ getEnv "AFTOK_CFG" :: IO (Either IOError String)
    [3.10445]
    [3.10513]
    cfgPath <- try @IOError $ getEnv "AFTOK_CFG"
  • edit in lib/Aftok/Auction.hs at line 5
    [3.5192][3.1857:1901]()
    import ClassyPrelude hiding (rem)
  • edit in lib/Aftok/Auction.hs at line 6
    [3.64][3.15:52]()
    import Control.Monad.State
  • replacement in lib/Aftok/Auction.hs at line 78
    [3.228][3.2464:2737]()
    let winFraction rem = rem % (bid ^. bidAmount . satoshi)
    remainderSeconds (Satoshi rem) = Seconds . round $ winFraction rem * fromIntegral (bid ^. bidSeconds)
    adjustBid rem = bid & bidSeconds .~ remainderSeconds rem & bidAmount .~ rem
    [3.228]
    [3.2737]
    let winFraction r = r % (bid ^. bidAmount . satoshi)
    remainderSeconds (Satoshi r) = Seconds . round $ winFraction r * fromIntegral (bid ^. bidSeconds)
    adjustBid r = bid & bidSeconds .~ remainderSeconds r & bidAmount .~ r
  • replacement in lib/Aftok/Auction.hs at line 103
    [3.763][3.3047:3222]()
    let winFraction rem = rem % (bid ^. bidAmount . satoshi)
    remainderSeconds (Satoshi rem) = Seconds . round $ winFraction rem * fromIntegral (bid ^. bidSeconds)
    [3.763]
    [3.3222]
    let winFraction r = r % (bid ^. bidAmount . satoshi)
    remainderSeconds (Satoshi r) = Seconds . round $ winFraction r * fromIntegral (bid ^. bidSeconds)
  • edit in lib/Aftok/Billables.hs at line 9
    [3.825][3.825:856]()
    import ClassyPrelude
  • edit in lib/Aftok/Billables.hs at line 10
    [3.857]
    [3.110]
  • edit in lib/Aftok/Config.hs at line 4
    [3.10824][3.10824:10874]()
    import ClassyPrelude hiding (FilePath)
  • replacement in lib/Aftok/Config.hs at line 11
    [3.3625][3.3625:3703]()
    import Filesystem.Path.CurrentOS (FilePath, fromText, encodeString)
    [3.3625]
    [3.11258]
    import Filesystem.Path.CurrentOS (fromText, encodeString)
    import qualified Filesystem.Path.CurrentOS as P
    import Safe (headMay)
  • replacement in lib/Aftok/Config.hs at line 32
    [3.3792][3.11728:11808](),[3.11728][3.11728:11808]()
    , _signingKeyFile :: FilePath
    , _certsFile :: FilePath
    [3.3792]
    [3.11808]
    , _signingKeyFile :: P.FilePath
    , _certsFile :: P.FilePath
  • replacement in lib/Aftok/Currency/Bitcoin.hs at line 7
    [3.4443][3.4443:4474]()
    import ClassyPrelude
    [3.4443]
    [3.4474]
  • edit in lib/Aftok/Database/PostgreSQL/Types.hs at line 3
    [3.6120][3.6120:6188]()
    import ClassyPrelude hiding (null)
  • edit in lib/Aftok/Database/PostgreSQL.hs at line 3
    [3.937]
    [3.13497]
    {-# LANGUAGE LambdaCase #-}
  • replacement in lib/Aftok/Database/PostgreSQL.hs at line 8
    [3.623][3.6666:6734]()
    import ClassyPrelude hiding (null)
    [3.623]
    [3.969]
    import Prelude hiding (null)
  • edit in lib/Aftok/Database/PostgreSQL.hs at line 28
    [3.65]
    [3.1011]
    import Safe (headMay)
  • replacement in lib/Aftok/Database/PostgreSQL.hs at line 196
    [3.3624][3.1153:1250](),[3.1250][3.2107:2168](),[3.3727][3.2107:2168](),[3.2168][3.1251:1420]()
    prec "annually" = nullField *> pure B.Annually
    prec "monthly" = B.Monthly <$> field
    --prec "semimonthly" = nullField *> pure B.SemiMonthly
    prec "weekly" = B.Weekly <$> field
    prec "onetime" = nullField *> pure B.OneTime
    prec s = fail $ "Unrecognized recurrence type: " ++ show s
    [3.3624]
    [3.3920]
    prec = \case
    "annually" -> nullField *> pure B.Annually
    "monthly" -> B.Monthly <$> field
    --"semimonthly" = nullField *> pure B.SemiMonthly
    "weekly" -> B.Weekly <$> field
    "onetime" -> nullField *> pure B.OneTime
    _ -> empty
  • replacement in lib/Aftok/Database/PostgreSQL.hs at line 215
    [3.263][3.263:338]()
    <*> ((either fail pure . runGet decodeMessage) =<< field)
    [3.263]
    [3.338]
    <*> ((either (const empty) pure . runGet decodeMessage) =<< field)
  • replacement in lib/Aftok/Database/PostgreSQL.hs at line 223
    [3.2624][3.2624:2692]()
    <*> (field >>= (either fail pure . runGet decodeMessage))
    [3.2624]
    [3.2692]
    <*> (field >>= (either (const empty) pure . runGet decodeMessage))
  • replacement in lib/Aftok/Database.hs at line 10
    [3.4986][3.112:143]()
    import ClassyPrelude
    [3.4986]
    [3.24463]
  • edit in lib/Aftok/Database.hs at line 16
    [3.1410]
    [3.6576]
    import Safe (headMay)
  • edit in lib/Aftok/Interval.hs at line 10
    [3.1494][3.3658:3689]()
    import ClassyPrelude
  • edit in lib/Aftok/Interval.hs at line 11
    [3.1727]
    [3.3690]
  • edit in lib/Aftok/Json.hs at line 11
    [3.156][3.20419:20510]()
    import ClassyPrelude hiding (Day, fail, fromEitherM, UTCTime)
  • edit in lib/Aftok/Json.hs at line 27
    [3.5025]
    [3.2070]
    import qualified Data.Text.Encoding as T
  • replacement in lib/Aftok/Json.hs at line 57
    [3.20940][3.20940:21035]()
    printVersion Version{..} = T.intercalate "." $ fmap (pack . show) [majorVersion, minorVersion]
    [3.20940]
    [3.2225]
    printVersion Version{..} = T.intercalate "." $ fmap (T.pack . show) [majorVersion, minorVersion]
  • replacement in lib/Aftok/Json.hs at line 88
    [3.803][3.21626:21704]()
    vers <- fromEitherM fail $ PC.parseOnly versionParser (encodeUtf8 verstr)
    [3.803]
    [3.804]
    vers <- fromEitherM fail $ PC.parseOnly versionParser (T.encodeUtf8 verstr)
  • replacement in lib/Aftok/Json.hs at line 108
    [3.21727][3.21727:21820]()
    const . fail $ "Unrecognized " <> name <> " schema version: " <> unpack (printVersion ver)
    [3.21727]
    [3.5114]
    const . fail $ "Unrecognized " <> name <> " schema version: " <> T.unpack (printVersion ver)
  • replacement in lib/Aftok/Json.hs at line 137
    [3.1445][3.1445:1508]()
    , "initiator" .= tshow (p ^. (P.initiator._UserId))
    [3.1445]
    [3.1508]
    , "initiator" .= (p ^. P.initiator . _UserId)
  • replacement in lib/Aftok/Json.hs at line 155
    [3.533][3.1759:1802]()
    obj [ "bidId" .= tshow (pid ^. _BidId) ]
    [3.533]
    [3.21865]
    obj [ "bidId" .= (pid ^. _BidId) ]
  • replacement in lib/Aftok/Json.hs at line 184
    [3.22744][3.22744:22838]()
    (fail . unpack $ "Address " <> addrText <> " cannot be parsed as a BTC network address.")
    [3.22744]
    [3.22838]
    (fail . T.unpack $ "Address " <> addrText <> " cannot be parsed as a BTC network address.")
  • replacement in lib/Aftok/Json.hs at line 329
    [3.25331][3.2803:2890](),[3.2803][3.2803:2890]()
    prBytes = (paymentRequest . to (decodeUtf8 . B64.encode . runPut . encodeMessage))
    [3.25331]
    [3.4011]
    prBytes = paymentRequest . to (T.decodeUtf8 . B64.encode . runPut . encodeMessage)
  • replacement in lib/Aftok/Json.hs at line 354
    [3.25340][3.3027:3110](),[3.3027][3.3027:3110]()
    paymentBytes = payment . to (decodeUtf8 . B64.encode . runPut . encodeMessage)
    [3.25340]
    [3.2430]
    paymentBytes = payment . to (T.decodeUtf8 . B64.encode . runPut . encodeMessage)
  • replacement in lib/Aftok/Json.hs at line 387
    [3.4292][3.26000:26082]()
    parseA tid = fail . unpack $ "Amendment type " <> tid <> " not recognized."
    [3.4292]
    [3.1328]
    parseA tid = fail . T.unpack $ "Amendment type " <> tid <> " not recognized."
  • replacement in lib/Aftok/Json.hs at line 400
    [3.4637][3.26379:26462]()
    parseA tid = fail . unpack $ "Amendment type " <> tid <> " not recognized."
    [3.4637]
    [3.1363]
    parseA tid = fail . T.unpack $ "Amendment type " <> tid <> " not recognized."
  • edit in lib/Aftok/Payments/Types.hs at line 9
    [3.10615][3.10615:10646]()
    import ClassyPrelude
  • edit in lib/Aftok/Payments/Types.hs at line 10
    [3.10647]
    [3.1902]
  • replacement in lib/Aftok/Payments/Types.hs at line 15
    [3.2019][3.2019:2064]()
    import Data.Thyme.Time as T
    [3.2019]
    [3.10746]
    import Data.Thyme.Time as C
    import qualified Data.Text as T
  • replacement in lib/Aftok/Payments/Types.hs at line 42
    [3.6833][3.6833:6866]()
    , _billingDate :: T.Day
    [3.6833]
    [3.6866]
    , _billingDate :: C.Day
  • replacement in lib/Aftok/Payments/Types.hs at line 65
    [3.2509][3.7170:7223](),[3.7170][3.7170:7223]()
    let check = any ((now >) . T.toThyme . expiryTime)
    [3.2509]
    [3.2510]
    let check = any ((now >) . C.toThyme . expiryTime)
  • replacement in lib/Aftok/Payments/Types.hs at line 68
    [3.7313][3.4707:4793]()
    in either error (check . getExpires) $ getPaymentDetails (view paymentRequest req)
    [3.7313]
    [3.2571]
    in either (error . T.pack) (check . getExpires) $ getPaymentDetails (view paymentRequest req)
  • edit in lib/Aftok/Payments.hs at line 10
    [3.5750][3.5750:5781]()
    import ClassyPrelude
  • edit in lib/Aftok/Payments.hs at line 11
    [3.5782]
    [3.2715]
  • edit in lib/Aftok/Project.hs at line 5
    [3.1097][3.1097:1128]()
    import ClassyPrelude
  • edit in lib/Aftok/Project.hs at line 6
    [3.1129]
    [3.1129]
  • edit in lib/Aftok/Project.hs at line 10
    [3.6469]
    [3.1198]
    import qualified Data.ByteString as BS
  • replacement in lib/Aftok/Project.hs at line 35
    [3.1961][3.1961:1984]()
    if length code == 32
    [3.1961]
    [3.1984]
    if BS.length code == 32
  • edit in lib/Aftok/TimeLog/Serialization.hs at line 2
    [3.29374][3.29374:29410]()
    {-# LANGUAGE NoImplicitPrelude #-}
  • replacement in lib/Aftok/TimeLog/Serialization.hs at line 8
    [3.29489][3.29489:29510]()
    import ClassyPrelude
    [3.29489]
    [3.29510]
  • edit in lib/Aftok/TimeLog/Serialization.hs at line 14
    [3.29676]
    [3.29676]
    import Data.Text (unpack)
  • edit in lib/Aftok/TimeLog.hs at line 2
    [3.30600][3.30600:30636]()
    {-# LANGUAGE NoImplicitPrelude #-}
  • edit in lib/Aftok/Types.hs at line 2
    [3.32395][3.32395:32431]()
    {-# LANGUAGE NoImplicitPrelude #-}
  • edit in lib/Aftok/Util/Http.hs at line 3
    [3.294][3.5325:5356]()
    import ClassyPrelude
  • edit in lib/Aftok/Util/Http.hs at line 4
    [3.317]
    [3.5357]
  • edit in lib/Aftok/Util.hs at line 6
    [3.10116][3.5563:5594]()
    import ClassyPrelude
  • edit in lib/Aftok/Util.hs at line 7
    [3.30980]
    [3.30980]
  • edit in server/Aftok/QConfig.hs at line 6
    [3.4529][3.32376:32425]()
    import ClassyPrelude hiding (FilePath)
  • replacement in server/Aftok/QConfig.hs at line 7
    [3.4552][2.24952:24991]()
    import Control.Lens (makeLenses, (^.))
    [3.4552]
    [3.32426]
    import Control.Lens (makeLenses, (^.))
  • replacement in server/Aftok/QConfig.hs at line 11
    [3.6698][2.24992:25085]()
    import System.Directory (doesFileExist, doesPathExist, listDirectory)
    [3.6698]
    [3.32480]
    import qualified Data.List as L
  • replacement in server/Aftok/QConfig.hs at line 13
    [3.32544][2.25086:25162]()
    import Filesystem.Path.CurrentOS (FilePath, fromText, encodeString, parent)
    [3.32544]
    [3.4736]
    import Filesystem.Path.CurrentOS (fromText, encodeString)
    import qualified Filesystem.Path.CurrentOS as P
  • replacement in server/Aftok/QConfig.hs at line 23
    [3.4863][2.25163:25196]()
    { _hostname :: ByteString
    [3.4863]
    [2.25196]
    { _hostname :: C8.ByteString
  • replacement in server/Aftok/QConfig.hs at line 25
    [2.25222][2.25222:25253]()
    , _authSiteKey :: FilePath
    [2.25222]
    [2.25253]
    , _authSiteKey :: P.FilePath
  • replacement in server/Aftok/QConfig.hs at line 30
    [2.25386][2.25386:25450]()
    , _templatePath :: FilePath
    , _staticAssetPath :: FilePath
    [2.25386]
    [3.534]
    , _templatePath :: P.FilePath
    , _staticAssetPath :: P.FilePath
  • replacement in server/Aftok/QConfig.hs at line 35
    [3.5085][3.32738:32776]()
    loadQConfig :: FilePath -> IO QConfig
    [3.5085]
    [3.7326]
    loadQConfig :: P.FilePath -> IO QConfig
  • edit in server/Aftok/QConfig.hs at line 38
    [3.5183][2.25473:25962]()
    cfgExists <- doesFileExist $ encodeString cfgFile
    pathExists <- doesPathExist $ encodeString cfgFile
    files <- listDirectory (encodeString $ parent cfgFile)
    putStrLn $ "Loading config from: " <> (pack . encodeString $ cfgFile)
    <> "; file exists = " <> (pack . show $ cfgExists)
    <> "; path exists = " <> (pack . show $ pathExists)
    <> "; parent dir = " <> (pack . encodeString $ parent cfgFile)
    <> "; dir contents = " <> (pack . show $ files)
  • replacement in server/Aftok/QConfig.hs at line 39
    [3.32829][3.32829:32903](),[3.32903][2.25963:26053]()
    let dbEnvCfg = pgsDefaultConfig . C8.pack <$> lookup "DATABASE_URL" env
    conf <- readQConfig cfg dbEnvCfg
    putStrLn $ "Config loaded successfully."
    pure conf
    [3.32829]
    [3.5321]
    let dbEnvCfg = pgsDefaultConfig . C8.pack <$> L.lookup "DATABASE_URL" env
    readQConfig cfg dbEnvCfg
  • replacement in server/Aftok/Snaplet/Auctions.hs at line 9
    [3.2542][3.2542:2573]()
    import ClassyPrelude
    [3.2542]
    [3.33151]
  • replacement in server/Aftok/Snaplet/Auctions.hs at line 49
    [3.3470][3.3470:3561]()
    req <- either (snapError 400 . tshow) pure $ parseEither auctionCreateParser requestBody
    [3.3470]
    [3.591]
    req <- either (snapError 400 . show) pure $ parseEither auctionCreateParser requestBody
  • replacement in server/Aftok/Snaplet/Auctions.hs at line 59
    [3.33263][3.33263:33326]()
    (snapError 404 $ "Auction not found for id " <> tshow aid)
    [3.33263]
    [3.33326]
    (snapError 404 $ "Auction not found for id " <> show aid)
  • replacement in server/Aftok/Snaplet/Auctions.hs at line 68
    [3.1438][3.1438:1541]()
    bid <- either (snapError 400 . tshow) pure $ parseEither (bidCreateParser uid timestamp) requestBody
    [3.1438]
    [3.1541]
    bid <- either (snapError 400 . show) pure $ parseEither (bidCreateParser uid timestamp) requestBody
  • replacement in server/Aftok/Snaplet/Auth.hs at line 3
    [3.240][3.7604:7635]()
    import ClassyPrelude
    [3.240]
    [3.262]
  • replacement in server/Aftok/Snaplet/Auth.hs at line 49
    [3.2922][3.2922:2973]()
    writeText $ "Access Denied: " <> tshow failure
    [3.2922]
    [3.2973]
    writeText $ "Access Denied: " <> show failure
  • replacement in server/Aftok/Snaplet/Billing.hs at line 9
    [3.33876][3.33876:33907]()
    import ClassyPrelude
    [3.33876]
    [3.33907]
  • replacement in server/Aftok/Snaplet/Billing.hs at line 50
    [3.35259][3.35259:35358]()
    b <- either (snapError 400 . tshow) pure $ parseEither (parseCreateBillable uid pid) requestBody
    [3.35259]
    [3.35358]
    b <- either (snapError 400 . show) pure $ parseEither (parseCreateBillable uid pid) requestBody
  • edit in server/Aftok/Snaplet/Payments.hs at line 9
    [3.9800][3.35870:35902]()
    import ClassyPrelude
  • edit in server/Aftok/Snaplet/Payments.hs at line 10
    [3.5783]
    [3.35903]
  • edit in server/Aftok/Snaplet/Payments.hs at line 13
    [3.36052]
    [3.36052]
    import Control.Exception (try)
  • edit in server/Aftok/Snaplet/Payments.hs at line 18
    [3.3707]
    [3.3707]
    import qualified Data.Text.Encoding as T
  • replacement in server/Aftok/Snaplet/Payments.hs at line 31
    [3.3883][3.36099:36138]()
    import Aftok.Payments
    [3.3883]
    [3.36138]
    import Aftok.Payments
  • replacement in server/Aftok/Snaplet/Payments.hs at line 53
    [3.4144][3.4144:4231]()
    (\msg -> snapError 400 $ "Could not decode payment response: " <> tshow msg)
    [3.4144]
    [3.4231]
    (\msg -> snapError 400 $ "Could not decode payment response: " <> show msg)
  • replacement in server/Aftok/Snaplet/Payments.hs at line 61
    [3.2064][3.36255:36358](),[3.36358][3.2164:2253](),[3.2164][3.2164:2253]()
    exchResp <- liftIO . try $ asValue =<< (withOpenSSL $ getWith opts (cfg ^. exchangeRateServiceURI))
    _ <- traverse (logError . encodeUtf8 . tshow @ HttpException) (preview _Left exchResp)
    [3.2064]
    [3.2253]
    exchResp <- liftIO . try @HttpException $ asValue =<< (withOpenSSL $ getWith opts (cfg ^. exchangeRateServiceURI))
    _ <- traverse (logError . T.encodeUtf8 . show) (preview _Left exchResp)
  • edit in server/Aftok/Snaplet/Projects.hs at line 11
    [3.2463][3.36523:36572]()
    import ClassyPrelude hiding (FilePath)
  • replacement in server/Aftok/Snaplet/Projects.hs at line 17
    [3.2263][3.36640:36708]()
    import Filesystem.Path.CurrentOS (FilePath, encodeString)
    [3.2263]
    [3.2263]
    import Filesystem.Path.CurrentOS (encodeString)
    import qualified Filesystem.Path.CurrentOS as F
  • replacement in server/Aftok/Snaplet/Projects.hs at line 48
    [3.3231][3.373:446]()
    cp <- either (snapError 400 . tshow) pure $ A.eitherDecode requestBody
    [3.3231]
    [3.8840]
    cp <- either (snapError 400 . show) pure $ A.eitherDecode requestBody
  • replacement in server/Aftok/Snaplet/Projects.hs at line 62
    [3.36833][3.36833:36896]()
    (snapError 404 $ "Project not found for id " <> tshow pid)
    [3.36833]
    [3.36896]
    (snapError 404 $ "Project not found for id " <> show pid)
  • replacement in server/Aftok/Snaplet/Projects.hs at line 91
    [3.9688][3.37210:37246]()
    buildProjectInviteEmail :: FilePath
    [3.9688]
    [3.2969]
    buildProjectInviteEmail :: F.FilePath
  • edit in server/Aftok/Snaplet/Users.hs at line 9
    [3.3487][3.8605:8636]()
    import ClassyPrelude
  • edit in server/Aftok/Snaplet/Users.hs at line 10
    [3.3510]
    [3.8637]
  • edit in server/Aftok/Snaplet/Users.hs at line 13
    [3.8708]
    [3.8708]
    import qualified Data.Map.Strict as M
  • replacement in server/Aftok/Snaplet/Users.hs at line 78
    [3.859][3.859:889]()
    (lookup "invCode" params)
    [3.859]
    [3.9309]
    (M.lookup "invCode" params)
  • edit in server/Aftok/Snaplet/Util.hs at line 3
    [3.4244][3.9324:9355]()
    import ClassyPrelude
  • replacement in server/Aftok/Snaplet/Util.hs at line 4
    [3.4267][3.9356:9399]()
    import Control.Monad.Trans.Maybe
    [3.4267]
    [3.9399]
  • edit in server/Aftok/Snaplet/WorkLog.hs at line 3
    [3.5522][3.9593:9624]()
    import ClassyPrelude
  • edit in server/Aftok/Snaplet/WorkLog.hs at line 4
    [3.5545]
    [3.9625]
  • edit in server/Aftok/Snaplet/WorkLog.hs at line 10
    [3.9730]
    [3.9730]
    import qualified Data.Text as T
  • replacement in server/Aftok/Snaplet/WorkLog.hs at line 40
    [3.35511][3.35511:35606]()
    snapError 400 $ "Unable to parse log entry " <> (tshow requestBody) <> ": " <> tshow err
    [3.35511]
    [3.35606]
    snapError 400 $ "Unable to parse log entry " <> (show requestBody) <> ": " <> show err
  • replacement in server/Aftok/Snaplet/WorkLog.hs at line 55
    [3.10164][3.12673:12756](),[3.12673][3.12673:12756]()
    snapError 400 $ "Unable to parse bitcoin address from " <> (tshow addrBytes)
    [3.10164]
    [3.10165]
    snapError 400 $ "Unable to parse bitcoin address from " <> (show addrBytes)
  • replacement in server/Aftok/Snaplet/WorkLog.hs at line 85
    [3.37430][3.37430:37493]()
    (snapError 400 $ "Project not found for id " <> tshow pid)
    [3.37430]
    [3.37493]
    (snapError 400 $ "Project not found for id " <> show pid)
  • replacement in server/Aftok/Snaplet/WorkLog.hs at line 103
    [3.10354][3.13350:13377](),[3.13350][3.13350:13377]()
    (snapError 400 . pack)
    [3.10354]
    [3.13377]
    (snapError 400 . T.pack)
  • edit in server/Aftok/Snaplet.hs at line 6
    [3.1192][3.10427:10458]()
    import ClassyPrelude
  • edit in server/Aftok/Snaplet.hs at line 7
    [3.1215]
    [3.10459]
  • edit in server/Aftok/Snaplet.hs at line 9
    [3.10489][3.10489:10564]()
    import Control.Monad.Reader
    import Control.Monad.State
  • replacement in server/Aftok/Snaplet.hs at line 52
    [3.11123][3.11678:11748](),[3.11678][3.11678:11748]()
    snapError 403 $ tshow reason <> " (User " <> tshow uid <> ")"
    [3.11123]
    [3.11124]
    snapError 403 $ show reason <> " (User " <> show uid <> ")"
  • replacement in server/Aftok/Snaplet.hs at line 65
    [3.3026][3.3026:3066]()
    writeText $ ((tshow c) <> " - " <> t)
    [3.3026]
    [3.3066]
    writeText $ ((show c) <> " - " <> t)
  • replacement in server/Aftok/Snaplet.hs at line 76
    [3.2105][3.2105:2190]()
    maybe (snapError 400 $ "Parameter "<> tshow name <>" is required") pure maybeBytes
    [3.2105]
    [3.2190]
    maybe (snapError 400 $ "Parameter "<> show name <>" is required") pure maybeBytes
  • replacement in server/Aftok/Snaplet.hs at line 85
    [3.2230][3.2230:2338]()
    (const . snapError 400 $ "Value of parameter "<> tshow name <>" could not be parsed to a valid value.")
    [3.2230]
    [3.2338]
    (const . snapError 400 $ "Value of parameter "<> show name <>" could not be parsed to a valid value.")
  • edit in server/Main.hs at line 1
    [3.5188]
    [3.129]
    {-# LANGUAGE TypeApplications #-}
  • edit in server/Main.hs at line 5
    [3.1461][3.37690:37739](),[3.170][3.5259:5260](),[3.1340][3.5259:5260](),[3.1482][3.5259:5260](),[3.11227][3.5259:5260](),[3.37739][3.5259:5260](),[3.5259][3.5259:5260]()
    import ClassyPrelude hiding (FilePath)
  • edit in server/Main.hs at line 6
    [2.26398]
    [3.11228]
    import Control.Exception (try)
  • edit in server/Main.hs at line 8
    [3.11294][3.37740:37783]()
    import Data.Either.Combinators (fromRight)
  • edit in server/Main.hs at line 12
    [3.11330]
    [3.918]
    import System.IO.Error (IOError)
  • replacement in server/Main.hs at line 37
    [3.8195][3.1662:1730]()
    cfgPath <- try $ getEnv "AFTOK_CFG" :: IO (Either IOError String)
    [3.8195]
    [3.37887]
    cfgPath <- try @IOError $ getEnv "AFTOK_CFG"
  • edit in test/Aftok/AuctionSpec.hs at line 3
    [3.162][3.162:193]()
    import ClassyPrelude
  • edit in test/Aftok/AuctionSpec.hs at line 4
    [3.543]
    [3.543]
  • edit in test/Aftok/Generators.hs at line 3
    [3.430][3.430:461]()
    import ClassyPrelude
  • edit in test/Aftok/Generators.hs at line 4
    [3.462]
    [3.462]
  • replacement in test/Aftok/PaymentsSpec.hs at line 5
    [3.1057][3.1057:1088]()
    import ClassyPrelude
    [3.1057]
    [3.1088]
  • edit in test/Aftok/TimeLogSpec.hs at line 1
    [3.3665][3.12023:12060]()
    {-# LANGUAGE NoImplicitPrelude #-}
  • replacement in test/Aftok/TimeLogSpec.hs at line 7
    [3.1660][3.12135:12166]()
    import ClassyPrelude
    [3.1660]
    [3.2656]
  • edit in test/Aftok/Util/HttpSpec.hs at line 1
    [3.4932][3.12907:12944]()
    {-# LANGUAGE NoImplicitPrelude #-}
  • replacement in test/Aftok/Util/HttpSpec.hs at line 6
    [3.5046][3.13019:13050]()
    import ClassyPrelude
    [3.5046]
    [3.5067]