From 28627a665f57a9952f7ad0866a3aaa2d32cd0051 Mon Sep 17 00:00:00 2001 From: Martin Huschenbett Date: Mon, 6 Apr 2020 18:28:39 +0200 Subject: [PATCH] Refactor daml-assitant ITs regarding yarn (#5453) There are multiple tests that setup an environment for yarn to find our TypeScript libraries. This PR unifies this setup by providing a single function to set it up. CHANGELOG_BEGIN CHANGELOG_END --- daml-assistant/integration-tests/BUILD.bazel | 6 -- .../src/DA/Daml/Assistant/IntegrationTests.hs | 46 ++++----------- language-support/ts/codegen/tests/BUILD.bazel | 2 +- .../ts/codegen/tests/src/DA/Test/Daml2js.hs | 13 ++--- .../codegen/tests/src/DA/Test/Daml2jsUtils.hs | 58 +++++++++++++++---- 5 files changed, 64 insertions(+), 61 deletions(-) diff --git a/daml-assistant/integration-tests/BUILD.bazel b/daml-assistant/integration-tests/BUILD.bazel index f53626b9143..18189c10d53 100644 --- a/daml-assistant/integration-tests/BUILD.bazel +++ b/daml-assistant/integration-tests/BUILD.bazel @@ -80,12 +80,6 @@ da_haskell_test( srcs = glob(["src/**/*.hs"]), args = [ "$(location //:yarn)", - # The JS codegen test which needs this next arg is not - # run on Windows but we need to pass something on Windows - # to make the test harness happy. If it should be misued, - # hopefully "daml-types-not-available" will end up in the - # error message. - "daml-types-not-available" if is_windows else "$(location //language-support/ts/daml-types:npm_package)", ], data = [ ":integration-tests-mvn", diff --git a/daml-assistant/integration-tests/src/DA/Daml/Assistant/IntegrationTests.hs b/daml-assistant/integration-tests/src/DA/Daml/Assistant/IntegrationTests.hs index 6dc6ac3b668..6d4e7752bc5 100644 --- a/daml-assistant/integration-tests/src/DA/Daml/Assistant/IntegrationTests.hs +++ b/daml-assistant/integration-tests/src/DA/Daml/Assistant/IntegrationTests.hs @@ -9,8 +9,6 @@ import Control.Exception import Control.Monad import Control.Monad.Fail (MonadFail) import qualified Data.Aeson as Aeson -import Data.Aeson ((.=), object) -import qualified Data.ByteString.Lazy as BSL import qualified Data.Conduit.Tar.Extra as Tar.Conduit.Extra import qualified Data.Conduit.Zlib as Zlib import Data.List.Extra @@ -34,28 +32,23 @@ import Test.Tasty import Test.Tasty.HUnit import qualified Web.JWT as JWT -import DA.Directory import DA.Bazel.Runfiles import DA.Daml.Assistant.FreePort (getFreePort,socketHints) import DA.Daml.Helper.Run (waitForHttpServer,waitForConnectionOnPort) -import DA.Test.Daml2jsUtils (writeRootPackageJson) +import DA.Test.Daml2jsUtils import DA.Test.Process (callCommandSilent,callProcessSilent) import DA.Test.Util import SdkVersion main :: IO () main = do - yarn : damlTypesPath : args <- getArgs + yarn : args <- getArgs withTempDir $ \tmpDir -> do oldPath <- getSearchPath javaPath <- locateRunfiles "local_jdk/bin" mvnPath <- locateRunfiles "mvn_dev_env/bin" tarPath <- locateRunfiles "tar_dev_env/bin" yarnPath <- takeDirectory <$> locateRunfiles (mainWorkspace yarn) - damlTypesDir <- - if isWindows - then pure damlTypesPath -- Not available. - else locateRunfiles (mainWorkspace damlTypesPath) -- NOTE: `COMSPEC` env. variable on Windows points to cmd.exe, which is required to be present -- on the PATH as mvn.cmd executes cmd.exe mbComSpec <- getEnv "COMSPEC" @@ -63,10 +56,10 @@ main = do withArgs args (withEnv [ ("PATH", Just $ intercalate [searchPathSeparator] $ (tarPath : javaPath : mvnPath : yarnPath : oldPath) ++ maybeToList mbCmdDir) , ("TASTY_NUM_THREADS", Just "1") - ] $ defaultMain (tests tmpDir damlTypesDir)) + ] $ defaultMain (tests tmpDir)) -tests :: FilePath -> FilePath -> TestTree -tests tmpDir damlTypesDir = withSdkResource $ \_ -> testGroup "Integration tests" +tests :: FilePath -> TestTree +tests tmpDir = withSdkResource $ \_ -> testGroup "Integration tests" [ testCase "daml version" $ callCommandSilent "daml version" , testCase "daml --help" $ callCommandSilent "daml --help" , testCase "daml new --list" $ callCommandSilent "daml new --list" @@ -74,7 +67,7 @@ tests tmpDir damlTypesDir = withSdkResource $ \_ -> testGroup "Integration tests , quickstartTests quickstartDir mvnDir , cleanTests cleanDir , templateTests - , codegenTests codegenDir damlTypesDir + , codegenTests codegenDir , createDamlAppTests ] where quickstartDir = tmpDir "q-u-i-c-k-s-t-a-r-t" @@ -518,8 +511,8 @@ templateTests = testGroup "templates" ] -- | Check we can generate language bindings. -codegenTests :: FilePath -> FilePath -> TestTree -codegenTests codegenDir damlTypes = testGroup "daml codegen" ( +codegenTests :: FilePath -> TestTree +codegenTests codegenDir = testGroup "daml codegen" ( [ codegenTestFor "java" Nothing , codegenTestFor "scala" (Just "com.cookiemonster.nomnomnom") ] ++ @@ -540,13 +533,8 @@ codegenTests codegenDir damlTypes = testGroup "daml codegen" ( let darFile = projectDir ".daml/dist/proj-" ++ lang ++ "-0.0.1.dar" outDir = projectDir "generated" lang when (lang == "js") $ do - -- This section makes - -- 'daml-types@0.0.0-SDKVERSION' available - -- to yarn. - createDirectoryIfMissing True "generated" - withCurrentDirectory "generated" $ do - copyDirectory damlTypes "daml-types" - writeRootPackageJson Nothing [lang] + let workspaces = Workspaces [makeRelative codegenDir outDir] + setupYarnEnv codegenDir workspaces [DamlTypes] callCommandSilent $ unwords [ "daml", "codegen", lang , darFile ++ maybe "" ("=" ++) namespace @@ -559,18 +547,8 @@ createDamlAppTests = testGroup "create-daml-app" [gettingStartedGuideTest | not where gettingStartedGuideTest = testCase "Getting Started Guide" $ withTempDir $ \tmpDir -> do - let tsLibs = ["daml-types", "daml-ledger", "daml-react"] - forM_ tsLibs $ \tsLib -> do - srcDir <- locateRunfiles $ mainWorkspace "language-support" "ts" tsLib "npm_package" - copyDirectory srcDir (tmpDir tsLib) - BSL.writeFile (tmpDir "package.json") $ Aeson.encode $ object - [ "private" .= True - , "workspaces" .= ["create-daml-app/daml.js", "create-daml-app/ui" :: String] - , "resolutions" .= object - [ pkgName .= ("file:" ++ tsLib) - | tsLib <- tsLibs, let pkgName = "@" <> T.replace "-" "/" (T.pack tsLib) - ] - ] + let workspaces = Workspaces ["create-daml-app/daml.js", "create-daml-app/ui"] + setupYarnEnv tmpDir workspaces allTsLibraries withCurrentDirectory tmpDir $ do callCommandSilent "daml new create-daml-app create-daml-app" let cdaDir = tmpDir "create-daml-app" diff --git a/language-support/ts/codegen/tests/BUILD.bazel b/language-support/ts/codegen/tests/BUILD.bazel index 17b00c7d7d2..70aebcd31d9 100644 --- a/language-support/ts/codegen/tests/BUILD.bazel +++ b/language-support/ts/codegen/tests/BUILD.bazel @@ -124,6 +124,7 @@ da_haskell_library( src_strip_prefix = "src", visibility = ["//visibility:public"], deps = [ + "//libs-haskell/bazel-runfiles", "//libs-haskell/da-hs-base", ], ) @@ -141,7 +142,6 @@ da_haskell_test( srcs = ["src/DA/Test/Daml2js.hs"], args = [ "$(location //:yarn)", - "$(location //language-support/ts/daml-types:npm_package)", ], data = [ "//:yarn", diff --git a/language-support/ts/codegen/tests/src/DA/Test/Daml2js.hs b/language-support/ts/codegen/tests/src/DA/Test/Daml2js.hs index 7fd2966d286..dc254e8167f 100644 --- a/language-support/ts/codegen/tests/src/DA/Test/Daml2js.hs +++ b/language-support/ts/codegen/tests/src/DA/Test/Daml2js.hs @@ -11,7 +11,6 @@ import System.Process import System.Exit import DA.Bazel.Runfiles import qualified DA.Daml.LF.Ast.Version as LF -import DA.Directory import DA.Test.Daml2jsUtils import Data.List.Extra import qualified Data.Text.Extended as T @@ -32,17 +31,16 @@ typescriptEslintVersion = "^2.16.0" main :: IO () main = do - yarnPath : damlTypesPath : args <- getArgs + yarnPath : args <- getArgs damlc <- locateRunfiles (mainWorkspace "compiler" "damlc" exe "damlc") daml2js <- locateRunfiles (mainWorkspace "language-support" "ts" "codegen" exe "daml2js") yarn <- locateRunfiles (mainWorkspace yarnPath) - damlTypes <- locateRunfiles (mainWorkspace damlTypesPath) davl <- locateRunfiles ("davl" "released") oldPath <- getSearchPath withArgs args $ withEnv [ ("PATH", Just $ intercalate [searchPathSeparator] $ takeDirectory yarn : oldPath) , ("TASTY_NUM_THREADS", Just "1") - ] $ defaultMain (tests damlTypes yarn damlc daml2js davl) + ] $ defaultMain (tests yarn damlc daml2js davl) -- It may help to keep in mind for the following tests, this quick -- refresher on the layout of a simple project: @@ -69,8 +67,8 @@ main = do -- ... -- daml-types <-- referred to by the "resolutions" field in package.json -tests :: FilePath -> FilePath -> FilePath -> FilePath -> FilePath -> TestTree -tests damlTypes yarn damlc daml2js davl = testGroup "daml2js tests" +tests :: FilePath -> FilePath -> FilePath -> FilePath -> TestTree +tests yarn damlc daml2js davl = testGroup "daml2js tests" [ testCaseSteps "Different package, same name test" $ \step -> withTempDir $ \here -> do let grover = here "grover" @@ -255,8 +253,7 @@ tests damlTypes yarn damlc daml2js davl = testGroup "daml2js tests" where setupYarnEnvironment :: IO () setupYarnEnvironment = do - copyDirectory damlTypes "daml-types" - writeRootPackageJson Nothing ["daml2js"] + setupYarnEnv "." (Workspaces ["daml2js"]) [DamlTypes] buildProject :: [String] -> IO () buildProject args = callProcessSilent damlc (["build"] ++ args) diff --git a/language-support/ts/codegen/tests/src/DA/Test/Daml2jsUtils.hs b/language-support/ts/codegen/tests/src/DA/Test/Daml2jsUtils.hs index 80c81681d31..198c7c4d83d 100644 --- a/language-support/ts/codegen/tests/src/DA/Test/Daml2jsUtils.hs +++ b/language-support/ts/codegen/tests/src/DA/Test/Daml2jsUtils.hs @@ -1,20 +1,54 @@ -- Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. -- SPDX-License-Identifier: Apache-2.0 -module DA.Test.Daml2jsUtils (writeRootPackageJson) where +module DA.Test.Daml2jsUtils ( + TsLibrary (..), + Workspaces (..), + allTsLibraries, + setupYarnEnv, + ) where import qualified Data.Text.Extended as T import qualified Data.ByteString.Lazy as BSL -import qualified Data.HashMap.Strict as HMS +import Control.Monad +import DA.Bazel.Runfiles +import DA.Directory import Data.Aeson import System.FilePath --- The need for this utility comes up in at least the assistant --- integration and daml2js tests. -writeRootPackageJson :: Maybe FilePath -> [String] -> IO () -writeRootPackageJson dir workspaces = - BSL.writeFile (maybe "package.json" ( "package.json") dir) $ encode $ - object - [ "private" .= True - , "workspaces" .= map T.pack workspaces - , "resolutions" .= HMS.fromList ([ ("@daml/types", "file:daml-types") ] :: [(T.Text, T.Text)]) - ] +data TsLibrary + = DamlLedger + | DamlReact + | DamlTypes + deriving (Bounded, Enum) + +newtype Workspaces = Workspaces [FilePath] + +allTsLibraries :: [TsLibrary] +allTsLibraries = [minBound .. maxBound] + +tsLibraryName :: TsLibrary -> String +tsLibraryName = \case + DamlLedger -> "daml-ledger" + DamlReact -> "daml-react" + DamlTypes -> "daml-types" + +-- NOTE(MH): In some tests we need our TS libraries like `@daml/types` in +-- scope. We achieve this by putting a `package.json` file futrher up in the +-- directory tree. This file sets up a yarn workspace that includes the TS +-- libraries via the `resolutions` field. +setupYarnEnv :: FilePath -> Workspaces -> [TsLibrary] -> IO () +setupYarnEnv rootDir (Workspaces workspaces) tsLibs = do + tsLibsRoot <- locateRunfiles $ mainWorkspace "language-support" "ts" + forM_ tsLibs $ \tsLib -> do + let name = tsLibraryName tsLib + copyDirectory (tsLibsRoot name "npm_package") (rootDir name) + BSL.writeFile (rootDir "package.json") $ encode $ object + [ "private" .= True + , "workspaces" .= workspaces + , "resolutions" .= object + [ pkgName .= ("file:./" ++ name) + | tsLib <- tsLibs + , let name = tsLibraryName tsLib + , let pkgName = "@" <> T.replace "-" "/" (T.pack name) + ] + ]