diff --git a/.github/workflows/validate_pull_request.yml b/.github/workflows/validate_pull_request.yml index 96c3a0467..bc5572225 100644 --- a/.github/workflows/validate_pull_request.yml +++ b/.github/workflows/validate_pull_request.yml @@ -32,27 +32,3 @@ jobs: dotnet-version: '6.0.x' - run: | dotnet build Src/CSharpier.MsBuild/CSharpier.MsBuild.csproj -# run_vscode_tests: -# runs-on: ${{ matrix.os }} -# strategy: -# matrix: -# os: [ ubuntu-latest ] #, windows-latest, macos-latest ] -# name: Test VSCode on ${{ matrix.os }} -# steps: -# - uses: actions/checkout@v2 -# - uses: actions/setup-node@v2 -# with: -# node-version: "14" -# - run: /usr/bin/Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & echo "Started xvfb" -# shell: bash -# if: ${{ success() && matrix.os == 'ubuntu-latest' }} -# - uses: actions/setup-dotnet@v1 -# with: -# dotnet-version: '6.0.x' -# - run: | -# dotnet build CSharpier.sln -c release -# cd Src/CSharpier.VSCode -# npm ci -# npm test -# env: -# DISPLAY: ":99.0" diff --git a/Src/CSharpier.VSCode/CHANGELOG.md b/Src/CSharpier.VSCode/CHANGELOG.md new file mode 100644 index 000000000..df36db98a --- /dev/null +++ b/Src/CSharpier.VSCode/CHANGELOG.md @@ -0,0 +1,25 @@ +## [1.1.0] + +- Support local version of csharpier +- Support multiple versions of csharpier in the same workspace +- Auto close csharpier process so that it can be updated while vscode is running + +## [1.0.4] + +- Update readme + +## [1.0.3] + +- New logo + +## [1.0.2] + +- Fix bug with long files sometimes losing content + +## [1.0.1] + +- Fix bug with ignored files + +## [1.0.0] + +- Initial release diff --git a/Src/CSharpier.VSCode/CONTRIBUTING.md b/Src/CSharpier.VSCode/CONTRIBUTING.md index 00dab21bc..847c7f16c 100644 --- a/Src/CSharpier.VSCode/CONTRIBUTING.md +++ b/Src/CSharpier.VSCode/CONTRIBUTING.md @@ -1 +1,10 @@ +npm run start +then start extension from vscode +ctrl r to reload window (Developer: Reload Window) + https://code.visualstudio.com/api/working-with-extensions/publishing-extension + +vsce package +vsce publish + +https://marketplace.visualstudio.com/manage/publishers/csharpier diff --git a/Src/CSharpier.VSCode/README.md b/Src/CSharpier.VSCode/README.md index 379a2e6bb..553ec9134 100644 --- a/Src/CSharpier.VSCode/README.md +++ b/Src/CSharpier.VSCode/README.md @@ -41,6 +41,4 @@ You can turn on format-on-save on a per-language basis by scoping the setting: ## Limitations -This extension currently only works with a globally installed version of csharpier. See [this issue](https://github.com/belav/csharpier/issues/493) for details. - Format Selection is not supported. diff --git a/Src/CSharpier.VSCode/icon.png b/Src/CSharpier.VSCode/icon.png deleted file mode 100644 index 2866f8235..000000000 Binary files a/Src/CSharpier.VSCode/icon.png and /dev/null differ diff --git a/Src/CSharpier.VSCode/logo.png b/Src/CSharpier.VSCode/logo.png new file mode 100644 index 000000000..8aa790888 Binary files /dev/null and b/Src/CSharpier.VSCode/logo.png differ diff --git a/Src/CSharpier.VSCode/package-lock.json b/Src/CSharpier.VSCode/package-lock.json index 742c7d45c..0bf9ac87e 100644 --- a/Src/CSharpier.VSCode/package-lock.json +++ b/Src/CSharpier.VSCode/package-lock.json @@ -1,6 +1,6 @@ { "name": "csharpier-vscode", - "version": "1.0.3", + "version": "1.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -10,18 +10,6 @@ "integrity": "sha512-6nFkfkmSeV/rqSaS4oWHgmpnYw194f6hmWF5is6b0J1naJZoiD0NTc9AiUwPHvWsowkjuHErCZT1wa0jg+BLIA==", "dev": true }, - "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true - }, - "@types/command-exists": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/command-exists/-/command-exists-1.2.0.tgz", - "integrity": "sha512-ugsxEJfsCuqMLSuCD4PIJkp5Uk2z6TCMRCgYVuhRo5cYQY3+1xXTQkSlPtkpGHuvWMjS2KTeVQXxkXRACMbM6A==", - "dev": true - }, "@types/eslint": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.2.0.tgz", @@ -94,24 +82,6 @@ "integrity": "sha512-wZt3VTmzYrgZ0l/3QmEbCq4KAJ71K3/hmMQ/nfpv84oH8e81KKwPEoQ5v8dNCxfHFVJ1JabHKmCvqdYOoVm1Ow==", "dev": true }, - "@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, - "@vscode/test-electron": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-1.6.2.tgz", - "integrity": "sha512-W01ajJEMx6223Y7J5yaajGjVs1QfW3YGkkOJHVKfAMEqNB1ZHN9wCcViehv5ZwVSSJnjhu6lYEYgwBdHtCxqhQ==", - "dev": true, - "requires": { - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "rimraf": "^3.0.2", - "unzipper": "^0.10.11" - } - }, "@webassemblyjs/ast": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", @@ -303,15 +273,6 @@ "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", "dev": true }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "requires": { - "debug": "4" - } - }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -330,62 +291,12 @@ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "big-integer": { - "version": "1.6.51", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", - "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", - "dev": true - }, - "binary": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", - "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", - "dev": true, - "requires": { - "buffers": "~0.1.1", - "chainsaw": "~0.1.0" - } - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "bluebird": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", - "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=", - "dev": true - }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -405,12 +316,6 @@ "fill-range": "^7.0.1" } }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, "browserslist": { "version": "4.18.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.18.1.tgz", @@ -430,39 +335,12 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, - "buffer-indexof-polyfill": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", - "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", - "dev": true - }, - "buffers": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", - "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=", - "dev": true - }, - "camelcase": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.1.tgz", - "integrity": "sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==", - "dev": true - }, "caniuse-lite": { "version": "1.0.30001283", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001283.tgz", "integrity": "sha512-9RoKo841j1GQFSJz/nCXOj0sD7tHBtlowjYlrqIUS812x9/emfBLBt6IyMz1zIaYc/eRL8Cs6HPUVi2Hzq4sIg==", "dev": true }, - "chainsaw": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", - "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", - "dev": true, - "requires": { - "traverse": ">=0.3.0 <0.4" - } - }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -514,73 +392,12 @@ } } }, - "chokidar": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", - "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, "chrome-trace-event": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", "dev": true }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, "clone-deep": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", @@ -610,12 +427,6 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -627,48 +438,12 @@ "which": "^2.0.1" } }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true - }, - "diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true - }, - "duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", - "dev": true, - "requires": { - "readable-stream": "^2.0.2" - } - }, "electron-to-chromium": { "version": "1.4.5", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.5.tgz", "integrity": "sha512-YKaB+t8ul5crdh6OeqT2qXdxJGI0fAYb6/X8pDIyye+c3a7ndOCk5gVeKX+ABwivCGNS56vOAif3TN0qJMpEHw==", "dev": true }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, "enhanced-resolve": { "version": "5.8.3", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", @@ -697,12 +472,6 @@ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, "eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -786,70 +555,18 @@ "to-regex-range": "^5.0.1" } }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true - }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "fstream": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", - "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - }, - "dependencies": { - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, "get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -870,15 +587,6 @@ "path-is-absolute": "^1.0.0" } }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, "glob-to-regexp": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", @@ -891,12 +599,6 @@ "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", "dev": true }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -912,33 +614,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dev": true, - "requires": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - } - }, - "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, "human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -977,15 +652,6 @@ "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", "dev": true }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, "is-core-module": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", @@ -995,39 +661,12 @@ "has": "^1.0.3" } }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true - }, "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -1043,18 +682,6 @@ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -1096,37 +723,12 @@ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true }, - "listenercount": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", - "integrity": "sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=", - "dev": true - }, "loader-runner": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", "dev": true }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - } - }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -1182,135 +784,6 @@ "brace-expansion": "^1.1.7" } }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "mocha": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.1.tgz", - "integrity": "sha512-0wE74YMgOkCgBUj8VyIDwmLUjTsS13WV1Pg7l0SHea2qzZzlq7MDnfbPsHKcELBRk3+izEVkRofjmClpycudCA==", - "dev": true, - "requires": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.2", - "debug": "4.3.1", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.1.7", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "3.0.4", - "ms": "2.1.3", - "nanoid": "3.1.23", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "which": "2.0.2", - "wide-align": "1.1.3", - "workerpool": "6.1.5", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "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 - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "nanoid": { - "version": "3.1.23", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", - "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==", - "dev": true - }, "neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -1323,12 +796,6 @@ "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==", "dev": true }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, "npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -1356,24 +823,6 @@ "mimic-fn": "^2.1.0" } }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -1470,12 +919,6 @@ "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==", "dev": true }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -1491,30 +934,6 @@ "safe-buffer": "^5.1.0" } }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, "rechoir": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", @@ -1524,12 +943,6 @@ "resolve": "^1.9.0" } }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, "resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", @@ -1599,12 +1012,6 @@ "randombytes": "^2.1.0" } }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, "shallow-clone": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", @@ -1651,46 +1058,12 @@ "source-map": "^0.6.0" } }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, "strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, "supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -1747,12 +1120,6 @@ "is-number": "^7.0.0" } }, - "traverse": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", - "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", - "dev": true - }, "ts-loader": { "version": "9.2.5", "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.2.5.tgz", @@ -1771,24 +1138,6 @@ "integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==", "dev": true }, - "unzipper": { - "version": "0.10.11", - "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.11.tgz", - "integrity": "sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==", - "dev": true, - "requires": { - "big-integer": "^1.6.17", - "binary": "~0.3.0", - "bluebird": "~3.4.1", - "buffer-indexof-polyfill": "~1.0.0", - "duplexer2": "~0.1.4", - "fstream": "^1.0.12", - "graceful-fs": "^4.2.2", - "listenercount": "~1.0.1", - "readable-stream": "~2.3.6", - "setimmediate": "~1.0.4" - } - }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -1798,12 +1147,6 @@ "punycode": "^2.1.0" } }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, "watchpack": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.0.tgz", @@ -1899,186 +1242,23 @@ "isexe": "^2.0.0" } }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, "wildcard": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", "dev": true }, - "workerpool": { - "version": "6.1.5", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz", - "integrity": "sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw==", - "dev": true - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "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" - } - }, - "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 - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true - }, - "yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "requires": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - } - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true } } } diff --git a/Src/CSharpier.VSCode/package.json b/Src/CSharpier.VSCode/package.json index a365927c8..70ce22a94 100644 --- a/Src/CSharpier.VSCode/package.json +++ b/Src/CSharpier.VSCode/package.json @@ -2,7 +2,7 @@ "name": "csharpier-vscode", "displayName": "CSharpier - Code formatter", "description": "Code formatter using csharpier", - "version": "1.0.4", + "version": "1.1.0", "publisher": "csharpier", "author": "CSharpier", "homepage": "https://marketplace.visualstudio.com/items?itemName=csharpier.csharpier-vscode", @@ -30,7 +30,7 @@ "activationEvents": [ "onStartupFinished" ], - "icon": "icon.png", + "icon": "logo.png", "main": "./build/Extension.js", "capabilities": { "untrustedWorkspaces": { @@ -57,21 +57,15 @@ "actualBuild": "webpack --env NODE_ENV=production", "build": "rimraf build && npm run actualBuild", "start": "rimraf build && webpack --env NODE_ENV=development --watch", - "pretest": "npm run actualBuild && tsc -p ./ && npm run actualBuild", "prettier": "prettier . --write", - "test": "node ./build/Tests/RunTests.js", "vsix": "vsce package" }, "devDependencies": { - "@types/command-exists": "1.2.0", "@types/glob": "7.1.4", "@types/mocha": "9.0.0", "@types/node": "14.x", "@types/semver": "7.3.9", "@types/vscode": "1.60.0", - "@vscode/test-electron": "1.6.2", - "glob": "^7.1.7", - "mocha": "9.1.1", "prettier": "2.4.1", "rimraf": "3.0.2", "semver": "7.3.5", diff --git a/Src/CSharpier.VSCode/src/CSharpierProcess.ts b/Src/CSharpier.VSCode/src/CSharpierProcess.ts index ca891cb63..65abc7216 100644 --- a/Src/CSharpier.VSCode/src/CSharpierProcess.ts +++ b/Src/CSharpier.VSCode/src/CSharpierProcess.ts @@ -1,11 +1,11 @@ import { Disposable } from "vscode"; export interface ICSharpierProcess extends Disposable { - formatFile(content: string, fileName: string): Promise; + formatFile(content: string, filePath: string): Promise; } export class NullCSharpierProcess implements ICSharpierProcess { - formatFile(content: string, fileName: string): Promise { + formatFile(content: string, filePath: string): Promise { return Promise.resolve(""); } diff --git a/Src/CSharpier.VSCode/src/CSharpierProcessPipeMultipleFiles.ts b/Src/CSharpier.VSCode/src/CSharpierProcessPipeMultipleFiles.ts index 21827abfc..4a382952f 100644 --- a/Src/CSharpier.VSCode/src/CSharpierProcessPipeMultipleFiles.ts +++ b/Src/CSharpier.VSCode/src/CSharpierProcessPipeMultipleFiles.ts @@ -8,17 +8,21 @@ export class CSharpierProcessPipeMultipleFiles implements ICSharpierProcess { private loggingService: LoggingService; private nextFile: string = ""; - constructor(loggingService: LoggingService, csharpierPath: string) { + constructor(loggingService: LoggingService, csharpierPath: string, workingDirectory: string) { this.loggingService = loggingService; - this.process = this.spawnProcess(csharpierPath); + this.process = this.spawnProcess(csharpierPath, workingDirectory); - this.loggingService.logInfo("Warm CSharpier with initial format"); - this.formatFile("public class ClassName { }", "Test.cs"); + this.loggingService.logDebug("Warm CSharpier with initial format"); + // warm by formatting a file twice, the 3rd time is when it gets really fast + this.formatFile("public class ClassName { }", "Test.cs").then(() => { + this.formatFile("public class ClassName { }", "Test.cs"); + }); } - private spawnProcess = (csharpierPath: string) => { + private spawnProcess = (csharpierPath: string, workingDirectory: string) => { const csharpierProcess = spawn("dotnet", [csharpierPath, "--pipe-multiple-files"], { stdio: "pipe", + cwd: workingDirectory, }); csharpierProcess.stderr.on("data", chunk => { @@ -30,11 +34,11 @@ export class CSharpierProcessPipeMultipleFiles implements ICSharpierProcess { }); csharpierProcess.stdout.on("data", chunk => { - this.loggingService.logInfo("Got chunk"); + this.loggingService.logDebug("Got chunk of size " + chunk.length); this.nextFile += chunk; - let number = this.nextFile.indexOf("\u0003"); + const number = this.nextFile.indexOf("\u0003"); if (number >= 0) { - this.loggingService.logInfo("Got last chunk"); + this.loggingService.logDebug("Got last chunk with ETX at " + number); const result = this.nextFile.substring(0, number); this.nextFile = this.nextFile.substring(number + 1); const callback = this.callbacks.shift(); @@ -47,8 +51,8 @@ export class CSharpierProcessPipeMultipleFiles implements ICSharpierProcess { return csharpierProcess; }; - formatFile(content: string, fileName: string): Promise { - this.process.stdin.write(fileName); + formatFile(content: string, filePath: string): Promise { + this.process.stdin.write(filePath); this.process.stdin.write("\u0003"); this.process.stdin.write(content); this.process.stdin.write("\u0003"); diff --git a/Src/CSharpier.VSCode/src/CSharpierProcessProvider.ts b/Src/CSharpier.VSCode/src/CSharpierProcessProvider.ts new file mode 100644 index 000000000..ced6e39d8 --- /dev/null +++ b/Src/CSharpier.VSCode/src/CSharpierProcessProvider.ts @@ -0,0 +1,230 @@ +import { Disposable, TextEditor, window, workspace } from "vscode"; +import { LoggingService } from "./LoggingService"; +import * as path from "path"; +import * as semver from "semver"; +import { execSync } from "child_process"; +import { ICSharpierProcess, NullCSharpierProcess } from "./CSharpierProcess"; +import { CSharpierProcessSingleFile } from "./CSharpierProcessSingleFile"; +import { CSharpierProcessPipeMultipleFiles } from "./CSharpierProcessPipeMultipleFiles"; +import * as fs from "fs"; +import { InstallerService } from "./InstallerService"; + +export class CSharpierProcessProvider implements Disposable { + warnedForOldVersion = false; + loggingService: LoggingService; + installerService: InstallerService; + csharpierPath: string; + warmingByDirectory: Record = {}; + csharpierVersionByDirectory: Record = {}; + csharpierProcessesByVersion: Record = {}; + + constructor(loggingService: LoggingService) { + this.loggingService = loggingService; + this.installerService = new InstallerService( + this.loggingService, + this.killRunningProcesses, + ); + + let timeoutHandle: NodeJS.Timeout; + const setupKillRunningProcesses = () => { + // TODO we can't detect when the terminal gets focused + // see https://github.com/microsoft/vscode/issues/117980 + // and we can't detect when the text editor itself loses focus + // so in order to make sure someone can use the terminal to update csharpier + // we have to kill off the background process after a set amount of time + clearTimeout(timeoutHandle); + timeoutHandle = setTimeout(this.killRunningProcesses, 15000); + }; + + window.onDidChangeWindowState(event => { + if (!event.focused) { + this.killRunningProcesses(); + } else { + } + }); + window.onDidChangeActiveTextEditor((event: TextEditor | undefined) => { + if (event?.document?.languageId !== "csharp") { + return; + } + this.findAndWarmProcess(event.document.fileName); + setupKillRunningProcesses(); + }); + workspace.onDidChangeTextDocument(event => { + if (event.document.languageId !== "csharp") { + return; + } + this.findAndWarmProcess(event.document.fileName); + clearTimeout(timeoutHandle); + setupKillRunningProcesses(); + }); + + this.csharpierPath = this.getCSharpierPath(); + + this.loggingService.logDebug("Using command dotnet " + this.csharpierPath); + } + + private findAndWarmProcess(filePath: string) { + const directory = path.parse(filePath).dir; + if (this.warmingByDirectory[directory]) { + return; + } + this.loggingService.logDebug("Ensure there is a csharpier process for " + directory); + this.warmingByDirectory[directory] = true; + let version = this.csharpierVersionByDirectory[directory]; + if (!version) { + version = this.getCSharpierVersion(directory); + if (!semver.valid(version)) { + this.installerService.displayInstallNeededMessage(directory); + } + this.csharpierVersionByDirectory[directory] = version; + } + + if (!this.csharpierProcessesByVersion[version]) { + this.csharpierProcessesByVersion[version] = this.setupCSharpierProcess( + directory, + version, + ); + } + delete this.warmingByDirectory[directory]; + } + + private getCSharpierPath = () => { + const csharpierPath = "csharpier"; + + // const csharpierDebugPath = path.resolve( + // __dirname, + // "../../CSharpier.Cli/bin/Debug/net6.0/dotnet-csharpier.dll", + // ); + // const csharpierReleasePath = csharpierDebugPath.replace("Debug", "Release"); + // + // if (fs.existsSync(csharpierDebugPath)) { + // csharpierPath = csharpierDebugPath; + // } else if (fs.existsSync(csharpierReleasePath)) { + // csharpierPath = csharpierReleasePath; + // } + return csharpierPath; + }; + + public getProcessFor = (filePath: string) => { + const directory = path.parse(filePath).dir; + let version = this.csharpierVersionByDirectory[directory]; + if (!version) { + this.findAndWarmProcess(filePath); + version = this.csharpierVersionByDirectory[directory]; + } + + if (!version || !this.csharpierProcessesByVersion[version]) { + // this shouldn't really happen, but just in case + return new NullCSharpierProcess(); + } + + return this.csharpierProcessesByVersion[version]!; + }; + + private getCSharpierVersion = (directoryThatContainsFile: string): string => { + let currentDirectory = directoryThatContainsFile; + while (true) { + const dotnetToolsPath = path.join(currentDirectory, ".config/dotnet-tools.json"); + this.loggingService.logDebug(`Looking for ${dotnetToolsPath}`); + if (fs.existsSync(dotnetToolsPath)) { + const data = JSON.parse(fs.readFileSync(dotnetToolsPath).toString()); + const version = data.tools.csharpier?.version; + if (version) { + this.loggingService.logDebug( + "Found version " + version + " in " + dotnetToolsPath, + ); + return version; + } + } + + const nextDirectory = path.join(currentDirectory, ".."); + if (nextDirectory === currentDirectory) { + break; + } + currentDirectory = nextDirectory; + } + + this.loggingService.logDebug( + "Unable to find dotnet-tools.json, falling back to running dotnet csharpier --version", + ); + + let outputFromCsharpier: string; + + try { + outputFromCsharpier = execSync(`dotnet ${this.csharpierPath} --version`, { + cwd: directoryThatContainsFile, + }).toString(); + } catch (error: any) { + this.loggingService.logDebug( + "dotnet csharpier --version failed with " + error.stderr.toString(), + ); + return ""; + } + + this.loggingService.logDebug(`dotnet csharpier --version output ${outputFromCsharpier}`); + + const lines = outputFromCsharpier.split(/\r?\n/); + + // sometimes .net outputs more than just the version + for (let x = lines.length - 1; x >= 0; x--) { + const version = lines[x].trim(); + if (version !== "") { + return version; + } + } + + this.loggingService.logDebug( + "Could not find version in output from dotnet csharpier --version in cwd " + + directoryThatContainsFile + + ". Output was \n" + + outputFromCsharpier, + ); + + return ""; + }; + + private setupCSharpierProcess = (directory: string, version: string) => { + try { + if (!semver.valid(version)) { + return new NullCSharpierProcess(); + } + + this.loggingService.logDebug(`Adding new version ${version} process for ${directory}`); + + if (semver.lt(version, "0.12.0")) { + if (!this.warnedForOldVersion) { + window.showInformationMessage( + "Please upgrade to CSharpier >= 0.12.0 for bug fixes and improved formatting speed.", + ); + this.warnedForOldVersion = true; + } + return new CSharpierProcessSingleFile(this.loggingService, this.csharpierPath); + } else { + return new CSharpierProcessPipeMultipleFiles( + this.loggingService, + this.csharpierPath, + directory, + ); + } + } catch (ex: any) { + this.loggingService.logError(ex.output.toString()); + return new NullCSharpierProcess(); + } + }; + + public dispose = () => { + this.killRunningProcesses(); + }; + + private killRunningProcesses = () => { + for (const key in this.csharpierProcessesByVersion) { + this.loggingService.logDebug( + "disposing of process for version " + (key === "" ? "null" : key), + ); + this.csharpierProcessesByVersion[key]?.dispose(); + } + this.warmingByDirectory = {}; + this.csharpierVersionByDirectory = {}; + this.csharpierProcessesByVersion = {}; + }; +} diff --git a/Src/CSharpier.VSCode/src/CSharpierProcessSingleFile.ts b/Src/CSharpier.VSCode/src/CSharpierProcessSingleFile.ts index 203ea6de7..d465750e0 100644 --- a/Src/CSharpier.VSCode/src/CSharpierProcessSingleFile.ts +++ b/Src/CSharpier.VSCode/src/CSharpierProcessSingleFile.ts @@ -1,6 +1,7 @@ import { LoggingService } from "./LoggingService"; import { spawn } from "child_process"; import { ICSharpierProcess } from "./CSharpierProcess"; +import * as path from "path"; export class CSharpierProcessSingleFile implements ICSharpierProcess { private readonly csharpierPath: string; @@ -11,10 +12,12 @@ export class CSharpierProcessSingleFile implements ICSharpierProcess { this.csharpierPath = csharpierPath; } - formatFile(content: string, fileName: string): Promise { + formatFile(content: string, filePath: string): Promise { + const directory = path.parse(filePath).dir; return new Promise((resolve, reject) => { const csharpier = spawn("dotnet", [this.csharpierPath, "--write-stdout"], { stdio: "pipe", + cwd: directory, }); let output = ""; diff --git a/Src/CSharpier.VSCode/src/CSharpierService.ts b/Src/CSharpier.VSCode/src/CSharpierService.ts deleted file mode 100644 index e126a6849..000000000 --- a/Src/CSharpier.VSCode/src/CSharpierService.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { Disposable, env, Uri, window } from "vscode"; -import { LoggingService } from "./LoggingService"; -import * as path from "path"; -import * as fs from "fs"; -import * as semver from "semver"; -import { execSync } from "child_process"; -import { ICSharpierProcess, NullCSharpierProcess } from "./CSharpierProcess"; -import { CSharpierProcessSingleFile } from "./CSharpierProcessSingleFile"; -import { CSharpierProcessPipeMultipleFiles } from "./CSharpierProcessPipeMultipleFiles"; - -export class CSharpierService implements Disposable { - loggingService: LoggingService; - csharpierPath: string; - callbacks: ((result: string) => void)[] = []; - csharpierProcess: ICSharpierProcess; - - constructor(loggingService: LoggingService) { - this.loggingService = loggingService; - - this.csharpierPath = this.getCSharpierPath(); - - this.loggingService.logDebug("Using command dotnet " + this.csharpierPath); - - this.csharpierProcess = this.setupCSharpierProcess(); - } - - private getCSharpierPath = () => { - let csharpierPath = "csharpier"; - - const csharpierDebugPath = path.resolve( - __dirname, - "../../CSharpier.Cli/bin/Debug/net6.0/dotnet-csharpier.dll", - ); - const csharpierReleasePath = csharpierDebugPath.replace("Debug", "Release"); - - if (fs.existsSync(csharpierDebugPath)) { - csharpierPath = csharpierDebugPath; - } else if (fs.existsSync(csharpierReleasePath)) { - csharpierPath = csharpierReleasePath; - } - return csharpierPath; - }; - - public formatInPlace = (content: string, fileName: string) => { - return this.csharpierProcess.formatFile(content, fileName); - }; - - private setupCSharpierProcess = () => { - try { - const version = execSync("dotnet " + this.csharpierPath + " --version") - .toString() - .trim(); - this.loggingService.logInfo("Version: " + version); - if (!semver.valid(version)) { - this.displayInstallNeededMessage(); - return new NullCSharpierProcess(); - } - - if (semver.lt(version, "0.12.0")) { - window.showInformationMessage( - "Please upgrade to CSharpier >= 0.12.0 for bug fixes and improved formatting speed.", - ); - return new CSharpierProcessSingleFile(this.loggingService, this.csharpierPath); - } else { - return new CSharpierProcessPipeMultipleFiles( - this.loggingService, - this.csharpierPath, - ); - } - } catch (ex: any) { - this.loggingService.logDebug(ex.output.toString()); - this.displayInstallNeededMessage(); - return new NullCSharpierProcess(); - } - }; - - private displayInstallNeededMessage = () => { - this.loggingService.logError("CSharpier not found"); - - window - .showErrorMessage("CSharpier must be installed globally.", "Install CSharpier") - .then(selection => { - if (selection === "Install CSharpier") { - const command = "dotnet tool install -g csharpier"; - this.loggingService.logInfo("Running " + command); - const output = execSync(command).toString(); - this.loggingService.logInfo(output); - this.csharpierProcess = this.setupCSharpierProcess(); - } - }); - }; - - dispose() { - this.csharpierProcess.dispose(); - } -} diff --git a/Src/CSharpier.VSCode/src/Extension.ts b/Src/CSharpier.VSCode/src/Extension.ts index 124fc3f77..3e6b2a33b 100644 --- a/Src/CSharpier.VSCode/src/Extension.ts +++ b/Src/CSharpier.VSCode/src/Extension.ts @@ -1,5 +1,5 @@ import { ExtensionContext, workspace } from "vscode"; -import { CSharpierService } from "./CSharpierService"; +import { CSharpierProcessProvider } from "./CSharpierProcessProvider"; import { FormattingService } from "./FormattingService"; import { LoggingService } from "./LoggingService"; @@ -22,8 +22,8 @@ const initPlugin = async (context: ExtensionContext) => { loggingService.logInfo("Initializing " + (process.env as any).EXTENSION_NAME); - const csharpierService = new CSharpierService(loggingService); - const formattingService = new FormattingService(loggingService, csharpierService); + const csharpierProcessProvider = new CSharpierProcessProvider(loggingService); + new FormattingService(loggingService, csharpierProcessProvider); - context.subscriptions.push(csharpierService); + context.subscriptions.push(csharpierProcessProvider); }; diff --git a/Src/CSharpier.VSCode/src/FormattingService.ts b/Src/CSharpier.VSCode/src/FormattingService.ts index bc6061b4c..1dbce2239 100644 --- a/Src/CSharpier.VSCode/src/FormattingService.ts +++ b/Src/CSharpier.VSCode/src/FormattingService.ts @@ -1,15 +1,18 @@ import { performance } from "perf_hooks"; import { languages, Range, TextDocument, TextEdit } from "vscode"; -import { CSharpierService } from "./CSharpierService"; +import { CSharpierProcessProvider } from "./CSharpierProcessProvider"; import { LoggingService } from "./LoggingService"; export class FormattingService { loggingService: LoggingService; - csharpierService: CSharpierService; + csharpierProcessProvider: CSharpierProcessProvider; - constructor(loggingService: LoggingService, csharpierService: CSharpierService) { + constructor( + loggingService: LoggingService, + csharpierProcessProvider: CSharpierProcessProvider, + ) { this.loggingService = loggingService; - this.csharpierService = csharpierService; + this.csharpierProcessProvider = csharpierProcessProvider; languages.registerDocumentFormattingEditProvider("csharp", { provideDocumentFormattingEdits: this.provideDocumentFormattingEdits, @@ -36,7 +39,7 @@ export class FormattingService { return new Range(0, 0, lastLineId, document.lineAt(lastLineId).text.length); } - private formatInPlace = async (content: string, fileName: string) => { - return this.csharpierService.formatInPlace(content, fileName); + private formatInPlace = async (content: string, filePath: string) => { + return this.csharpierProcessProvider.getProcessFor(filePath).formatFile(content, filePath); }; } diff --git a/Src/CSharpier.VSCode/src/InstallerService.ts b/Src/CSharpier.VSCode/src/InstallerService.ts new file mode 100644 index 000000000..27d7f922f --- /dev/null +++ b/Src/CSharpier.VSCode/src/InstallerService.ts @@ -0,0 +1,107 @@ +import { LoggingService } from "./LoggingService"; +import { window, workspace } from "vscode"; +import { execSync } from "child_process"; +import * as path from "path"; +import * as fs from "fs"; + +export class InstallerService { + rejectedError = false; + rejectedGlobalError = false; + errorVisible = false; + globalErrorVisible = false; + loggingService: LoggingService; + killRunningProcesses: () => void; + + constructor(loggingService: LoggingService, killRunningProcesses: () => void) { + this.loggingService = loggingService; + this.killRunningProcesses = killRunningProcesses; + } + + public displayInstallNeededMessage = (directoryThatContainsFile: string) => { + this.loggingService.logError("CSharpier was not found so files may not be formatted."); + + const items = ["Install CSharpier Globally"]; + let solutionRoot: string; + if (workspace.workspaceFolders) { + for (const folder of workspace.workspaceFolders) { + if (directoryThatContainsFile.startsWith(folder.uri.fsPath)) { + solutionRoot = folder.uri.fsPath; + items.unshift("Install CSharpier Locally"); + break; + } + } + } + + const isOnlyGlobal = items.length === 1; + let message: string; + + if (isOnlyGlobal) { + if (this.globalErrorVisible || this.rejectedGlobalError) { + return; + } + this.globalErrorVisible = true; + message = + "CSharpier needs to be installed globally to format files in " + + directoryThatContainsFile; + } else { + if (this.errorVisible || this.rejectedError) { + return; + } + + this.errorVisible = true; + message = "CSharpier needs to be installed to support formatting files"; + } + + window.showErrorMessage(message, ...items).then( + selection => { + if (selection === "Install CSharpier Globally") { + const command = "dotnet tool install -g csharpier"; + this.loggingService.logInfo("Installing csharpier globally with " + command); + const output = execSync(command).toString(); + this.loggingService.logInfo(output); + } else if (selection === "Install CSharpier Locally") { + if (solutionRoot) { + try { + const manifestPath = path.join( + solutionRoot, + ".config/dotnet-tools.json", + ); + this.loggingService.logInfo("Installing csharpier in " + manifestPath); + if (!fs.existsSync(manifestPath)) { + execSync("dotnet new tool-manifest", { cwd: solutionRoot }); + } + execSync("dotnet tool install csharpier", { cwd: solutionRoot }); + } catch (error) { + this.loggingService.logError("Installing failed with ", error); + } + } + } else { + if (isOnlyGlobal) { + this.rejectedError = true; + } else { + this.rejectedGlobalError = true; + } + + this.loggingService.logDebug("rejected"); + } + + if (isOnlyGlobal) { + this.globalErrorVisible = false; + } else { + this.errorVisible = false; + } + + this.killRunningProcesses(); + }, + () => { + if (isOnlyGlobal) { + this.globalErrorVisible = false; + this.rejectedGlobalError = true; + } else { + this.errorVisible = false; + this.rejectedError = true; + } + }, + ); + }; +} diff --git a/Src/CSharpier.VSCode/src/LoggingService.ts b/Src/CSharpier.VSCode/src/LoggingService.ts index 9b3ba3f33..7b94f98c8 100644 --- a/Src/CSharpier.VSCode/src/LoggingService.ts +++ b/Src/CSharpier.VSCode/src/LoggingService.ts @@ -12,7 +12,7 @@ export class LoggingService { } } - public logDebug(message: string, data?: unknown): void { + public logDebug(message: any, data?: unknown): void { if ( this.logLevel === "NONE" || this.logLevel === "INFO" || @@ -27,7 +27,7 @@ export class LoggingService { } } - public logInfo(message: string, data?: unknown): void { + public logInfo(message: any, data?: unknown): void { if (this.logLevel === "NONE" || this.logLevel === "WARN" || this.logLevel === "ERROR") { return; } @@ -37,7 +37,7 @@ export class LoggingService { } } - public logWarning(message: string, data?: unknown): void { + public logWarning(message: any, data?: unknown): void { if (this.logLevel === "NONE" || this.logLevel === "ERROR") { return; } @@ -47,7 +47,7 @@ export class LoggingService { } } - public logError(message: string, error?: unknown) { + public logError(message: any, error?: unknown) { if (this.logLevel === "NONE") { return; } @@ -78,7 +78,7 @@ export class LoggingService { this.outputChannel.appendLine(message); } - private logMessage(message: string, logLevel: LogLevel): void { + private logMessage(message: any, logLevel: LogLevel): void { const title = new Date().toLocaleTimeString(); this.outputChannel.appendLine(`["${logLevel}" - ${title}] ${message}`); console.log(message); diff --git a/Src/CSharpier.VSCode/src/Tests/Extension.tests.ts b/Src/CSharpier.VSCode/src/Tests/Extension.tests.ts deleted file mode 100644 index b53ab0d8a..000000000 --- a/Src/CSharpier.VSCode/src/Tests/Extension.tests.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { strictEqual } from "assert"; -import { readFileSync, writeFileSync } from "fs"; -import { commands, TextDocument, window, workspace } from "vscode"; -import * as path from "path"; - -const unformattedCode = "public class ClassName {\n\n}"; -const formattedCode = "public class ClassName { }\n"; - -suite("Formatting", () => { - test("Formats physical C# file", async () => { - const testFilePath = path.resolve(__dirname, "./TestFile.cs"); - writeFileSync(testFilePath, unformattedCode); - - await formatFile(testFilePath); - const actual = readFileSync(testFilePath, "utf8"); - - strictEqual(actual, formattedCode); - }); - - test("Ignores physical C# file", async () => { - const testFilePath = path.resolve(__dirname, "./Ignored.cs"); - writeFileSync(testFilePath, unformattedCode); - - const ignorePath = path.resolve(__dirname, "./.csharpierignore"); - writeFileSync(ignorePath, "Ignored.cs"); - - await formatFile(testFilePath); - const actual = readFileSync(testFilePath, "utf8"); - - strictEqual(actual, unformattedCode); - }); - - test("Formats virtual C# file", async () => { - const document = await workspace.openTextDocument({ - content: unformattedCode, - language: "csharp", - }); - - await showDocumentAndFormat(document); - - strictEqual(document.getText(), formattedCode); - }); - - test("Retains invalid virtual C# file", async () => { - const document = await workspace.openTextDocument({ - content: "public class ClassName {", - language: "csharp", - }); - - await showDocumentAndFormat(document); - - strictEqual(document.getText(), "public class ClassName {"); - }); -}); - -const formatFile = async (fileName: string): Promise => { - const document = await workspace.openTextDocument(fileName); - const originalCode = document.getText(); - - await showDocumentAndFormat(document); - await workspace.saveAll(); -}; - -const showDocumentAndFormat = async (document: TextDocument): Promise => { - await window.showTextDocument(document); - - await commands.executeCommand("editor.action.formatDocument"); -}; diff --git a/Src/CSharpier.VSCode/src/Tests/RunTests.ts b/Src/CSharpier.VSCode/src/Tests/RunTests.ts deleted file mode 100644 index ce2fe69c3..000000000 --- a/Src/CSharpier.VSCode/src/Tests/RunTests.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { runTests } from "@vscode/test-electron"; -import * as path from "path"; - -async function main() { - try { - const pathToPackageJson = path.resolve(__dirname, "../../"); - - const pathToTestSuite = path.resolve(__dirname, "./"); - - await runTests({ - extensionDevelopmentPath: pathToPackageJson, - extensionTestsPath: pathToTestSuite, - }); - } catch (err) { - console.error("Failed to run tests"); - process.exit(1); - } -} - -main(); diff --git a/Src/CSharpier.VSCode/src/Tests/index.ts b/Src/CSharpier.VSCode/src/Tests/index.ts deleted file mode 100644 index 930808586..000000000 --- a/Src/CSharpier.VSCode/src/Tests/index.ts +++ /dev/null @@ -1,35 +0,0 @@ -import * as glob from "glob"; -import * as Mocha from "mocha"; -import * as path from "path"; - -export function run(): Promise { - const mocha = new Mocha({ - ui: "tdd", - color: true, - }); - - const testsRoot = path.resolve(__dirname, ".."); - - return new Promise((resolve, reject) => { - glob("**/**.tests.js", { cwd: testsRoot }, (err, files) => { - if (err) { - return reject(err); - } - - files.forEach(file => mocha.addFile(path.resolve(testsRoot, file))); - - try { - mocha.run(failures => { - if (failures > 0) { - reject(new Error(`${failures} tests failed.`)); - } else { - resolve(); - } - }); - } catch (err) { - console.error(err); - reject(err); - } - }); - }); -} diff --git a/logo.png b/logo.png index 2866f8235..8aa790888 100644 Binary files a/logo.png and b/logo.png differ diff --git a/logo.svg b/logo.svg index f4537173e..215dc73a1 100644 --- a/logo.svg +++ b/logo.svg @@ -1,57 +1 @@ - - - - C - - - # - - - - ier - - - + \ No newline at end of file