Skip to content

Commit 1e673a2

Browse files
fix: add deploy:cancel (#66)
1 parent 2d399df commit 1e673a2

File tree

9 files changed

+151
-4
lines changed

9 files changed

+151
-4
lines changed

command-snapshot.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@
3737
"wait"
3838
]
3939
},
40+
{
41+
"command": "force:source:deploy:cancel",
42+
"plugin": "@salesforce/plugin-source",
43+
"flags": ["apiversion", "jobid", "json", "loglevel", "targetusername", "wait"]
44+
},
4045
{
4146
"command": "force:source:retrieve",
4247
"plugin": "@salesforce/plugin-source",

messages/cancel.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"description": "cancel a source deployment",
3+
"examples": [
4+
"$ sfdx force:source:deploy:cancel",
5+
"$ sfdx force:source:deploy:cancel -w 2",
6+
"$ sfdx force:source:deploy:cancel -i <jobid>"
7+
],
8+
"flags": {
9+
"wait": "wait time for command to finish in minutes",
10+
"jobid": "job ID of the deployment you want to cancel; defaults to your most recent CLI deployment if not specified"
11+
}
12+
}

package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,12 @@
9191
"external": true,
9292
"subtopics": {
9393
"source": {
94-
"description": "commands to interact with source formatted metadata"
94+
"description": "commands to interact with source formatted metadata",
95+
"subtopics": {
96+
"deploy": {
97+
"description": "interact with an active deploy request"
98+
}
99+
}
95100
}
96101
}
97102
}

