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
1 change: 1 addition & 0 deletions src/common/pickers/managers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ export async function pickCreator(creators: PythonProjectCreator[]): Promise<Pyt
const selected = await showQuickPickWithButtons(items, {
placeHolder: Pickers.Managers.selectProjectCreator,
ignoreFocusOut: true,
showBackButton: true,
});

if (!selected) {
Expand Down
69 changes: 4 additions & 65 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@ import { EventNames } from './common/telemetry/constants';
import { sendManagerSelectionTelemetry } from './common/telemetry/helpers';
import { sendTelemetryEvent } from './common/telemetry/sender';
import { createDeferred } from './common/utils/deferred';
import { isWindows } from './common/utils/platformUtils';

import {
activeTerminal,
createLogOutputChannel,
createTerminal,
onDidChangeActiveTerminal,
onDidChangeTerminalShellIntegration,
} from './common/window.apis';
Expand Down Expand Up @@ -71,15 +70,12 @@ import {
collectEnvironmentInfo,
getEnvManagerAndPackageManagerConfigLevels,
resolveDefaultInterpreter,
runPetInTerminalImpl,
} from './helpers';
import { EnvironmentManagers, ProjectCreators, PythonProjectManager } from './internal.api';
import { registerSystemPythonFeatures } from './managers/builtin/main';
import { SysPythonManager } from './managers/builtin/sysPythonManager';
import {
createNativePythonFinder,
getNativePythonToolsPath,
NativePythonFinder,
} from './managers/common/nativePythonFinder';
import { createNativePythonFinder, NativePythonFinder } from './managers/common/nativePythonFinder';
import { IDisposable } from './managers/common/types';
import { registerCondaFeatures } from './managers/conda/main';
import { registerPipenvFeatures } from './managers/pipenv/main';
Expand Down Expand Up @@ -365,64 +361,7 @@ export async function activate(context: ExtensionContext): Promise<PythonEnviron
}),
commands.registerCommand('python-envs.runPetInTerminal', async () => {
try {
const petPath = await getNativePythonToolsPath();

// Show quick pick menu for PET operation selection
const selectedOption = await window.showQuickPick(
[
{
label: 'Find All Environments',
description: 'Finds all environments and reports them to the standard output',
detail: 'Runs: pet find --verbose',
},
{
label: 'Resolve Environment...',
description: 'Resolves & reports the details of the environment to the standard output',
detail: 'Runs: pet resolve <path>',
},
],
{
placeHolder: 'Select a Python Environment Tool (PET) operation',
ignoreFocusOut: true,
},
);

if (!selectedOption) {
return; // User cancelled
}

const terminal = createTerminal({
name: 'Python Environment Tool (PET)',
});
terminal.show();

if (selectedOption.label === 'Find All Environments') {
// Run pet find --verbose
terminal.sendText(`"${petPath}" find --verbose`, true);
traceInfo(`Running PET find command: ${petPath} find --verbose`);
} else if (selectedOption.label === 'Resolve Environment...') {
// Show input box for path
const placeholder = isWindows() ? 'C:\\path\\to\\python\\executable' : '/path/to/python/executable';
const inputPath = await window.showInputBox({
prompt: 'Enter the path to the Python executable to resolve',
placeHolder: placeholder,
ignoreFocusOut: true,
validateInput: (value) => {
if (!value || value.trim().length === 0) {
return 'Please enter a valid path';
}
return null;
},
});

if (!inputPath) {
return; // User cancelled
}

// Run pet resolve with the provided path
terminal.sendText(`"${petPath}" resolve "${inputPath.trim()}"`, true);
traceInfo(`Running PET resolve command: ${petPath} resolve "${inputPath.trim()}"`);
}
await runPetInTerminalImpl();
} catch (error) {
traceError('Error running PET in terminal', error);
window.showErrorMessage(`Failed to run Python Environment Tool: ${error}`);
Expand Down
90 changes: 88 additions & 2 deletions src/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { ExtensionContext, extensions, Uri, workspace } from 'vscode';
import { ExtensionContext, extensions, QuickInputButtons, Uri, window, workspace } from 'vscode';
import { PythonEnvironment, PythonEnvironmentApi } from './api';
import { traceError, traceInfo, traceWarn } from './common/logging';
import { normalizePath } from './common/utils/pathUtils';
import { isWindows } from './common/utils/platformUtils';
import { createTerminal, showInputBoxWithButtons } from './common/window.apis';
import { getConfiguration } from './common/workspace.apis';
import { getAutoActivationType } from './features/terminal/utils';
import { EnvironmentManagers, PythonProjectManager } from './internal.api';
import { NativeEnvInfo, NativePythonFinder } from './managers/common/nativePythonFinder';
import { getNativePythonToolsPath, NativeEnvInfo, NativePythonFinder } from './managers/common/nativePythonFinder';

/**
* Collects relevant Python environment information for issue reporting
Expand Down Expand Up @@ -137,6 +139,90 @@ export function getUserConfiguredSetting<T>(section: string, key: string): T | u
return undefined;
}

/**
* Runs the Python Environment Tool (PET) in a terminal window, allowing users to
* execute various PET commands like finding all Python environments or resolving
* the details of a specific environment.
*
*
* @returns A Promise that resolves when the PET command has been executed or cancelled
*/
export async function runPetInTerminalImpl(): Promise<void> {
const petPath = await getNativePythonToolsPath();

// Show quick pick menu for PET operation selection
const selectedOption = await window.showQuickPick(
[
{
label: 'Find All Environments',
description: 'Finds all environments and reports them to the standard output',
detail: 'Runs: pet find --verbose',
},
{
label: 'Resolve Environment...',
description: 'Resolves & reports the details of the environment to the standard output',
detail: 'Runs: pet resolve <path>',
},
],
{
placeHolder: 'Select a Python Environment Tool (PET) operation',
ignoreFocusOut: true,
},
);

if (!selectedOption) {
return; // User cancelled
}

if (selectedOption.label === 'Find All Environments') {
// Create and show terminal immediately for 'Find All Environments' option
const terminal = createTerminal({
name: 'Python Environment Tool (PET)',
});
terminal.show();

// Run pet find --verbose
terminal.sendText(`"${petPath}" find --verbose`, true);
traceInfo(`Running PET find command: ${petPath} find --verbose`);
} else if (selectedOption.label === 'Resolve Environment...') {
try {
// Show input box for path with back button
const placeholder = isWindows() ? 'C:\\path\\to\\python\\executable' : '/path/to/python/executable';
const inputPath = await showInputBoxWithButtons({
prompt: 'Enter the path to the Python executable to resolve',
placeHolder: placeholder,
ignoreFocusOut: true,
showBackButton: true,
validateInput: (value) => {
if (!value || value.trim().length === 0) {
return 'Please enter a valid path';
}
return null;
},
});

if (inputPath) {
// Only create and show terminal after path has been entered
const terminal = createTerminal({
name: 'Python Environment Tool (PET)',
});
terminal.show();

// Run pet resolve with the provided path
terminal.sendText(`"${petPath}" resolve "${inputPath.trim()}"`, true);
traceInfo(`Running PET resolve command: ${petPath} resolve "${inputPath.trim()}"`);
}
} catch (ex) {
if (ex === QuickInputButtons.Back) {
// If back button was clicked, restart the flow
await runPetInTerminalImpl();
return;
}
throw ex; // Re-throw other errors
}
}
}

/**
* Sets the default Python interpreter for the workspace if the user has not explicitly set 'defaultEnvManager'.
* @param nativeFinder - used to resolve interpreter paths.
Expand Down
Loading
Loading