bytefun
Version:
一个打通了原型设计、UI设计与代码转换、跨平台原生代码开发等的平台
202 lines (172 loc) • 5.99 kB
text/typescript
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');
}
}