diff --git a/default.nix b/default.nix index 79c1787..b44e3bc 100644 --- a/default.nix +++ b/default.nix @@ -1,8 +1,7 @@ -{ mkDerivation, async, base, bytestring, c2hs, clock, containers +{ mkDerivation, async, base, bytestring, clock, containers , criterion, grpc-haskell-core, managed, pipes, proto3-suite -, proto3-wire, QuickCheck, random, safe, sorted-list, stdenv, stm -, tasty, tasty-hunit, tasty-quickcheck, text, time, transformers -, turtle, unix, vector +, proto3-wire, QuickCheck, random, safe, stdenv, tasty, tasty-hunit +, tasty-quickcheck, text, time, transformers, turtle, unix }: mkDerivation { pname = "grpc-haskell"; @@ -11,11 +10,9 @@ mkDerivation { isLibrary = true; isExecutable = true; libraryHaskellDepends = [ - async base bytestring clock containers grpc-haskell-core managed - pipes proto3-suite proto3-wire safe sorted-list stm tasty - tasty-hunit tasty-quickcheck transformers vector + async base bytestring grpc-haskell-core managed proto3-suite + proto3-wire ]; - libraryToolDepends = [ c2hs ]; testHaskellDepends = [ async base bytestring clock containers managed pipes proto3-suite QuickCheck safe tasty tasty-hunit tasty-quickcheck text time diff --git a/examples/echo/echo-hs/Echo.hs b/examples/echo/echo-hs/Echo.hs index f7908d6..339982b 100644 --- a/examples/echo/echo-hs/Echo.hs +++ b/examples/echo/echo-hs/Echo.hs @@ -32,12 +32,12 @@ import Network.GRPC.HighLevel.Client as HsGRPC import Network.GRPC.HighLevel.Server as HsGRPC hiding (serverLoop) import Network.GRPC.HighLevel.Server.Unregistered as HsGRPC (serverLoop) - + data Echo request response = Echo{echoDoEcho :: request 'HsGRPC.Normal Echo.EchoRequest Echo.EchoResponse -> Hs.IO (response 'HsGRPC.Normal Echo.EchoResponse)} deriving Hs.Generic - + echoServer :: Echo HsGRPC.ServerRequest HsGRPC.ServerResponse -> HsGRPC.ServiceOptions -> Hs.IO () @@ -56,7 +56,7 @@ echoServer Echo{echoDoEcho = echoDoEcho} optUserAgentSuffix = userAgentSuffix, optInitialMetadata = initialMetadata, optSSLConfig = sslConfig, optLogger = logger}) - + echoClient :: HsGRPC.Client -> Hs.IO (Echo HsGRPC.ClientRequest HsGRPC.ClientResult) @@ -65,13 +65,13 @@ echoClient client ((Hs.pure (HsGRPC.clientRequest client)) <*> (HsGRPC.clientRegisterMethod client (HsGRPC.MethodName "/echo.Echo/DoEcho"))) - + data EchoRequest = EchoRequest{echoRequestMessage :: Hs.Text} deriving (Hs.Show, Hs.Eq, Hs.Ord, Hs.Generic) - + instance HsProtobuf.Named EchoRequest where nameOf _ = (Hs.fromString "EchoRequest") - + instance HsProtobuf.Message EchoRequest where encodeMessage _ EchoRequest{echoRequestMessage = echoRequestMessage} @@ -87,24 +87,24 @@ instance HsProtobuf.Message EchoRequest where (HsProtobuf.Prim HsProtobuf.String) (HsProtobuf.Single "message") [] - Hs.Nothing)] - + "")] + instance HsJSONPB.ToJSONPB EchoRequest where toJSONPB (EchoRequest f1) = (HsJSONPB.object ["message" .= f1]) toEncodingPB (EchoRequest f1) = (HsJSONPB.pairs ["message" .= f1]) - + instance HsJSONPB.FromJSONPB EchoRequest where parseJSONPB = (HsJSONPB.withObject "EchoRequest" (\ obj -> (Hs.pure EchoRequest) <*> obj .: "message")) - + instance HsJSONPB.ToJSON EchoRequest where toJSON = HsJSONPB.toAesonValue toEncoding = HsJSONPB.toAesonEncoding - + instance HsJSONPB.FromJSON EchoRequest where parseJSON = HsJSONPB.parseJSONPB - + instance HsJSONPB.ToSchema EchoRequest where declareNamedSchema _ = do let declare_message = HsJSONPB.declareSchemaRef @@ -120,13 +120,13 @@ instance HsJSONPB.ToSchema EchoRequest where HsJSONPB._schemaProperties = HsJSONPB.insOrdFromList [("message", echoRequestMessage)]}}) - + data EchoResponse = EchoResponse{echoResponseMessage :: Hs.Text} deriving (Hs.Show, Hs.Eq, Hs.Ord, Hs.Generic) - + instance HsProtobuf.Named EchoResponse where nameOf _ = (Hs.fromString "EchoResponse") - + instance HsProtobuf.Message EchoResponse where encodeMessage _ EchoResponse{echoResponseMessage = echoResponseMessage} @@ -142,24 +142,24 @@ instance HsProtobuf.Message EchoResponse where (HsProtobuf.Prim HsProtobuf.String) (HsProtobuf.Single "message") [] - Hs.Nothing)] - + "")] + instance HsJSONPB.ToJSONPB EchoResponse where toJSONPB (EchoResponse f1) = (HsJSONPB.object ["message" .= f1]) toEncodingPB (EchoResponse f1) = (HsJSONPB.pairs ["message" .= f1]) - + instance HsJSONPB.FromJSONPB EchoResponse where parseJSONPB = (HsJSONPB.withObject "EchoResponse" (\ obj -> (Hs.pure EchoResponse) <*> obj .: "message")) - + instance HsJSONPB.ToJSON EchoResponse where toJSON = HsJSONPB.toAesonValue toEncoding = HsJSONPB.toAesonEncoding - + instance HsJSONPB.FromJSON EchoResponse where parseJSON = HsJSONPB.parseJSONPB - + instance HsJSONPB.ToSchema EchoResponse where declareNamedSchema _ = do let declare_message = HsJSONPB.declareSchemaRef @@ -174,4 +174,4 @@ instance HsJSONPB.ToSchema EchoResponse where HsJSONPB.SwaggerObject}, HsJSONPB._schemaProperties = HsJSONPB.insOrdFromList - [("message", echoResponseMessage)]}}) \ No newline at end of file + [("message", echoResponseMessage)]}}) diff --git a/examples/echo/echo-hs/EchoClient.hs b/examples/echo/echo-hs/EchoClient.hs index 899f6e3..1a72fd0 100644 --- a/examples/echo/echo-hs/EchoClient.hs +++ b/examples/echo/echo-hs/EchoClient.hs @@ -14,7 +14,6 @@ import qualified Data.Text.Lazy as TL import Echo import GHC.Generics (Generic) import Network.GRPC.HighLevel.Client -import Network.GRPC.HighLevel.Generated import Network.GRPC.LowLevel import Options.Generic import Prelude hiding (FilePath) diff --git a/examples/tutorial/Arithmetic.hs b/examples/tutorial/Arithmetic.hs index b2a8363..54f7597 100644 --- a/examples/tutorial/Arithmetic.hs +++ b/examples/tutorial/Arithmetic.hs @@ -32,7 +32,7 @@ import Network.GRPC.HighLevel.Client as HsGRPC import Network.GRPC.HighLevel.Server as HsGRPC hiding (serverLoop) import Network.GRPC.HighLevel.Server.Unregistered as HsGRPC (serverLoop) - + data Arithmetic request response = Arithmetic{arithmeticAdd :: request 'HsGRPC.Normal Arithmetic.TwoInts Arithmetic.OneInt @@ -46,7 +46,7 @@ data Arithmetic request response = Arithmetic{arithmeticAdd :: (response 'HsGRPC.ClientStreaming Arithmetic.OneInt)} deriving Hs.Generic - + arithmeticServer :: Arithmetic HsGRPC.ServerRequest HsGRPC.ServerResponse -> HsGRPC.ServiceOptions -> Hs.IO () @@ -72,7 +72,7 @@ arithmeticServer optUserAgentSuffix = userAgentSuffix, optInitialMetadata = initialMetadata, optSSLConfig = sslConfig, optLogger = logger}) - + arithmeticClient :: HsGRPC.Client -> Hs.IO (Arithmetic HsGRPC.ClientRequest HsGRPC.ClientResult) @@ -85,13 +85,13 @@ arithmeticClient client ((Hs.pure (HsGRPC.clientRequest client)) <*> (HsGRPC.clientRegisterMethod client (HsGRPC.MethodName "/arithmetic.Arithmetic/RunningSum"))) - + data TwoInts = TwoInts{twoIntsX :: Hs.Int32, twoIntsY :: Hs.Int32} deriving (Hs.Show, Hs.Eq, Hs.Ord, Hs.Generic) - + instance HsProtobuf.Named TwoInts where nameOf _ = (Hs.fromString "TwoInts") - + instance HsProtobuf.Message TwoInts where encodeMessage _ TwoInts{twoIntsX = twoIntsX, twoIntsY = twoIntsY} = (Hs.mconcat @@ -111,30 +111,30 @@ instance HsProtobuf.Message TwoInts where (HsProtobuf.Prim HsProtobuf.Int32) (HsProtobuf.Single "x") [] - Hs.Nothing), + ""), (HsProtobuf.DotProtoField (HsProtobuf.FieldNumber 2) (HsProtobuf.Prim HsProtobuf.Int32) (HsProtobuf.Single "y") [] - Hs.Nothing)] - + "")] + instance HsJSONPB.ToJSONPB TwoInts where toJSONPB (TwoInts f1 f2) = (HsJSONPB.object ["x" .= f1, "y" .= f2]) toEncodingPB (TwoInts f1 f2) = (HsJSONPB.pairs ["x" .= f1, "y" .= f2]) - + instance HsJSONPB.FromJSONPB TwoInts where parseJSONPB = (HsJSONPB.withObject "TwoInts" (\ obj -> (Hs.pure TwoInts) <*> obj .: "x" <*> obj .: "y")) - + instance HsJSONPB.ToJSON TwoInts where toJSON = HsJSONPB.toAesonValue toEncoding = HsJSONPB.toAesonEncoding - + instance HsJSONPB.FromJSON TwoInts where parseJSON = HsJSONPB.parseJSONPB - + instance HsJSONPB.ToSchema TwoInts where declareNamedSchema _ = do let declare_x = HsJSONPB.declareSchemaRef @@ -153,13 +153,13 @@ instance HsJSONPB.ToSchema TwoInts where HsJSONPB._schemaProperties = HsJSONPB.insOrdFromList [("x", twoIntsX), ("y", twoIntsY)]}}) - + data OneInt = OneInt{oneIntResult :: Hs.Int32} deriving (Hs.Show, Hs.Eq, Hs.Ord, Hs.Generic) - + instance HsProtobuf.Named OneInt where nameOf _ = (Hs.fromString "OneInt") - + instance HsProtobuf.Message OneInt where encodeMessage _ OneInt{oneIntResult = oneIntResult} = (Hs.mconcat @@ -174,24 +174,24 @@ instance HsProtobuf.Message OneInt where (HsProtobuf.Prim HsProtobuf.Int32) (HsProtobuf.Single "result") [] - Hs.Nothing)] - + "")] + instance HsJSONPB.ToJSONPB OneInt where toJSONPB (OneInt f1) = (HsJSONPB.object ["result" .= f1]) toEncodingPB (OneInt f1) = (HsJSONPB.pairs ["result" .= f1]) - + instance HsJSONPB.FromJSONPB OneInt where parseJSONPB = (HsJSONPB.withObject "OneInt" (\ obj -> (Hs.pure OneInt) <*> obj .: "result")) - + instance HsJSONPB.ToJSON OneInt where toJSON = HsJSONPB.toAesonValue toEncoding = HsJSONPB.toAesonEncoding - + instance HsJSONPB.FromJSON OneInt where parseJSON = HsJSONPB.parseJSONPB - + instance HsJSONPB.ToSchema OneInt where declareNamedSchema _ = do let declare_result = HsJSONPB.declareSchemaRef @@ -205,4 +205,4 @@ instance HsJSONPB.ToSchema OneInt where HsJSONPB.SwaggerObject}, HsJSONPB._schemaProperties = HsJSONPB.insOrdFromList - [("result", oneIntResult)]}}) \ No newline at end of file + [("result", oneIntResult)]}}) diff --git a/grpc-haskell.cabal b/grpc-haskell.cabal index 5398e4e..e9e758f 100644 --- a/grpc-haskell.cabal +++ b/grpc-haskell.cabal @@ -1,5 +1,5 @@ name: grpc-haskell -version: 0.0.0.0 +version: 0.0.1.0 synopsis: Haskell implementation of gRPC layered on shared C library. homepage: https://github.com/awakenetworks/gRPC-haskell license: Apache-2.0 @@ -25,7 +25,7 @@ library build-depends: base >=4.8 && <5.0 , bytestring ==0.10.* - , proto3-suite + , proto3-suite >=0.4.0.0 , proto3-wire , grpc-haskell-core @@ -201,7 +201,7 @@ test-suite tests , clock >=0.6.0 && <0.8.0 , turtle >= 1.2.0 , text - , QuickCheck >=2.8 && <3.0 + , QuickCheck >=2.10 && <3.0 other-modules: GeneratedTests default-language: Haskell2010 diff --git a/nix/QuickCheck.nix b/nix/QuickCheck.nix new file mode 100644 index 0000000..81c7c69 --- /dev/null +++ b/nix/QuickCheck.nix @@ -0,0 +1,16 @@ +{ mkDerivation, base, containers, deepseq, random, stdenv +, template-haskell, tf-random, transformers +}: +mkDerivation { + pname = "QuickCheck"; + version = "2.10"; + sha256 = "f6f55b798044ad985cce9c38a3d774b32811a0ffdb2066ca9ed45f32b25de7af"; + libraryHaskellDepends = [ + base containers deepseq random template-haskell tf-random + transformers + ]; + testHaskellDepends = [ base ]; + homepage = "https://github.com/nick8325/quickcheck"; + description = "Automatic testing of Haskell programs"; + license = stdenv.lib.licenses.bsd3; +} diff --git a/nix/proto3-suite.nix b/nix/proto3-suite.nix index 5a95bb4..d0df704 100644 --- a/nix/proto3-suite.nix +++ b/nix/proto3-suite.nix @@ -1,38 +1,42 @@ { mkDerivation, aeson, aeson-pretty, attoparsec, base , base64-bytestring, binary, bytestring, cereal, containers -, deepseq, doctest, fetchgit, foldl, hashable, haskell-src -, insert-ordered-containers, lens, mtl, neat-interpolation -, optparse-generic, parsec, parsers, pretty, pretty-show -, proto3-wire, QuickCheck, range-set-list, safe, semigroups, stdenv +, contravariant, deepseq, doctest, fetchgit, filepath, foldl +, hashable, haskell-src, insert-ordered-containers, lens, mtl +, neat-interpolation, optparse-applicative, optparse-generic +, parsec, parsers, pretty, pretty-show, proto3-wire, QuickCheck +, quickcheck-instances, range-set-list, safe, semigroups, stdenv , swagger2, system-filepath, tasty, tasty-hunit, tasty-quickcheck , text, transformers, turtle, vector }: mkDerivation { pname = "proto3-suite"; - version = "0.2.0.0"; + version = "0.4.0.0"; src = fetchgit { url = "https://github.com/awakesecurity/proto3-suite.git"; - sha256 = "1khix03a4hwaqc192s523rjlsk1iq923ndmrj5myh61fr1fpcbaq"; - rev = "c103a8c6d3c16515fe2e9ea7f932d54729db2f5f"; + sha256 = "091db048hgcq5idvf5gaiqb6hzbs7g1dz6xjqdx61dw2yxgdm957"; + rev = "973c317b91405a11438e3a21706024bfa3d754df"; + fetchSubmodules = true; }; isLibrary = true; isExecutable = true; enableSeparateDataOutput = true; libraryHaskellDepends = [ aeson aeson-pretty attoparsec base base64-bytestring binary - bytestring cereal containers deepseq foldl hashable haskell-src - insert-ordered-containers lens mtl neat-interpolation parsec - parsers pretty pretty-show proto3-wire QuickCheck safe semigroups - swagger2 system-filepath text transformers turtle vector + bytestring cereal containers contravariant deepseq filepath foldl + hashable haskell-src insert-ordered-containers lens mtl + neat-interpolation parsec parsers pretty pretty-show proto3-wire + QuickCheck quickcheck-instances safe semigroups swagger2 + system-filepath text transformers turtle vector ]; executableHaskellDepends = [ - base containers optparse-generic proto3-wire range-set-list - system-filepath text turtle + base containers mtl optparse-applicative optparse-generic + proto3-wire range-set-list system-filepath text turtle ]; testHaskellDepends = [ - aeson attoparsec base base64-bytestring bytestring cereal doctest - pretty-show proto3-wire QuickCheck semigroups swagger2 tasty - tasty-hunit tasty-quickcheck text transformers turtle vector + aeson attoparsec base base64-bytestring bytestring cereal + containers deepseq doctest mtl pretty-show proto3-wire QuickCheck + semigroups swagger2 tasty tasty-hunit tasty-quickcheck text + transformers turtle vector ]; description = "A low level library for writing out data in the Protocol Buffers wire format"; license = stdenv.lib.licenses.asl20; diff --git a/nix/quickcheck-instances.nix b/nix/quickcheck-instances.nix new file mode 100644 index 0000000..2e0bc75 --- /dev/null +++ b/nix/quickcheck-instances.nix @@ -0,0 +1,22 @@ +{ mkDerivation, array, base, base-compat, bytestring +, case-insensitive, containers, hashable, old-time, QuickCheck +, scientific, stdenv, tagged, text, time, transformers +, transformers-compat, unordered-containers, uuid-types, vector +}: +mkDerivation { + pname = "quickcheck-instances"; + version = "0.3.15"; + sha256 = "9e0efd0debe1fe390c97d7b3d80d59f3221f2ff4aa1649a1929b4a118156dc0a"; + libraryHaskellDepends = [ + array base base-compat bytestring case-insensitive containers + hashable old-time QuickCheck scientific tagged text time + transformers transformers-compat unordered-containers uuid-types + vector + ]; + testHaskellDepends = [ + base containers QuickCheck tagged uuid-types + ]; + homepage = "https://github.com/phadej/qc-instances"; + description = "Common quickcheck instances"; + license = stdenv.lib.licenses.bsd3; +} diff --git a/release.nix b/release.nix index b957772..339c7e9 100644 --- a/release.nix +++ b/release.nix @@ -189,6 +189,9 @@ let haskellPackages = pkgs.haskellPackages.override { overrides = haskellPackagesNew: haskellPackagesOld: rec { + attoparsec = + pkgs.haskell.lib.dontCheck haskellPackagesOld.attoparsec; + aeson = pkgs.haskell.lib.dontCheck (haskellPackagesNew.callPackage ./nix/aeson.nix {}); @@ -196,6 +199,12 @@ let cabal-doctest = haskellPackagesNew.callPackage ./nix/cabal-doctest.nix { }; + edit-distance = + pkgs.haskell.lib.dontCheck haskellPackagesOld.edit-distance; + + http-media = + pkgs.haskell.lib.dontCheck haskellPackagesOld.http-media; + insert-ordered-containers = haskellPackagesNew.callPackage ./nix/insert-ordered-containers.nix { }; @@ -212,6 +221,12 @@ let pkgs.haskell.lib.dontCheck (haskellPackagesNew.callPackage ./nix/proto3-suite.nix {}); + QuickCheck = + (haskellPackagesNew.callPackage ./nix/QuickCheck.nix {}); + + quickcheck-instances = + (haskellPackagesNew.callPackage ./nix/quickcheck-instances.nix {}); + grpc-haskell-core = usesGRPC (pkgs.haskell.lib.overrideCabal diff --git a/tests/GeneratedTests.hs b/tests/GeneratedTests.hs index ae82f1c..056a11a 100644 --- a/tests/GeneratedTests.hs +++ b/tests/GeneratedTests.hs @@ -21,7 +21,13 @@ testServerGeneration = testCase "server generation" $ do mktree hsTmpDir mktree pyTmpDir - compileDotProtoFileOrDie [] hsTmpDir ["tests"] "simple.proto" + let args = CompileArgs + { includeDir = ["tests"] + , extraInstanceFiles = [] + , inputProto = "simple.proto" + , outputDir = hsTmpDir + } + compileDotProtoFileOrDie args do exitCode <- proc "tests/simple-server.sh" [hsTmpDir] empty exitCode @?= ExitSuccess @@ -49,7 +55,13 @@ testClientGeneration = testCase "client generation" $ do mktree hsTmpDir mktree pyTmpDir - compileDotProtoFileOrDie [] hsTmpDir ["tests"] "simple.proto" + let args = CompileArgs + { includeDir = ["tests"] + , extraInstanceFiles = [] + , inputProto = "simple.proto" + , outputDir = hsTmpDir + } + compileDotProtoFileOrDie args do exitCode <- proc "tests/simple-client.sh" [hsTmpDir] empty exitCode @?= ExitSuccess diff --git a/tests/TestClient.hs b/tests/TestClient.hs index 0d3344e..ba1958e 100644 --- a/tests/TestClient.hs +++ b/tests/TestClient.hs @@ -34,7 +34,7 @@ import Test.Tasty import Test.Tasty.HUnit ((@?=), assertString, testCase) testNormalCall client = testCase "Normal call" $ - do randoms <- fromList <$> replicateM 1000 (Fixed <$> randomRIO (1, 1000)) + do randoms <- fromList <$> replicateM 1000 (randomRIO (1, 1000)) let req = SimpleServiceRequest "NormalRequest" randoms res <- simpleServiceNormalCall client (ClientNormalRequest req 10 mempty) @@ -52,7 +52,7 @@ testClientStreamingCall client = testCase "Client-streaming call" $ do (finalName, totalSum) <- fmap ((mconcat *** (sum . mconcat)) . unzip) . replicateM iterationCount $ - do randoms <- fromList <$> replicateM 1000 (Fixed <$> randomRIO (1, 1000)) + do randoms <- fromList <$> replicateM 1000 (randomRIO (1, 1000)) name <- fromString <$> replicateM 10 (randomRIO ('a', 'z')) send (SimpleServiceRequest name randoms) pure (name, randoms) @@ -69,7 +69,7 @@ testClientStreamingCall client = testCase "Client-streaming call" $ testServerStreamingCall client = testCase "Server-streaming call" $ do numCount <- randomRIO (50, 500) - nums <- replicateM numCount (Fixed <$> randomIO) + nums <- replicateM numCount randomIO let checkResults [] recv = do res <- recv @@ -98,7 +98,7 @@ testBiDiStreamingCall client = testCase "Bidi-streaming call" $ do let handleRequests (0 :: Int) _ _ done = done >> pure () handleRequests n recv send done = do numCount <- randomRIO (10, 1000) - nums <- fromList <$> replicateM numCount (Fixed <$> randomRIO (1, 1000)) + nums <- fromList <$> replicateM numCount (randomRIO (1, 1000)) testName <- fromString <$> replicateM 10 (randomRIO ('a', 'z')) send (SimpleServiceRequest testName nums)