current state

This commit is contained in:
Nicole Dresselhaus 2022-07-18 17:50:28 +02:00
parent befb1ab1eb
commit 80b5f09d95
Signed by: Drezil
GPG Key ID: AC88BB432537313A
11 changed files with 158 additions and 223 deletions

1
.gitignore vendored
View File

@ -6,3 +6,4 @@ imgui.ini
settings.json settings.json
*.lock *.lock
tags tags
dist-newstyle/

View File

@ -7,18 +7,19 @@ import Data.Aeson (eitherDecodeFileStrict')
import Control.Monad.Managed import Control.Monad.Managed
import Control.Concurrent import Control.Concurrent
import DearImGui import DearImGui
import DearImGui.Plot
import DearImGui.OpenGL3 import DearImGui.OpenGL3
import DearImGui.GLFW import DearImGui.SDL
import DearImGui.GLFW.OpenGL import DearImGui.SDL.OpenGL
import Run import Run
import RIO.Process import RIO.Process
import System.Directory import System.Directory
import Options.Applicative.Simple import Options.Applicative.Simple
import qualified Paths_ibhelper import qualified Paths_ibhelper
import qualified Graphics.UI.GLFW as GLFW
import qualified Data.Text as T import qualified Data.Text as T
import Prelude (putStrLn) import Prelude (putStrLn)
import AppFiller import AppFiller
import SDL
main :: IO () main :: IO ()
@ -50,27 +51,28 @@ main = do
withLogFunc lo $ \lf -> do withLogFunc lo $ \lf -> do
-- let bare_log = unLogFunc $ view logFuncL lf -- let bare_log = unLogFunc $ view logFuncL lf
-- logErr = liftIO . bare_log callStack "" LevelError -- logErr = liftIO . bare_log callStack "" LevelError
initialized <- GLFW.init initializeAll
unless initialized $ error "GLFW init failed"
liftIO $ runManaged $ do liftIO $ runManaged $ do
mwin <- managed $ bracket win <- do
(GLFW.createWindow (settings ^. windowParams . windowWidth) (settings ^. windowParams . windowHeight) "IB-Helper" Nothing Nothing) let title = "IB-Helper"
(maybe (return ()) GLFW.destroyWindow) let config = defaultWindow { windowGraphicsContext = OpenGLContext defaultOpenGL
case mwin of , windowInitialSize = V2 (settings ^. windowParams . windowWidth . to fromIntegral) (settings ^. windowParams . windowHeight . to fromIntegral)
Just win -> do , windowResizable = True
liftIO $ do }
GLFW.makeContextCurrent (Just win) managed $ bracket (createWindow title config) destroyWindow
GLFW.swapInterval 1
-- Create OpenGL Context
glContext <- managed $ bracket (glCreateContext win) glDeleteContext
-- Create an ImGui context -- Create an ImGui context
_ <- managed $ bracket createContext destroyContext _ <- managed $ bracket createContext destroyContext
-- Create an ImPlot context -- Create an ImPlot context
-- _ <- managed $ bracket createPlotContext destroyPlotContext _ <- managed $ bracket createPlotContext destroyPlotContext
-- Initialize ImGui's GLFW backend -- Initialize ImGui's SDL2 backend
_ <- managed_ $ bracket_ (glfwInitForOpenGL win True) glfwShutdown _ <- managed_ $ bracket_ (sdl2InitForOpenGL win glContext) sdl2Shutdown
-- Initialize ImGui's OpenGL backend -- Initialize ImGui's OpenGL backend
_ <- managed_ $ bracket_ openGL3Init openGL3Shutdown _ <- managed_ $ bracket_ openGL3Init openGL3Shutdown
@ -101,8 +103,3 @@ main = do
} }
void $ liftIO $ forkIO $ appFiller app void $ liftIO $ forkIO $ appFiller app
liftIO $ runRIO app run liftIO $ runRIO app run
Nothing -> do
error "GLFW createWindow failed"
GLFW.terminate

7
cabal.project Normal file
View File

@ -0,0 +1,7 @@
packages: deps/dear-imgui.hs
deps/dear-implot.hs
*.cabal
package ibhelper
ghc-options: -Wall -Wcompat -fno-warn-unused-do-bind
shared: false
static: true

