Files
orca/src/main/cli/cli-install-path-format.ts
T
NeilandClaude 6d8e4cfef2 refactor(shell): one shell-argument-quoting module for the duplicated quote copies (#30564)
* refactor(shell): one shell-argument-quoting module for the duplicated quote copies

Each former copy now calls the canonical function with its exact spelling; a table test pins
byte-identical output for every copy over hostile inputs. Distinct spellings stay distinct
functions: '\'' vs '"'"', the two plain-word sets, and the cmd.exe doubled quote.

Co-Authored-By: Claude <noreply@anthropic.com>

* style: keep the quoting import at the top of two import-less files

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-18 23:12:27 -07:00

82 lines
2.4 KiB
TypeScript

import { constants } from 'node:fs'
import { access, stat } from 'node:fs/promises'
import { isAbsolute, relative } from 'node:path'
import { expandWindowsEnvironmentVariables } from '../../shared/windows-environment-expansion'
export function splitPathEntries(platform: NodeJS.Platform, value: string | null): string[] {
if (!value) {
return []
}
return value
.split(platform === 'win32' ? ';' : ':')
.map((entry) => entry.trim())
.filter(Boolean)
}
export function uniquePathEntries(platform: NodeJS.Platform, entries: string[]): string[] {
const seen = new Set<string>()
const result: string[] = []
for (const entry of entries) {
const key = platform === 'win32' ? normalizeWindowsPath(entry) : entry
if (seen.has(key)) {
continue
}
seen.add(key)
result.push(entry)
}
return result
}
export function samePathEntry(
platform: NodeJS.Platform,
left: string,
right: string,
windowsEnvironment: NodeJS.ProcessEnv = process.env,
expandWindowsVariables = true
): boolean {
return platform === 'win32'
? normalizeWindowsPath(left, windowsEnvironment, expandWindowsVariables) ===
normalizeWindowsPath(right, windowsEnvironment, expandWindowsVariables)
: left === right
}
export function isPathInsideOrEqual(parentPath: string, childPath: string): boolean {
const childRelative = relative(parentPath, childPath)
return childRelative === '' || (!childRelative.startsWith('..') && !isAbsolute(childRelative))
}
export async function isExecutableFile(commandPath: string): Promise<boolean> {
try {
const stats = await stat(commandPath)
if (!stats.isFile()) {
return false
}
await access(commandPath, constants.X_OK)
return true
} catch {
return false
}
}
export function normalizeWindowsPath(
value: string,
env: NodeJS.ProcessEnv = process.env,
expandEnvironmentVariables = true
): string {
return (expandEnvironmentVariables ? expandWindowsEnvironmentVariables(value, env) : value)
.replaceAll('/', '\\')
.replace(/\\+$/, '')
.toLowerCase()
}
export function escapeWindowsBatchValue(value: string): string {
return value.replaceAll('"', '""')
}
export function isAbsoluteForPlatform(platform: NodeJS.Platform, value: string): boolean {
if (platform === 'win32') {
return /^[A-Za-z]:[\\/]/.test(value) || value.startsWith('\\\\')
}
return isAbsolute(value)
}