Update: 在线版添识别code中import来同时上传所有依赖文件 (实验性)
This commit is contained in:
@@ -14,6 +14,7 @@ goog.require('Mixly.Msg');
|
|||||||
goog.require('Mixly.Workspace');
|
goog.require('Mixly.Workspace');
|
||||||
goog.require('Mixly.Debug');
|
goog.require('Mixly.Debug');
|
||||||
goog.require('Mixly.HTMLTemplate');
|
goog.require('Mixly.HTMLTemplate');
|
||||||
|
goog.require('Mixly.MString');
|
||||||
goog.require('Mixly.Web.Serial');
|
goog.require('Mixly.Web.Serial');
|
||||||
goog.require('Mixly.Web.USB');
|
goog.require('Mixly.Web.USB');
|
||||||
goog.require('Mixly.Web.Ampy');
|
goog.require('Mixly.Web.Ampy');
|
||||||
@@ -29,7 +30,8 @@ const {
|
|||||||
Msg,
|
Msg,
|
||||||
Workspace,
|
Workspace,
|
||||||
Debug,
|
Debug,
|
||||||
HTMLTemplate
|
HTMLTemplate,
|
||||||
|
MString
|
||||||
} = Mixly;
|
} = Mixly;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -453,64 +455,61 @@ BU.burnWithAdafruitEsptool = async (binFile) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BU.getImportModulesName = (code) => {
|
BU.getImportModulesName = (code) => {
|
||||||
const { web = {} } = SELECTED_BOARD;
|
// 正则表达式: 匹配 import 或 from 导入语句
|
||||||
const { lib } = web;
|
const importRegex = /(?:import\s+([a-zA-Z0-9_]+)|from\s+([a-zA-Z0-9_]+)\s+import)/g;
|
||||||
if (!(lib instanceof Object)) {
|
|
||||||
return [];
|
let imports = [];
|
||||||
}
|
let match;
|
||||||
let lineList = [];
|
while ((match = importRegex.exec(code)) !== null) {
|
||||||
code.trim().split("\n").forEach(function (v, i) {
|
if (match[1]) {
|
||||||
lineList.push(v);
|
imports.push(match[1]); // 'import module'
|
||||||
});
|
}
|
||||||
let moduleName = "";
|
if (match[2]) {
|
||||||
let moduleList = [];
|
imports.push(match[2]); // 'from module import ...'
|
||||||
for (let data of lineList) {
|
|
||||||
let fromLoc = data.indexOf("from");
|
|
||||||
let importLoc = data.indexOf("import");
|
|
||||||
const str = data.substring(0, (fromLoc === -1)? importLoc : fromLoc);
|
|
||||||
str.split('').forEach((ch) => {
|
|
||||||
if (ch !== ' ' && ch !== '\t') {
|
|
||||||
fromLoc = -1;
|
|
||||||
importLoc = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (fromLoc !== -1) {
|
|
||||||
moduleName = data.substring(fromLoc + 4, data.indexOf("import"));
|
|
||||||
} else if (importLoc !== -1) {
|
|
||||||
moduleName = data.substring(importLoc + 6);
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
moduleName = moduleName.replaceAll(' ', '');
|
|
||||||
moduleName = moduleName.replaceAll('\r', '');
|
|
||||||
moduleList = [ ...moduleList, ...moduleName.split(",") ];
|
|
||||||
}
|
}
|
||||||
return moduleList;
|
return imports;
|
||||||
}
|
}
|
||||||
|
|
||||||
BU.searchLibs = (moduleList, libList = []) => {
|
BU.getImportModules = (code) => {
|
||||||
const { web = {} } = SELECTED_BOARD;
|
let importsMap = {};
|
||||||
const { lib } = web;
|
const libPath = SELECTED_BOARD.upload.libPath;
|
||||||
if (!(lib instanceof Object)) {
|
for (let i = libPath.length - 1; i >= 0; i--) {
|
||||||
return [];
|
const dirname = MString.tpl(libPath[i], { indexPath: Env.boardDirPath });
|
||||||
}
|
const map = goog.getJSON(path.join(dirname, 'map.json'));
|
||||||
const { mainStatusBarTabs } = Mixly;
|
if (!(map && map instanceof Object)) {
|
||||||
const statusBarTerminal = mainStatusBarTabs.getStatusBarById('output');
|
continue;
|
||||||
for (let name of moduleList) {
|
}
|
||||||
if (!libList.includes(name)) {
|
for (let key in map) {
|
||||||
if (!lib[name]) {
|
importsMap[key] = structuredClone(map[key]);
|
||||||
continue;
|
importsMap[key]['__path__'] = path.join(dirname, map[key]['__name__']);
|
||||||
}
|
|
||||||
libList.push(name);
|
|
||||||
statusBarTerminal.addValue(Msg.Lang['shell.copyLib'] + ' ' + name + '.py\n');
|
|
||||||
if (!lib[name].import.length) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
libList = BU.searchLibs(lib[name].import, libList);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return libList;
|
|
||||||
|
let usedMap = {};
|
||||||
|
let currentImports = BU.getImportModulesName(code);
|
||||||
|
while (currentImports.length) {
|
||||||
|
let temp = [];
|
||||||
|
for (let moduleName of currentImports) {
|
||||||
|
let moduleInfo = importsMap[moduleName];
|
||||||
|
if (!moduleInfo) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
usedMap[moduleName] = moduleInfo;
|
||||||
|
const moduleImports = moduleInfo['__require__'];
|
||||||
|
if (!moduleImports) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (let name of moduleImports) {
|
||||||
|
if (usedMap[name] || !importsMap[name] || temp.includes(name)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
temp.push(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentImports = temp;
|
||||||
|
}
|
||||||
|
return usedMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
BU.initUpload = async () => {
|
BU.initUpload = async () => {
|
||||||
@@ -548,32 +547,48 @@ BU.uploadWithAmpy = (portName) => {
|
|||||||
shade: LayerExt.SHADE_NAV,
|
shade: LayerExt.SHADE_NAV,
|
||||||
resize: false,
|
resize: false,
|
||||||
closeBtn: 0,
|
closeBtn: 0,
|
||||||
success: function (layero, index) {
|
success: async function (layero, index) {
|
||||||
const serial = new Serial(portName);
|
const serial = new Serial(portName);
|
||||||
const ampy = new Ampy(serial);
|
const ampy = new Ampy(serial);
|
||||||
const code = editor.getCode();
|
const code = editor.getCode();
|
||||||
/*let moduleList = BU.getImportModulesName(code);
|
|
||||||
moduleList = BU.searchLibs(moduleList);
|
|
||||||
const moduleInfo = {};
|
|
||||||
for (let name of moduleList) {
|
|
||||||
moduleInfo[name] = SELECTED_BOARD.web.lib[name].path;
|
|
||||||
}*/
|
|
||||||
let closePromise = Promise.resolve();
|
let closePromise = Promise.resolve();
|
||||||
if (statusBarSerial) {
|
if (statusBarSerial) {
|
||||||
closePromise = statusBarSerial.close();
|
closePromise = statusBarSerial.close();
|
||||||
}
|
}
|
||||||
closePromise
|
try {
|
||||||
.then(() => ampy.enter())
|
const importsMap = BU.getImportModules(code);
|
||||||
.then(() => {
|
let libraries = {};
|
||||||
|
for (let key in importsMap) {
|
||||||
|
const filename = importsMap[key]['__name__'];
|
||||||
|
const data = goog.get(importsMap[key]['__path__']);
|
||||||
|
libraries[filename] = {
|
||||||
|
data,
|
||||||
|
size: importsMap[key]['__size__']
|
||||||
|
};
|
||||||
|
}
|
||||||
|
await closePromise;
|
||||||
|
await ampy.enter();
|
||||||
|
const rootInfo = await ampy.ls('/');
|
||||||
|
let rootMap = {};
|
||||||
|
for (let item of rootInfo) {
|
||||||
|
rootMap[item[0]] = item[1];
|
||||||
|
}
|
||||||
statusBarTerminal.addValue('Writing main.py ');
|
statusBarTerminal.addValue('Writing main.py ');
|
||||||
return ampy.put('main.py', code);
|
await ampy.put('main.py', code);
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
statusBarTerminal.addValue('Done!\n');
|
statusBarTerminal.addValue('Done!\n');
|
||||||
return ampy.exit();
|
if (libraries && libraries instanceof Object) {
|
||||||
})
|
for (let key in libraries) {
|
||||||
.then(() => ampy.dispose())
|
if (rootMap[`/${key}`] !== undefined && rootMap[`/${key}`] === libraries[key].size) {
|
||||||
.then(() => {
|
statusBarTerminal.addValue(`Skip ${key}\n`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
statusBarTerminal.addValue(`Writing ${key} `);
|
||||||
|
await ampy.put(key, libraries[key].data);
|
||||||
|
statusBarTerminal.addValue('Done!\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await ampy.exit();
|
||||||
|
await ampy.dispose();
|
||||||
layer.close(index);
|
layer.close(index);
|
||||||
layer.msg(Msg.Lang['shell.uploadSucc'], { time: 1000 });
|
layer.msg(Msg.Lang['shell.uploadSucc'], { time: 1000 });
|
||||||
statusBarTerminal.addValue(`==${Msg.Lang['shell.uploadSucc']}==\n`);
|
statusBarTerminal.addValue(`==${Msg.Lang['shell.uploadSucc']}==\n`);
|
||||||
@@ -583,19 +598,16 @@ BU.uploadWithAmpy = (portName) => {
|
|||||||
}
|
}
|
||||||
statusBarSerial.setValue('');
|
statusBarSerial.setValue('');
|
||||||
mainStatusBarTabs.changeTo(portName);
|
mainStatusBarTabs.changeTo(portName);
|
||||||
statusBarSerial.open().catch(Debug.error);
|
await statusBarSerial.open();
|
||||||
})
|
} catch (error) {
|
||||||
.catch((error) => {
|
|
||||||
ampy.dispose();
|
ampy.dispose();
|
||||||
layer.close(index);
|
layer.close(index);
|
||||||
console.error(error);
|
console.error(error);
|
||||||
statusBarTerminal.addValue(`${error}\n`);
|
statusBarTerminal.addValue(`${error}\n`);
|
||||||
statusBarTerminal.addValue(`==${Msg.Lang['shell.uploadFailed']}==\n`);
|
statusBarTerminal.addValue(`==${Msg.Lang['shell.uploadFailed']}==\n`);
|
||||||
})
|
}
|
||||||
.finally(async () => {
|
BU.burning = false;
|
||||||
BU.burning = false;
|
BU.uploading = false;
|
||||||
BU.uploading = false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user