#fix lib | libPick

This commit is contained in:
锦恢 2023-07-12 19:10:08 +08:00
parent 17d735f1eb
commit c6ed600982
7 changed files with 161 additions and 105 deletions

View File

@ -68,7 +68,8 @@
"type": "string",
"enum": [
"local",
"remote"
"remote",
"unknown"
]
},
"hardware": {

View File

@ -454,10 +454,16 @@ class PrjInfo implements PrjInfoMeta {
this._library.hardware.custom.push(relPath);
}
public getLibraryCommonPaths(absolute: boolean = true): Path[] {
public getLibraryCommonPaths(absolute: boolean = true, state?: LibraryState): Path[] {
const targetState = state ? state : this._library.state;
const localLibPath = hdlPath.join(this.hardwareSrcPath, 'lib');
const remoteLibPath = this.libCommonPath;
const targetLibPath = (targetState === LibraryState.Local) ? localLibPath : remoteLibPath;
const commonFolder = hdlPath.join(targetLibPath, 'Empty');
if (absolute) {
const commonFolder = hdlPath.join(this.libCommonPath, 'Empty');
return this._library.hardware.common.map<Path>(relPath => hdlPath.rel2abs(commonFolder, relPath));
const absPaths = this._library.hardware.common.map<Path>(relPath => hdlPath.rel2abs(commonFolder, relPath));
return absPaths;
}
return this._library.hardware.common;
}

View File

@ -35,22 +35,23 @@ function mkdir(path: AbsPath): boolean {
}
function rmdir(path: AbsPath): void {
if (fs.existsSync(path)) {
if (fs.statSync(path).isDirectory()) {
const files = fs.readdirSync(path);
for (const file of files) {
const curPath = hdlPath.join(path, file);
if (fs.statSync(curPath).isDirectory()) { // recurse
rmdir(curPath);
} else { // delete file
fs.unlinkSync(curPath);
}
}
fs.rmdirSync(path);
} else {
fs.unlinkSync(path);
}
}
fs.rm(path, { recursive: true, force: true }, () => {});
// if (fs.existsSync(path)) {
// if (fs.statSync(path).isDirectory()) {
// const files = fs.readdirSync(path);
// for (const file of files) {
// const curPath = hdlPath.join(path, file);
// if (fs.statSync(curPath).isDirectory()) { // recurse
// rmdir(curPath);
// } else { // delete file
// fs.unlinkSync(curPath);
// }
// }
// fs.rmdirSync(path);
// } else {
// fs.unlinkSync(path);
// }
// }
}
function mvdir(src: AbsPath, dest: AbsPath, cover: boolean): boolean {

20
src/manager/ignore.ts Normal file
View File

@ -0,0 +1,20 @@
import * as vscode from 'vscode';
import { AbsPath } from '../global';
class HdlIgnore {
constructor() {
}
public getIgnoreFiles(): AbsPath[] {
return [];
}
}
const hdlIgnore = new HdlIgnore();
export {
hdlIgnore
};

View File

@ -5,6 +5,9 @@ import { AbsPath, opeParam } from '../global';
import { hdlDir, hdlFile, hdlPath } from '../hdlFs';
import { Library } from '../global/prjInfo';
import { Path } from '../../resources/hdlParser';
import { LibraryState } from '../global/enum';
import { PathSet } from '../global/util';
import { hdlIgnore } from './ignore';
interface LibFileChange {
add: AbsPath[],
@ -12,7 +15,7 @@ interface LibFileChange {
}
interface LibStatus {
type?: string,
state?: LibraryState,
list: AbsPath[]
}
@ -48,11 +51,11 @@ class LibManage {
}
public get srcPath(): AbsPath {
return opeParam.prjInfo.arch.hardware.src;
return opeParam.prjInfo.hardwareSrcPath;
}
public get simPath(): AbsPath {
return opeParam.prjInfo.arch.hardware.sim;
return opeParam.prjInfo.hardwareSimPath;
}
public get prjPath(): AbsPath {
@ -68,70 +71,49 @@ class LibManage {
}
public processLibFiles(library: Library): LibFileChange {
// 在不设置state属性的时候默认为remote
this.next.list = this.getLibFiles(library);
if (!hdlFile.isHasAttr(library, 'state')) {
this.next.type = 'remote';
this.next.list = this.getLibFiles();
if (library.state === LibraryState.Local) {
this.next.state = LibraryState.Local;
} else {
if (library.state !== 'remote' && library.state !== 'local') {
return {
'add' : [],
'del' : [],
};
}
this.next.type = library.state;
this.next.state = LibraryState.Remote;
}
// 处于初始状态时的情况
if (!this.curr.type) {
if (!hdlFile.isDir(this.localLibPath)) {
this.curr.type = 'local';
// current disk situation
if (hdlFile.isDir(this.localLibPath)) {
this.curr.state = LibraryState.Local;
} else {
this.curr.type = 'remote';
}
this.curr.state = LibraryState.Remote;
}
const state = `${this.curr.type}-${this.next.type}`;
let add: AbsPath[] = [];
let del: AbsPath[] = [];
switch (state) {
const add: AbsPath[] = [];
const del: AbsPath[] = [];
const statePair = this.curr.state + '-' + this.next.state;
switch (statePair) {
case 'remote-remote':
add = diffElement(this.next.list, this.curr.list);
del = diffElement(this.curr.list, this.next.list);
add.push(...diffElement(this.next.list, this.curr.list));
del.push(...diffElement(this.curr.list, this.next.list));
break;
case 'remote-local':
// 删除的内容全是remote的将curr的交出去即可
del = this.curr.list;
del.push(...this.curr.list);
// 将新增的全部复制到本地交给monitor进行处理
this.remote2Local(this.next.list, (src, dist) => {
// copy file from remote to local
const remotePathList = this.getLibFiles(LibraryState.Remote);
this.remote2Local(remotePathList, (src, dist) => {
hdlFile.copyFile(src, dist);
});
break;
case 'local-remote':
// 本地的lib全部删除交给monitor进行处理
const fn = async () => {
if (fs.existsSync(this.localLibPath)) {
const needNotice = vscode.workspace.getConfiguration('prj.file.structure.notice');
if (needNotice) {
let select = await vscode.window.showWarningMessage("local lib will be removed.", 'Yes', 'Cancel');
if (select === "Yes") {
hdlDir.rmdir(this.localLibPath);
}
} else {
hdlDir.rmdir(this.localLibPath);
}
}
};
fn();
add.push(...this.next.list);
// delete local files (async)
this.deleteLocalFiles();
// 增加的内容全是remote的将next的交出去即可
add = this.next.list;
break;
case 'local-local':
// 只管理library里面的内容如果自己再localPath里加减代码则不去管理
add = diffElement(this.next.list, this.curr.list);
del = diffElement(this.curr.list, this.next.list);
add.push(...diffElement(this.next.list, this.curr.list));
del.push(...diffElement(this.curr.list, this.next.list));
this.remote2Local(add, (src, dist) => {
hdlFile.copyFile(src, dist);
@ -140,7 +122,6 @@ class LibManage {
this.remote2Local(del, (src, dist) => {
hdlFile.removeFile(dist);
});
add = []; del = [];
break;
default: break;
}
@ -149,35 +130,46 @@ class LibManage {
}
getLibFiles(library: Library) {
const libFileList: AbsPath[] = [];
const prjInfo = opeParam.prjInfo;
public getLibFiles(state?: LibraryState): AbsPath[] {
const libPathSet = new PathSet();
// collect common libs
prjInfo.getLibraryCommonPaths().forEach(absPath => libFileList.push(...hdlFile.getHDLFiles(absPath)));
// collect custom libs
prjInfo.getLibraryCustomPaths().forEach(absPath => libFileList.push(...hdlFile.getHDLFiles(absPath)));
// Remove duplicate HDL files
return removeDuplicates(libFileList);
for (const path of opeParam.prjInfo.getLibraryCommonPaths(true, state)) {
libPathSet.checkAdd(path);
}
remote2Local(remotes: Path[], callback: (src: AbsPath, dist: AbsPath) => void) {
for (const path of opeParam.prjInfo.getLibraryCustomPaths()) {
libPathSet.checkAdd(path);
}
const ignores = hdlIgnore.getIgnoreFiles();
const libPathList = hdlFile.getHDLFiles(libPathSet.files, ignores);
return libPathList;
}
public async deleteLocalFiles() {
if (fs.existsSync(this.localLibPath)) {
const needNotice = vscode.workspace.getConfiguration('prj.file.structure.notice');
if (needNotice) {
let select = await vscode.window.showWarningMessage(`Local Lib (${this.localLibPath}) will be removed.`, 'Yes', 'Cancel');
if (select === "Yes") {
hdlDir.rmdir(this.localLibPath);
}
} else {
hdlDir.rmdir(this.localLibPath);
}
}
}
public remote2Local(remotes: Path[], callback: (src: AbsPath, dist: AbsPath) => void) {
const localLibPath = this.localLibPath;
const sourceLibPath = this.sourceLibPath;
const customerPath = this.customerPath;
const customerPathValid = hdlFile.isDir(customerPath);
for (const src of remotes) {
let dist;
if (customerPathValid && src.includes(customerPath)) {
dist = src.replace(customerPath, localLibPath);
} else {
dist = src.replace(sourceLibPath, localLibPath);
}
callback(src, dist);
for (const srcPath of remotes) {
const replacePath = ( customerPathValid && srcPath.includes(customerPath) ) ? customerPath : sourceLibPath;
const distPath = srcPath.replace(replacePath, localLibPath);
callback(srcPath, distPath);
}
}
};

View File

@ -10,6 +10,7 @@ import { libManage } from './lib';
import { hdlParam } from '../hdlParser';
import { PlManage } from './PL';
import { PsManage } from './PS';
import { hdlIgnore } from './ignore';
class PrjManage {
pl?: PlManage;
@ -83,10 +84,6 @@ class PrjManage {
}
}
public getIgnoreFiles(): AbsPath[] {
return [];
}
/**
* get all the hdl files that to be parsed in the project
* @returns
@ -111,7 +108,7 @@ class PrjManage {
searchPathSet.files.forEach(p => MainOutput.report(p, ReportType.Debug));
// TODO : make something like .gitignore
const ignores = this.getIgnoreFiles();
const ignores = hdlIgnore.getIgnoreFiles();
// do search
const searchPaths = searchPathSet.files;

View File

@ -9,6 +9,7 @@ import { isSameSet } from '../global/util';
import { hdlFile, hdlPath } from '../hdlFs';
import { hdlParam, HdlSymbol } from '../hdlParser';
import { prjManage } from '../manager';
import { libManage } from '../manager/lib';
import type { HdlMonitor } from './index';
@ -53,10 +54,30 @@ abstract class BaseAction {
fSWatcher.on(Event.Unlink, path => this.unlink(path, m));
}
public listenUnlinkDir(m: HdlMonitor) {
const fSWatcher = this.selectFSWatcher(m);
if (!fSWatcher) {
MainOutput.report("FSWatcher hasn't been made!", ReportType.Error);
return;
}
fSWatcher.on(Event.UnlinkDir, path => this.unlinkDir(path, m));
}
// public listenAddDir(m: HdlMonitor) {
// const fSWatcher = this.selectFSWatcher(m);
// if (!fSWatcher) {
// MainOutput.report("FSWatcher hasn't been made!", ReportType.Error);
// return;
// }
// fSWatcher.on(Event.UnlinkDir, path => this.unlinkDir(path, m));
// }
abstract selectFSWatcher(m: HdlMonitor): chokidar.FSWatcher | undefined;
abstract change(path: AbsPath, m: HdlMonitor): Promise<void>;
abstract add(path: AbsPath, m: HdlMonitor): Promise<void>;
// abstract addDir(path: AbsPath, m: HdlMonitor): Promise<void>;
abstract unlink(path: AbsPath, m: HdlMonitor): Promise<void>;
abstract unlinkDir(path: AbsPath, m: HdlMonitor): Promise<void>;
}
class HdlAction extends BaseAction {
@ -84,13 +105,18 @@ class HdlAction extends BaseAction {
}
async unlink(path: string, m: HdlMonitor): Promise<void> {
console.log('HdlAction unlink');
console.log('HdlAction unlink', path);
path = hdlPath.toSlash(path);
hdlParam.deleteHdlFile(path);
refreshArchTree();
}
async unlinkDir(path: string, m: HdlMonitor): Promise<void> {
console.log('HdlAction unlinkDir', path);
}
async change(path: string, m: HdlMonitor): Promise<void> {
console.log('HdlAction change');
@ -158,6 +184,10 @@ class PpyAction extends BaseAction {
this.updateProperty(m);
}
async unlinkDir(path: string, m: HdlMonitor): Promise<void> {
}
async change(path: string, m: HdlMonitor): Promise<void> {
console.log('PpyAction change');
assert.equal(hdlPath.toSlash(path), opeParam.propertyJsonPath);
@ -181,24 +211,33 @@ class PpyAction extends BaseAction {
public async updateProperty(m: HdlMonitor) {
const originalPathSet = this.getImportantPathSet();
const originalHdlFiles = prjManage.getPrjHardwareFiles();
const originalLibState = opeParam.prjInfo.library.state;
const rawPrjInfo = opeParam.getRawUserPrjInfo();
opeParam.mergePrjInfo(rawPrjInfo);
const currentPathSet = this.getImportantPathSet();
console.log(originalPathSet, currentPathSet);
const currentLibState = opeParam.prjInfo.library.state;
if (isSameSet(originalPathSet, currentPathSet)) {
return;
// skip hdl remake
if (originalLibState !== currentLibState) {
const fileChange = libManage.processLibFiles(opeParam.prjInfo.library);
MainOutput.report(`libManage finish process, add ${fileChange.add.length} files, del ${fileChange.del.length} files`, ReportType.Info);
}
} else {
// update hdl monitor
const options: vscode.ProgressOptions = { location: vscode.ProgressLocation.Notification, title: 'modify the project' };
vscode.window.withProgress(options, async () => await this.refreshHdlMonitor(m, originalHdlFiles));
}
}
public async refreshHdlMonitor(m: HdlMonitor, originalHdlFiles: AbsPath[]) {
m.remakeHdlMonitor();
// update pl
console.log('current lib state', opeParam.prjInfo.library.state);
const currentHdlFiles = prjManage.getPrjHardwareFiles();
await this.updatePL(originalHdlFiles, currentHdlFiles);