1
deps/dear-imgui.hs vendored

@ -1 +0,0 @@
Subproject commit e5969f6b358dab01d9e2bea8d3538fdfbee0c2f1

1
deps/dear-imgui.hs vendored Symbolic link
View File

@ -0,0 +1 @@
dear-implot.hs/dear-imgui.hs/

2
deps/dear-implot.hs vendored

@ -1 +1 @@
Subproject commit 78f7df091ceb88f57eaacdb0a1e2d43cbce04566 Subproject commit 9a62697e8d50aae80536b6c4dbe6cef67062a71d

View File

@ -1,9 +1,10 @@
cabal-version: 1.12 -- This file has been generated from package.yaml by hpack version 0.27.0.
-- This file has been generated from package.yaml by hpack version 0.34.4.
-- --
-- see: https://github.com/sol/hpack -- see: https://github.com/sol/hpack
--
-- hash: db89b15a8762e7924ae32ea1dcce94b46e75d067b37cc058d3be20c1e0b98964
cabal-version: >= 1.10
name: ibhelper name: ibhelper
version: 0.1.0.0 version: 0.1.0.0
description: Please see the README.md description: Please see the README.md
@ -15,9 +16,10 @@ copyright: 2022 Stefan Dresselhaus
license: BSD3 license: BSD3
license-file: LICENSE license-file: LICENSE
build-type: Simple build-type: Simple
extra-source-files: extra-source-files:
README.md
ChangeLog.md ChangeLog.md
README.md
source-repository head source-repository head
type: git type: git
@ -37,55 +39,22 @@ library
Paths_ibhelper Paths_ibhelper
hs-source-dirs: hs-source-dirs:
src src
default-extensions: default-extensions: BangPatterns BinaryLiterals ConstraintKinds DataKinds DefaultSignatures DeriveDataTypeable DeriveFoldable DeriveFunctor DeriveGeneric DeriveTraversable DoAndIfThenElse EmptyDataDecls ExistentialQuantification FlexibleContexts FlexibleInstances FunctionalDependencies GADTs GeneralizedNewtypeDeriving InstanceSigs KindSignatures LambdaCase MultiParamTypeClasses MultiWayIf NamedFieldPuns NoImplicitPrelude OverloadedStrings PartialTypeSignatures PatternGuards PolyKinds RankNTypes RecordWildCards ScopedTypeVariables StandaloneDeriving TupleSections TypeFamilies TypeSynonymInstances ViewPatterns DuplicateRecordFields
BangPatterns
BinaryLiterals
ConstraintKinds
DataKinds
DefaultSignatures
DeriveDataTypeable
DeriveFoldable
DeriveFunctor
DeriveGeneric
DeriveTraversable
DoAndIfThenElse
EmptyDataDecls
ExistentialQuantification
FlexibleContexts
FlexibleInstances
FunctionalDependencies
GADTs
GeneralizedNewtypeDeriving
InstanceSigs
KindSignatures
LambdaCase
MultiParamTypeClasses
MultiWayIf
NamedFieldPuns
NoImplicitPrelude
OverloadedStrings
PartialTypeSignatures
PatternGuards
PolyKinds
RankNTypes
RecordWildCards
ScopedTypeVariables
StandaloneDeriving
TupleSections
TypeFamilies
TypeSynonymInstances
ViewPatterns
DuplicateRecordFields
ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints
include-dirs:
deps/dear-implot.hs/implot
deps/dear-imgui.hs/imgui
extra-libraries:
HSdear-imgui-1.4.0-inplace
build-depends: build-depends:
GLFW-b StateVar
, StateVar
, aeson , aeson
, base >=4.11 && <10 , base >=4.11 && <10
, binary , binary
, bytestring , bytestring
, data-default , data-default
, dear-imgui , dear-imgui >=1.4.0
, dear-implot
, directory , directory
, fingertree , fingertree
, gl , gl
@ -94,6 +63,7 @@ library
, network , network
, pretty-show , pretty-show
, rio >=0.1.12.0 , rio >=0.1.12.0
, sdl2
, stm , stm
, text , text
, time , time
@ -107,55 +77,22 @@ executable ibhelper-exe
Paths_ibhelper Paths_ibhelper
hs-source-dirs: hs-source-dirs:
app app
default-extensions: default-extensions: BangPatterns BinaryLiterals ConstraintKinds DataKinds DefaultSignatures DeriveDataTypeable DeriveFoldable DeriveFunctor DeriveGeneric DeriveTraversable DoAndIfThenElse EmptyDataDecls ExistentialQuantification FlexibleContexts FlexibleInstances FunctionalDependencies GADTs GeneralizedNewtypeDeriving InstanceSigs KindSignatures LambdaCase MultiParamTypeClasses MultiWayIf NamedFieldPuns NoImplicitPrelude OverloadedStrings PartialTypeSignatures PatternGuards PolyKinds RankNTypes RecordWildCards ScopedTypeVariables StandaloneDeriving TupleSections TypeFamilies TypeSynonymInstances ViewPatterns DuplicateRecordFields
BangPatterns
BinaryLiterals
ConstraintKinds
DataKinds
DefaultSignatures
DeriveDataTypeable
DeriveFoldable
DeriveFunctor
DeriveGeneric
DeriveTraversable
DoAndIfThenElse
EmptyDataDecls
ExistentialQuantification
FlexibleContexts
FlexibleInstances
FunctionalDependencies
GADTs
GeneralizedNewtypeDeriving
InstanceSigs
KindSignatures
LambdaCase
MultiParamTypeClasses
MultiWayIf
NamedFieldPuns
NoImplicitPrelude
OverloadedStrings
PartialTypeSignatures
PatternGuards
PolyKinds
RankNTypes
RecordWildCards
ScopedTypeVariables
StandaloneDeriving
TupleSections
TypeFamilies
TypeSynonymInstances
ViewPatterns
DuplicateRecordFields
ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints -threaded -rtsopts -with-rtsopts=-N ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints -threaded -rtsopts -with-rtsopts=-N
include-dirs:
deps/dear-implot.hs/implot
deps/dear-imgui.hs/imgui
extra-libraries:
HSdear-imgui-1.4.0-inplace
build-depends: build-depends:
GLFW-b StateVar
, StateVar
, aeson , aeson
, base >=4.11 && <10 , base >=4.11 && <10
, binary , binary
, bytestring , bytestring
, data-default , data-default
, dear-imgui , dear-imgui >=1.4.0
, dear-implot
, directory , directory
, fingertree , fingertree
, gl , gl
@ -166,6 +103,7 @@ executable ibhelper-exe
, optparse-simple , optparse-simple
, pretty-show , pretty-show
, rio >=0.1.12.0 , rio >=0.1.12.0
, sdl2
, stm , stm
, text , text
, time , time
@ -181,55 +119,22 @@ test-suite ibhelper-test
Paths_ibhelper Paths_ibhelper
hs-source-dirs: hs-source-dirs:
test test
default-extensions: default-extensions: BangPatterns BinaryLiterals ConstraintKinds DataKinds DefaultSignatures DeriveDataTypeable DeriveFoldable DeriveFunctor DeriveGeneric DeriveTraversable DoAndIfThenElse EmptyDataDecls ExistentialQuantification FlexibleContexts FlexibleInstances FunctionalDependencies GADTs GeneralizedNewtypeDeriving InstanceSigs KindSignatures LambdaCase MultiParamTypeClasses MultiWayIf NamedFieldPuns NoImplicitPrelude OverloadedStrings PartialTypeSignatures PatternGuards PolyKinds RankNTypes RecordWildCards ScopedTypeVariables StandaloneDeriving TupleSections TypeFamilies TypeSynonymInstances ViewPatterns DuplicateRecordFields
BangPatterns
BinaryLiterals
ConstraintKinds
DataKinds
DefaultSignatures
DeriveDataTypeable
DeriveFoldable
DeriveFunctor
DeriveGeneric
DeriveTraversable
DoAndIfThenElse
EmptyDataDecls
ExistentialQuantification
FlexibleContexts
FlexibleInstances
FunctionalDependencies
GADTs
GeneralizedNewtypeDeriving
InstanceSigs
KindSignatures
LambdaCase
MultiParamTypeClasses
MultiWayIf
NamedFieldPuns
NoImplicitPrelude
OverloadedStrings
PartialTypeSignatures
PatternGuards
PolyKinds
RankNTypes
RecordWildCards
ScopedTypeVariables
StandaloneDeriving
TupleSections
TypeFamilies
TypeSynonymInstances
ViewPatterns
DuplicateRecordFields
ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints -threaded -rtsopts -with-rtsopts=-N ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints -threaded -rtsopts -with-rtsopts=-N
include-dirs:
deps/dear-implot.hs/implot
deps/dear-imgui.hs/imgui
extra-libraries:
HSdear-imgui-1.4.0-inplace
build-depends: build-depends:
GLFW-b StateVar
, StateVar
, aeson , aeson
, base >=4.11 && <10 , base >=4.11 && <10
, binary , binary
, bytestring , bytestring
, data-default , data-default
, dear-imgui , dear-imgui >=1.4.0
, dear-implot
, directory , directory
, fingertree , fingertree
, gl , gl
@ -240,6 +145,7 @@ test-suite ibhelper-test
, network , network
, pretty-show , pretty-show
, rio >=0.1.12.0 , rio >=0.1.12.0
, sdl2
, stm , stm
, text , text
, time , time

