Skip to content

Commit

Permalink
Enhancement: dynamic evaluation of commands #882
Browse files Browse the repository at this point in the history
  • Loading branch information
estruyf committed Oct 28, 2024
1 parent 6f288ff commit c84af84
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 32 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### 🎨 Enhancements

- [#878](https://github.com/estruyf/vscode-front-matter/issues/878): Allow the `select all` button to work on other pages when there is a selection present
- [#882](https://github.com/estruyf/vscode-front-matter/issues/882): Dynamic evaluation of the `node` executable path

### 🐞 Fixes

Expand Down
91 changes: 76 additions & 15 deletions src/helpers/CustomScript.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Settings } from './SettingsHelper';
import { CommandType, EnvironmentType } from './../models/PanelSettings';
import { CommandType } from './../models/PanelSettings';
import { CustomScript as ICustomScript, ScriptType } from '../models/PanelSettings';
import { window, env as vscodeEnv, ProgressLocation, Uri, commands } from 'vscode';
import { window, env as vscodeEnv, ProgressLocation, Uri, commands, workspace } from 'vscode';
import { ArticleHelper, Logger, MediaHelpers } from '.';
import { Folders, WORKSPACE_PLACEHOLDER } from '../commands/Folders';
import { exec, execSync } from 'child_process';
Expand All @@ -13,9 +13,10 @@ import { Dashboard } from '../commands/Dashboard';
import { DashboardCommand } from '../dashboardWebView/DashboardCommand';
import { ParsedFrontMatter } from '../parsers';
import { SETTING_CUSTOM_SCRIPTS } from '../constants';
import { existsAsync } from '../utils';
import { existsAsync, getPlatform } from '../utils';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../localization';
import { ShellSetting } from '../models';

export class CustomScript {
/**
Expand Down Expand Up @@ -373,34 +374,34 @@ export class CustomScript {
wsPath: string,
args: string
): Promise<string> {
const osType = os.type();
const platform = getPlatform();

// Check the command to use
let command = script.nodeBin || 'node';
if (script.command && script.command !== CommandType.Node) {
command = script.command;
}

if (script.command === CommandType.Node && platform !== 'windows') {
command = await CustomScript.evaluateCommand(CommandType.Node);
}

let scriptPath = join(wsPath, script.script);
if (script.script.includes(WORKSPACE_PLACEHOLDER)) {
scriptPath = Folders.getAbsFilePath(script.script);
}

// Check if there is an environments overwrite required
if (script.environments) {
let crntType: EnvironmentType | null = null;
if (osType === 'Windows_NT') {
crntType = 'windows';
} else if (osType === 'Darwin') {
crntType = 'macos';
} else {
crntType = 'linux';
}

const environment = script.environments.find((e) => e.type === crntType);
const environment = script.environments.find((e) => e.type === platform);
if (environment && environment.script && environment.command) {
if (await CustomScript.validateCommand(environment.command)) {
command = environment.command;

if (command === CommandType.Node && platform !== 'windows') {
command = await CustomScript.evaluateCommand(CommandType.Node);
}

scriptPath = join(wsPath, environment.script);
if (environment.script.includes(WORKSPACE_PLACEHOLDER)) {
scriptPath = Folders.getAbsFilePath(environment.script);
Expand All @@ -414,7 +415,7 @@ export class CustomScript {
throw new Error(`Script not found: ${scriptPath}`);
}

if (osType === 'Windows_NT' && command.toLowerCase() === 'powershell') {
if (platform === 'windows' && command.toLowerCase() === 'powershell') {
command = `${command} -File`;
}

Expand Down Expand Up @@ -506,4 +507,64 @@ export class CustomScript {
return false;
}
}

/**
* Evaluate the command dynamically using `which` command
* @param command
* @returns
*/
private static async evaluateCommand(command: string): Promise<string> {
const shell = CustomScript.getShellPath();
let shellPath: string | undefined = undefined;
if (typeof shell !== 'string' && !!shell) {
shellPath = shell.path;
} else {
shellPath = shell || undefined;
}

return new Promise((resolve, reject) => {
exec(`which ${command}`, { shell: shellPath }, (error, stdout) => {
if (error) {
Logger.error(`Error evaluating command: ${command}`);
reject(error);
return;
}

resolve(stdout.trim());
});
});
}

/**
* Retrieves the shell path configuration based on the current platform and terminal settings.
*
* This method checks for the following configurations in order:
* 1. `integrated.automationProfile.<platform>`: Returns the automation profile if it exists.
* 2. `integrated.defaultProfile.<platform>` and `integrated.profiles.<platform>`: Returns the shell setting from the default profile if it exists.
* 3. `integrated.shell.<platform>`: Returns the shell setting if the above configurations are not found.
*
* @returns {string | ShellSetting | undefined} The shell path configuration or undefined if not found.
*/
private static getShellPath(): string | ShellSetting | undefined {
const platform = getPlatform();
const terminalSettings = workspace.getConfiguration('terminal');

const automationProfile = terminalSettings.get<string | ShellSetting>(
`integrated.automationProfile.${platform}`
);
if (!!automationProfile) {
return automationProfile;
}

const defaultProfile = terminalSettings.get<string>(`integrated.defaultProfile.${platform}`);
const profiles = terminalSettings.get<{ [prop: string]: ShellSetting }>(
`integrated.profiles.${platform}`
);

if (defaultProfile && profiles && profiles[defaultProfile]) {
return profiles[defaultProfile];
}

return terminalSettings.get(`integrated.shell.${platform}`);
}
}
3 changes: 3 additions & 0 deletions src/models/ShellSetting.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface ShellSetting {
path: string;
}
1 change: 1 addition & 0 deletions src/models/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export * from './Mode';
export * from './PanelSettings';
export * from './PostMessageData';
export * from './Project';
export * from './ShellSetting';
export * from './Snippets';
export * from './SortOrder';
export * from './SortType';
Expand Down
19 changes: 2 additions & 17 deletions src/services/Terminal.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { workspace, window, ThemeIcon, TerminalOptions } from 'vscode';
import * as os from 'os';
import { Folders } from '../commands';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../localization';
import { getPlatform } from '../utils';

interface ShellSetting {
path: string;
Expand Down Expand Up @@ -96,7 +96,7 @@ export class Terminal {
* @returns
*/
private static getShellPath(): string | ShellSetting | undefined {
const platform = Terminal.getPlatform();
const platform = getPlatform();
const terminalSettings = workspace.getConfiguration('terminal');

const automationProfile = terminalSettings.get<string | ShellSetting>(
Expand All @@ -117,19 +117,4 @@ export class Terminal {

return terminalSettings.get(`integrated.shell.${platform}`);
}

/**
* Get the current platform
* @returns
*/
private static getPlatform = (): 'windows' | 'linux' | 'osx' => {
const platform = os.platform();
if (platform === 'win32') {
return 'windows';
} else if (platform === 'darwin') {
return 'osx';
}

return 'linux';
};
}
20 changes: 20 additions & 0 deletions src/utils/getPlatform.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as os from 'os';

/**
* Determines the current operating system platform.
*
* @returns {'windows' | 'linux' | 'osx'} - A string representing the platform:
* - 'windows' for Windows OS
* - 'osx' for macOS
* - 'linux' for Linux OS
*/
export const getPlatform = (): 'windows' | 'linux' | 'osx' => {
const platform = os.platform();
if (platform === 'win32') {
return 'windows';
} else if (platform === 'darwin') {
return 'osx';
}

return 'linux';
};
1 change: 1 addition & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export * from './flattenObjectKeys';
export * from './getDescriptionField';
export * from './getExtensibilityScripts';
export * from './getLocalizationFile';
export * from './getPlatform';
export * from './getTitleField';
export * from './getWebviewJsFiles';
export * from './ignoreMsgCommand';
Expand Down

0 comments on commit c84af84

Please sign in to comment.