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

fix: update deploy and retrieve beta to use 1.1.19 #3048

Merged
merged 28 commits into from
Mar 12, 2021

Conversation

brpowell
Copy link
Contributor

@brpowell brpowell commented Mar 9, 2021

What does this PR do?

Updates the deploy and retrieve beta functionality to utilize the latest changes in the library.

  • Fix timeout issues. Occurs when deploy/retrieve operation runs longer than 10 seconds. Cancellation coming in a subsequent PR.
  • Fix result output when deploying/retrieving multi-file components
  • Fix an issue with unzipping some zip StaticResource components
  • Fix log name for manifest command
  • Updated command labels that use i18n messages.
  • More shared code paths between the commands. This ensures consistent outputting and logging.
  • Utilize tooling retrieve for retrieving source-backed single components through org browser and manifest. Grants a performance boost for tooling supported types.
  • Removes Tooling API deploy code path. Through A/B testing, benefits were not seen.

What issues does this PR fix or reference?

@W-8899035@

@codecov
Copy link

codecov bot commented Mar 9, 2021

Codecov Report

Merging #3048 (c26f7e5) into develop (904b541) will decrease coverage by 7.87%.
The diff coverage is 90.15%.

Impacted file tree graph

@@             Coverage Diff             @@
##           develop    #3048      +/-   ##
===========================================
- Coverage    84.04%   76.17%   -7.88%     
===========================================
  Files           69      276     +207     
  Lines         3103    10502    +7399     
  Branches       295     1235     +940     
===========================================
+ Hits          2608     8000    +5392     
- Misses         437     2158    +1721     
- Partials        58      344     +286     
Impacted Files Coverage Δ
...alesforcedx-vscode-core/src/commands/util/index.ts 100.00% <ø> (ø)
...cedx-vscode-core/src/commands/baseDeployCommand.ts 50.57% <50.00%> (ø)
...forcedx-vscode-core/src/diagnostics/diagnostics.ts 77.77% <70.58%> (ø)
...ceSourceRetrieveMetadata/forceSourceRetrieveCmp.ts 68.42% <80.00%> (ø)
...edx-vscode-core/src/commands/baseDeployRetrieve.ts 93.22% <93.22%> (ø)
...ode-core/src/commands/forceSourceDeployManifest.ts 61.53% <100.00%> (ø)
...e-core/src/commands/forceSourceDeploySourcePath.ts 54.71% <100.00%> (ø)
...e-core/src/commands/forceSourceRetrieveManifest.ts 58.33% <100.00%> (ø)
...core/src/commands/forceSourceRetrieveSourcePath.ts 65.90% <100.00%> (ø)
.../salesforcedx-vscode-core/src/diagnostics/index.ts 100.00% <100.00%> (ø)
... and 208 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 904b541...c26f7e5. Read the comment docs.

@brpowell brpowell requested a review from a team March 9, 2021 23:22
Comment on lines 53 to 67
const components = await this.getComponents(response);

this.telemetry.addProperty(
'metadataCount',
this.createComponentCount(components)
);

result = await this.doOperation(components);

const status = this.getStatus(result);

return (
status === RequestStatus.Succeeded ||
status === RequestStatus.SucceededPartial
);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

All DeployRetrieve commands need to report metadata counts and report status to the base executor.

Comment on lines 73 to 106
protected getRelativeProjectPath(fsPath: string = '', packageDirs: string[]) {
let packageDirIndex;
for (let packageDir of packageDirs) {
if (!packageDir.startsWith(sep)) {
packageDir = sep + packageDir;
}
if (!packageDir.endsWith(sep)) {
packageDir = packageDir + sep;
}
packageDirIndex = fsPath.indexOf(packageDir);
if (packageDirIndex !== -1) {
packageDirIndex += 1;
break;
}
}
return packageDirIndex !== -1 ? fsPath.slice(packageDirIndex) : fsPath;
}

