Skip to content
Open
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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to the "pixi-code" extension will be documented in this file
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.2.1]

- Fix environment discovery failure when project contains unsupported environments
- Support relative paths and `${workspaceFolder}` in `pixi-code.pixiExecutable` setting
- Add error handling to package manager refresh

## [0.2.0]

- Use published @vscode/python-environments API package
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ The extension will automatically discover Pixi environments and register them wi

## Extension Settings

- `pixi-code.pixiExecutable`: Path to the Pixi executable. Leave empty to use auto-discovery (default).
- `pixi-code.pixiExecutable`: Path to the Pixi executable (supports `${workspaceFolder}` and relative paths). Leave empty to use auto-discovery (default).

## Limitations

Expand Down
69 changes: 36 additions & 33 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "Pixi support for the Python Environments extension",
"icon": "assets/icon.png",
"license": "MIT",
"version": "0.2.0",
"version": "0.2.1",
"homepage": "https://github.com/renan-r-santos/pixi-code",
"repository": {
"type": "git",
Expand Down
17 changes: 10 additions & 7 deletions src/pixi/projectManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,16 @@ export class PixiPackageManager implements PackageManager, Disposable {
}

const projectPath = path.dirname(environment.pixiInfo.project_info.manifest_path);
const pixiPackages = await listPixiPackages(environment.name, projectPath);

const before = environment.packages;
const after = pixiPkgsToPackages(pixiPackages, environment.envId.id);

environment.packages = after;
this.triggerOnDidChangePackages(environment, before, after);
try {
const pixiPackages = await listPixiPackages(environment.name, projectPath);
const before = environment.packages;
const after = pixiPkgsToPackages(pixiPackages, environment.envId.id);

environment.packages = after;
this.triggerOnDidChangePackages(environment, before, after);
} catch (error) {
traceVerbose(`Failed to refresh packages for environment '${environment.name}': ${error}`);
}
},
);
}
Expand Down
34 changes: 31 additions & 3 deletions src/pixi/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Package } from '@vscode/python-environments';
import * as ch from 'child_process';
import * as fs from 'fs';
import * as path from 'path';
import { CancellationError, CancellationToken, ThemeIcon, Uri, window, workspace } from 'vscode';
import which from 'which';

Expand Down Expand Up @@ -27,7 +29,21 @@ export async function getPixi(): Promise<string> {
const value = config.get<string>('pixiExecutable');

if (value) {
return untildify(value);
let resolved = untildify(value);
if (workspace.workspaceFolders && workspace.workspaceFolders.length > 0) {
const firstFolder = workspace.workspaceFolders[0].uri.fsPath;
resolved = resolved.replace(/\$\{workspaceFolder\}/g, firstFolder);
if (!path.isAbsolute(resolved)) {
for (const folder of workspace.workspaceFolders) {
const candidate = path.resolve(folder.uri.fsPath, resolved);
if (fs.existsSync(candidate)) {
resolved = candidate;
break;
}
}
}
}
return resolved;
}

const pixiPath = await findPixi();
Expand Down Expand Up @@ -87,7 +103,12 @@ async function _runPixi(

export async function runPixi(args: string[], options?: ch.SpawnOptions, token?: CancellationToken): Promise<string> {
const pixi = await getPixi();
return _runPixi(pixi, args, options, token);
const defaultCwd = workspace.workspaceFolders?.[0]?.uri.fsPath;
const spawnOptions: ch.SpawnOptions = {
...(defaultCwd ? { cwd: defaultCwd } : {}),
...options,
};
return _runPixi(pixi, args, spawnOptions, token);
}

export async function listPixiPackages(envName: string, projectPath: string): Promise<PixiPackage[]> {
Expand All @@ -113,7 +134,14 @@ export async function refreshPixi(projectPath: string): Promise<PixiEnvironment[

const results = await Promise.all(
pixiInfo.environments_info.map(async (pixiEnv) => {
const pixiPackages = await listPixiPackages(pixiEnv.name, projectPath);
let pixiPackages: PixiPackage[];
try {
pixiPackages = await listPixiPackages(pixiEnv.name, projectPath);
} catch (error) {
traceInfo(`Skipping Pixi environment '${pixiEnv.name}': ${error}`);
return null;
}

const pythonPackage = pixiPackages.find((pkg) => pkg.name === 'python');

if (!pythonPackage) {
Expand Down