From ccd17ca9e2bcec3899da221dc6596b808216aaa1 Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Tue, 1 Nov 2022 18:13:19 +0100 Subject: [PATCH 01/35] Use GHC 9.2.4 in nix and cabal --- cabal.project | 2 +- nix/wire-server.nix | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cabal.project b/cabal.project index b1c4c70161..ddfd0b8efc 100644 --- a/cabal.project +++ b/cabal.project @@ -1,4 +1,4 @@ -with-compiler: ghc-8.10.7 +with-compiler: ghc-9.2.4 packages: libs/api-bot/ diff --git a/nix/wire-server.nix b/nix/wire-server.nix index 586338588f..99dc0caaaf 100644 --- a/nix/wire-server.nix +++ b/nix/wire-server.nix @@ -145,7 +145,7 @@ let ) executablesMap; - hPkgs = localMods@{ enableOptimization, enableDocs, enableTests }: pkgs.haskell.packages.ghc8107.override { + hPkgs = localMods@{ enableOptimization, enableDocs, enableTests }: pkgs.haskell.packages.ghc92.override { overrides = lib.composeManyExtensions [ pinnedPackages (localPackages localMods) @@ -363,7 +363,7 @@ in devEnv = pkgs.buildEnv { name = "wire-server-dev-env"; paths = commonTools ++ [ - (pkgs.haskell-language-server.override { supportedGhcVersions = [ "8107" ]; }) + (pkgs.haskell-language-server.override { supportedGhcVersions = [ "92" ]; }) pkgs.ghcid pkgs.cfssl pkgs.kind From b347f058acf6b0e97d48d6b2fa863254e138bfcd Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Tue, 17 Jan 2023 18:11:52 +0100 Subject: [PATCH 02/35] Fix bug in generate-local-nix-packages.sh --- hack/bin/generate-local-nix-packages.sh | 4 ++-- libs/hscim/default.nix | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hack/bin/generate-local-nix-packages.sh b/hack/bin/generate-local-nix-packages.sh index abfdfeb925..c993e71188 100755 --- a/hack/bin/generate-local-nix-packages.sh +++ b/hack/bin/generate-local-nix-packages.sh @@ -4,7 +4,7 @@ set -euo pipefail SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) ROOT_DIR=$(cd -- "$SCRIPT_DIR/../../" &> /dev/null && pwd) -cabalFiles=$(find "$ROOT_DIR" -name '*.cabal' \ +cabalFiles=$(find -L "$ROOT_DIR" -name '*.cabal' \ | grep -v dist-newstyle | sort) warningFile=$(mktemp) @@ -21,7 +21,7 @@ echo "$cabalFiles" \ # shellcheck disable=SC2016 echo "$cabalFiles" \ - | xargs -I {} bash -c 'cd $(dirname {}); cabal2nix . --no-hpack --extra-arguments gitignoreSource | sed "s/.\/./gitignoreSource .\/./g" >> default.nix; nixpkgs-fmt default.nix &> /dev/null' + | xargs -I {} bash -c 'cd $(dirname {}); cabal2nix . --no-hpack --extra-arguments gitignoreSource | sed "s/src = \.\/\./src = gitignoreSource .\/./g" >> default.nix; nixpkgs-fmt default.nix &> /dev/null' overridesFile="$ROOT_DIR/nix/local-haskell-packages.nix" diff --git a/libs/hscim/default.nix b/libs/hscim/default.nix index ff9dda2955..7bd207e273 100644 --- a/libs/hscim/default.nix +++ b/libs/hscim/default.nix @@ -174,7 +174,7 @@ mkDerivation { warp ]; testToolDepends = [ hspec-discover ]; - homepage = "httpsgitignoreSource ./.github.cogitignoreSource ./.ireapgitignoreSource ./.ire-servegitignoreSource ./.ibgitignoreSource ./.scigitignoreSource ./.EADME.md"; + homepage = "https://github.com/wireapp/wire-server/libs/hscim/README.md"; description = "hscim json schema and server implementation"; license = lib.licenses.agpl3Only; mainProgram = "hscim-server"; From 8c2a26dfa623fd4dcd8208a9ddc96c988a66f5ad Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Wed, 2 Nov 2022 13:53:11 +0100 Subject: [PATCH 03/35] partial-isomorphisms: remove pin --- nix/haskell-pins.nix | 4 ---- 1 file changed, 4 deletions(-) diff --git a/nix/haskell-pins.nix b/nix/haskell-pins.nix index 900d716ce9..b27e3731cb 100644 --- a/nix/haskell-pins.nix +++ b/nix/haskell-pins.nix @@ -224,10 +224,6 @@ let version = "0.4.0"; sha256 = "sha256-DSMckKIeVE/buSMg8Mq+mUm1bYPYB7veA11Ns7vTBbc="; }; - partial-isomorphisms = { - version = "0.2.2.1"; - sha256 = "sha256-TdsLB0ueaUUllLdvcGu3YNQXCfGRRk5WxP3deHEbHGI="; - }; kind-generics = { version = "0.4.1.2"; sha256 = "sha256-orDfC5+QXRlAMVaqAhT1Fo7Eh/AnobROWeliZqEAXZU="; From 6f88d55c65591bd7682faa039fc906c61d6397cf Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Wed, 2 Nov 2022 16:00:22 +0100 Subject: [PATCH 04/35] type-errors: skip tests --- nix/manual-overrides.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/nix/manual-overrides.nix b/nix/manual-overrides.nix index 1d5e8c8a44..dffe4e60d0 100644 --- a/nix/manual-overrides.nix +++ b/nix/manual-overrides.nix @@ -27,6 +27,7 @@ hself: hsuper: { quickcheck-arbitrary-template = hlib.markUnbroken (hsuper.quickcheck-arbitrary-template); wai-middleware-prometheus = hlib.doJailbreak hsuper.wai-middleware-prometheus; one-liner = hlib.doJailbreak hsuper.one-liner; + type-errors = hlib.dontCheck hsuper.type-errors; # Some test seems to be broken hsaml2 = hlib.dontCheck hsuper.hsaml2; From 1c6d298e3f6820c09694770cda6e2ac67a40b716 Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Wed, 2 Nov 2022 16:46:30 +0100 Subject: [PATCH 05/35] binary-parsers: jailbreak --- nix/manual-overrides.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/nix/manual-overrides.nix b/nix/manual-overrides.nix index dffe4e60d0..0e31c905c8 100644 --- a/nix/manual-overrides.nix +++ b/nix/manual-overrides.nix @@ -28,6 +28,7 @@ hself: hsuper: { wai-middleware-prometheus = hlib.doJailbreak hsuper.wai-middleware-prometheus; one-liner = hlib.doJailbreak hsuper.one-liner; type-errors = hlib.dontCheck hsuper.type-errors; + binary-parsers = hlib.doJailbreak hsuper.binary-parsers; # Some test seems to be broken hsaml2 = hlib.dontCheck hsuper.hsaml2; From 7650bc50ae849f3e566443e614c6685451816f2f Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Wed, 2 Nov 2022 16:50:43 +0100 Subject: [PATCH 06/35] th-desugar: unpin --- nix/haskell-pins.nix | 4 ---- 1 file changed, 4 deletions(-) diff --git a/nix/haskell-pins.nix b/nix/haskell-pins.nix index b27e3731cb..382d4110bd 100644 --- a/nix/haskell-pins.nix +++ b/nix/haskell-pins.nix @@ -248,10 +248,6 @@ let version = "2.7"; sha256 = "sha256-q7yc/wyGSyYI0KdgHgRi0WISv9WEibxQ5yM7cSjXS2s="; }; - th-desugar = { - version = "1.11"; - sha256 = "sha256-07sUW1ufEM7Xqv6C2rlFGI5CDO5cchDOND7QFstKu5g="; - }; one-liner = { version = "1.0"; sha256 = "sha256-dv/W8hIPoHVevxiiCb6OfeP53O/9HPgUiqOHGSNb/pk="; From ab02f24c8ad3f878e53213fde145715783b47b75 Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Wed, 9 Nov 2022 18:04:08 +0100 Subject: [PATCH 07/35] imports: Remove hiding Option and option --- libs/imports/src/Imports.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/imports/src/Imports.hs b/libs/imports/src/Imports.hs index 81e583b880..664fb70fcc 100644 --- a/libs/imports/src/Imports.hs +++ b/libs/imports/src/Imports.hs @@ -161,7 +161,7 @@ import Data.Maybe import Data.Monoid hiding (First (..), Last (..)) import Data.Ord -- conflicts with Options.Applicative.Option (should we care?) -import Data.Semigroup hiding (Option, diff, option) +import Data.Semigroup hiding (diff) import Data.Set (Set) import Data.String import Data.Text (Text) From 5557575c94ee2ae2e59f957787f5826d34d4f684 Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Thu, 10 Nov 2022 09:51:42 +0100 Subject: [PATCH 08/35] use generic-data_1_0_0_0 --- nix/manual-overrides.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/nix/manual-overrides.nix b/nix/manual-overrides.nix index 0e31c905c8..ac0f51a5b9 100644 --- a/nix/manual-overrides.nix +++ b/nix/manual-overrides.nix @@ -29,6 +29,7 @@ hself: hsuper: { one-liner = hlib.doJailbreak hsuper.one-liner; type-errors = hlib.dontCheck hsuper.type-errors; binary-parsers = hlib.doJailbreak hsuper.binary-parsers; + generic-data = hsuper.generic-data_1_0_0_0; # Some test seems to be broken hsaml2 = hlib.dontCheck hsuper.hsaml2; From cb77263ae312bf47b9408313e5cd6e1e8b8eb975 Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Tue, 17 Jan 2023 18:03:20 +0100 Subject: [PATCH 09/35] tinylog: use new fork --- nix/haskell-pins.nix | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/nix/haskell-pins.nix b/nix/haskell-pins.nix index 382d4110bd..a04f005068 100644 --- a/nix/haskell-pins.nix +++ b/nix/haskell-pins.nix @@ -218,6 +218,22 @@ let sha256 = "sha256-yiw6hg3guRWS6CVdrUY8wyIDxoqfGjIVMrEtP+Fys0Y="; }; }; + # Not tested/relased yet + # https://github.com/dylex/invertible/commit/e203c6a729fde87b1f903c3f468f739a085fb446 + invertible = { + src = fetchgit { + url = "https://github.com/dylex/invertible.git"; + rev = "e203c6a729fde87b1f903c3f468f739a085fb446"; + sha256 = "sha256-G6PX5lpU18oWLkwIityN4Hs0HuwQrq9T51kxbsdpK3M="; + }; + }; + tinylog = { + src = fetchgit { + url = "https://gitlab.com/wireapp/forks/tinylog.git"; + rev = "9609104263e8cd2a631417c1c3ef23e090de0d09"; + sha256 = "sha256-htEIJY+LmIMACVZrflU60+X42/g14NxUyFM7VJs4E6w="; + }; + }; }; hackagePins = { wai-route = { From 3e682208156efd9c76f4f4fa59da0fd5381e15e2 Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Tue, 17 Jan 2023 18:18:29 +0100 Subject: [PATCH 10/35] kind-generics(-th): bump to newer versions --- nix/haskell-pins.nix | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nix/haskell-pins.nix b/nix/haskell-pins.nix index a04f005068..2c733a69c7 100644 --- a/nix/haskell-pins.nix +++ b/nix/haskell-pins.nix @@ -241,12 +241,12 @@ let sha256 = "sha256-DSMckKIeVE/buSMg8Mq+mUm1bYPYB7veA11Ns7vTBbc="; }; kind-generics = { - version = "0.4.1.2"; - sha256 = "sha256-orDfC5+QXRlAMVaqAhT1Fo7Eh/AnobROWeliZqEAXZU="; + version = "0.4.1.4"; + sha256 = "sha256-vH4YO/2NtaLDn1pyAQYK9vC5dD0bpdk26aH5sA9+UT8="; }; kind-generics-th = { - version = "0.2.2.2"; - sha256 = "sha256-nPuRq19UGVXe4YrITAZcF+U4TUBo5APMT2Nh9NqIkxQ="; + version = "0.2.2.3"; + sha256 = "sha256-LH2Wpo0v+RQSsvVbosuB99ekSzqsqMNjrd+w/B0SOUs="; }; polysemy = { version = "1.8.0.0"; From 75645fcf72d4d7159eca4699ae8d13acf34281d5 Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Thu, 19 Jan 2023 13:44:19 +0100 Subject: [PATCH 11/35] kind-generics-th: jailbreak --- nix/manual-overrides.nix | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nix/manual-overrides.nix b/nix/manual-overrides.nix index ac0f51a5b9..b291319cbc 100644 --- a/nix/manual-overrides.nix +++ b/nix/manual-overrides.nix @@ -64,4 +64,7 @@ hself: hsuper: { # Postie has been fixed upstream (master) postie = hlib.markUnbroken (hlib.doJailbreak hsuper.postie); + + # This would not be necessary if we could pull revision -r1 from 0.2.2.3 + kind-generics-th = hlib.doJailbreak hsuper.kind-generics-th; } From 29ae9bb77fb8879c72298115679da73ca836ef99 Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Thu, 19 Jan 2023 17:39:33 +0100 Subject: [PATCH 12/35] singletons: remove pin --- nix/haskell-pins.nix | 4 ---- 1 file changed, 4 deletions(-) diff --git a/nix/haskell-pins.nix b/nix/haskell-pins.nix index 2c733a69c7..a039983652 100644 --- a/nix/haskell-pins.nix +++ b/nix/haskell-pins.nix @@ -260,10 +260,6 @@ let version = "0.4.3.1"; sha256 = "sha256-0vkLYNZISr3fmmQvD8qdLkn2GHc80l1GzJuOmqjqXE4="; }; - singletons = { - version = "2.7"; - sha256 = "sha256-q7yc/wyGSyYI0KdgHgRi0WISv9WEibxQ5yM7cSjXS2s="; - }; one-liner = { version = "1.0"; sha256 = "sha256-dv/W8hIPoHVevxiiCb6OfeP53O/9HPgUiqOHGSNb/pk="; From a70bd03585f1af62f2a5dbd0e2cb11c876e31047 Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Thu, 19 Jan 2023 18:08:25 +0100 Subject: [PATCH 13/35] wai-predicates: use new fork --- nix/haskell-pins.nix | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/nix/haskell-pins.nix b/nix/haskell-pins.nix index a039983652..9f3872b77a 100644 --- a/nix/haskell-pins.nix +++ b/nix/haskell-pins.nix @@ -193,6 +193,13 @@ let sha256 = "1zj3fqlvcvp9s0myb98b6s9mpmiqamyxn2d3jan55irdgm53prmv"; }; }; + wai-predicates = { + src = fetchgit { + url = "https://gitlab.com/wireapp/forks/wai-predicates.git"; + rev = "ff95282a982ab45cced70656475eaf2cefaa26ea"; + sha256 = "sha256-x2XSv2+/+DG9FXN8hfUWGNIO7V4iBhlzYz19WWKaLKQ="; + }; + }; wai-routing = { src = fetchgit { url = "https://gitlab.com/twittner/wai-routing"; From b5a6d300b2f7fa1df49f9f9d2cf18a4c53e11274 Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Fri, 20 Jan 2023 11:04:28 +0100 Subject: [PATCH 14/35] hspec-wai: pin to commit 6984a0 --- nix/haskell-pins.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nix/haskell-pins.nix b/nix/haskell-pins.nix index 9f3872b77a..42bfeb9b4d 100644 --- a/nix/haskell-pins.nix +++ b/nix/haskell-pins.nix @@ -141,8 +141,8 @@ let hspec-wai = { src = fetchgit { url = "https://github.com/wireapp/hspec-wai"; - rev = "0a5142cd3ba48116ff059c041348b817fb7bdb25"; - sha256 = "1yqkla7467fgb23yw689xh15zjn38rkc7ckf18cfalpc2ff5wfq1"; + rev = "6984a06b0c6294677c49d59382d48f975a8733d4"; + sha256 = "sha256-6FLTMMqvL0xFa5zsMnjVAmdpghmdeBl813bWcOyQo5E="; }; }; http-client = { From a7c82fc3d10d52a9cf82f840766f3d77ff63f4c8 Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Fri, 20 Jan 2023 11:13:45 +0100 Subject: [PATCH 15/35] hscim: fix compilation and tests after by hspec-wai upgrade after hspec-wai upgrade test run in isolation. so we need to recreate the assumed initialisation each test case to make them pass --- libs/hscim/hscim.cabal | 228 +++++++++--------- libs/hscim/src/Web/Scim/Test/Util.hs | 24 +- .../test/Test/Capabilities/MetaSchemaSpec.hs | 6 +- libs/hscim/test/Test/Class/AuthSpec.hs | 2 +- libs/hscim/test/Test/Class/GroupSpec.hs | 6 +- libs/hscim/test/Test/Class/UserSpec.hs | 23 +- libs/hscim/test/Test/Schema/UserSpec.hs | 1 + 7 files changed, 158 insertions(+), 132 deletions(-) diff --git a/libs/hscim/hscim.cabal b/libs/hscim/hscim.cabal index 6ae8cbdae8..f98ad510a3 100644 --- a/libs/hscim/hscim.cabal +++ b/libs/hscim/hscim.cabal @@ -83,44 +83,44 @@ library ghc-options: -Wall -Werror build-depends: - aeson >=2 - , aeson-qq >=0.8.2 && <0.9 - , attoparsec >=0.13.2 && <0.15 - , base >=4.12 && <4.15 - , bytestring >=0.10.8 && <0.11 - , case-insensitive >=1.2.1.0 && <1.3 - , email-validate >=2.3.2 && <2.4 - , hashable >=1.2.7 && <1.5 - , hedgehog >=1.0.1 && <1.1 - , hspec >=2.7.1 && <2.9 - , hspec-expectations >=0.8.2 && <0.9 - , hspec-wai >=0.9.2 && <0.10 - , http-api-data >=0.4.1 && <0.5 - , http-media >=0.8.0 && <0.9 - , http-types >=0.12.3 && <0.13 - , hw-hspec-hedgehog >=0.1.0 && <0.2 - , list-t >=1.0.4 && <1.1 - , microlens >=0.4.10 && <0.5 - , mmorph >=1.1.3 && <1.2 - , mtl >=2.2.2 && <2.3 - , network-uri >=2.6.2 && <2.7 - , retry >=0.8.1.0 && <0.10 - , scientific >=0.3.6 && <0.4 - , servant >=0.16.2 && <0.20 - , servant-client >=0.16.2 && <0.20 - , servant-client-core >=0.16.2 && <0.20 - , servant-server >=0.16.2 && <0.20 - , stm >=2.5.0 && <2.6 - , stm-containers >=1.1.0 && <1.3 - , string-conversions >=0.4.0 && <0.5 - , template-haskell >=2.14.0 && <2.17 - , text >=1.2.3 && <1.3 - , time >=1.8.0 && <1.10 - , unordered-containers >=0.2.10 && <0.3 - , uuid >=1.3.13 && <1.4 - , wai >=3.2.2 && <3.3 - , wai-extra >=3.0.28 && <3.2 - , warp >=3.2.28 && <3.4 + aeson + , aeson-qq + , attoparsec + , base + , bytestring + , case-insensitive + , email-validate + , hashable + , hedgehog + , hspec + , hspec-expectations + , hspec-wai + , http-api-data + , http-media + , http-types + , hw-hspec-hedgehog + , list-t + , microlens + , mmorph + , mtl + , network-uri + , retry + , scientific + , servant + , servant-client + , servant-client-core + , servant-server + , stm + , stm-containers + , string-conversions + , template-haskell + , text + , time + , unordered-containers + , uuid + , wai + , wai-extra + , warp default-language: Haskell2010 @@ -148,45 +148,45 @@ executable hscim-server ghc-options: -Wall -Werror -threaded -rtsopts -with-rtsopts=-N build-depends: - aeson >=2 - , aeson-qq >=0.8.2 && <0.9 - , attoparsec >=0.13.2 && <0.15 - , base >=4.12 && <4.15 - , bytestring >=0.10.8 && <0.11 - , case-insensitive >=1.2.1.0 && <1.3 - , email-validate >=2.3.2 && <2.4 - , hashable >=1.2.7 && <1.5 - , hedgehog >=1.0.1 && <1.1 + aeson + , aeson-qq + , attoparsec + , base + , bytestring + , case-insensitive + , email-validate + , hashable + , hedgehog , hscim - , hspec >=2.7.1 && <2.9 - , hspec-expectations >=0.8.2 && <0.9 - , hspec-wai >=0.9.2 && <0.10 - , http-api-data >=0.4.1 && <0.5 - , http-media >=0.8.0 && <0.9 - , http-types >=0.12.3 && <0.13 - , hw-hspec-hedgehog >=0.1.0 && <0.2 - , list-t >=1.0.4 && <1.1 - , microlens >=0.4.10 && <0.5 - , mmorph >=1.1.3 && <1.2 - , mtl >=2.2.2 && <2.3 - , network-uri >=2.6.2 && <2.7 - , retry >=0.8.1.0 && <0.10 - , scientific >=0.3.6 && <0.4 - , servant >=0.16.2 && <0.20 - , servant-client >=0.16.2 && <0.20 - , servant-client-core >=0.16.2 && <0.20 - , servant-server >=0.16.2 && <0.20 - , stm >=2.5.0 && <2.6 - , stm-containers >=1.1.0 && <1.3 - , string-conversions >=0.4.0 && <0.5 - , template-haskell >=2.14.0 && <2.17 - , text >=1.2.3 && <1.3 - , time >=1.8.0 && <1.10 - , unordered-containers >=0.2.10 && <0.3 - , uuid >=1.3.13 && <1.4 - , wai >=3.2.2 && <3.3 - , wai-extra >=3.0.28 && <3.2 - , warp >=3.2.28 && <3.4 + , hspec + , hspec-expectations + , hspec-wai + , http-api-data + , http-media + , http-types + , hw-hspec-hedgehog + , list-t + , microlens + , mmorph + , mtl + , network-uri + , retry + , scientific + , servant + , servant-client + , servant-client-core + , servant-server + , stm + , stm-containers + , string-conversions + , template-haskell + , text + , time + , unordered-containers + , uuid + , wai + , wai-extra + , warp default-language: Haskell2010 @@ -232,45 +232,45 @@ test-suite spec ghc-options: -Wall -Werror -threaded -rtsopts -with-rtsopts=-N build-tool-depends: hspec-discover:hspec-discover build-depends: - aeson >=2 - , aeson-qq >=0.8.2 && <0.9 - , attoparsec >=0.13.2 && <0.15 - , base >=4.12 && <4.15 - , bytestring >=0.10.8 && <0.11 - , case-insensitive >=1.2.1.0 && <1.3 - , email-validate >=2.3.2 && <2.4 - , hashable >=1.2.7 && <1.5 - , hedgehog >=1.0.1 && <1.1 + aeson + , aeson-qq + , attoparsec + , base + , bytestring + , case-insensitive + , email-validate + , hashable + , hedgehog , hscim - , hspec >=2.7.1 && <2.9 - , hspec-expectations >=0.8.2 && <0.9 - , hspec-wai >=0.9.2 && <0.10 - , http-api-data >=0.4.1 && <0.5 - , http-media >=0.8.0 && <0.9 - , http-types >=0.12.3 && <0.13 - , hw-hspec-hedgehog >=0.1.0 && <0.2 + , hspec + , hspec-expectations + , hspec-wai + , http-api-data + , http-media + , http-types + , hw-hspec-hedgehog , indexed-traversable - , list-t >=1.0.4 && <1.1 - , microlens >=0.4.10 && <0.5 - , mmorph >=1.1.3 && <1.2 - , mtl >=2.2.2 && <2.3 - , network-uri >=2.6.2 && <2.7 - , retry >=0.8.1.0 && <0.10 - , scientific >=0.3.6 && <0.4 - , servant >=0.16.2 && <0.20 - , servant-client >=0.16.2 && <0.20 - , servant-client-core >=0.16.2 && <0.20 - , servant-server >=0.16.2 && <0.20 - , stm >=2.5.0 && <2.6 - , stm-containers >=1.1.0 && <1.3 - , string-conversions >=0.4.0 && <0.5 - , template-haskell >=2.14.0 && <2.17 - , text >=1.2.3 && <1.3 - , time >=1.8.0 && <1.10 - , unordered-containers >=0.2.10 && <0.3 - , uuid >=1.3.13 && <1.4 - , wai >=3.2.2 && <3.3 - , wai-extra >=3.0.28 && <3.2 - , warp >=3.2.28 && <3.4 + , list-t + , microlens + , mmorph + , mtl + , network-uri + , retry + , scientific + , servant + , servant-client + , servant-client-core + , servant-server + , stm + , stm-containers + , string-conversions + , template-haskell + , text + , time + , unordered-containers + , uuid + , wai + , wai-extra + , warp default-language: Haskell2010 diff --git a/libs/hscim/src/Web/Scim/Test/Util.hs b/libs/hscim/src/Web/Scim/Test/Util.hs index e05dfad157..754e2053ef 100644 --- a/libs/hscim/src/Web/Scim/Test/Util.hs +++ b/libs/hscim/src/Web/Scim/Test/Util.hs @@ -82,17 +82,17 @@ import Web.Scim.Schema.User (UserTypes (..)) -- FUTUREWORK: make this a PR upstream. (while we're at it, we can also patch 'WaiSession' -- and 'request' to keep track of the 'SRequest', and add that to the error message here with -- the response.) -shouldRespondWith :: HasCallStack => WaiSession SResponse -> ResponseMatcher -> WaiExpectation +shouldRespondWith :: HasCallStack => WaiSession st SResponse -> ResponseMatcher -> WaiExpectation st shouldRespondWith action matcher = either (liftIO . expectationFailure) pure =<< doesRespondWith action matcher -doesRespondWith :: HasCallStack => WaiSession SResponse -> ResponseMatcher -> WaiSession (Either String ()) +doesRespondWith :: HasCallStack => WaiSession st SResponse -> ResponseMatcher -> WaiSession st (Either String ()) doesRespondWith action matcher = do r <- action let extmsg = " details: " <> show r <> "\n" pure $ maybe (Right ()) (Left . (<> extmsg)) (match r matcher) -shouldEventuallyRespondWith :: HasCallStack => WaiSession SResponse -> ResponseMatcher -> WaiExpectation +shouldEventuallyRespondWith :: HasCallStack => WaiSession st SResponse -> ResponseMatcher -> WaiExpectation st shouldEventuallyRespondWith action matcher = either (liftIO . expectationFailure) pure =<< Retry.retrying @@ -150,31 +150,31 @@ defAcceptanceQueryConfig = AcceptanceQueryConfig {..} a' = maybe a (\(t, l) -> if l == '/' then t else a) $ BS8.unsnoc a b' = maybe b (\(h, t) -> if h == '/' then t else b) $ BS8.uncons b -post :: ByteString -> L.ByteString -> WaiSession SResponse +post :: ByteString -> L.ByteString -> WaiSession st SResponse post path = request methodPost path [(hContentType, "application/scim+json")] -put :: ByteString -> L.ByteString -> WaiSession SResponse +put :: ByteString -> L.ByteString -> WaiSession st SResponse put path = request methodPut path [(hContentType, "application/scim+json")] -patch :: ByteString -> L.ByteString -> WaiSession SResponse +patch :: ByteString -> L.ByteString -> WaiSession st SResponse patch path = request methodPatch path [(hContentType, "application/scim+json")] -request' :: Method -> AcceptanceQueryConfig tag -> ByteString -> L.ByteString -> WaiSession SResponse +request' :: Method -> AcceptanceQueryConfig tag -> ByteString -> L.ByteString -> WaiSession st SResponse request' method (AcceptanceQueryConfig prefix token) path = request method (prefix path) [(hAuthorization, token), (hContentType, "application/scim+json")] -get' :: AcceptanceQueryConfig tag -> ByteString -> WaiSession SResponse +get' :: AcceptanceQueryConfig tag -> ByteString -> WaiSession st SResponse get' cfg path = request' methodGet cfg path "" -post' :: AcceptanceQueryConfig tag -> ByteString -> L.ByteString -> WaiSession SResponse +post' :: AcceptanceQueryConfig tag -> ByteString -> L.ByteString -> WaiSession st SResponse post' = request' methodPost -put' :: AcceptanceQueryConfig tag -> ByteString -> L.ByteString -> WaiSession SResponse +put' :: AcceptanceQueryConfig tag -> ByteString -> L.ByteString -> WaiSession st SResponse put' = request' methodPut -patch' :: AcceptanceQueryConfig tag -> ByteString -> L.ByteString -> WaiSession SResponse +patch' :: AcceptanceQueryConfig tag -> ByteString -> L.ByteString -> WaiSession st SResponse patch' = request' methodPatch -delete' :: AcceptanceQueryConfig tag -> ByteString -> L.ByteString -> WaiSession SResponse +delete' :: AcceptanceQueryConfig tag -> ByteString -> L.ByteString -> WaiSession st SResponse delete' = request' methodDelete ---------------------------------------------------------------------------- diff --git a/libs/hscim/test/Test/Capabilities/MetaSchemaSpec.hs b/libs/hscim/test/Test/Capabilities/MetaSchemaSpec.hs index bff1aa4068..0c846782f6 100644 --- a/libs/hscim/test/Test/Capabilities/MetaSchemaSpec.hs +++ b/libs/hscim/test/Test/Capabilities/MetaSchemaSpec.hs @@ -44,9 +44,9 @@ app = do shouldSatisfy :: (Show a, FromJSON a) => - WaiSession SResponse -> + WaiSession st SResponse -> (a -> Bool) -> - WaiExpectation + WaiExpectation st shouldSatisfy resp predicate = do maybeDecoded <- eitherDecode . simpleBody <$> resp case maybeDecoded of @@ -69,7 +69,7 @@ coreSchemas = ] spec :: Spec -spec = beforeAll app $ do +spec = with app $ do describe "GET /Schemas" $ do it "lists schemas" $ do get "/Schemas" `shouldRespondWith` 200 diff --git a/libs/hscim/test/Test/Class/AuthSpec.hs b/libs/hscim/test/Test/Class/AuthSpec.hs index a5130476d5..9f5b063271 100644 --- a/libs/hscim/test/Test/Class/AuthSpec.hs +++ b/libs/hscim/test/Test/Class/AuthSpec.hs @@ -35,7 +35,7 @@ testStorage :: IO TestStorage testStorage = TestStorage <$> STMMap.newIO <*> STMMap.newIO spec :: Spec -spec = beforeAll ((\s -> app @Mock empty (nt s)) <$> testStorage) $ do +spec = with ((\s -> app @Mock empty (nt s)) <$> testStorage) $ do describe "/ServiceProviderConfig" $ do it "is accessible without authentication" $ do get "/ServiceProviderConfig" `shouldRespondWith` 200 diff --git a/libs/hscim/test/Test/Class/GroupSpec.hs b/libs/hscim/test/Test/Class/GroupSpec.hs index 7d3a472854..a48f92aa3c 100644 --- a/libs/hscim/test/Test/Class/GroupSpec.hs +++ b/libs/hscim/test/Test/Class/GroupSpec.hs @@ -43,7 +43,7 @@ app = do (nt storage) spec :: Spec -spec = beforeAll app $ do +spec = with app $ do describe "GET & POST /Groups" $ do it "responds with [] in empty environment" $ do get "/" `shouldRespondWith` emptyList @@ -54,17 +54,21 @@ spec = beforeAll app $ do it "responds with 404 for unknown group" $ do get "/9999" `shouldRespondWith` 404 it "retrieves stored group" $ do + post "/" adminGroup `shouldRespondWith` 201 -- the test implementation stores groups with uid [0,1..n-1] get "/0" `shouldRespondWith` admins describe "PUT /Groups/:id" $ do it "adds member to existing group" $ do + post "/" adminGroup `shouldRespondWith` 201 put "/0" adminUpdate0 `shouldRespondWith` updatedAdmins0 it "does not create new group" $ do put "/9999" adminGroup `shouldRespondWith` 404 describe "DELETE /Groups/:id" $ do it "responds with 404 for unknown group" $ do + post "/" adminGroup `shouldRespondWith` 201 delete "/Users/unknown" `shouldRespondWith` 404 it "deletes a stored group" $ do + post "/" adminGroup `shouldRespondWith` 201 delete "/0" `shouldRespondWith` 204 -- group should be gone get "/0" `shouldRespondWith` 404 diff --git a/libs/hscim/test/Test/Class/UserSpec.hs b/libs/hscim/test/Test/Class/UserSpec.hs index deebc04840..3d3d16d0e1 100644 --- a/libs/hscim/test/Test/Class/UserSpec.hs +++ b/libs/hscim/test/Test/Class/UserSpec.hs @@ -39,7 +39,7 @@ app = do pure $ mkapp @Mock (Proxy @(UserAPI Mock)) (toServant (userServer auth)) (nt storage) spec :: Spec -spec = beforeAll app $ do +spec = with app $ do describe "GET & POST /Users" $ do it "responds with [] in empty environment" $ do get "/" `shouldRespondWith` emptyList @@ -49,17 +49,23 @@ spec = beforeAll app $ do get "/" `shouldRespondWith` allUsers describe "filtering" $ do it "can filter by username" $ do + post "/" newBarbara `shouldRespondWith` 201 get "/?filter=userName eq \"bjensen\"" `shouldRespondWith` onlyBarbara it "is case-insensitive regarding syntax" $ do + post "/" newBarbara `shouldRespondWith` 201 get "/?filter=USERName EQ \"bjensen\"" `shouldRespondWith` onlyBarbara it "is case-insensitive regarding usernames" $ do + post "/" newBarbara `shouldRespondWith` 201 get "/?filter=userName eq \"BJensen\"" `shouldRespondWith` onlyBarbara it "handles malformed filter syntax" $ do + post "/" newBarbara `shouldRespondWith` 201 get "/?filter=userName eqq \"bjensen\"" `shouldRespondWith` 400 -- TODO: would be nice to check the error message as well it "handles type errors in comparisons" $ do + post "/" newBarbara `shouldRespondWith` 201 get "/?filter=userName eq true" `shouldRespondWith` 400 + describe "GET /Users/:id" $ do it "responds with 404 for unknown user" $ do get "/9999" `shouldRespondWith` 404 @@ -68,12 +74,15 @@ spec = beforeAll app $ do xit "responds with 401 for unparseable user ID" $ do get "/unparseable" `shouldRespondWith` 401 it "retrieves stored user" $ do + post "/" newBarbara `shouldRespondWith` 201 -- the test implementation stores users with uid [0,1..n-1] get "/0" `shouldRespondWith` barbara describe "PUT /Users/:id" $ do it "overwrites the user" $ do + post "/" newBarbara `shouldRespondWith` 201 put "/0" barbUpdate0 `shouldRespondWith` updatedBarb0 it "does not create new users" $ do + post "/" newBarbara `shouldRespondWith` 201 put "/9999" newBarbara `shouldRespondWith` 404 -- TODO(arianvp): Perhaps we want to make this an acceptance spec. describe "PATCH /Users/:id" $ do @@ -82,6 +91,7 @@ spec = beforeAll app $ do -- TODO(arianvp): We need to merge multi-value fields, but not supported yet -- TODO(arianvp): Add and Replace tests currently identical, because of lack of multi-value it "adds all fields if no target" $ do + post "/" newBarbara `shouldRespondWith` 201 _ <- put "/0" smallUser -- reset patch "/0" @@ -116,6 +126,7 @@ spec = beforeAll app $ do { matchStatus = 200 } it "adds fields if they didn't exist yet" $ do + post "/" newBarbara `shouldRespondWith` 201 _ <- put "/0" smallUser -- reset patch "/0" @@ -147,6 +158,7 @@ spec = beforeAll app $ do { matchStatus = 200 } it "replaces individual simple fields" $ do + post "/" newBarbara `shouldRespondWith` 201 _ <- put "/0" smallUser -- reset patch "/0" @@ -183,6 +195,7 @@ spec = beforeAll app $ do -- not limit by type what fields it lenses in to. It is a very untyped -- thingy currently. it "PatchOp is atomic. Either fully applies or not at all" $ do + post "/" newBarbara `shouldRespondWith` 201 _ <- put "/0" smallUser -- reset patch "/0" @@ -202,6 +215,7 @@ spec = beforeAll app $ do describe "Replace" $ do -- TODO(arianvp): Implement and test multi-value fields properly it "adds all fields if no target" $ do + post "/" newBarbara `shouldRespondWith` 201 _ <- put "/0" smallUser -- reset patch "/0" @@ -236,6 +250,7 @@ spec = beforeAll app $ do { matchStatus = 200 } it "adds fields if they didn't exist yet" $ do + post "/" newBarbara `shouldRespondWith` 201 _ <- put "/0" smallUser -- reset patch "/0" @@ -267,6 +282,7 @@ spec = beforeAll app $ do { matchStatus = 200 } it "replaces individual simple fields" $ do + post "/" newBarbara `shouldRespondWith` 201 _ <- put "/0" smallUser -- reset patch "/0" @@ -298,6 +314,7 @@ spec = beforeAll app $ do { matchStatus = 200 } it "PatchOp is atomic. Either fully applies or not at all" $ do + post "/" newBarbara `shouldRespondWith` 201 _ <- put "/0" smallUser -- reset patch "/0" @@ -316,6 +333,7 @@ spec = beforeAll app $ do get "/0" `shouldRespondWith` smallUserGet {matchStatus = 200} describe "Remove" $ do it "fails if no target" $ do + post "/" newBarbara `shouldRespondWith` 201 _ <- put "/0" barbUpdate0 -- reset patch "/0" @@ -329,6 +347,7 @@ spec = beforeAll app $ do { matchStatus = 400 } it "fails if removing immutable" $ do + post "/" newBarbara `shouldRespondWith` 201 _ <- put "/0" barbUpdate0 -- reset patch "/0" @@ -342,6 +361,7 @@ spec = beforeAll app $ do { matchStatus = 400 } it "deletes the specified attribute" $ do + post "/" newBarbara `shouldRespondWith` 201 _ <- put "/0" smallUser -- reset patch "/0" @@ -369,6 +389,7 @@ spec = beforeAll app $ do it "responds with 404 for unknown user" $ do delete "/9999" `shouldRespondWith` 404 it "deletes a stored user" $ do + post "/" newBarbara `shouldRespondWith` 201 delete "/0" `shouldRespondWith` 204 -- user should be gone get "/0" `shouldRespondWith` 404 diff --git a/libs/hscim/test/Test/Schema/UserSpec.hs b/libs/hscim/test/Test/Schema/UserSpec.hs index 6f7ae9180a..deff894b70 100644 --- a/libs/hscim/test/Test/Schema/UserSpec.hs +++ b/libs/hscim/test/Test/Schema/UserSpec.hs @@ -1,6 +1,7 @@ {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE ViewPatterns #-} +{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} -- This file is part of the Wire Server implementation. -- From 0e12168b6528c8013a7a459f2876885ff4c02209 Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Fri, 20 Jan 2023 14:26:08 +0100 Subject: [PATCH 16/35] saml2-web-sso: pin to b79a45 --- nix/haskell-pins.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nix/haskell-pins.nix b/nix/haskell-pins.nix index 42bfeb9b4d..373b15cc4b 100644 --- a/nix/haskell-pins.nix +++ b/nix/haskell-pins.nix @@ -168,8 +168,8 @@ let saml2-web-sso = { src = fetchgit { url = "https://github.com/wireapp/saml2-web-sso"; - rev = "74371cd775cb98d6cf85f6e182244a3c4fd48702"; - sha256 = "1w23yz2iiayniymk7k4g8gww7268187cayw0c8m3bz2hbnvbyfbc"; + rev = "b79a45ac98b1f592ac18511fce48ed88d2e931c9"; + sha256 = "sha256-g2lbKt3+hToVFQvaHOa9dg4HqAL7YgReo8fy7wQavmY="; }; }; swagger2 = { From 7c55aaf350d702cb8522fdfba0d9801af7dd0cb0 Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Fri, 20 Jan 2023 14:41:14 +0100 Subject: [PATCH 17/35] extended: fix compilation --- libs/extended/src/Servant/API/Extended.hs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libs/extended/src/Servant/API/Extended.hs b/libs/extended/src/Servant/API/Extended.hs index f87fc5d214..2d6914c7f1 100644 --- a/libs/extended/src/Servant/API/Extended.hs +++ b/libs/extended/src/Servant/API/Extended.hs @@ -21,6 +21,7 @@ module Servant.API.Extended where import qualified Data.ByteString.Lazy as BL import Data.EitherR (fmapL) +import Data.Kind import Data.Metrics.Servant import Data.String.Conversions (cs) import Data.Typeable @@ -54,12 +55,12 @@ import Prelude () -- that'll be). -- -- See also: https://github.com/haskell-servant/servant/issues/353 -data ReqBodyCustomError' (mods :: [*]) (list :: [ct]) (tag :: Symbol) (a :: *) +data ReqBodyCustomError' (mods :: [Type]) (list :: [ct]) (tag :: Symbol) (a :: Type) type ReqBodyCustomError = ReqBodyCustomError' '[Required, Strict] -- | Custom parse error for bad request bodies. -class MakeCustomError (tag :: Symbol) (a :: *) where +class MakeCustomError (tag :: Symbol) (a :: Type) where makeCustomError :: String -> ServerError -- | Variant of the 'ReqBody'' instance that takes a 'ServerError' as argument instead of a From 170c7fdb1c4d03a940b81fe02164316e25fa59ee Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Fri, 20 Jan 2023 18:15:02 +0100 Subject: [PATCH 18/35] types-common: refactor Data.Range w/ GHC.TypeNats --- libs/types-common/default.nix | 2 - libs/types-common/src/Data/Range.hs | 129 ++++++++++++--------------- libs/types-common/types-common.cabal | 1 - 3 files changed, 58 insertions(+), 74 deletions(-) diff --git a/libs/types-common/default.nix b/libs/types-common/default.nix index b1f22221ba..35c3fed38e 100644 --- a/libs/types-common/default.nix +++ b/libs/types-common/default.nix @@ -41,7 +41,6 @@ , schema-profunctor , scientific , servant-server -, singletons , string-conversions , swagger , swagger2 @@ -100,7 +99,6 @@ mkDerivation { schema-profunctor scientific servant-server - singletons string-conversions swagger swagger2 diff --git a/libs/types-common/src/Data/Range.hs b/libs/types-common/src/Data/Range.hs index ffceb0fddf..a9966edf35 100644 --- a/libs/types-common/src/Data/Range.hs +++ b/libs/types-common/src/Data/Range.hs @@ -24,7 +24,6 @@ module Data.Range ( Range, toRange, - LTE, Within, Bounds (..), checked, @@ -58,8 +57,6 @@ where import Cassandra (ColumnType, Cql (..), Tagged, retag) import Control.Lens ((%~), (?~)) import Data.Aeson (FromJSON (parseJSON), ToJSON (toJSON)) -import Data.Aeson.Types as Aeson (Parser) -import qualified Data.Attoparsec.ByteString as Atto import qualified Data.Bifunctor as Bifunctor import qualified Data.ByteString as B import Data.ByteString.Conversion @@ -75,22 +72,20 @@ import Data.List.NonEmpty (NonEmpty) import qualified Data.List.NonEmpty as N import Data.List1 (List1, toNonEmpty) import qualified Data.Map as Map +import Data.Proxy import Data.Schema import Data.Sequence (Seq) import qualified Data.Sequence as Seq import qualified Data.Set as Set -import Data.Singletons -import Data.Singletons.Prelude.Num -import Data.Singletons.Prelude.Ord -import Data.Singletons.TypeLits import Data.Swagger (ParamSchema, ToParamSchema (..)) import qualified Data.Swagger as S import qualified Data.Text as T import Data.Text.Ascii (AsciiChar, AsciiChars, AsciiText, fromAsciiChars) import qualified Data.Text.Ascii as Ascii import qualified Data.Text.Lazy as TL +import Data.Type.Ord +import GHC.TypeNats import Imports -import Numeric.Natural (Natural) import Servant (FromHttpApiData (..)) import System.Random (Random) import Test.QuickCheck (Arbitrary (arbitrary, shrink), Gen) @@ -103,7 +98,7 @@ newtype Range (n :: Nat) (m :: Nat) a = Range } deriving (Eq, Ord, Show) -toRange :: (LTE n x, LTE x m, KnownNat x, Num a) => Proxy x -> Range n m a +toRange :: (n <= x, x <= m, KnownNat x, Num a) => Proxy x -> Range n m a toRange = Range . fromIntegral . natVal instance (Show a, Num a, Within a n m, KnownNat n, KnownNat m) => Bounded (Range n m a) where @@ -115,19 +110,18 @@ instance NFData (Range n m a) where rnf (Range a) = seq a () instance ToJSON a => ToJSON (Range n m a) where toJSON = toJSON . fromRange -instance (Within a n m, FromJSON a) => FromJSON (Range n m a) where - parseJSON v = parseJSON v >>= maybe (msg sing sing) pure . checked +instance forall a n m. (KnownNat n, KnownNat m, Within a n m, FromJSON a) => FromJSON (Range n m a) where + parseJSON v = parseJSON v >>= maybe msg pure . checked where - msg :: Bounds a => SNat n -> SNat m -> Aeson.Parser (Range n m a) - msg sn sm = fail (errorMsg (fromSing sn) (fromSing sm) "") + msg = fail (errorMsg (natVal (Proxy @n)) (natVal (Proxy @m)) "") rangedSchema :: forall n m d v w a b. - (Within a n m, HasRangedSchemaDocModifier d b) => + (KnownNat n, KnownNat m, Within a n m, HasRangedSchemaDocModifier d b) => SchemaP d v w a b -> SchemaP d v w a (Range n m b) rangedSchema sch = - Range <$> untypedRangedSchema (toInteger (demote @n)) (toInteger (demote @m)) sch + Range <$> untypedRangedSchema (toInteger (natVal (Proxy @n))) (toInteger (natVal (Proxy @m))) sch untypedRangedSchema :: forall d v w a b. @@ -178,16 +172,15 @@ instance S.HasSchema d S.Schema => HasRangedSchemaDocModifier d Word32 where ran instance S.HasSchema d S.Schema => HasRangedSchemaDocModifier d Word64 where rangedSchemaDocModifier _ = numRangedSchemaDocModifier -instance (Within a n m, ToSchema a, HasRangedSchemaDocModifier NamedSwaggerDoc a) => ToSchema (Range n m a) where +instance (KnownNat n, KnownNat m, Within a n m, ToSchema a, HasRangedSchemaDocModifier NamedSwaggerDoc a) => ToSchema (Range n m a) where schema = fromRange .= rangedSchema schema -instance (Within a n m, Cql a) => Cql (Range n m a) where +instance forall a n m. (KnownNat n, KnownNat m, Within a n m, Cql a) => Cql (Range n m a) where ctype = retag (ctype :: Tagged a ColumnType) toCql = toCql . fromRange - fromCql c = fromCql c >>= maybe (msg sing sing) pure . checked + fromCql c = fromCql c >>= maybe msg pure . checked where - msg :: Bounds a => SNat n -> SNat m -> Either String (Range n m a) - msg sn sm = Left (errorMsg (fromSing sn) (fromSing sm) "") + msg = Left (errorMsg (natVal (Proxy @n)) (natVal (Proxy @m)) "") instance (KnownNat n, KnownNat m) => ToParamSchema (Range n m Integer) where toParamSchema = rangedNumToParamSchema @@ -241,25 +234,21 @@ instance S.ToSchema a => S.ToSchema (Range n m a) where declareNamedSchema _ = S.declareNamedSchema (Proxy @a) -instance (Within a n m, FromHttpApiData a) => FromHttpApiData (Range n m a) where +instance (KnownNat n, KnownNat m, Within a n m, FromHttpApiData a) => FromHttpApiData (Range n m a) where parseUrlPiece t = do unchecked <- parseUrlPiece t Bifunctor.first T.pack $ checkedEither @_ @n @m unchecked -type LTE (n :: Nat) (m :: Nat) = (SingI n, SingI m, (n <= m) ~ 'True) +type Within a (n :: Nat) (m :: Nat) = (Bounds a, n <= m) -type Within a (n :: Nat) (m :: Nat) = (Bounds a, LTE n m) +mk :: Bounds a => a -> Nat -> Nat -> Maybe (Range n m a) +mk a n m = + if within a (toInteger n) (toInteger m) + then Just (Range a) + else Nothing -mk :: Bounds a => a -> SNat n -> SNat m -> Maybe (Range n m a) -mk a sn sm = - let n = fromSing sn - m = fromSing sm - in if within a (toInteger n) (toInteger m) - then Just (Range a) - else Nothing - -checked :: Within a n m => a -> Maybe (Range n m a) -checked x = mk x sing sing +checked :: forall n m a. (KnownNat n, KnownNat m, Within a n m) => a -> Maybe (Range n m a) +checked x = mk x (natVal (Proxy @n)) (natVal (Proxy @m)) errorMsg :: (Show a, Show b) => a -> b -> ShowS errorMsg n m = @@ -269,20 +258,20 @@ errorMsg n m = . shows m . showString "]" -checkedEitherMsg :: forall a n m. Within a n m => String -> a -> Either String (Range n m a) +checkedEitherMsg :: forall a n m. (KnownNat n, KnownNat m) => Within a n m => String -> a -> Either String (Range n m a) checkedEitherMsg msg x = do - let sn = sing :: SNat n - sm = sing :: SNat m + let sn = natVal (Proxy @n) + sm = natVal (Proxy @m) case mk x sn sm of - Nothing -> Left $ showString msg . showString ": " . errorMsg (fromSing sn) (fromSing sm) $ "" + Nothing -> Left $ showString msg . showString ": " . errorMsg sn sm $ "" Just r -> Right r -checkedEither :: forall a n m. Within a n m => a -> Either String (Range n m a) +checkedEither :: forall a n m. (KnownNat n, KnownNat m) => Within a n m => a -> Either String (Range n m a) checkedEither x = do - let sn = sing :: SNat n - sm = sing :: SNat m + let sn = natVal (Proxy @n) + sm = natVal (Proxy @m) case mk x sn sm of - Nothing -> Left (errorMsg (fromSing sn) (fromSing sm) "") + Nothing -> Left (errorMsg sn sm "") Just r -> Right r rangedChunks :: forall a n. (Within [a] 1 n, KnownNat n) => [a] -> [Range 1 n [a]] @@ -293,34 +282,33 @@ rangedChunks xs = [] -> [] _ -> Range headPart : rangedChunks tailPart -unsafeRange :: (Show a, Within a n m) => a -> Range n m a -unsafeRange x = fromMaybe (msg sing sing) (checked x) +unsafeRange :: forall a n m. (Show a, KnownNat n, KnownNat m, Within a n m) => a -> Range n m a +unsafeRange x = fromMaybe msg (checked x) where - msg :: SNat n -> SNat m -> Range n m a - msg sn sm = + msg = error . shows x . showString " " - . errorMsg (fromSing sn) (fromSing sm) + . errorMsg (natVal (Proxy @n)) (natVal (Proxy @m)) $ "" -rcast :: (LTE n m, (m <= m') ~ 'True, (n >= n') ~ 'True) => Range n m a -> Range n' m' a +rcast :: (n <= m, m <= m', n >= n') => Range n m a -> Range n' m' a rcast (Range a) = Range a rnil :: Monoid a => Range 0 0 a rnil = Range mempty -rcons, (<|) :: LTE n m => a -> Range n m [a] -> Range n (m + 1) [a] +rcons, (<|) :: n <= m => a -> Range n m [a] -> Range n (m + 1) [a] rcons a (Range aa) = Range (a : aa) infixr 5 <| (<|) = rcons -rinc :: (Integral a, LTE n m) => Range n m a -> Range n (m + 1) a +rinc :: (Integral a, n <= m) => Range n m a -> Range n (m + 1) a rinc (Range a) = Range (a + 1) -rappend :: (LTE n m, LTE n' m', Monoid a) => Range n m a -> Range n' m' a -> Range n (m + m') a +rappend :: (n <= m, n' <= m', Monoid a) => Range n m a -> Range n' m' a -> Range n (m + m') a rappend (Range a) (Range b) = Range (a <> b) rsingleton :: a -> Range 1 1 [a] @@ -413,7 +401,7 @@ instance Bounds (AsciiText r) where ----------------------------------------------------------------------------- -instance (Within a n m, Read a) => Read (Range n m a) where +instance (KnownNat n, KnownNat m, Within a n m, Read a) => Read (Range n m a) where readsPrec p s = fromMaybe [] $ foldr f (Just []) (readsPrec p s) where f :: (Within a n m, Read a) => (a, String) -> Maybe [(Range n m a, String)] -> Maybe [(Range n m a, String)] @@ -422,11 +410,10 @@ instance (Within a n m, Read a) => Read (Range n m a) where ----------------------------------------------------------------------------- -instance (Within a n m, FromByteString a) => FromByteString (Range n m a) where - parser = parser >>= maybe (msg sing sing) pure . checked +instance (KnownNat n, KnownNat m, Within a n m, FromByteString a) => FromByteString (Range n m a) where + parser = parser >>= maybe msg pure . checked where - msg :: Bounds a => SNat n -> SNat m -> Atto.Parser (Range n m a) - msg sn sm = fail (errorMsg (fromSing sn) (fromSing sm) "") + msg = fail (errorMsg (natVal (Proxy @n)) (natVal (Proxy @m)) "") instance ToByteString a => ToByteString (Range n m a) where builder = builder . fromRange @@ -442,20 +429,20 @@ instance Arbitrary (Range m n a) => Arbitrary (Ranged m n a) where arbitrary = Ranged . fromRange <$> arbitrary @(Range m n a) instance - (KnownNat n, KnownNat m, LTE n m, Arbitrary a, Show a) => + (KnownNat n, KnownNat m, n <= m, Arbitrary a, Show a) => Arbitrary (Range n m [a]) where arbitrary = genRangeList @n @m @a arbitrary genRangeList :: - forall (n :: Nat) (m :: Nat) (a :: *). - (Show a, KnownNat n, KnownNat m, LTE n m) => + forall (n :: Nat) (m :: Nat) (a :: Type). + (Show a, KnownNat n, KnownNat m, n <= m) => Gen a -> Gen (Range n m [a]) genRangeList = genRange id instance - (KnownNat n, KnownNat m, LTE n m, Arbitrary a, Show a, Ord a) => + (KnownNat n, KnownNat m, n <= m, Arbitrary a, Show a, Ord a) => Arbitrary (Range n m (Set a)) where arbitrary = genRangeSet @n @m @a arbitrary @@ -465,14 +452,14 @@ instance -- However, it will only show up while running tests and might indicate deeper -- problems, so I'd say that's ok. genRangeSet :: - forall (n :: Nat) (m :: Nat) (a :: *). - (Show a, KnownNat n, KnownNat m, LTE n m, Ord a) => + forall (n :: Nat) (m :: Nat) (a :: Type). + (Show a, KnownNat n, KnownNat m, n <= m, Ord a) => Gen a -> Gen (Range n m (Set a)) genRangeSet gc = (Set.fromList . fromRange <$> genRangeList @n @m @a gc) `QC.suchThatMap` checked -instance (KnownNat n, KnownNat m, LTE n m) => Arbitrary (Range n m Text) where +instance (KnownNat n, KnownNat m, n <= m) => Arbitrary (Range n m Text) where arbitrary = genRangeText arbitrary -- FUTUREWORK: the shrinking could be more general (like genRange) and offer more options @@ -480,27 +467,27 @@ instance (KnownNat n, KnownNat m, LTE n m) => Arbitrary (Range n m Text) where genRangeText :: forall (n :: Nat) (m :: Nat). - (KnownNat n, KnownNat m, LTE n m) => + (KnownNat n, KnownNat m, n <= m) => Gen Char -> Gen (Range n m Text) genRangeText = genRange fromString instance - (AsciiChars c, KnownNat n, KnownNat m, LTE n m, Arbitrary (AsciiChar c)) => + (AsciiChars c, KnownNat n, KnownNat m, n <= m, Arbitrary (AsciiChar c)) => Arbitrary (Range n m (AsciiText c)) where arbitrary = genRangeAsciiText (arbitrary @(AsciiChar c)) genRangeAsciiText :: forall (n :: Nat) (m :: Nat) (c :: Type). - (HasCallStack, KnownNat n, KnownNat m, LTE n m, AsciiChars c) => + (HasCallStack, KnownNat n, KnownNat m, n <= m, AsciiChars c) => Gen (AsciiChar c) -> Gen (Range n m (AsciiText c)) genRangeAsciiText = genRange @n @m fromAsciiChars genRange :: - forall (n :: Nat) (m :: Nat) (a :: *) (b :: *). - (Show b, Bounds b, KnownNat n, KnownNat m, LTE n m) => + forall (n :: Nat) (m :: Nat) (a :: Type) (b :: Type). + (Show b, Bounds b, KnownNat n, KnownNat m, n <= m) => ([a] -> b) -> Gen a -> Gen (Range n m b) @@ -513,17 +500,17 @@ genRange pack_ gc = where grange mi ma gelem = (`replicateM` gelem) =<< QC.chooseInt (mi, ma) -instance (KnownNat n, KnownNat m, LTE n m) => Arbitrary (Range n m Integer) where +instance (KnownNat n, KnownNat m, n <= m) => Arbitrary (Range n m Integer) where arbitrary = genIntegral -instance (KnownNat n, KnownNat m, LTE n m) => Arbitrary (Range n m Word) where +instance (KnownNat n, KnownNat m, n <= m) => Arbitrary (Range n m Word) where arbitrary = genIntegral genIntegral :: forall n m i. - (KnownNat n, KnownNat m, LTE n m, Integral i, Show i, Bounds i, Random i) => + (KnownNat n, KnownNat m, n <= m, Integral i, Show i, Bounds i, Random i) => Gen (Range n m i) genIntegral = unsafeRange @i @n @m <$> QC.choose (fromKnownNat (Proxy @n), fromKnownNat (Proxy @m)) -fromKnownNat :: forall (k :: Nat) (i :: *). (Num i, KnownNat k) => Proxy k -> i +fromKnownNat :: forall (k :: Nat) (i :: Type). (Num i, KnownNat k) => Proxy k -> i fromKnownNat p = fromIntegral $ natVal p diff --git a/libs/types-common/types-common.cabal b/libs/types-common/types-common.cabal index 96fb5b5526..8abae0632b 100644 --- a/libs/types-common/types-common.cabal +++ b/libs/types-common/types-common.cabal @@ -122,7 +122,6 @@ library , schema-profunctor , scientific >=0.3.4 , servant-server - , singletons >=2.0 , string-conversions , swagger >=0.3 , swagger2 From bf7b95ff9bc4ae0107c972fee333b95c3c3860e5 Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Sun, 22 Jan 2023 00:15:02 +0100 Subject: [PATCH 19/35] singletons: pin libarries to new release --- nix/haskell-pins.nix | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/nix/haskell-pins.nix b/nix/haskell-pins.nix index 373b15cc4b..51b1c1554f 100644 --- a/nix/haskell-pins.nix +++ b/nix/haskell-pins.nix @@ -271,6 +271,22 @@ let version = "1.0"; sha256 = "sha256-dv/W8hIPoHVevxiiCb6OfeP53O/9HPgUiqOHGSNb/pk="; }; + singletons = { + version = "3.0.1"; + sha256 = "sha256-ixHWZae6AxjRUldMgpYolXBGsOUT5ZVIw9HZkxrhHQ0="; + }; + singletons-base = { + version = "3.1"; + sha256 = "sha256-SjpkQofdDMrUMi9cHNF5eyqic7WMAhWNqrKr4ip1RNs="; + }; + singletons-th = { + version = "3.1"; + sha256 = "sha256-34nyestxt8KNTSlmr1Y8nElNXa/wZ1+fuLEUVjZX8dk="; + }; + th-desugar = { + version = "1.13"; + sha256 = "sha256-xiAeSM2umcfsz5+mcW+oGKf/EmzvH0ch0lHoKBGzW9I="; + }; }; # Name -> Source -> Maybe Subpath -> Drv mkGitDrv = name: src: subpath: From ae4c084fbc1701e3864c3b30ece9c1af2caa76e8 Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Sun, 22 Jan 2023 00:15:18 +0100 Subject: [PATCH 20/35] wire-api: fix compilation --- libs/wire-api/default.nix | 4 + libs/wire-api/src/Wire/API/ApplyMods.hs | 3 +- .../src/Wire/API/Conversation/Action.hs | 3 +- .../src/Wire/API/Conversation/Role.hs | 116 +++++++++--------- libs/wire-api/src/Wire/API/Error.hs | 12 +- libs/wire-api/src/Wire/API/Error/Galley.hs | 4 +- libs/wire-api/src/Wire/API/MLS/Extension.hs | 3 +- libs/wire-api/src/Wire/API/MLS/Message.hs | 8 +- .../src/Wire/API/MLS/Serialisation.hs | 3 +- .../src/Wire/API/MakesFederatedCall.hs | 11 +- .../src/Wire/API/Provider/Service/Tag.hs | 15 +-- libs/wire-api/src/Wire/API/Routes/Cookies.hs | 11 +- .../src/Wire/API/Routes/MultiTablePaging.hs | 2 +- .../wire-api/src/Wire/API/Routes/MultiVerb.hs | 31 ++--- libs/wire-api/src/Wire/API/Routes/Named.hs | 5 +- libs/wire-api/src/Wire/API/Routes/Public.hs | 7 +- .../src/Wire/API/Routes/Public/Cargohold.hs | 3 +- .../src/Wire/API/Routes/QualifiedCapture.hs | 3 +- .../wire-api/src/Wire/API/Routes/Versioned.hs | 5 +- libs/wire-api/src/Wire/API/Team/Feature.hs | 11 +- libs/wire-api/src/Wire/API/Team/Member.hs | 3 +- libs/wire-api/src/Wire/API/Team/Permission.hs | 3 +- libs/wire-api/src/Wire/API/User.hs | 8 +- libs/wire-api/src/Wire/API/User/Client.hs | 3 +- libs/wire-api/wire-api.cabal | 2 + 25 files changed, 152 insertions(+), 127 deletions(-) diff --git a/libs/wire-api/default.nix b/libs/wire-api/default.nix index 8564a5767a..700d7743c9 100644 --- a/libs/wire-api/default.nix +++ b/libs/wire-api/default.nix @@ -79,6 +79,8 @@ , servant-swagger , servant-swagger-ui , singletons +, singletons-base +, singletons-th , sop-core , string-conversions , swagger @@ -177,6 +179,8 @@ mkDerivation { servant-swagger servant-swagger-ui singletons + singletons-base + singletons-th sop-core string-conversions swagger diff --git a/libs/wire-api/src/Wire/API/ApplyMods.hs b/libs/wire-api/src/Wire/API/ApplyMods.hs index ad65fdb28e..70d5dc9811 100644 --- a/libs/wire-api/src/Wire/API/ApplyMods.hs +++ b/libs/wire-api/src/Wire/API/ApplyMods.hs @@ -17,8 +17,9 @@ module Wire.API.ApplyMods where +import Data.Kind import Servant.API -type family ApplyMods (mods :: [*]) api where +type family ApplyMods (mods :: [Type]) api where ApplyMods '[] api = api ApplyMods (x ': xs) api = x :> ApplyMods xs api diff --git a/libs/wire-api/src/Wire/API/Conversation/Action.hs b/libs/wire-api/src/Wire/API/Conversation/Action.hs index 83edcf73e2..5d98193fd3 100644 --- a/libs/wire-api/src/Wire/API/Conversation/Action.hs +++ b/libs/wire-api/src/Wire/API/Conversation/Action.hs @@ -36,6 +36,7 @@ import Data.Aeson (FromJSON (..), ToJSON (..)) import qualified Data.Aeson as A import qualified Data.Aeson.KeyMap as A import Data.Id +import Data.Kind import qualified Data.List.NonEmpty as NonEmptyList import Data.Qualified (Qualified) import Data.Schema hiding (tag) @@ -52,7 +53,7 @@ import Wire.Arbitrary (Arbitrary (..)) -- | We use this type family instead of a sum type to be able to define -- individual effects per conversation action. See 'HasConversationActionEffects'. -type family ConversationAction (tag :: ConversationActionTag) :: * where +type family ConversationAction (tag :: ConversationActionTag) :: Type where ConversationAction 'ConversationJoinTag = ConversationJoin ConversationAction 'ConversationLeaveTag = () ConversationAction 'ConversationMemberUpdateTag = ConversationMemberUpdate diff --git a/libs/wire-api/src/Wire/API/Conversation/Role.hs b/libs/wire-api/src/Wire/API/Conversation/Role.hs index e215b72db8..43ea2f5a7e 100644 --- a/libs/wire-api/src/Wire/API/Conversation/Role.hs +++ b/libs/wire-api/src/Wire/API/Conversation/Role.hs @@ -85,6 +85,64 @@ import Imports import qualified Test.QuickCheck as QC import Wire.Arbitrary (Arbitrary (arbitrary), GenericUniform (..)) +-------------------------------------------------------------------------------- +-- Action + +newtype Actions = Actions + { allowedActions :: Set Action + } + deriving stock (Eq, Show, Generic) + deriving newtype (Arbitrary) + +allActions :: Actions +allActions = Actions $ Set.fromList [minBound .. maxBound] + +-- | These conversation-level permissions. Analogous to the team-level permissions called +-- 'Perm' (or 'Permissions'). +data Action + = AddConversationMember + | RemoveConversationMember + | ModifyConversationName + | ModifyConversationMessageTimer + | ModifyConversationReceiptMode + | ModifyConversationAccess + | ModifyOtherConversationMember + | LeaveConversation + | DeleteConversation + deriving stock (Eq, Ord, Show, Enum, Bounded, Generic) + deriving (Arbitrary) via (GenericUniform Action) + deriving (S.ToSchema) via (S.CustomSwagger '[S.ConstructorTagModifier S.CamelToSnake] Action) + +type family ActionName (a :: Action) :: Symbol where + ActionName 'AddConversationMember = "add_conversation_member" + ActionName 'RemoveConversationMember = "remove_conversation_member" + ActionName 'ModifyConversationName = "modify_conversation_name" + ActionName 'ModifyConversationMessageTimer = "modify_conversation_message_timer" + ActionName 'ModifyConversationReceiptMode = "modify_conversation_receipt_mode" + ActionName 'ModifyConversationAccess = "modify_conversation_access" + ActionName 'ModifyOtherConversationMember = "modify_other_conversation_member" + ActionName 'LeaveConversation = "leave_conversation" + ActionName 'DeleteConversation = "delete_conversation" + +typeConversationRoleAction :: Doc.DataType +typeConversationRoleAction = + Doc.string $ + Doc.enum + [ "add_conversation_member", + "remove_conversation_member", + "modify_conversation_name", + "modify_conversation_message_timer", + "modify_conversation_receipt_mode", + "modify_conversation_access", + "modify_other_conversation_member", + "leave_conversation", + "delete_conversation" + ] + +A.deriveJSON A.defaultOptions {A.constructorTagModifier = A.camelTo2 '_'} ''Action + +$(genSingletons [''Action]) + -------------------------------------------------------------------------------- -- Role @@ -251,61 +309,3 @@ isValidRoleName = *> count 126 (optional (satisfy chars)) *> endOfInput chars = inClass "a-z0-9_" - --------------------------------------------------------------------------------- --- Action - -newtype Actions = Actions - { allowedActions :: Set Action - } - deriving stock (Eq, Show, Generic) - deriving newtype (Arbitrary) - -allActions :: Actions -allActions = Actions $ Set.fromList [minBound .. maxBound] - --- | These conversation-level permissions. Analogous to the team-level permissions called --- 'Perm' (or 'Permissions'). -data Action - = AddConversationMember - | RemoveConversationMember - | ModifyConversationName - | ModifyConversationMessageTimer - | ModifyConversationReceiptMode - | ModifyConversationAccess - | ModifyOtherConversationMember - | LeaveConversation - | DeleteConversation - deriving stock (Eq, Ord, Show, Enum, Bounded, Generic) - deriving (Arbitrary) via (GenericUniform Action) - deriving (S.ToSchema) via (S.CustomSwagger '[S.ConstructorTagModifier S.CamelToSnake] Action) - -type family ActionName (a :: Action) :: Symbol where - ActionName 'AddConversationMember = "add_conversation_member" - ActionName 'RemoveConversationMember = "remove_conversation_member" - ActionName 'ModifyConversationName = "modify_conversation_name" - ActionName 'ModifyConversationMessageTimer = "modify_conversation_message_timer" - ActionName 'ModifyConversationReceiptMode = "modify_conversation_receipt_mode" - ActionName 'ModifyConversationAccess = "modify_conversation_access" - ActionName 'ModifyOtherConversationMember = "modify_other_conversation_member" - ActionName 'LeaveConversation = "leave_conversation" - ActionName 'DeleteConversation = "delete_conversation" - -typeConversationRoleAction :: Doc.DataType -typeConversationRoleAction = - Doc.string $ - Doc.enum - [ "add_conversation_member", - "remove_conversation_member", - "modify_conversation_name", - "modify_conversation_message_timer", - "modify_conversation_receipt_mode", - "modify_conversation_access", - "modify_other_conversation_member", - "leave_conversation", - "delete_conversation" - ] - -A.deriveJSON A.defaultOptions {A.constructorTagModifier = A.camelTo2 '_'} ''Action - -$(genSingletons [''Action]) diff --git a/libs/wire-api/src/Wire/API/Error.hs b/libs/wire-api/src/Wire/API/Error.hs index c34bf13a5f..92c6c38427 100644 --- a/libs/wire-api/src/Wire/API/Error.hs +++ b/libs/wire-api/src/Wire/API/Error.hs @@ -46,6 +46,7 @@ where import Control.Lens (at, (%~), (.~), (?~)) import Data.Aeson (FromJSON (..), ToJSON (..)) import qualified Data.Aeson as A +import Data.Kind import Data.Metrics.Servant import Data.Proxy import Data.SOP @@ -57,7 +58,6 @@ import GHC.TypeLits import Imports hiding (All) import Network.HTTP.Types.Status import qualified Network.Wai.Utilities.Error as Wai -import Numeric.Natural import Polysemy import Polysemy.Error import Servant @@ -204,8 +204,12 @@ errorResponseSwagger = addStaticErrorToSwagger :: forall e. KnownError e => S.Swagger -> S.Swagger addStaticErrorToSwagger = - S.allOperations . S.responses . S.responses . at (fromIntegral (eCode err)) - %~ Just . addRef + S.allOperations + . S.responses + . S.responses + . at (fromIntegral (eCode err)) + %~ Just + . addRef where err = dynError @e resp = errorResponseSwagger @e @@ -267,7 +271,7 @@ instance KnownError e => APIError (SStaticError e) where -------------------------------------------------------------------------------- -- MultiVerb support -type family RespondWithStaticError (s :: StaticError) :: * where +type family RespondWithStaticError (s :: StaticError) :: Type where RespondWithStaticError ('StaticError s l m) = RespondAs JSON s m DynError type family StaticErrorStatus (s :: StaticError) :: Nat where diff --git a/libs/wire-api/src/Wire/API/Error/Galley.hs b/libs/wire-api/src/Wire/API/Error/Galley.hs index 65596d70fa..782c02e023 100644 --- a/libs/wire-api/src/Wire/API/Error/Galley.hs +++ b/libs/wire-api/src/Wire/API/Error/Galley.hs @@ -31,8 +31,7 @@ where import Control.Lens ((%~)) import Data.Aeson (FromJSON (..), ToJSON (..)) -import Data.Singletons.CustomStar (genSingletons) -import Data.Singletons.Prelude (Show_) +import Data.Singletons.TH (genSingletons) import qualified Data.Swagger as S import Data.Tagged import GHC.TypeLits @@ -40,6 +39,7 @@ import Imports import qualified Network.Wai.Utilities.Error as Wai import Polysemy import Polysemy.Error +import Prelude.Singletons (Show_) import Wire.API.Conversation.Role import Wire.API.Error import qualified Wire.API.Error.Brig as BrigError diff --git a/libs/wire-api/src/Wire/API/MLS/Extension.hs b/libs/wire-api/src/Wire/API/MLS/Extension.hs index 406adfa7e8..5093398adf 100644 --- a/libs/wire-api/src/Wire/API/MLS/Extension.hs +++ b/libs/wire-api/src/Wire/API/MLS/Extension.hs @@ -44,6 +44,7 @@ module Wire.API.MLS.Extension where import Data.Binary +import Data.Kind import Data.Singletons.TH import Data.Time.Clock.POSIX import Imports @@ -86,7 +87,7 @@ data ExtensionTag $(genSingletons [''ExtensionTag]) -type family ExtensionType (t :: ExtensionTag) :: * where +type family ExtensionType (t :: ExtensionTag) :: Type where ExtensionType 'CapabilitiesExtensionTag = Capabilities ExtensionType 'LifetimeExtensionTag = Lifetime diff --git a/libs/wire-api/src/Wire/API/MLS/Message.hs b/libs/wire-api/src/Wire/API/MLS/Message.hs index 2393aa06e2..c70f736bfb 100644 --- a/libs/wire-api/src/Wire/API/MLS/Message.hs +++ b/libs/wire-api/src/Wire/API/MLS/Message.hs @@ -49,8 +49,8 @@ import Data.Binary import Data.Binary.Get import Data.Binary.Put import qualified Data.ByteArray as BA --- import qualified Data.ByteString as BS import Data.Json.Util +import Data.Kind import Data.Schema import Data.Singletons.TH import qualified Data.Swagger as S @@ -74,7 +74,7 @@ $(genSingletons [''WireFormatTag]) instance ParseMLS WireFormatTag where parseMLS = parseMLSEnum @Word8 "wire format" -data family MessageExtraFields (tag :: WireFormatTag) :: * +data family MessageExtraFields (tag :: WireFormatTag) :: Type data instance MessageExtraFields 'MLSPlainText = MessageExtraFields { msgSignature :: ByteString, @@ -226,7 +226,7 @@ instance ParseMLS SomeMessage where MLSPlainText -> SomeMessage SMLSPlainText <$> parseMLS MLSCipherText -> SomeMessage SMLSCipherText <$> parseMLS -data family Sender (tag :: WireFormatTag) :: * +data family Sender (tag :: WireFormatTag) :: Type data instance Sender 'MLSCipherText = EncryptedSender {esData :: ByteString} deriving (Eq, Show) @@ -268,7 +268,7 @@ instance SerialiseMLS (Sender 'MLSPlainText) where put x serialiseMLS NewMemberSender = serialiseMLS NewMemberSenderTag -data family MessagePayload (tag :: WireFormatTag) :: * +data family MessagePayload (tag :: WireFormatTag) :: Type deriving instance Eq (MessagePayload 'MLSPlainText) diff --git a/libs/wire-api/src/Wire/API/MLS/Serialisation.hs b/libs/wire-api/src/Wire/API/MLS/Serialisation.hs index 3e99b33cfb..0881c31773 100644 --- a/libs/wire-api/src/Wire/API/MLS/Serialisation.hs +++ b/libs/wire-api/src/Wire/API/MLS/Serialisation.hs @@ -58,6 +58,7 @@ import Data.Binary.Put import qualified Data.ByteString as BS import qualified Data.ByteString.Lazy as LBS import Data.Json.Util +import Data.Kind import Data.Proxy import Data.Schema import qualified Data.Swagger as S @@ -125,7 +126,7 @@ serialiseMLSOptional p (Just x) = do -- corresponding enumeration index. This makes it possible to parse enumeration -- types that don't contain an explicit constructor for a "reserved" value. parseMLSEnum :: - forall (w :: *) a. + forall (w :: Type) a. (Bounded a, Enum a, Integral w, Binary w) => String -> Get a diff --git a/libs/wire-api/src/Wire/API/MakesFederatedCall.hs b/libs/wire-api/src/Wire/API/MakesFederatedCall.hs index a6abb32dc0..78de951841 100644 --- a/libs/wire-api/src/Wire/API/MakesFederatedCall.hs +++ b/libs/wire-api/src/Wire/API/MakesFederatedCall.hs @@ -27,6 +27,7 @@ where import Data.Aeson (Value (..)) import Data.Constraint +import Data.Kind import Data.Metrics.Servant import Data.Proxy import Data.Swagger.Operation (addExtensions) @@ -72,7 +73,7 @@ synthesizeCallsFed = unsafeCoerce $ Dict @Nullary -- constraints on handlers. data MakesFederatedCall (comp :: Component) (name :: Symbol) -instance (HasServer api ctx) => HasServer (MakesFederatedCall comp name :> api :: *) ctx where +instance (HasServer api ctx) => HasServer (MakesFederatedCall comp name :> api :: Type) ctx where -- \| This should have type @CallsFed comp name => ServerT api m@, but GHC -- complains loudly thinking this is a polytype. We need to introduce the -- 'CallsFed' constraint so that we can eliminate it via @@ -82,11 +83,11 @@ instance (HasServer api ctx) => HasServer (MakesFederatedCall comp name :> api : route _ ctx f = route (Proxy @api) ctx $ fmap ($ synthesizeCallsFed @comp @name) f hoistServerWithContext _ ctx f s = hoistServerWithContext (Proxy @api) ctx f . s -instance HasLink api => HasLink (MakesFederatedCall comp name :> api :: *) where +instance HasLink api => HasLink (MakesFederatedCall comp name :> api :: Type) where type MkLink (MakesFederatedCall comp name :> api) x = MkLink api x toLink f _ l = toLink f (Proxy @api) l -instance RoutesToPaths api => RoutesToPaths (MakesFederatedCall comp name :> api :: *) where +instance RoutesToPaths api => RoutesToPaths (MakesFederatedCall comp name :> api :: Type) where getRoutes = getRoutes @api -- | Get a symbol representation of our component. @@ -97,7 +98,7 @@ type family ShowComponent (x :: Component) :: Symbol where -- | 'MakesFederatedCall' annotates the swagger documentation with an extension -- tag @x-wire-makes-federated-calls-to@. -instance (HasSwagger api, KnownSymbol name, KnownSymbol (ShowComponent comp)) => HasSwagger (MakesFederatedCall comp name :> api :: *) where +instance (HasSwagger api, KnownSymbol name, KnownSymbol (ShowComponent comp)) => HasSwagger (MakesFederatedCall comp name :> api :: Type) where toSwagger _ = toSwagger (Proxy @api) & addExtensions @@ -116,7 +117,7 @@ mergeJSONArray :: Value -> Value -> Value mergeJSONArray (Array x) (Array y) = Array $ x <> y mergeJSONArray _ _ = error "impossible! bug in construction of federated calls JSON" -instance HasClient m api => HasClient m (MakesFederatedCall comp name :> api :: *) where +instance HasClient m api => HasClient m (MakesFederatedCall comp name :> api :: Type) where type Client m (MakesFederatedCall comp name :> api) = Client m api clientWithRoute p _ = clientWithRoute p $ Proxy @api hoistClientMonad p _ f c = hoistClientMonad p (Proxy @api) f c diff --git a/libs/wire-api/src/Wire/API/Provider/Service/Tag.hs b/libs/wire-api/src/Wire/API/Provider/Service/Tag.hs index 60be42a427..555c5fa31a 100644 --- a/libs/wire-api/src/Wire/API/Provider/Service/Tag.hs +++ b/libs/wire-api/src/Wire/API/Provider/Service/Tag.hs @@ -44,10 +44,11 @@ import qualified Data.Aeson as JSON import qualified Data.ByteString.Builder as BB import qualified Data.ByteString.Char8 as C8 import Data.ByteString.Conversion -import Data.Range (LTE, Range, fromRange) +import Data.Range (Range, fromRange) import qualified Data.Range as Range import qualified Data.Set as Set import qualified Data.Text.Encoding as Text +import Data.Type.Ord import GHC.TypeLits (KnownNat, Nat) import Imports import Wire.Arbitrary (Arbitrary (..), GenericUniform (..)) @@ -180,10 +181,10 @@ newtype QueryAnyTags (m :: Nat) (n :: Nat) = QueryAnyTags {queryAnyTagsRange :: Range m n (Set (QueryAllTags m n))} deriving stock (Eq, Show, Ord) -instance (KnownNat m, KnownNat n, LTE m n) => Arbitrary (QueryAnyTags m n) where +instance (KnownNat m, KnownNat n, m <= n) => Arbitrary (QueryAnyTags m n) where arbitrary = QueryAnyTags <$> arbitrary -queryAnyTags :: LTE m n => MatchAny -> Maybe (QueryAnyTags m n) +queryAnyTags :: (KnownNat m, KnownNat n, m <= n) => MatchAny -> Maybe (QueryAnyTags m n) queryAnyTags t = do x <- mapM queryAllTags (Set.toList (matchAnySet t)) QueryAnyTags <$> Range.checked (Set.fromList x) @@ -199,7 +200,7 @@ instance ToByteString (QueryAnyTags m n) where . queryAnyTagsRange -- | QueryAny ::= QueryAll { "," QueryAll } -instance LTE m n => FromByteString (QueryAnyTags m n) where +instance (KnownNat n, KnownNat m, m <= n) => FromByteString (QueryAnyTags m n) where parser = do bs <- C8.split ',' <$> parser ts <- mapM (either fail pure . runParser parser) bs @@ -211,10 +212,10 @@ newtype QueryAllTags (m :: Nat) (n :: Nat) = QueryAllTags {queryAllTagsRange :: Range m n (Set ServiceTag)} deriving stock (Eq, Show, Ord) -instance (KnownNat m, KnownNat n, LTE m n) => Arbitrary (QueryAllTags m n) where +instance (KnownNat m, KnownNat n, m <= n) => Arbitrary (QueryAllTags m n) where arbitrary = QueryAllTags <$> arbitrary -queryAllTags :: LTE m n => MatchAll -> Maybe (QueryAllTags m n) +queryAllTags :: (KnownNat m, KnownNat n, m <= n) => MatchAll -> Maybe (QueryAllTags m n) queryAllTags = fmap QueryAllTags . Range.checked . matchAllSet -- | QueryAll ::= tag { "." tag } @@ -228,7 +229,7 @@ instance ToByteString (QueryAllTags m n) where . queryAllTagsRange -- | QueryAll ::= tag { "." tag } -instance LTE m n => FromByteString (QueryAllTags m n) where +instance (KnownNat m, KnownNat n, m <= n) => FromByteString (QueryAllTags m n) where parser = do bs <- C8.split '.' <$> parser ts <- mapM (either fail pure . runParser parser) bs diff --git a/libs/wire-api/src/Wire/API/Routes/Cookies.hs b/libs/wire-api/src/Wire/API/Routes/Cookies.hs index af51f950b6..3feadafb10 100644 --- a/libs/wire-api/src/Wire/API/Routes/Cookies.hs +++ b/libs/wire-api/src/Wire/API/Routes/Cookies.hs @@ -17,6 +17,7 @@ module Wire.API.Routes.Cookies where +import Data.Kind import Data.List.NonEmpty (NonEmpty (..)) import qualified Data.Map as M import Data.Metrics.Servant @@ -42,12 +43,12 @@ data (:::) a b -- @@ -- results in a cookie with name "foo" containing a 64-bit integer, and a -- cookie with name "bar" containing an arbitrary text value. -data Cookies (cs :: [*]) +data Cookies (cs :: [Type]) type CookieHeader cs = Header "Cookie" (CookieTuple cs) -- CookieTypes = map snd -type family CookieTypes (cs :: [*]) :: [*] +type family CookieTypes (cs :: [Type]) :: [Type] type instance CookieTypes '[] = '[] @@ -60,9 +61,9 @@ type CookieMap = Map ByteString (NonEmpty ByteString) instance HasSwagger api => HasSwagger (Cookies cs :> api) where toSwagger _ = toSwagger (Proxy @api) -class CookieArgs (cs :: [*]) where +class CookieArgs (cs :: [Type]) where -- example: AddArgs ["foo" :: Foo, "bar" :: Bar] a = Foo -> Bar -> a - type AddArgs cs a :: * + type AddArgs cs a :: Type uncurryArgs :: AddArgs cs a -> CookieTuple cs -> a mapArgs :: (a -> b) -> AddArgs cs a -> AddArgs cs b @@ -81,7 +82,7 @@ instance KnownSymbol label, FromHttpApiData x ) => - CookieArgs ((label ::: (x :: *)) ': cs) + CookieArgs ((label ::: (x :: Type)) ': cs) where type AddArgs ((label ::: x) ': cs) a = [Either Text x] -> AddArgs cs a uncurryArgs f (CookieTuple (I x :* xs)) = uncurryArgs @cs (f x) (CookieTuple xs) diff --git a/libs/wire-api/src/Wire/API/Routes/MultiTablePaging.hs b/libs/wire-api/src/Wire/API/Routes/MultiTablePaging.hs index 4a8f737967..f0b697e059 100644 --- a/libs/wire-api/src/Wire/API/Routes/MultiTablePaging.hs +++ b/libs/wire-api/src/Wire/API/Routes/MultiTablePaging.hs @@ -62,7 +62,7 @@ data GetMultiTablePageRequest (name :: Symbol) (tables :: Type) (max :: Nat) (de -- 24 | deriving ToJSON via Schema (GetMultiTablePageRequest name tables max def) -- | ^^^^^^ -type RequestSchemaConstraint name tables max def = (KnownNat max, KnownNat def, Within Int32 1 max, LTE 1 def, LTE def max, PagingTable tables, KnownSymbol name) +type RequestSchemaConstraint name tables max def = (KnownNat max, KnownNat def, Within Int32 1 max, 1 <= def, def <= max, PagingTable tables, KnownSymbol name) deriving via Schema (GetMultiTablePageRequest name tables max def) diff --git a/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs b/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs index e8d79bee60..8d1fa53d2a 100644 --- a/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs +++ b/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs @@ -19,7 +19,7 @@ -- with this program. If not, see . module Wire.API.Routes.MultiVerb - ( -- * MultiVerb types + ( -- Type MultiVerb types MultiVerb, MultiVerb1, Respond, @@ -58,6 +58,7 @@ import Data.Containers.ListUtils import Data.Either.Combinators (leftToMaybe) import Data.HashMap.Strict.InsOrd (InsOrdHashMap) import qualified Data.HashMap.Strict.InsOrd as InsOrdHashMap +import Data.Kind import Data.Metrics.Servant import Data.Proxy import Data.SOP @@ -94,13 +95,13 @@ type Declare = S.Declare (S.Definitions S.Schema) -- Includes status code, description, and return type. The content type of the -- response is determined dynamically using the accept header and the list of -- supported content types specified in the containing 'MultiVerb' type. -data Respond (s :: Nat) (desc :: Symbol) (a :: *) +data Respond (s :: Nat) (desc :: Symbol) (a :: Type) -- | A type to describe a 'MultiVerb' response with a fixed content type. -- -- Similar to 'Respond', but hardcodes the content type to be used for -- generating the response. -data RespondAs ct (s :: Nat) (desc :: Symbol) (a :: *) +data RespondAs ct (s :: Nat) (desc :: Symbol) (a :: Type) -- | A type to describe a 'MultiVerb' response with an empty body. -- @@ -111,7 +112,7 @@ type RespondEmpty s desc = RespondAs '() s desc () -- -- Includes status code, description, framing strategy and content type. Note -- that the handler return type is hardcoded to be 'SourceIO ByteString'. -data RespondStreaming (s :: Nat) (desc :: Symbol) (framing :: *) (ct :: *) +data RespondStreaming (s :: Nat) (desc :: Symbol) (framing :: Type) (ct :: Type) -- | The result of parsing a response as a union alternative of type 'a'. -- @@ -151,11 +152,11 @@ instance MonadPlus UnrenderResult where class IsSwaggerResponse a where responseSwagger :: Declare S.Response -type family ResponseType a :: * +type family ResponseType a :: Type class IsWaiBody (ResponseBody a) => IsResponse cs a where type ResponseStatus a :: Nat - type ResponseBody a :: * + type ResponseBody a :: Type responseRender :: AcceptHeader -> ResponseType a -> Maybe (ResponseF (ResponseBody a)) responseUnrender :: M.MediaType -> ResponseF (ResponseBody a) -> UnrenderResult (ResponseType a) @@ -211,7 +212,7 @@ instance MimeRender ct a, MimeUnrender ct a ) => - IsResponse cs (RespondAs (ct :: *) s desc a) + IsResponse cs (RespondAs (ct :: Type) s desc a) where type ResponseStatus (RespondAs ct s desc a) = s type ResponseBody (RespondAs ct s desc a) = LByteString @@ -248,7 +249,7 @@ instance KnownStatus s => IsResponse cs (RespondAs '() s desc ()) where instance (KnownSymbol desc, S.ToSchema a) => - IsSwaggerResponse (RespondAs (ct :: *) s desc a) + IsSwaggerResponse (RespondAs (ct :: Type) s desc a) where responseSwagger = simpleResponseSwagger @a @desc @@ -294,7 +295,7 @@ instance (KnownStatus s, KnownSymbol desc) => IsSwaggerResponse (RespondStreamin -- * @hs@: type-level list of headers -- * @a@: return type (with headers) -- * @r@: underlying response (without headers) -data WithHeaders (hs :: [*]) (a :: *) (r :: *) +data WithHeaders (hs :: [Type]) (a :: Type) (r :: Type) -- | This is used to convert a response containing headers to a custom type -- including the information in the headers. @@ -312,7 +313,7 @@ instance AsHeaders '[h] a (a, h) where toHeaders (t, cc) = (I cc :* Nil, t) fromHeaders (I cc :* Nil, t) = (t, cc) -data DescHeader (name :: Symbol) (desc :: Symbol) (a :: *) +data DescHeader (name :: Symbol) (desc :: Symbol) (a :: Type) -- | A wrapper to turn a response header into an optional one. data OptHeader h @@ -425,7 +426,7 @@ instance class IsSwaggerResponseList as where responseListSwagger :: Declare (InsOrdHashMap S.HttpStatusCode S.Response) -type family ResponseTypes (as :: [*]) where +type family ResponseTypes (as :: [Type]) where ResponseTypes '[] = '[] ResponseTypes (a ': as) = ResponseType a ': ResponseTypes as @@ -501,7 +502,7 @@ combineSwaggerSchema s1 s2 -- instance. -- * Headers can be attached to individual responses, also without affecting -- the handler return type. -data MultiVerb (method :: StdMethod) cs (as :: [*]) (r :: *) +data MultiVerb (method :: StdMethod) cs (as :: [Type]) (r :: Type) -- | A 'MultiVerb' endpoint with a single response. type MultiVerb1 m cs a = MultiVerb m cs '[a] (ResponseType a) @@ -512,7 +513,7 @@ type MultiVerb1 m cs a = MultiVerb m cs '[a] (ResponseType a) -- Any glue code necessary to convert application types to and from the -- canonical 'Union' type corresponding to a 'MultiVerb' endpoint should be -- packaged into an 'AsUnion' instance. -class AsUnion (as :: [*]) (r :: *) where +class AsUnion (as :: [Type]) (r :: Type) where toUnion :: r -> Union (ResponseTypes as) fromUnion :: Union (ResponseTypes as) -> r @@ -622,7 +623,7 @@ instance AsConstructor '[a] (Respond code desc a) where toConstructor x = I x :* Nil fromConstructor = unI . hd -instance AsConstructor '[a] (RespondAs (ct :: *) code desc a) where +instance AsConstructor '[a] (RespondAs (ct :: Type) code desc a) where toConstructor x = I x :* Nil fromConstructor = unI . hd @@ -718,7 +719,7 @@ instance instance (SwaggerMethod method, IsSwaggerResponseList as, AllMime cs) => - S.HasSwagger (MultiVerb method (cs :: [*]) as r) + S.HasSwagger (MultiVerb method (cs :: [Type]) as r) where toSwagger _ = mempty diff --git a/libs/wire-api/src/Wire/API/Routes/Named.hs b/libs/wire-api/src/Wire/API/Routes/Named.hs index df29b1a53b..fd5c3f5313 100644 --- a/libs/wire-api/src/Wire/API/Routes/Named.hs +++ b/libs/wire-api/src/Wire/API/Routes/Named.hs @@ -17,6 +17,7 @@ module Wire.API.Routes.Named where +import Data.Kind import Data.Metrics.Servant import Data.Proxy import GHC.TypeLits @@ -51,7 +52,7 @@ instance HasClient m api => HasClient m (Named n api) where clientWithRoute pm _ req = clientWithRoute pm (Proxy @api) req hoistClientMonad pm _ f = hoistClientMonad pm (Proxy @api) f -type family FindName n (api :: *) :: (n, *) where +type family FindName n (api :: Type) :: (n, Type) where FindName n (Named name api) = '(name, api) FindName n (x :> api) = AddPrefix x (FindName n api) FindName n api = '(TypeError ('Text "Named combinator not found"), api) @@ -89,7 +90,7 @@ type family FMap (f :: a -> b) (m :: Maybe a) :: Maybe b where FMap _ 'Nothing = 'Nothing FMap f ('Just a) = 'Just (f a) -type family LookupEndpoint api name :: Maybe (*) where +type family LookupEndpoint api name :: Maybe Type where LookupEndpoint (Named name endpoint) name = 'Just endpoint LookupEndpoint (api1 :<|> api2) name = MappendMaybe diff --git a/libs/wire-api/src/Wire/API/Routes/Public.hs b/libs/wire-api/src/Wire/API/Routes/Public.hs index deff0d727c..cdd0b835ba 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public.hs @@ -40,6 +40,7 @@ import Control.Lens ((<>~)) import Data.Domain import qualified Data.HashMap.Strict.InsOrd as InsOrdHashMap import Data.Id as Id +import Data.Kind import Data.Metrics.Servant import Data.Qualified import Data.Swagger @@ -87,8 +88,8 @@ class IsZType (ztype :: ZType) ctx where type ZHeader ztype :: Symbol - type ZParam ztype :: * - type ZQualifiedParam ztype :: * + type ZParam ztype :: Type + type ZQualifiedParam ztype :: Type qualifyZParam :: Context ctx -> ZParam ztype -> ZQualifiedParam ztype @@ -154,7 +155,7 @@ instance IsZType 'ZAuthProvider ctx where instance HasTokenType 'ZAuthProvider where tokenType = Just "provider" -data ZAuthServant (ztype :: ZType) (opts :: [*]) +data ZAuthServant (ztype :: ZType) (opts :: [Type]) type InternalAuthDefOpts = '[Servant.Required, Servant.Strict] diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Cargohold.hs b/libs/wire-api/src/Wire/API/Routes/Public/Cargohold.hs index f31683711f..b4ea06f2bb 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public/Cargohold.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public/Cargohold.hs @@ -18,6 +18,7 @@ module Wire.API.Routes.Public.Cargohold where import Data.Id +import Data.Kind import Data.Metrics.Servant import Data.Qualified import Data.SOP @@ -40,7 +41,7 @@ import Wire.API.Routes.Version data PrincipalTag = UserPrincipalTag | BotPrincipalTag | ProviderPrincipalTag deriving (Eq, Show) -type family PrincipalId (tag :: PrincipalTag) = (id :: *) | id -> tag where +type family PrincipalId (tag :: PrincipalTag) = (id :: Type) | id -> tag where PrincipalId 'UserPrincipalTag = Local UserId PrincipalId 'BotPrincipalTag = BotId PrincipalId 'ProviderPrincipalTag = ProviderId diff --git a/libs/wire-api/src/Wire/API/Routes/QualifiedCapture.hs b/libs/wire-api/src/Wire/API/Routes/QualifiedCapture.hs index 6356821b5d..ffbea77172 100644 --- a/libs/wire-api/src/Wire/API/Routes/QualifiedCapture.hs +++ b/libs/wire-api/src/Wire/API/Routes/QualifiedCapture.hs @@ -22,6 +22,7 @@ module Wire.API.Routes.QualifiedCapture where import Data.Domain +import Data.Kind import Data.Metrics.Servant import Data.Qualified import Data.Swagger @@ -35,7 +36,7 @@ import Servant.Server.Internal.ErrorFormatter import Servant.Swagger -- | Capture a value qualified by a domain, with modifiers. -data QualifiedCapture' (mods :: [*]) (capture :: Symbol) (a :: *) +data QualifiedCapture' (mods :: [Type]) (capture :: Symbol) (a :: Type) -- | Capture a value qualified by a domain. -- diff --git a/libs/wire-api/src/Wire/API/Routes/Versioned.hs b/libs/wire-api/src/Wire/API/Routes/Versioned.hs index bb9dcf766a..ead87a48dc 100644 --- a/libs/wire-api/src/Wire/API/Routes/Versioned.hs +++ b/libs/wire-api/src/Wire/API/Routes/Versioned.hs @@ -18,6 +18,7 @@ module Wire.API.Routes.Versioned where import Data.Aeson (FromJSON, ToJSON) +import Data.Kind import Data.Metrics.Servant import Data.Schema import Data.Singletons @@ -34,7 +35,7 @@ import Wire.API.Routes.Version -------------------------------------- -- Versioned requests -data VersionedReqBody' v (mods :: [*]) (ct :: [*]) (a :: *) +data VersionedReqBody' v (mods :: [Type]) (ct :: [Type]) (a :: Type) type VersionedReqBody v = VersionedReqBody' v '[Required, Strict] @@ -69,7 +70,7 @@ instance -------------------------------------------------------------------------------- -- Versioned responses -data VersionedRespond v (s :: Nat) (desc :: Symbol) (a :: *) +data VersionedRespond v (s :: Nat) (desc :: Symbol) (a :: Type) type instance ResponseType (VersionedRespond v s desc a) = a diff --git a/libs/wire-api/src/Wire/API/Team/Feature.hs b/libs/wire-api/src/Wire/API/Team/Feature.hs index a7d74ad034..c63f37c51c 100644 --- a/libs/wire-api/src/Wire/API/Team/Feature.hs +++ b/libs/wire-api/src/Wire/API/Team/Feature.hs @@ -96,6 +96,7 @@ import qualified Data.ByteString.UTF8 as UTF8 import Data.Domain (Domain) import Data.Either.Extra (maybeToEither) import Data.Id +import Data.Kind import Data.Proxy import Data.Schema import Data.Scientific (toBoundedInteger) @@ -184,7 +185,7 @@ featureNameBS = UTF8.fromString $ symbolVal (Proxy @(FeatureSymbol cfg)) ---------------------------------------------------------------------- -- WithStatusBase -data WithStatusBase (m :: * -> *) (cfg :: *) = WithStatusBase +data WithStatusBase (m :: Type -> Type) (cfg :: Type) = WithStatusBase { wsbStatus :: m FeatureStatus, wsbLockStatus :: m LockStatus, wsbConfig :: m cfg, @@ -223,7 +224,7 @@ setConfig c (WithStatusBase s ls _ ttl) = WithStatusBase s ls (Identity c) ttl setWsTTL :: FeatureTTL -> WithStatus cfg -> WithStatus cfg setWsTTL ttl (WithStatusBase s ls c _) = WithStatusBase s ls c (Identity ttl) -type WithStatus (cfg :: *) = WithStatusBase Identity cfg +type WithStatus (cfg :: Type) = WithStatusBase Identity cfg deriving instance (Eq cfg) => Eq (WithStatus cfg) @@ -267,7 +268,7 @@ withStatusModel = ---------------------------------------------------------------------- -- WithStatusPatch -type WithStatusPatch (cfg :: *) = WithStatusBase Maybe cfg +type WithStatusPatch (cfg :: Type) = WithStatusBase Maybe cfg deriving instance (Eq cfg) => Eq (WithStatusPatch cfg) @@ -325,7 +326,7 @@ instance (Arbitrary cfg, IsFeatureConfig cfg) => Arbitrary (WithStatusPatch cfg) -- if we switch to `unlocked`, we auto-enable the feature, and if we switch to locked, we -- auto-disable it. But we need to change the API to force clients to use `lockStatus` -- instead of `status`, current behavior is just wrong. -data WithStatusNoLock (cfg :: *) = WithStatusNoLock +data WithStatusNoLock (cfg :: Type) = WithStatusNoLock { wssStatus :: FeatureStatus, wssConfig :: cfg, wssTTL :: FeatureTTL @@ -543,7 +544,7 @@ instance ToSchema LockStatusResponse where LockStatusResponse <$> _unlockStatus .= field "lockStatus" schema -newtype ImplicitLockStatus (cfg :: *) = ImplicitLockStatus {_unImplicitLockStatus :: WithStatus cfg} +newtype ImplicitLockStatus (cfg :: Type) = ImplicitLockStatus {_unImplicitLockStatus :: WithStatus cfg} deriving newtype (Eq, Show, Arbitrary) instance (IsFeatureConfig a, ToSchema a) => ToJSON (ImplicitLockStatus a) where diff --git a/libs/wire-api/src/Wire/API/Team/Member.hs b/libs/wire-api/src/Wire/API/Team/Member.hs index e573a0658e..2fc27f12d5 100644 --- a/libs/wire-api/src/Wire/API/Team/Member.hs +++ b/libs/wire-api/src/Wire/API/Team/Member.hs @@ -71,6 +71,7 @@ import Data.Aeson (FromJSON (..), ToJSON (..), Value (..)) import qualified Data.ByteString.Lazy as LBS import Data.Id (UserId) import Data.Json.Util +import Data.Kind import Data.LegalHold (UserLegalHoldStatus (..), defUserLegalHoldStatus) import Data.Misc (PlainTextPassword (..)) import Data.Proxy @@ -86,7 +87,7 @@ import Wire.Arbitrary (Arbitrary, GenericUniform (..)) data PermissionTag = Required | Optional -type family PermissionType (tag :: PermissionTag) = (t :: *) | t -> tag where +type family PermissionType (tag :: PermissionTag) = (t :: Type) | t -> tag where PermissionType 'Required = Permissions PermissionType 'Optional = Maybe Permissions diff --git a/libs/wire-api/src/Wire/API/Team/Permission.hs b/libs/wire-api/src/Wire/API/Team/Permission.hs index 4b5c780235..98f983b1b3 100644 --- a/libs/wire-api/src/Wire/API/Team/Permission.hs +++ b/libs/wire-api/src/Wire/API/Team/Permission.hs @@ -53,7 +53,7 @@ import Data.Aeson (FromJSON (..), ToJSON (..)) import Data.Bits (testBit, (.|.)) import Data.Schema import qualified Data.Set as Set -import Data.Singletons.TH +import Data.Singletons.Base.TH import qualified Data.Swagger as S import qualified Data.Swagger.Build.Api as Doc import Imports @@ -211,4 +211,5 @@ instance Cql.Cql Permissions where fromCql _ = Left "permissions: udt expected" $(genSingletons [''Perm]) + $(promoteShowInstances [''Perm]) diff --git a/libs/wire-api/src/Wire/API/User.hs b/libs/wire-api/src/Wire/API/User.hs index 08af13b115..1e41a89c9d 100644 --- a/libs/wire-api/src/Wire/API/User.hs +++ b/libs/wire-api/src/Wire/API/User.hs @@ -150,7 +150,7 @@ import qualified Data.Text.Encoding as T import Data.UUID (UUID, nil) import qualified Data.UUID as UUID import Deriving.Swagger -import GHC.TypeLits (KnownNat, Nat) +import GHC.TypeLits import qualified Generics.SOP as GSOP import Imports import qualified SAML2.WebSSO as SAML @@ -226,14 +226,14 @@ newtype LimitedQualifiedUserIdList (max :: Nat) = LimitedQualifiedUserIdList deriving stock (Eq, Show, Generic) deriving (S.ToSchema) via CustomSwagger '[FieldLabelModifier CamelToSnake] (LimitedQualifiedUserIdList max) -instance (KnownNat max, LTE 1 max) => Arbitrary (LimitedQualifiedUserIdList max) where +instance (KnownNat max, 1 <= max) => Arbitrary (LimitedQualifiedUserIdList max) where arbitrary = LimitedQualifiedUserIdList <$> arbitrary -instance LTE 1 max => FromJSON (LimitedQualifiedUserIdList max) where +instance (KnownNat max, 1 <= max) => FromJSON (LimitedQualifiedUserIdList max) where parseJSON = A.withObject "LimitedQualifiedUserIdList" $ \o -> LimitedQualifiedUserIdList <$> o A..: "qualified_users" -instance LTE 1 max => ToJSON (LimitedQualifiedUserIdList max) where +instance 1 <= max => ToJSON (LimitedQualifiedUserIdList max) where toJSON e = A.object ["qualified_users" A..= qualifiedUsers e] -------------------------------------------------------------------------------- diff --git a/libs/wire-api/src/Wire/API/User/Client.hs b/libs/wire-api/src/Wire/API/User/Client.hs index e8b8f0574c..7e757dd420 100644 --- a/libs/wire-api/src/Wire/API/User/Client.hs +++ b/libs/wire-api/src/Wire/API/User/Client.hs @@ -94,7 +94,6 @@ import qualified Data.Map.Strict as Map import Data.Misc (Latitude (..), Location, Longitude (..), PlainTextPassword (..), latitude, location, longitude, modelLocation) import Data.Qualified import Data.Schema -import qualified Data.Semigroup as Semigroup import qualified Data.Set as Set import Data.Swagger hiding (Schema, ToSchema, schema) import qualified Data.Swagger as Swagger @@ -316,7 +315,7 @@ newtype QualifiedUserClientPrekeyMap = QualifiedUserClientPrekeyMap deriving stock (Eq, Show) deriving newtype (Arbitrary) deriving (FromJSON, ToJSON, Swagger.ToSchema) via Schema QualifiedUserClientPrekeyMap - deriving (Semigroup, Monoid) via (QualifiedUserClientMap (Semigroup.Option (Semigroup.First Prekey))) + deriving (Semigroup, Monoid) via (QualifiedUserClientMap (Alt Maybe Prekey)) instance ToSchema QualifiedUserClientPrekeyMap where schema = diff --git a/libs/wire-api/wire-api.cabal b/libs/wire-api/wire-api.cabal index 255c044065..e4edd396aa 100644 --- a/libs/wire-api/wire-api.cabal +++ b/libs/wire-api/wire-api.cabal @@ -266,6 +266,8 @@ library , servant-swagger , servant-swagger-ui , singletons + , singletons-base + , singletons-th , sop-core , string-conversions , swagger >=0.1 From 90e294491cc3d513b10c41ce012c8a5cbfbd98a6 Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Mon, 23 Jan 2023 09:49:58 +0100 Subject: [PATCH 21/35] wire-api-federation: fix compilation --- libs/wire-api-federation/default.nix | 3 +++ libs/wire-api-federation/src/Wire/API/Federation/API.hs | 3 ++- libs/wire-api-federation/src/Wire/API/Federation/Endpoint.hs | 3 ++- libs/wire-api-federation/wire-api-federation.cabal | 2 ++ 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/libs/wire-api-federation/default.nix b/libs/wire-api-federation/default.nix index 3c7d80254e..35d74d4b0c 100644 --- a/libs/wire-api-federation/default.nix +++ b/libs/wire-api-federation/default.nix @@ -37,6 +37,7 @@ , servant-client-core , servant-server , singletons +, singletons-th , sop-core , streaming-commons , swagger2 @@ -83,6 +84,7 @@ mkDerivation { servant-client-core servant-server singletons + singletons-th sop-core streaming-commons swagger2 @@ -128,6 +130,7 @@ mkDerivation { servant-client-core servant-server singletons + singletons-th sop-core streaming-commons swagger2 diff --git a/libs/wire-api-federation/src/Wire/API/Federation/API.hs b/libs/wire-api-federation/src/Wire/API/Federation/API.hs index 7fc6e981b0..8da8dc6601 100644 --- a/libs/wire-api-federation/src/Wire/API/Federation/API.hs +++ b/libs/wire-api-federation/src/Wire/API/Federation/API.hs @@ -29,6 +29,7 @@ module Wire.API.Federation.API ) where +import Data.Kind import Data.Proxy import GHC.TypeLits import Imports @@ -43,7 +44,7 @@ import Wire.API.Routes.Named -- Note: this type family being injective means that in most cases there is no need -- to add component annotations when invoking the federator client -type family FedApi (comp :: Component) = (api :: *) | api -> comp +type family FedApi (comp :: Component) = (api :: Type) | api -> comp type instance FedApi 'Galley = GalleyApi diff --git a/libs/wire-api-federation/src/Wire/API/Federation/Endpoint.hs b/libs/wire-api-federation/src/Wire/API/Federation/Endpoint.hs index 8c6367f249..509e73aa61 100644 --- a/libs/wire-api-federation/src/Wire/API/Federation/Endpoint.hs +++ b/libs/wire-api-federation/src/Wire/API/Federation/Endpoint.hs @@ -21,12 +21,13 @@ module Wire.API.Federation.Endpoint ) where +import Data.Kind import Servant.API import Wire.API.ApplyMods import Wire.API.Federation.Domain import Wire.API.Routes.Named -type FedEndpointWithMods (mods :: [*]) name input output = +type FedEndpointWithMods (mods :: [Type]) name input output = Named name ( ApplyMods diff --git a/libs/wire-api-federation/wire-api-federation.cabal b/libs/wire-api-federation/wire-api-federation.cabal index 81eae46d30..91c78be795 100644 --- a/libs/wire-api-federation/wire-api-federation.cabal +++ b/libs/wire-api-federation/wire-api-federation.cabal @@ -102,6 +102,7 @@ library , servant-client-core , servant-server , singletons + , singletons-th , sop-core , streaming-commons , swagger2 @@ -214,6 +215,7 @@ test-suite spec , servant-client-core , servant-server , singletons + , singletons-th , sop-core , streaming-commons , swagger2 From 18448d6eb2b13c2ad0178903b3419c1a281e87f3 Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Mon, 23 Jan 2023 09:56:21 +0100 Subject: [PATCH 22/35] polysemy-wire-zoo: fix compilation --- libs/polysemy-wire-zoo/src/Wire/Sem/Paging.hs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libs/polysemy-wire-zoo/src/Wire/Sem/Paging.hs b/libs/polysemy-wire-zoo/src/Wire/Sem/Paging.hs index 2636eae7a9..9648b957df 100644 --- a/libs/polysemy-wire-zoo/src/Wire/Sem/Paging.hs +++ b/libs/polysemy-wire-zoo/src/Wire/Sem/Paging.hs @@ -30,13 +30,14 @@ module Wire.Sem.Paging ) where +import Data.Kind import Imports -type family Page p a :: (page :: *) | page -> p a +type family Page p a :: (page :: Type) | page -> p a -type family PagingState p a = (ps :: *) +type family PagingState p a = (ps :: Type) -type family PagingBounds p a :: * +type family PagingBounds p a :: Type class Paging p where pageItems :: Page p a -> [a] From 73fe69a4635a8e81319cbf4f5db126d24e8b0e0a Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Mon, 23 Jan 2023 15:07:09 +0100 Subject: [PATCH 23/35] imports: dont export Data.List.singleton --- libs/imports/src/Imports.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/imports/src/Imports.hs b/libs/imports/src/Imports.hs index 664fb70fcc..4f5747f410 100644 --- a/libs/imports/src/Imports.hs +++ b/libs/imports/src/Imports.hs @@ -153,7 +153,7 @@ import Data.HashMap.Strict (HashMap) import Data.HashSet (HashSet) import Data.Int -- 'insert' and 'delete' are common in database modules -import Data.List hiding (delete, insert) +import Data.List hiding (delete, insert, singleton) -- Lazy and strict versions are the same import Data.Map (Map) import Data.Maybe From 35329532eff38dc0007db6c4061376472c03dd26 Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Mon, 23 Jan 2023 10:27:07 +0100 Subject: [PATCH 24/35] federator: fix compilation --- services/federator/src/Federator/Response.hs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/federator/src/Federator/Response.hs b/services/federator/src/Federator/Response.hs index 7cc670ad3d..fa71bab276 100644 --- a/services/federator/src/Federator/Response.hs +++ b/services/federator/src/Federator/Response.hs @@ -27,6 +27,7 @@ where import Control.Lens import Control.Monad.Codensity import Data.ByteString.Builder +import Data.Kind import Federator.Discovery import Federator.Env import Federator.Error @@ -55,7 +56,7 @@ import Wire.Sem.Logger.TinyLog defaultHeaders :: [HTTP.Header] defaultHeaders = [("Content-Type", "application/json")] -class ErrorEffects (ee :: [*]) r where +class ErrorEffects (ee :: [Type]) r where type Row ee :: EffectRow runWaiErrors :: Sem (Append (Row ee) r) Wai.Response -> From 11318c71bc0d1f19088be2383340413f186912b5 Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Mon, 23 Jan 2023 11:58:37 +0100 Subject: [PATCH 25/35] galley: fix compilation --- services/galley/default.nix | 3 +++ services/galley/galley.cabal | 2 ++ services/galley/src/Galley/API/LegalHold/Conflicts.hs | 1 + services/galley/src/Galley/API/Push.hs | 5 ----- services/galley/src/Galley/API/Teams/Features.hs | 10 +++++----- services/galley/src/Galley/Effects/TeamFeatureStore.hs | 4 ++-- services/galley/src/Galley/Validation.hs | 5 +++-- .../galley/test/integration/API/Federation/Util.hs | 3 ++- services/galley/test/integration/API/Teams.hs | 4 ++-- services/galley/test/integration/API/Util.hs | 6 ++++-- 10 files changed, 24 insertions(+), 19 deletions(-) diff --git a/services/galley/default.nix b/services/galley/default.nix index 6b48dee10b..812fc3e7aa 100644 --- a/services/galley/default.nix +++ b/services/galley/default.nix @@ -86,6 +86,7 @@ , servant-swagger , servant-swagger-ui , singletons +, singletons-th , sop-core , split , ssl-util @@ -206,6 +207,7 @@ mkDerivation { servant-swagger servant-swagger-ui singletons + singletons-th sop-core split ssl-util @@ -307,6 +309,7 @@ mkDerivation { servant-server servant-swagger singletons + singletons-th sop-core ssl-util string-conversions diff --git a/services/galley/galley.cabal b/services/galley/galley.cabal index 955c3ac159..cba743b719 100644 --- a/services/galley/galley.cabal +++ b/services/galley/galley.cabal @@ -257,6 +257,7 @@ library , servant-swagger , servant-swagger-ui , singletons + , singletons-th , sop-core , split >=0.2 , ssl-util >=0.1 @@ -503,6 +504,7 @@ executable galley-integration , servant-server , servant-swagger , singletons + , singletons-th , sop-core , ssl-util , string-conversions diff --git a/services/galley/src/Galley/API/LegalHold/Conflicts.hs b/services/galley/src/Galley/API/LegalHold/Conflicts.hs index f9e3e07126..dfcda4e1c9 100644 --- a/services/galley/src/Galley/API/LegalHold/Conflicts.hs +++ b/services/galley/src/Galley/API/LegalHold/Conflicts.hs @@ -14,6 +14,7 @@ -- -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . +{-# OPTIONS_GHC -Wno-overlapping-patterns #-} module Galley.API.LegalHold.Conflicts where diff --git a/services/galley/src/Galley/API/Push.hs b/services/galley/src/Galley/API/Push.hs index 1e17062e67..73bc8aed6a 100644 --- a/services/galley/src/Galley/API/Push.hs +++ b/services/galley/src/Galley/API/Push.hs @@ -46,7 +46,6 @@ import Galley.Data.Services import Galley.Effects.ExternalAccess import Galley.Effects.GundeckAccess hiding (Push) import Galley.Intra.Push -import Galley.Types.Conversations.Members import Gundeck.Types.Push.V2 (RecipientClients (..)) import Imports import Polysemy @@ -83,10 +82,6 @@ newBotPush b e = NormalMessagePush {userPushes = mempty, botPushes = pure (b, e) type BotMap = Map UserId BotMember -type family LocalMemberMap (t :: MessageType) = (m :: *) | m -> t where - LocalMemberMap 'NormalMessage = Map UserId LocalMember - LocalMemberMap 'Broadcast = () - type family MessagePushEffects (t :: MessageType) :: [Effect] type instance MessagePushEffects 'NormalMessage = '[ExternalAccess, GundeckAccess, TinyLog] diff --git a/services/galley/src/Galley/API/Teams/Features.hs b/services/galley/src/Galley/API/Teams/Features.hs index be179c9c99..10a30bce7b 100644 --- a/services/galley/src/Galley/API/Teams/Features.hs +++ b/services/galley/src/Galley/API/Teams/Features.hs @@ -40,7 +40,7 @@ import Control.Lens import Data.Bifunctor (second) import Data.ByteString.Conversion (toByteString') import Data.Id -import Data.Kind (Constraint) +import Data.Kind import Data.Proxy (Proxy (Proxy)) import Data.Qualified (Local, tUnqualified) import Data.Schema @@ -86,7 +86,7 @@ import Wire.Sem.Paging.Cassandra data DoAuth = DoAuth UserId | DontDoAuth -- | Don't export methods of this typeclass -class GetFeatureConfig (db :: *) cfg where +class GetFeatureConfig (db :: Type) cfg where type GetConfigForTeamConstraints db cfg (r :: EffectRow) :: Constraint type GetConfigForTeamConstraints db cfg (r :: EffectRow) = (FeaturePersistentConstraint db cfg, Members '[Input Opts, TeamFeatureStore db] r) @@ -143,7 +143,7 @@ class GetFeatureConfig (db :: *) cfg where getConfigForUser = genericGetConfigForUser @db -- | Don't export methods of this typeclass -class GetFeatureConfig (db :: *) cfg => SetFeatureConfig (db :: *) cfg where +class GetFeatureConfig (db :: Type) cfg => SetFeatureConfig (db :: Type) cfg where type SetConfigForTeamConstraints db cfg (r :: EffectRow) :: Constraint type SetConfigForTeamConstraints db cfg (r :: EffectRow) = () @@ -338,7 +338,7 @@ updateLockStatus tid lockStatus = do -- Here we explicitly return the team setting if the user is a team member. -- In `getConfigForUser` this is mostly also the case. But there are exceptions, e.g. `ConferenceCallingConfig` getFeatureStatusForUser :: - forall (db :: *) cfg r. + forall (db :: Type) cfg r. ( Members '[ ErrorS 'NotATeamMember, ErrorS OperationDenied, @@ -572,7 +572,7 @@ genericGetConfigForUser uid = do genericGetConfigForTeam @db tid persistAndPushEvent :: - forall (db :: *) cfg r. + forall (db :: Type) cfg r. ( IsFeatureConfig cfg, KnownSymbol (FeatureSymbol cfg), ToSchema cfg, diff --git a/services/galley/src/Galley/Effects/TeamFeatureStore.hs b/services/galley/src/Galley/Effects/TeamFeatureStore.hs index 78ca78b8b1..86ea0ed352 100644 --- a/services/galley/src/Galley/Effects/TeamFeatureStore.hs +++ b/services/galley/src/Galley/Effects/TeamFeatureStore.hs @@ -29,13 +29,13 @@ module Galley.Effects.TeamFeatureStore where import Data.Id -import Data.Kind (Constraint) +import Data.Kind import Data.Proxy import Imports import Polysemy import Wire.API.Team.Feature -type family FeaturePersistentConstraint db :: * -> Constraint +type family FeaturePersistentConstraint db :: Type -> Constraint data TeamFeatureStore db m a where -- the proxy argument makes sure that makeSem below generates type-inference-friendly code diff --git a/services/galley/src/Galley/Validation.hs b/services/galley/src/Galley/Validation.hs index 4ff62e03e2..f87db6df4b 100644 --- a/services/galley/src/Galley/Validation.hs +++ b/services/galley/src/Galley/Validation.hs @@ -28,18 +28,19 @@ where import Control.Lens import Data.Range +import GHC.TypeNats import Galley.API.Error import Galley.Options import Imports import Polysemy import Polysemy.Error -rangeChecked :: (Member (Error InvalidInput) r, Within a n m) => a -> Sem r (Range n m a) +rangeChecked :: (KnownNat n, KnownNat m, Member (Error InvalidInput) r, Within a n m) => a -> Sem r (Range n m a) rangeChecked = either throwErr pure . checkedEither {-# INLINE rangeChecked #-} rangeCheckedMaybe :: - (Member (Error InvalidInput) r, Within a n m) => + (Member (Error InvalidInput) r, KnownNat n, KnownNat m, Within a n m) => Maybe a -> Sem r (Maybe (Range n m a)) rangeCheckedMaybe Nothing = pure Nothing diff --git a/services/galley/test/integration/API/Federation/Util.hs b/services/galley/test/integration/API/Federation/Util.hs index 727a97c4f2..f29d031927 100644 --- a/services/galley/test/integration/API/Federation/Util.hs +++ b/services/galley/test/integration/API/Federation/Util.hs @@ -17,6 +17,7 @@ module API.Federation.Util (mkHandler) where +import Data.Kind import Data.SOP import Data.String.Conversions (cs) import GHC.TypeLits @@ -59,7 +60,7 @@ trivialNamedHandler = Named (trivialHandler @api (symbolVal (Proxy @name))) -- | Generate a servant handler from an incomplete list of handlers of named -- endpoints. -class PartialAPI (api :: *) (hs :: *) where +class PartialAPI (api :: Type) (hs :: Type) where mkHandler :: hs -> Server api instance diff --git a/services/galley/test/integration/API/Teams.hs b/services/galley/test/integration/API/Teams.hs index 72cb13c55b..154d1d8348 100644 --- a/services/galley/test/integration/API/Teams.hs +++ b/services/galley/test/integration/API/Teams.hs @@ -605,7 +605,7 @@ testRemoveBindingTeamMember ownerHasPassword = do mem1 <- Util.addUserToTeam owner tid assertQueue "team member join" $ tUpdate 3 [ownerWithPassword, owner] refreshIndex - Util.connectUsers owner (singleton mext) + Util.connectUsers owner (List1.singleton mext) cid1 <- Util.createTeamConv owner tid [mem1 ^. userId, mext] (Just "blaa") Nothing Nothing when ownerHasPassword $ do -- Deleting from a binding team with empty body is invalid @@ -1987,7 +1987,7 @@ postCryptoBroadcastMessage100OrMaxConns bcast = do where createAndConnectUserWhileLimitNotReached alice remaining acc pk = do (uid, cid) <- randomUserWithClient pk - (r1, r2) <- List1.head <$> connectUsersUnchecked alice (singleton uid) + (r1, r2) <- List1.head <$> connectUsersUnchecked alice (List1.singleton uid) case (statusCode r1, statusCode r2, remaining, acc) of (201, 200, 0, []) -> error "Need to connect with at least 1 user" (201, 200, 0, x : xs) -> pure (x, xs) diff --git a/services/galley/test/integration/API/Util.hs b/services/galley/test/integration/API/Util.hs index adfc6d1b29..ba66f58e6c 100644 --- a/services/galley/test/integration/API/Util.hs +++ b/services/galley/test/integration/API/Util.hs @@ -48,6 +48,7 @@ import qualified Data.Handle as Handle import qualified Data.HashMap.Strict as HashMap import Data.Id import Data.Json.Util hiding ((#)) +import Data.Kind import Data.LegalHold (defUserLegalHoldStatus) import Data.List.NonEmpty (NonEmpty) import Data.List1 as List1 @@ -72,6 +73,7 @@ import Data.UUID.V4 import Federator.MockServer (FederatedRequest (..)) import qualified Federator.MockServer as Mock import GHC.TypeLits (KnownSymbol) +import GHC.TypeNats import Galley.Intra.User (chunkify) import qualified Galley.Options as Opts import qualified Galley.Run as Run @@ -724,7 +726,7 @@ postConvWithRemoteUsers u n = Maybe (Range n m Text) -> Maybe (Range n m Text) + setName :: (KnownNat n, KnownNat m, Within Text n m) => Maybe (Range n m Text) -> Maybe (Range n m Text) setName Nothing = checked "federated gossip" setName x = x @@ -2634,7 +2636,7 @@ type CombinedBrigAndGalleyAPI = FedApi 'Brig :<|> FedApi 'Galley -- Starts a servant Application in Network.Wai.Test session and runs the -- FederatedRequest against it. makeFedRequestToServant :: - forall (api :: *). + forall (api :: Type). HasServer api '[] => Domain -> Server api -> From 7c7f7898f6da4aab2d41b4174db86a192a5cf495 Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Mon, 23 Jan 2023 14:04:17 +0100 Subject: [PATCH 26/35] bloodhound: bump to abf819 --- nix/haskell-pins.nix | 4 ++-- nix/manual-overrides.nix | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/nix/haskell-pins.nix b/nix/haskell-pins.nix index 51b1c1554f..cef97e3a6f 100644 --- a/nix/haskell-pins.nix +++ b/nix/haskell-pins.nix @@ -113,8 +113,8 @@ let bloodhound = { src = fetchgit { url = "https://github.com/wireapp/bloodhound"; - rev = "c68e6d877d87988331bf391ed16780383a58eefa"; - sha256 = "0fr5xgq8f1nmcbk8srrhyf4vad4xm5iqr974jgqfg1mg31y85h0x"; + rev = "abf819a4a6ec7601f1e58cb8da13b2fdad377d9e"; + sha256 = "sha256-m1O+F/mOJN5z5WNChmeyHP4dtmLRkl2YnLlTuwzRelk="; }; }; cryptobox-haskell = { diff --git a/nix/manual-overrides.nix b/nix/manual-overrides.nix index b291319cbc..024308d419 100644 --- a/nix/manual-overrides.nix +++ b/nix/manual-overrides.nix @@ -24,7 +24,6 @@ hself: hsuper: { servant-multipart = hlib.doJailbreak hsuper.servant-multipart; hashtables = hsuper.hashtables_1_3; quickcheck-state-machine = hlib.dontCheck hsuper.quickcheck-state-machine; - quickcheck-arbitrary-template = hlib.markUnbroken (hsuper.quickcheck-arbitrary-template); wai-middleware-prometheus = hlib.doJailbreak hsuper.wai-middleware-prometheus; one-liner = hlib.doJailbreak hsuper.one-liner; type-errors = hlib.dontCheck hsuper.type-errors; @@ -39,6 +38,8 @@ hself: hsuper: { cql-io = hlib.dontCheck hsuper.cql-io; # Needs network access to running ES + # also the test suite doesn't compile https://github.com/NixOS/nixpkgs/pull/167957 + # due to related broken quickcheck-arbitrary-template bloodhound = hlib.dontCheck hsuper.bloodhound; # These tests require newer version on hspec-wai, which doesn't work with some of the wire-server packages. From 0099c4b6b166c330cae666c21f67ddea9d5a8744 Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Mon, 23 Jan 2023 15:13:45 +0100 Subject: [PATCH 27/35] brig: fix compilation --- services/brig/src/Brig/API/Public.hs | 2 +- services/brig/src/Brig/Provider/API.hs | 3 ++- services/brig/test/integration/API/User/Util.hs | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/services/brig/src/Brig/API/Public.hs b/services/brig/src/Brig/API/Public.hs index bdcf685931..c62128ab36 100644 --- a/services/brig/src/Brig/API/Public.hs +++ b/services/brig/src/Brig/API/Public.hs @@ -326,7 +326,7 @@ servantSitemap = :<|> Named @"get-calls-config-v2" Calling.getCallsConfigV2 systemSettingsAPI :: ServerT SystemSettingsAPI (Handler r) - systemSettingsAPI = Named @ "get-system-settings" getSystemSettings + systemSettingsAPI = Named @"get-system-settings" getSystemSettings -- Note [ephemeral user sideeffect] -- If the user is ephemeral and expired, it will be removed upon calling diff --git a/services/brig/src/Brig/Provider/API.hs b/services/brig/src/Brig/Provider/API.hs index 84ea17a47a..5a9782dbc0 100644 --- a/services/brig/src/Brig/Provider/API.hs +++ b/services/brig/src/Brig/Provider/API.hs @@ -78,6 +78,7 @@ import qualified Data.Swagger.Build.Api as Doc import qualified Data.Text.Ascii as Ascii import qualified Data.Text.Encoding as Text import qualified Data.ZAuth.Token as ZAuth +import GHC.TypeNats import Imports import Network.HTTP.Types.Status import Network.Wai (Response) @@ -1232,7 +1233,7 @@ maybeInvalidBot = maybe (throwStd invalidBot) pure maybeInvalidUser :: Monad m => Maybe a -> (ExceptT Error m) a maybeInvalidUser = maybe (throwStd (errorToWai @'E.InvalidUser)) pure -rangeChecked :: (Within a n m, Monad monad) => a -> (ExceptT Error monad) (Range n m a) +rangeChecked :: (KnownNat n, KnownNat m, Within a n m, Monad monad) => a -> (ExceptT Error monad) (Range n m a) rangeChecked = either (throwStd . invalidRange . fromString) pure . checkedEither invalidServiceKey :: Wai.Error diff --git a/services/brig/test/integration/API/User/Util.hs b/services/brig/test/integration/API/User/Util.hs index 1428b66ec0..872f903768 100644 --- a/services/brig/test/integration/API/User/Util.hs +++ b/services/brig/test/integration/API/User/Util.hs @@ -40,6 +40,7 @@ import qualified Data.ByteString.Lazy as LB import Data.Domain import Data.Handle (Handle (Handle)) import Data.Id hiding (client) +import Data.Kind import qualified Data.List1 as List1 import Data.Misc (PlainTextPassword (..)) import Data.Qualified @@ -539,7 +540,7 @@ setTeamSndFactorPasswordChallenge galley tid status = do put (galley . paths ["i", "teams", toByteString' tid, "features", featureNameBS @Public.SndFactorPasswordChallengeConfig] . contentJson . body js) !!! const 200 === statusCode setTeamFeatureLockStatus :: - forall (cfg :: *) m. + forall (cfg :: Type) m. ( MonadCatch m, MonadIO m, MonadHttp m, From ae40488736487260b48a57e3138c58e1e38f4657 Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Mon, 23 Jan 2023 15:44:39 +0100 Subject: [PATCH 28/35] cargohold: fix compilation --- services/cargohold/src/CargoHold/API/Public.hs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/cargohold/src/CargoHold/API/Public.hs b/services/cargohold/src/CargoHold/API/Public.hs index 67821235c9..6e2ff12830 100644 --- a/services/cargohold/src/CargoHold/API/Public.hs +++ b/services/cargohold/src/CargoHold/API/Public.hs @@ -28,6 +28,7 @@ import Data.ByteString.Builder import qualified Data.ByteString.Lazy as LBS import Data.Domain import Data.Id +import Data.Kind import Data.Qualified import Imports hiding (head) import qualified Network.HTTP.Types as HTTP @@ -96,7 +97,7 @@ instance HasLocation 'ProviderPrincipalTag where assetKeyToText (tUnqualified key) ] -class HasLocation tag => MakePrincipal (tag :: PrincipalTag) (id :: *) | id -> tag, tag -> id where +class HasLocation tag => MakePrincipal (tag :: PrincipalTag) (id :: Type) | id -> tag, tag -> id where mkPrincipal :: id -> V3.Principal instance MakePrincipal 'UserPrincipalTag (Local UserId) where From de11ae6a1f0376c3e3a3c496bc5ef99b5dd4ac52 Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Mon, 23 Jan 2023 16:28:58 +0100 Subject: [PATCH 29/35] gundeck: fix compilation --- services/gundeck/src/Gundeck/Options.hs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/services/gundeck/src/Gundeck/Options.hs b/services/gundeck/src/Gundeck/Options.hs index 95eb235f41..8e23457e9d 100644 --- a/services/gundeck/src/Gundeck/Options.hs +++ b/services/gundeck/src/Gundeck/Options.hs @@ -87,10 +87,6 @@ data MaxConcurrentNativePushes = MaxConcurrentNativePushes } deriving (Show, Generic) -deriveFromJSON toOptionFieldName ''Settings - -makeLenses ''Settings - deriveFromJSON toOptionFieldName ''MaxConcurrentNativePushes makeLenses ''MaxConcurrentNativePushes @@ -113,6 +109,10 @@ deriveFromJSON toOptionFieldName ''RedisEndpoint makeLenses ''RedisEndpoint +makeLenses ''Settings + +deriveFromJSON toOptionFieldName ''Settings + data Opts = Opts { -- | Hostname and port to bind to _optGundeck :: !Endpoint, From c8ed6f8667023095c9b80c3b33be02920b929565 Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Tue, 24 Jan 2023 09:59:39 +0100 Subject: [PATCH 30/35] stern: fix compilation --- tools/stern/src/Stern/API.hs | 2 +- tools/stern/src/Stern/API/Routes.hs | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/tools/stern/src/Stern/API.hs b/tools/stern/src/Stern/API.hs index a849241aeb..31b67199ac 100644 --- a/tools/stern/src/Stern/API.hs +++ b/tools/stern/src/Stern/API.hs @@ -207,7 +207,7 @@ searchOnBehalf :: UserId -> Maybe T.Text -> Maybe Int32 -> Handler (SearchResult searchOnBehalf uid (fromMaybe "" -> q) - (fromMaybe (unsafeRange 10) . checked @Int32 @1 @100 . fromMaybe 10 -> s) = + (fromMaybe (unsafeRange 10) . checked @1 @100 @Int32 . fromMaybe 10 -> s) = Intra.getContacts uid q (fromRange s) revokeIdentity :: Maybe Email -> Maybe Phone -> Handler NoContent diff --git a/tools/stern/src/Stern/API/Routes.hs b/tools/stern/src/Stern/API/Routes.hs index 5fabd0ffe0..ac61085d1d 100644 --- a/tools/stern/src/Stern/API/Routes.hs +++ b/tools/stern/src/Stern/API/Routes.hs @@ -32,6 +32,7 @@ import Control.Monad.Trans.Except import qualified Data.Aeson as A import Data.Handle import Data.Id +import Data.Kind import qualified Data.Schema as Schema import qualified Data.Swagger as S import Imports hiding (head) @@ -422,7 +423,7 @@ doubleMaybeToEither _ (Just a) Nothing = pure $ Left a doubleMaybeToEither _ Nothing (Just b) = pure $ Right b doubleMaybeToEither msg _ _ = throwE $ mkError status400 "either-params" ("Must use exactly one of two query params: " <> msg) -type MkFeatureGetRoute (feature :: *) = +type MkFeatureGetRoute (feature :: Type) = Summary "Shows whether a feature flag is enabled or not for a given team." :> "teams" :> Capture "tid" TeamId @@ -430,7 +431,7 @@ type MkFeatureGetRoute (feature :: *) = :> FeatureSymbol feature :> Get '[JSON] (WithStatus feature) -type MkFeaturePutRouteTrivialConfigNoTTL (feature :: *) = +type MkFeaturePutRouteTrivialConfigNoTTL (feature :: Type) = Summary "Disable / enable status for a given feature / team" :> "teams" :> Capture "tid" TeamId @@ -439,7 +440,7 @@ type MkFeaturePutRouteTrivialConfigNoTTL (feature :: *) = :> QueryParam' [Required, Strict] "status" FeatureStatus :> Put '[JSON] NoContent -type MkFeaturePutRouteTrivialConfigWithTTL (feature :: *) = +type MkFeaturePutRouteTrivialConfigWithTTL (feature :: Type) = Summary "Disable / enable status for a given feature / team" :> Description "team feature time to live, given in days, or 'unlimited' (default). only available on *some* features!" :> "teams" @@ -450,7 +451,7 @@ type MkFeaturePutRouteTrivialConfigWithTTL (feature :: *) = :> QueryParam' [Required, Strict, Description "team feature time to live, given in days, or 'unlimited' (default)."] "ttl" FeatureTTLDays :> Put '[JSON] NoContent -type MkFeaturePutRoute (feature :: *) = +type MkFeaturePutRoute (feature :: Type) = Summary "Disable / enable feature flag for a given team" :> "teams" :> Capture "tid" TeamId From dba1027f73e68646765d1073c64c0161fd68472e Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Tue, 24 Jan 2023 10:06:49 +0100 Subject: [PATCH 31/35] assets: fix compilation --- tools/db/assets/src/Assets/Lib.hs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/db/assets/src/Assets/Lib.hs b/tools/db/assets/src/Assets/Lib.hs index c4947b4d52..036b31ae6b 100644 --- a/tools/db/assets/src/Assets/Lib.hs +++ b/tools/db/assets/src/Assets/Lib.hs @@ -188,5 +188,4 @@ instance Semigroup Result where instance Monoid Result where mempty = Result 0 0 [] - mappend (Result n1 v1 i1) (Result n2 v2 i2) = - Result (n1 + n2) (v1 + v2) (i1 <> i2) + mappend = (<>) From b43e3823fde5e3019fce5862ceb7ece4850548b0 Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Tue, 24 Jan 2023 12:13:28 +0100 Subject: [PATCH 32/35] move wire forks repos from axeman to wireapp/forks --- nix/haskell-pins.nix | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nix/haskell-pins.nix b/nix/haskell-pins.nix index cef97e3a6f..33026ee33d 100644 --- a/nix/haskell-pins.nix +++ b/nix/haskell-pins.nix @@ -181,16 +181,16 @@ let }; cql-io = { src = fetchgit { - url = "https://gitlab.com/axeman/cql-io"; + url = "https://gitlab.com/wireapp/forks/cql-io"; rev = "c2b6aa995b5817ed7c78c53f72d5aa586ef87c36"; - sha256 = "1wncign8ilvqs9qyl6pkz66x2s8dgwhnfdjw82wv38ijmr95di0c"; + sha256 = "sha256-DMRWUq4yorG5QFw2ZyF/DWnRjfnzGupx0njTiOyLzPI="; }; }; swagger = { src = fetchgit { - url = "https://gitlab.com/axeman/swagger"; + url = "https://gitlab.com/wireapp/forks/swagger.git"; rev = "e2d3f5b5274b8d8d301b5377b0af4319cea73f9e"; - sha256 = "1zj3fqlvcvp9s0myb98b6s9mpmiqamyxn2d3jan55irdgm53prmv"; + sha256 = "sha256-u+Y7Sn0tx1KskqMJ231VONZbkzYLpeUr0Olutil2Q/4="; }; }; wai-predicates = { From 7aa419f2bdc7372797ae102f934c8744a7de7155 Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Tue, 24 Jan 2023 12:53:48 +0100 Subject: [PATCH 33/35] Add docs with workflow hints when upgrading --- docs/src/developer/developer/upgrading.md | 32 +++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 docs/src/developer/developer/upgrading.md diff --git a/docs/src/developer/developer/upgrading.md b/docs/src/developer/developer/upgrading.md new file mode 100644 index 0000000000..29ab268778 --- /dev/null +++ b/docs/src/developer/developer/upgrading.md @@ -0,0 +1,32 @@ +# Upgrading + +Here are some workflow suggestions when you're trying to upgrade packages (or GHC) in wire-server. + +- Use and install https://github.com/maralorn/nix-output-monitor when building nix derivations locally. It shows you the dependency tree building as well as the progress. This can give you a feeling how much progress you've made. + +- The `.envrc` environment probably won't load anymore. To fix this adjust the for packages that get passed to `shellFor` in `wire-server.nix`. In the beginning you might want to start out with an empty list as an argument. + +- You can explore our nix derivations via `nix repl` and then `:l ./nix` to load the attrset in `./nix/default.nix`. For example to see which version of `aeson` will be used you can evaluate `wireServer.haskellPackages.aeson.version`. TAB-autocompletion also tells you if multiple versions of a package are included in the `nixpkgs` pin, e.g. `aeson_1_5_6_0`, `aeson_2_1_1_0`, which can be used in `manual-overrides.nix` to overwrite the default, e.g. `aeson`. + +- Your goal is to make all packages compile again with nix. Start small by trying to build single packages, e.g. `wire-api` or any external dependencies. +``` +nix-build ./nix -A wireServer.haskellPackagesUnoptimizedNoDocs.wire-api +``` + +- When a dependency doesn't build anymore because of unmet version constraints see if you can use a never version (`haskell-pins.nix`, or `manual-overrides.nix` if multiple versions of the package are included in the `nixpkgs` pin). Also check out the git repo or issue tracker of the dependency to find forks that work. You can also try removing versions constraints of packages: see `doJailbreak` in `manual-overrides.nix`. + +- If test-suites of a dependency don't compile, or cannot be run because they require IO interaction you can disable them: see `dontCheck` in `manual-overrides.nix` + +- To force a rebuild of the nix shell delete the `.env` directory and run `direnv reload` + +- If you need to fix code in a dependency consider forking it and creating a PR to the upstream after successful adapation. Clone the repo and then symlink it inside `libs/` and run `generate-local-nix-packages.sh` to temporarily include its dependencies in the development shell. Make sure to include the package in `shellFor`. If you've got a working shell you can check the output of `ghc-pkg dump` to see the nix-provided ghc packages used by cabal. + +- Consider using `ghcid --command "cabal repl "` when fixing packages + +- Delete the `dist-newstyle` directory everytime you upgrade the nix environment, without any exception. That is because cabal does not pick up changes to the `ghc-pkg` set (defined the development shell). Cabal will complain about missing dependencies in these cases. + +- When trying to build any packages with cabal (e.g. for fixing code in a depencency or fixing local packages), make sure you've got the right package set in the `shellFor` argument and the right transitive dependencies in `cabal.project`. It takes a couple of tries to get both: a nix provided environment that work and cabal not complaining about missing dependencies when building inside the environment. + +- It might happen that a package's test suite dependencies are not available in the nix environment. When you try to build with cabal it might try to build these external dependencies (which you want to avoid). What might work in these cases temporarily updating the `default.nix` file (generated by `generate-local-nix-packages.sh`) to add the test suits dependencies to the library section. + +- If cabal is complaining about missing a missing `libsodium` add `sodium-crypt-sign` to the `shellFor` environment From c4faef6bcc39a228a3e8c2e7c6ed91a8a77f0e28 Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Wed, 25 Jan 2023 10:51:09 +0100 Subject: [PATCH 34/35] Apply suggestions from code review Co-authored-by: Igor Ranieri Elland <54423+elland@users.noreply.github.com> --- docs/src/developer/developer/upgrading.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/src/developer/developer/upgrading.md b/docs/src/developer/developer/upgrading.md index 29ab268778..bf8a18859c 100644 --- a/docs/src/developer/developer/upgrading.md +++ b/docs/src/developer/developer/upgrading.md @@ -19,14 +19,14 @@ nix-build ./nix -A wireServer.haskellPackagesUnoptimizedNoDocs.wire-api - To force a rebuild of the nix shell delete the `.env` directory and run `direnv reload` -- If you need to fix code in a dependency consider forking it and creating a PR to the upstream after successful adapation. Clone the repo and then symlink it inside `libs/` and run `generate-local-nix-packages.sh` to temporarily include its dependencies in the development shell. Make sure to include the package in `shellFor`. If you've got a working shell you can check the output of `ghc-pkg dump` to see the nix-provided ghc packages used by cabal. +- If you need to fix code in a dependency consider forking it and creating a PR to the upstream after successful integration. Clone the repo and then symlink it inside `libs/` then run `generate-local-nix-packages.sh` to temporarily include its dependencies in the development shell. Make sure to include the package in `shellFor`. If you've got a working shell you can check the output of `ghc-pkg dump` to see the list of nix-provided ghc packages used by cabal. - Consider using `ghcid --command "cabal repl "` when fixing packages - Delete the `dist-newstyle` directory everytime you upgrade the nix environment, without any exception. That is because cabal does not pick up changes to the `ghc-pkg` set (defined the development shell). Cabal will complain about missing dependencies in these cases. -- When trying to build any packages with cabal (e.g. for fixing code in a depencency or fixing local packages), make sure you've got the right package set in the `shellFor` argument and the right transitive dependencies in `cabal.project`. It takes a couple of tries to get both: a nix provided environment that work and cabal not complaining about missing dependencies when building inside the environment. +- When trying to build any packages with cabal (e.g. for fixing code in a depencency or fixing local packages), make sure you've got the right package set in the `shellFor` argument and the right transitive dependencies in `cabal.project`. It takes a couple of tries to get both: a nix provided environment that works, and cabal not complaining about missing dependencies when building inside the environment. -- It might happen that a package's test suite dependencies are not available in the nix environment. When you try to build with cabal it might try to build these external dependencies (which you want to avoid). What might work in these cases temporarily updating the `default.nix` file (generated by `generate-local-nix-packages.sh`) to add the test suits dependencies to the library section. +- It might happen that a package's test suite dependencies are not available in the nix environment. When you try to build with cabal it might try to build these external dependencies (which you want to avoid). What might work in these cases is to temporarily update the `default.nix` file (generated by `generate-local-nix-packages.sh`) to add the test suits dependencies to the library section. -- If cabal is complaining about missing a missing `libsodium` add `sodium-crypt-sign` to the `shellFor` environment +- If cabal is complaining about missing `libsodium`: add `sodium-crypt-sign` to the `shellFor` environment. From c6a75e02ad9bb5184f59b61c4144c59327d523d9 Mon Sep 17 00:00:00 2001 From: Stefan Matting Date: Fri, 27 Jan 2023 10:13:08 +0100 Subject: [PATCH 35/35] Apply suggestions from code review --- docs/src/developer/developer/upgrading.md | 2 +- libs/wire-api/src/Wire/API/Routes/MultiVerb.hs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/developer/developer/upgrading.md b/docs/src/developer/developer/upgrading.md index bf8a18859c..74a7d40bd2 100644 --- a/docs/src/developer/developer/upgrading.md +++ b/docs/src/developer/developer/upgrading.md @@ -29,4 +29,4 @@ nix-build ./nix -A wireServer.haskellPackagesUnoptimizedNoDocs.wire-api - It might happen that a package's test suite dependencies are not available in the nix environment. When you try to build with cabal it might try to build these external dependencies (which you want to avoid). What might work in these cases is to temporarily update the `default.nix` file (generated by `generate-local-nix-packages.sh`) to add the test suits dependencies to the library section. -- If cabal is complaining about missing `libsodium`: add `sodium-crypt-sign` to the `shellFor` environment. +- If cabal is complaining about a missing `libsodium`, add `sodium-crypt-sign` to the `shellFor` environment. diff --git a/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs b/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs index 8d1fa53d2a..6cba238dc3 100644 --- a/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs +++ b/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs @@ -19,7 +19,7 @@ -- with this program. If not, see . module Wire.API.Routes.MultiVerb - ( -- Type MultiVerb types + ( -- * MultiVerb types MultiVerb, MultiVerb1, Respond,