private createComponentCount(
components: Iterable<MetadataComponent>
): string {
const quantities: { [type: string]: number } = {};
for (const component of components) {
const { name: typeName } = component.type;
const typeCount = quantities[typeName];
quantities[typeName] = typeCount ? typeCount + 1 : 1;
}
return JSON.stringify(
Object.keys(quantities).map(type => ({
type,
quantity: quantities[type]
}))
);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Some of these scattered utilities have been made private methods here since they are internal implementation to these commands.

Comment on lines +128 to +136
protected async doOperation(
components: ComponentSet
): Promise<DeployResult | undefined> {
return components
.deploy({
usernameOrConnection: await workspaceContext.getConnection()
})
.start();
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

All deploy commands follow the same pattern for kicking off

Comment on lines +141 to +157
try {
if (result) {
BaseDeployExecutor.errorCollection.clear();

const relativePackageDirs = await SfdxPackageDirectories.getPackageDirectoryPaths();
const output = this.createOutput(result, relativePackageDirs);
channelService.appendLine(output);

const success = result.response.status === RequestStatus.Succeeded;

if (!success) {
handleDeployDiagnostics(result, BaseDeployExecutor.errorCollection);
}
}
} finally {
await DeployQueue.get().unlock();
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

All deploy commands need to:

  • output results the same way
  • handle diagnostics the same way
  • unlock the deploy queue when they are finished

}
}

private createOutput(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Again, consolidating scattered output utilities as internal implementation to the deploy command. Did the same for retrieve below.

// utilize the tooling API for single component retrieves for improved performance
const oneComponent = components.getSourceComponents().first();

if (components.size === 1 && this.isToolingSupported(oneComponent)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

All retrieve commands will utilize the tooling api when it can, since single component retrieves are quite fast.

Copy link
Contributor

Choose a reason for hiding this comment

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

Why are we not adding this into SDR ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is how it has always been in the extensions up until this point. It should be added to the library though.

* This exists because the Tooling API result currently doesn't conform to the
* same interface as the Metadata API deploy and retrieve result objects.
*/
private createToolingOutput(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Eventually, consumers shouldn't really have to think about using the tooling api or not. The library should handle using the best api when it can. Also tooling results currently still have their own result format, so we have to do some gymnastics to handle that.

Comment on lines +59 to +65
protected async getComponents(
response: ContinueResponse<string>
): Promise<ComponentSet> {
const packageDirs = await SfdxPackageDirectories.getPackageDirectoryPaths();
try {
const components = await ComponentSet.fromManifestFile(response.data, {
resolve: packageDirs.map(dir => join(getRootWorkspacePath(), dir))
});
const deployPromise = components.deploy(
await workspaceContext.getConnection()
);
this.telemetry.addProperty(
'metadataCount',
JSON.stringify(createComponentCount(components))
);
const result = await deployPromise;

const outputResult = createDeployOutput(result, packageDirs);
channelService.appendLine(outputResult);
BaseDeployExecutor.errorCollection.clear();

if (result.status === DeployStatus.Succeeded) {
return true;
}

handleDeployRetrieveLibraryDiagnostics(
result,
BaseDeployExecutor.errorCollection
);

return false;
} finally {
await DeployQueue.get().unlock();
}
return ComponentSet.fromManifestFile(response.data, {
resolve: packageDirs.map(dir => join(getRootWorkspacePath(), dir))
});
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Now individual commands for the most part just have to extend the relevant base class (Deploy or Retrieve), and then describe how to fetch components.

.gitignore Outdated Show resolved Hide resolved
@brpowell brpowell marked this pull request as ready for review March 10, 2021 20:15
const components = await this.getComponents(response);

this.telemetry.addProperty(
'metadataCount',
Copy link
Contributor

@sfsholden sfsholden Mar 10, 2021

Choose a reason for hiding this comment

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

Does this make more sense to have as a constant?

filePath: this.getRelativeProjectPath(xml, relativePackageDirs)
});
}
} else if (properties) {
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 curious about testing this piece. Is this the type that would trigger this path? https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_properties.htm

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is sort of dead code...it's a relic from a previous implementation to provide a fallback if component isn't set. I can probably get rid of it

import { ContinueResponse } from '@salesforce/salesforcedx-utils-vscode/src/types';
import { ComponentSet, DeployStatus } from '@salesforce/source-deploy-retrieve';
import { ContinueResponse } from '@salesforce/salesforcedx-utils-vscode/out/src/types';
import { ComponentSet, DeployResult } from '@salesforce/source-deploy-retrieve';
Copy link
Contributor

Choose a reason for hiding this comment

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

Small nit - some unused imports here

const components = new ComponentSet(
comps.map(lc => ({ fullName: lc.fileName, type: lc.type }))
): Promise<ComponentSet> {
const filter = new ComponentSet(
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 able to walkthrough this portion of the code - I can't find a way to fire it. Is that because this class LibraryRetrieveSourcePathExecutor is also defined in forceSourceRetrieveSourcePath? Let me know if this is just simple user error on my end.

Copy link
Contributor

Choose a reason for hiding this comment

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

It looked like the index was only referring to the one defined within forceSourceRetrieveSourcePath.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This command is only used by the org browser (right now), so there isn't a command palette option for it. Try retrieving components through that tree.

@brpowell brpowell merged commit d628c7d into develop Mar 12, 2021
@brpowell brpowell deleted the bp/sdrUpdate-1.1.19 branch March 12, 2021 16:51
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.

None yet

3 participants