src/commands/force/source/deploy.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,9 @@ export class Deploy extends SourceCommand {
135135

136136
await hookEmitter.emit('postdeploy', results);
137137

138+
const file = this.getConfig();
139+
await file.write({ [SourceCommand.STASH_KEY]: { jobid: results.response.id } });
140+
138141
// skip a lot of steps that would do nothing
139142
if (!this.flags.json) {
140143
this.print(results);
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright (c) 2020, salesforce.com, inc.
3+
* All rights reserved.
4+
* Licensed under the BSD 3-Clause license.
5+
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6+
*/
7+
8+
import * as os from 'os';
9+
import { flags, FlagsConfig } from '@salesforce/command';
10+
import { Messages } from '@salesforce/core';
11+
import { DeployResult } from '@salesforce/source-deploy-retrieve';
12+
import { Duration } from '@salesforce/kit';
13+
import { asString } from '@salesforce/ts-types';
14+
import { SourceCommand } from '../../../../sourceCommand';
15+
16+
Messages.importMessagesDirectory(__dirname);
17+
const messages = Messages.loadMessages('@salesforce/plugin-source', 'cancel');
18+
19+
export class Cancel extends SourceCommand {
20+
public static readonly description = messages.getMessage('description');
21+
public static readonly examples = messages.getMessage('examples').split(os.EOL);
22+
public static readonly requiresUsername = true;
23+
public static readonly flagsConfig: FlagsConfig = {
24+
wait: flags.minutes({
25+
char: 'w',
26+
default: Duration.minutes(SourceCommand.DEFAULT_SRC_WAIT_MINUTES),
27+
min: Duration.minutes(1),
28+
description: messages.getMessage('flags.wait'),
29+
}),
30+
jobid: flags.id({
31+
char: 'i',
32+
description: messages.getMessage('flags.jobid'),
33+
}),
34+
};
35+
36+
public async run(): Promise<DeployResult> {
37+
let id = asString(this.flags.jobid);
38+
if (!id) {
39+
const stash = this.getConfig();
40+
stash.readSync();
41+
id = asString((stash.get(SourceCommand.STASH_KEY) as { jobid: string }).jobid);
42+
}
43+
44+
// TODO: update to use SDRL we can just do this for now
45+
// this is the toolbelt implementation
46+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-assignment
47+
return (await this.org.getConnection().metadata['_invoke']('cancelDeploy', {
48+
id,
49+
})) as DeployResult;
50+
}
51+
}

src/sourceCommand.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import * as path from 'path';
88
import { SfdxCommand } from '@salesforce/command';
99
import { ComponentSet } from '@salesforce/source-deploy-retrieve';
10-
import { fs, SfdxError, Logger } from '@salesforce/core';
10+
import { fs, SfdxError, Logger, ConfigFile } from '@salesforce/core';
1111
import { ComponentLike } from '@salesforce/source-deploy-retrieve/lib/src/common';
1212

1313
export type FlagOptions = {
@@ -20,6 +20,12 @@ export type FlagOptions = {
2020

2121
export abstract class SourceCommand extends SfdxCommand {
2222
public static DEFAULT_SRC_WAIT_MINUTES = 33;
23+
public static STASH_KEY = 'SOURCE_DEPLOY';
24+
25+
public getConfig(): ConfigFile<{ isGlobal: true; filename: 'stash.json' }> {
26+
return new ConfigFile({ isGlobal: true, filename: 'stash.json' });
27+
}
28+
2329
/**
2430
* will create one ComponentSet to be deployed/retrieved
2531
* will combine from all options passed in
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright (c) 2020, salesforce.com, inc.
3+
* All rights reserved.
4+
* Licensed under the BSD 3-Clause license.
5+
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6+
*/
7+
8+
import { Dictionary } from '@salesforce/ts-types';
9+
import { DeployResult } from '@salesforce/source-deploy-retrieve';
10+
import * as sinon from 'sinon';
11+
import { expect } from 'chai';
12+
import { Cancel } from '../../../src/commands/force/source/deploy/cancel';
13+
14+
describe('force:source:cancel', () => {
15+
const jobid = '0Af1k00000r2BebCAE';
16+
const sandbox = sinon.createSandbox();
17+
18+
const run = async (
19+
flags: Dictionary<boolean | string | number | string[]> = {},
20+
id?: string
21+
): Promise<DeployResult> => {
22+
// TODO: fix this test for SDRL
23+
// Run the command
24+
// all the stubs will change with SDRL implementation, just call it good for now
25+
return Cancel.prototype.run.call({
26+
flags: Object.assign({}, flags),
27+
getConfig: () => {
28+
return { readSync: () => {}, get: () => jobid };
29+
},
30+
org: {
31+
getConnection: () => {
32+
return {
33+
metadata: {
34+
_invoke: () => {
35+
return {
36+
id: id || jobid,
37+
};
38+
},
39+
},
40+
};
41+
},
42+
},
43+
}) as Promise<DeployResult>;
44+
};
45+
46+
beforeEach(() => {});
47+
48+
afterEach(() => {
49+
sandbox.restore();
50+
});
51+
52+
it('should read from ~/.sfdx/stash.json', async () => {
53+
const result = await run({ json: true });
54+
expect(result).to.deep.equal({ id: jobid });
55+
});
56+
57+
it('should use the jobid flag', async () => {
58+
const jobIdFlag = '0Af1k00000r29C9CAI';
59+
const result = await run({ json: true, jobid: jobIdFlag }, jobIdFlag);
60+
expect(result).to.deep.equal({ id: jobIdFlag });
61+
});
62+
});

test/commands/source/deploy.test.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ describe('force:source:deploy', () => {
2020

2121
// TODO: When output work items have been done we can test result output
2222
// that more closely matches actual output.
23-
const stubbedResults = 'the stubbed results';
23+
const stubbedResults = { response: { id: '0Af1k00000r2BfKCAU' } };
2424

2525
// Stubs
2626
let createComponentSetStub: sinon.SinonStub;
@@ -45,6 +45,9 @@ describe('force:source:deploy', () => {
4545
getUsername: () => username,
4646
},
4747
createComponentSet: createComponentSetStub,
48+
getConfig: () => {
49+
return { write: () => {} };
50+
},
4851
progress: progressStub,
4952
print: () => {},
5053
}) as Promise<DeployResult>;

yarn.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,7 @@
740740

741741
"@salesforce/[email protected]":
742742
version "1.1.21"
743-
resolved "https://registry.npmjs.org/@salesforce/source-deploy-retrieve/-/source-deploy-retrieve-1.1.21.tgz#afb3b7dfe5b79ce1b3b9a016433fba9e3d83e0c7"
743+
resolved "https://registry.yarnpkg.com/@salesforce/source-deploy-retrieve/-/source-deploy-retrieve-1.1.21.tgz#afb3b7dfe5b79ce1b3b9a016433fba9e3d83e0c7"
744744
integrity sha512-+2nJh/GsSGE6bUolrcV6zA+RAutGIKjzS6IS7uFwHrpy0r7NCElgjRL/EkfahMgKxuVJDg8nQiVzWzi108AgPw==
745745
dependencies:
746746
"@salesforce/core" "2.13.0"

0 commit comments

Comments
 (0)