View File

@ -19,6 +19,13 @@ extra-source-files:
# common to point users to the README.md file. # common to point users to the README.md file.
description: Please see the README.md description: Please see the README.md
include-dirs:
- deps/dear-implot.hs/implot
- deps/dear-imgui.hs/imgui
extra-libraries:
- HSdear-imgui-1.4.0-inplace
default-extensions: default-extensions:
- BangPatterns - BangPatterns
- BinaryLiterals - BinaryLiterals
@ -62,8 +69,7 @@ default-extensions:
dependencies: dependencies:
- base >= 4.11 && < 10 - base >= 4.11 && < 10
- rio >= 0.1.12.0 - rio >= 0.1.12.0
- dear-imgui - dear-imgui >= 1.4.0
- GLFW-b
- managed - managed
- gl - gl
- aeson - aeson
@ -81,6 +87,8 @@ dependencies:
- time - time
- unordered-containers - unordered-containers
- fingertree - fingertree
- dear-implot
- sdl2
ghc-options: ghc-options:
- -Wall - -Wall

View File

@ -22,7 +22,7 @@ data FillerException = QuitFiller
instance Exception FillerException instance Exception FillerException
deriving via Integer instance Hashable Day --deriving via Integer instance Hashable Day
newChart :: IBContract -> RIO App () newChart :: IBContract -> RIO App ()
newChart contract = do newChart contract = do

