Skip to content

Commit b748410

Browse files
Merge pull request #304 from salesforcecli/bm/W-10657353
feat: new command org:status
2 parents a1bccfb + 4d7722f commit b748410

File tree

11 files changed

+433
-125
lines changed

11 files changed

+433
-125
lines changed

command-snapshot.json

Lines changed: 85 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,86 @@
11
[
2-
{
3-
"command": "force:org:beta:create",
4-
"plugin": "@salesforce/plugin-org",
5-
"flags": [
6-
"apiversion",
7-
"clientid",
8-
"definitionfile",
9-
"durationdays",
10-
"json",
11-
"loglevel",
12-
"noancestors",
13-
"nonamespace",
14-
"retry",
15-
"setalias",
16-
"setdefaultusername",
17-
"targetdevhubusername",
18-
"targetusername",
19-
"type",
20-
"wait"
21-
]
22-
},
23-
{
24-
"command": "force:org:delete",
25-
"plugin": "@salesforce/plugin-org",
26-
"flags": ["apiversion", "json", "loglevel", "noprompt", "targetdevhubusername", "targetusername"]
27-
},
28-
{
29-
"command": "force:org:display",
30-
"plugin": "@salesforce/plugin-org",
31-
"flags": ["apiversion", "json", "loglevel", "targetusername", "verbose"]
32-
},
33-
{
34-
"command": "force:org:list",
35-
"plugin": "@salesforce/plugin-org",
36-
"flags": ["all", "clean", "json", "loglevel", "noprompt", "skipconnectionstatus", "verbose"]
37-
},
38-
{
39-
"command": "force:org:open",
40-
"plugin": "@salesforce/plugin-org",
41-
"flags": ["apiversion", "browser", "json", "loglevel", "path", "targetusername", "urlonly"]
42-
}
43-
]
2+
{
3+
"command": "force:org:beta:create",
4+
"plugin": "@salesforce/plugin-org",
5+
"flags": [
6+
"apiversion",
7+
"clientid",
8+
"definitionfile",
9+
"durationdays",
10+
"json",
11+
"loglevel",
12+
"noancestors",
13+
"nonamespace",
14+
"retry",
15+
"setalias",
16+
"setdefaultusername",
17+
"targetdevhubusername",
18+
"targetusername",
19+
"type",
20+
"wait"
21+
]
22+
},
23+
{
24+
"command": "force:org:delete",
25+
"plugin": "@salesforce/plugin-org",
26+
"flags": [
27+
"apiversion",
28+
"json",
29+
"loglevel",
30+
"noprompt",
31+
"targetdevhubusername",
32+
"targetusername"
33+
]
34+
},
35+
{
36+
"command": "force:org:display",
37+
"plugin": "@salesforce/plugin-org",
38+
"flags": [
39+
"apiversion",
40+
"json",
41+
"loglevel",
42+
"targetusername",
43+
"verbose"
44+
]
45+
},
46+
{
47+
"command": "force:org:list",
48+
"plugin": "@salesforce/plugin-org",
49+
"flags": [
50+
"all",
51+
"clean",
52+
"json",
53+
"loglevel",
54+
"noprompt",
55+
"skipconnectionstatus",
56+
"verbose"
57+
]
58+
},
59+
{
60+
"command": "force:org:open",
61+
"plugin": "@salesforce/plugin-org",
62+
"flags": [
63+
"apiversion",
64+
"browser",
65+
"json",
66+
"loglevel",
67+
"path",
68+
"targetusername",
69+
"urlonly"
70+
]
71+
},
72+
{
73+
"command": "force:org:status",
74+
"plugin": "@salesforce/plugin-org",
75+
"flags": [
76+
"apiversion",
77+
"json",
78+
"loglevel",
79+
"sandboxname",
80+
"setalias",
81+
"setdefaultusername",
82+
"targetusername",
83+
"wait"
84+
]
85+
}
86+
]

