Skip to content
This repository has been archived by the owner on Jul 12, 2023. It is now read-only.

Use $VIRTUAL_ENV when set #37

Merged
merged 1 commit into from
Jun 24, 2022
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
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ This extension is meant act as a playground for the [Python extension](https://m

## Features

### Automatic detection of activated virtual environments

If the `VIRTUAL_ENV` environment variable is set, WWBD will use that to set the selected Python environment.

### `Create Environment` command

1. Use an appropriate interpreter (the selected interpreter, ask the user to use the newest version of Python installed, or ask the user to pick an interpreter).
Expand Down
8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,13 @@
"Other"
],
"activationEvents": [
"onCommand:wwbd.createEnvironment"
"onCommand:wwbd.createEnvironment",
"onLanguage:python",
"workspaceContains:*.py",
"workspaceContains:mspythonconfig.json",
"workspaceContains:pyproject.toml",
"workspaceContains:Pipfile",
"workspaceContains:requirements.txt"
],
"main": "./out/extension.js",
"contributes": {
Expand Down
56 changes: 38 additions & 18 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as child_process from "node:child_process";
import * as fs from "node:fs";
import * as os from "node:os";
import * as path from "node:path";
import * as process from "node:process";
import * as vscode from "vscode";
import * as pvsc from "./pvsc";

Expand All @@ -15,7 +16,21 @@ export interface PythonPayload {
requirementsFile: string | null;
}

export function activate(context: vscode.ExtensionContext): void {
export function venvExecutable(dir: undefined): undefined;
export function venvExecutable(dir: string): string;
export function venvExecutable(dir: string | undefined): string | undefined;
export function venvExecutable(dir: string | undefined): string | undefined {
if (dir === undefined) {
return undefined;
}
return os.platform() === "win32"
? path.join(dir, "Scripts", "python.exe")
: path.join(dir, "bin", "python");
}

export async function activate(
context: vscode.ExtensionContext
): Promise<void> {
let disposable = vscode.commands.registerCommand(
"wwbd.createEnvironment",
() =>
Expand All @@ -32,6 +47,19 @@ export function activate(context: vscode.ExtensionContext): void {
);

context.subscriptions.push(disposable);

const activatedVirtualEnv = venvExecutable(process.env.VIRTUAL_ENV);
if (activatedVirtualEnv !== undefined) {
outputChannel.appendLine(
`$VIRTUAL_ENV is set to ${process.env.VIRTUAL_ENV}`
);
const pythonExtension = await pvscApi();
await pythonExtension?.environment.setActiveEnvironment(
activatedVirtualEnv
);
} else {
outputChannel.appendLine("$VIRTUAL_ENV is not set");
}
}

export function deactivate(): void {}
Expand Down Expand Up @@ -197,12 +225,6 @@ function noInterpreterSelected(): void {
vscode.window.showErrorMessage("No interpreter selected.");
}

export function venvExecutable(dir: string): string {
return os.platform() === "win32"
? path.join(dir, "Scripts", "python.exe")
: path.join(dir, "bin", "python");
}

export function parseOutput(output: string): PythonPayload | undefined {
const jsonMatch = jsonTagRegex.exec(output);

Expand Down Expand Up @@ -279,17 +301,15 @@ async function createEnvironment(
if (fs.existsSync(venvInterpreter)) {
const selectEnvironmentButton = "Select Environment";

vscode.window
.showWarningMessage(
"A virtual environment already exists at `.venv`. Would you like to select it and halt environment creation?",
selectEnvironmentButton,
"Cancel"
)
.then((selected) => {
if (selected === selectEnvironmentButton) {
pythonExtension.environment.setActiveEnvironment(venvInterpreter);
}
});
const selected = await vscode.window.showWarningMessage(
"A virtual environment already exists at `.venv`. Would you like to select it and halt environment creation?",
selectEnvironmentButton,
"Cancel"
);

if (selected === selectEnvironmentButton) {
await pythonExtension.environment.setActiveEnvironment(venvInterpreter);
}

return;
} else {
Expand Down
29 changes: 18 additions & 11 deletions src/test/suite/extension.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as assert from "node:assert";
import * as os from "node:os";
import * as path from "node:path";
import * as process from "node:process";
import * as vscode from "vscode";
import * as wwbd from "../../extension";
import * as pvsc from "../../pvsc";
Expand All @@ -14,6 +15,23 @@ function arrayEquals<T>(a: T[], b: T[]): void {
suite("Unit Tests", function () {
vscode.window.showInformationMessage("Start all tests.");

suite("venvExecutable()", function () {
test("string", function () {
const dir = ".venv";

const expect =
os.platform() === "win32"
? path.join(dir, "Scripts", "python.exe")
: path.join(dir, "bin", "python");

assert.strictEqual(wwbd.venvExecutable(dir), expect);
});

test("undefined", function () {
assert.strictEqual(wwbd.venvExecutable(undefined), undefined);
});
});

suite("isGlobal()", function () {
const knownKinds = [
pvsc.PythonEnvKind.Unknown,
Expand Down Expand Up @@ -129,17 +147,6 @@ suite("Unit Tests", function () {
arrayEquals(wwbd.filterByPathType(given), expected);
});

test("venvExecutable()", function () {
const dir = ".venv";

const expect =
os.platform() === "win32"
? path.join(dir, "Scripts", "python.exe")
: path.join(dir, "bin", "python");

assert.strictEqual(wwbd.venvExecutable(dir), expect);
});

suite("parseOutput()", function () {
const badOutput =
"People put the strangest stuff in their `sitecustomize.py` ...";
Expand Down