Skip to content

Commit 1d295ae

Browse files
committed
chore: [A] Allow using key=value format for config env
1 parent fe7f0ed commit 1d295ae

File tree

3 files changed

+85
-5
lines changed

3 files changed

+85
-5
lines changed

src/cli/config.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ module.exports = ({ commandProcessor, root }) => {
4444
});
4545

4646
commandProcessor.createCommand(env, 'set', 'Set an environment variable', {
47-
params: '<key> <value>',
47+
params: '<key> [value]',
4848
options: {
4949
'sandbox': {
5050
description: 'Target the sandbox',
@@ -65,9 +65,10 @@ module.exports = ({ commandProcessor, root }) => {
6565
return new EnvVarsCommand(args).setEnvVars(args);
6666
},
6767
examples: {
68-
'$0 $command <key> <value> --sandbox': 'Set env var to user\'s sandbox',
68+
'$0 $command <key> <value> --sandbox': 'Set env var to user\'s sandbox (space format)',
69+
'$0 $command <key=value> --sandbox': 'Set env var to user\'s sandbox (equal sign format)',
6970
'$0 $command <key> <value> --org <org>': 'Set env var for an organization',
70-
'$0 $command <key> <value> --product <productId>': 'Set env var for a product',
71+
'$0 $command <key=value> --product <productId>': 'Set env var for a product',
7172
'$0 $command <key> <value> --device <deviceId>': 'Set env var for a device',
7273
}
7374
});

src/cmd/env.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,12 @@ module.exports = class EnvVarsCommand extends CLICommandBase {
8888
this.ui.write('---------------------------------------------');
8989
};
9090

91-
async setEnvVars({ params: { key, value }, org, product, device, sandbox }) {
91+
async setEnvVars({ params, org, product, device, sandbox }) {
9292
this._validateScope({ sandbox, org, product, device });
93+
94+
// Parse key and value - supports both "key value" and "key=value" formats
95+
const { key, value } = this._parseKeyValue(params);
96+
9397
const operation = this._buildEnvVarOperation({ key, value, operation: 'Set' });
9498
await this.ui.showBusySpinnerUntilResolved('Setting environment variable...',
9599
this.api.patchEnvVars({
@@ -102,6 +106,28 @@ module.exports = class EnvVarsCommand extends CLICommandBase {
102106
this.ui.write(`Key ${key} has been successfully set.`);
103107
}
104108

109+
_parseKeyValue(params) {
110+
// If params has both key and value, use them directly (e.g., "key value" format)
111+
if (params.key && params.value) {
112+
return { key: params.key, value: params.value };
113+
}
114+
115+
// Otherwise, check if key contains "=" (e.g., "key=value" format)
116+
if (params.key && params.key.includes('=')) {
117+
const [key, ...valueParts] = params.key.split('=');
118+
const value = valueParts.join('='); // Handle values that contain "="
119+
120+
if (!key || value === undefined) {
121+
throw new Error('Invalid format. Use either "key value" or "key=value"');
122+
}
123+
124+
return { key, value };
125+
}
126+
127+
// If we got here, the format is invalid
128+
throw new Error('Invalid format. Use either "key value" or "key=value"');
129+
}
130+
105131
async deleteEnv({ params: { key }, org, product, device, sandbox, dryRun }) {
106132
this._validateScope({ sandbox, org, product, device });
107133

src/cmd/env.test.js

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,13 @@ describe('config env Command', () => {
138138
error_description: 'Validation error: : Must only contain uppercase letters, numbers, and underscores. Must not start with a number. at "ops[0].key"',
139139
error:'invalid_request'
140140
};
141+
const params = { key: 'invalid-key', value: 'bar' }; // Invalid key with dash
141142
nock('https://api.particle.io/v1')
142143
.intercept('/env', 'PATCH')
143144
.reply(400, apiError);
144145
let error;
145146
try {
146-
await envVarsCommands.setEnvVars({ params: {}, sandbox: true });
147+
await envVarsCommands.setEnvVars({ params, sandbox: true });
147148
} catch (_error) {
148149
error = _error;
149150
}
@@ -178,6 +179,58 @@ describe('config env Command', () => {
178179
expect(envVarsCommands.ui.showBusySpinnerUntilResolved).calledWith('Setting environment variable...');
179180
expect(envVarsCommands.ui.write).to.have.been.calledWith(`Key ${params.key} has been successfully set.`);
180181
});
182+
183+
it('set env var using key=value format', async () => {
184+
let receivedBody;
185+
const params = { key: 'FOO=bar' };
186+
nock('https://api.particle.io/v1')
187+
.intercept('/env', 'PATCH')
188+
.reply((uri, requestBody) => {
189+
receivedBody = requestBody;
190+
return [200, sandboxList];
191+
});
192+
await envVarsCommands.setEnvVars({ params, sandbox: true });
193+
expect(receivedBody).to.deep.equal({ ops: [{ key: 'FOO', value: 'bar', op: 'Set' }] });
194+
expect(envVarsCommands.ui.showBusySpinnerUntilResolved).calledWith('Setting environment variable...');
195+
expect(envVarsCommands.ui.write).to.have.been.calledWith('Key FOO has been successfully set.');
196+
});
197+
198+
it('set env var using key=value format with value containing equals sign', async () => {
199+
let receivedBody;
200+
const params = { key: 'FOO=bar=baz' };
201+
nock('https://api.particle.io/v1')
202+
.intercept('/env', 'PATCH')
203+
.reply((uri, requestBody) => {
204+
receivedBody = requestBody;
205+
return [200, sandboxList];
206+
});
207+
await envVarsCommands.setEnvVars({ params, sandbox: true });
208+
expect(receivedBody).to.deep.equal({ ops: [{ key: 'FOO', value: 'bar=baz', op: 'Set' }] });
209+
expect(envVarsCommands.ui.showBusySpinnerUntilResolved).calledWith('Setting environment variable...');
210+
expect(envVarsCommands.ui.write).to.have.been.calledWith('Key FOO has been successfully set.');
211+
});
212+
213+
it('throws error when key=value format is invalid (empty key)', async () => {
214+
const params = { key: '=bar' };
215+
let error;
216+
try {
217+
await envVarsCommands.setEnvVars({ params, sandbox: true });
218+
} catch (_error) {
219+
error = _error;
220+
}
221+
expect(error.message).to.equal('Invalid format. Use either "key value" or "key=value"');
222+
});
223+
224+
it('throws error when neither key/value nor key=value format is provided', async () => {
225+
const params = { key: 'FOO' }; // Missing value
226+
let error;
227+
try {
228+
await envVarsCommands.setEnvVars({ params, sandbox: true });
229+
} catch (_error) {
230+
error = _error;
231+
}
232+
expect(error.message).to.equal('Invalid format. Use either "key value" or "key=value"');
233+
});
181234
});
182235

183236
describe('delete env vars', () => {

0 commit comments

Comments
 (0)