Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flagfeature #1237

Merged
merged 20 commits into from
Oct 30, 2024
Merged

Flagfeature #1237

merged 20 commits into from
Oct 30, 2024

Conversation

soridalac
Copy link
Contributor

@soridalac soridalac commented Oct 14, 2024

What does this PR do?

feat: update flags and fields in definition file for cloning existing sandbox.

What issues does this PR fix or reference?

@W-16883274@
forcedotcom/cli#3036

@soridalac soridalac requested a review from a team as a code owner October 14, 2024 21:05
Copy link
Contributor

@jshackell-sfdc jshackell-sfdc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see my suggestions and a question!


# error.sandboxNameQueryFailed

Unable to find the ID of the sandboxName "%s" that's defined in the definition file.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Unable to find the ID of the sandboxName "%s" that's defined in the definition file.
Unable to find the ID of the sandbox "%s" that's defined in the definition file.

The value of --clone must be an existing sandbox. The existing sandbox, and the new sandbox specified with the --name flag, must both be associated with the production org (--target-org) that contains the sandbox licenses.
The value of --source-sandbox-name must be an existing sandbox. The existing sandbox, and the new sandbox specified with the --name flag, must both be associated with the production org (--target-org) that contains the sandbox licenses.

You can specify either --source-sandbox-name or --source-id for clone an existing sandbox but not both.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You can specify either --source-sandbox-name or --source-id for clone an existing sandbox but not both.
You can specify either --source-sandbox-name or --source-id when cloning an existing sandbox, but not both.


The value of --source-id must be an existing sandbox. The existing sandbox, and the new sandbox specified with the --name flag, must both be associated with the production org (--target-org) that contains the sandbox licenses.

You can specify either --source-sandbox-name or --source-id for clone an existing sandbox but not both.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You can specify either --source-sandbox-name or --source-id for clone an existing sandbox but not both.
You can specify either --source-sandbox-name or --source-id when cloning an existing sandbox, but not both.

@@ -120,6 +132,14 @@ The sandbox request configuration isn't acceptable.

The poll interval (%d seconds) can't be larger that wait (%d in seconds)

# error.noCloneSource
# error.noCloneSourceName

Could not find the clone sandbox name "%s" in the target org.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Could not find the clone sandbox name "%s" in the target org.
Couldn't find the clone sandbox name "%s" in the target org.


# error.noCloneSourceId

Could not find the clone sandbox id "%s" in the target org.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Could not find the clone sandbox id "%s" in the target org.
Couldn't find the clone sandbox ID "%s" in the target org.


# error.cloneFlagsConflict

You can not use clone Name or Id flags and clone Name or Id fields in the definition file at the same time.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand what this error message means. Can you elaborate? Thanks!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on our DMs, it sounds like this error occurs if users try to use --source-sandbox-name AND --definition-file AND the definition file contains SourceSandboxName. Ditto for the ID equivalents. And I guess this isn't allowed? If this is indeed the situation, here's my edit of the error:

You can't specify both the --source-sandbox-name and --definition-file flags, and also include the "SourceSandboxName" option in the definition file. Same with the --source-id flag and "SourceId" option. Pick one method of cloning a sandbox and try again.

@@ -211,7 +211,7 @@ export class Create extends SfCommand<CreateResult> {
});