View File

@ -11,11 +11,12 @@ import Data.Aeson (encodeFile)
import Data.Bits import Data.Bits
import Data.FingerTree (ViewL(..), ViewR(..), viewl, viewr, split, FingerTree) import Data.FingerTree (ViewL(..), ViewR(..), viewl, viewr, split, FingerTree)
import DearImGui import DearImGui
import DearImGui.Plot
import DearImGui.OpenGL3 import DearImGui.OpenGL3
import DearImGui.GLFW import DearImGui.SDL
import Graphics.GL import Graphics.GL
import SDL
import Data.StateVar import Data.StateVar
import qualified Graphics.UI.GLFW as GLFW
import qualified Data.Text as T import qualified Data.Text as T
import qualified Data.HashMap.Strict as HM import qualified Data.HashMap.Strict as HM
import qualified Data.FingerTree as FT import qualified Data.FingerTree as FT
@ -30,22 +31,17 @@ run = do
-- close connections to IB -- close connections to IB
renderLoop :: RIO App () shutdownApp :: RIO App ()
renderLoop = do shutdownApp = do
win <- appWindow <$> ask win <- appWindow <$> ask
liftIO GLFW.pollEvents
close <- liftIO $ GLFW.windowShouldClose win
if close
then do
-- save settings & config -- save settings & config
(w,h) <- liftIO $ GLFW.getWindowSize win (V2 w h) <- liftIO $ get $ windowSize win
settings <- appSettings <$> ask settings <- appSettings <$> ask
refs <- appRefs <$> ask refs <- appRefs <$> ask
host' <- liftIO . readTVarIO . twsConnectionRefsHost . twsConnectionRefs $ refs host' <- liftIO . readTVarIO . twsConnectionRefsHost . twsConnectionRefs $ refs
port' <- liftIO . readTVarIO . twsConnectionRefsPort . twsConnectionRefs $ refs port' <- liftIO . readTVarIO . twsConnectionRefsPort . twsConnectionRefs $ refs
let settings' = settings & windowParams . windowWidth .~ w let settings' = settings & windowParams . windowWidth .~ fromIntegral w
& windowParams . windowHeight .~ h & windowParams . windowHeight .~ fromIntegral h
& twsConnection . host .~ T.pack host' & twsConnection . host .~ T.pack host'
& twsConnection . port .~ T.pack port' & twsConnection . port .~ T.pack port'
liftIO $ encodeFile "settings.json" settings' liftIO $ encodeFile "settings.json" settings'
@ -53,6 +49,24 @@ renderLoop = do
-- save cached data -- save cached data
logInfo $ display $ T.pack $ ppShow settings' logInfo $ display $ T.pack $ ppShow settings'
renderLoop :: RIO App ()
renderLoop = do
win <- appWindow <$> ask
let checkEvents = do
pollEventWithImGui >>= \case
Nothing ->
return False
Just event ->
(isQuit event ||) <$> checkEvents
isQuit event =
SDL.eventPayload event == SDL.QuitEvent
close <- liftIO checkEvents
if close
then shutdownApp
else do else do
refs' <- appRefs <$> ask refs' <- appRefs <$> ask
data' <- appData <$> ask data' <- appData <$> ask
@ -61,7 +75,7 @@ renderLoop = do
-- Tell ImGui we're starting a new frame -- Tell ImGui we're starting a new frame
liftIO $ do liftIO $ do
openGL3NewFrame openGL3NewFrame
glfwNewFrame sdl2NewFrame
newFrame newFrame
@ -70,7 +84,7 @@ renderLoop = do
withMenuOpen "File" $ do withMenuOpen "File" $ do
menuItem "Quit" >>= \case menuItem "Quit" >>= \case
False -> return () False -> return ()
True -> liftIO $ GLFW.setWindowShouldClose win True True -> shutdownApp
let cr = twsConnectionRefs refs' let cr = twsConnectionRefs refs'
accs <- fmap HM.keys $ liftIO $ readTVarIO $ Types.accounts data' accs <- fmap HM.keys $ liftIO $ readTVarIO $ Types.accounts data'
withComboOpen "Account" (maybe "Select account" T.unpack selectedAccount) $ do withComboOpen "Account" (maybe "Select account" T.unpack selectedAccount) $ do
@ -146,12 +160,12 @@ renderLoop = do
forM_ ((accs HM.! aid) ^.. accountPortfolio . traverse) $ \(IBPortfolioValue c p mp mv ac up rp) -> forM_ ((accs HM.! aid) ^.. accountPortfolio . traverse) $ \(IBPortfolioValue c p mp mv ac up rp) ->
do do
tableNextRow tableNextRow
whenM tableNextColumn (text $ T.unpack $ localSymbol c) tableNextColumn $ text $ T.unpack $ localSymbol c
whenM tableNextColumn (text $ show p) tableNextColumn $ text $ show p
whenM tableNextColumn (text $ show up) tableNextColumn $ text $ show up
whenM tableNextColumn (text $ show rp) tableNextColumn $ text $ show rp
whenM tableNextColumn (text $ show mp) tableNextColumn $ text $ show mp
whenM tableNextColumn (text $ show mv) tableNextColumn $ text $ show mv
bracket_ (begin "Search Symbols") end $ do bracket_ (begin "Search Symbols") end $ do
readTVarIO (currentAccount refs') >>= \case readTVarIO (currentAccount refs') >>= \case
@ -177,7 +191,7 @@ renderLoop = do
tableSetupColumn "Primary exchange" tableSetupColumn "Primary exchange"
tableSetupColumn "Currency" tableSetupColumn "Currency"
tableSetupColumn "Available derivatives" tableSetupColumn "Available derivatives"
withSortableTable $ \(mustSort, sortSpecs) -> do withSortableTable $ \mustSort sortSpecs -> do
when mustSort $ liftIO $ pPrint sortSpecs when mustSort $ liftIO $ pPrint sortSpecs
tableHeadersRow tableHeadersRow
lResult <- readTVarIO $ symbolLookupResults data' lResult <- readTVarIO $ symbolLookupResults data'
@ -190,9 +204,9 @@ renderLoop = do
True -> do True -> do
logInfo $ display $ "new chart open for: " <> _symbol logInfo $ display $ "new chart open for: " <> _symbol
newChart $ def { conId = _symbolId, symbol = _symbol, secType = _secType, exchange = "SMART", primaryExchange = _primaryExchange, currency = _currency} newChart $ def { conId = _symbolId, symbol = _symbol, secType = _secType, exchange = "SMART", primaryExchange = _primaryExchange, currency = _currency}
let printDatum x = whenM tableNextColumn $ text $ T.unpack x let printDatum x = tableNextColumn $ text $ T.unpack x
tableNextRow tableNextRow
whenM tableNextColumn $ do tableNextColumn $ do
void $ selectableWith (defSelectableOptions { flags = ImGuiSelectableFlags_SpanAllColumns }) (T.unpack _symbol) void $ selectableWith (defSelectableOptions { flags = ImGuiSelectableFlags_SpanAllColumns }) (T.unpack _symbol)
openPopupOnItemClick popupName ImGuiPopupFlags_MouseButtonRight openPopupOnItemClick popupName ImGuiPopupFlags_MouseButtonRight
printDatum _secType printDatum _secType
@ -217,7 +231,7 @@ renderLoop = do
showDemoWindow showDemoWindow
-- Show the ImPlot demo window -- Show the ImPlot demo window
--showPlotDemoWindow showPlotDemoWindow
-- Render -- Render
liftIO $ glClear GL_COLOR_BUFFER_BIT liftIO $ glClear GL_COLOR_BUFFER_BIT
@ -225,6 +239,6 @@ renderLoop = do
render render
liftIO $ openGL3RenderDrawData =<< getDrawData liftIO $ openGL3RenderDrawData =<< getDrawData
liftIO $ GLFW.swapBuffers win liftIO $ glSwapWindow win
renderLoop renderLoop

