Skip to content

Commit a2bd50c

Browse files
authored
feat: run:function:start defaults to local mode (#343)
* feat: run:function:start now defaults to local It is now an alias to run:function:start:local rather than run:function:start:container. * feat: hide deprecated/ignored arguments * feat: add deprecation warnings for deprecated flags * chore: test deprecation notices * chore: fix deprecation note for --env * chore: reuse local code from start * chore: update snapshot with new argument
1 parent ce1a41b commit a2bd50c

File tree

5 files changed

+172
-21
lines changed

5 files changed

+172
-21
lines changed

command-snapshot.json

+1
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@
114114
"debug-port",
115115
"descriptor",
116116
"env",
117+
"language",
117118
"network",
118119
"no-build",
119120
"no-pull",

messages/run.function.start.md

+55-1
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,58 @@ Build and run a Salesforce Function.
66

77
Run this command from the directory of your Salesforce Functions project.
88

9-
This command will run the target function in a container. In the future, this command will run the target function on the host operating system (locally) instead. If one mode is preferred over the other, consider using the `container` or `local` subcommand instead.
9+
This command will run the target function locally (on the same operating system as this CLI), just like the `local` subcommand.
10+
11+
Previously, this command ran functions in a container. Container mode is still supported via the `container` subcommand. Arguments relevant to container mode are still accepted, but are deprecated, ignored, and will be dropped in a future release.
12+
13+
# flags.language.summary
14+
15+
The language that the function runs in.
16+
17+
# flags.path.summary
18+
19+
Path to function directory.
20+
21+
# flags.port.summary
22+
23+
Port for running the function.
24+
25+
# flags.debug-port.summary
26+
27+
Port for remote debugging.
28+
29+
# flags.verbose.summary
30+
31+
Output additional logs.
32+
33+
# flags.builder.deprecation
34+
35+
--builder is deprecated and will be removed in a future release. Please discontinue use of this flag or use the `container` subcommand instead.
36+
37+
# flags.clear-cache.deprecation
38+
39+
--clear-cache is deprecated and will be removed in a future release. Please discontinue use of this flag or use the `container` subcommand instead.
40+
41+
# flags.descriptor.deprecation
42+
43+
--descriptor is deprecated and will be removed in a future release. Please discontinue use of this flag or use the `container` subcommand instead.
44+
45+
# flags.env.deprecation
46+
47+
--env is deprecated and will be removed in a future release. Please discontinue use of this flag or use the `container` subcommand instead.
48+
49+
# flags.network.deprecation
50+
51+
--network is deprecated and will be removed in a future release. Please discontinue use of this flag or use the `container` subcommand instead.
52+
53+
# flags.no-build.deprecation
54+
55+
--no-build is deprecated and will be removed in a future release. Please discontinue use of this flag or use the `container` subcommand instead.
56+
57+
# flags.no-pull.deprecation
58+
59+
--no-pull is deprecated and will be removed in a future release. Please discontinue use of this flag or use the `container` subcommand instead.
60+
61+
# flags.no-run.deprecation
62+
63+
--no-run is deprecated and will be removed in a future release. Please discontinue use of this flag or use the `container` subcommand instead.

src/commands/run/function/start.ts

+80-3
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,91 @@
55
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
66
*/
77

8+
import * as path from 'path';
89
import { Messages } from '@salesforce/core';
9-
import Container from './start/container';
10+
import { Flags } from '@oclif/core';
11+
import { LocalRun } from '@heroku/functions-core';
12+
13+
import Local from './start/local';
1014

1115
Messages.importMessagesDirectory(__dirname);
1216
const messages = Messages.loadMessages('@salesforce/plugin-functions', 'run.function.start');
1317

14-
// run:function:start is an alias to run:function:start:container
15-
export default class Start extends Container {
18+
// run:function:start is an alias command to run:function:start:local.
19+
// run:function:start previously ran via container mode, so it still accepts
20+
// arguments applicable to the container subcommand, but ignores them and flags
21+
// them as deprecated. The additional flags may be removed after 04/30/2022.
22+
export default class Start extends Local {
1623
static summary = messages.getMessage('summary');
24+
1725
static description = messages.getMessage('description');
26+
27+
static flags = {
28+
builder: Flags.string({
29+
hidden: true,
30+
}),
31+
'clear-cache': Flags.boolean({
32+
hidden: true,
33+
}),
34+
'debug-port': Flags.integer({
35+
char: 'b',
36+
description: messages.getMessage('flags.debug-port.summary'),
37+
default: 9229,
38+
}),
39+
descriptor: Flags.string({
40+
hidden: true,
41+
}),
42+
env: Flags.string({
43+
char: 'e',
44+
multiple: true,
45+
hidden: true,
46+
}),
47+
language: Flags.enum({
48+
options: ['javascript', 'typescript', 'java', 'auto'],
49+
char: 'l',
50+
default: 'auto',
51+
}),
52+
network: Flags.string({
53+
hidden: true,
54+
}),
55+
'no-build': Flags.boolean({
56+
hidden: true,
57+
}),
58+
'no-pull': Flags.boolean({
59+
hidden: true,
60+
}),
61+
'no-run': Flags.boolean({
62+
hidden: true,
63+
}),
64+
path: Flags.string({
65+
description: messages.getMessage('flags.path.summary'),
66+
default: path.resolve('.'),
67+
hidden: true,
68+
}),
69+
port: Flags.integer({
70+
char: 'p',
71+
description: messages.getMessage('flags.port.summary'),
72+
default: 8080,
73+
}),
74+
verbose: Flags.boolean({
75+
char: 'v',
76+
description: messages.getMessage('flags.verbose.summary'),
77+
}),
78+
};
79+
80+
async run() {
81+
const { flags } = await this.parse(Start);
82+
Object.entries(flags).forEach(([flag, val]) => {
83+
let msg: string | null = null;
84+
try {
85+
msg = messages.getMessage(`flags.${flag}.deprecation`);
86+
if (val) {
87+
this.warn(msg);
88+
}
89+
} catch {
90+
// No deprecation message, flag is not deprecated
91+
}
92+
});
93+
await this.runWithFlags(flags);
94+
}
1895
}

src/commands/run/function/start/local.ts

+6
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ export default class Local extends Command {
4343

4444
async run() {
4545
const { flags } = await this.parse(Local);
46+
await this.runWithFlags(flags);
47+
}
48+
49+
async runWithFlags(
50+
flags: { path: string; port: number; 'debug-port': number; language: string } & { json: boolean | undefined }
51+
) {
4652
const localRun = new LocalRun(flags.language, {
4753
path: flags.path,
4854
port: flags.port,

test/commands/run/function/start.test.ts

+30-17
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,46 @@
44
* Licensed under the BSD 3-Clause license.
55
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
66
*/
7-
import { test } from '@oclif/test';
7+
import { expect, test } from '@oclif/test';
88
import * as sinon from 'sinon';
9+
import { LocalRun } from '@heroku/functions-core';
910

10-
import * as library from '@heroku/functions-core';
11-
import { Benny } from '@heroku/functions-core';
12-
13-
describe('function:start', () => {
11+
describe('run:function:start', () => {
1412
let sandbox: sinon.SinonSandbox;
15-
let bennyRunStub: sinon.SinonStub;
16-
let bennyBuildStub: sinon.SinonStub;
13+
let localRunExecStub: sinon.SinonStub;
1714
beforeEach(() => {
1815
sandbox = sinon.createSandbox();
19-
bennyRunStub = sandbox.stub(Benny.prototype, 'run');
20-
bennyBuildStub = sandbox.stub(Benny.prototype, 'build');
21-
bennyRunStub.returns(true);
22-
bennyBuildStub.returns(true);
23-
sandbox
24-
.stub(library, 'getProjectDescriptor')
25-
.returns(Promise.resolve({ com: { salesforce: { id: 'allthethingsfunction' } } }));
16+
localRunExecStub = sandbox.stub(LocalRun.prototype, 'exec');
17+
localRunExecStub.resolves();
2618
});
2719

2820
afterEach(() => {
2921
sandbox.restore();
3022
});
3123

32-
test.command(['run:function:start']).it('Should call the library methods', async () => {
33-
sinon.assert.calledOnce(bennyBuildStub);
34-
sinon.assert.calledOnce(bennyRunStub);
24+
test.command(['run:function:start']).it('Should call LocalRun.exec', async () => {
25+
sinon.assert.calledOnce(localRunExecStub);
26+
});
27+
28+
['--builder', '--network', '--env'].forEach((deprecatedArg) => {
29+
describe(`with deprecated arg ${deprecatedArg}`, () => {
30+
test
31+
.stderr()
32+
.command(['run:function:start', deprecatedArg, 'some:val'])
33+
.it('will include a deprecation notice', (ctx) => {
34+
expect(ctx.stderr).to.contain(`${deprecatedArg} is deprecated`);
35+
});
36+
});
37+
});
38+
39+
['--no-pull', '--no-run', '--no-build'].forEach((deprecatedArg) => {
40+
describe(`with deprecated flag ${deprecatedArg}`, () => {
41+
test
42+
.stderr()
43+
.command(['run:function:start', deprecatedArg])
44+
.it('will include a deprecation notice', (ctx) => {
45+
expect(ctx.stderr).to.contain(`${deprecatedArg} is deprecated`);
46+
});
47+
});
3548
});
3649
});

0 commit comments

Comments
 (0)