Skip to content

Commit

Permalink
fix: source:retrieve working as a user, json and hook info wrong, mis…
Browse files Browse the repository at this point in the history
…sing tests
  • Loading branch information
WillieRuemmele committed Feb 16, 2021
1 parent aba798d commit 7828c3f
Show file tree
Hide file tree
Showing 12 changed files with 2,146 additions and 1,347 deletions.
18 changes: 17 additions & 1 deletion command-snapshot.json
Original file line number Diff line number Diff line change
@@ -1 +1,17 @@
[]
[
{
"command": "force:source:retrieve",
"plugin": "@salesforce/plugin-source",
"flags": [
"apiversion",
"json",
"loglevel",
"manifest",
"metadata",
"packagenames",
"sourcepath",
"targetusername",
"wait"
]
}
]
26 changes: 26 additions & 0 deletions messages/deploy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"description": "retrieve source from an org",
"examples": [
"sfdx force:source:retrieve -p path/to/source",
"sfdx force:source:retrieve -p \"path/to/apex/classes/MyClass.cls,path/to/source/objects\"",
"sfdx force:source:retrieve -p \"path/to/objects/MyCustomObject/fields/MyField.field-meta.xml, path/to/apex/classes\"",
"sfdx force:source:retrieve -m ApexClass",
"sfdx force:source:retrieve -m ApexClass:MyApexClass",
"sfdx force:source:retrieve -m \"CustomObject,ApexClass\"",
"sfdx force:source:retrieve -x path/to/package.xml",
"sfdx force:source:retrieve -n \"Package1, PackageName With Spaces, Package3\"",
"sfdx force:source:retrieve -n MyPackageName -p path/to/apex/classes",
"sfdx force:source:retrieve -n MyPackageName -x path/to/package.xml"
],
"flags": {
"sourcePath": "comma-separated list of source file paths to retrieve",
"manifestParamDescription": "file path for manifest (package.xml) of components to retrieve",
"metadataParamDescription": "comma-separated list of metadata component names",
"wait": "wait time for command to finish in minutes",
"manifest": "file path for manifest (package.xml) of components to retrieve",
"metadata": "comma-separated list of metadata component names",
"packagename": "a comma-separated list of packages to retrieve",
"verbose": "verbose output of retrieve result"
},
"SourceRetrieveError": "Could not retrieve files in the sourcepath%s"
}
27 changes: 27 additions & 0 deletions messages/retrieve.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"description": "retrieve source from an org",
"examples": [
"sfdx force:source:retrieve -p path/to/source",
"sfdx force:source:retrieve -p \"path/to/apex/classes/MyClass.cls,path/to/source/objects\"",
"sfdx force:source:retrieve -p \"path/to/objects/MyCustomObject/fields/MyField.field-meta.xml, path/to/apex/classes\"",
"sfdx force:source:retrieve -m ApexClass",
"sfdx force:source:retrieve -m ApexClass:MyApexClass",
"sfdx force:source:retrieve -m \"CustomObject,ApexClass\"",
"sfdx force:source:retrieve -x path/to/package.xml",
"sfdx force:source:retrieve -n \"Package1, PackageName With Spaces, Package3\"",
"sfdx force:source:retrieve -n MyPackageName -p path/to/apex/classes",
"sfdx force:source:retrieve -n MyPackageName -x path/to/package.xml"
],
"flags": {
"sourcePath": "comma-separated list of source file paths to retrieve",
"manifestParamDescription": "file path for manifest (package.xml) of components to retrieve",
"metadataParamDescription": "comma-separated list of metadata component names",
"wait": "wait time for command to finish in minutes",
"manifest": "file path for manifest (package.xml) of components to retrieve",
"metadata": "comma-separated list of metadata component names",
"packagename": "a comma-separated list of packages to retrieve",
"verbose": "verbose output of retrieve result"
},
"SourceRetrieveError": "Could not retrieve files in the sourcepath%s",
"retrieveTimeout": "Your retrieve request did not complete within the specified wait time [%s minutes]. Try again with a longer wait time."
}
41 changes: 41 additions & 0 deletions messages/sourceCommand.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"SourceTrackedOrgError": "This command cannot be used on orgs that have source tracking enabled.",
"NonSourceTrackedOrgError": "This command can only be used on orgs that have source tracking enabled, such as sandboxes and scratch orgs.",
"SourceTrackedOrgErrorAction": "Run \"sfdx force:source:%s\" instead.",
"waitParamDescription": "wait time for command to finish in minutes",
"waitParamDescriptionLong": "Number of minutes to wait for the command to complete and display results to the terminal window. If the command continues to run after the wait period, the CLI returns control of the terminal window to you. The default is 33 minutes.",
"pushCommandCliPreExecute": "Pushing source changes to org %s as user %s",
"deployCommandCliPreExecute": "Deploy source to org %s as user %s",
"stateTableColumn": "STATE",
"fullNameTableColumn": "FULL NAME",
"typeTableColumn": "TYPE",
"workspacePathTableColumn": "PROJECT PATH",
"retrievedSourceHeader": "Retrieved Source",
"NoResultsFound": "No results found",
"metadataNotFoundWarning": "WARNING: The following metadata isn’t in your org. If it’s not new, someone deleted it from the org.",
"columnNumberColumn": "COLUMN NUMBER",
"lineNumberColumn": "LINE NUMBER",
"errorColumn": "PROBLEM",
"pushCommandHumanSuccess": "Pushed Source",
"pushCommandHumanError": "Push Errors",
"deployCommandHumanSuccess": "Deployed Source",
"deployCommandHumanError": "Deploy Errors",
"deleteCommandHumanSuccess": "Deleted Source",
"deleteCommandHummanError": "Delete Errors",
"DeployTimeout": "The source %s operation took longer than the specified wait time. Wait time in minutes (%s) exceeded. Increase the wait time using the --wait option, and try again.",
"mdapiCliInvalidNumericParam": "Invalid value for %s. Must be a positive numerical value.",
"SourcePathInvalid": "The sourcepath \"%s\" is not a valid source file path.",
"IllFormattedManifest": "The manifest file is improperly formatted%s.",
"InvalidManifestError": "The specified manifest file [%s] does not exist, or you don't have access to it.",
"failedToCreateManifest": "Couldn't create a manifest.",
"missingScopeOption": "Missing source scope option.",
"missingOutputDirPath": "The output directory is missing but required.",
"UnsupportedType": "The specified metadata type is unsupported: [%s]",
"flowDefinitionDeprecation": "FlowDefinition isn’t supported in the Salesforce CLI for API version 44.0 and later. Make sure that the flowDefinitions directory is empty and that you’ve upgraded the flow files per the instructions in the Metadata API Developer Guide: https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_visual_workflow.htm#md_flow_upgrade.",
"flowDeprecation": "Flows must be used with a minimum API version of 44.0. Make sure that the sfdx-project.json file is set to use \"sourceApiVersion\": \"44.0\" or later, and that you’ve upgraded the flow files per the instructions in the Metadata API Developer Guide: https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_visual_workflow.htm#md_flow_upgrade.",
"MissingRequiredParam": "Missing one of the following parameters: %s",
"XmlParsingError": "This file has an XML parsing error: %s. This is the first file we encountered; however, other files could be affected.",
"StaticResourceDeleteError": "You can't delete an individual file from a static resource using force:source:delete, only an entire directory. To delete a file, delete it from your local DX project, then use force:source:push (for scratch orgs) or force:source:deploy to update the static resource in the target org.",
"MissingComponentOrResource": "We're unable to complete this action due to a missing source file. Verify that the source file name that corresponds to the %s exists and is correct, and try again.",
"MetadataTypeDoesNotExist": "We can't find the metadata object named %s. Verify that this metadata exists and try again."
}
14 changes: 11 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
"bugs": "https://github.com/forcedotcom/cli/issues",
"dependencies": {
"@oclif/config": "^1",
"@salesforce/cli-plugins-testkit": "^0.0.3",
"@salesforce/command": "^3.1.0",
"@salesforce/core": "^2.18.0",
"@salesforce/core": "^2.18.3",
"@salesforce/source-deploy-retrieve": "^1.1.17",
"chalk": "^4.1.0",
"tslib": "^2"
},
"devDependencies": {
Expand Down Expand Up @@ -73,8 +76,13 @@
"@salesforce/plugin-command-reference"
],
"topics": {
"hello": {
"description": "Commands to say hello."
"force": {
"external": true,
"subtopics": {
"source": {
"description": "commands to interact with source formatted metadata"
}
}
}
}
},
Expand Down
126 changes: 126 additions & 0 deletions src/commands/force/source/retrieve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,129 @@
* 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 * as os from 'os';
import { flags, FlagsConfig } from '@salesforce/command';
import { Lifecycle, Messages, SfdxError } from '@salesforce/core';
import { SourceRetrieveResult } from '@salesforce/source-deploy-retrieve';
import { Duration } from '@salesforce/kit';
import { DEFAULT_SRC_WAIT_MINUTES, MINIMUM_SRC_WAIT_MINUTES, SourceCommand } from '../../../sourceCommand';

