mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-05-20 01:01:53 +00:00
Merge pull request #2536 from LaZzyMan/fix/test-artifacts-and-shell-permissions
Some checks are pending
Qwen Code CI / Lint (push) Waiting to run
Qwen Code CI / Test (push) Blocked by required conditions
Qwen Code CI / Test-1 (push) Blocked by required conditions
Qwen Code CI / Test-2 (push) Blocked by required conditions
Qwen Code CI / Test-3 (push) Blocked by required conditions
Qwen Code CI / Test-4 (push) Blocked by required conditions
Qwen Code CI / Test-5 (push) Blocked by required conditions
Qwen Code CI / Test-6 (push) Blocked by required conditions
Qwen Code CI / Test-7 (push) Blocked by required conditions
Qwen Code CI / Test-8 (push) Blocked by required conditions
Qwen Code CI / Post Coverage Comment (push) Blocked by required conditions
Qwen Code CI / CodeQL (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:docker (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none (push) Waiting to run
E2E Tests / E2E Test - macOS (push) Waiting to run
Some checks are pending
Qwen Code CI / Lint (push) Waiting to run
Qwen Code CI / Test (push) Blocked by required conditions
Qwen Code CI / Test-1 (push) Blocked by required conditions
Qwen Code CI / Test-2 (push) Blocked by required conditions
Qwen Code CI / Test-3 (push) Blocked by required conditions
Qwen Code CI / Test-4 (push) Blocked by required conditions
Qwen Code CI / Test-5 (push) Blocked by required conditions
Qwen Code CI / Test-6 (push) Blocked by required conditions
Qwen Code CI / Test-7 (push) Blocked by required conditions
Qwen Code CI / Test-8 (push) Blocked by required conditions
Qwen Code CI / Post Coverage Comment (push) Blocked by required conditions
Qwen Code CI / CodeQL (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:docker (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none (push) Waiting to run
E2E Tests / E2E Test - macOS (push) Waiting to run
Fix shell permission parsing and test-created debug artifacts
This commit is contained in:
commit
a0041191a7
4 changed files with 62 additions and 2 deletions
|
|
@ -9,4 +9,10 @@ if (process.env['NO_COLOR'] !== undefined) {
|
|||
delete process.env['NO_COLOR'];
|
||||
}
|
||||
|
||||
// Avoid writing per-session debug log files during CLI tests.
|
||||
// Individual tests can still opt in by overriding this env var explicitly.
|
||||
if (process.env['QWEN_DEBUG_LOG_FILE'] === undefined) {
|
||||
process.env['QWEN_DEBUG_LOG_FILE'] = '0';
|
||||
}
|
||||
|
||||
import './src/test-utils/customMatchers.js';
|
||||
|
|
|
|||
|
|
@ -949,6 +949,24 @@ describe('ShellTool', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('should not surface file descriptor redirects as standalone commands in confirmation details', async () => {
|
||||
const params = {
|
||||
command: 'npm run build 2>&1 | head -100',
|
||||
is_background: false,
|
||||
};
|
||||
const invocation = shellTool.build(params);
|
||||
|
||||
const permission = await invocation.getDefaultPermission();
|
||||
expect(permission).toBe('ask');
|
||||
|
||||
const details = (await invocation.getConfirmationDetails(
|
||||
new AbortController().signal,
|
||||
)) as { rootCommand: string; permissionRules: string[] };
|
||||
|
||||
expect(details.rootCommand).toBe('npm');
|
||||
expect(details.permissionRules).toEqual(['Bash(npm run *)']);
|
||||
});
|
||||
|
||||
it('should throw an error if validation fails', () => {
|
||||
expect(() =>
|
||||
shellTool.build({ command: '', is_background: false }),
|
||||
|
|
|
|||
|
|
@ -440,6 +440,16 @@ describe('getCommandRoots', () => {
|
|||
const result = getCommandRoots('ls\n\ngrep foo');
|
||||
expect(result).toEqual(['ls', 'grep']);
|
||||
});
|
||||
|
||||
it('should not treat file descriptor redirection as a command separator', () => {
|
||||
const result = getCommandRoots('npm run build 2>&1 | head -100');
|
||||
expect(result).toEqual(['npm', 'head']);
|
||||
});
|
||||
|
||||
it('should not treat >| redirection as a pipeline separator', () => {
|
||||
const result = getCommandRoots('echo hello >| out.txt');
|
||||
expect(result).toEqual(['echo']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('stripShellWrapper', () => {
|
||||
|
|
|
|||
|
|
@ -126,6 +126,16 @@ export function splitCommands(command: string): string[] {
|
|||
let inDoubleQuotes = false;
|
||||
let i = 0;
|
||||
|
||||
const previousNonWhitespaceChar = (index: number): string | undefined => {
|
||||
for (let j = index - 1; j >= 0; j--) {
|
||||
const ch = command[j];
|
||||
if (ch && !/\s/.test(ch)) {
|
||||
return ch;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
while (i < command.length) {
|
||||
const char = command[i];
|
||||
const nextChar = command[i + 1];
|
||||
|
|
@ -145,14 +155,30 @@ export function splitCommands(command: string): string[] {
|
|||
if (!inSingleQuotes && !inDoubleQuotes) {
|
||||
if (
|
||||
(char === '&' && nextChar === '&') ||
|
||||
(char === '|' && nextChar === '|')
|
||||
(char === '|' && (nextChar === '|' || nextChar === '&'))
|
||||
) {
|
||||
commands.push(currentCommand.trim());
|
||||
currentCommand = '';
|
||||
i++; // Skip the next character
|
||||
} else if (char === ';' || char === '&' || char === '|') {
|
||||
} else if (char === ';') {
|
||||
commands.push(currentCommand.trim());
|
||||
currentCommand = '';
|
||||
} else if (char === '&') {
|
||||
const prevChar = previousNonWhitespaceChar(i);
|
||||
if (prevChar === '>' || prevChar === '<') {
|
||||
currentCommand += char;
|
||||
} else {
|
||||
commands.push(currentCommand.trim());
|
||||
currentCommand = '';
|
||||
}
|
||||
} else if (char === '|') {
|
||||
const prevChar = previousNonWhitespaceChar(i);
|
||||
if (prevChar === '>') {
|
||||
currentCommand += char;
|
||||
} else {
|
||||
commands.push(currentCommand.trim());
|
||||
currentCommand = '';
|
||||
}
|
||||
} else if (char === '\r' && nextChar === '\n') {
|
||||
// Windows-style \r\n newline - treat as command separator
|
||||
commands.push(currentCommand.trim());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue