From 2a079b716084f183c247dbbe0f8c3cb508c6f997 Mon Sep 17 00:00:00 2001 From: Robin Krom Date: Wed, 19 Aug 2020 15:59:18 +0200 Subject: [PATCH 1/3] replace yarn with npm in docs CHANGELOG_BEGIN CHANGELOG_END --- docs/source/app-dev/app-arch.rst | 8 ++++---- docs/source/getting-started/first-feature.rst | 8 ++++---- docs/source/getting-started/index.rst | 18 ++++++------------ docs/source/getting-started/testing.rst | 8 ++++---- release/RELEASE.md | 19 ++++++++----------- templates/create-daml-app/README.md.template | 10 +++++----- templates/create-daml-app/ui/.gitignore | 1 + 7 files changed, 32 insertions(+), 40 deletions(-) create mode 100644 templates/create-daml-app/ui/.gitignore diff --git a/docs/source/app-dev/app-arch.rst b/docs/source/app-dev/app-arch.rst index ee2ec1e704da..200ce970e56b 100644 --- a/docs/source/app-dev/app-arch.rst +++ b/docs/source/app-dev/app-arch.rst @@ -72,8 +72,8 @@ We provide two libraries to build your React frontend for a DAML application. | `@daml/ledger `_ | DAML ledger object to connect and directly submit commands to the ledger | +--------------------------------------------------------------+--------------------------------------------------------------------------+ -You can install any of these libraries by running ``yarn add `` in the ``ui`` directory of -your project, e.g. ``yarn add @daml/react``. Please explore the ``create-daml-app`` example project +You can install any of these libraries by running ``npm install `` in the ``ui`` directory of +your project, e.g. ``npm install @daml/react``. Please explore the ``create-daml-app`` example project to see the usage of these libraries. To make your life easy when interacting with the ledger, the DAML assistant can generate JavaScript @@ -81,7 +81,7 @@ libraries with TypeScript typings from the data types declared in the deployed D .. code-block:: bash - daml codegen js .daml/dist/ -o daml.js + daml codegen js .daml/dist/ -o ui/daml.js This command will generate a JavaScript library for each DALF in you DAR, containing metadata about types and templates in the DALF and TypeScript typings them. In ``create-daml-app``, ``ui/package.json`` refers to these @@ -111,7 +111,7 @@ Developer workflow The DAML SDK enables a local development environment with fast iteration cycles. If you run ``daml-reload-on-change.sh`` of the ``create-daml-app``, a local DAML sandbox ledger is started that is updated with your most recent DAML code on any change. Next, you can start your frontend in -development mode by changing to your ``ui`` directory and run ``yarn start``. This will reload your +development mode by changing to your ``ui`` directory and run ``npm start``. This will reload your frontend whenever you make changes to it. You can add unit tests for your DAML models by writing :ref:`DAML scenarios `. These will also be reevaluated on change. A typical DAML developer workflow is to diff --git a/docs/source/getting-started/first-feature.rst b/docs/source/getting-started/first-feature.rst index 68f9799d66aa..822a79d93869 100644 --- a/docs/source/getting-started/first-feature.rst +++ b/docs/source/getting-started/first-feature.rst @@ -74,14 +74,14 @@ Since we have changed our DAML code, we also need to rerun the TypeScript code g Open a new terminal and run the following commands:: daml build - daml codegen js .daml/dist/create-daml-app-0.1.0.dar -o daml.js + daml codegen js .daml/dist/create-daml-app-0.1.0.dar -o ui/daml.js The result is an up-to-date TypeScript interface to our DAML model, in particular to the new ``Message`` template and ``SendMessage`` choice. To make sure that Yarn picks up the newly generated JavaScript code, we have to run the following command in the ``ui`` directory:: - yarn install --force --frozen-lockfile + npm install --force --frozen-lockfile Once that command finishes, you have to close Visual Studio Code and restart it by running ``daml studio`` from the root directory of @@ -197,7 +197,7 @@ Then in the root ``create-daml-app`` folder run ``daml start``. As mentioned at the beginning of this *Getting Started with DAML* guide, DAML Sandbox uses an in-memory store, which means it loses its state when stopped or restarted. That means that all user data and follower relationships are lost. -If you have the frontend UI up and running you're all set. In case you don't have the UI running open a new terminal window and navigate to the ``create-daml-app/ui`` folder and run the ``yarn start`` command, which will start the UI. +If you have the frontend UI up and running you're all set. In case you don't have the UI running open a new terminal window and navigate to the ``create-daml-app/ui`` folder and run the ``npm start`` command, which will start the UI. Once you've done all these changes you should see the same login page as before at http://localhost:3000. .. figure:: images/create-daml-app-login-screen.png @@ -231,4 +231,4 @@ We've gone through the process of setting up a full-stack DAML app and implement As the next step we encourage you to really dig into the fundamentals of DAML and understand its core concepts such as parties, signatories, observers, and controllers. You can do that either by :doc:`going through our docs ` or by taking an `online course `_. After you've got a good grip on these concepts learn :doc:`how to conduct end-to-end testing of your app `. -Last but not least learn how to deploy your application to a ledger hosted on `project:DABL `_. \ No newline at end of file +Last but not least learn how to deploy your application to a ledger hosted on `project:DABL `_. diff --git a/docs/source/getting-started/index.rst b/docs/source/getting-started/index.rst index 4455302dc4ed..6c88875de9b1 100644 --- a/docs/source/getting-started/index.rst +++ b/docs/source/getting-started/index.rst @@ -32,14 +32,8 @@ Please make sure that you have the DAML SDK, Java 8 or higher, and Visual Studio You will also need some common software tools to build and interact with the template project. - `Git `_ version control system -- `Yarn `_ package manager for JavaScript. You have to have yarn version 1.10.0 or higher. - - Note: Ubuntu 17.04 and higher come with ``cmdtest`` package installed by default. If you are getting errors when installing yarn, you may want to run ``sudo apt remove cmdtest`` first and then install yarn. More information can be found `here `_ as well as in the official `yarn installation docs for Debian / Ubuntu `_ -- `NodeJS `_ in version 8.16 or higher. This will usually be - installed automatically as part of installing Yarn. - - Note: On Ubuntu 18.04, NodeJS 8.10 will be installed as part of installing Yarn which is too old. - You can find instructions for installing newer versions at `NodeSource `_. +- `Node `_ package manager for JavaScript. + Note: On Ubuntu 18.04, NodeJS 8.10 will be installed but its too old. - A terminal application for command line interaction @@ -69,12 +63,12 @@ Once the DAR file is created you will see this message in terminal ``Created .da Any commands starting with ``daml`` are using the :doc:`DAML Assistant `, a command line tool in the DAML SDK for building and running DAML apps. In order to connect the UI code to this DAML, we need to run a code generation step:: - daml codegen js .daml/dist/create-daml-app-0.1.0.dar -o daml.js + daml codegen js .daml/dist/create-daml-app-0.1.0.dar -o ui/daml.js -Now, changing to the ``ui`` folder, use Yarn to install the project dependencies:: +Now, changing to the ``ui`` folder, use ``npm`` to install the project dependencies:: cd ui - yarn install --force --frozen-lockfile + npm install --force --frozen-lockfile This step may take a couple of moments (it's worth it!). You should see ``success Saved lockfile.`` in the output if everything worked as expected. @@ -98,7 +92,7 @@ We'll leave these processes running to serve requests from our UI. In a second terminal, navigate to the ``create-daml-app/ui`` folder and run the application:: cd ui - yarn start + npm start This starts the web UI connected to the running Sandbox and JSON API server. The command should automatically open a window in your default browser at http://localhost:3000. diff --git a/docs/source/getting-started/testing.rst b/docs/source/getting-started/testing.rst index f69bc715bca7..c0a951350fc3 100644 --- a/docs/source/getting-started/testing.rst +++ b/docs/source/getting-started/testing.rst @@ -18,7 +18,7 @@ Of course there are more to choose from, but this is one combination that works. To install Puppeteer and some other testing utilities we are going to use, run the following command in the ``ui`` directory:: - yarn add --dev puppeteer wait-on @types/jest @types/node @types/puppeteer @types/wait-on + npm add --only=dev puppeteer wait-on @types/jest @types/node @types/puppeteer @types/wait-on Setting up our tests @@ -31,7 +31,7 @@ To run this test suite, create a new file ``ui/src/index.test.ts``, copy the code in this section into that file and run the following command in the ``ui`` folder:: - yarn test + npm test The actual tests are the clauses beginning with ``test``. You can scroll down to the important ones with the following descriptions (the first argument to each ``test``): @@ -43,11 +43,11 @@ You can scroll down to the important ones with the following descriptions (the f Before this, we need to set up the environment in which the tests run. At the top of the file we have some global state that we use throughout. -Specifically, we have child processes for the ``daml start`` and ``yarn start`` commands, which run for the duration of our tests. +Specifically, we have child processes for the ``daml start`` and ``npm start`` commands, which run for the duration of our tests. We also have a single Puppeteer browser that we share among tests, opening new browser pages for each one. The ``beforeAll()`` section is a function run once before any of the tests run. -We use it to spawn the ``daml start`` and ``yarn start`` processes and launch the browser. +We use it to spawn the ``daml start`` and ``npm start`` processes and launch the browser. On the other hand the ``afterAll()`` section is used to shut down these processes and close the browser. This step is important to prevent child processes persisting in the background after our program has finished. diff --git a/release/RELEASE.md b/release/RELEASE.md index c9da6aedaf1e..f83011f7ae2e 100644 --- a/release/RELEASE.md +++ b/release/RELEASE.md @@ -87,11 +87,10 @@ patches we backport to the 1.0 release branch). > > [adoptopenjdk]: https://adoptopenjdk.net > - > [node], [yarn] and [VS Code] installers all add to PATH by default so - > those are just download > next > next installations. + > [node] and [VS Code] installers add to PATH by default so those are just + > download > next > next installations. > > [node]: https://nodejs.org/en/ - > [yarn]: https://classic.yarnpkg.com/en/docs/install/ > [VS Code]: https://code.visualstudio.com > > All of the commands mentioned in this document can be run from a simple @@ -101,8 +100,6 @@ patches we backport to the 1.0 release branch). - [Visual Studio Code, Java-SDK](https://docs.daml.com/getting-started/installation.html) - [Node.js](https://nodejs.org/en/download/) - Just the bare install; no need to build C dependencies. - - [Yarn](https://classic.yarnpkg.com/en/docs/install/) - - Install Node.js first. 1. Run `daml version --assistant=yes` and verify that the new version is selected as the assistant version and the default version for new projects. @@ -131,9 +128,9 @@ patches we backport to the 1.0 release branch). 1. In a new terminal, from the `ui` folder: - 1. `yarn install` + 1. `npm install` - 1. `yarn start` + 1. `npm start` 1. Open two browser windows (you want to see them simultaneously ideally) at `localhost:3000`. @@ -147,7 +144,7 @@ patches we backport to the 1.0 release branch). the list of users `Bob` is following. Verify in the other browser window that `Bob` shows up in `Alice`’s network. - 1. Kill the `daml start` process and the `yarn start` process. + 1. Kill the `daml start` process and the `npm start` process. 1. Open the your first feature section of the GSG, e.g., from https://docs.daml.com/$VERSION/getting-started/first-feature.html @@ -165,7 +162,7 @@ patches we backport to the 1.0 release branch). 1. Run `daml build` then `daml codegen js .daml/dist/create-daml-app-0.1.0.dar -o daml.js` from the project root. - 1. From the `ui` directory run `yarn install --force --frozen-lockfile`. + 1. From the `ui` directory run `npm install --force --frozen-lockfile`. 1. Run `code .` from the project root directory (the extension is already installed, no need to use `daml studio`). @@ -179,7 +176,7 @@ patches we backport to the 1.0 release branch). 1. Run `daml start` from the project root directory. - 1. In a separate terminal, run `yarn start` from the `ui` directory. + 1. In a separate terminal, run `npm start` from the `ui` directory. 1. As before, open two browser windows at `localhost:3000` and log in as `Alice` and `Bob`. @@ -199,7 +196,7 @@ patches we backport to the 1.0 release branch). 1. Verify that `Bob` has received the message in the other window. 1. You can now close both browser windows and both running processes (`daml - start` and `yarn start`). + start` and `npm start`). 1. Don't forget to run this on the other platform! E.g. if you just ran through on Linux or macOS, you still need to run on Windows, and vice diff --git a/templates/create-daml-app/README.md.template b/templates/create-daml-app/README.md.template index 8406b0414401..1d3deaa7ed02 100644 --- a/templates/create-daml-app/README.md.template +++ b/templates/create-daml-app/README.md.template @@ -24,7 +24,7 @@ replaceable. ## Getting started Before you can run the application, you need to install the -[yarn](https://yarnpkg.com/en/docs/install) package manager for JavaScript. +[Node](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) package manager for JavaScript. There are two steps to build the project. First, we need to generate TypeScript code bindings for the compiled DAML model. @@ -38,8 +38,8 @@ The latter command generates TypeScript packages in the `daml.js` directory. Next, navigate to the `ui` directory and install the dependencies and build the app by running ``` cd ui -yarn install -yarn build +npm install +npm run-script build ``` The last step is not absolutely necessary but useful to check that the app compiles. @@ -52,7 +52,7 @@ This must continue running to serve ledger requests. Then in a second terminal window in the `ui` directory, start the UI server via ``` -yarn start +npm start ``` This should open a browser window with a login screen. If it doesn't, you can manually point your browser to http://localhost:3000. @@ -88,7 +88,7 @@ To upload the UI, create a ZIP file containing all your UI assets by executing ``` daml build daml codegen js .daml/dist/__PROJECT_NAME__-0.1.0.dar -o daml.js -(cd ui && yarn build && zip -r ../__PROJECT_NAME__-ui.zip build) +(cd ui && npm run-script build && zip -r ../__PROJECT_NAME__-ui.zip build) ``` at the root of the repository. Afterwards, select the "UI Assets" tab of your chosen ledger on the DABL website, upload the ZIP file diff --git a/templates/create-daml-app/ui/.gitignore b/templates/create-daml-app/ui/.gitignore new file mode 100644 index 000000000000..56a0db160af0 --- /dev/null +++ b/templates/create-daml-app/ui/.gitignore @@ -0,0 +1 @@ +daml.js/ From fa0c37282c81064b00fb80e4cd8c82536d2c1441 Mon Sep 17 00:00:00 2001 From: Robin Krom Date: Mon, 7 Sep 2020 10:46:51 +0200 Subject: [PATCH 2/3] updating assistant and compatibility tests --- .../bazel_tools/create-daml-app/BUILD.bazel | 3 +- .../bazel_tools/create-daml-app/Main.hs | 175 ++++++++++++------ .../bazel_tools/create-daml-app/index.test.ts | 9 +- .../bazel_tools/create_daml_app_test.sh | 16 +- compatibility/bazel_tools/testing.bzl | 6 +- daml-assistant/integration-tests/BUILD.bazel | 19 +- .../DA/Daml/Assistant/CreateDamlAppTests.hs | 131 ++++++++----- .../codegen/tests/src/DA/Test/Daml2jsUtils.hs | 1 + .../index.test.ts | 12 +- templates/create-daml-app/README.md.template | 4 +- .../create-daml-app/ui/package.json.template | 2 +- 11 files changed, 253 insertions(+), 125 deletions(-) diff --git a/compatibility/bazel_tools/create-daml-app/BUILD.bazel b/compatibility/bazel_tools/create-daml-app/BUILD.bazel index 4d36179615dd..88b79601d29a 100644 --- a/compatibility/bazel_tools/create-daml-app/BUILD.bazel +++ b/compatibility/bazel_tools/create-daml-app/BUILD.bazel @@ -22,13 +22,14 @@ da_haskell_binary( "filepath", "jwt", "mtl", - "unix-compat", "process", "tagged", "tar-conduit", "tasty", "tasty-hunit", "text", + "unix-compat", + "unordered-containers", ], visibility = ["//visibility:public"], deps = [ diff --git a/compatibility/bazel_tools/create-daml-app/Main.hs b/compatibility/bazel_tools/create-daml-app/Main.hs index 81288642b1c6..b40aae7c6226 100644 --- a/compatibility/bazel_tools/create-daml-app/Main.hs +++ b/compatibility/bazel_tools/create-daml-app/Main.hs @@ -8,12 +8,14 @@ import Control.Monad import DA.Test.Process import DA.Test.Tar import DA.Test.Util -import qualified Data.Aeson as Aeson import qualified Data.Aeson.Extra as Aeson import Data.Conduit ((.|), runConduitRes) +import qualified Data.ByteString as BS +import qualified Data.ByteString.Lazy as BSL import qualified Data.Conduit.Combinators as Conduit import qualified Data.Conduit.Tar as Tar import qualified Data.Conduit.Zlib as Zlib +import qualified Data.HashMap.Strict as HMS import Data.Maybe import Data.Proxy import Data.Tagged @@ -21,6 +23,7 @@ import qualified Data.Text as T import System.Directory.Extra import System.Environment.Blank import System.FilePath +import System.Info.Extra import System.IO.Extra import System.Process import Test.Tasty @@ -33,7 +36,8 @@ data Tools = Tools , damlTypesPath :: FilePath , damlReactPath :: FilePath , messagingPatch :: FilePath - , yarnPath :: FilePath + , npmPath :: FilePath + , nodePath :: FilePath , patchPath :: FilePath , testDepsPath :: FilePath , testTsPath :: FilePath @@ -75,12 +79,19 @@ instance IsOption MessagingPatchOption where optionName = Tagged "messaging-patch" optionHelp = Tagged "path to messaging patch" -newtype YarnOption = YarnOption FilePath -instance IsOption YarnOption where - defaultValue = YarnOption "" - parseValue = Just . YarnOption - optionName = Tagged "yarn" - optionHelp = Tagged "path to yarn" +newtype NpmOption = NpmOption FilePath +instance IsOption NpmOption where + defaultValue = NpmOption "" + parseValue = Just . NpmOption + optionName = Tagged "npm" + optionHelp = Tagged "path to npm" + +newtype NodeOption = NodeOption FilePath +instance IsOption NodeOption where + defaultValue = NodeOption "" + parseValue = Just . NodeOption + optionName = Tagged "node" + optionHelp = Tagged "path to node" newtype PatchOption = PatchOption FilePath instance IsOption PatchOption where @@ -117,7 +128,8 @@ withTools tests = do askOption $ \(DamlTypesOption damlTypesPath) -> do askOption $ \(DamlReactOption damlReactPath) -> do askOption $ \(MessagingPatchOption messagingPatch) -> do - askOption $ \(YarnOption yarnPath) -> do + askOption $ \(NpmOption npmPath) -> do + askOption $ \(NodeOption nodePath) -> do askOption $ \(PatchOption patchPath) -> do askOption $ \(TestDepsOption testDepsPath) -> do askOption $ \(TestTsOption testTsPath) -> do @@ -136,7 +148,8 @@ withTools tests = do , damlTypesPath , damlReactPath , messagingPatch - , yarnPath + , npmPath + , nodePath , patchPath , testDepsPath , testTsPath @@ -145,8 +158,8 @@ withTools tests = do tests tools main :: IO () -main = withTempDir $ \yarnCache -> do - setEnv "YARN_CACHE_FOLDER" yarnCache True +main = withTempDir $ \npmCache -> do + setEnv "npm_config_cache" npmCache True setEnv "TASTY_NUM_THREADS" "1" True let options = [ Option @DamlOption Proxy @@ -154,7 +167,8 @@ main = withTempDir $ \yarnCache -> do , Option @DamlTypesOption Proxy , Option @DamlReactOption Proxy , Option @MessagingPatchOption Proxy - , Option @YarnOption Proxy + , Option @NpmOption Proxy + , Option @NodeOption Proxy , Option @PatchOption Proxy , Option @TestDepsOption Proxy , Option @TestTsOption Proxy @@ -167,48 +181,116 @@ main = withTempDir $ \yarnCache -> do [ test getTools ] where - test getTools = testCaseSteps "Getting Started Guide" $ \step -> withTempDir $ \tmpDir -> do + test getTools = testCaseSteps "Getting Started Guide" $ \step -> withTempDir $ \tmpDir' -> do + -- npm gets confused when the temporary directory is not under 'private' on mac. + let tmpDir + | isMac = "/private" <> tmpDir' + | otherwise = tmpDir' Tools{..} <- getTools setEnv "CI" "yes" True step "Create app from template" withCurrentDirectory tmpDir $ do callProcess damlBinary ["new", "create-daml-app", "create-daml-app"] let cdaDir = tmpDir "create-daml-app" + let uiDir = cdaDir "ui" step "Patch the application code with messaging feature" withCurrentDirectory cdaDir $ do callProcessSilent patchPath ["-p2", "-i", messagingPatch] forM_ ["MessageEdit", "MessageList"] $ \messageComponent -> assertFileExists ("ui" "src" "components" messageComponent <.> "tsx") step "Extract codegen output" - runConduitRes - $ Conduit.sourceFile codegenPath - .| Zlib.ungzip - .| Tar.untar (restoreFile (\a b -> fail (T.unpack $ a <> b)) (cdaDir "daml.js")) - withCurrentDirectory (cdaDir "ui") $ do + extractTarGz codegenPath $ uiDir "daml.js" + -- we patch all the 'package.json' files to point to the local versions of the TypeScript + -- libraries. + genFiles <- listFilesRecursive $ uiDir "daml.js" + forM_ [file | file <- genFiles, takeFileName file == "package.json"] (patchTsDependencies uiDir) + withCurrentDirectory uiDir $ do step "Set up libraries and workspaces" - setupYarnEnv tmpDir (Workspaces ["create-daml-app/ui"]) - [(DamlLedger, damlLedgerPath), (DamlReact, damlReactPath), (DamlTypes, damlTypesPath)] + setupNpmEnv uiDir [(DamlTypes, damlTypesPath) + , (DamlLedger, damlLedgerPath) + , (DamlReact, damlReactPath) + ] step "Install Jest, Puppeteer and other dependencies" addTestDependencies "package.json" testDepsPath - retry 3 (callProcessSilent yarnPath ["install"]) + patchTsDependencies uiDir "package.json" + -- use '--scripts-prepend-node-path' to make sure we are using the correct 'node' binary + retry 3 (callProcessSilent npmPath ["install", "--scripts-prepend-node-path"]) step "Run Puppeteer end-to-end tests" - copyFile testTsPath (cdaDir "ui" "src" "index.test.ts") - callProcess yarnPath ["run", "test", "--ci", "--all"] + copyFile testTsPath (uiDir "src" "index.test.ts") + -- we need 'npm-cli.js' in the path for the following test + mbOldPath <- getEnv "PATH" + setEnv "PATH" (takeDirectory npmPath <> (searchPathSeparator : fromMaybe "" mbOldPath)) True + callProcess npmPath ["run", "test", "--ci", "--all", "--scripts-prepend-node-path"] addTestDependencies :: FilePath -> FilePath -> IO () addTestDependencies packageJsonFile extraDepsFile = do packageJson <- readJsonFile packageJsonFile extraDeps <- readJsonFile extraDepsFile let newPackageJson = Aeson.lodashMerge packageJson extraDeps - Aeson.encodeFile packageJsonFile newPackageJson - where - readJsonFile :: FilePath -> IO Aeson.Value - readJsonFile path = do - -- Read file strictly to avoid lock being held when we subsequently write to it. - mbContent <- Aeson.decodeFileStrict' path - case mbContent of - Nothing -> fail ("Could not decode JSON object from " <> path) - Just val -> return val + BSL.writeFile packageJsonFile (Aeson.encode newPackageJson) + +readJsonFile :: FilePath -> IO Aeson.Value +readJsonFile path = do + -- Read file strictly to avoid lock being held when we subsequently write to it. + content <- BSL.fromStrict <$> BS.readFile path + case Aeson.decode content of + Nothing -> error ("Could not decode JSON object from " <> path) + Just val -> return val + +extractTarGz :: FilePath -> FilePath -> IO () +extractTarGz targz outDir = do + runConduitRes + $ Conduit.sourceFile targz + .| Zlib.ungzip + .| Tar.untar (restoreFile (\a b -> fail (T.unpack $ a <> b)) outDir) + +setupNpmEnv :: FilePath -> [(TsLibrary, FilePath)] -> IO () +setupNpmEnv uiDir libs = do + forM_ libs $ \(tsLib, path) -> do + let name = tsLibraryName tsLib + let uiLibPath = uiDir name + extractTarGz path uiLibPath + patchTsDependencies uiDir $ uiLibPath "package.json" + +-- | Overwrite dependencies to our TypeScript libraries to point to local file dependencies in the +-- 'ui' directory in the specified package.json file. +patchTsDependencies :: FilePath -> FilePath -> IO () +patchTsDependencies uiDir packageJsonFile = do + packageJson0 <- readJsonFile packageJsonFile + case packageJson0 of + Aeson.Object packageJson -> + case HMS.lookup "dependencies" packageJson of + Just (Aeson.Object dependencies) -> do + let depNames = HMS.keys dependencies + -- patch dependencies to point to local files if they are present in the package.json + let patchedDeps = + HMS.fromList + ([ ( "@daml.js/create-daml-app" + , Aeson.String $ + T.pack $ + "file:" <> "./daml.js/create-daml-app-0.1.0") + | "@daml.js/create-daml-app" `elem` depNames + ] ++ + [ (depName, Aeson.String $ T.pack $ "file:" <> libRelPath) + | tsLib <- allTsLibraries + , let libName = tsLibraryName tsLib + , let libPath = uiDir libName + , let libRelPath = + makeRelative (takeDirectory packageJsonFile) libPath + , let depName = T.replace "-" "/" $ T.pack $ "@" <> libName + , depName `elem` depNames + ]) `HMS.union` + dependencies + let newPackageJson = + Aeson.Object $ + HMS.insert "dependencies" (Aeson.Object patchedDeps) packageJson + -- Make sure we have write permissions before writing + p <- getPermissions packageJsonFile + setPermissions packageJsonFile (setOwnerWritable True p) + BSL.writeFile packageJsonFile (Aeson.encode newPackageJson) + Nothing -> pure () -- Nothing to patch + _otherwise -> error $ "malformed package.json:" <> show packageJson + _otherwise -> error $ "malformed package.json:" <> show packageJson0 data TsLibrary = DamlLedger @@ -216,34 +298,11 @@ data TsLibrary | 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 further 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, FilePath)] -> IO () -setupYarnEnv rootDir (Workspaces workspaces) tsLibs = do - forM_ tsLibs $ \(tsLib, libLocation) -> do - let name = tsLibraryName tsLib - removePathForcibly (rootDir name) - runConduitRes - $ Conduit.sourceFile libLocation - .| Zlib.ungzip - .| Tar.untar (restoreFile (\a b -> fail (T.unpack $ a <> b)) (rootDir name)) - Aeson.encodeFile (rootDir "package.json") $ Aeson.object - [ "private" Aeson..= True - , "workspaces" Aeson..= workspaces - , "resolutions" Aeson..= Aeson.object - [ pkgName Aeson..= ("file:./" ++ name) - | (tsLib, _) <- tsLibs - , let name = tsLibraryName tsLib - , let pkgName = "@" <> T.replace "-" "/" (T.pack name) - ] - ] diff --git a/compatibility/bazel_tools/create-daml-app/index.test.ts b/compatibility/bazel_tools/create-daml-app/index.test.ts index b26c6a20c87b..9fef344fa3c9 100644 --- a/compatibility/bazel_tools/create-daml-app/index.test.ts +++ b/compatibility/bazel_tools/create-daml-app/index.test.ts @@ -36,7 +36,7 @@ const UI_PORT = 3000; let sandbox: ChildProcess | undefined = undefined; let jsonApi: ChildProcess | undefined = undefined; -// `yarn start` process +// `npm start` process let uiProc: ChildProcess | undefined = undefined; // Chrome browser that we run in headless mode @@ -104,6 +104,8 @@ const killTree = async (p: ChildProcess) => { const detached = process.platform != "win32"; +const npmExeName = process.platform == "win32" ? "npm" : "npm-cli.js"; + // Start the DAML and UI processes before the tests begin. // To reduce test times, we reuse the same processes between all the tests. // This means we need to use a different set of parties and a new browser page for each test. @@ -155,12 +157,15 @@ beforeAll(async () => { ); await waitOn({ resources: [`file:../${JSON_API_PORT_FILE_NAME}`] }); - uiProc = spawn("yarn", ["start"], { + + uiProc = + spawn(npmExeName, ["start"], { env: { ...process.env, BROWSER: "none" }, stdio: "inherit", shell: true, detached: detached, }); + await waitOn({ resources: [`tcp:localhost:${UI_PORT}`] }); // Launch a single browser for all tests. diff --git a/compatibility/bazel_tools/create_daml_app_test.sh b/compatibility/bazel_tools/create_daml_app_test.sh index 171274942997..3a44788eedbf 100755 --- a/compatibility/bazel_tools/create_daml_app_test.sh +++ b/compatibility/bazel_tools/create_daml_app_test.sh @@ -32,12 +32,13 @@ DAML_TYPES="$(rlocation "$TEST_WORKSPACE/$7")" DAML_LEDGER="$(rlocation "$TEST_WORKSPACE/$8")" DAML_REACT="$(rlocation "$TEST_WORKSPACE/$9")" MESSAGING_PATCH="$(rlocation "$TEST_WORKSPACE/${10}")" -YARN="$(rlocation "$TEST_WORKSPACE/${11}")" -PATCH="$(rlocation "$TEST_WORKSPACE/${12}")" -TEST_DEPS="$(rlocation "$TEST_WORKSPACE/${13}")" -TEST_TS="$(rlocation "$TEST_WORKSPACE/${14}")" -CODEGEN_OUTPUT="$(canonicalize_rlocation "${15}")" -export DAR_PATH="$(canonicalize_rlocation "${16}")" +NPM="$(rlocation "$TEST_WORKSPACE/${11}")" +NODE="$(rlocation "$TEST_WORKSPACE/${12}")" +PATCH="$(rlocation "$TEST_WORKSPACE/${13}")" +TEST_DEPS="$(rlocation "$TEST_WORKSPACE/${14}")" +TEST_TS="$(rlocation "$TEST_WORKSPACE/${15}")" +CODEGEN_OUTPUT="$(canonicalize_rlocation "${16}")" +export DAR_PATH="$(canonicalize_rlocation "${17}")" "$RUNNER" \ --daml "$DAML" \ @@ -45,7 +46,8 @@ export DAR_PATH="$(canonicalize_rlocation "${16}")" --daml-ledger "$DAML_LEDGER" \ --daml-react "$DAML_REACT" \ --messaging-patch "$MESSAGING_PATCH" \ - --yarn "$YARN" \ + --npm "$NPM" \ + --node "$NODE" \ --patch "$PATCH" \ --test-deps "$TEST_DEPS" \ --test-ts "$TEST_TS" \ diff --git a/compatibility/bazel_tools/testing.bzl b/compatibility/bazel_tools/testing.bzl index 43d103bb3523..5f66f79db63e 100644 --- a/compatibility/bazel_tools/testing.bzl +++ b/compatibility/bazel_tools/testing.bzl @@ -271,7 +271,8 @@ def create_daml_app_test( "$(rootpath %s)" % daml_ledger, "$(rootpath %s)" % daml_react, "$(rootpath %s)" % messaging_patch, - "$(rootpath @nodejs//:yarn)", + "$(rootpath @nodejs//:npm_bin)", + "$(rootpath @nodejs//:node)", "$(rootpath @patch_dev_env//:patch)", "$(rootpath //bazel_tools/create-daml-app:testDeps.json)", "$(rootpath //bazel_tools/create-daml-app:index.test.ts)", @@ -280,7 +281,8 @@ def create_daml_app_test( ], data = data + depset(direct = [ "//bazel_tools/create-daml-app:runner", - "@nodejs//:yarn", + "@nodejs//:npm_bin", + "@nodejs//:node", "@patch_dev_env//:patch", "//bazel_tools/create-daml-app:testDeps.json", "//bazel_tools/create-daml-app:index.test.ts", diff --git a/daml-assistant/integration-tests/BUILD.bazel b/daml-assistant/integration-tests/BUILD.bazel index 690a51e3e2be..f33b5c7b4f2b 100644 --- a/daml-assistant/integration-tests/BUILD.bazel +++ b/daml-assistant/integration-tests/BUILD.bazel @@ -179,6 +179,7 @@ da_haskell_library( "tagged", "tasty", "tasty-hunit", + "unordered-containers", ], visibility = ["//visibility:public"], deps = [ @@ -194,8 +195,14 @@ da_haskell_test( name = "create-daml-app-tests", timeout = "long", srcs = ["src/DA/Daml/Assistant/CreateDamlAppTestsMain.hs"], - args = ["$(location //:yarn)"], - data = ["//:yarn"], + args = [ + "$(location @nodejs//:npm_bin)", + "$(location @nodejs//:node_bin)", + ], + data = [ + "@nodejs//:node_bin", + "@nodejs//:npm_bin", + ], hackage_deps = ["base"], main_function = "DA.Daml.Assistant.CreateDamlAppTestsMain.main", # Exclusive until we stop hardcoding port numbers in index.test.ts @@ -208,11 +215,15 @@ da_haskell_test( timeout = "long", srcs = ["src/DA/Daml/Assistant/CreateDamlAppTestsMain.hs"], args = [ - "$(location //:yarn)", + "$(location @nodejs//:npm_bin)", + "$(location @nodejs//:node_bin)", "--project-name", "not-create-daml-app", ], - data = ["//:yarn"], + data = [ + "@nodejs//:node_bin", + "@nodejs//:npm_bin", + ], hackage_deps = ["base"], main_function = "DA.Daml.Assistant.CreateDamlAppTestsMain.main", # Exclusive until we stop hardcoding port numbers in index.test.ts diff --git a/daml-assistant/integration-tests/src/DA/Daml/Assistant/CreateDamlAppTests.hs b/daml-assistant/integration-tests/src/DA/Daml/Assistant/CreateDamlAppTests.hs index 8cb06f2079eb..dafc8a00a7db 100644 --- a/daml-assistant/integration-tests/src/DA/Daml/Assistant/CreateDamlAppTests.hs +++ b/daml-assistant/integration-tests/src/DA/Daml/Assistant/CreateDamlAppTests.hs @@ -8,6 +8,7 @@ import Data.Aeson import Data.Aeson.Extra.Merge import qualified Data.ByteString.Lazy as BSL import qualified Data.ByteString as BS +import qualified Data.HashMap.Strict as HMS import Data.List.Extra import Data.Proxy (Proxy (..)) import Data.Tagged (Tagged (..)) @@ -23,6 +24,7 @@ import Test.Tasty.Options import DA.Bazel.Runfiles import DA.Daml.Assistant.IntegrationTestUtils +import DA.Directory import DA.Test.Daml2jsUtils import DA.Test.Process (callCommandSilent) import DA.Test.Util @@ -36,16 +38,18 @@ instance IsOption ProjectName where optionHelp = Tagged "name of the project" main :: IO () -main = withTempDir $ \yarnCache -> do - setEnv "YARN_CACHE_FOLDER" yarnCache True +main = withTempDir $ \npmCache -> do + setEnv "npm_config_cache" npmCache True limitJvmMemory defaultJvmMemoryLimits - yarn : args <- getArgs + npm : node : args <- getArgs javaPath <- locateRunfiles "local_jdk/bin" oldPath <- getSearchPath - yarnPath <- takeDirectory <$> locateRunfiles (mainWorkspace yarn) + npmPath <- takeDirectory <$> locateRunfiles (mainWorkspace npm) + -- we need node in scope for the post install step of babel + nodePath <- takeDirectory <$> locateRunfiles (mainWorkspace node) let ingredients = defaultIngredients ++ [includingOptions [Option @ProjectName Proxy]] withArgs args (withEnv - [ ("PATH", Just $ intercalate [searchPathSeparator] (javaPath : yarnPath : oldPath)) + [ ("PATH", Just $ intercalate [searchPathSeparator] (javaPath : npmPath : nodePath : oldPath)) , ("TASTY_NUM_THREADS", Just "1") ] $ defaultMainWithIngredients ingredients tests) @@ -56,34 +60,37 @@ tests = testGroup "Create DAML App tests" [gettingStartedGuideTest projectName | not isWindows] where gettingStartedGuideTest projectName = testCaseSteps "Getting Started Guide" $ \step -> - withTempDir $ \tmpDir -> do + withTempDir $ \tmpDir' -> do + -- npm gets confused when the temp dir is not under /private on mac. + let tmpDir + | isMac = "/private" <> tmpDir' + | otherwise = tmpDir' step "Create app from template" withCurrentDirectory tmpDir $ do callCommandSilent $ "daml new " <> projectName <> " --template create-daml-app" let cdaDir = tmpDir projectName + let uiDir = cdaDir "ui" + -- We need all local libraries to be in the root dir of the node project + setupNpmEnv uiDir -- First test the base application (without the user-added feature). withCurrentDirectory cdaDir $ do step "Build DAML model for base application" callCommandSilent "daml build" - step "Set up TypeScript libraries and Yarn workspaces for codegen" - setupYarnEnv tmpDir (Workspaces [projectName <> "/daml.js"]) [DamlTypes, DamlLedger] step "Run JavaScript codegen" - callCommandSilent $ "daml codegen js -o daml.js .daml/dist/" <> projectName <> "-0.1.0.dar" - assertFileDoesNotExist (cdaDir "ui" "build" "index.html") - withCurrentDirectory (cdaDir "ui") $ do - -- NOTE(MH): We set up the yarn env again to avoid having all the - -- dependencies of the UI already in scope when `daml2js` runs - -- `yarn install`. Some of the UI dependencies are a bit flaky to - -- install and might need some retries. - step "Set up libraries and workspaces again for UI build" - setupYarnEnv tmpDir (Workspaces [projectName <> "/ui"]) allTsLibraries + callCommandSilent $ "daml codegen js -o ui/daml.js .daml/dist/" <> projectName <> "-0.1.0.dar" + -- We patch all package.json files to point to local files for our TypeScript libraries. + genFiles <- listFilesRecursive "ui/daml.js" + forM_ [file | file <- genFiles, takeFileName file == "package.json"] (patchTsDependencies uiDir) + assertFileDoesNotExist (uiDir "build" "index.html") + withCurrentDirectory uiDir $ do + patchTsDependencies uiDir "package.json" step "Install dependencies for UI" - retry 3 (callCommandSilent "yarn install") + retry 3 (callCommandSilent "npm-cli.js install") step "Run linter" - callCommandSilent "yarn lint --max-warnings 0" + callCommandSilent "npm-cli.js run-script lint -- --max-warnings 0" step "Build the application UI" - callCommandSilent "yarn build" - assertFileExists (cdaDir "ui" "build" "index.html") + callCommandSilent "npm-cli.js run-script build" + assertFileExists (uiDir "build" "index.html") -- Now test that the messaging feature works by applying the necessary -- changes and testing in the same way as above. @@ -98,33 +105,32 @@ tests = assertFileExists ("ui" "src" "components" messageComponent <.> "tsx") step "Build the new DAML model" callCommandSilent "daml build" - step "Set up TypeScript libraries and Yarn workspaces for codegen again" - setupYarnEnv tmpDir (Workspaces [projectName <> "/daml.js"]) [DamlTypes, DamlLedger] step "Run JavaScript codegen for new DAML model" - callCommandSilent $ "daml codegen js -o daml.js .daml/dist/" <> projectName <> "-0.1.0.dar" - withCurrentDirectory (cdaDir "ui") $ do - step "Set up libraries and workspaces again for UI build" - setupYarnEnv tmpDir (Workspaces [projectName <> "/ui"]) allTsLibraries + callCommandSilent $ "daml codegen js -o ui/daml.js .daml/dist/" <> projectName <> "-0.1.0.dar" + genFiles <- listFilesRecursive "ui/daml.js" + forM_ [file | file <- genFiles, takeFileName file == "package.json"] (patchTsDependencies uiDir) + withCurrentDirectory uiDir $ do + patchTsDependencies uiDir "package.json" step "Install UI dependencies again, forcing rebuild of generated code" - callCommandSilent "yarn install --force --frozen-lockfile" + callCommandSilent "npm-cli.js install --force --frozen-lockfile" step "Run linter again" - callCommandSilent "yarn lint --max-warnings 0" + callCommandSilent "npm-cli.js run-script lint -- --max-warnings 0" step "Build the new UI" - callCommandSilent "yarn build" + callCommandSilent "npm-cli.js run-script build" -- Run end to end testing for the app. withCurrentDirectory (cdaDir "ui") $ do step "Install Jest, Puppeteer and other dependencies" extraDepsFile <- locateRunfiles (mainWorkspace "templates" "create-daml-app-test-resources" "testDeps.json") - addTestDependencies (cdaDir "ui" "package.json") extraDepsFile - retry 3 (callCommandSilent "yarn install") + addTestDependencies (uiDir "package.json") extraDepsFile + retry 3 (callCommandSilent "npm-cli.js install") step "Run Puppeteer end-to-end tests" testFile <- locateRunfiles (mainWorkspace "templates" "create-daml-app-test-resources" "index.test.ts") testFileContent <- T.readFileUtf8 testFile T.writeFileUtf8 - (cdaDir "ui" "src" "index.test.ts") + (uiDir "src" "index.test.ts") (T.replace "create-daml-app" (T.pack projectName) testFileContent) - callCommandSilent "CI=yes yarn run test --ci --all" + callCommandSilent "CI=yes npm-cli.js run-script test -- --ci --all" addTestDependencies :: FilePath -> FilePath -> IO () addTestDependencies packageJsonFile extraDepsFile = do @@ -132,11 +138,52 @@ addTestDependencies packageJsonFile extraDepsFile = do extraDeps <- readJsonFile extraDepsFile let newPackageJson = lodashMerge packageJson extraDeps BSL.writeFile packageJsonFile (encode newPackageJson) - where - readJsonFile :: FilePath -> IO Value - readJsonFile path = do - -- Read file strictly to avoid lock being held when we subsequently write to it. - content <- BSL.fromStrict <$> BS.readFile path - case decode content of - Nothing -> error ("Could not decode JSON object from " <> path) - Just val -> return val + +readJsonFile :: FilePath -> IO Value +readJsonFile path = do + -- Read file strictly to avoid lock being held when we subsequently write to it. + content <- BSL.fromStrict <$> BS.readFile path + case decode content of + Nothing -> error ("Could not decode JSON object from " <> path) + Just val -> return val + +setupNpmEnv :: FilePath -> IO () +setupNpmEnv uiDir = do + tsLibsRoot <- locateRunfiles $ mainWorkspace "language-support" "ts" + forM_ allTsLibraries $ \tsLib -> do + let name = tsLibraryName tsLib + let uiLibPath = uiDir name + copyDirectory (tsLibsRoot name "npm_package") uiLibPath + patchTsDependencies uiDir $ uiLibPath "package.json" + +-- | Overwrite dependencies to our ts libraries to point to local file dependencies in the ui +-- director in the specified package.json file. +patchTsDependencies :: FilePath -> FilePath -> IO () +patchTsDependencies uiDir packageJsonFile = do + packageJson0 <- readJsonFile packageJsonFile + case packageJson0 of + Object packageJson -> + case HMS.lookup "dependencies" packageJson of + Just (Object dependencies) -> do + let depNames = HMS.keys dependencies + let patchedDeps = + HMS.fromList + [ (depName, String $ T.pack $ "file:" <> libRelPath) + | tsLib <- allTsLibraries + , let libName = tsLibraryName tsLib + , let libPath = uiDir libName + , let libRelPath = + makeRelative (takeDirectory packageJsonFile) libPath + , let depName = T.pack $ "@" <> replace "-" "/" libName + , depName `elem` depNames + ] `HMS.union` + dependencies + let newPackageJson = + Object $ + HMS.insert "dependencies" (Object patchedDeps) packageJson + p <- getPermissions packageJsonFile + setPermissions packageJsonFile (setOwnerWritable True p) + BSL.writeFile packageJsonFile (encode newPackageJson) + Nothing -> pure () -- Nothing to patch + _otherwise -> error $ "malformed package.json:" <> show packageJson + _otherwise -> error $ "malformed package.json:" <> show packageJson0 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 e6013bc18169..82cbae09fce6 100644 --- a/language-support/ts/codegen/tests/src/DA/Test/Daml2jsUtils.hs +++ b/language-support/ts/codegen/tests/src/DA/Test/Daml2jsUtils.hs @@ -4,6 +4,7 @@ module DA.Test.Daml2jsUtils ( TsLibrary (..), Workspaces (..), allTsLibraries, + tsLibraryName, setupYarnEnv, ) where diff --git a/templates/create-daml-app-test-resources/index.test.ts b/templates/create-daml-app-test-resources/index.test.ts index a19a2e5d0454..05d5c9fc300d 100644 --- a/templates/create-daml-app-test-resources/index.test.ts +++ b/templates/create-daml-app-test-resources/index.test.ts @@ -19,7 +19,7 @@ const UI_PORT = 3000; // `daml start` process let startProc: ChildProcess | undefined = undefined; -// `yarn start` process +// `npm start` process let uiProc: ChildProcess | undefined = undefined; // Chrome browser that we run in headless mode @@ -79,12 +79,12 @@ beforeAll(async () => { await waitOn({resources: [`file:${jsonApiPortFilePath}`]}); - // Run `yarn start` in another shell. + // Run `npm start` in another shell. // Disable automatically opening a browser using the env var described here: // https://github.com/facebook/create-react-app/issues/873#issuecomment-266318338 const env = {...process.env, BROWSER: 'none'}; - uiProc = spawn('yarn', ['start'], { env, stdio: 'inherit', detached: true}); - // Note(kill-yarn-start): The `detached` flag starts the process in a new process group. + uiProc = spawn('npm-cli.js', ['run-script', 'start'], { env, stdio: 'inherit', detached: true}); + // Note(kill-npm-start): The `detached` flag starts the process in a new process group. // This allows us to kill the process with all its descendents after the tests finish, // following https://azimi.me/2014/12/31/kill-child_process-node-js.html. @@ -104,9 +104,9 @@ afterAll(async () => { startProc.kill('SIGTERM'); } - // Kill the `yarn start` process including all its descendents. + // Kill the `npm start` process including all its descendents. // The `-` indicates to kill all processes in the process group. - // See Note(kill-yarn-start). + // See Note(kill-npm-start). // TODO: Test this on Windows. if (uiProc) { process.kill(-uiProc.pid) diff --git a/templates/create-daml-app/README.md.template b/templates/create-daml-app/README.md.template index 1d3deaa7ed02..09be7b6867d2 100644 --- a/templates/create-daml-app/README.md.template +++ b/templates/create-daml-app/README.md.template @@ -31,7 +31,7 @@ First, we need to generate TypeScript code bindings for the compiled DAML model. At the root of the repository, run ``` daml build -daml codegen js .daml/dist/__PROJECT_NAME__-0.1.0.dar -o daml.js +daml codegen js .daml/dist/__PROJECT_NAME__-0.1.0.dar -o ui/daml.js ``` The latter command generates TypeScript packages in the `daml.js` directory. @@ -87,7 +87,7 @@ DAR `__PROJECT_NAME__.dar` you have just created. To upload the UI, create a ZIP file containing all your UI assets by executing ``` daml build -daml codegen js .daml/dist/__PROJECT_NAME__-0.1.0.dar -o daml.js +daml codegen js .daml/dist/__PROJECT_NAME__-0.1.0.dar -o ui/daml.js (cd ui && npm run-script build && zip -r ../__PROJECT_NAME__-ui.zip build) ``` at the root of the repository. Afterwards, select the "UI Assets" tab of your diff --git a/templates/create-daml-app/ui/package.json.template b/templates/create-daml-app/ui/package.json.template index 48c14dd912d5..f2fbec9a50f2 100644 --- a/templates/create-daml-app/ui/package.json.template +++ b/templates/create-daml-app/ui/package.json.template @@ -3,7 +3,7 @@ "version": "0.1.0", "private": true, "dependencies": { - "@daml.js/__PROJECT_NAME__": "file:../daml.js/__PROJECT_NAME__-0.1.0", + "@daml.js/__PROJECT_NAME__": "file:daml.js/__PROJECT_NAME__-0.1.0", "@daml/ledger": "__VERSION__", "@daml/react": "__VERSION__", "@daml/types": "__VERSION__", From 05a1d035c2e74f50ac256733c38d9f9a607b65d5 Mon Sep 17 00:00:00 2001 From: Robin Krom Date: Tue, 8 Sep 2020 11:38:50 +0200 Subject: [PATCH 3/3] moved gitignore entry to toplevel --- templates/create-daml-app/.gitignore | 2 +- templates/create-daml-app/ui/.gitignore | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) delete mode 100644 templates/create-daml-app/ui/.gitignore diff --git a/templates/create-daml-app/.gitignore b/templates/create-daml-app/.gitignore index 2ddff9b58786..eeaa3773704f 100644 --- a/templates/create-daml-app/.gitignore +++ b/templates/create-daml-app/.gitignore @@ -6,4 +6,4 @@ node_modules *.log -daml.js/ +ui/daml.js diff --git a/templates/create-daml-app/ui/.gitignore b/templates/create-daml-app/ui/.gitignore deleted file mode 100644 index 56a0db160af0..000000000000 --- a/templates/create-daml-app/ui/.gitignore +++ /dev/null @@ -1 +0,0 @@ -daml.js/