diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 87dc38e0..2d4f632c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: - node-version: 12 + node-version: 14 - run: npm ci - name: Publish to Visual Studio Marketplace id: publishToVSMarketplace diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bbcea430..d1b29546 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -23,7 +23,7 @@ jobs: - name: Install Node.js uses: actions/setup-node@v1 with: - node-version: 10.x + node-version: 14 - name: Ensure there is a supported ghc versions uses: haskell/actions/setup@v1 with: @@ -40,4 +40,12 @@ jobs: with: name: extension-${{ matrix.os }}.log path: test-workspace/hls.log - + - name: Package tested extension + if: runner.os == 'Linux' + run: npx vsce package + - name: Upload extension vsix to workflow artifacts + if: runner.os == 'Linux' + uses: actions/upload-artifact@v2 + with: + name: haskell-${{ github.sha }}.vsix + path: haskell-*.vsix diff --git a/package-lock.json b/package-lock.json index a614385e..6db359a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "request": "^2.88.2", "request-promise-native": "^1.0.8", "vscode-languageclient": "^7.0.0", + "which": "^2.0.1", "yauzl": "^2.10.0" }, "devDependencies": { @@ -29,13 +30,14 @@ "@types/node": "^14.0.3", "@types/request-promise-native": "^1.0.17", "@types/vscode": "^1.52.0", + "@types/which": "^2.0.1", "@types/yauzl": "^2.9.1", "@vscode/test-electron": "^1.6.2", "glob": "^7.1.4", "husky": "^7.0.2", "mocha": "^9.1.2", - "prettier": "^2.0.5", - "pretty-quick": "^2.0.1", + "prettier": "^2.5.1", + "pretty-quick": "^3.1.2", "set-value": ">=4.0.1", "ts-loader": "^6.2.2", "tslint": "^5.20.1", @@ -221,6 +223,12 @@ "integrity": "sha512-wZt3VTmzYrgZ0l/3QmEbCq4KAJ71K3/hmMQ/nfpv84oH8e81KKwPEoQ5v8dNCxfHFVJ1JabHKmCvqdYOoVm1Ow==", "dev": true }, + "node_modules/@types/which": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/which/-/which-2.0.1.tgz", + "integrity": "sha512-Jjakcv8Roqtio6w1gr0D7y6twbhx6gGgFGF5BLwajPpnOIOxFkakFhCq+LmyyeAz7BX6ULrjBOxdKaCDy+4+dQ==", + "dev": true + }, "node_modules/@types/yauzl": { "version": "2.9.1", "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz", @@ -1376,62 +1384,35 @@ } }, "node_modules/execa": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-2.1.0.tgz", - "integrity": "sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", "dev": true, "dependencies": { "cross-spawn": "^7.0.0", "get-stream": "^5.0.0", + "human-signals": "^1.1.1", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", - "npm-run-path": "^3.0.0", + "npm-run-path": "^4.0.0", "onetime": "^5.1.0", - "p-finally": "^2.0.0", "signal-exit": "^3.0.2", "strip-final-newline": "^2.0.0" }, "engines": { - "node": "^8.12.0 || >=9.7.0" - } - }, - "node_modules/execa/node_modules/is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/execa/node_modules/npm-run-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz", - "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==", - "dev": true, - "dependencies": { - "path-key": "^3.0.0" + "node": ">=10" }, - "engines": { - "node": ">=8" - } - }, - "node_modules/execa/node_modules/p-finally": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", - "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==", - "dev": true, - "engines": { - "node": ">=8" + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/execa/node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "node_modules/execa/node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", "dev": true, "engines": { - "node": ">=8" + "node": ">=8.12.0" } }, "node_modules/extend": { @@ -1581,15 +1562,18 @@ } }, "node_modules/get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "dependencies": { "pump": "^3.0.0" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/getpass": { @@ -1941,8 +1925,7 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "node_modules/isobject": { "version": "3.0.1", @@ -2653,15 +2636,18 @@ } }, "node_modules/onetime": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", - "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "dependencies": { "mimic-fn": "^2.1.0" }, "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-limit": { @@ -2781,9 +2767,9 @@ } }, "node_modules/prettier": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", - "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", + "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", "dev": true, "bin": { "prettier": "bin-prettier.js" @@ -2793,26 +2779,93 @@ } }, "node_modules/pretty-quick": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-2.0.1.tgz", - "integrity": "sha512-y7bJt77XadjUr+P1uKqZxFWLddvj3SKY6EU4BuQtMxmmEFSMpbN132pUWdSG1g1mtUfO0noBvn7wBf0BVeomHg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.1.2.tgz", + "integrity": "sha512-T+fpTJrDjTzewql4p3lKrRA7z3MrNyjBK1MKeaBm5PpKwATgVm885TpY7TgY8KFt5Q1Qn3QDseRQcyX9AKTKkA==", "dev": true, "dependencies": { - "chalk": "^2.4.2", - "execa": "^2.1.0", + "chalk": "^3.0.0", + "execa": "^4.0.0", "find-up": "^4.1.0", "ignore": "^5.1.4", - "mri": "^1.1.4", + "mri": "^1.1.5", "multimatch": "^4.0.0" }, "bin": { "pretty-quick": "bin/pretty-quick.js" }, "engines": { - "node": ">=8" + "node": ">=10.13" }, "peerDependencies": { - "prettier": ">=1.8.0" + "prettier": ">=2.0.0" + } + }, + "node_modules/pretty-quick/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/pretty-quick/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pretty-quick/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/pretty-quick/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/pretty-quick/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pretty-quick/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, "node_modules/process-nextick-args": { @@ -3136,9 +3189,9 @@ } }, "node_modules/signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", + "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", "dev": true }, "node_modules/source-map": { @@ -3803,27 +3856,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/webpack-cli/node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/webpack-cli/node_modules/signal-exit": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.4.tgz", - "integrity": "sha512-rqYhcAnZ6d/vTPGghdrw7iumdcbXpsk1b8IG/rz+VWV51DM0p7XCtMoJ3qhPLIbp3tvyt3pKRbaaEMZYpHto8Q==", - "dev": true - }, "node_modules/webpack-merge": { "version": "5.8.0", "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", @@ -3899,7 +3931,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -4224,6 +4255,12 @@ "integrity": "sha512-wZt3VTmzYrgZ0l/3QmEbCq4KAJ71K3/hmMQ/nfpv84oH8e81KKwPEoQ5v8dNCxfHFVJ1JabHKmCvqdYOoVm1Ow==", "dev": true }, + "@types/which": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/which/-/which-2.0.1.tgz", + "integrity": "sha512-Jjakcv8Roqtio6w1gr0D7y6twbhx6gGgFGF5BLwajPpnOIOxFkakFhCq+LmyyeAz7BX6ULrjBOxdKaCDy+4+dQ==", + "dev": true + }, "@types/yauzl": { "version": "2.9.1", "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz", @@ -5140,47 +5177,26 @@ "dev": true }, "execa": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-2.1.0.tgz", - "integrity": "sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", "dev": true, "requires": { "cross-spawn": "^7.0.0", "get-stream": "^5.0.0", + "human-signals": "^1.1.1", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", - "npm-run-path": "^3.0.0", + "npm-run-path": "^4.0.0", "onetime": "^5.1.0", - "p-finally": "^2.0.0", "signal-exit": "^3.0.2", "strip-final-newline": "^2.0.0" }, "dependencies": { - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "dev": true - }, - "npm-run-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz", - "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==", - "dev": true, - "requires": { - "path-key": "^3.0.0" - } - }, - "p-finally": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", - "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", "dev": true } } @@ -5300,9 +5316,9 @@ "dev": true }, "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "requires": { "pump": "^3.0.0" @@ -5558,8 +5574,7 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "isobject": { "version": "3.0.1", @@ -6107,9 +6122,9 @@ } }, "onetime": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", - "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "requires": { "mimic-fn": "^2.1.0" @@ -6202,23 +6217,74 @@ } }, "prettier": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", - "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", + "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", "dev": true }, "pretty-quick": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-2.0.1.tgz", - "integrity": "sha512-y7bJt77XadjUr+P1uKqZxFWLddvj3SKY6EU4BuQtMxmmEFSMpbN132pUWdSG1g1mtUfO0noBvn7wBf0BVeomHg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.1.2.tgz", + "integrity": "sha512-T+fpTJrDjTzewql4p3lKrRA7z3MrNyjBK1MKeaBm5PpKwATgVm885TpY7TgY8KFt5Q1Qn3QDseRQcyX9AKTKkA==", "dev": true, "requires": { - "chalk": "^2.4.2", - "execa": "^2.1.0", + "chalk": "^3.0.0", + "execa": "^4.0.0", "find-up": "^4.1.0", "ignore": "^5.1.4", - "mri": "^1.1.4", + "mri": "^1.1.5", "multimatch": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "process-nextick-args": { @@ -6471,9 +6537,9 @@ } }, "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", + "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", "dev": true }, "source-map": { @@ -6996,21 +7062,6 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "signal-exit": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.4.tgz", - "integrity": "sha512-rqYhcAnZ6d/vTPGghdrw7iumdcbXpsk1b8IG/rz+VWV51DM0p7XCtMoJ3qhPLIbp3tvyt3pKRbaaEMZYpHto8Q==", - "dev": true } } }, @@ -7034,7 +7085,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "requires": { "isexe": "^2.0.0" } diff --git a/package.json b/package.json index a7d47476..4f888dc1 100644 --- a/package.json +++ b/package.json @@ -398,13 +398,14 @@ "@types/node": "^14.0.3", "@types/request-promise-native": "^1.0.17", "@types/vscode": "^1.52.0", + "@types/which": "^2.0.1", "@types/yauzl": "^2.9.1", "@vscode/test-electron": "^1.6.2", "glob": "^7.1.4", "husky": "^7.0.2", "mocha": "^9.1.2", - "prettier": "^2.0.5", - "pretty-quick": "^2.0.1", + "prettier": "^2.5.1", + "pretty-quick": "^3.1.2", "set-value": ">=4.0.1", "ts-loader": "^6.2.2", "tslint": "^5.20.1", @@ -425,6 +426,7 @@ "request": "^2.88.2", "request-promise-native": "^1.0.8", "vscode-languageclient": "^7.0.0", + "which": "^2.0.1", "yauzl": "^2.10.0" } } diff --git a/src/extension.ts b/src/extension.ts index 619fa625..2fa49d8d 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -23,7 +23,7 @@ import { CommandNames } from './commands/constants'; import { ImportIdentifier } from './commands/importIdentifier'; import { DocsBrowser } from './docsBrowser'; import { downloadHaskellLanguageServer } from './hlsBinaries'; -import { directoryExists, executableExists, ExtensionLogger, resolvePathPlaceHolders } from './utils'; +import { directoryExists, executableExists, expandHomeDir, ExtensionLogger, resolvePathPlaceHolders } from './utils'; // Used for environment variables later on interface IEnvVars { @@ -171,11 +171,11 @@ async function activateServerForFolder(context: ExtensionContext, uri: Uri, fold const logLevel = workspace.getConfiguration('haskell', uri).trace.server; const clientLogLevel = workspace.getConfiguration('haskell', uri).trace.client; - const logFile = workspace.getConfiguration('haskell', uri).logFile; + const logFile: string = workspace.getConfiguration('haskell', uri).logFile; const outputChannel: OutputChannel = window.createOutputChannel(langName); - const logFilePath = logFile ? path.resolve(currentWorkingDir, logFile) : undefined; + const logFilePath = logFile !== '' ? path.resolve(currentWorkingDir, expandHomeDir(logFile)) : undefined; const logger: Logger = new ExtensionLogger('client', clientLogLevel, outputChannel, logFilePath); if (logFilePath) { logger.info(`Writing client log to file ${logFilePath}`); diff --git a/src/utils.ts b/src/utils.ts index 924cbaa0..15f91a6f 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -10,6 +10,7 @@ import * as url from 'url'; import { promisify } from 'util'; import { OutputChannel, ProgressLocation, window, WorkspaceFolder } from 'vscode'; import { Logger } from 'vscode-languageclient'; +import * as which from 'which'; import * as yazul from 'yauzl'; import { createGunzip } from 'zlib'; @@ -18,7 +19,7 @@ enum LogLevel { Error, Warn, Info, - Debug + Debug, } export class ExtensionLogger implements Logger { public readonly name: string; @@ -52,7 +53,7 @@ export class ExtensionLogger implements Logger { let now = new Date(); // Ugly hack to make js date iso format similar to hls one const offset = now.getTimezoneOffset(); - now = new Date(now.getTime() - (offset * 60 * 1000)); + now = new Date(now.getTime() - offset * 60 * 1000); const timedMsg = `${new Date().toISOString().replace('T', ' ').replace('Z', '0000')} ${msg}`; this.channel.appendLine(timedMsg); if (this.logFile) { @@ -161,87 +162,90 @@ export async function downloadFile(titleMsg: string, src: string, dest: string): fs.unlinkSync(downloadDest); } - const downloadTask = window.withProgress( - { - location: ProgressLocation.Notification, - title: titleMsg, - cancellable: false, - }, - async (progress) => { - const p = new Promise((resolve, reject) => { - const srcUrl = url.parse(src); - const opts: https.RequestOptions = { - host: srcUrl.host, - path: srcUrl.path, - protocol: srcUrl.protocol, - port: srcUrl.port, - headers: userAgentHeader, - }; - getWithRedirects(opts, (res) => { - const totalSize = parseInt(res.headers['content-length'] || '1', 10); - const fileStream = fs.createWriteStream(downloadDest, { mode: 0o744 }); - let curSize = 0; + const downloadTask = window + .withProgress( + { + location: ProgressLocation.Notification, + title: titleMsg, + cancellable: false, + }, + async (progress) => { + const p = new Promise((resolve, reject) => { + const srcUrl = url.parse(src); + const opts: https.RequestOptions = { + host: srcUrl.host, + path: srcUrl.path, + protocol: srcUrl.protocol, + port: srcUrl.port, + headers: userAgentHeader, + }; + getWithRedirects(opts, (res) => { + const totalSize = parseInt(res.headers['content-length'] || '1', 10); + const fileStream = fs.createWriteStream(downloadDest, { mode: 0o744 }); + let curSize = 0; - // Decompress it if it's a gzip or zip - const needsGunzip = - res.headers['content-type'] === 'application/gzip' || extname(srcUrl.path ?? '') === '.gz'; - const needsUnzip = res.headers['content-type'] === 'application/zip' || extname(srcUrl.path ?? '') === '.zip'; - if (needsGunzip) { - const gunzip = createGunzip(); - gunzip.on('error', reject); - res.pipe(gunzip).pipe(fileStream); - } else if (needsUnzip) { - const zipDest = downloadDest + '.zip'; - const zipFs = fs.createWriteStream(zipDest); - zipFs.on('error', reject); - zipFs.on('close', () => { - yazul.open(zipDest, (err, zipfile) => { - if (err) { - throw err; - } - if (!zipfile) { - throw Error("Couldn't decompress zip"); - } + // Decompress it if it's a gzip or zip + const needsGunzip = + res.headers['content-type'] === 'application/gzip' || extname(srcUrl.path ?? '') === '.gz'; + const needsUnzip = + res.headers['content-type'] === 'application/zip' || extname(srcUrl.path ?? '') === '.zip'; + if (needsGunzip) { + const gunzip = createGunzip(); + gunzip.on('error', reject); + res.pipe(gunzip).pipe(fileStream); + } else if (needsUnzip) { + const zipDest = downloadDest + '.zip'; + const zipFs = fs.createWriteStream(zipDest); + zipFs.on('error', reject); + zipFs.on('close', () => { + yazul.open(zipDest, (err, zipfile) => { + if (err) { + throw err; + } + if (!zipfile) { + throw Error("Couldn't decompress zip"); + } - // We only expect *one* file inside each zip - zipfile.on('entry', (entry: yazul.Entry) => { - zipfile.openReadStream(entry, (err2, readStream) => { - if (err2) { - throw err2; - } - readStream?.pipe(fileStream); + // We only expect *one* file inside each zip + zipfile.on('entry', (entry: yazul.Entry) => { + zipfile.openReadStream(entry, (err2, readStream) => { + if (err2) { + throw err2; + } + readStream?.pipe(fileStream); + }); }); }); }); - }); - res.pipe(zipFs); - } else { - res.pipe(fileStream); - } + res.pipe(zipFs); + } else { + res.pipe(fileStream); + } - function toMB(bytes: number) { - return bytes / (1024 * 1024); - } + function toMB(bytes: number) { + return bytes / (1024 * 1024); + } - res.on('data', (chunk: Buffer) => { - curSize += chunk.byteLength; - const msg = `${toMB(curSize).toFixed(1)}MB / ${toMB(totalSize).toFixed(1)}MB`; - progress.report({ message: msg, increment: (chunk.length / totalSize) * 100 }); - }); - res.on('error', reject); - fileStream.on('close', resolve); - }).on('error', reject); - }); - try { - await p; - // Finally rename it to the actual dest - fs.renameSync(downloadDest, dest); - } finally { - // And remember to remove it from the list of current downloads - inFlightDownloads.get(src)?.delete(dest); + res.on('data', (chunk: Buffer) => { + curSize += chunk.byteLength; + const msg = `${toMB(curSize).toFixed(1)}MB / ${toMB(totalSize).toFixed(1)}MB`; + progress.report({ message: msg, increment: (chunk.length / totalSize) * 100 }); + }); + res.on('error', reject); + fileStream.on('close', resolve); + }).on('error', reject); + }); + try { + await p; + // Finally rename it to the actual dest + fs.renameSync(downloadDest, dest); + } finally { + // And remember to remove it from the list of current downloads + inFlightDownloads.get(src)?.delete(dest); + } } - } - ).then(_ => true); + ) + .then((_) => true); try { if (inFlightDownloads.has(src)) { @@ -277,15 +281,18 @@ export function executableExists(exe: string): boolean { const isWindows = process.platform === 'win32'; const cmd: string = isWindows ? 'where' : 'which'; const out = child_process.spawnSync(cmd, [exe]); - return out.status === 0 || (isWindows && fileExists(exe)); + return out.status === 0 || (which.sync(exe, { nothrow: true }) ?? '') !== ''; } export function directoryExists(path: string): boolean { return fs.existsSync(path) && fs.lstatSync(path).isDirectory(); } -function fileExists(path: string): boolean { - return fs.existsSync(path) && fs.lstatSync(path).isFile(); +export function expandHomeDir(path: string): string { + if (path.startsWith('~')) { + return path.replace('~', os.homedir); + } + return path; } export function resolvePathPlaceHolders(path: string, folder?: WorkspaceFolder) { diff --git a/test/suite/extension.test.ts b/test/suite/extension.test.ts index 8fe6d8f6..2edbfd77 100644 --- a/test/suite/extension.test.ts +++ b/test/suite/extension.test.ts @@ -132,7 +132,7 @@ suite('Extension Test Suite', () => { test('Extension log should have server output', async () => { await vscode.workspace.openTextDocument(getWorkspaceFile('Main.hs')); - await delay(10); + await delay(20); const logContents = getExtensionLogContent(); assert.ok(logContents, 'Extension log file does not exist'); assert.match(logContents, /INFO hls:\s+Registering ide configuration/, 'Extension log file has no hls output');