├── .github └── workflows │ └── haskell.yml ├── .gitignore ├── .project-settings.yml ├── .vim └── haskell-language-server-wrapper ├── .vscode └── settings.json ├── README.md ├── compose.override.github.yml ├── compose.yml ├── fourmolu.yaml ├── package.yaml ├── rollbar.cabal ├── scripts ├── bootstrap ├── build ├── build-executables ├── format-repo └── lib │ └── run-in-container.sh ├── src ├── Rollbar.hs └── Rollbar │ └── MonadLogger.hs ├── stack.yaml └── stack.yaml.lock /.github/workflows/haskell.yml: -------------------------------------------------------------------------------- 1 | name: Rollbar-Haskell CI 2 | 3 | on: 4 | push: 5 | 6 | defaults: 7 | run: 8 | shell: bash 9 | 10 | jobs: 11 | build: 12 | runs-on: [self-hosted, linux, x64] 13 | steps: 14 | - name: Checkout 15 | uses: actions/checkout@v4 16 | 17 | - name: Cache 18 | uses: actions/cache@v4 19 | env: 20 | cache-version: v1 21 | with: 22 | key: ${{ env.cache-version }}-${{ hashFiles('stack.yaml') }}-${{ hashFiles('package.yaml') }} 23 | restore-keys: | 24 | ${{ env.cache-version }}- 25 | path: | 26 | ./stack-root 27 | 28 | - name: Build 29 | run: | 30 | set -e 31 | mkdir -p ./stack-root 32 | mv compose.override.github.yml compose.override.yml 33 | echo "PROJECT_DIR=$PWD" >> .env 34 | ./scripts/build 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | cabal-dev 3 | *.o 4 | *.hi 5 | *.chi 6 | *.chs.h 7 | .virthualenv 8 | .cabal-sandbox/ 9 | cabal.sandbox.config 10 | .stack-work 11 | compose.override.yml 12 | .env 13 | -------------------------------------------------------------------------------- /.project-settings.yml: -------------------------------------------------------------------------------- 1 | extensions: {} 2 | cabal-file: project.cabal 3 | version: 1 4 | module-template: ! 'module MODULE_NAME where 5 | 6 | ' 7 | modules: 8 | Rollbar: 9 | filename: src/Rollbar.hs 10 | Rollbar.MonadLogger: 11 | filename: src/Rollbar/MonadLogger.hs 12 | -------------------------------------------------------------------------------- /.vim/haskell-language-server-wrapper: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | exec docker-compose \ 4 | run --rm -T \ 5 | dev haskell-language-server-wrapper "$@" 6 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "haskell.serverExecutablePath": "${workspaceFolder}/.vim/haskell-language-server-wrapper", 3 | } 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | rollbar-haskell 2 | =============== 3 | 4 | send error notifications to rollbar.com 5 | 6 | I have used a few different error notification services. 7 | 8 | Rollbar has: 9 | 10 | * good support for client-side javascript errors 11 | * a nice UI 12 | * a complete feature set (for me at least) 13 | 14 | 15 | Usage 16 | ===== 17 | 18 | Below is some example Yesod code. 19 | Integration should be similar elsewhere: 20 | 21 | 1) (optional) save Settings at startup 22 | 2) have a global exception handler that notifies Rollbar 23 | 24 | ``` haskell 25 | 26 | -- initialization code 27 | -- in Yesod, this is in makeFoundation in Application.hs 28 | hn <- getHostName 29 | let rc = Rollbar.Settings 30 | { Rollbar.environment = Rollbar.Environment $ tshow $ appEnv conf 31 | , Rollbar.token = 32 | Rollbar.ApiToken $ rollbarApiKeyServer $ appExtra conf 33 | , Rollbar.hostName = hn 34 | } 35 | -- put rc into the foundation type 36 | 37 | -- using in a global exception handler 38 | -- in Yesod, this is in the Yesod typeclass in Foundation.hs 39 | import qualified Rollbar 40 | import Rollbar.MonadLogger (reportErrorS) 41 | 42 | -- Add a field to the foundation data type 43 | data App = App { 44 | ... 45 | , appRollbar :: Rollbar.Settings 46 | } 47 | 48 | 49 | errorHandler err@(InternalError e) = do 50 | app <- getYesod 51 | -- forking means error reporting to Rollbar won't hold up 52 | -- the response to the client 53 | unless development $ forkHandler ($logErrorS "errorHandler" . tshow) $ do 54 | muser <- maybeAuth 55 | let rollbarPerson (Entity uid user) = 56 | Rollbar.Person 57 | { Rollbar.id = toPathPiece uid 58 | , Rollbar.username = Nothing 59 | , Rollbar.email = Just $ emailToText $ userEmail user 60 | } 61 | let rPerson = fmap rollbarPerson muser 62 | reportErrorS (appRollbar app) 63 | (Rollbar.Options rPerson Nothing) 64 | "errorHandler" 65 | ($logDebugS) e 66 | defaultErrorHandler err 67 | 68 | errorHandler err = defaultErrorHandler err 69 | ``` 70 | -------------------------------------------------------------------------------- /compose.override.github.yml: -------------------------------------------------------------------------------- 1 | services: 2 | dev: 3 | tty: false 4 | volumes: 5 | - ./stack-root:/stack-root 6 | -------------------------------------------------------------------------------- /compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | dev: 3 | image: ghcr.io/flipstone/haskell-tools:debian-stable-ghc-9.6.6-2024-10-31-833d7d1 4 | environment: 5 | STACK_ROOT: /stack-root 6 | IN_DEV_CONTAINER: 'true' 7 | # Pass through the CI variable from GitHub (or set it to `true` locally 8 | # for debugging CI builds) 9 | CI: 10 | volumes: 11 | - .:${PROJECT_DIR} 12 | - flipstone_stack_root:/stack-root 13 | working_dir: ${PROJECT_DIR} 14 | tty: true 15 | 16 | volumes: 17 | flipstone_stack_root: 18 | external: true 19 | -------------------------------------------------------------------------------- /fourmolu.yaml: -------------------------------------------------------------------------------- 1 | indentation: 2 2 | function-arrows: trailing 3 | comma-style: leading # default 4 | import-export-style: leading 5 | indent-wheres: false # default 6 | record-brace-space: true 7 | newlines-between-decls: 1 # default 8 | haddock-style: multi-line # default 9 | haddock-style-module: # default 10 | let-style: newline 11 | in-style: left-align 12 | unicode: never # default 13 | respectful: true # default 14 | single-constraint-parens: never 15 | -------------------------------------------------------------------------------- /package.yaml: -------------------------------------------------------------------------------- 1 | name: rollbar 2 | version: 2.2.1 3 | synopsis: error tracking through rollbar.com 4 | homepage: https://github.com/flipstone/rollbar-haskell 5 | license: MIT 6 | author: Flipstone Technology Partners 7 | maintainer: development@flipstone.com 8 | copyright: Daggerboard Inc. makers of docmunch.com, Azara Solutions Inc. 9 | category: Logging 10 | 11 | language: GHC2021 12 | 13 | ghc-options: 14 | - -Wall 15 | - -Werror 16 | - -Wcpp-undef 17 | - -Widentities 18 | - -Wincomplete-record-updates 19 | - -Wincomplete-uni-patterns 20 | - -Wpartial-fields 21 | - -Wredundant-constraints 22 | - -fno-warn-orphans 23 | dependencies: 24 | - base >=4.6 && < 5 25 | - text >=1.2 && < 2.2 26 | - aeson >=1.2 && < 2.3 27 | - vector >=0.12 && < 0.14 28 | - network >=2.6 && < 3.3 29 | - monad-control >=1.0.2 && < 1.0.4 30 | - resourcet >=1.1 && < 1.4 31 | - http-conduit >=2.2 && < 2.4 32 | - lifted-base == 0.2.3.* 33 | 34 | library: 35 | source-dirs: src 36 | exposed-modules: 37 | - Rollbar 38 | - Rollbar.MonadLogger 39 | -------------------------------------------------------------------------------- /rollbar.cabal: -------------------------------------------------------------------------------- 1 | cabal-version: 1.12 2 | 3 | -- This file has been generated from package.yaml by hpack version 0.37.0. 4 | -- 5 | -- see: https://github.com/sol/hpack 6 | 7 | name: rollbar 8 | version: 2.2.1 9 | synopsis: error tracking through rollbar.com 10 | category: Logging 11 | homepage: https://github.com/flipstone/rollbar-haskell 12 | author: Flipstone Technology Partners 13 | maintainer: development@flipstone.com 14 | copyright: Daggerboard Inc. makers of docmunch.com, Azara Solutions Inc. 15 | license: MIT 16 | build-type: Simple 17 | 18 | library 19 | exposed-modules: 20 | Rollbar 21 | Rollbar.MonadLogger 22 | other-modules: 23 | Paths_rollbar 24 | hs-source-dirs: 25 | src 26 | ghc-options: -Wall -Werror -Wcpp-undef -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints -fno-warn-orphans 27 | build-depends: 28 | aeson >=1.2 && <2.3 29 | , base >=4.6 && <5 30 | , http-conduit >=2.2 && <2.4 31 | , lifted-base ==0.2.3.* 32 | , monad-control >=1.0.2 && <1.0.4 33 | , network >=2.6 && <3.3 34 | , resourcet >=1.1 && <1.4 35 | , text >=1.2 && <2.2 36 | , vector >=0.12 && <0.14 37 | default-language: GHC2021 38 | -------------------------------------------------------------------------------- /scripts/bootstrap: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | if $(docker volume inspect flipstone_stack_root >/dev/null 2>/dev/null); then 6 | echo "Skipping creation of flipstone_stack_root docker volume. It already exists" 7 | else 8 | echo "Creating flipstone_stack_root docker volume" 9 | docker volume create flipstone_stack_root 10 | fi 11 | 12 | if [ -f .env ]; then 13 | echo "Skipping creation of .env because it already exists. Remove it if you want to this script to recreate it" 14 | else 15 | echo "PROJECT_DIR=$PWD" >> .env 16 | fi 17 | -------------------------------------------------------------------------------- /scripts/build: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | ./scripts/format-repo 6 | ./scripts/build-executables 7 | -------------------------------------------------------------------------------- /scripts/build-executables: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | source scripts/lib/run-in-container.sh 6 | 7 | STACK_OPTIONS="" 8 | 9 | if [ "$CI" ]; then 10 | : 11 | else 12 | STACK_OPTIONS="--fast" 13 | fi 14 | 15 | stack build \ 16 | --test \ 17 | $STACK_OPTIONS \ 18 | "$@" 19 | -------------------------------------------------------------------------------- /scripts/format-repo: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | source scripts/lib/run-in-container.sh 6 | 7 | if [ "$CI" ]; then 8 | MODE=check 9 | else 10 | MODE=inplace 11 | fi 12 | 13 | git ls-files -z '*.hs' | xargs -0 fourmolu --mode $MODE 14 | -------------------------------------------------------------------------------- /scripts/lib/run-in-container.sh: -------------------------------------------------------------------------------- 1 | if [ "$IN_DEV_CONTAINER" ]; then 2 | # Already in container, nothing to do 3 | : 4 | else 5 | EXTRA_ARGS=() 6 | 7 | if [ "$RUN_AS_SERVICE" ]; then 8 | EXTRA_ARGS+=(--service-ports) 9 | EXTRA_ARGS+=(--use-aliases) 10 | fi 11 | 12 | # Script was run from outside the container, re-exec inside the container 13 | # with the same arguments 14 | docker compose build 15 | exec docker compose run --rm "${EXTRA_ARGS[@]}" dev $0 "$@" 16 | fi 17 | -------------------------------------------------------------------------------- /src/Rollbar.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE OverloadedStrings #-} 2 | 3 | -- | Main entry point to the application. 4 | module Rollbar 5 | ( ApiToken (..) 6 | , UUID (..) 7 | , Environment (..) 8 | , Person (..) 9 | , Settings (..) 10 | , Options (..) 11 | , ErrorLevel (..) 12 | , emptyOptions 13 | , simpleLogMessage 14 | , reportErrorS 15 | , reportLoggerErrorS 16 | , reportErrorSCustomFingerprint 17 | , reportErrorSWithOptions 18 | , buildFrameJSON 19 | , buildJSON 20 | ) where 21 | 22 | import Control.Exception qualified as Ex 23 | import Control.Exception.Lifted (catch) 24 | import Control.Monad qualified as Monad 25 | import Control.Monad.IO.Class qualified as MIO 26 | import Control.Monad.Trans.Control (MonadBaseControl) 27 | import Data.Aeson ((.:), (.=)) 28 | import Data.Aeson qualified as Aeson 29 | import Data.Aeson.Types (parseMaybe) 30 | import Data.Maybe qualified as Maybe 31 | import Data.Text qualified as T 32 | import Data.Text.Encoding qualified as Enc 33 | import Data.Vector qualified as V 34 | import GHC.Stack (CallStack, SrcLoc (..), getCallStack) 35 | import Network.HTTP.Conduit 36 | ( Request (method, requestBody) 37 | , RequestBody (RequestBodyLBS) 38 | , Response (..) 39 | , httpLbs 40 | , newManager 41 | , parseUrlThrow 42 | , requestHeaders 43 | , tlsManagerSettings 44 | ) 45 | 46 | newtype ApiToken = ApiToken {unApiToken :: T.Text} deriving (Show) 47 | 48 | newtype UUID = UUID {unUUID :: T.Text} deriving (Show) 49 | 50 | -- (development, production, etc) 51 | newtype Environment = Environment {unEnvironment :: T.Text} deriving (Show) 52 | 53 | data Person = Person 54 | { personId :: T.Text 55 | , personUsername :: Maybe T.Text 56 | , personEmail :: Maybe T.Text 57 | } 58 | deriving (Show) 59 | 60 | instance Aeson.ToJSON Person where 61 | toJSON person = 62 | Aeson.object 63 | [ "id" .= personId person 64 | , "username" .= personUsername person 65 | , "email" .= personEmail person 66 | ] 67 | 68 | data Settings = Settings 69 | { environment :: Environment 70 | , token :: ApiToken 71 | , hostName :: String 72 | , reportErrors :: Bool 73 | } 74 | 75 | data Options = Options 76 | { optionsPerson :: Maybe Person 77 | , optionsRevisionSha :: Maybe T.Text 78 | } 79 | deriving (Show) 80 | 81 | data ErrorLevel 82 | = Critical 83 | | Error 84 | | Warning 85 | | Info 86 | | Debug 87 | 88 | instance Aeson.ToJSON ErrorLevel where 89 | toJSON lvl = 90 | Aeson.String $ 91 | case lvl of 92 | Critical -> "critical" 93 | Error -> "error" 94 | Warning -> "warning" 95 | Info -> "info" 96 | Debug -> "debug" 97 | 98 | emptyOptions :: Options 99 | emptyOptions = Options Nothing Nothing 100 | 101 | simpleLogMessage :: MIO.MonadIO m => T.Text -> T.Text -> m () 102 | simpleLogMessage section message = 103 | MIO.liftIO $ putStrLn $ T.unpack $ "[Error#" <> section <> "] " <> " " <> message 104 | 105 | -- | report errors to rollbar.com and log them to stdout 106 | reportErrorS :: 107 | (MIO.MonadIO m, MonadBaseControl IO m) => 108 | Settings -> 109 | Options -> 110 | -- | log section 111 | T.Text -> 112 | Maybe CallStack -> 113 | ErrorLevel -> 114 | -- | log message 115 | T.Text -> 116 | m () 117 | reportErrorS settings opts section = 118 | reportLoggerErrorS settings opts section simpleLogMessage 119 | 120 | -- | used by Rollbar.MonadLogger to pass a custom logger 121 | reportLoggerErrorS :: 122 | (MIO.MonadIO m, MonadBaseControl IO m) => 123 | Settings -> 124 | Options -> 125 | -- | log section 126 | T.Text -> 127 | -- | logger that takes the section and the message 128 | (T.Text -> T.Text -> m ()) -> 129 | Maybe CallStack -> 130 | ErrorLevel -> 131 | -- | log message 132 | T.Text -> 133 | m () 134 | reportLoggerErrorS settings opts section loggerS callstack errorLevel msg = 135 | Monad.void $ reportErrorSWithOptions settings opts section (Just loggerS) msg Nothing callstack errorLevel 136 | 137 | -- | Pass in custom fingerprint for grouping on rollbar 138 | reportErrorSCustomFingerprint :: 139 | (MIO.MonadIO m, MonadBaseControl IO m) => 140 | Settings -> 141 | Options -> 142 | -- | log section 143 | T.Text -> 144 | -- | logger that takes the section and the message 145 | Maybe (T.Text -> T.Text -> m ()) -> 146 | Maybe CallStack -> 147 | ErrorLevel -> 148 | -- | log message 149 | T.Text -> 150 | T.Text -> -- fingerprint 151 | m () 152 | reportErrorSCustomFingerprint settings opts section loggerS callstack errorLevel msg fingerprint = 153 | Monad.void $ reportErrorSWithOptions settings opts section loggerS msg (Just fingerprint) callstack errorLevel 154 | 155 | -- | Pass in custom fingerprint for grouping on rollbar or a custom logger 156 | reportErrorSWithOptions :: 157 | (MIO.MonadIO m, MonadBaseControl IO m) => 158 | Settings -> 159 | Options -> 160 | -- | log section 161 | T.Text -> 162 | -- | logger that takes the section and the message 163 | Maybe (T.Text -> T.Text -> m ()) -> 164 | -- | log message 165 | T.Text -> 166 | Maybe T.Text -> -- fingerprint 167 | Maybe CallStack -> 168 | ErrorLevel -> 169 | m (Maybe UUID) 170 | reportErrorSWithOptions settings opts section loggerS msg fingerprint callstack errorLevel = 171 | if reportErrors settings 172 | then go 173 | else pure Nothing 174 | where 175 | go = 176 | do 177 | logger msg 178 | MIO.liftIO $ do 179 | unauthenticatedReq <- parseUrlThrow "https://api.rollbar.com/api/1/item/" 180 | manager <- newManager tlsManagerSettings 181 | let 182 | authenticatedRequest = 183 | unauthenticatedReq 184 | { method = "POST" 185 | , requestHeaders = [("X-Rollbar-Access-Token", Enc.encodeUtf8 . unApiToken $ token settings)] 186 | , requestBody = RequestBodyLBS $ Aeson.encode rollbarJson 187 | } 188 | response <- httpLbs authenticatedRequest manager 189 | let 190 | body = responseBody response 191 | uuid = 192 | fmap UUID $ 193 | parseMaybe 194 | ( \obj -> do 195 | result <- obj .: "result" 196 | result .: "uuid" 197 | ) 198 | =<< Aeson.decode body 199 | pure uuid 200 | `catch` (\(e :: Ex.SomeException) -> Nothing <$ logger (T.pack $ show e)) 201 | 202 | logger = Maybe.fromMaybe defaultLogger loggerS section 203 | defaultLogger message = pure $ simpleLogMessage section message 204 | rollbarJson = buildJSON settings opts section msg fingerprint callstack errorLevel 205 | 206 | buildFrameJSON :: (String, SrcLoc) -> Aeson.Value 207 | buildFrameJSON (name, srcLoc) = 208 | Aeson.object 209 | [ "filename" .= Aeson.String (T.pack $ srcLocFile srcLoc) 210 | , "method" .= Aeson.String (T.pack name) 211 | , "lineno" .= Aeson.toJSON (srcLocStartLine srcLoc) 212 | , "colno" .= Aeson.toJSON (srcLocStartCol srcLoc) 213 | , "class_name" .= Aeson.String (T.pack $ srcLocModule srcLoc) 214 | ] 215 | 216 | buildJSON :: 217 | Settings -> 218 | Options -> 219 | -- | log section 220 | T.Text -> 221 | -- | log message 222 | T.Text -> 223 | -- | fingerprint 224 | Maybe T.Text -> 225 | Maybe CallStack -> 226 | ErrorLevel -> 227 | Aeson.Value 228 | buildJSON settings opts section msg fingerprint callstack level = 229 | Aeson.object 230 | [ "data" 231 | .= Aeson.object 232 | ( [ "environment" .= T.toLower (unEnvironment $ environment settings) 233 | , "level" .= Aeson.toJSON level 234 | , "code_version" .= optionsRevisionSha opts 235 | , "language" .= ("haskell" :: T.Text) 236 | , "server" .= Aeson.object ["host" .= hostName settings] 237 | , "person" .= Aeson.toJSON (optionsPerson opts) 238 | , "body" 239 | .= Aeson.object 240 | [ "trace" 241 | .= Aeson.object 242 | [ "frames" .= Aeson.Array (V.fromList $ maybe [] (map buildFrameJSON . getCallStack) callstack) 243 | , "exception" .= Aeson.object ["class" .= section, "message" .= msg] 244 | ] 245 | ] 246 | ] 247 | <> fp 248 | ) 249 | , "title" .= title 250 | , "notifier" 251 | .= Aeson.object 252 | [ "name" .= ("rollbar-haskell" :: T.Text) 253 | , "version" .= ("2.2.0" :: T.Text) 254 | ] 255 | ] 256 | where 257 | title = section <> ": " <> msg 258 | fp = 259 | case fingerprint of 260 | Just fp' -> 261 | ["fingerprint" .= fp'] 262 | Nothing -> 263 | [] 264 | -------------------------------------------------------------------------------- /src/Rollbar/MonadLogger.hs: -------------------------------------------------------------------------------- 1 | module Rollbar.MonadLogger 2 | ( reportErrorS 3 | ) where 4 | 5 | import Data.Text qualified as T 6 | import GHC.Exception (CallStack) 7 | import Rollbar qualified 8 | 9 | -- | report errors to rollbar.com and log them with monad-logger 10 | reportErrorS :: 11 | Rollbar.Settings -> 12 | Rollbar.Options -> 13 | -- | log section 14 | T.Text -> 15 | -- | monad-logger logging function. takes a section and a message 16 | (T.Text -> T.Text -> IO ()) -> 17 | Maybe CallStack -> 18 | Rollbar.ErrorLevel -> 19 | -- | message 20 | T.Text -> 21 | IO () 22 | reportErrorS = Rollbar.reportLoggerErrorS 23 | -------------------------------------------------------------------------------- /stack.yaml: -------------------------------------------------------------------------------- 1 | resolver: lts-22.40 2 | system-ghc: true 3 | install-ghc: false 4 | 5 | # User packages to be built. 6 | # Various formats can be used as shown in the example below. 7 | # 8 | # packages: 9 | # - some-directory 10 | # - https://example.com/foo/bar/baz-0.0.2.tar.gz 11 | # - location: 12 | # git: https://github.com/commercialhaskell/stack.git 13 | # commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a 14 | # - location: https://github.com/commercialhaskell/stack/commit/e7b331f14bcffb8367cd58fbfc8b40ec7642100a 15 | # extra-dep: true 16 | # subdirs: 17 | # - auto-update 18 | # - wai 19 | # 20 | # A package marked 'extra-dep: true' will only be built if demanded by a 21 | # non-dependency (i.e. a user package), and its test suites and benchmarks 22 | # will not be run. This is useful for tweaking upstream packages. 23 | packages: 24 | - '.' 25 | # Dependency packages to be pulled from upstream that are not in the resolver 26 | # (e.g., acme-missiles-0.3) 27 | extra-deps: [] 28 | 29 | # Override default flag values for local packages and extra-deps 30 | flags: {} 31 | 32 | # Extra package databases containing global packages 33 | extra-package-dbs: [] 34 | 35 | # Control whether we use the GHC we find on the path 36 | # system-ghc: true 37 | # 38 | # Require a specific version of stack, using version ranges 39 | # require-stack-version: -any # Default 40 | # require-stack-version: ">=1.2" 41 | # 42 | # Override the architecture used by stack, especially useful on Windows 43 | # arch: i386 44 | # arch: x86_64 45 | # 46 | # Extra directories used by stack for building 47 | # extra-include-dirs: [/path/to/dir] 48 | # extra-lib-dirs: [/path/to/dir] 49 | # 50 | # Allow a newer minor version of GHC than the snapshot specifies 51 | # compiler-check: newer-minor 52 | -------------------------------------------------------------------------------- /stack.yaml.lock: -------------------------------------------------------------------------------- 1 | # This file was autogenerated by Stack. 2 | # You should not edit this file by hand. 3 | # For more information, please see the documentation at: 4 | # https://docs.haskellstack.org/en/stable/lock_files 5 | 6 | packages: [] 7 | snapshots: 8 | - completed: 9 | sha256: 521009bd88879b6993fab5ea5abe1ee2a539dfd8ec2dfc7c57017a8eaee1e78b 10 | size: 720262 11 | url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/22/40.yaml 12 | original: lts-22.40 13 | --------------------------------------------------------------------------------