Messages.importMessagesDirectory(__dirname);
const messages = Messages.loadMessages('@salesforce/plugin-source', 'retrieve');

export class retrieve extends SourceCommand {
public static readonly description = messages.getMessage('description');
public static readonly examples = messages.getMessage('examples').split(os.EOL);
public static readonly requiresProject = true;
public static readonly requiresUsername = true;
public static readonly flagsConfig: FlagsConfig = {
sourcepath: flags.array({
char: 'p',
description: messages.getMessage('flags.sourcePath'),
exclusive: ['manifest', 'metadata'],
}),
wait: flags.minutes({
char: 'w',
default: Duration.minutes(DEFAULT_SRC_WAIT_MINUTES),
min: MINIMUM_SRC_WAIT_MINUTES,
description: messages.getMessage('flags.wait'),
}),
manifest: flags.filepath({
char: 'x',
description: messages.getMessage('flags.manifest'),
exclusive: ['metadata', 'sourcepath'],
}),
metadata: flags.array({
char: 'm',
description: messages.getMessage('flags.metadata'),
exclusive: ['manifest', 'sourcepath'],
}),
packagenames: flags.array({
char: 'n',
description: messages.getMessage('flags.packagename'),
}),
};
protected readonly lifecycleEventNames = ['preretrieve', 'postretrieve'];

public async run(): Promise<SourceRetrieveResult> {
const hookEmitter = Lifecycle.getInstance();
const packages = await this.retrievePackageDirs();
const defaultPackage = packages.find((pkg) => pkg.default);

const cs = await this.createComponentSet({
// safe to cast from the flags as an array of strings
packagenames: this.flags.packagenames as string[],
sourcepath: this.flags.sourcepath as string[],
manifest: this.flags.manifest as string,
metadata: this.flags.metadata as string[],
});

// emit pre retrieve event
// needs to be a path to the temp dir package.xml
await hookEmitter.emit('preretrieve', { packageXmlPath: cs.getPackageXml() });

const results = await cs.retrieve(this.org.getUsername(), this.getAbsolutePath(defaultPackage.path), {
merge: true,
// TODO: fix this once wait has been updated in library
wait: 1000000,
});

// emit post retrieve event
// results must match = {
// "done": true,
// "fileProperties": [
// {
// "createdById": "0053B000005FbiuQAC",
// "createdByName": "User User",
// "createdDate": "2021-02-09T23:48:26.000Z",
// "fileName": "unpackaged/classes/MyTest.cls",
// "fullName": "MyTest",
// "id": "01p3B000008hOVcQAM",
// "lastModifiedById": "0053B000005FbiuQAC",
// "lastModifiedByName": "User User",
// "lastModifiedDate": "2021-02-11T23:00:49.000Z",
// "manageableState": "unmanaged",
// "type": "ApexClass"
// },
// {
// "createdById": "0053B000005FbiuQAC",
// "createdByName": "User User",
// "createdDate": "2021-02-09T23:48:27.000Z",
// "fileName": "unpackaged/classes/force.cls",
// "fullName": "force",
// "id": "01p3B000008hOVdQAM",
// "lastModifiedById": "0053B000005FbiuQAC",
// "lastModifiedByName": "User User",
// "lastModifiedDate": "2021-02-11T23:00:49.000Z",
// "manageableState": "unmanaged",
// "type": "ApexClass"
// },
// {
// "createdById": "0053B000005FbiuQAC",
// "createdByName": "User User",
// "createdDate": "2021-02-12T17:27:58.876Z",
// "fileName": "unpackaged/package.xml",
// "fullName": "unpackaged/package.xml",
// "id": "",
// "lastModifiedById": "0053B000005FbiuQAC",
// "lastModifiedByName": "User User",
// "lastModifiedDate": "2021-02-12T17:27:58.876Z",
// "manageableState": "unmanaged",
// "type": "Package"
// }
// ],
// "id": "09S3B000002N5lcUAC",
// "status": "Succeeded",
// "success": true,
// "zipFilePath": "/var/folders/28/dmr8rt4d5f5bq_ttscbspz580000gp/T/sdx_sourceRetrieve_pkg_1613150491146/unpackaged.zip"
// }
await hookEmitter.emit('postretrieve', results);

if (results.status === 'InProgress') {
throw new SfdxError(messages.getMessage('retrieveTimeout', [(this.flags.wait as Duration).minutes]));
}
this.printTable(results, true);

return results;
}
}
Loading

0 comments on commit 7828c3f

Please sign in to comment.