Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Simplify locator
  • Loading branch information
karthiknadig committed Sep 30, 2020
commit 24445acf71ead4d9ad31fa2166576594cd8c6536
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,16 @@

import * as fsapi from 'fs-extra';
import * as path from 'path';
import { Event, EventEmitter } from 'vscode';
import { traceWarning } from '../../../../common/logger';
import { Architecture, getEnvironmentVariable } from '../../../../common/utils/platform';
import {
PythonEnvInfo, PythonEnvKind, PythonReleaseLevel, PythonVersion,
} from '../../../base/info';
import { parseVersion } from '../../../base/info/pythonVersion';
import { ILocator, IPythonEnvsIterator } from '../../../base/locator';
import { PythonEnvsChangedEvent } from '../../../base/watcher';
import { PythonEnvsWatcher } from '../../../base/watcher';
import { getFileInfo } from '../../../common/externalDependencies';
import { isWindowsPythonExe } from '../../../common/windowsUtils';
import { IEnvironmentInfoService } from '../../../info/environmentInfoService';

/**
* Gets path to the Windows Apps directory.
Expand Down Expand Up @@ -116,13 +114,9 @@ export async function getWindowsStorePythonExes(): Promise<string[]> {
.filter(isWindowsPythonExe);
}

export class WindowsStoreLocator implements ILocator {
export class WindowsStoreLocator extends PythonEnvsWatcher implements ILocator {
private readonly kind:PythonEnvKind = PythonEnvKind.WindowsStore;

private readonly eventEmitter = new EventEmitter<PythonEnvsChangedEvent>();

public constructor(private readonly envService:IEnvironmentInfoService) { }

public iterEnvs(): IPythonEnvsIterator {
const buildEnvInfo = (exe:string) => this.buildEnvInfo(exe);
const iterator = async function* () {
Expand All @@ -135,31 +129,11 @@ export class WindowsStoreLocator implements ILocator {
public async resolveEnv(env: string | PythonEnvInfo): Promise<PythonEnvInfo | undefined> {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

We'll be removing this right?
If not, this doesn't seem right. resolveEnv should always add to env. So you might wanna clone and replace on existing fields on passed in environments. Right now I see we're returning empty fields there.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes. when we get the new interface we should be replacing this. The only thing this will set (after new interface) is the distro.

const executablePath = typeof env === 'string' ? env : env.executable.filename;
if (await isWindowsStoreEnvironment(executablePath)) {
const interpreterInfo = await this.envService.getEnvironmentInfo(executablePath);
if (interpreterInfo) {
const data = await getFileInfo(executablePath);
interpreterInfo.executable = {
...interpreterInfo.executable,
...data,
};
return Promise.resolve({
name: '',
location: '',
kind: this.kind,
executable: interpreterInfo.executable,
version: interpreterInfo.version,
arch: interpreterInfo.arch,
distro: { org: 'Microsoft' },
});
}
return this.buildEnvInfo(executablePath);
}
return undefined;
}

public get onChanged(): Event<PythonEnvsChangedEvent> {
return this.eventEmitter.event;
}

private async buildEnvInfo(exe:string): Promise<PythonEnvInfo> {
let version:PythonVersion;
try {
Expand All @@ -169,7 +143,7 @@ export class WindowsStoreLocator implements ILocator {
major: 3,
minor: -1,
micro: -1,
release: { level: PythonReleaseLevel.Unknown, serial: -1 },
release: { level: PythonReleaseLevel.Final, serial: -1 },
sysVersion: undefined,
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import { InterpreterInformation } from '../../../../client/pythonEnvironments/ba
import { parseVersion } from '../../../../client/pythonEnvironments/base/info/pythonVersion';
import * as externalDep from '../../../../client/pythonEnvironments/common/externalDependencies';
import { getWindowsStorePythonExes, WindowsStoreLocator } from '../../../../client/pythonEnvironments/discovery/locators/services/windowsStoreLocator';
import { EnvironmentInfoService } from '../../../../client/pythonEnvironments/info/environmentInfoService';
import { getEnvs } from '../../base/common';
import { TEST_LAYOUT_ROOT } from '../../common/commonTestConstants';

Expand Down Expand Up @@ -95,7 +94,7 @@ suite('Windows Store', () => {
major: 3,
minor: -1,
micro: -1,
release: { level: PythonReleaseLevel.Unknown, serial: -1 },
release: { level: PythonReleaseLevel.Final, serial: -1 },
sysVersion,
};
}
Expand Down Expand Up @@ -167,8 +166,7 @@ suite('Windows Store', () => {
return undefined;
});

const envService = new EnvironmentInfoService();
const locator = new WindowsStoreLocator(envService);
const locator = new WindowsStoreLocator();
const iterator = locator.iterEnvs();
const actualEnvs = (await getEnvs(iterator))
.sort((a, b) => a.executable.filename.localeCompare(b.executable.filename));
Expand All @@ -187,11 +185,10 @@ suite('Windows Store', () => {
location: '',
kind: PythonEnvKind.WindowsStore,
distro: { org: 'Microsoft' },
...createExpectedInterpreterInfo(python38path, python383data.sysVersion, python383data.sysPrefix, '3.8.3'),
...createExpectedInterpreterInfo(python38path),
};

const envService = new EnvironmentInfoService();
const locator = new WindowsStoreLocator(envService);
const locator = new WindowsStoreLocator();
const actual = await locator.resolveEnv(python38path);

assertEnvEqual(actual, expected);
Expand All @@ -205,7 +202,7 @@ suite('Windows Store', () => {
location: '',
kind: PythonEnvKind.WindowsStore,
distro: { org: 'Microsoft' },
...createExpectedInterpreterInfo(python38path, python383data.sysVersion, python383data.sysPrefix, '3.8.3'),
...createExpectedInterpreterInfo(python38path),
};

// Partially filled in env info object
Expand All @@ -225,12 +222,11 @@ suite('Windows Store', () => {
major: 3,
minor: -1,
micro: -1,
release: { level: PythonReleaseLevel.Unknown, serial: -1 },
release: { level: PythonReleaseLevel.Final, serial: -1 },
},
};

const envService = new EnvironmentInfoService();
const locator = new WindowsStoreLocator(envService);
const locator = new WindowsStoreLocator();
const actual = await locator.resolveEnv(input);

assertEnvEqual(actual, expected);
Expand All @@ -239,8 +235,16 @@ suite('Windows Store', () => {
// Use a non store root path
const python38path = path.join(testLocalAppData, 'python3.8.exe');

const envService = new EnvironmentInfoService();
const locator = new WindowsStoreLocator(envService);
const locator = new WindowsStoreLocator();
const actual = await locator.resolveEnv(python38path);

assert.deepStrictEqual(actual, undefined);
});
test('resolveEnv(string): forbidden path', async () => {
// Use a non store root path
const python38path = path.join(testLocalAppData, 'Program Files', 'WindowsApps', 'python3.8.exe');

const locator = new WindowsStoreLocator();
const actual = await locator.resolveEnv(python38path);

assert.deepStrictEqual(actual, undefined);
Expand Down