From c6ed6009820169e85dac4d39099a1e92354ff548 Mon Sep 17 00:00:00 2001 From: Kirigaya <1193466151@qq.com> Date: Wed, 12 Jul 2023 19:10:08 +0800 Subject: [PATCH] #fix lib | libPick --- project/property-schema.json | 3 +- src/global/prjInfo.ts | 14 +++- src/hdlFs/dir.ts | 33 +++++---- src/manager/ignore.ts | 20 +++++ src/manager/lib.ts | 138 +++++++++++++++++------------------ src/manager/prj.ts | 7 +- src/monitor/event.ts | 51 +++++++++++-- 7 files changed, 161 insertions(+), 105 deletions(-) create mode 100644 src/manager/ignore.ts diff --git a/project/property-schema.json b/project/property-schema.json index d0e8a07..3fd55e4 100644 --- a/project/property-schema.json +++ b/project/property-schema.json @@ -68,7 +68,8 @@ "type": "string", "enum": [ "local", - "remote" + "remote", + "unknown" ] }, "hardware": { diff --git a/src/global/prjInfo.ts b/src/global/prjInfo.ts index 4a56d04..2cf2087 100644 --- a/src/global/prjInfo.ts +++ b/src/global/prjInfo.ts @@ -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(relPath => hdlPath.rel2abs(commonFolder, relPath)); + const absPaths = this._library.hardware.common.map(relPath => hdlPath.rel2abs(commonFolder, relPath)); + return absPaths; } return this._library.hardware.common; } @@ -519,7 +525,7 @@ class PrjInfo implements PrjInfoMeta { } public get hardwareSimPath(): AbsPath { - const simPath = this._arch.hardware.sim; + const simPath = this._arch.hardware.sim; if (fspath.isAbsolute(simPath)) { return simPath; } diff --git a/src/hdlFs/dir.ts b/src/hdlFs/dir.ts index 79c14bd..800f7cf 100644 --- a/src/hdlFs/dir.ts +++ b/src/hdlFs/dir.ts @@ -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 { diff --git a/src/manager/ignore.ts b/src/manager/ignore.ts new file mode 100644 index 0000000..990dcc2 --- /dev/null +++ b/src/manager/ignore.ts @@ -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 +}; \ No newline at end of file diff --git a/src/manager/lib.ts b/src/manager/lib.ts index ffbad5e..74bf57a 100644 --- a/src/manager/lib.ts +++ b/src/manager/lib.ts @@ -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,79 +71,57 @@ 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'; - } else { - this.curr.type = 'remote'; - } - } + // current disk situation - const state = `${this.curr.type}-${this.next.type}`; - let add: AbsPath[] = []; - let del: AbsPath[] = []; - switch (state) { + if (hdlFile.isDir(this.localLibPath)) { + this.curr.state = LibraryState.Local; + } else { + this.curr.state = LibraryState.Remote; + } + + 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); }); - this.remote2Local(del, (src, dist) => { + 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))); + for (const path of opeParam.prjInfo.getLibraryCommonPaths(true, state)) { + libPathSet.checkAdd(path); + } - // collect custom libs - prjInfo.getLibraryCustomPaths().forEach(absPath => libFileList.push(...hdlFile.getHDLFiles(absPath))); + for (const path of opeParam.prjInfo.getLibraryCustomPaths()) { + libPathSet.checkAdd(path); + } - // Remove duplicate HDL files - return removeDuplicates(libFileList); + const ignores = hdlIgnore.getIgnoreFiles(); + const libPathList = hdlFile.getHDLFiles(libPathSet.files, ignores); + return libPathList; } - remote2Local(remotes: Path[], callback: (src: AbsPath, dist: AbsPath) => void) { + 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); } } }; diff --git a/src/manager/prj.ts b/src/manager/prj.ts index 16e319c..b8cdfc3 100644 --- a/src/manager/prj.ts +++ b/src/manager/prj.ts @@ -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; diff --git a/src/monitor/event.ts b/src/monitor/event.ts index 8334fb8..4eefd18 100644 --- a/src/monitor/event.ts +++ b/src/monitor/event.ts @@ -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; abstract add(path: AbsPath, m: HdlMonitor): Promise; + // abstract addDir(path: AbsPath, m: HdlMonitor): Promise; abstract unlink(path: AbsPath, m: HdlMonitor): Promise; + abstract unlinkDir(path: AbsPath, m: HdlMonitor): Promise; } class HdlAction extends BaseAction { @@ -84,13 +105,18 @@ class HdlAction extends BaseAction { } async unlink(path: string, m: HdlMonitor): Promise { - console.log('HdlAction unlink'); + console.log('HdlAction unlink', path); path = hdlPath.toSlash(path); hdlParam.deleteHdlFile(path); refreshArchTree(); } + async unlinkDir(path: string, m: HdlMonitor): Promise { + console.log('HdlAction unlinkDir', path); + + } + async change(path: string, m: HdlMonitor): Promise { console.log('HdlAction change'); @@ -157,6 +183,10 @@ class PpyAction extends BaseAction { assert.equal(hdlPath.toSlash(path), opeParam.propertyJsonPath); this.updateProperty(m); } + + async unlinkDir(path: string, m: HdlMonitor): Promise { + + } async change(path: string, m: HdlMonitor): Promise { console.log('PpyAction change'); @@ -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)); } - 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);