diff --git a/README.md b/README.md index 19456aab6..0dbba8a21 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,10 @@ - Для прошивки могут понадобиться драйвера прошиваемых устройств (например, нестандартных Arduino или необновлённых системах). - Linux-дистрибутивы с менеджером **Systemd**. - Для прошивки потребуется `libusb`, для опроса устройств также используется `udevadm`. Возможна работа с `eudev`, но это не тестировалось. +- macOS (тестировалось на 14-ой версии "Sonoma") + - См. раздел [Безопасность](https://github.com/kruzhok-team/lapki-client/wiki/%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C-%D0%B7%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D1%87%D0%B8%D0%BA%D0%B0-%D0%BD%D0%B0-macOS#%D0%B1%D0%B5%D0%B7%D0%BE%D0%BF%D0%B0%D1%81%D0%BD%D0%BE%D1%81%D1%82%D1%8C) для решения проблем с открытием Lapki IDE. -Также для прошивки потребуется **avrdude**. В Linux достаточно установить утилиту встроенным пакетным менеджером, под Windows предлагается установить [форк от maurisgreuel](https://github.com/mariusgreuel/avrdude), положить в рабочую директорию или PATH. +Также для прошивки потребуется **avrdude**. В Linux достаточно установить утилиту встроенным пакетным менеджером, под Windows предлагается установить [форк от maurisgreuel](https://github.com/mariusgreuel/avrdude), положить в рабочую директорию или PATH. Инструкцию по установке avrdude на macOS можно посмотреть [здесь](https://github.com/kruzhok-team/lapki-client/wiki/%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C-%D0%B7%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D1%87%D0%B8%D0%BA%D0%B0-%D0%BD%D0%B0-macOS#avrdude). ## Разработка diff --git a/package-lock.json b/package-lock.json index 159309efd..a59ca69e2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,6 +29,7 @@ "electron-settings": "^4.0.2", "fast-xml-parser": "^4.3.2", "find-free-port": "^2.0.0", + "fix-path": "^3.0.0", "isomorphic-ws": "^5.0.0", "lodash.debounce": "^4.0.8", "lodash.throttle": "^4.1.1", @@ -4409,6 +4410,14 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/default-shell": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/default-shell/-/default-shell-1.0.1.tgz", + "integrity": "sha512-/Os8tTMPSriNHCsVj3VLjMZblIl1sIg8EXz3qg7C5K+y9calfTA/qzlfPvCQ+LEgLWmtZ9wCnzE1w+S6TPPFyQ==", + "engines": { + "node": ">=4" + } + }, "node_modules/defer-to-connect": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", @@ -5796,6 +5805,69 @@ "node": ">=0.8.x" } }, + "node_modules/execa": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.5.1.tgz", + "integrity": "sha512-R66dW/hW3I8yV77Wg4xn6zMguRPUgt59VLm5e85NrOF05ZdPn7YOfPBSw0E9epJDvuzwVWEG+HmEaQ4muYuWKQ==", + "dependencies": { + "cross-spawn": "^4.0.0", + "get-stream": "^2.2.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/execa/node_modules/cross-spawn": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", + "integrity": "sha512-yAXz/pA1tD8Gtg2S98Ekf/sewp3Lcp3YoFKJ4Hkp5h5yLWnKVTDU0kwjKJ8NDCYcfTLfyGkzTikst+jWypT1iA==", + "dependencies": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "node_modules/execa/node_modules/get-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", + "integrity": "sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA==", + "dependencies": { + "object-assign": "^4.0.1", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa/node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/execa/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/execa/node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" + }, "node_modules/exenv": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz", @@ -6015,6 +6087,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/fix-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/fix-path/-/fix-path-3.0.0.tgz", + "integrity": "sha512-opGAl4+ip5jUikHR2C8Jo7czZ80pz8EK/0gMlAZu7xgDmBqIynlX8SMYg9KowYjAU6HT0nxsSJEWru0u+n+N2Q==", + "dependencies": { + "shell-path": "^2.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/flat-cache": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", @@ -6999,6 +7085,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", @@ -7109,8 +7203,7 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/isomorphic-ws": { "version": "5.0.0", @@ -8271,6 +8364,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "engines": { + "node": ">=4" + } + }, "node_modules/nwsapi": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", @@ -8436,6 +8548,14 @@ "node": ">=8" } }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "engines": { + "node": ">=4" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -8627,6 +8747,25 @@ "node": ">=0.10.0" } }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/pirates": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", @@ -9016,6 +9155,11 @@ "react-is": "^16.13.1" } }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" + }, "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", @@ -9985,6 +10129,49 @@ "node": ">=8" } }, + "node_modules/shell-env": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/shell-env/-/shell-env-0.3.0.tgz", + "integrity": "sha512-VrC6OSm5riGAFWvlYExA80Rrlfi4STsztNXjyet9Jf20hbiVeeKvJIesb92gJk7zlmpQjB0wOZpy8ClzVdPVWQ==", + "dependencies": { + "default-shell": "^1.0.0", + "execa": "^0.5.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/shell-env/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shell-env/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shell-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/shell-path/-/shell-path-2.1.0.tgz", + "integrity": "sha512-w+mbrnpA+r5jSFS4MgFfxZJ1Wx8qMKkR4gvQ+wgaZEoZCMMYZ6Yl/dcNjW/zLMfmx5a9IVIFwGAtUJcnDMmFrg==", + "dependencies": { + "shell-env": "^0.3.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", @@ -10369,6 +10556,14 @@ "node": ">=4" } }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", diff --git a/package.json b/package.json index c7955e39a..76298fc8f 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "electron-settings": "^4.0.2", "fast-xml-parser": "^4.3.2", "find-free-port": "^2.0.0", + "fix-path": "^3.0.0", "isomorphic-ws": "^5.0.0", "lodash.debounce": "^4.0.8", "lodash.throttle": "^4.1.1", diff --git a/resources/modules/darwin/lapki-flasher b/resources/modules/darwin/lapki-flasher new file mode 100755 index 000000000..b3a31ced2 Binary files /dev/null and b/resources/modules/darwin/lapki-flasher differ diff --git a/src/main/index.ts b/src/main/index.ts index db72882d1..c2bd17c8f 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -68,9 +68,7 @@ function createWindow(): void { //Получаем ответ из рендера и закрываем приложение ipcMain.on('closed', (_) => { ModuleManager.stopModule('lapki-flasher'); - if (process.platform !== 'darwin') { - app.exit(0); - } + app.exit(0); }); // Вместо создания новых окон мы передаём ссылку в систему. @@ -144,12 +142,8 @@ app.whenReady().then(() => { }); // Завершаем приложение, когда окна закрыты. -// Кроме macOS, там выход явный, через Cmd+Q. app.on('window-all-closed', () => { // явно останавливаем загрузчик, так как в некоторых случаях он остаётся висеть ModuleManager.stopModule('lapki-flasher'); - if (process.platform !== 'darwin') { - app.quit(); - } - // + app.quit(); }); diff --git a/src/main/modules/ModuleManager.ts b/src/main/modules/ModuleManager.ts index da0c9d7a1..2502adf89 100644 --- a/src/main/modules/ModuleManager.ts +++ b/src/main/modules/ModuleManager.ts @@ -1,9 +1,10 @@ import settings from 'electron-settings'; +// импорт старой версии (3.0 вместо 4.0), так как новая версия требует ESM +import fixPath from 'fix-path'; import { ChildProcessWithoutNullStreams, spawn } from 'child_process'; import { existsSync } from 'fs'; import path from 'path'; - export type ModuleName = 'lapki-flasher'; export class ModuleStatus { @@ -47,6 +48,13 @@ export class ModuleManager { let modulePath: string = ''; let osPath = ''; switch (platform) { + case 'darwin': { + // позволяет унаследовать $PATH, то есть системный путь + // это нужно для того, чтобы загрузчик смог получить доступ к avrdude, если путь к нему прописан в $PATH + fixPath(); + // break не нужен, так как дальнейшие действия одинаковы для Linux и macOS + } + // eslint-disable-next-line no-fallthrough case 'linux': { osPath = `${basePath}/modules/${platform}`; modulePath = `${osPath}/${module}`; @@ -99,6 +107,7 @@ export class ModuleManager { let avrdudePath = ''; let configPath = ''; switch (platform) { + case 'darwin': case 'linux': avrdudePath = `${osPath}/avrdude`; configPath = `${osPath}/avrdude.conf`;