import { readdir, readFile } from 'fs/promises'import memoize from 'lodash-es/memoize.js'import { release as osRelease } from 'os'import { getFsImplementation } from './fsOperations.js'import { logError } from './log.js'export type Platform = 'macos' | 'windows' | 'wsl' | 'linux' | 'unknown'export const SUPPORTED_PLATFORMS: Platform[] = ['macos', 'wsl']export const getPlatform = memoize((): Platform => {try {if (process.platform === 'darwin') {return 'macos'}if (process.platform === 'win32') {return 'windows'}if (process.platform === 'linux') {// Check if running in WSL (Windows Subsystem for Linux)try {const procVersion = getFsImplementation().readFileSync('/proc/version',{ encoding: 'utf8' },)if (procVersion.toLowerCase().includes('microsoft') ||procVersion.toLowerCase().includes('wsl')) {return 'wsl'}} catch (error) {// Error reading /proc/version, assume regular LinuxlogError(error)}// Regular Linuxreturn 'linux'}// Unknown platformreturn 'unknown'} catch (error) {logError(error)return 'unknown'}})export const getWslVersion = memoize((): string | undefined => {// Only check for WSL on Linux systemsif (process.platform !== 'linux') {return undefined}try {const procVersion = getFsImplementation().readFileSync('/proc/version', {encoding: 'utf8',})// First check for explicit WSL version markers (e.g., "WSL2", "WSL3", etc.)const wslVersionMatch = procVersion.match(/WSL(\d+)/i)if (wslVersionMatch && wslVersionMatch[1]) {return wslVersionMatch[1]}// If no explicit WSL version but contains Microsoft, assume WSL1// This handles the original WSL1 format: "4.4.0-19041-Microsoft"if (procVersion.toLowerCase().includes('microsoft')) {return '1'}// Not WSL or unable to determine versionreturn undefined} catch (error) {logError(error)return undefined}})export type LinuxDistroInfo = {linuxDistroId?: stringlinuxDistroVersion?: stringlinuxKernel?: string}export const getLinuxDistroInfo = memoize(async (): Promise<LinuxDistroInfo | undefined> => {if (process.platform !== 'linux') {return undefined}const result: LinuxDistroInfo = {linuxKernel: osRelease(),}try {const content = await readFile('/etc/os-release', 'utf8')for (const line of content.split('\n')) {const match = line.match(/^(ID|VERSION_ID)=(.*)$/)if (match && match[1] && match[2]) {const value = match[2].replace(/^"|"$/g, '')if (match[1] === 'ID') {result.linuxDistroId = value} else {result.linuxDistroVersion = value}}}} catch {// /etc/os-release may not exist on all Linux systems}return result},)const VCS_MARKERS: Array<[string, string]> = [['.git', 'git'],['.hg', 'mercurial'],['.svn', 'svn'],['.p4config', 'perforce'],['$tf', 'tfs'],['.tfvc', 'tfs'],['.jj', 'jujutsu'],['.sl', 'sapling'],]export async function detectVcs(dir?: string): Promise<string[]> {const detected = new Set<string>()// Check for Perforce via env varif (process.env.P4PORT) {detected.add('perforce')}try {const targetDir = dir ?? getFsImplementation().cwd()const entries = new Set(await readdir(targetDir))for (const [marker, vcs] of VCS_MARKERS) {if (entries.has(marker)) {detected.add(vcs)}}} catch {// Directory may not be readable}return [...detected]}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。