Skip to content
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
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"author": "Salesforce",
"bugs": "https://github.com/forcedotcom/cli/issues",
"dependencies": {
"@oclif/core": "^3.20.0",
"@oclif/core": "^3.26.0",
"@salesforce/core": "^6.7.3",
"@salesforce/sf-plugins-core": "^8.0.2",
"fast-levenshtein": "^3.0.0"
Expand All @@ -15,9 +15,8 @@
"@oclif/test": "^3.2.8",
"@salesforce/cli-plugins-testkit": "^5.1.13",
"@salesforce/dev-scripts": "^8.4.2",
"@salesforce/kit": "^3.0.15",
"@salesforce/plugin-command-reference": "^3.0.73",
"@salesforce/plugin-deploy-retrieve": "^1.20.3",
"@salesforce/plugin-deploy-retrieve": "^3.5.2",
"@salesforce/ts-sinon": "^1.4.17",
"@types/fast-levenshtein": "^0.0.4",
"eslint-plugin-sf-plugin": "^1.17.4",
Expand Down
10 changes: 10 additions & 0 deletions src/alias.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,13 @@ export abstract class AliasCommand<T> extends SfCommand<T> {
this.table(results, columns, { title, 'no-truncate': true });
}
}

export const aliasErrorHandler = (err: unknown, alias: string, value?: string): AliasResult => {
const { name, message } =
err instanceof Error
? err
: typeof err === 'string'
? new Error(err)
: { name: 'UnknownError', message: 'Unknown Error' };
return { alias, success: false, error: { name, message }, value };
};
38 changes: 16 additions & 22 deletions src/commands/alias/set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import { loglevel, parseVarArgs } from '@salesforce/sf-plugins-core';
import { StateAggregator, Messages } from '@salesforce/core';
import { AliasCommand, AliasResults } from '../../alias.js';
import { AliasCommand, AliasResults, aliasErrorHandler } from '../../alias.js';

Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
const messages = Messages.loadMessages('@salesforce/plugin-settings', 'alias.set');
Expand All @@ -31,28 +31,22 @@ export default class AliasSet extends AliasCommand<AliasResults> {

const parsed = parseVarArgs(args, argv as string[]);

const results = Object.entries(parsed).map(([alias, value]) => {
try {
// to support plugin-settings in sfdx, which allowed setting an alias to undefined, when that happens we'll unset the alias
// which is what the user wants
if (!value) {
stateAggregator.aliases.unset(alias);
} else {
stateAggregator.aliases.set(alias, value);
const results = await Promise.all(
Object.entries(parsed).map(async ([alias, value]) => {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because we're setting aliases in parallel you'll see some NUTs change because the alias entries can end up in any order

[also, they're now good tests of the alias cross-save lockfile feature]

try {
// to support plugin-settings in sfdx, which allowed setting an alias to undefined, when that happens we'll unset the alias
// which is what the user wants
if (!value) {
await stateAggregator.aliases.unsetAndSave(alias);
} else {
await stateAggregator.aliases.setAndSave(alias, value);
}
return { alias, success: true, value };
} catch (err) {
return aliasErrorHandler(err, alias, value);
}
return { alias, success: true, value };
} catch (err) {
const { name, message } =
err instanceof Error
? err
: typeof err === 'string'
? new Error(err)
: { name: 'UnknownError', message: 'Unknown Error' };
return { alias, success: false, error: { name, message }, value };
}
});

await stateAggregator.aliases.write();
})
);

this.output('Alias Set', results);

Expand Down
34 changes: 15 additions & 19 deletions src/commands/alias/unset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import { Flags, loglevel } from '@salesforce/sf-plugins-core';
import { StateAggregator, Messages } from '@salesforce/core';
import { AliasCommand, AliasResults } from '../../alias.js';
import { AliasCommand, AliasResults, aliasErrorHandler } from '../../alias.js';

Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
const messages = Messages.loadMessages('@salesforce/plugin-settings', 'alias.unset');
Expand Down Expand Up @@ -57,24 +57,20 @@ export default class AliasUnset extends AliasCommand<AliasResults> {
return [];
}

const results = toRemove.map((alias) => {
// We will log the value in the output in case an alias was unset by mistake.
const value = aliases[alias];
try {
stateAggregator.aliases.unset(alias);
return { alias, value, success: true };
} catch (err) {
const { name, message } =
err instanceof Error
? err
: typeof err === 'string'
? new Error(err)
: { name: 'UnknownError', message: 'Unknown Error' };
return { alias, value, success: false, error: { name, message } };
}
});

await stateAggregator.aliases.write();
const results = await Promise.all(
toRemove
// We will log the value in the output in case an alias was unset by mistake.
.map((alias) => ({ alias, value: aliases[alias] }))
.map(async ({ alias, value }) => {
try {
// safe to parallelize because of file locking
await stateAggregator.aliases.unsetAndSave(alias);
return { alias, value, success: true };
} catch (err) {
return aliasErrorHandler(err, alias, value);
}
})
);

this.output('Alias Unset', results);

Expand Down
5 changes: 3 additions & 2 deletions test/commands/alias/list.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ describe('alias list NUTs', () => {

it('lists multiple results correctly JSON', () => {
const result = execCmd('alias list --json', { ensureExitCode: 0 }).jsonOutput?.result;
expect(result).to.deep.equal([
expect(result).lengthOf(3);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these each now assert the total length and that each item is included

[
{
alias: 'DevHub',
value: 'mydevhuborg@salesforce.com',
Expand All @@ -89,7 +90,7 @@ describe('alias list NUTs', () => {
alias: 'user',
value: 'user@salesforce.com',
},
]);
].map((expected) => expect(result).to.deep.include(expected));
});

it('lists multiple results correctly stdout', () => {
Expand Down
1 change: 0 additions & 1 deletion test/commands/alias/list.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
* 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 { expect, test } from '@oclif/test';
import { TestContext } from '@salesforce/core/lib/testSetup.js';

Expand Down
18 changes: 9 additions & 9 deletions test/commands/alias/unset.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ describe('alias unset NUTs', () => {
]);

const res = execCmd<AliasResults>('alias list --json', { ensureExitCode: 0 }).jsonOutput?.result;

expect(res).to.deep.equal([
expect(res).lengthOf(2);
[
{
alias: 'Admin',
value: 'admin@salesforce.com',
Expand All @@ -78,7 +78,7 @@ describe('alias unset NUTs', () => {
alias: 'user',
value: 'user@salesforce.com',
},
]);
].map((expected) => expect(res).to.deep.include(expected));
});

it('alias unset DevHub', () => {
Expand Down Expand Up @@ -118,8 +118,8 @@ describe('alias unset NUTs', () => {

it('alias unset --json', () => {
const result = execCmd('alias unset DevHub user --json', { ensureExitCode: 0 }).jsonOutput?.result;

expect(result).to.deep.equal([
expect(result).lengthOf(2);
[
{
alias: 'DevHub',
success: true,
Expand All @@ -130,7 +130,7 @@ describe('alias unset NUTs', () => {
success: true,
value: 'user@salesforce.com',
},
]);
].map((expected) => expect(result).to.deep.include(expected));

const res = execCmd('alias list --json', { ensureExitCode: 0 }).jsonOutput?.result;

Expand All @@ -155,8 +155,8 @@ describe('alias unset NUTs', () => {

it('removes all aliases when passing --all', () => {
const result = execCmd('alias unset --all --no-prompt --json', { ensureExitCode: 0 }).jsonOutput?.result;

expect(result).to.deep.equal([
expect(result).lengthOf(3);
[
{
alias: 'Admin',
success: true,
Expand All @@ -172,7 +172,7 @@ describe('alias unset NUTs', () => {
success: true,
value: 'user@salesforce.com',
},
]);
].map((expected) => expect(result).to.deep.include(expected));

const res = execCmd('alias list --json', { ensureExitCode: 0 }).jsonOutput?.result;

Expand Down
2 changes: 1 addition & 1 deletion test/commands/sfdx/config/get.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ chaiConfig.truncateThreshold = 0;

describe('config:get NUTs', async () => {
testSession = await TestSession.create({
project: { name: 'configGetNUTs' },
project: { name: 'configGetNUTs-sfdx' },
devhubAuthStrategy: 'NONE',
});

Expand Down
2 changes: 1 addition & 1 deletion test/commands/sfdx/config/list.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ let testSession: TestSession;

describe('config:list NUTs', async () => {
testSession = await TestSession.create({
project: { name: 'configListNUTs' },
project: { name: 'configListNUTs-sfdx' },
devhubAuthStrategy: 'NONE',
});
describe('config:list with no configs set', () => {
Expand Down
2 changes: 1 addition & 1 deletion test/commands/sfdx/config/set.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ function verifyKeysAndValuesStdout(key: string, value: string | boolean, asserti

describe('config:set NUTs', async () => {
testSession = await TestSession.create({
project: { name: 'configSetNUTs' },
project: { name: 'configSetNUTs-sfdx' },
devhubAuthStrategy: 'NONE',
});

Expand Down
2 changes: 1 addition & 1 deletion test/commands/sfdx/config/unset.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ let testSession: TestSession;

describe('config:unset NUTs', async () => {
testSession = await TestSession.create({
project: { name: 'configUnsetNUTs' },
project: { name: 'configUnsetNUTs-sfdx' },
});

describe('config:unset without keys', () => {
Expand Down
Loading