-
Notifications
You must be signed in to change notification settings - Fork 393
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
Conversation
Codecov Report
@@ 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
Continue to review full report at Codecov.
|
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 | ||
); |
There was a problem hiding this comment.
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.
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] | ||
})) | ||
); | ||
} |
There was a problem hiding this comment.
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.
protected async doOperation( | ||
components: ComponentSet | ||
): Promise<DeployResult | undefined> { | ||
return components | ||
.deploy({ | ||
usernameOrConnection: await workspaceContext.getConnection() | ||
}) | ||
.start(); | ||
} |
There was a problem hiding this comment.
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
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(); | ||
} |
There was a problem hiding this comment.
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( |
There was a problem hiding this comment.
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)) { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 ?
There was a problem hiding this comment.
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( |
There was a problem hiding this comment.
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.
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)) | ||
}); |
There was a problem hiding this comment.
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.
const components = await this.getComponents(response); | ||
|
||
this.telemetry.addProperty( | ||
'metadataCount', |
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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'; |
There was a problem hiding this comment.
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( |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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.
What does this PR do?
Updates the deploy and retrieve beta functionality to utilize the latest changes in the library.
What issues does this PR fix or reference?
@W-8899035@