Skip to content

Commit beb31b5

Browse files
committed
fix: improve template override command in context menu
1 parent 9e3e929 commit beb31b5

3 files changed

Lines changed: 26 additions & 19 deletions

File tree

src/extension.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import * as path from 'node:path';
12
import * as vscode from 'vscode';
23
import { CommandsProvider, MAGEFORGE_COMMANDS, MageforgeCommand } from './commandsProvider';
34
import { ThemeTreeItem, ThemesProvider } from './themesProvider';
@@ -137,8 +138,12 @@ export async function overrideFile(
137138
return;
138139
}
139140

141+
// Use a path relative to the Magento root so the command works inside
142+
// containerized environments (ddev, docker-compose, lando) where the
143+
// absolute host path does not exist.
144+
const relativeTemplatePath = path.relative(magentoRoot, uri.fsPath);
140145
const commandLine = buildCommandLine(magentoRoot, 'mageforge:template:override', [
141-
uri.fsPath,
146+
relativeTemplatePath,
142147
'--theme',
143148
theme,
144149
]);

src/magento.ts

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ export function getDockerComposeService(): string {
6868
/**
6969
* Build the shell command line that runs a MageForge CLI command.
7070
* All arguments are safely quoted to prevent shell injection.
71+
* The MageForge command name itself is not quoted because it is always a
72+
* known, hard-coded CLI identifier (e.g. `mageforge:theme:build`); escaping
73+
* its colons makes the generated command hard to read and can confuse
74+
* containerized PHP wrappers.
7175
*/
7276
export function buildCommandLine(
7377
magentoRoot: string,
@@ -79,26 +83,27 @@ export function buildCommandLine(
7983
.get<string>('phpBinary', 'php');
8084
const env = getExecutionEnvironment(magentoRoot);
8185

86+
const quote = (parts: string[]): string => shellQuote.quote(parts);
87+
88+
function buildLine(baseParts: string[]): string {
89+
const base = quote(baseParts);
90+
const quotedArgs = args.length > 0 ? ` ${quote(args)}` : '';
91+
return `${base} ${mageforgeCommand}${quotedArgs}`;
92+
}
93+
8294
switch (env) {
8395
case 'ddev':
84-
return shellQuote.quote(['ddev', 'php', 'bin/magento', mageforgeCommand, ...args]);
96+
return buildLine(['ddev', 'php', 'bin/magento']);
8597
case 'docker-compose': {
8698
const service = getDockerComposeService();
87-
return shellQuote.quote([
88-
'docker-compose',
89-
'exec',
90-
service,
91-
'bin/magento',
92-
mageforgeCommand,
93-
...args,
94-
]);
99+
return buildLine(['docker-compose', 'exec', service, 'bin/magento']);
95100
}
96101
case 'lando':
97-
return shellQuote.quote(['lando', 'php', 'bin/magento', mageforgeCommand, ...args]);
102+
return buildLine(['lando', 'php', 'bin/magento']);
98103
default: {
99104
// phpBinary can be a full command like "docker-compose exec php" or just "php"
100105
const phpParts = shellQuote.parse(phpBinary) as string[];
101-
return shellQuote.quote([...phpParts, 'bin/magento', mageforgeCommand, ...args]);
106+
return buildLine([...phpParts, 'bin/magento']);
102107
}
103108
}
104109
}

src/test/unit/magento.test.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ suite('magento.ts unit tests', () => {
131131
const line = moduleUnderTest.buildCommandLine(root, 'mageforge:theme:build', [
132132
'Magento/luma',
133133
]);
134-
assert.strictEqual(line, 'php bin/magento mageforge\\:theme\\:build Magento/luma');
134+
assert.strictEqual(line, 'php bin/magento mageforge:theme:build Magento/luma');
135135
});
136136

137137
test('quotes paths with spaces', () => {
@@ -175,15 +175,15 @@ suite('magento.ts unit tests', () => {
175175
]);
176176
assert.strictEqual(
177177
line,
178-
'docker-compose exec php bin/magento mageforge\\:theme\\:build Magento/luma',
178+
'docker-compose exec php bin/magento mageforge:theme:build Magento/luma',
179179
);
180180
});
181181

182182
test('builds ddev command', () => {
183183
const root = createMagentoRoot();
184184
moduleUnderTest = loadModule({ 'mageforge.phpExecution': 'ddev' });
185185
const line = moduleUnderTest.buildCommandLine(root, 'mageforge:theme:list');
186-
assert.strictEqual(line, 'ddev php bin/magento mageforge\\:theme\\:list');
186+
assert.strictEqual(line, 'ddev php bin/magento mageforge:theme:list');
187187
});
188188

189189
test('builds docker-compose command with custom service', () => {
@@ -193,10 +193,7 @@ suite('magento.ts unit tests', () => {
193193
'mageforge.dockerComposeService': 'app',
194194
});
195195
const line = moduleUnderTest.buildCommandLine(root, 'mageforge:theme:list');
196-
assert.strictEqual(
197-
line,
198-
'docker-compose exec app bin/magento mageforge\\:theme\\:list',
199-
);
196+
assert.strictEqual(line, 'docker-compose exec app bin/magento mageforge:theme:list');
200197
});
201198

202199
test('quotes Windows-style paths safely', () => {

0 commit comments

Comments
 (0)