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

Wr/manifest generate #168

Merged
merged 21 commits into from
Aug 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

### [1.0.7](https://github.com/salesforcecli/plugin-source/compare/v1.0.6...v1.0.7) (2021-08-05)


### Bug Fixes

* bump SDR to 4.0.2 ([#169](https://github.com/salesforcecli/plugin-source/issues/169)) ([f750a3b](https://github.com/salesforcecli/plugin-source/commit/f750a3b9e841a9f6fe22e65093cb58886db69d93))

### [1.0.6](https://github.com/salesforcecli/plugin-source/compare/v1.0.5...v1.0.6) (2021-07-30)

### [1.0.5](https://github.com/salesforcecli/plugin-source/compare/v1.0.3...v1.0.5) (2021-07-29)
Expand Down
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ $ npm install -g @salesforce/plugin-source
$ sfdx COMMAND
running command...
$ sfdx (-v|--version|version)
@salesforce/plugin-source/1.0.5 linux-x64 node-v12.22.4
@salesforce/plugin-source/1.0.6 linux-x64 node-v12.22.4
$ sfdx --help [COMMAND]
USAGE
$ sfdx COMMAND
Expand Down Expand Up @@ -139,7 +139,7 @@ EXAMPLES
$ sfdx force:source:convert -r path/to/source -d path/to/outputdir -n 'My Package'
```

_See code: [src/commands/force/source/convert.ts](https://github.com/salesforcecli/plugin-source/blob/v1.0.5/src/commands/force/source/convert.ts)_
_See code: [src/commands/force/source/convert.ts](https://github.com/salesforcecli/plugin-source/blob/v1.0.6/src/commands/force/source/convert.ts)_

## `sfdx force:source:deploy [--soapdeploy] [-w <minutes>] [-q <id> | -x <filepath> | -m <array> | -p <array> | -c | -l NoTestRun|RunSpecifiedTests|RunLocalTests|RunAllTestsInOrg | -r <array> | -o | -g] [-u <string>] [--apiversion <string>] [--verbose] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]`

Expand Down Expand Up @@ -214,7 +214,7 @@ EXAMPLES
$ sfdx force:source:deploy -q 0Af9A00000FTM6pSAH
```

_See code: [src/commands/force/source/deploy.ts](https://github.com/salesforcecli/plugin-source/blob/v1.0.5/src/commands/force/source/deploy.ts)_
_See code: [src/commands/force/source/deploy.ts](https://github.com/salesforcecli/plugin-source/blob/v1.0.6/src/commands/force/source/deploy.ts)_

## `sfdx force:source:deploy:cancel [-w <minutes>] [-i <id>] [-u <string>] [--apiversion <string>] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]`

Expand Down Expand Up @@ -252,7 +252,7 @@ EXAMPLES
$ sfdx force:source:deploy:cancel -i <jobid>
```

_See code: [src/commands/force/source/deploy/cancel.ts](https://github.com/salesforcecli/plugin-source/blob/v1.0.5/src/commands/force/source/deploy/cancel.ts)_
_See code: [src/commands/force/source/deploy/cancel.ts](https://github.com/salesforcecli/plugin-source/blob/v1.0.6/src/commands/force/source/deploy/cancel.ts)_

## `sfdx force:source:deploy:report [-w <minutes>] [-i <id>] [-u <string>] [--apiversion <string>] [--verbose] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]`

Expand Down Expand Up @@ -297,7 +297,7 @@ EXAMPLES
$ sfdx force:source:deploy:report
```

_See code: [src/commands/force/source/deploy/report.ts](https://github.com/salesforcecli/plugin-source/blob/v1.0.5/src/commands/force/source/deploy/report.ts)_
_See code: [src/commands/force/source/deploy/report.ts](https://github.com/salesforcecli/plugin-source/blob/v1.0.6/src/commands/force/source/deploy/report.ts)_

## `sfdx force:source:open -f <filepath> [-r] [-u <string>] [--apiversion <string>] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]`

Expand Down Expand Up @@ -339,7 +339,7 @@ EXAMPLES
$ sfdx force:source:open -f path/to/source -u [email protected]
```

_See code: [src/commands/force/source/open.ts](https://github.com/salesforcecli/plugin-source/blob/v1.0.5/src/commands/force/source/open.ts)_
_See code: [src/commands/force/source/open.ts](https://github.com/salesforcecli/plugin-source/blob/v1.0.6/src/commands/force/source/open.ts)_

## `sfdx force:source:retrieve [-p <array> | -x <filepath> | -m <array>] [-w <minutes>] [-n <array>] [-u <string>] [-a <string>] [--verbose] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]`

Expand Down Expand Up @@ -394,5 +394,5 @@ EXAMPLES
sfdx force:source:retrieve -n MyPackageName -x path/to/package.xml
```

_See code: [src/commands/force/source/retrieve.ts](https://github.com/salesforcecli/plugin-source/blob/v1.0.5/src/commands/force/source/retrieve.ts)_
_See code: [src/commands/force/source/retrieve.ts](https://github.com/salesforcecli/plugin-source/blob/v1.0.6/src/commands/force/source/retrieve.ts)_
<!-- commandsstop -->
7 changes: 6 additions & 1 deletion command-snapshot.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@
{
"command": "force:source:deploy:report",
"plugin": "@salesforce/plugin-source",
"flags": ["apiversion", "jobid", "json", "loglevel", "targetusername", "wait", "verbose"]
"flags": ["apiversion", "jobid", "json", "loglevel", "targetusername", "verbose", "wait"]
},
{
"command": "force:source:manifest:create",
"plugin": "@salesforce/plugin-source",
"flags": ["apiversion", "json", "loglevel", "manifestname", "manifesttype", "metadata", "outputdir", "sourcepath"]
},
{
"command": "force:source:open",
Expand Down
17 changes: 17 additions & 0 deletions messages/create.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"description": "create a project manifest that lists the metadata components you want to deploy or retrieve \n Create a manifest from a list of metadata components (--metadata) or from one or more local directories that contain source files (--sourcepath). You can specify either of these parameters, not both.\n\nUse --manifesttype to specify the type of manifest you want to create. The resulting manifest files have specific names, such as the standard package.xml or destructiveChanges.xml to delete metadata. Valid values for this parameter, and their respective file names, are:\n\n package : package.xml (default)\n pre : destructiveChangesPre.xml\n post : destructiveChangesPost.xml\n destroy : destructiveChanges.xml\n\nSee https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_deploy_deleting_files.htm for information about these destructive manifest files. \n\nUse --manifestname to specify a custom name for the generated manifest if the pre-defined ones don’t suit your needs. You can specify either --manifesttype or --manifestname, but not both.\n",
"examples": [
"$ sfdx force:source:manifest:create -m ApexClass",
"$ sfdx force:source:manifest:create -m ApexClass:MyApexClass --manifesttype destroy",
"$ sfdx force:source:manifest:create --sourcepath force-app --manifestname myNewManifest"
],
"flags": {
"manifesttype": "type of manifest to create; the type determines the name of the created file",
"manifestname": "name of a custom manifest file to create",
"outputdir": "directory to save the created manifest",
"sourcepath": "comma-separated list of paths to the local source files to include in the manifest",
"metadata": "comma-separated list of names of metadata components to include in the manifest"
},
"success": "successfully wrote %s",
"successOutputDir": "successfully wrote %s to %s"
}
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"name": "@salesforce/plugin-source",
"description": "Commands to interact with source formatted metadata",
"version": "1.0.6",
"version": "1.0.7",
"author": "Salesforce",
"bugs": "https://github.com/forcedotcom/cli/issues",
"dependencies": {
"@oclif/config": "^1",
"@salesforce/command": "^4.0.4",
"@salesforce/core": "^2.26.1",
"@salesforce/source-deploy-retrieve": "^4.0.1",
"@salesforce/source-deploy-retrieve": "^4.0.2",
"chalk": "^4.1.1",
"cli-ux": "^5.6.3",
"open": "^8.2.1",
Expand Down Expand Up @@ -100,6 +100,9 @@
"subtopics": {
"deploy": {
"description": "interact with an active deploy request"
},
"manifest": {
"description": "create a manifest to use in a deploy/retrieve"
}
}
}
Expand Down Expand Up @@ -129,6 +132,7 @@
"test:nuts:convert": "PLUGIN_SOURCE_SEED_FILTER=\"convert\" ts-node ./test/nuts/generateNuts.ts && nyc mocha \"**/*.nut.ts\" --slow 3000 --timeout 600000 --parallel --retries 0",
"test:nuts:deploy": "PLUGIN_SOURCE_SEED_FILTER=\"deploy\" ts-node ./test/nuts/generateNuts.ts && nyc mocha \"**/*.nut.ts\" --slow 3000 --timeout 600000 --parallel --retries 0",
"test:nuts:retrieve": "PLUGIN_SOURCE_SEED_FILTER=\"retrieve\" ts-node ./test/nuts/generateNuts.ts && nyc mocha \"**/*.nut.ts\" --slow 3000 --timeout 600000 --parallel --retries 0",
"test:nuts:manifest:create": "nyc mocha \"test/nuts/create.nut.ts\" --slow 3000 --timeout 600000 --parallel --retries 0",
"version": "oclif-dev readme"
},
"husky": {
Expand Down
12 changes: 5 additions & 7 deletions src/commands/force/source/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/
import * as os from 'os';
import { flags, FlagsConfig } from '@salesforce/command';
import { Messages, SfdxError } from '@salesforce/core';
import { Messages } from '@salesforce/core';
import { AsyncResult, DeployResult } from '@salesforce/source-deploy-retrieve';
import { Duration } from '@salesforce/kit';
import { getString, isString } from '@salesforce/ts-types';
Expand All @@ -24,7 +24,6 @@ Messages.importMessagesDirectory(__dirname);
const messages = Messages.loadMessages('@salesforce/plugin-source', 'deploy');

// One of these flags must be specified for a valid deploy.
const requiredFlags = ['manifest', 'metadata', 'sourcepath', 'validateddeployrequestid'];

type TestLevel = 'NoTestRun' | 'RunSpecifiedTests' | 'RunLocalTests' | 'RunAllTestsInOrg';

Expand Down Expand Up @@ -100,6 +99,7 @@ export class Deploy extends DeployCommand {
exclusive: ['metadata', 'sourcepath'],
}),
};
protected xorFlags = ['manifest', 'metadata', 'sourcepath', 'validateddeployrequestid'];
protected readonly lifecycleEventNames = ['predeploy', 'postdeploy'];

private isAsync = false;
Expand All @@ -112,11 +112,6 @@ export class Deploy extends DeployCommand {
});

public async run(): Promise<DeployCommandResult | DeployCommandAsyncResult> {
// verify that the user defined one of: manifest, metadata, sourcepath, validateddeployrequestid
if (!Object.keys(this.flags).some((flag) => requiredFlags.includes(flag))) {
throw SfdxError.create('@salesforce/plugin-source', 'deploy', 'MissingRequiredParam', [requiredFlags.join(', ')]);
}

await this.deploy();
this.resolveSuccess();
return this.formatResult();
Expand All @@ -127,6 +122,9 @@ export class Deploy extends DeployCommand {
// 2. asynchronous - deploy metadata and immediately return.
// 3. recent validation - deploy metadata that's already been validated by the org
protected async deploy(): Promise<void> {
// verify that the user defined one of: manifest, metadata, sourcepath, validateddeployrequestid
this.validateFlags();

const waitDuration = this.getFlag<Duration>('wait');
this.isAsync = waitDuration.quantity === 0;
this.isRest = await this.isRestDeploy();
Expand Down
117 changes: 117 additions & 0 deletions src/commands/force/source/manifest/create.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*
* Copyright (c) 2020, salesforce.com, inc.
* All rights reserved.
* 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 { join } from 'path';
import { flags, FlagsConfig } from '@salesforce/command';
import { fs } from '@salesforce/core';
import { Messages } from '@salesforce/core';
import { SourceCommand } from '../../../../sourceCommand';
import { ComponentSetBuilder } from '../../../../componentSetBuilder';

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

const manifestTypes: Record<string, string> = {
pre: 'destructiveChangesPre.xml',
post: 'destructiveChangesPost.xml',
destroy: 'destructiveChanges.xml',
package: 'package.xml',
};

interface CreateCommandResult {
name: string;
path: string;
}

export class create 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 flagsConfig: FlagsConfig = {
apiversion: flags.builtin({}),
metadata: flags.array({
char: 'm',
description: messages.getMessage('flags.metadata'),
exclusive: ['sourcepath'],
}),
sourcepath: flags.array({
char: 'p',
description: messages.getMessage('flags.sourcepath'),
exclusive: ['metadata'],
}),
manifestname: flags.string({
char: 'n',
description: messages.getMessage('flags.manifestname'),
exclusive: ['manifesttype'],
}),
manifesttype: flags.enum({
description: messages.getMessage('flags.manifesttype'),
options: Object.keys(manifestTypes),
char: 't',
}),
outputdir: flags.string({
char: 'o',
description: messages.getMessage('flags.outputdir'),
}),
};
protected xorFlags = ['metadata', 'sourcepath'];
private manifestName: string;
private outputDir: string;
private outputPath: string;

public async run(): Promise<CreateCommandResult> {
await this.createManifest();
this.resolveSuccess();
return this.formatResult();
}

protected async createManifest(): Promise<void> {
this.validateFlags();
// convert the manifesttype into one of the "official" manifest names
// if no manifesttype flag passed, use the manifestname flag
// if no manifestname flag, default to 'package.xml'
this.manifestName =
manifestTypes[this.getFlag<string>('manifesttype')] || this.getFlag<string>('manifestname') || 'package.xml';
this.outputDir = this.getFlag<string>('outputdir');

const componentSet = await ComponentSetBuilder.build({
apiversion: this.getFlag('apiversion'),
sourcepath: this.getFlag<string[]>('sourcepath'),
metadata: this.flags.metadata && {
metadataEntries: this.getFlag<string[]>('metadata'),
directoryPaths: this.getPackageDirs(),
},
});

// add the .xml suffix if the user just provided a file name
this.manifestName = this.manifestName.endsWith('.xml') ? this.manifestName : this.manifestName + '.xml';

if (this.outputDir) {
fs.mkdirSync(this.outputDir, { recursive: true });
this.outputPath = join(this.outputDir, this.manifestName);
} else {
this.outputPath = this.manifestName;
}

return fs.writeFile(this.outputPath, componentSet.getPackageXml());
}

// noop this method because any errors will be reported by the createManifest method
// eslint-disable-next-line @typescript-eslint/no-empty-function
protected resolveSuccess(): void {}

protected formatResult(): CreateCommandResult {
if (!this.isJsonOutput()) {
if (this.outputDir) {
this.ux.log(messages.getMessage('successOutputDir', [this.manifestName, this.outputDir]));
} else {
this.ux.log(messages.getMessage('success', [this.manifestName]));
}
}
return { path: this.outputPath, name: this.manifestName };
}
}
10 changes: 9 additions & 1 deletion src/sourceCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

import { SfdxCommand } from '@salesforce/command';
import { Lifecycle } from '@salesforce/core';
import { Lifecycle, SfdxError } from '@salesforce/core';
import { ComponentSet } from '@salesforce/source-deploy-retrieve';
import { get, getBoolean, getString, Optional } from '@salesforce/ts-types';
import cli from 'cli-ux';
Expand All @@ -21,6 +21,7 @@ export type ProgressBar = {

export abstract class SourceCommand extends SfdxCommand {
public static readonly DEFAULT_SRC_WAIT_MINUTES = 33;
protected xorFlags: string[] = [];
protected progressBar?: ProgressBar;
protected lifecycle = Lifecycle.getInstance();

Expand All @@ -30,6 +31,13 @@ export abstract class SourceCommand extends SfdxCommand {
return getBoolean(this.flags, 'json', false);
}

protected validateFlags(): void {
// verify that the user defined one of the flag names specified in requiredFlags property
if (!Object.keys(this.flags).some((flag) => this.xorFlags.includes(flag))) {
throw SfdxError.create('@salesforce/plugin-source', 'deploy', 'MissingRequiredParam', [this.xorFlags.join(', ')]);
}
}

protected getFlag<T>(flagName: string, defaultVal?: unknown): T {
return get(this.flags, flagName, defaultVal) as T;
}
Expand Down
Loading