UNPKG

bytefun

Version:

一个打通了原型设计、UI设计与代码转换、跨平台原生代码开发等的平台

202 lines (172 loc) 5.99 kB
import * as vscode from 'vscode'; import * as path from 'path'; import * as fs from 'fs'; /** * 工作区工具类 * 提供兼容多工作区环境的路径获取方法 */ export class WorkspaceUtils { /** * 特征目录列表,用于识别项目根目录 */ private static readonly PROJECT_SIGNATURE_DIRS = ['.bytefun', 'doc', 'src']; /** * 智能获取真正的项目根目录 * 兼容单工作区和多工作区环境 * * @returns 项目根目录的绝对路径,如果未找到则返回null */ static getProjectRootPath(): string | null { const workspaceFolder = vscode.workspace.workspaceFolders?.[0]; if (!workspaceFolder) { return null; } return workspaceFolder.uri.fsPath; // const workspaceFolders = vscode.workspace.workspaceFolders; // if (!workspaceFolders || workspaceFolders.length === 0) { // // return null; // } // // 遍历所有工作区文件夹 // for (const workspaceFolder of workspaceFolders) { // const workspaceRoot = workspaceFolder.uri.fsPath; // // // 先检查工作区根目录是否就是项目目录 // if (this.isProjectRoot(workspaceRoot)) { // // return workspaceRoot; // } // // 递归搜索子目录 // const projectRoot = this.findProjectRootInDirectory(workspaceRoot); // if (projectRoot) { // // return projectRoot; // } // } // // return null; } /** * 获取项目根目录对应的VSCode工作区文件夹 * * @returns VSCode工作区文件夹对象,如果未找到则返回null */ static getProjectWorkspaceFolder(): vscode.WorkspaceFolder | null { const projectRoot = this.getProjectRootPath(); if (!projectRoot) { return null; } const workspaceFolders = vscode.workspace.workspaceFolders; if (!workspaceFolders) { return null; } // 查找包含项目根目录的工作区文件夹 for (const workspaceFolder of workspaceFolders) { const workspaceRoot = workspaceFolder.uri.fsPath; if (projectRoot === workspaceRoot || projectRoot.startsWith(workspaceRoot + path.sep)) { return workspaceFolder; } } return null; } /** * 获取指定文件/目录相对于项目根目录的路径 * * @param relativePath 相对于项目根目录的路径 * @returns 绝对路径,如果项目根目录未找到则返回null */ static getProjectPath(relativePath: string): string | null { const projectRoot = this.getProjectRootPath(); if (!projectRoot) { return null; } return path.resolve(projectRoot, relativePath); } /** * 检查指定目录是否为项目根目录 * * @param dirPath 要检查的目录路径 * @returns 是否为项目根目录 */ private static isProjectRoot(dirPath: string): boolean { try { // 检查是否包含所有特征目录 for (const signatureDir of this.PROJECT_SIGNATURE_DIRS) { const signaturePath = path.join(dirPath, signatureDir); if (!fs.existsSync(signaturePath) || !fs.statSync(signaturePath).isDirectory()) { return false; } } return true; } catch (error) { return false; } } /** * 在指定目录中递归搜索项目根目录 * * @param searchDir 搜索起始目录 * @param maxDepth 最大搜索深度,默认为3 * @returns 项目根目录路径,如果未找到则返回null */ private static findProjectRootInDirectory(searchDir: string, maxDepth: number = 3): string | null { if (maxDepth <= 0) { return null; } try { if (!fs.existsSync(searchDir) || !fs.statSync(searchDir).isDirectory()) { return null; } const entries = fs.readdirSync(searchDir, { withFileTypes: true }); // 遍历子目录 for (const entry of entries) { if (entry.isDirectory() && !entry.name.startsWith('.')) { const subDirPath = path.join(searchDir, entry.name); // 检查当前子目录是否为项目根目录 if (this.isProjectRoot(subDirPath)) { return subDirPath; } // 递归搜索更深层级 const deepResult = this.findProjectRootInDirectory(subDirPath, maxDepth - 1); if (deepResult) { return deepResult; } } } } catch (error) { } return null; } /** * 检查项目根目录是否存在 * * @returns 项目根目录是否存在 */ static isProjectRootExists(): boolean { return this.getProjectRootPath() !== null; } /** * 获取.bytefun目录路径 * * @returns .bytefun目录的绝对路径,如果未找到则返回null */ static getBytefunDirPath(): string | null { return this.getProjectPath('.bytefun'); } /** * 获取doc目录路径 * * @returns doc目录的绝对路径,如果未找到则返回null */ static getDocDirPath(): string | null { return this.getProjectPath('doc'); } /** * 获取src目录路径 * * @returns src目录的绝对路径,如果未找到则返回null */ static getSrcDirPath(): string | null { return this.getProjectPath('src'); } }