From 37731968053a26862cd495c54d3e9972b3c45cf4 Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Mon, 12 Jun 2023 17:55:38 -0700 Subject: [PATCH 01/13] Bump megaparsec bounds --- package.yaml | 2 +- toml-reader.cabal | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.yaml b/package.yaml index 5475f20..5234922 100644 --- a/package.yaml +++ b/package.yaml @@ -29,7 +29,7 @@ library: dependencies: - base >= 4.9 && < 5 - containers >= 0.6.0.1 && < 0.7 - - megaparsec >= 7.0.5 && < 9.4 + - megaparsec >= 7.0.5 && < 9.5 - parser-combinators >= 1.1.0 && < 1.4 - text >= 1.2.3.1 && < 2.1 - time >= 1.8.0.2 && < 1.13 diff --git a/toml-reader.cabal b/toml-reader.cabal index a8ea5fe..a5c3668 100644 --- a/toml-reader.cabal +++ b/toml-reader.cabal @@ -1,6 +1,6 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.35.0. +-- This file has been generated from package.yaml by hpack version 0.35.2. -- -- see: https://github.com/sol/hpack @@ -53,7 +53,7 @@ library build-depends: base >=4.9 && <5 , containers >=0.6.0.1 && <0.7 - , megaparsec >=7.0.5 && <9.4 + , megaparsec >=7.0.5 && <9.5 , parser-combinators >=1.1.0 && <1.4 , text >=1.2.3.1 && <2.1 , time >=1.8.0.2 && <1.13 From 1d4cb86b45c95313f1aa5f5a091e78368f7d7fb8 Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Mon, 12 Jun 2023 17:57:35 -0700 Subject: [PATCH 02/13] Fix README badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3ed0ebf..cca399b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # toml-reader -[![](https://img.shields.io/github/workflow/status/brandonchinn178/toml-reader/CI/main)](https://github.com/brandonchinn178/toml-reader/actions) +[![GitHub Actions](https://img.shields.io/github/actions/workflow/status/brandonchinn178/toml-reader/ci.yml?branch=main)](https://github.com/brandonchinn178/toml-reader/actions?query=branch%3Amain) [![](https://img.shields.io/codecov/c/gh/brandonchinn178/toml-reader)](https://app.codecov.io/gh/brandonchinn178/toml-reader) [![](https://img.shields.io/hackage/v/toml-reader)](https://hackage.haskell.org/package/toml-reader) From 1573e6909a0bf3fab0114a4a1cf06e52cc93e350 Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Mon, 12 Jun 2023 17:59:37 -0700 Subject: [PATCH 03/13] Reformat CI files --- .github/workflows/ci.yml | 53 ++++++++++++++++++++--------------- .github/workflows/release.yml | 30 +++++++++++--------- 2 files changed, 46 insertions(+), 37 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 404a56c..20f9e0f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,9 +27,10 @@ jobs: STACK_YAML: ${{ matrix.stack_yaml }} steps: - - uses: actions/checkout@v3 - - - name: Install toml-test + - + uses: actions/checkout@v3 + - + name: Install toml-test env: TOML_TEST_VERSION: '1.2.0' run: | @@ -39,21 +40,23 @@ jobs: gunzip toml-test.gz chmod +x toml-test mv toml-test /usr/local/bin/ - - - uses: actions/cache@v3 + - + uses: actions/cache@v3 with: path: ~/.stack key: ${{ runner.os }}-stack-cache-${{ hashFiles(matrix.stack_yaml, 'package.yaml') }} - - name: Build + test + - + name: Build + test run: stack test --coverage - - - name: Check that Cabal file was generated + - + name: Check that Cabal file was generated run: git diff --exit-code '*.cabal' - # upload coverage data - - name: Generate coverage data + - + name: Generate coverage data run: stack install hpc-lcov && hpc-lcov - - uses: codecov/codecov-action@v2 + - + uses: codecov/codecov-action@v2 with: files: lcov.info if: ${{ matrix.latest }} @@ -63,33 +66,37 @@ jobs: env: FOURMOLU_VERSION: '0.7.0.1' steps: - - uses: actions/checkout@v3 - - - name: Install fourmolu + - + uses: actions/checkout@v3 + - + name: Install fourmolu run: | curl -sSL \ "https://github.com/fourmolu/fourmolu/releases/download/v${FOURMOLU_VERSION}/fourmolu-${FOURMOLU_VERSION}-linux-x86_64" \ -o /usr/local/bin/fourmolu chmod +x /usr/local/bin/fourmolu - - name: Run fourmolu + - + name: Run fourmolu run: fourmolu -m check $(git ls-files '*.hs') check_sdist: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/cache@v3 + - + uses: actions/checkout@v3 + - + uses: actions/cache@v3 with: path: ~/.stack key: ${{ runner.os }}-check_sdist-${{ hashFiles('stack.yaml') }} - - - name: Strip unreleased section from CHANGELOG + - + name: Strip unreleased section from CHANGELOG run: sed -i -n '/^## Unreleased/d; /^## /,$p' CHANGELOG.md - - - name: Create sdist bundle + - + name: Create sdist bundle run: stack sdist --test-tarball --tar-dir . - - - uses: actions/upload-artifact@v3 + - + uses: actions/upload-artifact@v3 with: name: toml-reader-sdist path: toml-reader-*.tar.gz diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 16525f8..addf24d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,29 +11,31 @@ jobs: - ci steps: - - uses: actions/checkout@v3 + - + uses: actions/checkout@v3 with: ref: main - - - uses: actions/download-artifact@v3 + - + uses: actions/download-artifact@v3 with: name: toml-reader-sdist path: ./sdist/ - - - uses: brandonchinn178/haskell-actions/parse-cabal-file@parse-cabal-file + - + uses: brandonchinn178/haskell-actions/parse-cabal-file@parse-cabal-file id: cabal_file with: cabal_file: toml-reader.cabal - - name: Set version label + - + name: Set version label run: echo 'VERSION=v${{ steps.cabal_file.outputs.version }}' >> "${GITHUB_ENV}" - - - name: Load Hackage token secret name + - + name: Load Hackage token secret name id: hackage_token_secret run: | USERNAME="$(echo "${GITHUB_ACTOR}" | tr '[:lower:]' '[:upper:]' | tr '-' '_')" echo "name=HACKAGE_TOKEN_${USERNAME}" >> "${GITHUB_OUTPUT}" - - - name: Get CHANGELOG section + - + name: Get CHANGELOG section run: | sed '/^## Unreleased/,/^$/d' CHANGELOG.md > /tmp/changelog-without-unreleased if [[ "$(head -n 1 /tmp/changelog-without-unreleased)" != "## ${VERSION}" ]]; then @@ -41,13 +43,13 @@ jobs: exit 1 fi sed '1 d; /^## v/,$ d' /tmp/changelog-without-unreleased > /tmp/changelog-body - - - uses: brandonchinn178/haskell-actions/hackage-upload@hackage-upload + - + uses: brandonchinn178/haskell-actions/hackage-upload@hackage-upload with: archive: sdist/toml-reader-*.tar.gz token: ${{ secrets[steps.hackage_token_secret.outputs.name] }} - - - uses: softprops/action-gh-release@v1 + - + uses: softprops/action-gh-release@v1 with: tag_name: ${{ env.VERSION }} body_path: /tmp/changelog-body From 4c80f4409c09b175917ade928d540ed7fc0cf883 Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Mon, 12 Jun 2023 18:00:03 -0700 Subject: [PATCH 04/13] Update fourmolu --- .github/workflows/ci.yml | 2 +- src/TOML/Decode.hs | 52 ++++++++++++++++++++-------------------- src/TOML/Parser.hs | 4 ++-- src/TOML/Value.hs | 2 +- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 20f9e0f..1a3b15b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: lint: runs-on: ubuntu-latest env: - FOURMOLU_VERSION: '0.7.0.1' + FOURMOLU_VERSION: '0.13.0.0' steps: - uses: actions/checkout@v3 diff --git a/src/TOML/Decode.hs b/src/TOML/Decode.hs index e56e1e7..5049772 100644 --- a/src/TOML/Decode.hs +++ b/src/TOML/Decode.hs @@ -246,7 +246,7 @@ addContextItem p m = DecodeM $ \ctx -> unDecodeM m (ctx <> [p]) {--- Decoding ---} -- | Decode the given TOML input. -decode :: DecodeTOML a => Text -> Either TOMLError a +decode :: (DecodeTOML a) => Text -> Either TOMLError a decode = decodeWith tomlDecoder -- | Decode the given TOML input using the given 'Decoder'. @@ -259,7 +259,7 @@ decodeWithOpts decoder filename input = do first (uncurry DecodeError) $ decoderToEither decoder v [] -- | Decode a TOML file at the given file path. -decodeFile :: DecodeTOML a => FilePath -> IO (Either TOMLError a) +decodeFile :: (DecodeTOML a) => FilePath -> IO (Either TOMLError a) decodeFile fp = decodeWithOpts tomlDecoder fp <$> Text.readFile fp {--- Decoder helpers ---} @@ -278,7 +278,7 @@ b = 'asdf' MyConfig \<$> getField "a" \<*> getField "b" @ -} -getField :: DecodeTOML a => Text -> Decoder a +getField :: (DecodeTOML a) => Text -> Decoder a getField = getFieldWith tomlDecoder {- | @@ -294,7 +294,7 @@ a = 1 MyConfig \<$> getFieldOr 42 "a" \<*> getFieldOr "asdf" "b" @ -} -getFieldOr :: DecodeTOML a => a -> Text -> Decoder a +getFieldOr :: (DecodeTOML a) => a -> Text -> Decoder a getFieldOr def key = fromMaybe def <$> getFieldOpt key -- | Same as 'getField', except with the given 'Decoder'. @@ -314,7 +314,7 @@ a = 1 MyConfig \<$> getFieldOpt "a" \<*> getFieldOpt "b" @ -} -getFieldOpt :: DecodeTOML a => Text -> Decoder (Maybe a) +getFieldOpt :: (DecodeTOML a) => Text -> Decoder (Maybe a) getFieldOpt = getFieldOptWith tomlDecoder -- | Same as 'getFieldOpt', except with the given 'Decoder'. @@ -333,7 +333,7 @@ a.b = 1 MyConfig \<$> getFields ["a", "b"] @ -} -getFields :: DecodeTOML a => [Text] -> Decoder a +getFields :: (DecodeTOML a) => [Text] -> Decoder a getFields = getFieldsWith tomlDecoder -- | Same as 'getFields', except with the given 'Decoder'. @@ -365,7 +365,7 @@ MyConfig \<*> getFieldsOpt ["b", "c"] @ -} -getFieldsOpt :: DecodeTOML a => [Text] -> Decoder (Maybe a) +getFieldsOpt :: (DecodeTOML a) => [Text] -> Decoder (Maybe a) getFieldsOpt = getFieldsOptWith tomlDecoder -- | Same as 'getFieldsOpt', except with the given 'Decoder'. @@ -428,7 +428,7 @@ instance DecodeTOML Integer where Integer x -> pure x v -> typeMismatch v -tomlDecoderInt :: forall a. Num a => Decoder a +tomlDecoderInt :: forall a. (Num a) => Decoder a tomlDecoderInt = fromInteger <$> tomlDecoder tomlDecoderBoundedInt :: forall a. (Integral a, Bounded a) => Decoder a @@ -472,14 +472,14 @@ instance DecodeTOML Double where Float x -> pure x v -> typeMismatch v -tomlDecoderFrac :: Fractional a => Decoder a +tomlDecoderFrac :: (Fractional a) => Decoder a tomlDecoderFrac = realToFrac <$> tomlDecoder @Double instance DecodeTOML Float where tomlDecoder = tomlDecoderFrac -instance Integral a => DecodeTOML (Ratio a) where +instance (Integral a) => DecodeTOML (Ratio a) where tomlDecoder = tomlDecoderFrac -instance HasResolution a => DecodeTOML (Fixed a) where +instance (HasResolution a) => DecodeTOML (Fixed a) where tomlDecoder = tomlDecoderFrac instance DecodeTOML Char where @@ -568,46 +568,46 @@ instance DecodeTOML Ordering where "GT" -> pure GT _ -> makeDecoder $ invalidValue "Invalid Ordering" -instance DecodeTOML a => DecodeTOML (Identity a) where +instance (DecodeTOML a) => DecodeTOML (Identity a) where tomlDecoder = Identity <$> tomlDecoder instance DecodeTOML (Proxy a) where tomlDecoder = pure Proxy -instance DecodeTOML a => DecodeTOML (Const a b) where +instance (DecodeTOML a) => DecodeTOML (Const a b) where tomlDecoder = Const <$> tomlDecoder {- | Since TOML doesn't support literal NULLs, this will only ever return 'Just'. To get the absence of a field, use 'getFieldOpt' or one of its variants. -} -instance DecodeTOML a => DecodeTOML (Maybe a) where +instance (DecodeTOML a) => DecodeTOML (Maybe a) where tomlDecoder = Just <$> tomlDecoder instance (DecodeTOML a, DecodeTOML b) => DecodeTOML (Either a b) where tomlDecoder = (Right <$> tomlDecoder) <|> (Left <$> tomlDecoder) -instance DecodeTOML a => DecodeTOML (Monoid.First a) where +instance (DecodeTOML a) => DecodeTOML (Monoid.First a) where tomlDecoder = Monoid.First <$> tomlDecoder -instance DecodeTOML a => DecodeTOML (Monoid.Last a) where +instance (DecodeTOML a) => DecodeTOML (Monoid.Last a) where tomlDecoder = Monoid.Last <$> tomlDecoder -instance DecodeTOML a => DecodeTOML (Semigroup.First a) where +instance (DecodeTOML a) => DecodeTOML (Semigroup.First a) where tomlDecoder = Semigroup.First <$> tomlDecoder -instance DecodeTOML a => DecodeTOML (Semigroup.Last a) where +instance (DecodeTOML a) => DecodeTOML (Semigroup.Last a) where tomlDecoder = Semigroup.Last <$> tomlDecoder -instance DecodeTOML a => DecodeTOML (Semigroup.Max a) where +instance (DecodeTOML a) => DecodeTOML (Semigroup.Max a) where tomlDecoder = Semigroup.Max <$> tomlDecoder -instance DecodeTOML a => DecodeTOML (Semigroup.Min a) where +instance (DecodeTOML a) => DecodeTOML (Semigroup.Min a) where tomlDecoder = Semigroup.Min <$> tomlDecoder -instance DecodeTOML a => DecodeTOML (Monoid.Dual a) where +instance (DecodeTOML a) => DecodeTOML (Monoid.Dual a) where tomlDecoder = Monoid.Dual <$> tomlDecoder -instance DecodeTOML a => DecodeTOML [a] where +instance (DecodeTOML a) => DecodeTOML [a] where tomlDecoder = getArrayOf tomlDecoder instance (IsString k, Ord k, DecodeTOML v) => DecodeTOML (Map k v) where tomlDecoder = makeDecoder $ \case Table o -> Map.mapKeys (fromString . Text.unpack) <$> mapM (runDecoder tomlDecoder) o v -> typeMismatch v -instance DecodeTOML a => DecodeTOML (NonEmpty a) where +instance (DecodeTOML a) => DecodeTOML (NonEmpty a) where tomlDecoder = maybe raiseEmpty pure . NonEmpty.nonEmpty =<< tomlDecoder where raiseEmpty = makeDecoder $ invalidValue "Got empty list" @@ -615,9 +615,9 @@ instance DecodeTOML IntSet where tomlDecoder = IntSet.fromList <$> tomlDecoder instance (DecodeTOML a, Ord a) => DecodeTOML (Set a) where tomlDecoder = Set.fromList <$> tomlDecoder -instance DecodeTOML a => DecodeTOML (IntMap a) where +instance (DecodeTOML a) => DecodeTOML (IntMap a) where tomlDecoder = IntMap.fromList <$> tomlDecoder -instance DecodeTOML a => DecodeTOML (Seq a) where +instance (DecodeTOML a) => DecodeTOML (Seq a) where tomlDecoder = Seq.fromList <$> tomlDecoder tomlDecoderTuple :: ([Value] -> Maybe (DecodeM a)) -> Decoder a @@ -625,7 +625,7 @@ tomlDecoderTuple f = makeDecoder $ \case Array vs | Just decodeM <- f vs -> decodeM v -> typeMismatch v -decodeElem :: DecodeTOML a => Int -> Value -> DecodeM a +decodeElem :: (DecodeTOML a) => Int -> Value -> DecodeM a decodeElem i v = addContextItem (Index i) (runDecoder tomlDecoder v) instance DecodeTOML () where tomlDecoder = tomlDecoderTuple $ \case diff --git a/src/TOML/Parser.hs b/src/TOML/Parser.hs index d7fab0c..ceb8f67 100644 --- a/src/TOML/Parser.hs +++ b/src/TOML/Parser.hs @@ -752,7 +752,7 @@ isUnicodeScalar code = (0x0 <= code && code <= 0xD7FF) || (0xE000 <= code && cod parseSignRaw :: Parser Text parseSignRaw = optionalOr "" (string "-" <|> string "+") -parseSign :: Num a => Parser (a -> a) +parseSign :: (Num a) => Parser (a -> a) parseSign = do sign <- parseSignRaw pure $ if sign == "-" then negate else id @@ -853,7 +853,7 @@ readBin = foldl' go 0 . Text.unpack | otherwise = error $ "readBin got unexpected digit: " <> show x in 2 * acc + digit -runReader :: Show a => ReadS a -> Text -> a +runReader :: (Show a) => ReadS a -> Text -> a runReader rdr digits = case rdr $ Text.unpack digits of [(x, "")] -> x diff --git a/src/TOML/Value.hs b/src/TOML/Value.hs index 3e01d8e..5e32556 100644 --- a/src/TOML/Value.hs +++ b/src/TOML/Value.hs @@ -44,5 +44,5 @@ renderValue = \case where renderKeyValue (k, v) = showT k <> ": " <> renderValue v - showT :: Show a => a -> Text + showT :: (Show a) => a -> Text showT = Text.pack . show From 13fa9ee03ff803f3d1161fff342ac6473746bd47 Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Mon, 12 Jun 2023 18:00:45 -0700 Subject: [PATCH 05/13] Update fourmolu config --- fourmolu.yaml | 3 + src/TOML/Decode.hs | 310 +++++++++++++++---------------- src/TOML/Parser.hs | 41 ++-- src/TOML/Utils/Map.hs | 55 +++--- src/TOML/Utils/NonEmpty.hs | 11 +- test/tasty/TOML/Utils/MapTest.hs | 6 +- 6 files changed, 207 insertions(+), 219 deletions(-) diff --git a/fourmolu.yaml b/fourmolu.yaml index abd6f82..6164d29 100644 --- a/fourmolu.yaml +++ b/fourmolu.yaml @@ -1,2 +1,5 @@ indentation: 2 indent-wheres: true +function-arrows: leading-args +haddock-style: single-line +haddock-style-module: multi-line-compact diff --git a/src/TOML/Decode.hs b/src/TOML/Decode.hs index 5049772..b458c31 100644 --- a/src/TOML/Decode.hs +++ b/src/TOML/Decode.hs @@ -92,32 +92,31 @@ import TOML.Value (Value (..)) {--- Decoder ---} -{- | -A @Decoder a@ represents a function for decoding a TOML value to a value of type @a@. - -Generally, you'd only need to chain the @getField*@ functions together, like - -@ -decoder = - MyConfig - \<$> getField "a" - \<*> getField "b" - \<*> getField "c" -@ - -or use interfaces like 'Monad' and 'Alternative': - -@ -decoder = do - cfgType <- getField "type" - case cfgType of - "int" -> MyIntValue \<$> (getField "int" \<|> getField "integer") - "bool" -> MyBoolValue \<$> getField "bool" - _ -> fail $ "Invalid type: " <> cfgType -@ - -but you can also manually implement a 'Decoder' with 'makeDecoder'. --} +-- | +-- A @Decoder a@ represents a function for decoding a TOML value to a value of type @a@. +-- +-- Generally, you'd only need to chain the @getField*@ functions together, like +-- +-- @ +-- decoder = +-- MyConfig +-- \<$> getField "a" +-- \<*> getField "b" +-- \<*> getField "c" +-- @ +-- +-- or use interfaces like 'Monad' and 'Alternative': +-- +-- @ +-- decoder = do +-- cfgType <- getField "type" +-- case cfgType of +-- "int" -> MyIntValue \<$> (getField "int" \<|> getField "integer") +-- "bool" -> MyBoolValue \<$> getField "bool" +-- _ -> fail $ "Invalid type: " <> cfgType +-- @ +-- +-- but you can also manually implement a 'Decoder' with 'makeDecoder'. newtype Decoder a = Decoder {unDecoder :: Value -> DecodeM a} instance Functor Decoder where @@ -181,54 +180,51 @@ instance MonadFail.MonadFail DecodeM where fail = decodeFail . Text.pack #endif -{- | -Run a 'Decoder' with the given 'Value'. - -@ -makeDecoder $ \\v -> do - a <- runDecoder decoder1 v - b <- runDecoder decoder2 v - return (a, b) -@ - -Satisfies - -@ -makeDecoder . runDecoder === id -runDecoder . makeDecoder === id -@ --} +-- | +-- Run a 'Decoder' with the given 'Value'. +-- +-- @ +-- makeDecoder $ \\v -> do +-- a <- runDecoder decoder1 v +-- b <- runDecoder decoder2 v +-- return (a, b) +-- @ +-- +-- Satisfies +-- +-- @ +-- makeDecoder . runDecoder === id +-- runDecoder . makeDecoder === id +-- @ runDecoder :: Decoder a -> Value -> DecodeM a runDecoder decoder v = DecodeM (decoderToEither decoder v) -{- | -Throw an error indicating that the given 'Value' is invalid. - -@ -makeDecoder $ \\v -> - case v of - Integer 42 -> invalidValue "We don't like this number" v - _ -> runDecoder tomlDecoder v - --- or alternatively, -tomlDecoder >>= \case - 42 -> makeDecoder $ invalidValue "We don't like this number" - v -> pure v -@ --} +-- | +-- Throw an error indicating that the given 'Value' is invalid. +-- +-- @ +-- makeDecoder $ \\v -> +-- case v of +-- Integer 42 -> invalidValue "We don't like this number" v +-- _ -> runDecoder tomlDecoder v +-- +-- -- or alternatively, +-- tomlDecoder >>= \case +-- 42 -> makeDecoder $ invalidValue "We don't like this number" +-- v -> pure v +-- @ invalidValue :: Text -> Value -> DecodeM a invalidValue msg v = decodeError $ InvalidValue msg v -{- | -Throw an error indicating that the given 'Value' isn't the correct type of value. - -@ -makeDecoder $ \\v -> - case v of - String s -> ... - _ -> typeMismatch v -@ --} +-- | +-- Throw an error indicating that the given 'Value' isn't the correct type of value. +-- +-- @ +-- makeDecoder $ \\v -> +-- case v of +-- String s -> ... +-- _ -> typeMismatch v +-- @ typeMismatch :: Value -> DecodeM a typeMismatch v = decodeError $ TypeMismatch v @@ -264,36 +260,34 @@ decodeFile fp = decodeWithOpts tomlDecoder fp <$> Text.readFile fp {--- Decoder helpers ---} -{- | -Decode a field in a TOML Value. -Equivalent to 'getFields' with a single-element list. - -@ -a = 1 -b = 'asdf' -@ - -@ --- MyConfig 1 "asdf" -MyConfig \<$> getField "a" \<*> getField "b" -@ --} +-- | +-- Decode a field in a TOML Value. +-- Equivalent to 'getFields' with a single-element list. +-- +-- @ +-- a = 1 +-- b = 'asdf' +-- @ +-- +-- @ +-- -- MyConfig 1 "asdf" +-- MyConfig \<$> getField "a" \<*> getField "b" +-- @ getField :: (DecodeTOML a) => Text -> Decoder a getField = getFieldWith tomlDecoder -{- | -Decode a field in a TOML Value or succeed with a default value when the field is missing. - -@ -a = 1 -# b is missing -@ - -@ --- MyConfig 1 "asdf" -MyConfig \<$> getFieldOr 42 "a" \<*> getFieldOr "asdf" "b" -@ --} +-- | +-- Decode a field in a TOML Value or succeed with a default value when the field is missing. +-- +-- @ +-- a = 1 +-- # b is missing +-- @ +-- +-- @ +-- -- MyConfig 1 "asdf" +-- MyConfig \<$> getFieldOr 42 "a" \<*> getFieldOr "asdf" "b" +-- @ getFieldOr :: (DecodeTOML a) => a -> Text -> Decoder a getFieldOr def key = fromMaybe def <$> getFieldOpt key @@ -301,19 +295,18 @@ getFieldOr def key = fromMaybe def <$> getFieldOpt key getFieldWith :: Decoder a -> Text -> Decoder a getFieldWith decoder key = getFieldsWith decoder [key] -{- | -Decode a field in a TOML Value, or Nothing if the field doesn't exist. -Equivalent to 'getFieldsOpt' with a single-element list. - -@ -a = 1 -@ - -@ --- MyConfig (Just 1) Nothing -MyConfig \<$> getFieldOpt "a" \<*> getFieldOpt "b" -@ --} +-- | +-- Decode a field in a TOML Value, or Nothing if the field doesn't exist. +-- Equivalent to 'getFieldsOpt' with a single-element list. +-- +-- @ +-- a = 1 +-- @ +-- +-- @ +-- -- MyConfig (Just 1) Nothing +-- MyConfig \<$> getFieldOpt "a" \<*> getFieldOpt "b" +-- @ getFieldOpt :: (DecodeTOML a) => Text -> Decoder (Maybe a) getFieldOpt = getFieldOptWith tomlDecoder @@ -321,18 +314,17 @@ getFieldOpt = getFieldOptWith tomlDecoder getFieldOptWith :: Decoder a -> Text -> Decoder (Maybe a) getFieldOptWith decoder key = getFieldsOptWith decoder [key] -{- | -Decode a nested field in a TOML Value. - -@ -a.b = 1 -@ - -@ --- MyConfig 1 -MyConfig \<$> getFields ["a", "b"] -@ --} +-- | +-- Decode a nested field in a TOML Value. +-- +-- @ +-- a.b = 1 +-- @ +-- +-- @ +-- -- MyConfig 1 +-- MyConfig \<$> getFields ["a", "b"] +-- @ getFields :: (DecodeTOML a) => [Text] -> Decoder a getFields = getFieldsWith tomlDecoder @@ -350,21 +342,20 @@ getFieldsWith decoder = makeDecoder . go Nothing -> decodeError MissingField _ -> typeMismatch v -{- | -Decode a nested field in a TOML Value, or 'Nothing' if any of the fields don't exist. - -@ -a.b = 1 -@ - -@ --- MyConfig (Just 1) Nothing Nothing -MyConfig - \<$> getFieldsOpt ["a", "b"] - \<*> getFieldsOpt ["a", "c"] - \<*> getFieldsOpt ["b", "c"] -@ --} +-- | +-- Decode a nested field in a TOML Value, or 'Nothing' if any of the fields don't exist. +-- +-- @ +-- a.b = 1 +-- @ +-- +-- @ +-- -- MyConfig (Just 1) Nothing Nothing +-- MyConfig +-- \<$> getFieldsOpt ["a", "b"] +-- \<*> getFieldsOpt ["a", "c"] +-- \<*> getFieldsOpt ["b", "c"] +-- @ getFieldsOpt :: (DecodeTOML a) => [Text] -> Decoder (Maybe a) getFieldsOpt = getFieldsOptWith tomlDecoder @@ -378,23 +369,22 @@ getFieldsOptWith decoder keys = Left (ctx', e) -> Left (ctx', e) Right x -> Right $ Just x -{- | -Decode a list of values using the given 'Decoder'. - -@ -[[a]] -b = 1 - -[[a]] -b = 2 -@ - -@ --- MyConfig [1, 2] -MyConfig - \<$> getFieldWith (getArrayOf (getField "b")) "a" -@ --} +-- | +-- Decode a list of values using the given 'Decoder'. +-- +-- @ +-- [[a]] +-- b = 1 +-- +-- [[a]] +-- b = 2 +-- @ +-- +-- @ +-- -- MyConfig [1, 2] +-- MyConfig +-- \<$> getFieldWith (getArrayOf (getField "b")) "a" +-- @ getArrayOf :: Decoder a -> Decoder [a] getArrayOf decoder = makeDecoder $ \case @@ -403,11 +393,10 @@ getArrayOf decoder = {--- DecodeTOML ---} -{- | -A type class containing the default 'Decoder' for the given type. - -See the docs for 'Decoder' for examples. --} +-- | +-- A type class containing the default 'Decoder' for the given type. +-- +-- See the docs for 'Decoder' for examples. class DecodeTOML a where tomlDecoder :: Decoder a @@ -575,10 +564,9 @@ instance DecodeTOML (Proxy a) where instance (DecodeTOML a) => DecodeTOML (Const a b) where tomlDecoder = Const <$> tomlDecoder -{- | -Since TOML doesn't support literal NULLs, this will only ever return 'Just'. -To get the absence of a field, use 'getFieldOpt' or one of its variants. --} +-- | +-- Since TOML doesn't support literal NULLs, this will only ever return 'Just'. +-- To get the absence of a field, use 'getFieldOpt' or one of its variants. instance (DecodeTOML a) => DecodeTOML (Maybe a) where tomlDecoder = Just <$> tomlDecoder diff --git a/src/TOML/Parser.hs b/src/TOML/Parser.hs index ceb8f67..98f4d2f 100644 --- a/src/TOML/Parser.hs +++ b/src/TOML/Parser.hs @@ -5,7 +5,7 @@ {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TypeFamilies #-} -{- | +{-| Parse a TOML document. References: @@ -44,11 +44,11 @@ import TOML.Utils.Map (getPathLens) import TOML.Value (Table, Value (..)) parseTOML :: - -- | Name of file (for error messages) - String -> - -- | Input - Text -> - Either TOMLError Value + String + -- ^ Name of file (for error messages) + -> Text + -- ^ Input + -> Either TOMLError Value parseTOML filename input = case runParser parseTOMLDocument filename input of Left e -> Left $ ParseError $ Text.pack $ errorBundlePretty e @@ -68,9 +68,9 @@ data GenericValue map key tableMeta arrayMeta | GenericLocalTime TimeOfDay fromGenericValue :: - (map key (GenericValue map key tableMeta arrayMeta) -> Table) -> - GenericValue map key tableMeta arrayMeta -> - Value + (map key (GenericValue map key tableMeta arrayMeta) -> Table) + -> GenericValue map key tableMeta arrayMeta + -> Value fromGenericValue fromGenericTable = \case GenericTable _ t -> Table $ fromGenericTable t GenericArray _ vs -> Array $ map (fromGenericValue fromGenericTable) vs @@ -261,13 +261,12 @@ parseEscaped = char '\\' *> parseEscapedChar guard $ isUnicodeScalar code pure $ chr code -{- | -Parse the multiline delimiter (" in """ quotes, or ' in ''' quotes), unless -the delimiter indicates the end of the multiline string. - -i.e. parse 1 or 2 delimiters, or 4 or 5, which is 1 or 2 delimiters at the -end of a multiline string (then backtrack 3 to mark the end). --} +-- | +-- Parse the multiline delimiter (" in """ quotes, or ' in ''' quotes), unless +-- the delimiter indicates the end of the multiline string. +-- +-- i.e. parse 1 or 2 delimiters, or 4 or 5, which is 1 or 2 delimiters at the +-- end of a multiline string (then backtrack 3 to mark the end). parseMultilineDelimiter :: Char -> Parser Text parseMultilineDelimiter delim = choice @@ -687,11 +686,11 @@ nonTableInNestedKeyError key table = \history existingValue -> } setValueAtPath :: - ValueAtPathOptions -> - Key -> - AnnTable -> - (Maybe AnnValue -> NormalizeM AnnValue) -> - NormalizeM AnnTable + ValueAtPathOptions + -> Key + -> AnnTable + -> (Maybe AnnValue -> NormalizeM AnnValue) + -> NormalizeM AnnTable setValueAtPath ValueAtPathOptions{..} fullKey initialTable f = do (mValue, setValue) <- getPathLens doRecurse fullKey initialTable setValue <$> f mValue diff --git a/src/TOML/Utils/Map.hs b/src/TOML/Utils/Map.hs index 32db364..09fe50c 100644 --- a/src/TOML/Utils/Map.hs +++ b/src/TOML/Utils/Map.hs @@ -12,27 +12,26 @@ import qualified Data.Map.Strict as Map import TOML.Utils.NonEmpty (zipHistory) -{- | -For a non-empty list of keys, iterate through the given 'Map' and return -the possibly missing value at the path and a function to set the value at -the given path and return the modified input 'Map'. - -@ -let obj = undefined -- { "a": { "b": { "c": 1 } } } -(mValue, setValue) <- getPathLens doRecurse ["a", "b", "c"] obj - -print mValue -- Just 1 -print (setValue 2) -- { "a": { "b": { "c": 2 } } } -@ --} +-- | +-- For a non-empty list of keys, iterate through the given 'Map' and return +-- the possibly missing value at the path and a function to set the value at +-- the given path and return the modified input 'Map'. +-- +-- @ +-- let obj = undefined -- { "a": { "b": { "c": 1 } } } +-- (mValue, setValue) <- getPathLens doRecurse ["a", "b", "c"] obj +-- +-- print mValue -- Just 1 +-- print (setValue 2) -- { "a": { "b": { "c": 2 } } } +-- @ getPathLens :: (Monad m, Ord k) => - -- | How to get and set the next Map from the possibly missing value. + (NonEmpty k -> Maybe v -> m (Map k v, Map k v -> v)) + -- ^ How to get and set the next Map from the possibly missing value. -- Passes in the path taken so far. - (NonEmpty k -> Maybe v -> m (Map k v, Map k v -> v)) -> - NonEmpty k -> - Map k v -> - m (Maybe v, v -> Map k v) + -> NonEmpty k + -> Map k v + -> m (Maybe v, v -> Map k v) getPathLens = getPathLensWith (\setVal fromMap -> mkSetter (setVal . fromMap)) (mkSetter id) where @@ -41,10 +40,10 @@ getPathLens = -- | Same as 'getPathLens', except without the setter. getPath :: (Monad m, Ord k) => - (NonEmpty k -> Maybe v -> m (Map k v)) -> - NonEmpty k -> - Map k v -> - m (Maybe v) + (NonEmpty k -> Maybe v -> m (Map k v)) + -> NonEmpty k + -> Map k v + -> m (Maybe v) getPath doRecurse path originalMap = fst <$> getPathLensWith (\_ _ _ _ -> ()) (\_ _ -> ()) doRecurse' path originalMap where @@ -54,12 +53,12 @@ getPath doRecurse path originalMap = getPathLensWith :: (Monad m, Ord k) => - (b -> a -> (k -> Map k v -> b)) -> - (k -> Map k v -> b) -> - (NonEmpty k -> Maybe v -> m (Map k v, a)) -> - NonEmpty k -> - Map k v -> - m (Maybe v, b) + (b -> a -> (k -> Map k v -> b)) + -> (k -> Map k v -> b) + -> (NonEmpty k -> Maybe v -> m (Map k v, a)) + -> NonEmpty k + -> Map k v + -> m (Maybe v, b) getPathLensWith mkAnn mkFirstAnn doRecurse path originalMap = let (_, k) :| ks = zipHistory path in foldlM go (buildLens k mkFirstAnn originalMap) ks diff --git a/src/TOML/Utils/NonEmpty.hs b/src/TOML/Utils/NonEmpty.hs index ed083b3..27142c8 100644 --- a/src/TOML/Utils/NonEmpty.hs +++ b/src/TOML/Utils/NonEmpty.hs @@ -8,12 +8,11 @@ import Data.List (scanl') import Data.List.NonEmpty (NonEmpty ((:|))) import qualified Data.List.NonEmpty as NonEmpty -{- | -Annotates each element with the history of all past elements. - ->>> zipHistory ["a", "b", "c"] -[(["a"], "a"), (["a", "b"], "b"), (["a", "b", "c"], "c")] --} +-- | +-- Annotates each element with the history of all past elements. +-- +-- >>> zipHistory ["a", "b", "c"] +-- [(["a"], "a"), (["a", "b"], "b"), (["a", "b", "c"], "c")] zipHistory :: NonEmpty a -> NonEmpty (NonEmpty a, a) zipHistory (a :| as) = NonEmpty.fromList $ diff --git a/test/tasty/TOML/Utils/MapTest.hs b/test/tasty/TOML/Utils/MapTest.hs index c205862..cb040cf 100644 --- a/test/tasty/TOML/Utils/MapTest.hs +++ b/test/tasty/TOML/Utils/MapTest.hs @@ -23,9 +23,9 @@ data MapOrInt = Map [(String, MapOrInt)] | Int Int deriving (Show, Eq) recurseMapOrInt :: - NonEmpty String -> - Maybe MapOrInt -> - Either String (Map String MapOrInt, Map String MapOrInt -> MapOrInt) + NonEmpty String + -> Maybe MapOrInt + -> Either String (Map String MapOrInt, Map String MapOrInt -> MapOrInt) recurseMapOrInt _ = \case Nothing -> Right (Map.empty, fromMap) Just (Map kvs) -> Right (Map.fromList kvs, fromMap) From db7254c0e024cf0c3761d4fa675448cb75ae9d59 Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Mon, 12 Jun 2023 18:01:24 -0700 Subject: [PATCH 06/13] Install hpc-lcov from releases --- .github/workflows/ci.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1a3b15b..8804840 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,13 +53,20 @@ jobs: run: git diff --exit-code '*.cabal' # upload coverage data - + if: ${{ matrix.latest }} name: Generate coverage data - run: stack install hpc-lcov && hpc-lcov + run: | + HPC_LCOV_VERSION=1.1.1 + curl -fsSL \ + "https://github.com/brandonchinn178/hpc-lcov/releases/download/v${HPC_LCOV_VERSION}/hpc-lcov-${HPC_LCOV_VERSION}-linux-x86_64" \ + -o /usr/local/bin/hpc-lcov + chmod +x /usr/local/bin/hpc-lcov + hpc-lcov - + if: ${{ matrix.latest }} uses: codecov/codecov-action@v2 with: files: lcov.info - if: ${{ matrix.latest }} lint: runs-on: ubuntu-latest From bfa368a3708216ce7a973cbfed5a7258521d2a00 Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Mon, 12 Jun 2023 18:04:53 -0700 Subject: [PATCH 07/13] Use Cabal to test GHC compatibility --- .github/workflows/ci.yml | 92 +++++++++++++++++++++++++++------------- .gitignore | 4 +- cabal.project | 4 ++ stack-ghc-8.10.yaml | 4 -- stack-ghc-8.6.yaml | 4 -- stack-ghc-8.8.yaml | 4 -- stack-ghc-9.0.yaml | 4 -- stack-ghc-9.2.yaml | 4 -- stack-ghc-9.4.yaml | 4 -- stack.yaml | 5 ++- stack.yaml.lock | 8 ++-- 11 files changed, 78 insertions(+), 59 deletions(-) create mode 100644 cabal.project delete mode 100644 stack-ghc-8.10.yaml delete mode 100644 stack-ghc-8.6.yaml delete mode 100644 stack-ghc-8.8.yaml delete mode 100644 stack-ghc-9.0.yaml delete mode 100644 stack-ghc-9.2.yaml delete mode 100644 stack-ghc-9.4.yaml mode change 120000 => 100644 stack.yaml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8804840..a767806 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,54 +6,36 @@ on: - main workflow_call: +env: + TOML_TEST_VERSION: '1.2.0' + jobs: build_and_test: - strategy: - matrix: - stack_yaml: - - stack-ghc-8.6.yaml - - stack-ghc-8.8.yaml - - stack-ghc-8.10.yaml - - stack-ghc-9.0.yaml - - stack-ghc-9.2.yaml - - stack-ghc-9.4.yaml - include: - - stack_yaml: stack.yaml - latest: true - - name: build_and_test (${{ matrix.stack_yaml }}) - runs-on: ubuntu-22.04 - env: - STACK_YAML: ${{ matrix.stack_yaml }} + name: build_and_test + runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Install toml-test - env: - TOML_TEST_VERSION: '1.2.0' run: | - curl -sSL \ - "https://github.com/BurntSushi/toml-test/releases/download/v${TOML_TEST_VERSION}/toml-test-v${TOML_TEST_VERSION}-linux-amd64.gz" \ - -o toml-test.gz - gunzip toml-test.gz - chmod +x toml-test - mv toml-test /usr/local/bin/ + curl -fsSL "https://github.com/BurntSushi/toml-test/releases/download/v${TOML_TEST_VERSION}/toml-test-v${TOML_TEST_VERSION}-linux-amd64.gz" \ + | gunzip \ + > /usr/local/bin/toml-test + chmod +x /usr/local/bin/toml-test - uses: actions/cache@v3 with: path: ~/.stack - key: ${{ runner.os }}-stack-cache-${{ hashFiles(matrix.stack_yaml, 'package.yaml') }} + key: ${{ runner.os }}-stack-cache-${{ hashFiles('stack.yaml', 'package.yaml') }} - name: Build + test run: stack test --coverage - name: Check that Cabal file was generated run: git diff --exit-code '*.cabal' - # upload coverage data - - if: ${{ matrix.latest }} name: Generate coverage data run: | HPC_LCOV_VERSION=1.1.1 @@ -63,11 +45,63 @@ jobs: chmod +x /usr/local/bin/hpc-lcov hpc-lcov - - if: ${{ matrix.latest }} uses: codecov/codecov-action@v2 with: files: lcov.info + ghc_compat_test: + strategy: + matrix: + ghc_version: + - '8.6' + - '8.8' + - '8.10' + - '9.0' + - '9.2' + - '9.4' + + name: ghc_compat_test (${{ matrix.ghc_version }}) + runs-on: ubuntu-latest + + steps: + - + uses: actions/checkout@v3 + - + name: Install toml-test + run: | + curl -fsSL "https://github.com/BurntSushi/toml-test/releases/download/v${TOML_TEST_VERSION}/toml-test-v${TOML_TEST_VERSION}-linux-amd64.gz" \ + | gunzip \ + > /usr/local/bin/toml-test + chmod +x /usr/local/bin/toml-test + - + id: setup + name: Set up GHC ${{ matrix.ghc_version }} + uses: haskell-actions/setup@v2 + with: + ghc-version: ${{ matrix.ghc_version }} + - + name: Configure the build + run: + cabal configure + --enable-test + --test-show-details=streaming + - + name: Get build plan + run: cabal build --dry-run + - + name: Get current month to clear cache + run: echo "CURR_MONTH=$(date +%B)" | tee -a "$GITHUB_ENV" + - + uses: actions/cache@v3 + with: + path: ${{ steps.setup.outputs.cabal-store }} + key: ${{ runner.os }}-cabal-cache-${{ env.CURR_MONTH }}-${{ matrix.ghc_version }}-${{ hashFiles('**/plan.json') }} + restore-keys: | + ${{ runner.os }}-cabal-cache-${{ env.CURR_MONTH }}-${{ matrix.ghc_version }}- + - + name: Build + Test + run: cabal test + lint: runs-on: ubuntu-latest env: diff --git a/.gitignore b/.gitignore index 5c14966..7d2ae0b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ .stack-work/ -stack-ghc-*.yaml.lock + +cabal.project.local* +dist-newstyle/ .DS_Store diff --git a/cabal.project b/cabal.project new file mode 100644 index 0000000..0e58f6d --- /dev/null +++ b/cabal.project @@ -0,0 +1,4 @@ +packages: . + +program-options + ghc-options: -Werror diff --git a/stack-ghc-8.10.yaml b/stack-ghc-8.10.yaml deleted file mode 100644 index 89140d5..0000000 --- a/stack-ghc-8.10.yaml +++ /dev/null @@ -1,4 +0,0 @@ -resolver: lts-18.28 - -ghc-options: - '$locals': -Werror diff --git a/stack-ghc-8.6.yaml b/stack-ghc-8.6.yaml deleted file mode 100644 index 39beb50..0000000 --- a/stack-ghc-8.6.yaml +++ /dev/null @@ -1,4 +0,0 @@ -resolver: lts-14.27 - -ghc-options: - '$locals': -Werror diff --git a/stack-ghc-8.8.yaml b/stack-ghc-8.8.yaml deleted file mode 100644 index 0fedfcd..0000000 --- a/stack-ghc-8.8.yaml +++ /dev/null @@ -1,4 +0,0 @@ -resolver: lts-16.31 - -ghc-options: - '$locals': -Werror diff --git a/stack-ghc-9.0.yaml b/stack-ghc-9.0.yaml deleted file mode 100644 index d573b23..0000000 --- a/stack-ghc-9.0.yaml +++ /dev/null @@ -1,4 +0,0 @@ -resolver: lts-19.33 - -ghc-options: - '$locals': -Werror diff --git a/stack-ghc-9.2.yaml b/stack-ghc-9.2.yaml deleted file mode 100644 index 29511a2..0000000 --- a/stack-ghc-9.2.yaml +++ /dev/null @@ -1,4 +0,0 @@ -resolver: lts-20.0 - -ghc-options: - '$locals': -Werror diff --git a/stack-ghc-9.4.yaml b/stack-ghc-9.4.yaml deleted file mode 100644 index 20e7c6d..0000000 --- a/stack-ghc-9.4.yaml +++ /dev/null @@ -1,4 +0,0 @@ -resolver: nightly-2022-11-19 - -ghc-options: - '$locals': -Werror diff --git a/stack.yaml b/stack.yaml deleted file mode 120000 index fb6ed20..0000000 --- a/stack.yaml +++ /dev/null @@ -1 +0,0 @@ -stack-ghc-9.0.yaml \ No newline at end of file diff --git a/stack.yaml b/stack.yaml new file mode 100644 index 0000000..b58a87c --- /dev/null +++ b/stack.yaml @@ -0,0 +1,4 @@ +resolver: lts-20.24 + +ghc-options: + '$locals': -Werror diff --git a/stack.yaml.lock b/stack.yaml.lock index d79c369..84da166 100644 --- a/stack.yaml.lock +++ b/stack.yaml.lock @@ -6,7 +6,7 @@ packages: [] snapshots: - completed: - sha256: 6d1532d40621957a25bad5195bfca7938e8a06d923c91bc52aa0f3c41181f2d4 - size: 619204 - url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/19/33.yaml - original: lts-19.33 + sha256: e019cd29e3f7f9dbad500225829a3f7a50f73c674614f2f452e21bb8bf5d99ea + size: 650253 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/20/24.yaml + original: lts-20.24 From 79aefdf6accdd7188a5ea9f74bc986e78474e952 Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Mon, 12 Jun 2023 18:07:38 -0700 Subject: [PATCH 08/13] Add GHC 9.6 support --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a767806..af31eba 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,6 +59,7 @@ jobs: - '9.0' - '9.2' - '9.4' + - '9.6' name: ghc_compat_test (${{ matrix.ghc_version }}) runs-on: ubuntu-latest From 6cc74c1cef5bdd538a36035418d1320973bc9f8b Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Mon, 12 Jun 2023 18:10:11 -0700 Subject: [PATCH 09/13] Drop support for GHC < 9.0 --- .github/workflows/ci.yml | 3 --- CHANGELOG.md | 2 ++ package.yaml | 14 ++++++-------- toml-reader.cabal | 12 +++--------- 4 files changed, 11 insertions(+), 20 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index af31eba..4e8f3ab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,9 +53,6 @@ jobs: strategy: matrix: ghc_version: - - '8.6' - - '8.8' - - '8.10' - '9.0' - '9.2' - '9.4' diff --git a/CHANGELOG.md b/CHANGELOG.md index 138dc33..3d54382 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## Unreleased +* Drop support for GHC < 9.0 + ## v0.2.0.0 * Add getFieldOr [#10](https://github.com/brandonchinn178/toml-reader/issues/10) diff --git a/package.yaml b/package.yaml index 5234922..a686131 100644 --- a/package.yaml +++ b/package.yaml @@ -15,14 +15,12 @@ extra-source-files: github: brandonchinn178/toml-reader -ghc-options: -Wall -when: - - condition: impl(ghc >= 8.0) - ghc-options: - - -Wcompat - - -Wincomplete-record-updates - - -Wincomplete-uni-patterns - - -Wnoncanonical-monad-instances +ghc-options: + - -Wall + - -Wcompat + - -Wincomplete-record-updates + - -Wincomplete-uni-patterns + - -Wnoncanonical-monad-instances library: source-dirs: src diff --git a/toml-reader.cabal b/toml-reader.cabal index a5c3668..54bb21f 100644 --- a/toml-reader.cabal +++ b/toml-reader.cabal @@ -49,7 +49,7 @@ library Paths_toml_reader hs-source-dirs: src - ghc-options: -Wall + ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wnoncanonical-monad-instances build-depends: base >=4.9 && <5 , containers >=0.6.0.1 && <0.7 @@ -58,8 +58,6 @@ library , text >=1.2.3.1 && <2.1 , time >=1.8.0.2 && <1.13 default-language: Haskell2010 - if impl(ghc >= 8.0) - ghc-options: -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wnoncanonical-monad-instances test-suite parser-validator type: exitcode-stdio-1.0 @@ -68,7 +66,7 @@ test-suite parser-validator Paths_toml_reader hs-source-dirs: test/toml-test - ghc-options: -Wall + ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wnoncanonical-monad-instances build-depends: aeson , base @@ -82,8 +80,6 @@ test-suite parser-validator , unordered-containers , vector default-language: Haskell2010 - if impl(ghc >= 8.0) - ghc-options: -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wnoncanonical-monad-instances test-suite toml-reader-tests type: exitcode-stdio-1.0 @@ -97,7 +93,7 @@ test-suite toml-reader-tests Paths_toml_reader hs-source-dirs: test/tasty - ghc-options: -Wall + ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wnoncanonical-monad-instances build-depends: base , containers @@ -108,5 +104,3 @@ test-suite toml-reader-tests , time , toml-reader default-language: Haskell2010 - if impl(ghc >= 8.0) - ghc-options: -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wnoncanonical-monad-instances From 93fa95c55da13ed81598bc94816a7f9cebaf3470 Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Mon, 12 Jun 2023 18:40:03 -0700 Subject: [PATCH 10/13] Enable -Wunused-packages --- package.yaml | 1 + test/toml-test/ValidateParser.hs | 1 + toml-reader.cabal | 6 +++--- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/package.yaml b/package.yaml index a686131..a89a255 100644 --- a/package.yaml +++ b/package.yaml @@ -21,6 +21,7 @@ ghc-options: - -Wincomplete-record-updates - -Wincomplete-uni-patterns - -Wnoncanonical-monad-instances + - -Wunused-packages library: source-dirs: src diff --git a/test/toml-test/ValidateParser.hs b/test/toml-test/ValidateParser.hs index 1d20935..6952bfb 100644 --- a/test/toml-test/ValidateParser.hs +++ b/test/toml-test/ValidateParser.hs @@ -25,6 +25,7 @@ import TOML.Parser (parseTOML) import qualified Data.Aeson.Key as Key import Data.Aeson.KeyMap (KeyMap) import qualified Data.Aeson.KeyMap as KeyMap +import Data.HashMap.Lazy () #else import qualified Data.HashMap.Lazy as HashMap #endif diff --git a/toml-reader.cabal b/toml-reader.cabal index 54bb21f..909447d 100644 --- a/toml-reader.cabal +++ b/toml-reader.cabal @@ -49,7 +49,7 @@ library Paths_toml_reader hs-source-dirs: src - ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wnoncanonical-monad-instances + ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wnoncanonical-monad-instances -Wunused-packages build-depends: base >=4.9 && <5 , containers >=0.6.0.1 && <0.7 @@ -66,7 +66,7 @@ test-suite parser-validator Paths_toml_reader hs-source-dirs: test/toml-test - ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wnoncanonical-monad-instances + ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wnoncanonical-monad-instances -Wunused-packages build-depends: aeson , base @@ -93,7 +93,7 @@ test-suite toml-reader-tests Paths_toml_reader hs-source-dirs: test/tasty - ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wnoncanonical-monad-instances + ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wnoncanonical-monad-instances -Wunused-packages build-depends: base , containers From 7c35d1252ddc07e5b5f8da00a11d2c2776b40c25 Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Mon, 12 Jun 2023 18:08:48 -0700 Subject: [PATCH 11/13] Remove lower bounds, test with --prefer-oldest --- .github/workflows/ci.yml | 7 +++++++ package.yaml | 12 ++++++------ toml-reader.cabal | 12 ++++++------ 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4e8f3ab..d2d518a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,6 +57,9 @@ jobs: - '9.2' - '9.4' - '9.6' + include: + - ghc_version: '9.0' + oldest: true name: ghc_compat_test (${{ matrix.ghc_version }}) runs-on: ubuntu-latest @@ -83,6 +86,10 @@ jobs: cabal configure --enable-test --test-show-details=streaming + - + if: ${{ matrix.oldest }} + name: Use oldest dependencies + run: cabal configure --enable-append --prefer-oldest - name: Get build plan run: cabal build --dry-run diff --git a/package.yaml b/package.yaml index a89a255..b6f0484 100644 --- a/package.yaml +++ b/package.yaml @@ -26,12 +26,12 @@ ghc-options: library: source-dirs: src dependencies: - - base >= 4.9 && < 5 - - containers >= 0.6.0.1 && < 0.7 - - megaparsec >= 7.0.5 && < 9.5 - - parser-combinators >= 1.1.0 && < 1.4 - - text >= 1.2.3.1 && < 2.1 - - time >= 1.8.0.2 && < 1.13 + - base >= 4.15 && < 5 + - containers < 0.7 + - megaparsec < 9.5 + - parser-combinators < 1.4 + - text < 2.1 + - time < 1.13 tests: toml-reader-tests: diff --git a/toml-reader.cabal b/toml-reader.cabal index 909447d..3df3d3f 100644 --- a/toml-reader.cabal +++ b/toml-reader.cabal @@ -51,12 +51,12 @@ library src ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wnoncanonical-monad-instances -Wunused-packages build-depends: - base >=4.9 && <5 - , containers >=0.6.0.1 && <0.7 - , megaparsec >=7.0.5 && <9.5 - , parser-combinators >=1.1.0 && <1.4 - , text >=1.2.3.1 && <2.1 - , time >=1.8.0.2 && <1.13 + base >=4.15 && <5 + , containers <0.7 + , megaparsec <9.5 + , parser-combinators <1.4 + , text <2.1 + , time <1.13 default-language: Haskell2010 test-suite parser-validator From 6f5f2bca7443951b169d872b62e739c1aa1da018 Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Mon, 12 Jun 2023 18:30:07 -0700 Subject: [PATCH 12/13] Update release process --- .github/workflows/release.yml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index addf24d..4ddc3ae 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,24 +13,22 @@ jobs: steps: - uses: actions/checkout@v3 - with: - ref: main - uses: actions/download-artifact@v3 with: name: toml-reader-sdist path: ./sdist/ - - uses: brandonchinn178/haskell-actions/parse-cabal-file@parse-cabal-file id: cabal_file + uses: haskell-actions/parse-cabal-file@v1 with: cabal_file: toml-reader.cabal - name: Set version label run: echo 'VERSION=v${{ steps.cabal_file.outputs.version }}' >> "${GITHUB_ENV}" - - name: Load Hackage token secret name id: hackage_token_secret + name: Load Hackage token secret name run: | USERNAME="$(echo "${GITHUB_ACTOR}" | tr '[:lower:]' '[:upper:]' | tr '-' '_')" echo "name=HACKAGE_TOKEN_${USERNAME}" >> "${GITHUB_OUTPUT}" @@ -44,10 +42,10 @@ jobs: fi sed '1 d; /^## v/,$ d' /tmp/changelog-without-unreleased > /tmp/changelog-body - - uses: brandonchinn178/haskell-actions/hackage-upload@hackage-upload + uses: haskell-actions/hackage-publish@v1 with: - archive: sdist/toml-reader-*.tar.gz - token: ${{ secrets[steps.hackage_token_secret.outputs.name] }} + hackageToken: ${{ secrets[steps.hackage_token_secret.outputs.name] }} + packagesPath: ./sdist/ - uses: softprops/action-gh-release@v1 with: From 8b88158d7181a9cab45e15ee7e4d88aa21e0a48e Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Mon, 12 Jun 2023 18:31:40 -0700 Subject: [PATCH 13/13] Release 0.2.1.0 --- CHANGELOG.md | 2 ++ package.yaml | 2 +- toml-reader.cabal | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d54382..cef1cd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## Unreleased +## v0.2.1.0 + * Drop support for GHC < 9.0 ## v0.2.0.0 diff --git a/package.yaml b/package.yaml index b6f0484..94d063e 100644 --- a/package.yaml +++ b/package.yaml @@ -1,5 +1,5 @@ name: toml-reader -version: 0.2.0.0 +version: 0.2.1.0 category: TOML, Text, Configuration synopsis: TOML format parser compliant with v1.0.0. description: TOML format parser compliant with v1.0.0. See README.md for more details. diff --git a/toml-reader.cabal b/toml-reader.cabal index 3df3d3f..30aa64b 100644 --- a/toml-reader.cabal +++ b/toml-reader.cabal @@ -5,7 +5,7 @@ cabal-version: 1.12 -- see: https://github.com/sol/hpack name: toml-reader -version: 0.2.0.0 +version: 0.2.1.0 synopsis: TOML format parser compliant with v1.0.0. description: TOML format parser compliant with v1.0.0. See README.md for more details. category: TOML, Text, Configuration