From ccfc9f58077ef53dbbfc973c5d63d6950be28268 Mon Sep 17 00:00:00 2001 From: mshanemc Date: Tue, 11 Apr 2023 11:43:10 -0500 Subject: [PATCH 1/5] feat: more scratch org creation flags --- command-snapshot.json | 4 ++++ messages/create_scratch.md | 22 ++++++++++++++++++++++ src/commands/org/create/scratch.ts | 26 +++++++++++++++++++++++--- test/nut/scratchCreate.nut.ts | 13 ++++++++++++- 4 files changed, 61 insertions(+), 4 deletions(-) diff --git a/command-snapshot.json b/command-snapshot.json index f99dd485..f284ef35 100644 --- a/command-snapshot.json +++ b/command-snapshot.json @@ -78,14 +78,18 @@ "async", "client-id", "definition-file", + "description", "duration-days", "edition", "json", + "name", "no-ancestors", "no-namespace", + "release", "set-default", "target-dev-hub", "track-source", + "username", "wait" ], "alias": ["env:create:scratch"] diff --git a/messages/create_scratch.md b/messages/create_scratch.md index 9c1bd2b0..de278d98 100644 --- a/messages/create_scratch.md +++ b/messages/create_scratch.md @@ -96,6 +96,28 @@ Create the scratch org with no namespace, even if the Dev Hub has a namespace. Number of days before the org expires. +# flags.username.summary + +Set the username of the scratch org admin user. Overrides any value from the definition file. + +# flags.username.description + +The username must be unique within the entire scratch org and sandbox universe. You need to add logic to ensure uniqueness. + +Omit this flag to have Salesforce generate a unique username for your org. + +# flags.description.summary + +Set the description of the scratch org in the Dev Hub. Overrides any value from the definition file. + +# flags.name.summary + +Set the orgName property of the scratch org in the Dev Hub. Overrides any value from the definition file. + +# flags.release.summary + +By default, orgs will on the same release as the Dev Hub. During the preview period you can override this behavior to opt in or out of the new release. + # prompt.secret OAuth client secret of your personal connected app diff --git a/src/commands/org/create/scratch.ts b/src/commands/org/create/scratch.ts index 4a4b4d3a..a584fed5 100644 --- a/src/commands/org/create/scratch.ts +++ b/src/commands/org/create/scratch.ts @@ -115,6 +115,20 @@ export default class EnvCreateScratch extends SfCommand { description: messages.getMessage('flags.track-source.description'), allowNo: true, }), + username: Flags.string({ + summary: messages.getMessage('flags.username.summary'), + description: messages.getMessage('flags.username.description'), + }), + description: Flags.string({ + summary: messages.getMessage('flags.description.summary'), + }), + name: Flags.string({ + summary: messages.getMessage('flags.name.summary'), + }), + release: Flags.string({ + summary: messages.getMessage('flags.release.summary'), + options: ['preview', 'previous'], + }), }; public async run(): Promise { const lifecycle = Lifecycle.getInstance(); @@ -123,9 +137,15 @@ export default class EnvCreateScratch extends SfCommand { if (!baseUrl) { throw new SfError('No instance URL found for the dev hub'); } - const orgConfig = flags['definition-file'] - ? (JSON.parse(await fs.promises.readFile(flags['definition-file'], 'utf-8')) as Record) - : { edition: flags.edition }; + const orgConfig = { + ...(flags['definition-file'] + ? (JSON.parse(await fs.promises.readFile(flags['definition-file'], 'utf-8')) as Record) + : { edition: flags.edition }), + ...(flags.username ? { username: flags.username } : {}), + ...(flags.description ? { description: flags.description } : {}), + ...(flags.name ? { orgName: flags.name } : {}), + ...(flags.release ? { release: flags.release } : {}), + }; const createCommandOptions: ScratchOrgCreateOptions = { hubOrg: flags['target-dev-hub'], diff --git a/test/nut/scratchCreate.nut.ts b/test/nut/scratchCreate.nut.ts index 615f5981..194885f0 100644 --- a/test/nut/scratchCreate.nut.ts +++ b/test/nut/scratchCreate.nut.ts @@ -6,7 +6,7 @@ */ import * as fs from 'fs'; import * as path from 'path'; -import { execCmd, TestSession } from '@salesforce/cli-plugins-testkit'; +import { execCmd, genUniqueString, TestSession } from '@salesforce/cli-plugins-testkit'; import { assert, expect } from 'chai'; import { AuthFields, Messages, Global, StateAggregator } from '@salesforce/core'; import { secretTimeout } from '../../src/commands/org/create/scratch'; @@ -85,6 +85,17 @@ describe('env create scratch NUTs', () => { ).jsonOutput?.result; expect(resp).to.have.all.keys(keys); }); + it('creates an org from config file with "override" flags ', () => { + const expectedUsername = genUniqueString('%s@nut.org'); + const resp = execCmd( + `env:create:scratch -f config/project-scratch-def.json --json --username ${expectedUsername} --description "new one" --name TheOrg --wait 60`, + { + ensureExitCode: 0, + } + ).jsonOutput?.result; + expect(resp).to.have.all.keys(keys); + expect(resp?.username).to.equal(expectedUsername); + }); it('creates an org with tracking disabled ', async () => { const resp = execCmd( 'env:create:scratch --edition developer --no-track-source --json --wait 60', From d74006b8b11b8780b50031fad51f8d90867fe708 Mon Sep 17 00:00:00 2001 From: Juliet Shackell Date: Tue, 11 Apr 2023 11:19:04 -0700 Subject: [PATCH 2/5] fix: edit messages for new flags --- messages/create_scratch.md | 33 ++++++++++++++++++++++-------- src/commands/org/create/scratch.ts | 1 + 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/messages/create_scratch.md b/messages/create_scratch.md index de278d98..1966dcf0 100644 --- a/messages/create_scratch.md +++ b/messages/create_scratch.md @@ -4,7 +4,16 @@ Create a scratch org. # description -There are two ways to create a scratch org: specify a definition file that contains the options or use the --edition flag to specify the one required option. If you want to set options other than the edition, such as org features or settings, you must use a definition file. +There are two ways to create a scratch org: either specify a definition file that contains the options or use the --edition flag to specify the one required option. In other words, you can specify --edition or --definition-file, but not both. + +For either method, you can also use these flags; if you use them with --definition-file, they override their equivalent option in the scratch org definition file: + + * --description + * --name (equivalent to the "orgName" option) + * --username + * --release + +If you want to set options other than the preceding ones, such as org features or settings, you must use a definition file. You must specify a Dev Hub to create a scratch org, either with the --target-dev-hub flag or by setting your default Dev Hub with the target-dev-hub configuration variable. @@ -14,9 +23,13 @@ You must specify a Dev Hub to create a scratch org, either with the --target-dev <%= config.bin %> <%= command.id %> --edition=developer --alias my-scratch-org -- Specify the Dev Hub using its alias and a scratch org definition file. Set the scratch org as your default and specify that it expires in 3 days: +- Create a scratch org with a definition file. Specify the Dev Hub using its alias, set the scratch org as your default, and specify that it expires in 3 days: + + <%= config.bin %> <%= command.id %> --target-dev-hub MyHub --definition-file config/project-scratch-def.json --set-default --duration-days 3 - <%= config.bin %> <%= command.id %> --target-dev-hub=MyHub --definition-file config/project-scratch-def.json --set-default --duration-days 3 +- Create a preview Enterprise edition scratch org; for use only during Salesforce release transition periods: + + <%= config.bin %> <%= command.id %> --edition=enterprise --alias my-scratch-org --target-dev-hub MyHub --release preview # flags.target-hub.summary @@ -98,25 +111,29 @@ Number of days before the org expires. # flags.username.summary -Set the username of the scratch org admin user. Overrides any value from the definition file. +Username of the scratch org admin user. Overrides the value of the "username" option in the definition file, if set. # flags.username.description -The username must be unique within the entire scratch org and sandbox universe. You need to add logic to ensure uniqueness. +The username must be unique within the entire scratch org and sandbox universe. You must add your own logic to ensure uniqueness. Omit this flag to have Salesforce generate a unique username for your org. # flags.description.summary -Set the description of the scratch org in the Dev Hub. Overrides any value from the definition file. +Description of the scratch org in the Dev Hub. Overrides the value of the "description" option in the definition file, if set. # flags.name.summary -Set the orgName property of the scratch org in the Dev Hub. Overrides any value from the definition file. +Name of the org, such as "Acme Company". Overrides the value of the "orgName" option in the definition file, if set. # flags.release.summary -By default, orgs will on the same release as the Dev Hub. During the preview period you can override this behavior to opt in or out of the new release. +Release of the scratch org as compared to the Dev Hub release. + +# flags.release.description + +By default, scratch orgs are on the same release as the Dev Hub. During Salesforce release transition periods, you can override this default behavior and opt in or out of the new release. # prompt.secret diff --git a/src/commands/org/create/scratch.ts b/src/commands/org/create/scratch.ts index a584fed5..8c70cf4b 100644 --- a/src/commands/org/create/scratch.ts +++ b/src/commands/org/create/scratch.ts @@ -127,6 +127,7 @@ export default class EnvCreateScratch extends SfCommand { }), release: Flags.string({ summary: messages.getMessage('flags.release.summary'), + description: messages.getMessage('flags.release.description'), options: ['preview', 'previous'], }), }; From 4ee0e4ed8ec8bc7f2af2e4146ac37554dfd2c31b Mon Sep 17 00:00:00 2001 From: mshanemc Date: Fri, 14 Apr 2023 14:18:19 -0500 Subject: [PATCH 3/5] feat: edition overrides definition file, both are allowed --- messages/create_scratch.md | 5 +++-- src/commands/org/create/scratch.ts | 5 ++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/messages/create_scratch.md b/messages/create_scratch.md index 1966dcf0..1c96bc7b 100644 --- a/messages/create_scratch.md +++ b/messages/create_scratch.md @@ -4,7 +4,7 @@ Create a scratch org. # description -There are two ways to create a scratch org: either specify a definition file that contains the options or use the --edition flag to specify the one required option. In other words, you can specify --edition or --definition-file, but not both. +There are two ways to create a scratch org: either specify a definition file that contains the options or use the --edition flag to specify the one required option. For either method, you can also use these flags; if you use them with --definition-file, they override their equivalent option in the scratch org definition file: @@ -12,6 +12,7 @@ For either method, you can also use these flags; if you use them with --definiti * --name (equivalent to the "orgName" option) * --username * --release + * --edition If you want to set options other than the preceding ones, such as org features or settings, you must use a definition file. @@ -57,7 +58,7 @@ Don't include second-generation managed package (2GP) ancestors in the scratch o # flags.edition.summary -Salesforce edition of the scratch org. +Salesforce edition of the scratch org. Overrides the value of the "edition" option in the definition file, if set. # flags.async.summary diff --git a/src/commands/org/create/scratch.ts b/src/commands/org/create/scratch.ts index 8c70cf4b..8ef13505 100644 --- a/src/commands/org/create/scratch.ts +++ b/src/commands/org/create/scratch.ts @@ -51,7 +51,6 @@ export default class EnvCreateScratch extends SfCommand { char: 'f', summary: messages.getMessage('flags.definition-file.summary'), description: messages.getMessage('flags.definition-file.description'), - exactlyOne: ['definition-file', 'edition'], }), 'target-dev-hub': Flags.requiredHub({ char: 'v', @@ -78,7 +77,6 @@ export default class EnvCreateScratch extends SfCommand { 'partner-group', 'partner-professional', ], - exactlyOne: ['definition-file', 'edition'], }), 'no-namespace': Flags.boolean({ char: 'm', @@ -141,7 +139,8 @@ export default class EnvCreateScratch extends SfCommand { const orgConfig = { ...(flags['definition-file'] ? (JSON.parse(await fs.promises.readFile(flags['definition-file'], 'utf-8')) as Record) - : { edition: flags.edition }), + : {}), + ...(flags.edition ? { edition: flags.edition } : {}), ...(flags.username ? { username: flags.username } : {}), ...(flags.description ? { description: flags.description } : {}), ...(flags.name ? { orgName: flags.name } : {}), From 8439d2cc037df4125290d5459b497283a146f40e Mon Sep 17 00:00:00 2001 From: mshanemc Date: Fri, 14 Apr 2023 14:26:11 -0500 Subject: [PATCH 4/5] test: allow edition with config file --- test/nut/scratchCreate.nut.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/nut/scratchCreate.nut.ts b/test/nut/scratchCreate.nut.ts index 194885f0..1fa0ef23 100644 --- a/test/nut/scratchCreate.nut.ts +++ b/test/nut/scratchCreate.nut.ts @@ -42,9 +42,6 @@ describe('env create scratch NUTs', () => { it('non-existent config file', () => { execCmd('env:create:scratch -f badfile.json', { ensureExitCode: 1 }); }); - it('config file AND edition', () => { - execCmd('env:create:scratch -f config/project-scratch-def.json --edition developer', { ensureExitCode: 1 }); - }); it('wait zero', () => { execCmd('env:create:scratch -f config/project-scratch-def.json --wait 0', { ensureExitCode: 1 }); }); From 084b09176a0d555a9b19873652e0177ac9019a45 Mon Sep 17 00:00:00 2001 From: mshanemc Date: Fri, 14 Apr 2023 14:31:26 -0500 Subject: [PATCH 5/5] test: remove unused test dep --- package.json | 4 +--- test/unit/org/list.test.ts | 5 +---- yarn.lock | 14 -------------- 3 files changed, 2 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index 77e03118..779aeda2 100644 --- a/package.json +++ b/package.json @@ -24,12 +24,10 @@ "@salesforce/prettier-config": "^0.0.2", "@salesforce/ts-sinon": "1.4.6", "@swc/core": "1.3.39", - "@types/chai-as-promised": "^7.1.5", "@types/shelljs": "^0.8.10", "@typescript-eslint/eslint-plugin": "^5.57.0", "@typescript-eslint/parser": "^5.57.1", "chai": "^4.3.7", - "chai-as-promised": "^7.1.1", "eslint": "^8.38.0", "eslint-config-prettier": "^8.6.0", "eslint-config-salesforce": "^1.1.1", @@ -236,4 +234,4 @@ "output": [] } } -} \ No newline at end of file +} diff --git a/test/unit/org/list.test.ts b/test/unit/org/list.test.ts index 84b91549..38e48009 100644 --- a/test/unit/org/list.test.ts +++ b/test/unit/org/list.test.ts @@ -4,8 +4,7 @@ * Licensed under the BSD 3-Clause license. * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -import { expect, use as ChaiUse } from 'chai'; -import * as chaiAsPromised from 'chai-as-promised'; +import { expect } from 'chai'; import { TestContext } from '@salesforce/core/lib/testSetup'; import { AuthInfo, Connection, Org } from '@salesforce/core'; import { stubMethod } from '@salesforce/ts-sinon'; @@ -14,8 +13,6 @@ import OrgListMock = require('../../shared/orgListMock'); import { OrgListCommand } from '../../../src/commands/org/list'; import { OrgListUtil } from '../../../src/shared/orgListUtil'; -ChaiUse(chaiAsPromised); - describe('org:list', () => { // Create new TestContext, which automatically creates and restores stubs // pertaining to authorization, orgs, config files, etc... diff --git a/yarn.lock b/yarn.lock index 92b3002a..29731e3f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1332,13 +1332,6 @@ "@types/node" "*" "@types/responselike" "^1.0.0" -"@types/chai-as-promised@^7.1.5": - version "7.1.5" - resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.5.tgz#6e016811f6c7a64f2eed823191c3a6955094e255" - integrity sha512-jStwss93SITGBwt/niYrkf2C+/1KTeZCZl1LaeezTlqppAKeoQC7jxyqYuP72sxBGKCIbw7oHgbYssIRzT5FCQ== - dependencies: - "@types/chai" "*" - "@types/chai@*", "@types/chai@^4.2.11": version "4.3.4" resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.4.tgz#e913e8175db8307d78b4e8fa690408ba6b65dee4" @@ -2269,13 +2262,6 @@ cardinal@^2.1.1: ansicolors "~0.3.2" redeyed "~2.1.0" -chai-as-promised@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.1.tgz#08645d825deb8696ee61725dbf590c012eb00ca0" - integrity sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA== - dependencies: - check-error "^1.0.2" - chai@^4.2.0, chai@^4.3.7: version "4.3.7" resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.7.tgz#ec63f6df01829088e8bf55fca839bcd464a8ec51"