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
17 changes: 17 additions & 0 deletions src/desktop/env-manager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,23 @@ describe('EnvironmentManager', () => {
});
});

describe('updateEnvironment - fires onDidChangeEnvVars', () => {
it('fires on init and config change', async () => {
const listener = jest.fn();
environmentManager.onDidChangeEnvVars(listener);

await environmentManager.activate(mockContext);
expect(listener).toHaveBeenCalledTimes(1);

listener.mockClear();
configurationProviderMock.getConfigVariableOrDefault.mockReturnValue({
MY_VAR: 'new_value',
});
configurationProviderMock.fireOnChangeConfiguration(CONFIG_ENVIRONMENT_VARIABLES);
expect(listener).toHaveBeenCalledTimes(1);
});
});

describe('updateEnvironment - mixed variables', () => {
it('handles both PATH and non-PATH variables together', async () => {
configurationProviderMock = configurationProviderFactory({
Expand Down
20 changes: 19 additions & 1 deletion src/desktop/env-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ const DEFAULT_PATH_VAR = (process.platform === 'win32') ? 'Path' : 'PATH';
export interface EnvironmentManager {
activate(context: vscode.ExtensionContext): Promise<void>;
augmentEnv(env: Environment | undefined): Environment;

readonly onDidChangeEnvVars: vscode.Event<void>;
}

export interface Environment {
Expand Down Expand Up @@ -175,10 +177,14 @@ class PythonEnvironmentExtensionWrapper {
}

class EnvironmentManagerImpl implements EnvironmentManager {
private lastEnvVars: string | undefined;

private pyEnvWrapper: Optional<PythonEnvironmentExtensionWrapper> = undefined;
private context: vscode.ExtensionContext | undefined = undefined;

private readonly envVarsChangeEmitter = new vscode.EventEmitter<void>();
public readonly onDidChangeEnvVars = this.envVarsChangeEmitter.event;

constructor(
private readonly configurationProvider: ConfigurationProvider,
) {
Expand All @@ -192,6 +198,7 @@ class EnvironmentManagerImpl implements EnvironmentManager {

context.subscriptions.push(
vscode.extensions.onDidChange(() => this.updateEnvironment(context)),
this.envVarsChangeEmitter,
);

this.configurationProvider.onChangeConfiguration(
Expand Down Expand Up @@ -234,6 +241,16 @@ class EnvironmentManagerImpl implements EnvironmentManager {
});
}

const vars = envSettings.vars;
const currentEnvVars = JSON.stringify(
Object.entries(vars)
.filter(([, v]) => v !== undefined)
.sort(([a], [b]) => a.localeCompare(b)),
);
if (currentEnvVars === this.lastEnvVars) {
return;
}

context.environmentVariableCollection.clear();
for (const [key, value] of Object.entries(envSettings.vars)) {
if (value !== undefined) {
Expand All @@ -243,8 +260,9 @@ class EnvironmentManagerImpl implements EnvironmentManager {
context.environmentVariableCollection.replace(key, value);
}
}

}
this.lastEnvVars = currentEnvVars;
this.envVarsChangeEmitter.fire();
Comment thread
jthuangarm marked this conversation as resolved.
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/desktop/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,8 @@ export const activate = async (context: ExtensionContext): Promise<CsolutionExte
eventHub,
rpcData,
commandsProvider,
environmentManagerApiProvider);
environmentManagerApiProvider,
envManager);

initUtils(configurationProvider, solutionManager);

Expand Down
42 changes: 42 additions & 0 deletions src/solutions/solution-manager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ import { TestDataHandler } from '../__test__/test-data';
import { Board, Device } from '../json-rpc/csolution-rpc-client';
import { csolutionServiceFactory } from '../json-rpc/csolution-rpc-client.factory';
import { SolutionRpcData } from './solution-rpc-data';
import { configurationProviderFactory, MockConfigurationProvider } from '../vscode-api/configuration-provider.factories';
import { EnvironmentManager } from '../desktop/env-manager';
import { CONFIG_ENVIRONMENT_VARIABLES } from '../manifest';


const convertResultData: ConvertResultData = {
Expand All @@ -51,9 +54,11 @@ describe('SolutionManager', () => {
let loadStateChangeListener: jest.Mock;
let changeConfigurationEmitter: EventEmitter<ConfigurationChangeEvent>;
let commandsProvider: MockCommandsProvider;
let configurationProviderMock: MockConfigurationProvider;
let changeSolutionFilesEmitter: EventEmitter<void>;
let vcpkgActivateEmitter: EventEmitter<VcpkgResults>;
let environmentManagerApi: Pick<EnvironmentManagerApiV1, 'onDidActivate' | 'getActiveTools'>;
let environmentManager: EnvironmentManager;
let eventHub: SolutionEventHub;
let convertMock: jest.Mock;
let loadBuildFilesListener: jest.Mock;
Expand Down Expand Up @@ -116,20 +121,25 @@ describe('SolutionManager', () => {

commandsProvider = commandsProviderFactory();
csolutionService = csolutionServiceFactory();
configurationProviderMock = configurationProviderFactory({
[CONFIG_ENVIRONMENT_VARIABLES]: {},
});
const device: Device = { id: 'device-id' };
const board: Board = { id: 'board-id' };
csolutionService.getDeviceInfo.mockResolvedValue({ success: true, device });
csolutionService.getBoardInfo.mockResolvedValue({ success: true, board });
csolutionService.loadSolution.mockResolvedValue({ success: true });
csolutionService.getVariables.mockResolvedValue({ success: true, variables: {} });
rpcData = new SolutionRpcData(csolutionService);
environmentManager = new EnvironmentManager(configurationProviderMock);

solutionManager = new SolutionManagerImpl(
mockActiveSolutionTracker as unknown as ActiveSolutionTracker,
eventHub,
rpcData,
commandsProvider,
extensionApiProviderFactory(environmentManagerApi),
environmentManager,
);
loadStateChangeListener = jest.fn();
solutionManager.onDidChangeLoadState(loadStateChangeListener);
Expand Down Expand Up @@ -279,4 +289,36 @@ describe('SolutionManager', () => {
]),
);
});

it('requests restartRpc when envVars change after solution is activated', async () => {
mockActiveSolutionTracker.activeSolution = testSolutionPath;
changeActiveSolutionEmitter.fire();
await waitTimeout(100);

await environmentManager.activate({
subscriptions: [],
environmentVariableCollection: {
clear: jest.fn(),
prepend: jest.fn(),
replace: jest.fn(),
} as unknown as vscode.GlobalEnvironmentVariableCollection,
} as unknown as ExtensionContext);

convertMock.mockClear();
configurationProviderMock.getConfigVariableOrDefault.mockReturnValue({
NEW_VAR: 'new_value',
});
configurationProviderMock.fireOnChangeConfiguration(CONFIG_ENVIRONMENT_VARIABLES);
await waitTimeout(600);

expect(convertMock).toHaveBeenCalledTimes(1);
expect(convertMock).toHaveBeenLastCalledWith(
expect.objectContaining({
solutionPath: testSolutionPath,
updateRte: false,
restartRpc: true,
lockAbort: false,
}),
);
});
});
6 changes: 5 additions & 1 deletion src/solutions/solution-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { EnvironmentManagerApiV1 } from '@arm-software/vscode-environment-manage
import { ETextFileResult } from '../generic/text-file';
import { debounce } from 'lodash';
import { SolutionRpcData } from './solution-rpc-data';
import { EnvironmentManager } from '../desktop/env-manager';


export interface SolutionLoadState {
Expand Down Expand Up @@ -94,7 +95,7 @@ export class SolutionManagerImpl implements SolutionManager {
private readonly rpcData: SolutionRpcData,
private readonly commandsProvider: CommandsProvider,
private readonly environmentManagerApiProvider: ExtensionApiProvider<Pick<EnvironmentManagerApiV1, 'onDidActivate' | 'getActiveTools'>>,

private readonly environmentManager: EnvironmentManager,
) { }

public async activate(context: vscode.ExtensionContext): Promise<void> {
Expand All @@ -111,6 +112,9 @@ export class SolutionManagerImpl implements SolutionManager {
this.debouncedHandleEnvironmentChange();
}, undefined, context.subscriptions);
}),
this.environmentManager.onDidChangeEnvVars(() => {
Comment thread
edriouk marked this conversation as resolved.
this.debouncedHandleEnvironmentChange();
}, undefined, context.subscriptions),
this.loadStateChangeEmitter,
this.loadBuildFilesEmitter,
this.updatedCompileCommandsEmitter,
Expand Down
Loading