From e4917442c920b46827982b385fa9b919a769c6ca Mon Sep 17 00:00:00 2001 From: Francesco Ariis Date: Thu, 21 Aug 2025 21:57:52 +0200 Subject: [PATCH 01/17] Bump dependencies --- sgf.cabal | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sgf.cabal b/sgf.cabal index d661e98..4d4654c 100644 --- a/sgf.cabal +++ b/sgf.cabal @@ -26,12 +26,12 @@ library Data.SGF.Parse.Raw Data.SGF.Parse.Util build-depends: base >=3 && < 5, - containers >= 0.6.7 && < 0.7, - encoding >= 0.8.9 && < 0.9, + containers >= 0.6.7 && < 0.9, + encoding >= 0.8.9 && < 0.11, extensible-exceptions >= 0.1.1 && < 0.2, mtl >= 2.2.2, transformers >= 0.5.6, - time >= 1.12.2 && < 1.13, + time >= 1.12.2 && < 1.16, split >= 0.2.5, parsec >= 3.1.16 && < 3.2 From 9874b854e06bfebe1c527b23a73691f170356dbd Mon Sep 17 00:00:00 2001 From: Francesco Ariis Date: Fri, 22 Aug 2025 14:10:27 +0200 Subject: [PATCH 02/17] Add common stanza --- sgf.cabal | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/sgf.cabal b/sgf.cabal index 4d4654c..baa34c3 100644 --- a/sgf.cabal +++ b/sgf.cabal @@ -1,3 +1,4 @@ +cabal-version: 2.2 name: sgf version: 0.1.3.3 author: Daniel Wagner daniel@wagner-home.com @@ -12,21 +13,24 @@ description: editors. There are plans to support other games and pretty-printing in future releases. category: Data -license: BSD3 +license: BSD-3-Clause license-file: LICENSE -cabal-version: >= 1.10 build-type: Simple +common shared + build-depends: base == 4.*, + ghc-options: -Wall + default-language: Haskell2010 + library - default-language: Haskell2010 + import: shared exposed-modules: Data.SGF Data.SGF.Parse Data.SGF.Types other-modules: Data.SGF.Parse.Encodings Data.SGF.Parse.Raw Data.SGF.Parse.Util - build-depends: base >=3 && < 5, - containers >= 0.6.7 && < 0.9, + build-depends: containers >= 0.6.7 && < 0.9, encoding >= 0.8.9 && < 0.11, extensible-exceptions >= 0.1.1 && < 0.2, mtl >= 2.2.2, From 33c79c57ea70cb32e816528079e08f531ef21bc2 Mon Sep 17 00:00:00 2001 From: Francesco Ariis Date: Fri, 22 Aug 2025 14:15:04 +0200 Subject: [PATCH 03/17] Export ByteString functions For easier testing and better lib ergonomics --- Data/SGF.hs | 5 ++++- sgf.cabal | 14 ++++++++------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/Data/SGF.hs b/Data/SGF.hs index a213d38..1569186 100644 --- a/Data/SGF.hs +++ b/Data/SGF.hs @@ -10,7 +10,8 @@ module Data.SGF ( module Data.SGF.Parse, module Data.Word, module Data.Tree, - module Text.ParserCombinators.Parsec + module Text.ParserCombinators.Parsec, + module Data.ByteString -- * Overview of SGF -- $sgf @@ -27,6 +28,8 @@ import Data.Word import Data.Tree import Text.ParserCombinators.Parsec (runParser) +import Data.ByteString (getContents, unpack, readFile) + -- TODO: -- * support parsing from ByteString, then take the "unpack" out of "parse" below -- * support the rest of the SGF format ;-) diff --git a/sgf.cabal b/sgf.cabal index baa34c3..71b597c 100644 --- a/sgf.cabal +++ b/sgf.cabal @@ -25,12 +25,14 @@ common shared library import: shared exposed-modules: Data.SGF - Data.SGF.Parse - Data.SGF.Types - other-modules: Data.SGF.Parse.Encodings - Data.SGF.Parse.Raw - Data.SGF.Parse.Util - build-depends: containers >= 0.6.7 && < 0.9, + Data.SGF.Parse, + Data.SGF.Types, + other-modules: Data.SGF.Parse.Encodings, + Data.SGF.Parse.Raw, + Data.SGF.Parse.Util, + Data.SGF.Reexports + build-depends: bytestring >= 0.12.2 && < 0.13, + containers >= 0.6.7 && < 0.9, encoding >= 0.8.9 && < 0.11, extensible-exceptions >= 0.1.1 && < 0.2, mtl >= 2.2.2, From 7dc186ea449847ce7ab603619a860d55d874a2d2 Mon Sep 17 00:00:00 2001 From: Francesco Ariis Date: Fri, 22 Aug 2025 14:28:23 +0200 Subject: [PATCH 04/17] Split internal/external libraries --- {Data => lib/Data}/SGF.hs | 13 ++++--------- sgf.cabal | 11 +++++++++-- {Data => src/Data}/SGF/Parse.hs | 0 {Data => src/Data}/SGF/Parse/Encodings.hs | 0 {Data => src/Data}/SGF/Parse/Raw.hs | 0 {Data => src/Data}/SGF/Parse/Util.hs | 0 src/Data/SGF/Reexports.hs | 12 ++++++++++++ {Data => src/Data}/SGF/Types.hs | 0 8 files changed, 25 insertions(+), 11 deletions(-) rename {Data => lib/Data}/SGF.hs (96%) rename {Data => src/Data}/SGF/Parse.hs (100%) rename {Data => src/Data}/SGF/Parse/Encodings.hs (100%) rename {Data => src/Data}/SGF/Parse/Raw.hs (100%) rename {Data => src/Data}/SGF/Parse/Util.hs (100%) create mode 100644 src/Data/SGF/Reexports.hs rename {Data => src/Data}/SGF/Types.hs (100%) diff --git a/Data/SGF.hs b/lib/Data/SGF.hs similarity index 96% rename from Data/SGF.hs rename to lib/Data/SGF.hs index 1569186..504e895 100644 --- a/Data/SGF.hs +++ b/lib/Data/SGF.hs @@ -8,10 +8,6 @@ There are plans to support other games and pretty-printing in future releases. module Data.SGF ( module Data.SGF.Types, module Data.SGF.Parse, - module Data.Word, - module Data.Tree, - module Text.ParserCombinators.Parsec, - module Data.ByteString -- * Overview of SGF -- $sgf @@ -20,15 +16,14 @@ module Data.SGF ( -- * Example usage -- $example + + -- * Convenience reexports + module Data.SGF.Reexports ) where import Data.SGF.Types import Data.SGF.Parse (collection) -import Data.Word -import Data.Tree -import Text.ParserCombinators.Parsec (runParser) - -import Data.ByteString (getContents, unpack, readFile) +import Data.SGF.Reexports -- TODO: -- * support parsing from ByteString, then take the "unpack" out of "parse" below diff --git a/sgf.cabal b/sgf.cabal index 71b597c..cea219e 100644 --- a/sgf.cabal +++ b/sgf.cabal @@ -25,9 +25,15 @@ common shared library import: shared exposed-modules: Data.SGF - Data.SGF.Parse, + build-depends: sgf-internal + hs-source-dirs: lib/ + +library sgf-internal + import: shared + visibility: internal + exposed-modules: Data.SGF.Parse, Data.SGF.Types, - other-modules: Data.SGF.Parse.Encodings, + Data.SGF.Parse.Encodings, Data.SGF.Parse.Raw, Data.SGF.Parse.Util, Data.SGF.Reexports @@ -40,6 +46,7 @@ library time >= 1.12.2 && < 1.16, split >= 0.2.5, parsec >= 3.1.16 && < 3.2 + hs-source-dirs: src/ source-repository head type: git diff --git a/Data/SGF/Parse.hs b/src/Data/SGF/Parse.hs similarity index 100% rename from Data/SGF/Parse.hs rename to src/Data/SGF/Parse.hs diff --git a/Data/SGF/Parse/Encodings.hs b/src/Data/SGF/Parse/Encodings.hs similarity index 100% rename from Data/SGF/Parse/Encodings.hs rename to src/Data/SGF/Parse/Encodings.hs diff --git a/Data/SGF/Parse/Raw.hs b/src/Data/SGF/Parse/Raw.hs similarity index 100% rename from Data/SGF/Parse/Raw.hs rename to src/Data/SGF/Parse/Raw.hs diff --git a/Data/SGF/Parse/Util.hs b/src/Data/SGF/Parse/Util.hs similarity index 100% rename from Data/SGF/Parse/Util.hs rename to src/Data/SGF/Parse/Util.hs diff --git a/src/Data/SGF/Reexports.hs b/src/Data/SGF/Reexports.hs new file mode 100644 index 0000000..db0af3e --- /dev/null +++ b/src/Data/SGF/Reexports.hs @@ -0,0 +1,12 @@ +module Data.SGF.Reexports ( + module Data.Word, + module Data.Tree, + module Text.ParserCombinators.Parsec, + module Data.ByteString + ) where + +import Data.Word +import Data.Tree +import Text.ParserCombinators.Parsec (runParser) + +import Data.ByteString (getContents, unpack, readFile) diff --git a/Data/SGF/Types.hs b/src/Data/SGF/Types.hs similarity index 100% rename from Data/SGF/Types.hs rename to src/Data/SGF/Types.hs From a32484e1b8df9c510c89dbd476c155c2f96fea0c Mon Sep 17 00:00:00 2001 From: Francesco Ariis Date: Fri, 22 Aug 2025 14:51:23 +0200 Subject: [PATCH 05/17] Format .cabal file Whitespace and vertical alignment. --- sgf.cabal | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/sgf.cabal b/sgf.cabal index cea219e..02ac447 100644 --- a/sgf.cabal +++ b/sgf.cabal @@ -2,7 +2,7 @@ cabal-version: 2.2 name: sgf version: 0.1.3.3 author: Daniel Wagner daniel@wagner-home.com -maintainer: Toni Cebrián ancechu@gmail.com +maintainer: Toni Cebrián ancechu@gmail.com homepage: https://github.com/tonicebrian/sgf bug-reports: https://github.com/tonicebrian/sgf/issues synopsis: SGF (Smart Game Format) parser @@ -18,9 +18,9 @@ license-file: LICENSE build-type: Simple common shared - build-depends: base == 4.*, - ghc-options: -Wall - default-language: Haskell2010 + build-depends: base == 4.*, + ghc-options: -Wall + default-language: Haskell2010 library import: shared @@ -37,15 +37,15 @@ library sgf-internal Data.SGF.Parse.Raw, Data.SGF.Parse.Util, Data.SGF.Reexports - build-depends: bytestring >= 0.12.2 && < 0.13, - containers >= 0.6.7 && < 0.9, - encoding >= 0.8.9 && < 0.11, - extensible-exceptions >= 0.1.1 && < 0.2, - mtl >= 2.2.2, - transformers >= 0.5.6, - time >= 1.12.2 && < 1.16, - split >= 0.2.5, - parsec >= 3.1.16 && < 3.2 + build-depends: bytestring >= 0.12.2 && < 0.13, + containers >= 0.6.7 && < 0.9, + encoding >= 0.8.9 && < 0.11, + extensible-exceptions >= 0.1.1 && < 0.2, + mtl >= 2.2.2, + transformers >= 0.5.6, + time >= 1.12.2 && < 1.16, + split >= 0.2.5, + parsec >= 3.1.16 && < 3.2 hs-source-dirs: src/ source-repository head From c878f671ae7fafdb05c3721b5bd88ce283de065e Mon Sep 17 00:00:00 2001 From: Francesco Ariis Date: Fri, 22 Aug 2025 14:53:07 +0200 Subject: [PATCH 06/17] Put upper bounds --- sgf.cabal | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sgf.cabal b/sgf.cabal index 02ac447..7077b05 100644 --- a/sgf.cabal +++ b/sgf.cabal @@ -41,10 +41,10 @@ library sgf-internal containers >= 0.6.7 && < 0.9, encoding >= 0.8.9 && < 0.11, extensible-exceptions >= 0.1.1 && < 0.2, - mtl >= 2.2.2, - transformers >= 0.5.6, + mtl >= 2.2.2 && < 2.4, + transformers >= 0.5.6 && < 0.7, time >= 1.12.2 && < 1.16, - split >= 0.2.5, + split >= 0.2.5 && < 0.3, parsec >= 3.1.16 && < 3.2 hs-source-dirs: src/ From 9f24c3f7b42b0ac86aded7c8326301b0162f175b Mon Sep 17 00:00:00 2001 From: Francesco Ariis Date: Fri, 22 Aug 2025 15:06:58 +0200 Subject: [PATCH 07/17] Fix `guessEncoding` hanging --- sgf.cabal | 11 +++++++++++ src/Data/SGF/Parse/Encodings.hs | 8 ++++---- test/Test.hs | 1 + test/Unit/Data/SGF/Parse/EncodingsSpec.hs | 16 ++++++++++++++++ 4 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 test/Test.hs create mode 100644 test/Unit/Data/SGF/Parse/EncodingsSpec.hs diff --git a/sgf.cabal b/sgf.cabal index 7077b05..b3d99f1 100644 --- a/sgf.cabal +++ b/sgf.cabal @@ -48,6 +48,17 @@ library sgf-internal parsec >= 3.1.16 && < 3.2 hs-source-dirs: src/ +test-suite test + import: shared + main-is: Test.hs + other-modules: Unit.Data.SGF.Parse.EncodingsSpec + build-depends: sgf-internal, + hspec >= 2.11.8 && < 2.12, + build-tool-depends: hspec-discover:hspec-discover + hs-source-dirs: test + type: exitcode-stdio-1.0 + + source-repository head type: git location: https://github.com/tonicebrian/sgf diff --git a/src/Data/SGF/Parse/Encodings.hs b/src/Data/SGF/Parse/Encodings.hs index df4f7d1..0755191 100644 --- a/src/Data/SGF/Parse/Encodings.hs +++ b/src/Data/SGF/Parse/Encodings.hs @@ -3,9 +3,9 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE InstanceSigs #-} -module Data.SGF.Parse.Encodings - ( guessEncoding - , decodeWordStringExplicit +module Data.SGF.Parse.Encodings ( + module Data.SGF.Parse.Encodings, + encodingFromString ) where import Control.Applicative (Applicative(..)) @@ -27,7 +27,7 @@ instance Functor (MyEither a) where instance Applicative (MyEither a) where pure :: a2 -> MyEither a1 a2 - pure x = return x -- note that an eta reduced version of this trips the type checker for non-canonical "pure = return" + pure x = MyEither (Right x) (<*>) :: MyEither a1 (a2 -> b) -> MyEither a1 a2 -> MyEither a1 b (<*>) = ap diff --git a/test/Test.hs b/test/Test.hs new file mode 100644 index 0000000..a824f8c --- /dev/null +++ b/test/Test.hs @@ -0,0 +1 @@ +{-# OPTIONS_GHC -F -pgmF hspec-discover #-} diff --git a/test/Unit/Data/SGF/Parse/EncodingsSpec.hs b/test/Unit/Data/SGF/Parse/EncodingsSpec.hs new file mode 100644 index 0000000..93ca87e --- /dev/null +++ b/test/Unit/Data/SGF/Parse/EncodingsSpec.hs @@ -0,0 +1,16 @@ +module Unit.Data.SGF.Parse.EncodingsSpec where + +import Data.SGF.Parse.Encodings + +import Test.Hspec + + +main :: IO () +main = hspec spec + +spec :: Spec +spec = do + + describe "guessEncoding" $ do + it "does not hang" $ + guessEncoding [85,84,70,45,56] `shouldBe` [encodingFromString "utf-8"] From 5aac1dece70e761084109de58421b69fd9bfcc74 Mon Sep 17 00:00:00 2001 From: Francesco Ariis Date: Fri, 22 Aug 2025 15:09:20 +0200 Subject: [PATCH 08/17] Clean Data.SGF.Parse.EncodingsSpec Fixed * Unused extensions * Unused imports * Missing type signatures --- src/Data/SGF/Parse/Encodings.hs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Data/SGF/Parse/Encodings.hs b/src/Data/SGF/Parse/Encodings.hs index 0755191..3ca2f97 100644 --- a/src/Data/SGF/Parse/Encodings.hs +++ b/src/Data/SGF/Parse/Encodings.hs @@ -1,4 +1,3 @@ -{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE InstanceSigs #-} @@ -8,8 +7,6 @@ module Data.SGF.Parse.Encodings ( encodingFromString ) where -import Control.Applicative (Applicative(..)) -import Control.Exception.Extensible import Control.Monad (ap, liftM) import Control.Monad.State import Control.Throws @@ -33,7 +30,7 @@ instance Applicative (MyEither a) where instance Monad (MyEither a) where (MyEither (Right x)) >>= f = f x - (MyEither (Left x)) >>= f = MyEither (Left x) + (MyEither (Left x)) >>= _ = MyEither (Left x) instance ByteSource (StateT [Word8] (MyEither DecodingException)) where sourceEmpty = gets null @@ -49,8 +46,10 @@ instance ByteSource (StateT [Word8] (MyEither DecodingException)) where return v -- some ones that we know satisfy our invariant (see SGF.Parse.Raw) +encodings :: [DynEncoding] encodings = map encodingFromString ["latin1", "utf-8", "ascii"] +guess :: [Word8] -> DynEncoding -> Bool guess ws encoding = case runStateT (decode encoding) ws :: MyIHateGHC of (MyEither (Right (s, []))) -> From 4d5d84822469798be72574b3df610a26e67a0c01 Mon Sep 17 00:00:00 2001 From: Francesco Ariis Date: Fri, 22 Aug 2025 15:11:03 +0200 Subject: [PATCH 09/17] Removed useless stack .lock files --- stack-9.6.yaml.lock | 26 -------------------------- stack.yaml.lock | 33 --------------------------------- 2 files changed, 59 deletions(-) delete mode 100644 stack-9.6.yaml.lock delete mode 100644 stack.yaml.lock diff --git a/stack-9.6.yaml.lock b/stack-9.6.yaml.lock deleted file mode 100644 index b13807b..0000000 --- a/stack-9.6.yaml.lock +++ /dev/null @@ -1,26 +0,0 @@ -# This file was autogenerated by Stack. -# You should not edit this file by hand. -# For more information, please see the documentation at: -# https://docs.haskellstack.org/en/stable/lock_files - -packages: -- completed: - hackage: encoding-0.8.9@sha256:9a6c6d16f8d92e2fc379427a47831488aba03bb6f50d6fce3cf204775b41acd6,5362 - pantry-tree: - sha256: 8e7d82f65affaa39268d6c8020bce6d392eecd444f48bffb2be6d8d2df5ec329 - size: 5454 - original: - hackage: encoding-0.8.9 -- completed: - hackage: regex-compat-0.95.2.1@sha256:96c83b06280ebfb6fef01864b2af9eb9e136a9832c563773f327d4197bbbb851,1705 - pantry-tree: - sha256: 3e65e1219ca48e8988b93151ef6d3d705f57ae65f1ba91e8e8b626c2eaa6b43f - size: 262 - original: - hackage: regex-compat-0.95.2.1 -snapshots: -- completed: - sha256: 6a553c5fa4f211a9b639da5e5359124a93627852dd9967bed202fdd71b25f15e - size: 720021 - url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/22/36.yaml - original: lts-22.36 diff --git a/stack.yaml.lock b/stack.yaml.lock deleted file mode 100644 index 3e99f6f..0000000 --- a/stack.yaml.lock +++ /dev/null @@ -1,33 +0,0 @@ -# This file was autogenerated by Stack. -# You should not edit this file by hand. -# For more information, please see the documentation at: -# https://docs.haskellstack.org/en/stable/lock_files - -packages: -- completed: - hackage: encoding-0.8.9@sha256:9a6c6d16f8d92e2fc379427a47831488aba03bb6f50d6fce3cf204775b41acd6,5362 - pantry-tree: - sha256: 8e7d82f65affaa39268d6c8020bce6d392eecd444f48bffb2be6d8d2df5ec329 - size: 5454 - original: - hackage: encoding-0.8.9 -- completed: - hackage: regex-compat-0.95.2.1@sha256:96c83b06280ebfb6fef01864b2af9eb9e136a9832c563773f327d4197bbbb851,1705 - pantry-tree: - sha256: 3e65e1219ca48e8988b93151ef6d3d705f57ae65f1ba91e8e8b626c2eaa6b43f - size: 262 - original: - hackage: regex-compat-0.95.2.1 -- completed: - hackage: split-0.2.5@sha256:5bc1ae848bfded3087ea3e568908f1b75f56ecde6f02df3fad1a138dd5c783d5,2625 - pantry-tree: - sha256: 5d28c851a2c98e3d8ac0f01adc58303d775afe39dce23ec953be64ae65d11166 - size: 443 - original: - hackage: split-0.2.5 -snapshots: -- completed: - sha256: a81fb3877c4f9031e1325eb3935122e608d80715dc16b586eb11ddbff8671ecd - size: 640086 - url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/21/25.yaml - original: lts-21.25 From 81f09167f7f1f0b03f8c0e01d51cb416a5ef8962 Mon Sep 17 00:00:00 2001 From: Francesco Ariis Date: Fri, 22 Aug 2025 15:23:33 +0200 Subject: [PATCH 10/17] Fix example --- lib/Data/SGF.hs | 2 -- src/Data/SGF/Reexports.hs | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/Data/SGF.hs b/lib/Data/SGF.hs index 504e895..9181b99 100644 --- a/lib/Data/SGF.hs +++ b/lib/Data/SGF.hs @@ -97,8 +97,6 @@ obscure the idea.) First, some boring stuff. > import Data.SGF -> import Data.ByteString (ByteString, getContents, unpack) -> import Data.Tree > import Data.List hiding ((!!)) > import Prelude hiding ((!!), getContents) > diff --git a/src/Data/SGF/Reexports.hs b/src/Data/SGF/Reexports.hs index db0af3e..9bd38e8 100644 --- a/src/Data/SGF/Reexports.hs +++ b/src/Data/SGF/Reexports.hs @@ -6,7 +6,7 @@ module Data.SGF.Reexports ( ) where import Data.Word -import Data.Tree +import Data.Tree (Tree(..), levels) import Text.ParserCombinators.Parsec (runParser) -import Data.ByteString (getContents, unpack, readFile) +import Data.ByteString (ByteString, getContents, unpack, readFile) From 7e815fc88eceee467e0f1672b26caf7977fdb3b9 Mon Sep 17 00:00:00 2001 From: Francesco Ariis Date: Fri, 22 Aug 2025 15:57:27 +0200 Subject: [PATCH 11/17] Make docs pretty --- lib/Data/SGF.hs | 6 ++---- lib/Data/SGF/Prim.hs | 10 ++++++++++ sgf.cabal | 3 ++- src/Data/SGF/Reexports.hs | 2 +- 4 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 lib/Data/SGF/Prim.hs diff --git a/lib/Data/SGF.hs b/lib/Data/SGF.hs index 9181b99..86ae112 100644 --- a/lib/Data/SGF.hs +++ b/lib/Data/SGF.hs @@ -6,8 +6,7 @@ robust to minor errors, especially those made by the most common SGF editors. There are plans to support other games and pretty-printing in future releases. -} module Data.SGF ( - module Data.SGF.Types, - module Data.SGF.Parse, + module Data.SGF.Prim, -- * Overview of SGF -- $sgf @@ -21,8 +20,7 @@ module Data.SGF ( module Data.SGF.Reexports ) where -import Data.SGF.Types -import Data.SGF.Parse (collection) +import Data.SGF.Prim import Data.SGF.Reexports -- TODO: diff --git a/lib/Data/SGF/Prim.hs b/lib/Data/SGF/Prim.hs new file mode 100644 index 0000000..eae2975 --- /dev/null +++ b/lib/Data/SGF/Prim.hs @@ -0,0 +1,10 @@ +module Data.SGF.Prim ( + -- * Types + module Data.SGF.Types, + + -- * Parse + module Data.SGF.Parse + ) where + +import Data.SGF.Parse (collection) +import Data.SGF.Types diff --git a/sgf.cabal b/sgf.cabal index b3d99f1..812bcb8 100644 --- a/sgf.cabal +++ b/sgf.cabal @@ -24,7 +24,8 @@ common shared library import: shared - exposed-modules: Data.SGF + exposed-modules: Data.SGF, + Data.SGF.Prim build-depends: sgf-internal hs-source-dirs: lib/ diff --git a/src/Data/SGF/Reexports.hs b/src/Data/SGF/Reexports.hs index 9bd38e8..f230f8b 100644 --- a/src/Data/SGF/Reexports.hs +++ b/src/Data/SGF/Reexports.hs @@ -5,7 +5,7 @@ module Data.SGF.Reexports ( module Data.ByteString ) where -import Data.Word +import Data.Word (Word8(..)) import Data.Tree (Tree(..), levels) import Text.ParserCombinators.Parsec (runParser) From 679416ca5e578b343630603ecbe86476512b8bdc Mon Sep 17 00:00:00 2001 From: Francesco Ariis Date: Fri, 22 Aug 2025 18:38:31 +0200 Subject: [PATCH 12/17] Fix warnings --- src/Data/SGF/Parse.hs | 2 +- src/Data/SGF/Parse/Raw.hs | 36 ++++++++++++++++++++++++++---------- src/Data/SGF/Parse/Util.hs | 29 +++++++++++++++++------------ src/Data/SGF/Reexports.hs | 2 +- src/Data/SGF/Types.hs | 2 ++ 5 files changed, 47 insertions(+), 24 deletions(-) diff --git a/src/Data/SGF/Parse.hs b/src/Data/SGF/Parse.hs index 4bd85d3..267a14d 100644 --- a/src/Data/SGF/Parse.hs +++ b/src/Data/SGF/Parse.hs @@ -77,7 +77,7 @@ test = runParser collection () "" . map enum -- two kinds of errors in SGF files: recoverable ones (which will be -- accumulated in the ['Warning'] return) and unrecoverable ones (which will -- result in parse errors). -collection :: Stream s m Word8 => ParsecT s u m (Collection, [Warning]) +collection :: SGFParser (Collection, [Warning]) collection = second concat . unzip <$> (mapM (translate gameTree) =<< Raw.collection) diff --git a/src/Data/SGF/Parse/Raw.hs b/src/Data/SGF/Parse/Raw.hs index 2e06406..c46266d 100644 --- a/src/Data/SGF/Parse/Raw.hs +++ b/src/Data/SGF/Parse/Raw.hs @@ -3,6 +3,7 @@ module Data.SGF.Parse.Raw ( collection, Property(..), + SGFParser, enum ) where @@ -12,9 +13,12 @@ import Data.Char import Data.Tree import Data.Word import Prelude hiding (lex) -import Text.Parsec (SourcePos(..), incSourceColumn) +import Text.Parsec (SourcePos, incSourceColumn) import Text.Parsec.Prim import Text.Parsec.Combinator + +type SGFParser a = Parsec [Word8] () a + -- }}} data Property = Property { position :: SourcePos, -- ^ @@ -38,19 +42,25 @@ data Property = Property { -- things. enum :: (Enum a, Enum b) => a -> b enum = toEnum . fromEnum +ensure :: (Monad m, Alternative m) => (b -> Bool) -> b -> m b ensure p x = guard (p x) >> return x +satisfy :: (Word8 -> Bool) -> SGFParser Word8 satisfy p = tokenPrim ((\x -> ['\'', x, '\'']) . enum) (\pos _ _ -> incSourceColumn pos 1) (ensure p) +satisfyChar :: Enum b => (b -> Bool) -> SGFParser Word8 satisfyChar = satisfy . (. enum) +anyWord :: SGFParser Word8 anyWord = satisfy (const True) +exactWord :: Char -> SGFParser Word8 exactWord = satisfy . (==) . enum -someWord = satisfy . flip elem . map enum +noWord :: [Char] -> SGFParser Word8 noWord = satisfy . flip notElem . map enum +whitespace :: SGFParser [Word8] whitespace = many (satisfyChar isSpace) -- assumed: the current byte is literally ASCII '\\' iff the current byte is @@ -58,30 +68,36 @@ whitespace = many (satisfyChar isSpace) -- the bytes that are literally ASCII ']' and ASCII ':' occur after the first -- byte of any multi-byte encoded character -- (in particular, UTF-8, ASCII, and ISO 8859-1 satisfy this property) +escapedChar :: SGFParser [Word8] escapedChar = liftM2 (\x y -> [x, y]) (exactWord '\\') anyWord +unescapedExcept :: [Char] -> SGFParser [Word8] unescapedExcept ws = fmap return (noWord ws) +literalTextExcept :: [Char] -> SGFParser [Word8] literalTextExcept ws = fmap concat $ many (escapedChar <|> unescapedExcept ws) +property :: SGFParser Property property = liftM3 ((. map enum) . Property) (getPosition) (many1 (satisfyChar (liftM2 (&&) isUpper (< '\128')))) (sepEndBy1 (exactWord '[' >> literalTextExcept "]" <* exactWord ']') whitespace) +node :: SGFParser [Property] node = do - exactWord ';' - whitespace + _ <- exactWord ';' + _ <- whitespace sepEndBy property whitespace +gameTree :: SGFParser (Tree [Property]) gameTree = do - exactWord '(' - whitespace - (node:nodes) <- sepEndBy1 node whitespace + _ <- exactWord '(' + _ <- whitespace + (node':nodes) <- sepEndBy1 node whitespace trees <- sepEndBy gameTree whitespace - exactWord ')' - return (Node node (foldr ((return .) . Node) trees nodes)) + _ <- exactWord ')' + return (Node node' (foldr ((return .) . Node) trees nodes)) -- | -- Parse the tree-structure of an SGF file, but without any knowledge of the -- semantics of the properties, etc. -collection :: Stream s m Word8 => ParsecT s u m [Tree [Property]] +collection :: SGFParser [Tree [Property]] collection = whitespace >> sepEndBy1 gameTree whitespace <* whitespace <* eof diff --git a/src/Data/SGF/Parse/Util.hs b/src/Data/SGF/Parse/Util.hs index 95e0864..b2584c3 100644 --- a/src/Data/SGF/Parse/Util.hs +++ b/src/Data/SGF/Parse/Util.hs @@ -4,14 +4,13 @@ module Data.SGF.Parse.Util where import Control.Arrow (Arrow (first, second, (&&&))) import Control.Monad (liftM, liftM2, when, (>=>)) import Control.Monad.State (MonadState (get), MonadTrans (lift), StateT (StateT), gets, modify) -import qualified Control.Monad.Trans.Except as Either -import Control.Monad.Writer (MonadTrans (lift), MonadWriter (tell), WriterT) +import Control.Monad.Writer (MonadWriter (tell), WriterT) import Data.Char (isDigit, isSpace, toLower) import Data.Encoding (DynEncoding) import Data.Function (on) import Data.Ix (Ix (range)) import Data.List (groupBy, isPrefixOf, nub, partition, sortBy) -import Data.Map (Map (..), fromList, keys) +import Data.Map (Map, fromList, keys) import Data.Maybe (fromJust, listToMaybe) import Data.Ord (comparing) import Data.SGF.Parse.Encodings (decodeWordStringExplicit) @@ -136,11 +135,11 @@ readNumber s pos newline :: a -> (String -> a) -> (Char -> String -> a) -> String -> a newline empty with without xs = case xs of - '\r' : '\n' : xs -> with xs - '\n' : '\r' : xs -> with xs - '\r' : xs -> with xs - '\n' : xs -> with xs - x : xs -> without x xs + '\r' : '\n' : xs' -> with xs' + '\n' : '\r' : xs' -> with xs' + '\r' : xs' -> with xs' + '\n' : xs' -> with xs' + x : xs' -> without x xs' [] -> empty trim :: Char -> Char @@ -156,8 +155,10 @@ descape hard pos s = case s of decodeAndDescape :: Char -> Header -> PTranslator String decodeAndDescape hard (Header {encoding = e}) (Property {values = v : _, position = pos}) = case decodeWordStringExplicit e v of - Left exception -> dieWithPos BadlyEncodedValue pos + Left _exception -> dieWithPos BadlyEncodedValue pos Right decoded -> descape hard pos decoded +decodeAndDescape _ (Header _ _) (Property _ _ []) = + error "decodeAndDescape error" splitColon :: [Word8] -> Maybe ([Word8], [Word8]) splitColons :: [[Word8]] -> Maybe ([[Word8]], [[Word8]]) @@ -191,7 +192,7 @@ hasAny = fmap or . mapM has consume :: String -> Translator (Maybe Property) consume s = do (v, rest) <- gets (partition ((== s) . name) . rootLabel) - modify (\s -> s {rootLabel = rest}) + modify (\s' -> s' {rootLabel = rest}) return (listToMaybe v) consumeSingle :: String -> Translator (Maybe Property) @@ -206,17 +207,19 @@ consumeSingle s = do unknownProperties :: Translator (Map String [[Word8]]) unknownProperties = do m <- gets (fromList . map (name &&& values) . rootLabel) - tell [UnknownPropertyPreserved name | name <- keys m] + tell [UnknownPropertyPreserved pnam | pnam <- keys m] return m -- }}} -- PTranslators and combinators {{{ number :: PTranslator Integer +number (Property _ _ []) = error "number: empty property list" number p@(Property {values = v : _}) | enum '.' `elem` v = dieWith BadlyFormattedValue p | otherwise = fmap floor (real p) real :: PTranslator Rational +real (Property _ _ []) = error "real: empty property list" real (Property {values = v : _, position = pos}) | [enum '+'] `isPrefixOf` v = result 1 | [enum '-'] `isPrefixOf` v = fmap negate (result 1) @@ -241,7 +244,7 @@ none (Property {values = [[]]}) = return () none p = tell [PropValueForNonePropertyOmitted p] choice :: [([Word8], a)] -> PTranslator a -choice vs p@(Property {values = []}) = dieWith BadlyFormattedValue p -- can't happen +choice _vs p@(Property {values = []}) = dieWith BadlyFormattedValue p -- can't happen choice vs p@(Property {values = v : _}) = maybe (dieWith BadlyFormattedValue p) return (lookup v vs) choice' :: [(String, a)] -> PTranslator a @@ -266,6 +269,8 @@ elistOf _ (Property {values = [[]]}) = return [] elistOf a p = listOf a p mayBeCompoundPoint, listOfPoint, elistOfPoint :: PTranslator Point -> PTranslator [Point] +mayBeCompoundPoint _ (Property _ _ []) = + error "mayBeCompoundPoint: empty property list" mayBeCompoundPoint a p@(Property {values = v : _}) = case splitColon v of Nothing -> return <$> a p Just {} -> do diff --git a/src/Data/SGF/Reexports.hs b/src/Data/SGF/Reexports.hs index f230f8b..fae6ec6 100644 --- a/src/Data/SGF/Reexports.hs +++ b/src/Data/SGF/Reexports.hs @@ -5,7 +5,7 @@ module Data.SGF.Reexports ( module Data.ByteString ) where -import Data.Word (Word8(..)) +import Data.Word (Word8) import Data.Tree (Tree(..), levels) import Text.ParserCombinators.Parsec (runParser) diff --git a/src/Data/SGF/Types.hs b/src/Data/SGF/Types.hs index 73c0ffa..8099919 100644 --- a/src/Data/SGF/Types.hs +++ b/src/Data/SGF/Types.hs @@ -85,6 +85,7 @@ data GameType = Sahara | Byte | Focus | Dvonn | Tamsk | Gipf | Kropki deriving (Eq, Ord, Bounded, Show, Read) +allGameTypesInSGFOrder :: [GameType] allGameTypesInSGFOrder = [Go, Othello, Chess, Gomoku, NineMen'sMorris, Backgammon, ChineseChess, Shogi, LinesOfAction, Ataxx, Hex, Jungle, @@ -204,6 +205,7 @@ data Numbering -- number that the first labeled move is below 100. deriving (Eq, Ord, Show, Read, Enum, Bounded) +allGameInfoTypes :: [GameInfoType] allGameInfoTypes = [TeamName Black, TeamName White, PlayerName Black, PlayerName White, Annotator, Source, User, Copyright, Context, Location, Event, GameName, Opening, Overtime] instance Enum GameInfoType where toEnum = (allGameInfoTypes !!) From 413654fb07e8203bbeab784959a07b745ed339e8 Mon Sep 17 00:00:00 2001 From: Francesco Ariis Date: Sat, 27 Sep 2025 20:57:25 +0200 Subject: [PATCH 13/17] Do not break interface Revert to having three exposed modules: Data.SGF Data.SGF.Parse Data.SGF.Types Far from ergonomic, but at least it will not break API. --- lib/Data/SGF.hs | 6 ++++-- lib/Data/SGF/Prim.hs | 10 ---------- sgf.cabal | 7 ++++--- src/Data/SGF/{Parse.hs => Parse/Internal.hs} | 8 ++++---- src/Data/SGF/Parse/Util.hs | 2 +- src/Data/SGF/{Types.hs => Types/Internal.hs} | 2 +- 6 files changed, 14 insertions(+), 21 deletions(-) delete mode 100644 lib/Data/SGF/Prim.hs rename src/Data/SGF/{Parse.hs => Parse/Internal.hs} (99%) rename src/Data/SGF/{Types.hs => Types/Internal.hs} (99%) diff --git a/lib/Data/SGF.hs b/lib/Data/SGF.hs index 86ae112..f5fa0a5 100644 --- a/lib/Data/SGF.hs +++ b/lib/Data/SGF.hs @@ -6,7 +6,8 @@ robust to minor errors, especially those made by the most common SGF editors. There are plans to support other games and pretty-printing in future releases. -} module Data.SGF ( - module Data.SGF.Prim, + module Data.SGF.Types, + collection, -- * Overview of SGF -- $sgf @@ -20,7 +21,8 @@ module Data.SGF ( module Data.SGF.Reexports ) where -import Data.SGF.Prim +import Data.SGF.Types +import Data.SGF.Parse (collection) import Data.SGF.Reexports -- TODO: diff --git a/lib/Data/SGF/Prim.hs b/lib/Data/SGF/Prim.hs deleted file mode 100644 index eae2975..0000000 --- a/lib/Data/SGF/Prim.hs +++ /dev/null @@ -1,10 +0,0 @@ -module Data.SGF.Prim ( - -- * Types - module Data.SGF.Types, - - -- * Parse - module Data.SGF.Parse - ) where - -import Data.SGF.Parse (collection) -import Data.SGF.Types diff --git a/sgf.cabal b/sgf.cabal index 812bcb8..c658e77 100644 --- a/sgf.cabal +++ b/sgf.cabal @@ -25,15 +25,16 @@ common shared library import: shared exposed-modules: Data.SGF, - Data.SGF.Prim + Data.SGF.Parse, + Data.SGF.Types build-depends: sgf-internal hs-source-dirs: lib/ library sgf-internal import: shared visibility: internal - exposed-modules: Data.SGF.Parse, - Data.SGF.Types, + exposed-modules: Data.SGF.Parse.Internal, + Data.SGF.Types.Internal, Data.SGF.Parse.Encodings, Data.SGF.Parse.Raw, Data.SGF.Parse.Util, diff --git a/src/Data/SGF/Parse.hs b/src/Data/SGF/Parse/Internal.hs similarity index 99% rename from src/Data/SGF/Parse.hs rename to src/Data/SGF/Parse/Internal.hs index 267a14d..c13caea 100644 --- a/src/Data/SGF/Parse.hs +++ b/src/Data/SGF/Parse/Internal.hs @@ -8,7 +8,7 @@ -- boilerplate {{{ -- TODO: check that every occurrence of "die" should really be a death, and not just a "fix-it-up-and-warn" -- boilerplate {{{ -module Data.SGF.Parse +module Data.SGF.Parse.Internal ( collection , clipDate , PropertyType(..) @@ -40,15 +40,15 @@ import Data.SGF.Parse.Encodings import Data.SGF.Parse.Raw hiding (collection) import qualified Data.SGF.Parse.Raw as Raw import Data.SGF.Parse.Util -import Data.SGF.Types (Game(Game), GameNode(GameNode)) -import Data.SGF.Types hiding +import Data.SGF.Types.Internal (Game(Game), GameNode(GameNode)) +import Data.SGF.Types.Internal hiding ( Game(..) , GameInfo(..) , GameNode(..) , Move(..) , Setup(..) ) -import qualified Data.SGF.Types as T +import qualified Data.SGF.Types.Internal as T import qualified Data.Set as Set import Data.Time.Calendar import Data.Tree diff --git a/src/Data/SGF/Parse/Util.hs b/src/Data/SGF/Parse/Util.hs index b2584c3..57726fd 100644 --- a/src/Data/SGF/Parse/Util.hs +++ b/src/Data/SGF/Parse/Util.hs @@ -15,7 +15,7 @@ import Data.Maybe (fromJust, listToMaybe) import Data.Ord (comparing) import Data.SGF.Parse.Encodings (decodeWordStringExplicit) import Data.SGF.Parse.Raw (Property (..), enum) -import Data.SGF.Types (Color (..), Emphasis (..), Judgment, Mark, PartialDate, Point) +import Data.SGF.Types.Internal (Color (..), Emphasis (..), Judgment, Mark, PartialDate, Point) import Data.Set (Set) import Data.Tree (Tree (rootLabel)) import Data.Word (Word8) diff --git a/src/Data/SGF/Types.hs b/src/Data/SGF/Types/Internal.hs similarity index 99% rename from src/Data/SGF/Types.hs rename to src/Data/SGF/Types/Internal.hs index 8099919..3de04e3 100644 --- a/src/Data/SGF/Types.hs +++ b/src/Data/SGF/Types/Internal.hs @@ -3,7 +3,7 @@ -- | Types used to represent an SGF tree. Whenever a data type is used by -- exactly one other data type, there will be a \"see also\" link to its -- containing type. -module Data.SGF.Types ( +module Data.SGF.Types.Internal ( -- * Game type Game(..), GameTree(..), GameNode(..), Move(..), Setup(..), From f7bac80bf0bbb123772de52383e0de8d47203a14 Mon Sep 17 00:00:00 2001 From: Francesco Ariis Date: Mon, 20 Oct 2025 09:02:44 +0200 Subject: [PATCH 14/17] Remove Reexports --- lib/Data/SGF.hs | 12 ++++++++++-- sgf.cabal | 8 +++++--- src/Data/SGF/Reexports.hs | 12 ------------ 3 files changed, 15 insertions(+), 17 deletions(-) delete mode 100644 src/Data/SGF/Reexports.hs diff --git a/lib/Data/SGF.hs b/lib/Data/SGF.hs index f5fa0a5..fdce25d 100644 --- a/lib/Data/SGF.hs +++ b/lib/Data/SGF.hs @@ -18,12 +18,20 @@ module Data.SGF ( -- $example -- * Convenience reexports - module Data.SGF.Reexports + Word8, + Tree(..), levels, + runParser, + B.ByteString, B.getContents, B.unpack, B.readFile ) where import Data.SGF.Types import Data.SGF.Parse (collection) -import Data.SGF.Reexports + +import Data.Word (Word8) +import Data.Tree (Tree(..), levels) +import Text.ParserCombinators.Parsec (runParser) + +import qualified Data.ByteString as B -- TODO: -- * support parsing from ByteString, then take the "unpack" out of "parse" below diff --git a/sgf.cabal b/sgf.cabal index c658e77..a0490f3 100644 --- a/sgf.cabal +++ b/sgf.cabal @@ -27,7 +27,10 @@ library exposed-modules: Data.SGF, Data.SGF.Parse, Data.SGF.Types - build-depends: sgf-internal + build-depends: sgf-internal, + bytestring >= 0.12.2 && < 0.13, + containers >= 0.6.7 && < 0.9, + parsec >= 3.1.16 && < 3.2 hs-source-dirs: lib/ library sgf-internal @@ -37,8 +40,7 @@ library sgf-internal Data.SGF.Types.Internal, Data.SGF.Parse.Encodings, Data.SGF.Parse.Raw, - Data.SGF.Parse.Util, - Data.SGF.Reexports + Data.SGF.Parse.Util build-depends: bytestring >= 0.12.2 && < 0.13, containers >= 0.6.7 && < 0.9, encoding >= 0.8.9 && < 0.11, diff --git a/src/Data/SGF/Reexports.hs b/src/Data/SGF/Reexports.hs deleted file mode 100644 index fae6ec6..0000000 --- a/src/Data/SGF/Reexports.hs +++ /dev/null @@ -1,12 +0,0 @@ -module Data.SGF.Reexports ( - module Data.Word, - module Data.Tree, - module Text.ParserCombinators.Parsec, - module Data.ByteString - ) where - -import Data.Word (Word8) -import Data.Tree (Tree(..), levels) -import Text.ParserCombinators.Parsec (runParser) - -import Data.ByteString (ByteString, getContents, unpack, readFile) From 3ea532ca8e3fcf109e222a6b7032dd8f21211fcd Mon Sep 17 00:00:00 2001 From: Francesco Ariis Date: Mon, 20 Oct 2025 09:06:46 +0200 Subject: [PATCH 15/17] Add missing modules --- lib/Data/SGF/Parse.hs | 5 +++++ lib/Data/SGF/Types.hs | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 lib/Data/SGF/Parse.hs create mode 100644 lib/Data/SGF/Types.hs diff --git a/lib/Data/SGF/Parse.hs b/lib/Data/SGF/Parse.hs new file mode 100644 index 0000000..b2998c1 --- /dev/null +++ b/lib/Data/SGF/Parse.hs @@ -0,0 +1,5 @@ +module Data.SGF.Parse ( + module Data.SGF.Parse.Internal + ) where + +import Data.SGF.Parse.Internal diff --git a/lib/Data/SGF/Types.hs b/lib/Data/SGF/Types.hs new file mode 100644 index 0000000..86e7227 --- /dev/null +++ b/lib/Data/SGF/Types.hs @@ -0,0 +1,5 @@ +module Data.SGF.Types ( + module Data.SGF.Types.Internal, + ) where + +import Data.SGF.Types.Internal From 852fcca13fcd5b07daeb6e47422e08658c3ef386 Mon Sep 17 00:00:00 2001 From: Francesco Ariis Date: Mon, 20 Oct 2025 09:07:58 +0200 Subject: [PATCH 16/17] Fix internal library visibility --- sgf.cabal | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sgf.cabal b/sgf.cabal index a0490f3..ecbe228 100644 --- a/sgf.cabal +++ b/sgf.cabal @@ -1,4 +1,4 @@ -cabal-version: 2.2 +cabal-version: 3.0 name: sgf version: 0.1.3.3 author: Daniel Wagner daniel@wagner-home.com @@ -35,7 +35,7 @@ library library sgf-internal import: shared - visibility: internal + visibility: private exposed-modules: Data.SGF.Parse.Internal, Data.SGF.Types.Internal, Data.SGF.Parse.Encodings, From d73400be1d8156992fc2bc11e34d7600c1f6edb6 Mon Sep 17 00:00:00 2001 From: Francesco Ariis Date: Mon, 20 Oct 2025 09:46:47 +0200 Subject: [PATCH 17/17] Fix stack --- sgf.cabal | 6 +++--- stack-9.6.yaml.lock | 26 ++++++++++++++++++++++++++ stack.yaml.lock | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 stack-9.6.yaml.lock create mode 100644 stack.yaml.lock diff --git a/sgf.cabal b/sgf.cabal index ecbe228..8fe4154 100644 --- a/sgf.cabal +++ b/sgf.cabal @@ -28,7 +28,7 @@ library Data.SGF.Parse, Data.SGF.Types build-depends: sgf-internal, - bytestring >= 0.12.2 && < 0.13, + bytestring >= 0.11.5.3 && < 0.13, containers >= 0.6.7 && < 0.9, parsec >= 3.1.16 && < 3.2 hs-source-dirs: lib/ @@ -41,7 +41,7 @@ library sgf-internal Data.SGF.Parse.Encodings, Data.SGF.Parse.Raw, Data.SGF.Parse.Util - build-depends: bytestring >= 0.12.2 && < 0.13, + build-depends: bytestring >= 0.11.5.3 && < 0.13, containers >= 0.6.7 && < 0.9, encoding >= 0.8.9 && < 0.11, extensible-exceptions >= 0.1.1 && < 0.2, @@ -57,7 +57,7 @@ test-suite test main-is: Test.hs other-modules: Unit.Data.SGF.Parse.EncodingsSpec build-depends: sgf-internal, - hspec >= 2.11.8 && < 2.12, + hspec >= 2.10.10 && < 2.12, build-tool-depends: hspec-discover:hspec-discover hs-source-dirs: test type: exitcode-stdio-1.0 diff --git a/stack-9.6.yaml.lock b/stack-9.6.yaml.lock new file mode 100644 index 0000000..b13807b --- /dev/null +++ b/stack-9.6.yaml.lock @@ -0,0 +1,26 @@ +# This file was autogenerated by Stack. +# You should not edit this file by hand. +# For more information, please see the documentation at: +# https://docs.haskellstack.org/en/stable/lock_files + +packages: +- completed: + hackage: encoding-0.8.9@sha256:9a6c6d16f8d92e2fc379427a47831488aba03bb6f50d6fce3cf204775b41acd6,5362 + pantry-tree: + sha256: 8e7d82f65affaa39268d6c8020bce6d392eecd444f48bffb2be6d8d2df5ec329 + size: 5454 + original: + hackage: encoding-0.8.9 +- completed: + hackage: regex-compat-0.95.2.1@sha256:96c83b06280ebfb6fef01864b2af9eb9e136a9832c563773f327d4197bbbb851,1705 + pantry-tree: + sha256: 3e65e1219ca48e8988b93151ef6d3d705f57ae65f1ba91e8e8b626c2eaa6b43f + size: 262 + original: + hackage: regex-compat-0.95.2.1 +snapshots: +- completed: + sha256: 6a553c5fa4f211a9b639da5e5359124a93627852dd9967bed202fdd71b25f15e + size: 720021 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/22/36.yaml + original: lts-22.36 diff --git a/stack.yaml.lock b/stack.yaml.lock new file mode 100644 index 0000000..3e99f6f --- /dev/null +++ b/stack.yaml.lock @@ -0,0 +1,33 @@ +# This file was autogenerated by Stack. +# You should not edit this file by hand. +# For more information, please see the documentation at: +# https://docs.haskellstack.org/en/stable/lock_files + +packages: +- completed: + hackage: encoding-0.8.9@sha256:9a6c6d16f8d92e2fc379427a47831488aba03bb6f50d6fce3cf204775b41acd6,5362 + pantry-tree: + sha256: 8e7d82f65affaa39268d6c8020bce6d392eecd444f48bffb2be6d8d2df5ec329 + size: 5454 + original: + hackage: encoding-0.8.9 +- completed: + hackage: regex-compat-0.95.2.1@sha256:96c83b06280ebfb6fef01864b2af9eb9e136a9832c563773f327d4197bbbb851,1705 + pantry-tree: + sha256: 3e65e1219ca48e8988b93151ef6d3d705f57ae65f1ba91e8e8b626c2eaa6b43f + size: 262 + original: + hackage: regex-compat-0.95.2.1 +- completed: + hackage: split-0.2.5@sha256:5bc1ae848bfded3087ea3e568908f1b75f56ecde6f02df3fad1a138dd5c783d5,2625 + pantry-tree: + sha256: 5d28c851a2c98e3d8ac0f01adc58303d775afe39dce23ec953be64ae65d11166 + size: 443 + original: + hackage: split-0.2.5 +snapshots: +- completed: + sha256: a81fb3877c4f9031e1325eb3935122e608d80715dc16b586eb11ddbff8671ecd + size: 640086 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/21/25.yaml + original: lts-21.25