diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 2cd2611d..070a4b38 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -122,12 +122,6 @@ steps: msbuildArguments: /p:SignType=$(SignType) # MicroBuild signing will always fail on public PRs. condition: ne(variables['Build.Reason'], 'PullRequest') - # VSIX signing removes the executable attributes on files. Luckily, the - # signature only seems to be based on the content of the files, not the - # attributes, so we can safely go back and mark the serial monitor as - # executable without invalidating the signature. - - script: python .\build\markExecutableFiles.py - displayName: Make serial monitor executable - publish: $(Build.StagingDirectory)\vscode-arduino.vsix artifact: VS Code extension VSIX displayName: Publish extension VSIX as artifact diff --git a/build/SignFiles.proj b/build/SignFiles.proj index 19a18ba7..953c4acb 100644 --- a/build/SignFiles.proj +++ b/build/SignFiles.proj @@ -13,14 +13,6 @@ Microsoft400 - - - Microsoft400 - - - Microsoft400 - 3PartyScriptsSHA2 diff --git a/build/markExecutableFiles.py b/build/markExecutableFiles.py deleted file mode 100644 index 9d7380fa..00000000 --- a/build/markExecutableFiles.py +++ /dev/null @@ -1,31 +0,0 @@ -import os -import zipfile - -staging_directory = os.getenv('BUILD_STAGINGDIRECTORY') -input_archive_path = f"{staging_directory}/vscode-arduino.vsix" -output_archive_path = f"{staging_directory}/vscode-arduino-out.vsix" - -filenames = [ - "extension/out/serial-monitor-cli/darwin/main.out", - "extension/out/serial-monitor-cli/linux/main.out" -] - -input_archive = zipfile.ZipFile(input_archive_path, 'r') -output_archive = zipfile.ZipFile(output_archive_path, 'w') - -executable_count = 0 -for info in input_archive.infolist(): - data = input_archive.read(info) - if info.filename in filenames: - # Magic number from from https://stackoverflow.com/a/48435482 - info.external_attr = 0o100755 << 16 - executable_count += 1 - output_archive.writestr(info, data) - -if executable_count != len(filenames): - raise Exception(f'Expected to find {len(filenames)} executables but only found {executable_count}') - -input_archive.close() -output_archive.close() - -os.replace(output_archive_path, input_archive_path) diff --git a/gulpfile.js b/gulpfile.js index f7fd3432..79b24d12 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -63,28 +63,6 @@ gulp.task("node_modules-webpack", (done) => { }); }); -gulp.task("insert-serial-monitor-cli", async (done) => { - const platforms = [ - "linux", - "darwin", - "win32", - ]; - const release = "latest"; - const destDir = path.resolve("out", "serial-monitor-cli"); - - async function downloadAndUnzip(platform) { - const fileName = `${platform}.zip`; - const zipPath = path.join(destDir, fileName); - await download(`https://github.com/microsoft/serial-monitor-cli/releases/${release}/download/${fileName}`, - destDir, - ); - await extract(zipPath, { dir: path.join(destDir, platform) }); - fs.rmSync(zipPath); - } - - Promise.all(platforms.map(downloadAndUnzip)).then(done); -}); - gulp.task("ts-compile", () => { const tsProject = ts.createProject("./tsconfig.json"); return tsProject.src() @@ -156,7 +134,7 @@ gulp.task("test", (done) => { }); }); -gulp.task("build", gulp.series("clean", "ts-compile", "html-webpack", "node_modules-webpack", "insert-serial-monitor-cli")); +gulp.task("build", gulp.series("clean", "ts-compile", "html-webpack", "node_modules-webpack")); gulp.task("build_without_view", gulp.series("clean", "ts-compile")); diff --git a/package-lock.json b/package-lock.json index 1dd9f1db..f8ee3c26 100644 --- a/package-lock.json +++ b/package-lock.json @@ -199,70 +199,35 @@ "fastq": "^1.6.0" } }, - "@serialport/binding-abstract": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/@serialport/binding-abstract/-/binding-abstract-9.0.7.tgz", - "integrity": "sha512-g1ncCMIG9rMsxo/28ObYmXZcHThlvtZygsCANmyMUuFS7SwXY4+PhcEnt2+ZcMkEDNRiOklT+ngtIVx5GGpt/A==", + "@serialport/bindings-cpp": { + "version": "10.6.2", + "resolved": "https://registry.npmjs.org/@serialport/bindings-cpp/-/bindings-cpp-10.6.2.tgz", + "integrity": "sha512-vhId2K4Y4WOgy/UJE8NOHX6GZpozORCCMh6GM5UQeIzXihoYLxt4eomgl1eXasFipcRs06n71lAToqixb7NPpA==", "requires": { - "debug": "^4.3.1" + "@serialport/bindings-interface": "1.2.1", + "@serialport/parser-readline": "^10.2.1", + "debug": "^4.3.2", + "node-addon-api": "^4.3.0", + "node-gyp-build": "^4.3.0" }, "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - } + "@serialport/parser-delimiter": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-10.2.2.tgz", + "integrity": "sha512-VsepMDIjbHbANMxH4IkXIJY0Tds8XsDo0mgtWK3DrV+IJGXp+2b0pHOuQlSLSfEUmdw7F5drI17fkxc9mxn+pg==" }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "@serialport/binding-mock": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/@serialport/binding-mock/-/binding-mock-9.0.7.tgz", - "integrity": "sha512-aR8H+htZwwZZkVb1MdbnNvGWw8eXVRqQ2qPhkbKyx0N/LY5aVIgCgT98Kt1YylLsG7SzNG+Jbhd4wzwEuPVT5Q==", - "requires": { - "@serialport/binding-abstract": "^9.0.7", - "debug": "^4.3.1" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "@serialport/parser-readline": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-10.2.2.tgz", + "integrity": "sha512-OcWoTsUJeLKWw+rdTuqXFZhii2liE6LeoFK2rtS6L00pB0cd2FGt2Rsx76oTCTyrub6AAUqaS9PRrAI+AUJJpg==", "requires": { - "ms": "2.1.2" + "@serialport/parser-delimiter": "10.2.2" } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "@serialport/bindings": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/@serialport/bindings/-/bindings-9.0.7.tgz", - "integrity": "sha512-cNWaxnEbbpLoSJ6GMb0ZeCpaciczm8XRE4jgBqe/BflWZb+wyiTYIocbsySxpS40WT3kJ0sNTFag77uSmQ6ftg==", - "requires": { - "@serialport/binding-abstract": "^9.0.7", - "@serialport/parser-readline": "^9.0.7", - "bindings": "^1.5.0", - "debug": "^4.3.1", - "nan": "^2.14.2", - "prebuild-install": "^6.0.1" - }, - "dependencies": { "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "requires": { "ms": "2.1.2" } @@ -271,74 +236,28 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nan": { - "version": "2.14.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", - "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" } } }, - "@serialport/parser-byte-length": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/@serialport/parser-byte-length/-/parser-byte-length-9.0.7.tgz", - "integrity": "sha512-evf7oOOSBMBn2AZZbgBFMRIyEzlsyQkhqaPm7IBCPTxMDXRf4tKkFYJHYZB0/6d1W4eI0meH079UqmSsh/uoDA==" - }, - "@serialport/parser-cctalk": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/@serialport/parser-cctalk/-/parser-cctalk-9.0.7.tgz", - "integrity": "sha512-ert5jhMkeiTfr44TkbdySC09J8UwAsf/RxBucVN5Mz5enG509RggnkfFi4mfj3UCG2vZ7qsmM6gtZ62DshY02Q==" - }, - "@serialport/parser-delimiter": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-9.0.7.tgz", - "integrity": "sha512-Vb2NPeXPZ/28M4m5x4OAHFd8jRAeddNCgvL+Q+H/hqFPY1w47JcMLchC7pigRW8Cnt1fklmzfwdNQ8Fb+kMkxQ==" - }, - "@serialport/parser-inter-byte-timeout": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/@serialport/parser-inter-byte-timeout/-/parser-inter-byte-timeout-9.0.7.tgz", - "integrity": "sha512-lUZ3cwgUluBvJ1jf+0LQsqoiPYAokDO6+fRCw9HCfnrF/OS60Gm4rxuyo2uQIueqZkJ7NIFP+ibKsULrA47AEA==" - }, - "@serialport/parser-readline": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-9.0.7.tgz", - "integrity": "sha512-ydoLbgVQQPxWrwbe3Fhh4XnZexbkEQAC6M/qgRTzjnKvTjrD61CJNxLc3vyDaAPI9bJIhTiI7eTX3JB5jJv8Hg==", - "requires": { - "@serialport/parser-delimiter": "^9.0.7" - } + "@serialport/bindings-interface": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@serialport/bindings-interface/-/bindings-interface-1.2.1.tgz", + "integrity": "sha512-63Dyqz2gtryRDDckFusOYqLYhR3Hq/M4sEdbF9i/VsvDb6T+tNVgoAKUZ+FMrXXKnCSu+hYbk+MTc0XQANszxw==" }, - "@serialport/parser-ready": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/@serialport/parser-ready/-/parser-ready-9.0.7.tgz", - "integrity": "sha512-3qYhI4cNUPAYqVYvdwV57Y+PVRl4dJf1fPBtMoWtwDgwopsAXTR93WCs49WuUq9JCyNW+8Hrfqv8x8eNAD5Dqg==" + "@serialport/parser-packet-length": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@serialport/parser-packet-length/-/parser-packet-length-10.2.2.tgz", + "integrity": "sha512-AEh/4pOoolUgCwg7ZW5M81isPjOhSf+Fq7OdyaR0GEHHrRgaY7ma2xkyp+sgjcYoeBzlxe3pPdi7LGtBJEFDnw==" }, - "@serialport/parser-regex": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/@serialport/parser-regex/-/parser-regex-9.0.7.tgz", - "integrity": "sha512-5XF+FXbhqQ/5bVKM4NaGs1m+E9KjfmeCx/obwsKaUZognQF67jwoTfjJJWNP/21jKfxdl8XoCYjZjASl3XKRAw==" + "@serialport/parser-slip-encoder": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@serialport/parser-slip-encoder/-/parser-slip-encoder-10.2.2.tgz", + "integrity": "sha512-cDJvco/exmQ7xgISVNbNb73r8l0j7eQDTVXxa8whUt8tdkf/J5y8jZLZgboh/iXbEcrNtohwUhIfb633NotNxg==" }, - "@serialport/stream": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/@serialport/stream/-/stream-9.0.7.tgz", - "integrity": "sha512-c/h7HPAeFiryD9iTGlaSvPqHFHSZ0NMQHxC4rcmKS2Vu3qJuEtkBdTLABwsMp7iWEiSnI4KC3s7bHapaXP06FQ==", - "requires": { - "debug": "^4.3.1" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } + "@serialport/parser-spacepacket": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@serialport/parser-spacepacket/-/parser-spacepacket-10.2.2.tgz", + "integrity": "sha512-TdfDYfIg41lXXuFsbdTZ2IHKhb3MgLJMMRhutoc/q6wX7LFhFD7FhdlkX3w85x15p1Et+iekGW5I/b48s47gXQ==" }, "@sindresorhus/is": { "version": "0.7.0", @@ -475,6 +394,12 @@ "@types/node": "*" } }, + "@types/strftime": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/@types/strftime/-/strftime-0.9.4.tgz", + "integrity": "sha512-MlicGsqGq8pVXa0umCVrYvno0bNUH/JYGPtlAvV/oU0/0lGtAVs/EtbDi6rz3241K3MF7+l6fuXxb9Ae3nLhJQ==", + "dev": true + }, "@types/uuid": { "version": "8.3.1", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.1.tgz", @@ -8370,7 +8295,9 @@ "nan": { "version": "2.14.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "dev": true, + "optional": true }, "nanomatch": { "version": "1.2.13", @@ -8426,13 +8353,18 @@ "dev": true }, "node-abi": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.26.0.tgz", - "integrity": "sha512-ag/Vos/mXXpWLLAYWsAoQdgS+gW7IwvgMLOgqopm/DbzAjazLltzgzpVMsFlgmo9TzG5hGXeaBZx2AI731RIsQ==", + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.1.tgz", + "integrity": "sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w==", "requires": { "semver": "^5.4.1" } }, + "node-addon-api": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" + }, "node-environment-flags": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", @@ -8462,6 +8394,11 @@ "which": "^1.3.1" } }, + "node-gyp-build": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", + "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==" + }, "node-libs-browser": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", @@ -8512,21 +8449,6 @@ } } }, - "node-usb-native": { - "version": "0.0.20", - "resolved": "https://registry.npmjs.org/node-usb-native/-/node-usb-native-0.0.20.tgz", - "integrity": "sha512-otQB1PegVUHzRS2iV+WrRm6VbDoPCF9gvEo5X3FzefP3MHXNqIbExVEwiLm/u2VDAF03lumddd3/I+DG4P7kxw==", - "requires": { - "glob": "^7.1.6", - "serialport": "^9.0.7", - "usb-detection": "^4.10.0" - } - }, - "noop-logger": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", - "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=" - }, "nopt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", @@ -9455,9 +9377,9 @@ "dev": true }, "prebuild-install": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.2.tgz", - "integrity": "sha512-PzYWIKZeP+967WuKYXlTOhYBgGOvTRSfaKI89XnfJ0ansRAH7hDU45X+K+FZeI1Wb/7p/NnuctPH3g0IqKUuSQ==", + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.4.tgz", + "integrity": "sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ==", "requires": { "detect-libc": "^1.0.3", "expand-template": "^2.0.3", @@ -9466,7 +9388,6 @@ "mkdirp-classic": "^0.5.3", "napi-build-utils": "^1.0.1", "node-abi": "^2.21.0", - "noop-logger": "^0.1.1", "npmlog": "^4.0.1", "pump": "^3.0.0", "rc": "^1.2.7", @@ -10122,27 +10043,86 @@ } }, "serialport": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/serialport/-/serialport-9.0.7.tgz", - "integrity": "sha512-NeDfVks3JAJ7s8cXDopx1iUUgC/7TaltE7iQGiSewIWMZaK7oStiz3VJzcuKgor7F+U/y6zbAnj4i6eHq0on+g==", - "requires": { - "@serialport/binding-mock": "^9.0.7", - "@serialport/bindings": "^9.0.7", - "@serialport/parser-byte-length": "^9.0.7", - "@serialport/parser-cctalk": "^9.0.7", - "@serialport/parser-delimiter": "^9.0.7", - "@serialport/parser-inter-byte-timeout": "^9.0.7", - "@serialport/parser-readline": "^9.0.7", - "@serialport/parser-ready": "^9.0.7", - "@serialport/parser-regex": "^9.0.7", - "@serialport/stream": "^9.0.7", - "debug": "^4.3.1" - }, - "dependencies": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/serialport/-/serialport-10.2.2.tgz", + "integrity": "sha512-yYp8UM915g8C3+lYZ7GU1Em1BnMeaH9c2bN2/A8ptQH5ttD7E+k9PuDEVOuyxONuyiBOp+vHfIPnje1evnslEw==", + "requires": { + "@serialport/binding-mock": "10.2.2", + "@serialport/bindings-cpp": "10.6.2", + "@serialport/parser-byte-length": "10.2.2", + "@serialport/parser-cctalk": "10.2.2", + "@serialport/parser-delimiter": "10.2.2", + "@serialport/parser-inter-byte-timeout": "10.2.2", + "@serialport/parser-packet-length": "10.2.2", + "@serialport/parser-readline": "10.2.2", + "@serialport/parser-ready": "10.2.2", + "@serialport/parser-regex": "10.2.2", + "@serialport/parser-slip-encoder": "10.2.2", + "@serialport/parser-spacepacket": "10.2.2", + "@serialport/stream": "10.2.2", + "debug": "^4.3.2" + }, + "dependencies": { + "@serialport/binding-mock": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@serialport/binding-mock/-/binding-mock-10.2.2.tgz", + "integrity": "sha512-HAFzGhk9OuFMpuor7aT5G1ChPgn5qSsklTFOTUX72Rl6p0xwcSVsRtG/xaGp6bxpN7fI9D/S8THLBWbBgS6ldw==", + "requires": { + "@serialport/bindings-interface": "^1.2.1", + "debug": "^4.3.3" + } + }, + "@serialport/parser-byte-length": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@serialport/parser-byte-length/-/parser-byte-length-10.2.2.tgz", + "integrity": "sha512-3xqaRbNiqDo8Gf1jPgrZr2nObKfAjhFihINZLJfPG7skWXfDKuF0zXuStzixre26N8GYWnkn4j/oEnI0RZjVDA==" + }, + "@serialport/parser-cctalk": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@serialport/parser-cctalk/-/parser-cctalk-10.2.2.tgz", + "integrity": "sha512-WK+82D10y+vL2Rv1Hs2MRNKeY18uVC0+eH9QCfD9e2o+4+jPHfN2boJQFxVGtrlss8j5DmQ5Sc5Qe6Ep+f20/Q==" + }, + "@serialport/parser-delimiter": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-10.2.2.tgz", + "integrity": "sha512-VsepMDIjbHbANMxH4IkXIJY0Tds8XsDo0mgtWK3DrV+IJGXp+2b0pHOuQlSLSfEUmdw7F5drI17fkxc9mxn+pg==" + }, + "@serialport/parser-inter-byte-timeout": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@serialport/parser-inter-byte-timeout/-/parser-inter-byte-timeout-10.2.2.tgz", + "integrity": "sha512-J9895aJ+3cHp2Q9qMH3UulfaifHDbDHjLPbO2H0vqjI8gZemL0DGql5ooFI6zsgJStXYT1MjqIhIb8dBIE0nxA==" + }, + "@serialport/parser-readline": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-10.2.2.tgz", + "integrity": "sha512-OcWoTsUJeLKWw+rdTuqXFZhii2liE6LeoFK2rtS6L00pB0cd2FGt2Rsx76oTCTyrub6AAUqaS9PRrAI+AUJJpg==", + "requires": { + "@serialport/parser-delimiter": "10.2.2" + } + }, + "@serialport/parser-ready": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@serialport/parser-ready/-/parser-ready-10.2.2.tgz", + "integrity": "sha512-Y5NA/kMb27afeFvSHhQ0Ov7PUt6vPSUqm7y+u6gajMpYOhKMjbLyQHuYMkgtGgk/PsryaOerd4OCVaYCEj0C+Q==" + }, + "@serialport/parser-regex": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@serialport/parser-regex/-/parser-regex-10.2.2.tgz", + "integrity": "sha512-+fAchSfl65Ix1BbyNPBu0SreZg2Tc2JJkvXsKsWFpoaOEsuxbCthrNmyvjt3AZ228pay6kKvF2PkRd/z+BFSfw==" + }, + "@serialport/stream": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@serialport/stream/-/stream-10.2.2.tgz", + "integrity": "sha512-xKO5f73KbqZYadKYbtlDHE5RUwqSK8dF2brQRA6dikeyHWbVNhjwNtjWglwgzPl4SLB1A1uT97hMxrBrSCs6/w==", + "requires": { + "@serialport/bindings-interface": "1.2.1", + "debug": "^4.3.2" + } + }, "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "requires": { "ms": "2.1.2" } @@ -10269,9 +10249,9 @@ "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" }, "simple-get": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", - "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", "requires": { "decompress-response": "^4.2.0", "once": "^1.3.1", @@ -10643,6 +10623,11 @@ "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", "dev": true }, + "strftime": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/strftime/-/strftime-0.9.2.tgz", + "integrity": "sha1-vMooYfKUVtNyqvaheBHIvG859YM=" + }, "strict-uri-encode": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", @@ -11588,14 +11573,14 @@ "dev": true }, "usb-detection": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/usb-detection/-/usb-detection-4.10.0.tgz", - "integrity": "sha512-YUzVWXwfSviE2pInXCKYXhR5heY9GUzlWsdZYxb/Br1Xela6P31A0KDHm7XW0Wsku1HwrokZx+/OD8cZSPHR3w==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/usb-detection/-/usb-detection-4.13.0.tgz", + "integrity": "sha512-5b0P+IYSN6Qv29hZ/m8P+iJyBDFYQR1UD8n4bWwPWbCIG6c2erQ9F8Owp69OSK0cwqf/InxYjIBuTVvl97bpZA==", "requires": { - "bindings": "^1.3.0", + "bindings": "^1.5.0", "eventemitter2": "^5.0.1", - "nan": "^2.13.2", - "prebuild-install": "^5.3.5" + "nan": "^2.15.0", + "prebuild-install": "^6.1.4" }, "dependencies": { "eventemitter2": { @@ -11603,27 +11588,10 @@ "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-5.0.1.tgz", "integrity": "sha1-YZegldX7a1folC9v1+qtY6CclFI=" }, - "prebuild-install": { - "version": "5.3.6", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.6.tgz", - "integrity": "sha512-s8Aai8++QQGi4sSbs/M1Qku62PFK49Jm1CbgXklGz4nmHveDq0wzJkg7Na5QbnO1uNH8K7iqx2EQ/mV0MZEmOg==", - "requires": { - "detect-libc": "^1.0.3", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^2.7.0", - "noop-logger": "^0.1.1", - "npmlog": "^4.0.1", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^3.0.3", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0", - "which-pm-runs": "^1.0.0" - } + "nan": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", + "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" } } }, @@ -12048,11 +12016,6 @@ "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", "dev": true }, - "which-pm-runs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=" - }, "wide-align": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", diff --git a/package.json b/package.json index b2aaae08..19b6ff00 100644 --- a/package.json +++ b/package.json @@ -587,7 +587,7 @@ }, "scripts": { "vscode:prepublish": "gulp build --mode=production", - "postinstall": "cd ./src/views && npm install && node ../../node_modules/node-usb-native/scripts/rebuild-serialport.js", + "postinstall": "cd ./src/views && npm install", "test": "gulp test" }, "extensionDependencies": [ @@ -599,6 +599,7 @@ "@types/glob": "^7.1.4", "@types/mocha": "^5.2.7", "@types/node": "^16.9.6", + "@types/strftime": "^0.9.2", "@types/uuid": "^8.3.1", "@types/vscode": "^1.43.0", "@types/winreg": "^1.2.30", @@ -642,8 +643,10 @@ "glob": "^7.1.1", "iconv-lite": "^0.4.18", "impor": "^0.1.1", - "node-usb-native": "^0.0.20", "properties": "^1.2.1", + "serialport": "^10.2.2", + "strftime": "^0.9.2", + "usb-detection": "^4.13.0", "uuid": "^3.0.1", "vscode-extension-telemetry": "0.1.6", "winreg": "^1.2.3", diff --git a/src/debug/debuggerManager.ts b/src/debug/debuggerManager.ts index 1c9e81f0..5546e8dd 100644 --- a/src/debug/debuggerManager.ts +++ b/src/debug/debuggerManager.ts @@ -43,7 +43,10 @@ export class DebuggerManager { } } } - this._usbDetector = require("node-usb-native").detector; + // For anyone looking at blame history, I doubt this import works as-is. + // I swapped it out for the old import to remove dependency on "node-usb-native", + // but otherwise anything that was broken before is still broken. + this._usbDetector = require("usb-detection"); this._debugServerPath = platform.findFile(platform.getExecutableFileName("openocd"), path.join(this._arduinoSettings.packagePath, "packages")); if (!util.fileExistsSync(this._debugServerPath)) { diff --git a/src/serialmonitor/serialportctrl.ts b/src/serialmonitor/serialportctrl.ts index 47217c87..0ab29af1 100644 --- a/src/serialmonitor/serialportctrl.ts +++ b/src/serialmonitor/serialportctrl.ts @@ -1,16 +1,14 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. -import { ChildProcess, execFileSync, spawn } from "child_process"; import * as os from "os"; -import * as path from "path"; -import { DeviceContext } from "../deviceContext"; +import { SerialPort } from "serialport"; +import * as strftime from "strftime"; import { BufferedOutputChannel } from "./outputBuffer"; interface ISerialPortDetail { port: string; desc: string; - hwid: string; vendorId: string; productId: string; } @@ -18,50 +16,25 @@ interface ISerialPortDetail { export class SerialPortCtrl { /** - * Launches the serial monitor to check which external usb devices are connected. + * Check which external serial devices are connected. * * @returns An array of ISerialPortDetail from external serial devices. * */ - public static list(): Promise { - // TODO: Wrap this in a try catch block, catch error if no serial monitor at path - const stdout = execFileSync(SerialPortCtrl._serialCliPath, ["list-ports"]); - const lists = JSON.parse(stdout.toString("utf-8")); - lists.forEach((port) => { - const vidPid = this._parseVidPid(port["hwid"]); - port["vendorId"] = vidPid["vid"]; - port["productId"] = vidPid["pid"]; + public static async list(): Promise { + return (await SerialPort.list()).map((port) => { + return { + port: port.path, + desc: (port as any).friendlyName ?? port.manufacturer, + vendorId: port.vendorId, + productId: port.productId, + }; }); - return lists; } - /** - * Parse out vendor id and product id from the hardware id provided by the device. - * - * @param hwid: The hardware information for a sepcific device - * - * @returns vendor id and product id values in an array. Returns null if none are found. - */ - private static _parseVidPid(hwid: string): any { - const result = hwid.match(/VID:PID=(?\w+):(?\w+)/i); - return result !== null ? result["groups"] : [null, null]; - } - - private static get _serialCliPath(): string { - let fileName: string; - if (os.platform() === "win32") { - fileName = "main.exe" - } else if (os.platform() === "linux" || os.platform() === "darwin") { - fileName = "main.out" - } - const deviceContext = DeviceContext.getInstance(); - return path.resolve(deviceContext.extensionPath, "out", "serial-monitor-cli", `${os.platform}`, fileName); - } - - private _child: ChildProcess; + private _port?: SerialPort; private _currentPort: string; private _currentBaudRate: number; - private _currentSerialPort = null; private _currentTimestampFormat: string; public constructor( @@ -75,47 +48,51 @@ export class SerialPortCtrl { this._currentTimestampFormat = timestampFormat; } - /* - * Return true if child proccess is currently running - */ public get isActive(): boolean { - return this._child ? true : false; + return this._port?.isOpen ?? false; } public get currentPort(): string { return this._currentPort; } - public open(): Promise { + public async open(): Promise { this._bufferedOutputChannel.appendLine(`[Starting] Opening the serial port - ${this._currentPort}`); this.showOutputChannel(); - if (this._child) { - this.stop(); - } - - return new Promise((resolve, reject) => { - this._child = spawn(SerialPortCtrl._serialCliPath, - ["open", this._currentPort, "-b", this._currentBaudRate.toString(), "-t", this._currentTimestampFormat, "--json"]) + if (this.isActive) { await this.close(); } - this._child.on("error", (err) => { - reject(err) + await new Promise((resolve, reject) => { + this._port = new SerialPort( + { autoOpen: false, path: this._currentPort, baudRate: this._currentBaudRate }, + (err) => { + if (err) { reject(err); } }); + this._port.open((err) => { + if (err) { + reject(err); + } else { + resolve(); + } + }); + }); - this._child.stdout.on("data", (data) => { - if (this.isActive) { - const jsonObj = JSON.parse(data.toString()) - this._bufferedOutputChannel.append(jsonObj["timestamp"] + jsonObj["payload"]); - } - }); - // TODO: add message check to ensure _child spawned without errors - resolve(); - // The spawn event is only supported in node v15+ vscode - // this._child.on("spawn", (spawn) => { - // resolve(); - // }); - - }); + let lastDataEndedWithNewline = true; + this._port.on("data", (data) => { + const text: string = data.toString("utf8"); + if (this._currentTimestampFormat) { + const timestamp = strftime(this._currentTimestampFormat); + this._bufferedOutputChannel.append( + // Timestamps should only be added at the beginning of a line. + // Look for newlines except at the very end of the string. + (lastDataEndedWithNewline ? timestamp : "") + + text.replace(/\n(?!$)/g, "\n" + timestamp), + ); + lastDataEndedWithNewline = text.endsWith("\n"); + } else { + this._bufferedOutputChannel.append(text); + } + }); } public sendMessage(text: string): Promise { @@ -124,7 +101,7 @@ export class SerialPortCtrl { resolve(); return; } - this._child.stdin.write(`{"cmd": "write", "payload": "${text}"}\n`, (error) => { + this._port.write(text + "\n", (error) => { if (!error) { resolve(); } else { @@ -134,80 +111,45 @@ export class SerialPortCtrl { }); } - public changePort(newPort: string): Promise { - return new Promise((resolve, reject) => { - if (newPort === this._currentPort) { - resolve(); - return; - } - this._currentPort = newPort; - if (!this._currentSerialPort || !this.isActive) { - resolve(); - return; - } - this._currentSerialPort.close((err) => { - if (err) { - reject(err); - } else { - this._currentSerialPort = null; - resolve(); - } - }); - }); + public async changePort(newPort: string): Promise { + if (newPort === this._currentPort) { return; } + this._currentPort = newPort; + if (!this.isActive) { return; } + await this.close(); } - public stop(): Promise { - return new Promise((resolve, reject) => { - if (!this.isActive) { - resolve(false); - return; - } - try { - this._child.stdin.write('{"cmd": "close"}\n'); - if (this._bufferedOutputChannel) { - this._bufferedOutputChannel.appendLine(`[Done] Closed the serial port ${os.EOL}`); - } - this._child = null; - resolve(true); - } catch (error) { - reject(error); - } - }); + public async stop(): Promise { + if (!this.isActive) { return false; } + + await this.close(); + if (this._bufferedOutputChannel) { + this._bufferedOutputChannel.appendLine(`[Done] Closed the serial port ${os.EOL}`); + } + + return true; } - public changeBaudRate(newRate: number): Promise { - return new Promise((resolve, reject) => { - this._currentBaudRate = newRate; - if (!this._child || !this.isActive) { - resolve(); - return; - } else { - try { - this.stop(); - this.open(); - resolve(); - } catch (error) { - reject(error); - } - } - }); + public async changeBaudRate(newRate: number): Promise { + this._currentBaudRate = newRate; + if (!this.isActive) { return; } + await this.stop(); + await this.open(); + } + + public async changeTimestampFormat(newTimestampFormat: string): Promise { + this._currentTimestampFormat = newTimestampFormat; } - public changeTimestampFormat(newTimestampFormat: string): Promise { + private close(): Promise { return new Promise((resolve, reject) => { - this._currentTimestampFormat = newTimestampFormat; - if (!this._child || !this.isActive) { - resolve(); - return; - } else { - try { - this.stop(); - this.open(); - resolve(); - } catch (error) { - reject(error); - } + this._port.close((err) => { + if (err) { + reject(err); + } else { + this._port = undefined; + resolve(); } + }) }); } } diff --git a/src/serialmonitor/usbDetector.ts b/src/serialmonitor/usbDetector.ts index a5b71a96..9e1ec165 100644 --- a/src/serialmonitor/usbDetector.ts +++ b/src/serialmonitor/usbDetector.ts @@ -47,7 +47,7 @@ export class UsbDetector { if (os.platform() === "linux" || !enableUSBDetection) { return; } - this._usbDetector = require("node-usb-native").detector; + this._usbDetector = require("usb-detection"); if (!this._usbDetector) { return; diff --git a/test/runTest.ts b/test/runTest.ts index 6ef6495f..435fd815 100644 --- a/test/runTest.ts +++ b/test/runTest.ts @@ -15,9 +15,11 @@ async function main() { // Running tests on the specific workspace const testWorkspace = path.resolve(__dirname, "../../test/resources/blink") // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath , launchArgs: [testWorkspace]}); + // Tests pass on 1.64 pass but then VS Code itself mysteriously exits + // with code 0xDEAD. Pin to an older version for now. + await runTests({ extensionDevelopmentPath, extensionTestsPath, version: "1.63.2", launchArgs: [testWorkspace]}); } catch (err) { - // console.error("Failed to run tests"); + // console.error("Failed to run tests", err); process.exit(1); } } diff --git a/webpack.config.js b/webpack.config.js index b18b814a..64cbd8a8 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -12,16 +12,21 @@ function getEntry() { const mod = JSON.parse(npmListRes); const unbundledModule = ['impor', 'uuid', // usb-native modules can not be bundled - 'node-usb-native', 'usb-detection', '@serialport/bindings', 'bindings', 'serialport']; + 'usb-detection', '@serialport', 'bindings', 'serialport']; for (const mod of unbundledModule) { const p = 'node_modules/' + mod; fs.copySync(p, 'out/node_modules/' + mod); } + // The nan module is nested inside usb-detection, so it was already copied. + const noEntryModules = unbundledModule.concat(['nan']); const list = getDependenciesFromNpm(mod); const moduleList = list.filter((value, index, self) => { - return self.indexOf(value) === index && unbundledModule.indexOf(value) === -1 && !/^@types\//.test(value); + // Some entries in the list of unbundled modules are really namespaces, so + // we do a prefix match to see if the module should be excluded. This isn't + // perfect, but works for the set of modules we care about. + return self.indexOf(value) === index && noEntryModules.filter(m => value.startsWith(m)).length === 0 && !/^@types\//.test(value); }); for (const mod of moduleList) { @@ -56,7 +61,8 @@ const config = { devtoolModuleFilenameTemplate: "../[resource-path]", }, externals: { - vscode: "commonjs vscode" + vscode: "commonjs vscode", + serialport: "serialport" }, resolve: { extensions: ['.js', '.json']