#fix lib | libPick
This commit is contained in:
parent
17d735f1eb
commit
c6ed600982
@ -68,7 +68,8 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"local",
|
"local",
|
||||||
"remote"
|
"remote",
|
||||||
|
"unknown"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"hardware": {
|
"hardware": {
|
||||||
|
@ -454,10 +454,16 @@ class PrjInfo implements PrjInfoMeta {
|
|||||||
this._library.hardware.custom.push(relPath);
|
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) {
|
if (absolute) {
|
||||||
const commonFolder = hdlPath.join(this.libCommonPath, 'Empty');
|
const absPaths = this._library.hardware.common.map<Path>(relPath => hdlPath.rel2abs(commonFolder, relPath));
|
||||||
return this._library.hardware.common.map<Path>(relPath => hdlPath.rel2abs(commonFolder, relPath));
|
return absPaths;
|
||||||
}
|
}
|
||||||
return this._library.hardware.common;
|
return this._library.hardware.common;
|
||||||
}
|
}
|
||||||
|
@ -35,22 +35,23 @@ function mkdir(path: AbsPath): boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function rmdir(path: AbsPath): void {
|
function rmdir(path: AbsPath): void {
|
||||||
if (fs.existsSync(path)) {
|
fs.rm(path, { recursive: true, force: true }, () => {});
|
||||||
if (fs.statSync(path).isDirectory()) {
|
// if (fs.existsSync(path)) {
|
||||||
const files = fs.readdirSync(path);
|
// if (fs.statSync(path).isDirectory()) {
|
||||||
for (const file of files) {
|
// const files = fs.readdirSync(path);
|
||||||
const curPath = hdlPath.join(path, file);
|
// for (const file of files) {
|
||||||
if (fs.statSync(curPath).isDirectory()) { // recurse
|
// const curPath = hdlPath.join(path, file);
|
||||||
rmdir(curPath);
|
// if (fs.statSync(curPath).isDirectory()) { // recurse
|
||||||
} else { // delete file
|
// rmdir(curPath);
|
||||||
fs.unlinkSync(curPath);
|
// } else { // delete file
|
||||||
}
|
// fs.unlinkSync(curPath);
|
||||||
}
|
// }
|
||||||
fs.rmdirSync(path);
|
// }
|
||||||
} else {
|
// fs.rmdirSync(path);
|
||||||
fs.unlinkSync(path);
|
// } else {
|
||||||
}
|
// fs.unlinkSync(path);
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
function mvdir(src: AbsPath, dest: AbsPath, cover: boolean): boolean {
|
function mvdir(src: AbsPath, dest: AbsPath, cover: boolean): boolean {
|
||||||
|
20
src/manager/ignore.ts
Normal file
20
src/manager/ignore.ts
Normal 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
|
||||||
|
};
|
@ -5,6 +5,9 @@ import { AbsPath, opeParam } from '../global';
|
|||||||
import { hdlDir, hdlFile, hdlPath } from '../hdlFs';
|
import { hdlDir, hdlFile, hdlPath } from '../hdlFs';
|
||||||
import { Library } from '../global/prjInfo';
|
import { Library } from '../global/prjInfo';
|
||||||
import { Path } from '../../resources/hdlParser';
|
import { Path } from '../../resources/hdlParser';
|
||||||
|
import { LibraryState } from '../global/enum';
|
||||||
|
import { PathSet } from '../global/util';
|
||||||
|
import { hdlIgnore } from './ignore';
|
||||||
|
|
||||||
interface LibFileChange {
|
interface LibFileChange {
|
||||||
add: AbsPath[],
|
add: AbsPath[],
|
||||||
@ -12,7 +15,7 @@ interface LibFileChange {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface LibStatus {
|
interface LibStatus {
|
||||||
type?: string,
|
state?: LibraryState,
|
||||||
list: AbsPath[]
|
list: AbsPath[]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,11 +51,11 @@ class LibManage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public get srcPath(): AbsPath {
|
public get srcPath(): AbsPath {
|
||||||
return opeParam.prjInfo.arch.hardware.src;
|
return opeParam.prjInfo.hardwareSrcPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get simPath(): AbsPath {
|
public get simPath(): AbsPath {
|
||||||
return opeParam.prjInfo.arch.hardware.sim;
|
return opeParam.prjInfo.hardwareSimPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get prjPath(): AbsPath {
|
public get prjPath(): AbsPath {
|
||||||
@ -68,70 +71,49 @@ class LibManage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public processLibFiles(library: Library): LibFileChange {
|
public processLibFiles(library: Library): LibFileChange {
|
||||||
// 在不设置state属性的时候默认为remote
|
this.next.list = this.getLibFiles();
|
||||||
this.next.list = this.getLibFiles(library);
|
if (library.state === LibraryState.Local) {
|
||||||
if (!hdlFile.isHasAttr(library, 'state')) {
|
this.next.state = LibraryState.Local;
|
||||||
this.next.type = 'remote';
|
|
||||||
} else {
|
} else {
|
||||||
if (library.state !== 'remote' && library.state !== 'local') {
|
this.next.state = LibraryState.Remote;
|
||||||
return {
|
|
||||||
'add' : [],
|
|
||||||
'del' : [],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
this.next.type = library.state;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处于初始状态时的情况
|
// current disk situation
|
||||||
if (!this.curr.type) {
|
|
||||||
if (!hdlFile.isDir(this.localLibPath)) {
|
if (hdlFile.isDir(this.localLibPath)) {
|
||||||
this.curr.type = 'local';
|
this.curr.state = LibraryState.Local;
|
||||||
} else {
|
} else {
|
||||||
this.curr.type = 'remote';
|
this.curr.state = LibraryState.Remote;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const state = `${this.curr.type}-${this.next.type}`;
|
const add: AbsPath[] = [];
|
||||||
let add: AbsPath[] = [];
|
const del: AbsPath[] = [];
|
||||||
let del: AbsPath[] = [];
|
const statePair = this.curr.state + '-' + this.next.state;
|
||||||
switch (state) {
|
|
||||||
|
switch (statePair) {
|
||||||
case 'remote-remote':
|
case 'remote-remote':
|
||||||
add = diffElement(this.next.list, this.curr.list);
|
add.push(...diffElement(this.next.list, this.curr.list));
|
||||||
del = diffElement(this.curr.list, this.next.list);
|
del.push(...diffElement(this.curr.list, this.next.list));
|
||||||
break;
|
break;
|
||||||
case 'remote-local':
|
case 'remote-local':
|
||||||
// 删除的内容全是remote的,将curr的交出去即可
|
del.push(...this.curr.list);
|
||||||
del = this.curr.list;
|
|
||||||
|
|
||||||
// 将新增的全部复制到本地,交给monitor进行处理
|
// copy file from remote to local
|
||||||
this.remote2Local(this.next.list, (src, dist) => {
|
const remotePathList = this.getLibFiles(LibraryState.Remote);
|
||||||
|
this.remote2Local(remotePathList, (src, dist) => {
|
||||||
hdlFile.copyFile(src, dist);
|
hdlFile.copyFile(src, dist);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 'local-remote':
|
case 'local-remote':
|
||||||
// 本地的lib全部删除,交给monitor进行处理
|
add.push(...this.next.list);
|
||||||
const fn = async () => {
|
|
||||||
if (fs.existsSync(this.localLibPath)) {
|
// delete local files (async)
|
||||||
const needNotice = vscode.workspace.getConfiguration('prj.file.structure.notice');
|
this.deleteLocalFiles();
|
||||||
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();
|
|
||||||
|
|
||||||
// 增加的内容全是remote的,将next的交出去即可
|
|
||||||
add = this.next.list;
|
|
||||||
break;
|
break;
|
||||||
case 'local-local':
|
case 'local-local':
|
||||||
// 只管理library里面的内容,如果自己再localPath里加减代码,则不去管理
|
add.push(...diffElement(this.next.list, this.curr.list));
|
||||||
add = diffElement(this.next.list, this.curr.list);
|
del.push(...diffElement(this.curr.list, this.next.list));
|
||||||
del = diffElement(this.curr.list, this.next.list);
|
|
||||||
|
|
||||||
this.remote2Local(add, (src, dist) => {
|
this.remote2Local(add, (src, dist) => {
|
||||||
hdlFile.copyFile(src, dist);
|
hdlFile.copyFile(src, dist);
|
||||||
@ -140,7 +122,6 @@ class LibManage {
|
|||||||
this.remote2Local(del, (src, dist) => {
|
this.remote2Local(del, (src, dist) => {
|
||||||
hdlFile.removeFile(dist);
|
hdlFile.removeFile(dist);
|
||||||
});
|
});
|
||||||
add = []; del = [];
|
|
||||||
break;
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
@ -149,35 +130,46 @@ class LibManage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
getLibFiles(library: Library) {
|
public getLibFiles(state?: LibraryState): AbsPath[] {
|
||||||
const libFileList: AbsPath[] = [];
|
const libPathSet = new PathSet();
|
||||||
const prjInfo = opeParam.prjInfo;
|
|
||||||
|
|
||||||
// collect common libs
|
for (const path of opeParam.prjInfo.getLibraryCommonPaths(true, state)) {
|
||||||
prjInfo.getLibraryCommonPaths().forEach(absPath => libFileList.push(...hdlFile.getHDLFiles(absPath)));
|
libPathSet.checkAdd(path);
|
||||||
|
}
|
||||||
|
|
||||||
// collect custom libs
|
for (const path of opeParam.prjInfo.getLibraryCustomPaths()) {
|
||||||
prjInfo.getLibraryCustomPaths().forEach(absPath => libFileList.push(...hdlFile.getHDLFiles(absPath)));
|
libPathSet.checkAdd(path);
|
||||||
|
}
|
||||||
|
|
||||||
// Remove duplicate HDL files
|
const ignores = hdlIgnore.getIgnoreFiles();
|
||||||
return removeDuplicates(libFileList);
|
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 localLibPath = this.localLibPath;
|
||||||
const sourceLibPath = this.sourceLibPath;
|
const sourceLibPath = this.sourceLibPath;
|
||||||
const customerPath = this.customerPath;
|
const customerPath = this.customerPath;
|
||||||
const customerPathValid = hdlFile.isDir(customerPath);
|
const customerPathValid = hdlFile.isDir(customerPath);
|
||||||
|
|
||||||
for (const src of remotes) {
|
for (const srcPath of remotes) {
|
||||||
let dist;
|
const replacePath = ( customerPathValid && srcPath.includes(customerPath) ) ? customerPath : sourceLibPath;
|
||||||
if (customerPathValid && src.includes(customerPath)) {
|
const distPath = srcPath.replace(replacePath, localLibPath);
|
||||||
dist = src.replace(customerPath, localLibPath);
|
callback(srcPath, distPath);
|
||||||
} else {
|
|
||||||
dist = src.replace(sourceLibPath, localLibPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
callback(src, dist);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -10,6 +10,7 @@ import { libManage } from './lib';
|
|||||||
import { hdlParam } from '../hdlParser';
|
import { hdlParam } from '../hdlParser';
|
||||||
import { PlManage } from './PL';
|
import { PlManage } from './PL';
|
||||||
import { PsManage } from './PS';
|
import { PsManage } from './PS';
|
||||||
|
import { hdlIgnore } from './ignore';
|
||||||
|
|
||||||
class PrjManage {
|
class PrjManage {
|
||||||
pl?: PlManage;
|
pl?: PlManage;
|
||||||
@ -83,10 +84,6 @@ class PrjManage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public getIgnoreFiles(): AbsPath[] {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get all the hdl files that to be parsed in the project
|
* get all the hdl files that to be parsed in the project
|
||||||
* @returns
|
* @returns
|
||||||
@ -111,7 +108,7 @@ class PrjManage {
|
|||||||
searchPathSet.files.forEach(p => MainOutput.report(p, ReportType.Debug));
|
searchPathSet.files.forEach(p => MainOutput.report(p, ReportType.Debug));
|
||||||
|
|
||||||
// TODO : make something like .gitignore
|
// TODO : make something like .gitignore
|
||||||
const ignores = this.getIgnoreFiles();
|
const ignores = hdlIgnore.getIgnoreFiles();
|
||||||
|
|
||||||
// do search
|
// do search
|
||||||
const searchPaths = searchPathSet.files;
|
const searchPaths = searchPathSet.files;
|
||||||
|
@ -9,6 +9,7 @@ import { isSameSet } from '../global/util';
|
|||||||
import { hdlFile, hdlPath } from '../hdlFs';
|
import { hdlFile, hdlPath } from '../hdlFs';
|
||||||
import { hdlParam, HdlSymbol } from '../hdlParser';
|
import { hdlParam, HdlSymbol } from '../hdlParser';
|
||||||
import { prjManage } from '../manager';
|
import { prjManage } from '../manager';
|
||||||
|
import { libManage } from '../manager/lib';
|
||||||
|
|
||||||
import type { HdlMonitor } from './index';
|
import type { HdlMonitor } from './index';
|
||||||
|
|
||||||
@ -53,10 +54,30 @@ abstract class BaseAction {
|
|||||||
fSWatcher.on(Event.Unlink, path => this.unlink(path, m));
|
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 selectFSWatcher(m: HdlMonitor): chokidar.FSWatcher | undefined;
|
||||||
abstract change(path: AbsPath, m: HdlMonitor): Promise<void>;
|
abstract change(path: AbsPath, m: HdlMonitor): Promise<void>;
|
||||||
abstract add(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 unlink(path: AbsPath, m: HdlMonitor): Promise<void>;
|
||||||
|
abstract unlinkDir(path: AbsPath, m: HdlMonitor): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
class HdlAction extends BaseAction {
|
class HdlAction extends BaseAction {
|
||||||
@ -84,13 +105,18 @@ class HdlAction extends BaseAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async unlink(path: string, m: HdlMonitor): Promise<void> {
|
async unlink(path: string, m: HdlMonitor): Promise<void> {
|
||||||
console.log('HdlAction unlink');
|
console.log('HdlAction unlink', path);
|
||||||
|
|
||||||
path = hdlPath.toSlash(path);
|
path = hdlPath.toSlash(path);
|
||||||
hdlParam.deleteHdlFile(path);
|
hdlParam.deleteHdlFile(path);
|
||||||
refreshArchTree();
|
refreshArchTree();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async unlinkDir(path: string, m: HdlMonitor): Promise<void> {
|
||||||
|
console.log('HdlAction unlinkDir', path);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
async change(path: string, m: HdlMonitor): Promise<void> {
|
async change(path: string, m: HdlMonitor): Promise<void> {
|
||||||
console.log('HdlAction change');
|
console.log('HdlAction change');
|
||||||
|
|
||||||
@ -158,6 +184,10 @@ class PpyAction extends BaseAction {
|
|||||||
this.updateProperty(m);
|
this.updateProperty(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async unlinkDir(path: string, m: HdlMonitor): Promise<void> {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
async change(path: string, m: HdlMonitor): Promise<void> {
|
async change(path: string, m: HdlMonitor): Promise<void> {
|
||||||
console.log('PpyAction change');
|
console.log('PpyAction change');
|
||||||
assert.equal(hdlPath.toSlash(path), opeParam.propertyJsonPath);
|
assert.equal(hdlPath.toSlash(path), opeParam.propertyJsonPath);
|
||||||
@ -181,24 +211,33 @@ class PpyAction extends BaseAction {
|
|||||||
public async updateProperty(m: HdlMonitor) {
|
public async updateProperty(m: HdlMonitor) {
|
||||||
const originalPathSet = this.getImportantPathSet();
|
const originalPathSet = this.getImportantPathSet();
|
||||||
const originalHdlFiles = prjManage.getPrjHardwareFiles();
|
const originalHdlFiles = prjManage.getPrjHardwareFiles();
|
||||||
|
const originalLibState = opeParam.prjInfo.library.state;
|
||||||
|
|
||||||
const rawPrjInfo = opeParam.getRawUserPrjInfo();
|
const rawPrjInfo = opeParam.getRawUserPrjInfo();
|
||||||
opeParam.mergePrjInfo(rawPrjInfo);
|
opeParam.mergePrjInfo(rawPrjInfo);
|
||||||
|
|
||||||
const currentPathSet = this.getImportantPathSet();
|
const currentPathSet = this.getImportantPathSet();
|
||||||
console.log(originalPathSet, currentPathSet);
|
const currentLibState = opeParam.prjInfo.library.state;
|
||||||
|
|
||||||
if (isSameSet(originalPathSet, currentPathSet)) {
|
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[]) {
|
public async refreshHdlMonitor(m: HdlMonitor, originalHdlFiles: AbsPath[]) {
|
||||||
m.remakeHdlMonitor();
|
m.remakeHdlMonitor();
|
||||||
|
|
||||||
// update pl
|
// update pl
|
||||||
|
console.log('current lib state', opeParam.prjInfo.library.state);
|
||||||
const currentHdlFiles = prjManage.getPrjHardwareFiles();
|
const currentHdlFiles = prjManage.getPrjHardwareFiles();
|
||||||
await this.updatePL(originalHdlFiles, currentHdlFiles);
|
await this.updatePL(originalHdlFiles, currentHdlFiles);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user