View File

@ -18,7 +18,7 @@ import Data.Time
import Data.FingerTree import Data.FingerTree
import Data.Semigroup import Data.Semigroup
import GHC.Generics import GHC.Generics
import Graphics.UI.GLFW (Window) import SDL (Window)
import DearImGui import DearImGui
import RIO import RIO
import RIO.Process import RIO.Process

View File

@ -31,6 +31,7 @@ resolver: lts-18.24
packages: packages:
- . - .
- deps/dear-imgui.hs - deps/dear-imgui.hs
- deps/dear-implot.hs
# Dependency packages to be pulled from upstream that are not in the resolver. # Dependency packages to be pulled from upstream that are not in the resolver.
# These entries can reference officially published versions as well as # These entries can reference officially published versions as well as
# forks / in-progress versions pinned to a git hash. For example: # forks / in-progress versions pinned to a git hash. For example:
@ -50,8 +51,8 @@ allow-newer: true
flags: flags:
dear-imgui: dear-imgui:
# libraries # libraries
glfw: true glfw: false
sdl: false sdl: true
vulkan: false vulkan: false
# hardware-requirements # hardware-requirements
opengl3: true opengl3: true
@ -73,7 +74,8 @@ flags:
# #
# Extra directories used by stack for building # Extra directories used by stack for building
# extra-include-dirs: [/path/to/dir] # extra-include-dirs: [/path/to/dir]
# extra-lib-dirs: [/path/to/dir] extra-lib-dirs:
- deps/dear-imgui.hs/build/
# #
# Allow a newer minor version of GHC than the snapshot specifies # Allow a newer minor version of GHC than the snapshot specifies
# compiler-check: newer-minor # compiler-check: newer-minor