Respect project name in create-daml-app (#6694)

* Respect project name in create-daml-app

Now `daml new foobar create-daml-app` creates a project called
`foobar` replacing the name everywhere. The tests now run twice once
with the original project name since that’s what we use in the GSG and
once with a modified one. I guess you could argue that only running
the second should be enough so I’m open to removing the first one.

fixes #6681

changelog_begin

- [DAML Assistant] `daml new foobar create-daml-app` now properly
  respects the project name and creates a project called `foobar`
  instead of hardcoding the name fo `create-daml-app`.

changelog_end

* .

changelog_begin
changelog_end

* Remove debugging output

changelog_begin
changelog_end
This commit is contained in:
Moritz Kiefer 2020-07-13 17:30:21 +02:00 committed by GitHub
parent 6366fb753d
commit a0f9eae489
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 105 additions and 47 deletions

View File

@ -159,22 +159,15 @@ da_haskell_test(
],
)
da_haskell_test(
name = "create-daml-app-tests",
timeout = "long",
da_haskell_library(
name = "create-daml-app-tests-lib",
srcs = ["src/DA/Daml/Assistant/CreateDamlAppTests.hs"],
args = [
"$(location //:yarn)",
],
data = [
"//release:sdk-release-tarball",
"@local_jdk//:bin/java.exe" if is_windows else "@local_jdk//:bin/java",
"//:yarn",
"@patch_dev_env//:patch",
] + ([] if is_windows else ts_libraries + create_daml_app_resources),
# The Puppeteer tests can have race conditions, probably due to the way
# we depend on UI elements appearing.
flaky = True,
hackage_deps = [
"aeson",
"aeson-extra",
@ -183,12 +176,10 @@ da_haskell_test(
"directory",
"extra",
"filepath",
"tagged",
"tasty",
"tasty-hunit",
],
main_function = "DA.Daml.Assistant.CreateDamlAppTests.main",
# Exclusive until we stop hardcoding port numbers in index.test.ts
tags = ["exclusive"],
visibility = ["//visibility:public"],
deps = [
":integration-test-utils",
@ -198,3 +189,33 @@ da_haskell_test(
"//libs-haskell/test-utils",
],
)
da_haskell_test(
name = "create-daml-app-tests",
timeout = "long",
srcs = ["src/DA/Daml/Assistant/CreateDamlAppTestsMain.hs"],
args = ["$(location //:yarn)"],
data = ["//:yarn"],
hackage_deps = ["base"],
main_function = "DA.Daml.Assistant.CreateDamlAppTestsMain.main",
# Exclusive until we stop hardcoding port numbers in index.test.ts
tags = ["exclusive"],
deps = [":create-daml-app-tests-lib"],
)
da_haskell_test(
name = "create-daml-app-tests-proj-name",
timeout = "long",
srcs = ["src/DA/Daml/Assistant/CreateDamlAppTestsMain.hs"],
args = [
"$(location //:yarn)",
"--project-name",
"not-create-daml-app",
],
data = ["//:yarn"],
hackage_deps = ["base"],
main_function = "DA.Daml.Assistant.CreateDamlAppTestsMain.main",
# Exclusive until we stop hardcoding port numbers in index.test.ts
tags = ["exclusive"],
deps = [":create-daml-app-tests-lib"],
)

View File

@ -9,6 +9,9 @@ import Data.Aeson.Extra.Merge
import qualified Data.ByteString.Lazy as BSL
import qualified Data.ByteString as BS
import Data.List.Extra
import Data.Proxy (Proxy (..))
import Data.Tagged (Tagged (..))
import qualified Data.Text.Extended as T
import System.Directory.Extra
import System.Environment.Blank
import System.FilePath
@ -16,6 +19,7 @@ import System.IO.Extra
import System.Info.Extra
import Test.Tasty
import Test.Tasty.HUnit
import Test.Tasty.Options
import DA.Bazel.Runfiles
import DA.Daml.Assistant.IntegrationTestUtils
@ -23,6 +27,14 @@ import DA.Test.Daml2jsUtils
import DA.Test.Process (callCommandSilent)
import DA.Test.Util
newtype ProjectName = ProjectName String
instance IsOption ProjectName where
defaultValue = ProjectName "create-daml-app"
parseValue = Just . ProjectName
optionName = Tagged "project-name"
optionHelp = Tagged "name of the project"
main :: IO ()
main = withTempDir $ \yarnCache -> do
setEnv "YARN_CACHE_FOLDER" yarnCache True
@ -30,29 +42,32 @@ main = withTempDir $ \yarnCache -> do
javaPath <- locateRunfiles "local_jdk/bin"
oldPath <- getSearchPath
yarnPath <- takeDirectory <$> locateRunfiles (mainWorkspace </> yarn)
let ingredients = defaultIngredients ++ [includingOptions [Option @ProjectName Proxy]]
withArgs args (withEnv
[ ("PATH", Just $ intercalate [searchPathSeparator] (javaPath : yarnPath : oldPath))
, ("TASTY_NUM_THREADS", Just "1")
] $ defaultMain tests)
] $ defaultMainWithIngredients ingredients tests)
tests :: TestTree
tests = withSdkResource $ \_ -> testGroup "Create DAML App tests" [gettingStartedGuideTest | not isWindows]
tests =
withSdkResource $ \_ ->
askOption $ \(ProjectName projectName) -> do
testGroup "Create DAML App tests" [gettingStartedGuideTest projectName | not isWindows]
where
gettingStartedGuideTest = testCaseSteps "Getting Started Guide" $ \step ->
gettingStartedGuideTest projectName = testCaseSteps "Getting Started Guide" $ \step ->
withTempDir $ \tmpDir -> do
step "Create app from template"
withCurrentDirectory tmpDir $ do
callCommandSilent "daml new create-daml-app create-daml-app"
let cdaDir = tmpDir </> "create-daml-app"
callCommandSilent $ "daml new " <> projectName <> " create-daml-app"
let cdaDir = tmpDir </> projectName
-- 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 ["create-daml-app/daml.js"]) [DamlTypes, DamlLedger]
setupYarnEnv tmpDir (Workspaces [projectName <> "/daml.js"]) [DamlTypes, DamlLedger]
step "Run JavaScript codegen"
callCommandSilent "daml codegen js -o daml.js .daml/dist/create-daml-app-0.1.0.dar"
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
@ -60,7 +75,7 @@ tests = withSdkResource $ \_ -> testGroup "Create DAML App tests" [gettingStarte
-- `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 ["create-daml-app/ui"]) allTsLibraries
setupYarnEnv tmpDir (Workspaces [projectName <> "/ui"]) allTsLibraries
step "Install dependencies for UI"
retry 3 (callCommandSilent "yarn install")
step "Run linter"
@ -75,18 +90,20 @@ tests = withSdkResource $ \_ -> testGroup "Create DAML App tests" [gettingStarte
messagingPatch <- locateRunfiles (mainWorkspace </> "templates" </> "create-daml-app-test-resources" </> "messaging.patch")
patchTool <- locateRunfiles "patch_dev_env/bin/patch"
withCurrentDirectory cdaDir $ do
callCommandSilent $ unwords [patchTool, "-s", "-p2", "<", messagingPatch]
patchContent <- T.readFileUtf8 messagingPatch
T.writeFileUtf8 (cdaDir </> "messaging.patch") (T.replace "create-daml-app" (T.pack projectName) patchContent)
callCommandSilent $ unwords [patchTool, "-s", "-p2", "<", cdaDir </> "messaging.patch"]
forM_ ["MessageEdit", "MessageList"] $ \messageComponent ->
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 ["create-daml-app/daml.js"]) [DamlTypes, DamlLedger]
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/create-daml-app-0.1.0.dar"
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 ["create-daml-app/ui"]) allTsLibraries
setupYarnEnv tmpDir (Workspaces [projectName <> "/ui"]) allTsLibraries
step "Install UI dependencies again, forcing rebuild of generated code"
callCommandSilent "yarn install --force --frozen-lockfile"
step "Run linter again"
@ -102,7 +119,10 @@ tests = withSdkResource $ \_ -> testGroup "Create DAML App tests" [gettingStarte
retry 3 (callCommandSilent "yarn install")
step "Run Puppeteer end-to-end tests"
testFile <- locateRunfiles (mainWorkspace </> "templates" </> "create-daml-app-test-resources" </> "index.test.ts")
copyFile testFile (cdaDir </> "ui" </> "src" </> "index.test.ts")
testFileContent <- T.readFileUtf8 testFile
T.writeFileUtf8
(cdaDir </> "ui" </> "src" </> "index.test.ts")
(T.replace "create-daml-app" (T.pack projectName) testFileContent)
callCommandSilent "CI=yes yarn run test --ci --all"
addTestDependencies :: FilePath -> FilePath -> IO ()

View File

@ -0,0 +1,11 @@
-- Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
-- SPDX-License-Identifier: Apache-2.0
-- Wrapper around the tests so we can change the arguments
module DA.Daml.Assistant.CreateDamlAppTestsMain (main) where
import qualified DA.Daml.Assistant.CreateDamlAppTests as CreateDamlAppTests
main :: IO ()
main = CreateDamlAppTests.main

View File

@ -396,6 +396,7 @@ genrule(
# Copy templates for code snippets in getting started guide
CODE_DIR=$$PWD/build/docs/source/getting-started/code/
mkdir -p $$CODE_DIR
tar -zxf $(location //templates:templates-tarball) -C $$CODE_DIR
rm -rf $$CODE_DIR/templates-tarball/create-daml-app
tar -zxf $(location //templates:create-daml-app-docs) -C $$CODE_DIR/templates-tarball/

View File

@ -1,5 +1,6 @@
# Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
load("@os_info//:os_info.bzl", "is_windows")
exports_files(glob(["create-daml-app-test-resources/*"]))
@ -15,10 +16,14 @@ genrule(
],
outs = ["create-daml-app-docs.tar.gz"],
cmd = """
set -eou pipefail
SRC=templates
OUT=create-daml-app
mkdir -p $$OUT
cp -rL $$SRC/create-daml-app/* $$OUT
# Undo project name templating since we dont want that to show up
# in the docs.
find $$OUT/ -name '*.template' -type f -exec sh -c 'mv "$$0" "$${0%.template}" && sed -i "s/__PROJECT_NAME__/create-daml-app/g" "$${0%.template}"' {} ';'
# Apply patch for messaging feature (we only need the "after" state)
PATCH_TOOL=$$PWD/$(location @patch_dev_env//:patch)
MESSAGING_PATCH=$$PWD/$(location //templates:create-daml-app-test-resources/messaging.patch)
@ -29,7 +34,7 @@ tar c create-daml-app \\
""",
tools = ["@patch_dev_env//:patch"],
visibility = ["//visibility:public"],
)
) if not is_windows else None
genrule(
name = "templates-tarball",

View File

@ -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/create-daml-app-0.1.0.dar -o daml.js
daml codegen js .daml/dist/__PROJECT_NAME__-0.1.0.dar -o daml.js
```
The latter command generates TypeScript packages in the `daml.js` directory.
@ -72,29 +72,29 @@ us. We can follow `Alice` by clicking the plus symbol to the right of here name.
## Deploying to DABL
Deploying `create-daml-app` to the hosted DAML platform
Deploying `__PROJECT_NAME__` to the hosted DAML platform
[project:DABL](https://projectdabl.com/) is quite simple. Log into your DABL
account, create a new ledger and upload your DAML models and your UI.
To upload the DAML models, compile them into a DAR by executing
```
daml build -o create-daml-app.dar
daml build -o __PROJECT_NAME__.dar
```
at the root of your repository. Afterwards, open to the DABL website, select
the ledger you want to deploy to, go to the "DAML" selection and upload the
DAR `create-daml-app.dar` you have just created.
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/create-daml-app-0.1.0.dar -o daml.js
(cd ui && yarn build && zip -r ../create-daml-app-ui.zip 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)
```
at the root of the repository. Afterwards, select the "UI Assets" tab of your
chosen ledger on the DABL website, upload the ZIP file
(`create-daml-app-ui.zip`) you have just created and publish it.
(`__PROJECT_NAME__-ui.zip`) you have just created and publish it.
To see your deployed instance of `create-daml-app` in action, follow the
To see your deployed instance of `__PROJECT_NAME__` in action, follow the
"Visit site" link at the top right corner of your "UI Assets" page.
@ -105,7 +105,7 @@ Regardless of which direction you pick, the following files will be the most
interesting ones to familiarize yourself with:
- [`daml/User.daml`](daml/User.daml): the DAML model of the social network
- `daml.js/create-daml-app-0.1.0/src/User.ts` (once you've generated it):
- `daml.js/__PROJECT_NAME__-0.1.0/src/User.ts` (once you've generated it):
a reflection of the types contained in the DAML model in TypeScript
- [`ui/src/components/MainView.tsx`](ui/src/components/MainView.tsx):
a React component using the HTTP Ledger API and rendering the main features

View File

@ -1,5 +1,5 @@
sdk-version: __VERSION__
name: create-daml-app
name: __PROJECT_NAME__
version: 0.1.0
source: daml
parties:
@ -12,5 +12,5 @@ dependencies:
- daml-trigger
sandbox-options:
- --wall-clock-time
- --ledgerid=create-daml-app-sandbox
- --ledgerid=__PROJECT_NAME__-sandbox
start-navigator: false

View File

@ -1,2 +0,0 @@
REACT_APP_LEDGER_ID=create-daml-app-sandbox
REACT_APP_HTTP_JSON_PORT=7575

View File

@ -0,0 +1,2 @@
REACT_APP_LEDGER_ID=__PROJECT_NAME__-sandbox
REACT_APP_HTTP_JSON_PORT=7575

View File

@ -1,9 +1,9 @@
{
"name": "create-daml-app",
"name": "__PROJECT_NAME__",
"version": "0.1.0",
"private": true,
"dependencies": {
"@daml.js/create-daml-app": "file:../daml.js/create-daml-app-0.1.0",
"@daml.js/__PROJECT_NAME__": "file:../daml.js/__PROJECT_NAME__-0.1.0",
"@daml/ledger": "__VERSION__",
"@daml/react": "__VERSION__",
"@daml/types": "__VERSION__",

View File

@ -4,7 +4,7 @@
import { encode } from 'jwt-simple';
import { ledgerId } from './config';
export const APPLICATION_ID: string = 'create-daml-app';
export const APPLICATION_ID: string = '__PROJECT_NAME__';
// NOTE: This is for testing purposes only.
// To handle authentication properly,

View File

@ -5,7 +5,7 @@ import React, { useCallback } from 'react'
import { Button, Form, Grid, Header, Image, Segment } from 'semantic-ui-react'
import Credentials, { computeCredentials } from '../Credentials';
import Ledger from '@daml/ledger';
import { User } from '@daml.js/create-daml-app';
import { User } from '@daml.js/__PROJECT_NAME__';
import { DeploymentMode, deploymentMode, ledgerId, httpBaseUrl} from '../config';
import { useEffect } from 'react';

View File

@ -4,7 +4,7 @@
import React, { useMemo } from 'react';
import { Container, Grid, Header, Icon, Segment, Divider } from 'semantic-ui-react';
import { Party } from '@daml/types';
import { User } from '@daml.js/create-daml-app';
import { User } from '@daml.js/__PROJECT_NAME__';
import { useParty, useLedger, useStreamFetchByKey, useStreamQuery } from '@daml/react';
import UserList from './UserList';
import PartyListEdit from './PartyListEdit';

View File

@ -4,7 +4,7 @@
import React from 'react'
import { Icon, List } from 'semantic-ui-react'
import { Party } from '@daml/types';
import { User } from '@daml.js/create-daml-app';
import { User } from '@daml.js/__PROJECT_NAME__';
type Props = {
users: User.User[];

View File

@ -20,7 +20,7 @@ export const ledgerId: string =
deploymentMode === DeploymentMode.PROD_DABL
? window.location.hostname.split('.')[0]
: process.env.REACT_APP_LEDGER_ID
?? 'create-daml-app-sandbox';
?? '__PROJECT_NAME__-sandbox';
export const httpBaseUrl =
deploymentMode === DeploymentMode.PROD_DABL