const { sandboxReq } = await requestFunctions.createSandboxRequest(
false,
// false,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this comment

@@ -20,13 +20,15 @@ const getLicenseTypes = (): string[] => Object.values(SandboxLicenseType);

type SandboxConfirmData = SandboxRequest & { CloneSource?: string };

// eslint-disable-next-line sf-plugin/only-extend-SfCommand
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

were these causing errors? if not, let's re-enable them 👍🏼 (warnings reminds us we have to do it anyway)

@@ -79,18 +81,25 @@ export default class CreateSandbox extends SandboxCommandBase<SandboxCommandResp
return Promise.resolve(name);
},
}),
clone: Flags.string({
'source-sandbox-name': Flags.string({
char: 'c',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the short flag -c should also be a deprecated alias.

deprecateAliases: true,
aliases: ['clone'],
}),
'source-id': Flags.string({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be a salesforceId flag, example:

'source-org': Flags.salesforceId({
summary: messages.getMessage('flags.source-org.summary'),
startsWith: '00D',
length: 15,
helpGroup: definitionFileHelpGroupName,
// salesforceId flag has `i` and that would be a conflict with client-id
char: undefined,
}),

I don't see the API mentions sandbox IDs start with a particular prefix so we can omit the startWith option.

Flags.salesforceId will validate that the ID length is 15 or 18.

? { SourceId: await requestFunctions.getSrcIdByName(this.flags['target-org'].getConnection(), srcSandboxName) }
: {}),
...(srcId ? { SourceId: srcId } : {}),
...(this.flags['source-id'] ? { SourceId: await this.getSourceId() } : {}),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to check for flags and props, on L140 we already pass the source flags as requestOptions to requestFunctions.createSandboxRequest, srcSandboxName and srcId should have the flag/def. file values.

? { CloneSource: this.flags['source-sandbox-name'] }
: this.flags['source-id']
? { CloneSource: this.flags['source-id'] }
: {}),
Copy link
Member

@cristiand391 cristiand391 Oct 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CloneSource will only be shown if when using the source flags, what if I'm specifying the ID in the def. file instead?

Maybe CloneSource should always show the source ID (you can grab it from sandboxReq.SourceId, so we don't need to check flag/def. file values here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@soridalac this is still unresolved ⬆️
we can ignore --source-sandbox-name, just check for sandboxReq.SourceId

const sourceSandboxNameInDefFile = !!defFileContent.SourceSandboxName;

if ((sourceIdFlag || sourceSandboxNameFlag) && (sourceIdInDefFile || sourceSandboxNameInDefFile)) {
throw messages.createError('error.cloneFlagsConflict');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these validations don't require any specific context other than reading the def.file, let's move these to each source flag, like this:

parse: (name: string): Promise<string> => {

you can do more specific error msgs like Can't use --source-id and define sourceId in the def. file at the same time.

return sourceOrg.SandboxInfoId;
} catch (err) {
throw messages.createError('error.noCloneSource', [this.flags.clone], [], err as Error);
throw messages.createError('error.noCloneSourceId', [this.flags['source-id']], [], err as Error);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this method can be removed, the value of --source-id or sourceId in the def. file is already a valid ID that we can pass to the API.

Copy link
Member

@cristiand391 cristiand391 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

requested some changes.
Also can you add some UTs in test/shared/sandboxRequest.test.ts to cover the new scenarios? e.g. sourceId/sourceSandboxName throws, sourceId/sourceSandboxName trigger a clone.

if (!SourceSandboxName) {
// error - we need SourceSandboxName to know which sandbox to clone from
if (!sandboxReqWithName.SourceSandboxName && !sandboxReqWithName.SourceId) {
// error - we need SourceSandboxName or SourceId to know which sandbox to clone from
throw new SfError(
cloneMessages.getMessage('missingSourceSandboxName', ['SourceSandboxName']),
cloneMessages.getMessage('missingSourceSandboxNameAction', ['SourceSandboxName'])
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we update these errors so they point if either SourceSandboxName or SourceId are being missed? the missingSourceSandboxName error will only mention SourceSandboxName

src/shared/sandboxRequest.ts Show resolved Hide resolved
test/shared/sandboxRequest.test.ts Show resolved Hide resolved
return {
...sandboxReq,
...(this.flags.clone ? { SourceId: await this.getSourceId() } : {}),
...(srcSandboxName ?? this.flags['source-sandbox-name']
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to check for --source-sandbox-name here, srcSandboxName should have that value (requestFunctions.createSandboxRequest takes these flags as requestOptions and merges them with the def.file).

...(srcSandboxName ?? this.flags['source-sandbox-name']
? { SourceId: await requestFunctions.getSrcIdByName(this.flags['target-org'].getConnection(), srcSandboxName) }
: {}),
...(srcId ?? this.flags['source-id'] ? { SourceId: srcId } : {}),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto, srcId should have the flag value, def. file value or undefined
https://github.com/salesforcecli/plugin-org/pull/1237/files#r1805117017

Copy link
Member

@cristiand391 cristiand391 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

almost there!
there are a few unresolved comments

src/shared/sandboxRequest.ts Show resolved Hide resolved
test/shared/sandboxRequest.test.ts Show resolved Hide resolved
Copy link
Member

@cristiand391 cristiand391 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, I'm approving code changes only, will ping Juliet for another review of the messages before merging.

@cristiand391
Copy link
Member

QA notes:

flags

--source-id and --source-sandbox-name is blocked
--source-id and sourceId in def. file is blocked
--source-*** flags and --license-type is blocked.
--source-sandbox-name and sourceSandboxName in def. file is blocked
--clone/-c flag is deprecated
--source-id works with 15/18-char IDs
--source-sandbox-name is resolved to the correct sourceId
✅ throw user-friendly error if sourceSbxName -> sourceID can't be solved.

def. file

sourceId and sourceSandboxName is blocked
sourceId and licenseType is blocked
Screenshot 2024-10-28 at 9 18 58 AM
sourceSandboxName and licenseType is blocked
✅ throw user-friendly error if sourceSbxName -> sourceID can't be solved.

command

✅ any source-id-related flag/prop triggers a clone
⚠️ tab with values is readable
CloneSource is always the sourceID even though it's not a real request value.
Screenshot 2024-10-28 at 9 31 06 AM

Since we'll always show the sourceId value when cloning let's remove CloneSource from the table.

⚠️ command help-text/examples are valid

sf org create sandbox --help still mentions --clone as the way to clone sandboxes and in examples:

Screenshot 2024-10-28 at 9 28 55 AM

@cristiand391
Copy link
Member

❌ sourceId and licenseType is blocked
❌ sourceSandboxName and licenseType is blocked
⚠️ command help-text/examples are valid

✅ fixed

@cristiand391 cristiand391 merged commit a23ce06 into main Oct 30, 2024
11 checks passed
@cristiand391 cristiand391 deleted the flagfeature branch October 30, 2024 15:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants