From 3a1864df59f0b4850789a80ac538698dd18a8d0a Mon Sep 17 00:00:00 2001
From: Virgil <28490646+sisoe24@users.noreply.github.com>
Date: Thu, 10 Oct 2024 11:41:26 -0400
Subject: [PATCH] sisoe24/0.16.0 (#23)
* Refactor placeholder replacements in launch_executable.ts
* Remove duplicate import
* Improve environment variables options #22
* Refactor resolveEnvVariables function and optimize environment variable replacement
* Remove commented lines
* Update readme
* Update changelog
* Rename file
* Update readme
* Update notification message for breaking changes in settings
* Use property shorthand
* Fix commands camelCaseName #21
* Update run_code.svg icon
* Update changelog
---
CHANGELOG.md | 13 ++
README.md | 39 ++++--
package.json | 14 ++-
resources/icons/light/run_code.svg | 7 +-
src/config.ts | 2 +-
src/extension.ts | 119 +++++++++++--------
src/launch_executable.ts | 83 ++++++-------
src/notification.ts | 4 +-
src/{fetch_packages.ts => packages_fetch.ts} | 0
9 files changed, 167 insertions(+), 114 deletions(-)
rename src/{fetch_packages.ts => packages_fetch.ts} (100%)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9718706..4bf8e2e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,18 @@
# Change Log
+## [0.16.0] - 07/07/2024
+
+### Changed
+
+- Changed the `nuketools.environmentVariables` keys to use an array of strings rather than a single string (`{"VAR_NAME": ["value1", "value2", ...]}`)
+- Added new placeholders for the `nuketools.environmentVariables` setting: `${workspaceFolderBasename}` and `${userHome}`.
+- Added the ability to use any system environment variable in the `nuketools.environmentVariables` setting.
+
+### Fixed
+
+- Fixed light theme icon
+- Extensions commands for extra and packages now properly show a label rather than a variable name.
+
## [0.15.1] - 07/07/2024
### Fixed
diff --git a/README.md b/README.md
index 8a4414c..1dde9ee 100644
--- a/README.md
+++ b/README.md
@@ -39,6 +39,7 @@ Seamlessly integrate Nuke into your Visual Studio Code workflow, enabling you to
- [1.7. BlinkScript](#17-blinkscript)
- [1.8. Available Commands](#18-available-commands)
- [1.9. Environment Variables](#19-environment-variables)
+ - [Placeholders and Variables](#placeholders-and-variables)
- [1.9.1. Additional Settings](#191-additional-settings)
- [1.9.2. Network Settings](#192-network-settings)
- [1.10. Windows Users](#110-windows-users)
@@ -163,19 +164,43 @@ NOTES:
## 1.9. Environment Variables
-Add environment variables to the terminal instance with `$VAR_NAME` for system variables or `${workspaceFolder}` for the workspace folder.
+Add environment variables to the terminal instance using the `nukeTools.environmentVariables` setting.
```json
{
- "nukeTools.environmentVariables": {
- "NUKE_PATH": "${workspaceFolder}/gizmo:$NUKE_PATH",
- "PYTHONPATH": "$PYTHONPATH:/path/to/python/lib",
- "API_KEY": "0a9f0381-aebb-4e40-a77a-2c381b08e0ea"
- }
+ "nukeTools.environmentVariables": {
+ "VAR_NAME": ["value1", "value2", ...]
+ }
+}
+```
+
+### Placeholders and Variables
+
+- `${workspaceFolder}`: Current workspace folder
+- `${workspaceFolderBasename}`: Name of the workspace folder
+- `${userHome}`: User's home directory
+- `$VAR_NAME`: System environment variables
+
+Example
+
+```json
+{
+ "nukeTools.environmentVariables": {
+ "NUKE_PATH": [
+ "${workspaceFolder}/gizmo",
+ "$NUKE_PATH"
+ ],
+ "PYTHONPATH": [
+ "$MYLIB/path/to/python/lib"
+ ],
+ "API_KEY": [
+ "0a9f0381-aebb-4e40-a77a-2c381b08e0ea"
+ ]
+ }
}
```
-> Note: From my testing it seems that you can use the ':' separator for multiple paths even on Windows.
+The extension combines arrays of strings using the appropriate separator for the detected shell and operating system.
## 1.9.1. Additional Settings
diff --git a/package.json b/package.json
index 205a8fb..0a46b22 100644
--- a/package.json
+++ b/package.json
@@ -143,11 +143,21 @@
"type": "boolean"
},
"nukeTools.environmentVariables": {
- "description": "Environment variables that will be added when running an executable.",
+ "description": "An object with environment variables that will be added when running an executable.",
"type": "object",
+ "additionalProperties": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
"examples": [
{
- "NUKE_PATH": "${workspaceFolder}/gizmos:$NUKE_PATH"
+ "NUKE_PATH": [
+ "${workspaceFolder}/${workspaceFolderBasename}/bin",
+ "${userHome}/.nuke",
+ "$NUKE_PATH"
+ ]
}
]
},
diff --git a/resources/icons/light/run_code.svg b/resources/icons/light/run_code.svg
index 7bd76ec..ba7ebb9 100644
--- a/resources/icons/light/run_code.svg
+++ b/resources/icons/light/run_code.svg
@@ -2,10 +2,9 @@
diff --git a/src/config.ts b/src/config.ts
index 1ba2fe4..40f89f7 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -9,7 +9,7 @@ type ExecutableMap = {
[key: string]: ExecutableConfig;
};
-export type EnvVars = { [key: string]: string };
+export type EnvVars = { [key: string]: Array };
type CommandMappings = "executablesMap";
diff --git a/src/extension.ts b/src/extension.ts
index cda24f6..ab29cc1 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -10,8 +10,6 @@ import { Version } from "./version";
import * as executables from "./launch_executable";
import * as nukeTemplate from "./create_project";
-import { Version } from "./version";
-
import { BlinkSnippets } from "./blinkscript/blink_snippet";
import { BlinkScriptFormat } from "./blinkscript/blink_format";
import { BlinkScriptCompletionProvider } from "./blinkscript/blink_completion";
@@ -20,7 +18,7 @@ import { NukeCompletionProvider } from "./nuke/completitions";
import { NukeNodesInspectorProvider } from "./nuke/nodes_tree";
import { showNotification } from "./notification";
-import { fetchPackagesLatestVersion } from "./fetch_packages";
+import { fetchPackagesLatestVersion } from "./packages_fetch";
import { initializePackageLog } from "./packages";
import { getConfig } from "./config";
@@ -74,69 +72,88 @@ function registerBlinkScriptCommands(context: vscode.ExtensionContext): void {
);
}
+type Action = {
+ label: string;
+ execute: () => void;
+};
+
+interface ActionItem extends vscode.QuickPickItem {
+ execute: () => void;
+}
+
+function showActionPicker(items: Array) {
+ const picker = vscode.window.createQuickPick();
+ picker.items = items.map((item) => {
+ return {
+ label: item.label,
+ execute: item.execute,
+ };
+ });
+
+ picker.onDidChangeSelection((selection) => {
+ const selected = selection[0] as ActionItem;
+ if (selected) {
+ selected.execute();
+ picker.hide();
+ }
+ });
+
+ picker.onDidHide(() => picker.dispose());
+ picker.show();
+}
+
function registerPackagesCommands(context: vscode.ExtensionContext): void {
- const addExtras: Record void> = {
- pysideTemplate: nukeTemplate.createTemplate,
- pythonStubs: stubs.addStubs,
- nukeServerSocket: nuke.addNukeServerSocket,
- vimDcc: nuke.addVimDcc,
- };
+ const actions: Array = [
+ {
+ label: "Pyside Template",
+ execute: nukeTemplate.createTemplate,
+ },
+ {
+ label: "Python Stubs",
+ execute: stubs.addStubs,
+ },
+ {
+ label: "Nuke Server Socket",
+ execute: nuke.addNukeServerSocket,
+ },
+ {
+ label: "Vim DCC",
+ execute: nuke.addVimDcc,
+ },
+ ];
context.subscriptions.push(
vscode.commands.registerCommand("nuke-tools.addPackages", () => {
- const picker = vscode.window.createQuickPick();
- picker.items = Object.keys(addExtras).map((key) => {
- return {
- label: key,
- };
- });
-
- picker.onDidChangeSelection((selection) => {
- if (selection[0]) {
- addExtras[selection[0].label]();
- picker.hide();
- }
- });
-
- picker.onDidHide(() => picker.dispose());
- picker.show();
+ showActionPicker(actions);
})
);
}
function registerExtraCommands(context: vscode.ExtensionContext): void {
- const extras: Record void> = {
- clearPackagesCache: () => {
- initializePackageLog();
- fetchPackagesLatestVersion();
- vscode.window.showInformationMessage("Packages cached cleared.");
+ const actions: Array = [
+ {
+ label: "Clear Package Cache",
+ execute: () => {
+ initializePackageLog();
+ fetchPackagesLatestVersion();
+ vscode.window.showInformationMessage("Packages cached cleared.");
+ },
},
- testRunInsideNuke: () => {
- void socket.sendDebugMessage();
+ {
+ label: "Send Debug Message",
+ execute: socket.sendDebugMessage,
},
- showNetworkAddresses: () => {
- vscode.window.showInformationMessage(socket.getAddresses());
+ {
+ label: "Show Network Addresses",
+ execute: () => {
+ vscode.window.showInformationMessage(socket.getAddresses());
+ },
},
- };
+ ];
context.subscriptions.push(
vscode.commands.registerCommand("nuke-tools.extras", () => {
- const picker = vscode.window.createQuickPick();
- picker.items = Object.keys(extras).map((key) => {
- return {
- label: key,
- };
- });
-
- picker.onDidChangeSelection((selection) => {
- if (selection[0]) {
- extras[selection[0].label]();
- picker.hide();
- }
- });
-
- picker.onDidHide(() => picker.dispose());
- picker.show();
+ showActionPicker(actions);
})
);
}
diff --git a/src/launch_executable.ts b/src/launch_executable.ts
index c8f8b04..4a8b033 100644
--- a/src/launch_executable.ts
+++ b/src/launch_executable.ts
@@ -70,23 +70,42 @@ export class ExecutablePath {
}
/**
- * Concatenate the user's environment variables with the system's environment variables.
+ * Replace placeholders in a string with their corresponding values.
+ *
+ * @example
+ * resolveEnvVariables("foo ${workspaceFolder} $SHELL bar");
+ * // => "foo /home/user /bin/bash bar"
*
- * @param userEnvironmentVars EnvVars object containing the user's environment variables
- * return an EnvVars object containing the concatenated environment variables
+ * @param text - The text to resolve the placeholders in.
+ * @return - The text with the placeholders resolved.
*/
-function concatEnv(userEnvironmentVars: EnvVars): EnvVars {
- const env: EnvVars = {};
+function resolveEnvVariables(text: string):string {
+ let workspaceFolder = vscode.workspace.workspaceFolders?.[0].uri.fsPath || "";
+
+ // on windows we need to convert the path to a unix-like path
+ if (IS_WINDOWS && isUnixShell()) {
+ workspaceFolder = workspaceFolder.replace(/\\/g, "/");
+ // Convert the drive letter to lowercase and add a leading slash (e.g. C: -> /c)
+ workspaceFolder = workspaceFolder.replace(/^([a-zA-Z]):/, (_, driveLetter) => {
+ return `/${driveLetter.toLowerCase()}`;
+ });
+ }
- for (const [k, v] of Object.entries(userEnvironmentVars)) {
- // Replace all instances of $envVar with the system environment variable
- env[k] = v.replace(new RegExp(`\\$${k}`, "g"), process.env[k] || "");
+ const placeholders: { [key: string]: string } = {
+ workspaceFolder,
+ workspaceFolderBasename: path.basename(workspaceFolder),
+ userHome: os.homedir(),
+ };
- // Clean up the path separator in the beginning and end of the string
- env[k] = env[k].replace(/^[\s:;]+|[\s:;]+$/g, "");
+ for (const [placeholder, replacement] of Object.entries(placeholders)) {
+ text = text.replace(new RegExp(`\\$\\{${placeholder}\\}`, "g"), replacement);
}
- return env;
+ for (const match of text.match(/\$\w+/g) || []) {
+ text = text.replace(match, process.env[match.replace("$", "")] || match);
+ }
+
+ return text;
}
/**
@@ -99,14 +118,15 @@ function stringifyEnv(env: EnvVars): string {
let envString = "";
for (const [k, v] of Object.entries(env)) {
+ const envPath = v.join(path.delimiter);
if (isPowerShell()) {
- envString += `$env:${k}="${v}"; `;
+ envString += `$env:${k}="${envPath}"; `;
} else if (isUnixShell()) {
- envString += `${k}=${v} `;
+ envString += `${k}=${envPath} `;
} else if (isCmdShell()) {
- envString += `set ${k}=${v}&&`;
+ envString += `set ${k}=${envPath}&&`;
} else {
- envString += `${k}=${v} `;
+ envString += `${k}=${envPath} `;
vscode.window.showWarningMessage(
`Unknown shell detected ${vscode.env.shell}. Environment variables may not be set correctly.`
);
@@ -116,35 +136,6 @@ function stringifyEnv(env: EnvVars): string {
return envString;
}
-/**
- * Replace placeholders in a string with their corresponding values.
- *
- * @param value The string to replace placeholders in
- * @returns The string with placeholders replaced
- */
-function replacePlaceholders(value: string): string {
- let workspaceFolder = vscode.workspace.workspaceFolders?.[0].uri.fsPath || "";
-
- // on windows we need to convert the path to a unix-like path
- if (IS_WINDOWS && isUnixShell()) {
- workspaceFolder = workspaceFolder.replace(/\\/g, "/");
- // Convert the drive letter to lowercase and add a leading slash (e.g. C: -> /c)
- workspaceFolder = workspaceFolder.replace(/^([a-zA-Z]):/, (_, driveLetter) => {
- return `/${driveLetter.toLowerCase()}`;
- });
- }
-
- // always escape the backslashes in the placeholder
- const placeholders = {
- "\\$\\{workspaceFolder\\}": workspaceFolder,
- };
-
- for (const [placeholder, replacement] of Object.entries(placeholders)) {
- value = value.replace(new RegExp(placeholder, "g"), replacement);
- }
-
- return value;
-}
/**
* Execute the command in the terminal. Before executing the command, if restartInstance
@@ -163,8 +154,8 @@ function execCommand(execPath: ExecutablePath): void {
});
}
- const env = stringifyEnv(concatEnv(getConfig("environmentVariables")));
- const command = replacePlaceholders(`${env} ${execPath.buildExecutableCommand()}`.trim());
+ const env = stringifyEnv(getConfig("environmentVariables"));
+ const command = resolveEnvVariables(`${env} ${execPath.buildExecutableCommand()}`.trim());
const terminal = vscode.window.createTerminal(terminalName);
terminal.sendText(command);
diff --git a/src/notification.ts b/src/notification.ts
index c0e46e8..7a71984 100644
--- a/src/notification.ts
+++ b/src/notification.ts
@@ -1,9 +1,7 @@
import * as vscode from "vscode";
const _msg = `
-0.15.0 Introduces some breaking changes in the settings.
-Please review the settings and update them accordingly.
-See the changelog for more information.
+0.16.0. Breaking Changes: 'nuketools.environmentVariables' keys now uses an array of strings rather than a single string
`;
diff --git a/src/fetch_packages.ts b/src/packages_fetch.ts
similarity index 100%
rename from src/fetch_packages.ts
rename to src/packages_fetch.ts