messages/status.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"examples": [
3+
"sfdx force:org:status --sandboxname DevSbx1 --setalias MySandbox -u prodOrg",
4+
"sfdx force:org:status --sandboxname DevSbx1 --wait 45 --setdefaultusername -u prodOrg"
5+
],
6+
"description": "report status of sandbox creation or clone and authenticate to it\nUse this command to check the status of your sandbox creation or clone and, if the sandbox is ready, authenticate to it.\nUse the --wait (-w) parameter to specify the number of minutes that the command waits for the sandbox creation or clone to complete before returning control of the terminal to you.\nSet the --targetusername (-u) parameter to the username or alias of the production org that contains the sandbox license.",
7+
"flags": {
8+
"sandboxname": "name of the sandbox org to check status for",
9+
"wait": "number of minutes to wait while polling for status",
10+
"setdefaultusername": "set the created or cloned org as your default",
11+
"setalias": "alias for the created or cloned org"
12+
}
13+
}

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"dependencies": {
88
"@oclif/config": "^1.18.1",
99
"@salesforce/command": "^4.2.2",
10-
"@salesforce/core": "^2.35.0",
10+
"@salesforce/core": "^2.36.3",
1111
"@salesforce/kit": "^1.5.17",
1212
"open": "8.4.0",
1313
"tslib": "^2"
@@ -43,11 +43,15 @@
4343
"nyc": "^15.1.0",
4444
"prettier": "^2.4.1",
4545
"pretty-quick": "^3.1.0",
46+
"shelljs": "^0.8.5",
4647
"shx": "0.3.4",
4748
"sinon": "10.0.0",
4849
"ts-node": "^10.0.0",
4950
"typescript": "^4.4.4"
5051
},
52+
"resolutions": {
53+
"@salesforce/core": "^2.36.3"
54+
},
5155
"config": {
5256
"commitizen": {
5357
"path": "cz-conventional-changelog"

src/commands/force/org/status.ts

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* Copyright (c) 2021, salesforce.com, inc.
3+
* All rights reserved.
4+
* Licensed under the BSD 3-Clause license.
5+
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6+
*/
7+
8+
import { EOL } from 'os';
9+
import { flags, FlagsConfig, SfdxCommand } from '@salesforce/command';
10+
import {
11+
Config,
12+
Lifecycle,
13+
Messages,
14+
Aliases,
15+
SandboxEvents,
16+
StatusEvent,
17+
ResultEvent,
18+
SandboxProcessObject,
19+
} from '@salesforce/core';
20+
import { Duration } from '@salesforce/kit';
21+
import { SandboxReporter } from '../../../shared/sandboxReporter';
22+
23+
Messages.importMessagesDirectory(__dirname);
24+
const messages = Messages.loadMessages('@salesforce/plugin-org', 'status');
25+
26+
export class OrgStatusCommand extends SfdxCommand {
27+
public static readonly examples = messages.getMessage('examples').split(EOL);
28+
public static readonly description = messages.getMessage('description');
29+
public static readonly requiresProject = false;
30+
public static readonly requiresUsername = true;
31+
32+
public static readonly flagsConfig: FlagsConfig = {
33+
sandboxname: flags.string({
34+
char: 'n',
35+
description: messages.getMessage('flags.sandboxname'),
36+
required: true,
37+
}),
38+
setdefaultusername: flags.boolean({
39+
char: 's',
40+
description: messages.getMessage('flags.setdefaultusername'),
41+
}),
42+
setalias: flags.string({
43+
char: 'a',
44+
description: messages.getMessage('flags.setalias'),
45+
}),
46+
wait: flags.minutes({
47+
char: 'w',
48+
description: messages.getMessage('flags.wait'),
49+
min: Duration.minutes(2),
50+
default: Duration.minutes(6),
51+
}),
52+
};
53+
54+
public async run(): Promise<SandboxProcessObject> {
55+
this.logger.debug('Status started with args %s ', this.flags);
56+
const lifecycle = Lifecycle.getInstance();
57+
58+
// eslint-disable-next-line @typescript-eslint/require-await
59+
lifecycle.on(SandboxEvents.EVENT_STATUS, async (results: StatusEvent) => {
60+
this.ux.log(SandboxReporter.sandboxProgress(results));
61+
});
62+
63+
lifecycle.on(SandboxEvents.EVENT_RESULT, async (results: ResultEvent) => {
64+
const resultMsg = `Sandbox ${results.sandboxProcessObj.SandboxName}(${results.sandboxProcessObj.Id}) is ready for use.`;
65+
this.ux.log(resultMsg);
66+
const { data } = SandboxReporter.logSandboxProcessResult(results);
67+
this.ux.styledHeader('Sandbox Org Status');
68+
this.ux.table(data, {
69+
columns: [
70+
{ key: 'key', label: 'Name' },
71+
{ key: 'value', label: 'Value' },
72+
],
73+
});
74+
if (results.sandboxRes?.authUserName) {
75+
if (this.flags.setalias) {
76+
const aliases = await Aliases.create(Aliases.getDefaultOptions());
77+
const result = await aliases.updateValue(this.flags.setalias, results.sandboxRes.authUserName);
78+
this.logger.debug('Set Alias: %s result: %s', this.flags.setalias, result);
79+
}
80+
if (this.flags.setdefaultusername) {
81+
const globalConfig: Config = this.configAggregator.getGlobalConfig();
82+
globalConfig.set(Config.DEFAULT_USERNAME, results.sandboxRes.authUserName);
83+
const result = await globalConfig.write();
84+
this.logger.debug('Set defaultUsername: %s result: %s', this.flags.setdefaultusername, result);
85+
}
86+
}
87+
});
88+
89+
this.logger.debug('Calling auth for SandboxName args: %s ', this.flags.sandboxname);
90+
const results = await this.org.sandboxStatus(this.flags.sandboxname, { wait: this.flags.wait as Duration });
91+
this.logger.debug('Results for auth call: %s ', results);
92+
if (!results) {
93+
this.ux.styledHeader('Sandbox Org Creation Status');
94+
this.ux.log('No SandboxProcess Result Found');
95+
}
96+
return results;
97+
}
98+
}

test/commands/force/org/display.test.ts

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
* Licensed under the BSD 3-Clause license.
55
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
66
*/
7-
import { $$, expect, test } from '@salesforce/command/lib/test';
7+
import { expect, test } from '@salesforce/command/lib/test';
88
import { Aliases, AuthInfo, Connection, Org } from '@salesforce/core';
9-
9+
import * as sinon from 'sinon';
1010
import { stubMethod, stubInterface, StubbedType } from '@salesforce/ts-sinon';
1111
import * as utils from '../../../../src/shared/utils';
1212

@@ -45,15 +45,15 @@ const fakeAuthUrl = 'fakeAuthUrl';
4545

4646
describe('org:display', () => {
4747
let authInfoStub: StubbedType<AuthInfo>;
48+
const sandbox = sinon.createSandbox();
4849

4950
beforeEach(async function () {
50-
$$.SANDBOX.restore();
51-
stubMethod($$.SANDBOX, Aliases, 'fetch')
51+
stubMethod(sandbox, Aliases, 'fetch')
5252
.withArgs('nonscratchalias')
5353
.resolves('[email protected]')
5454
.withArgs('scratchAlias')
5555
.resolves('[email protected]');
56-
stubMethod($$.SANDBOX, utils, 'getAliasByUsername')
56+
stubMethod(sandbox, utils, 'getAliasByUsername')
5757
.withArgs('[email protected]')
5858
.resolves('nonscratchalias')
5959
.withArgs('[email protected]')
@@ -62,9 +62,13 @@ describe('org:display', () => {
6262
.resolves(undefined);
6363
});
6464

65+
afterEach(() => {
66+
sandbox.restore();
67+
});
68+
6569
// eslint-disable-next-line @typescript-eslint/no-explicit-any
6670
async function prepareStubs(AuthInfoModifications: any = {}) {
67-
authInfoStub = stubInterface<AuthInfo>($$.SANDBOX, {
71+
authInfoStub = stubInterface<AuthInfo>(sandbox, {
6872
getFields: () => ({
6973
...baseAuthInfo,
7074
...AuthInfoModifications,
@@ -76,7 +80,7 @@ describe('org:display', () => {
7680
return 'badUrl';
7781
},
7882
});
79-
stubMethod($$.SANDBOX, AuthInfo, 'create').callsFake(async () => authInfoStub);
83+
stubMethod(sandbox, AuthInfo, 'create').callsFake(async () => authInfoStub);
8084
}
8185

8286
test
@@ -206,16 +210,16 @@ describe('org:display', () => {
206210
await prepareStubs({
207211
devHubUsername: devHub.username,
208212
});
209-
stubMethod($$.SANDBOX, Org, 'create').resolves(Org.prototype);
210-
stubMethod($$.SANDBOX, Org.prototype, 'getUsername').returns('[email protected]');
213+
stubMethod(sandbox, Org, 'create').resolves(Org.prototype);
214+
stubMethod(sandbox, Org.prototype, 'getUsername').returns('[email protected]');
211215

212-
stubMethod($$.SANDBOX, Org.prototype, 'getOrgId').resolves(devHub.id);
213-
stubMethod($$.SANDBOX, Org.prototype, 'getDevHubOrg').resolves({
216+
stubMethod(sandbox, Org.prototype, 'getOrgId').resolves(devHub.id);
217+
stubMethod(sandbox, Org.prototype, 'getDevHubOrg').resolves({
214218
getUsername: () => devHub.username,
215219
});
216-
stubMethod($$.SANDBOX, Org.prototype, 'getConnection').returns(Connection.prototype);
220+
stubMethod(sandbox, Org.prototype, 'getConnection').returns(Connection.prototype);
217221

218-
stubMethod($$.SANDBOX, Connection.prototype, 'sobject').returns({
222+
stubMethod(sandbox, Connection.prototype, 'sobject').returns({
219223
find: async () => {
220224
return [
221225
{

0 commit comments

Comments
 (0)