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
15 changes: 15 additions & 0 deletions qt-python/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,21 @@
"title": "Qt Python Configuration",
"properties": {}
},
"commands": [
{
"command": "qt-python.installPySide6",
"title": "%qt-python.command.installPySide6.title%",
"category": "Qt-Python"
}
],
"menus": {
"commandPalette": [
{
"command": "qt-python.installPySide6",
"when": "workspaceFolderCount > 0"
}
]
},
"taskDefinitions": [
{
"type": "pyside",
Expand Down
4 changes: 3 additions & 1 deletion qt-python/package.nls.json
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
{}
{
"qt-python.command.installPySide6.title": "Install PySide6"
}
82 changes: 82 additions & 0 deletions qt-python/src/builder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only

import * as path from 'path';
import * as childProcess from 'child_process';

import { IsWindows } from 'qt-lib';
import { PySideEnv } from './env';

export interface PySideCommandBuildOptions {
useVenv?: boolean;
cwd?: string;
}

export class PySideCommandBuilder {
private readonly _shellPath: string;
private readonly _shellArgs: string[];
private readonly _venvActivationCommand: string;

constructor(
private readonly _env: PySideEnv,
private readonly _options?: PySideCommandBuildOptions
) {
this._shellPath = resolveShellPath();
this._shellArgs = [IsWindows ? '/c' : '-c'];
this._venvActivationCommand = resolveVenvActivationCommand(this._env);
}

get shellPath(): string {
return this._shellPath;
}

get shellArgs(): string[] {
return this._shellArgs;
}

get venvActivationCommand(): string {
return this._venvActivationCommand;
}

public build(command: string) {
const all: string[] = [command];

if (this._options?.cwd) {
all.unshift(`cd ${enclosePath(this._options.cwd)}`);
}

if (this._options?.useVenv && this._venvActivationCommand) {
all.unshift(this._venvActivationCommand);
}

return all.join(' && ');
}
}

// helpers
function resolveShellPath(): string {
if (IsWindows) {
return process.env.ComSpec ?? 'C:\\Windows\\System32\\cmd.exe';
}

const result = childProcess.spawnSync('command -v bash', { shell: true });
const found = result.stdout.toString().trim();
return result.status === 0 && found ? found : '/bin/bash';
}

function resolveVenvActivationCommand(env: PySideEnv): string {
const bin = env.venvBinPath;
if (!bin) {
return '';
}

const script = enclosePath(
path.join(bin, IsWindows ? 'activate.bat' : 'activate')
);

return IsWindows ? script : `source ${script}`;
}

function enclosePath(s: string) {
return IsWindows ? `"${s}"` : `'${s}'`;
}
6 changes: 6 additions & 0 deletions qt-python/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ export const EXTENSION_ID = 'qt-python';
export const MS_PYTHON_ID = 'ms-python.python';
export const LOG_NAME = 'qt-python';

export const COMMAND_PREFIX = 'qt-python';
export const COMMAND_INSTALL_PYSIDE = 'installPySide6'; // contributes > commands
export const COMMAND_PYTHON_CREATE_ENV = 'python.createEnvironment';
export const COMMAND_PYTHON_SELECT_PYTHON = 'python.setInterpreter';

export const TASK_TYPE = 'pyside'; // contributes > taskDefinitions
export const TASK_SOURCE = 'PySide';

Expand All @@ -21,3 +26,4 @@ export const TOML_KEY_PROJECT_NAME = 'project.name';
export const TOML_KEY_PROJECT_FILES = 'tool.pyside6-project.files';

export const PYSIDE_PROJECT_TOOL = 'pyside6-project';
export const MAINT_WHEEL_DIR_NAME = 'QtForPython';
12 changes: 12 additions & 0 deletions qt-python/src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,22 @@ export class PySideEnv {
this._pyEnv = pyenv;
}

public isVenv(): boolean {
return this._pyEnv?.environment?.type === 'VirtualEnvironment';
}

get venvName(): string | undefined {
return this._pyEnv?.environment?.name;
}

get venvBinPath(): string {
const root = this._pyEnv?.executable.sysPrefix ?? '';
return root
? utils.toForwardSlash(path.join(root, consts.VENV_BIN_DIR))
: '';
}

get interpreterPath(): string | undefined {
return this._pyEnv?.executable.uri?.fsPath;
}
}
19 changes: 19 additions & 0 deletions qt-python/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { PySideTaskProvider } from './task';
import { PySideDebugConfigProvider } from './debug';
import { PySideProjectManager } from './project-manager';
import * as consts from '@/constants';
import { onInstallPySide6Command } from './installer';

const logger = createLogger('extension');

Expand All @@ -34,6 +35,8 @@ export async function activate(context: vscode.ExtensionContext) {
await initDependency();
await initCoreApi();
await initPythonSupport(context);
initCommands(context);

logger.info(`Activated: ${consts.EXTENSION_ID}`);
telemetry.sendEvent('activated');
} catch (e) {
Expand Down Expand Up @@ -74,6 +77,22 @@ async function initPythonSupport(context: vscode.ExtensionContext) {
);
}

function initCommands(context: vscode.ExtensionContext) {
function register(c: string, callback: (...args: unknown[]) => unknown) {
return vscode.commands.registerCommand(
`${consts.COMMAND_PREFIX}.${c}`,
async () => {
telemetry.sendAction(c);
await callback();
}
);
}

context.subscriptions.push(
register(consts.COMMAND_INSTALL_PYSIDE, onInstallPySide6Command)
);
}

const onPyApiEnvChanged = async (e: PyApiEnvChanged) => {
const folder = e.resource;
if (folder) {
Expand Down
Loading
Loading