diff --git a/CHANGELOG.md b/CHANGELOG.md index 539032a3b0..4068b4b6a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,28 @@ - Diagnostics related feature requests and improvements [#5951](https://github.com/dotnet/vscode-csharp/issues/5951) - Debug from .csproj and .sln [#5876](https://github.com/dotnet/vscode-csharp/issues/5876) +# 2.96.x + +# 2.95.x +* Update RoslynCopilot url to 18.0.898-alpha (PR: [#8696](https://github.com/dotnet/vscode-csharp/pull/8696)) +* Bump Roslyn to 5.3.0-1.25514.3 (PR: [#8700](https://github.com/dotnet/vscode-csharp/pull/8700)) + * Ensure `LspWorkspaceManager` returns solutions without misc document when file moved(PR: [#80535](https://github.com/dotnet/roslyn/pull/80535)) + * Add limited support for binarylogger to MSBuildWorkspace(PR: [#80120](https://github.com/dotnet/roslyn/pull/80120)) + * Restore fully qualify for Razor (PR: [#80674](https://github.com/dotnet/roslyn/pull/80674)) + * Improve diagnostic quality for less accessible base type argument (PR: [#80483](https://github.com/dotnet/roslyn/pull/80483)) + * Build BuildHost against net8.0 (PR: [#80641](https://github.com/dotnet/roslyn/pull/80641)) + * Add completion for directives in file based programs (PR: [#80410](https://github.com/dotnet/roslyn/pull/80410)) +* Bump Razor to 10.0.0-preview.25517.9 (PR: [#8706](https://github.com/dotnet/vscode-csharp/pull/8706)) + * Provide a way for users to turn on logging for formatting, to help resolve bugs (PR: [#12304](https://github.com/dotnet/razor/pull/12304)) + * Handle diagnostic spans that cover an entire attribute value (PR: [#12302](https://github.com/dotnet/razor/pull/12302)) + * Map component start tags to C#, for better GTD, FAR, Hover, etc. (PR: [#12287](https://github.com/dotnet/razor/pull/12287)) + * Add snippet support for component completion with EditorRequired attributes (PR: [#12325](https://github.com/dotnet/razor/pull/12325)) + * Add Go To Definition support for file paths in string literals (PR: [#12323](https://github.com/dotnet/razor/pull/12323)) + * Add IntelliSense support for Blazor enhanced navigation and form handling data attributes (PR: [#12324](https://github.com/dotnet/razor/pull/12324)) + * Fix component end tags to behave consistently with start tags for Hover, Go To Definition, and Find All References (PR: [#12327](https://github.com/dotnet/razor/pull/12327)) + * Add out-of-scope Blazor Component completions with auto-insert @using statements (PR: [#12336](https://github.com/dotnet/razor/pull/12336)) + * Fix classification for fully qualified components (PR: [#12335](https://github.com/dotnet/razor/pull/12335)) + # 2.94.x * Add completion for razor components in settings (PR: [#8680](https://github.com/dotnet/vscode-csharp/pull/8680)) * Add copilot instructions (PR: [#8676](https://github.com/dotnet/vscode-csharp/pull/8676)) diff --git a/package.json b/package.json index 5280275c89..26aa8e4180 100644 --- a/package.json +++ b/package.json @@ -40,9 +40,9 @@ "workspace" ], "defaults": { - "roslyn": "5.1.0-1.25506.3", + "roslyn": "5.3.0-1.25514.3", "omniSharp": "1.39.14", - "razor": "10.0.0-preview.25503.1", + "razor": "10.0.0-preview.25517.9", "razorOmnisharp": "7.0.0-preview.23363.1", "xamlTools": "18.0.11023.10" }, @@ -405,7 +405,7 @@ { "id": "RoslynCopilot", "description": "Language server for Roslyn Copilot integration", - "url": "https://roslyn.blob.core.windows.net/releases/Microsoft.VisualStudio.Copilot.Roslyn.LanguageServer-18.0.797-alpha.zip", + "url": "https://roslyn.blob.core.windows.net/releases/Microsoft.VisualStudio.Copilot.Roslyn.LanguageServer-18.0.904-alpha.zip", "installPath": ".roslynCopilot", "platforms": [ "neutral" @@ -414,12 +414,12 @@ "neutral" ], "installTestPath": "./.roslynCopilot/Microsoft.VisualStudio.Copilot.Roslyn.LanguageServer.dll", - "integrity": "168DC3B3757B5F58DD35E27820949CA8AF4B890BE92D1A0CA6461A3A62E9D0A4" + "integrity": "0BD733B23A706226F2B429AB0CE35576FB474493C8E19C7B88311007876DE5CC" }, { "id": "Debugger", "description": ".NET Core Debugger (Windows / x64)", - "url": "https://vsdebugger-cyg0dxb6czfafzaz.b01.azurefd.net/coreclr-debug-2-90-0/coreclr-debug-win7-x64.zip", + "url": "https://vsdebugger-cyg0dxb6czfafzaz.b01.azurefd.net/coreclr-debug-2-95-0/coreclr-debug-win7-x64.zip", "installPath": ".debugger/x86_64", "platforms": [ "win32" @@ -429,12 +429,12 @@ "arm64" ], "installTestPath": "./.debugger/x86_64/vsdbg-ui.exe", - "integrity": "C25E19B3DBAE55DBBBD7384561E34064CDB92633A816FFB862E68635221A63EC" + "integrity": "9A8766F5B62BC2D7AE80016323B093AD75E822399329DEA32C282187005EBE38" }, { "id": "Debugger", "description": ".NET Core Debugger (Windows / ARM64)", - "url": "https://vsdebugger-cyg0dxb6czfafzaz.b01.azurefd.net/coreclr-debug-2-90-0/coreclr-debug-win10-arm64.zip", + "url": "https://vsdebugger-cyg0dxb6czfafzaz.b01.azurefd.net/coreclr-debug-2-95-0/coreclr-debug-win10-arm64.zip", "installPath": ".debugger/arm64", "platforms": [ "win32" @@ -443,12 +443,12 @@ "arm64" ], "installTestPath": "./.debugger/arm64/vsdbg-ui.exe", - "integrity": "F8F9DE062D0678CFF808B8BC9AADC59C7C39253B1249DE2F9CF3037163D8049F" + "integrity": "6D495C5DA79179ED78DE03C6C623A4BC022919A58FAC486506DC5917EC68F426" }, { "id": "Debugger", "description": ".NET Core Debugger (macOS / x64)", - "url": "https://vsdebugger-cyg0dxb6czfafzaz.b01.azurefd.net/coreclr-debug-2-90-0/coreclr-debug-osx-x64.zip", + "url": "https://vsdebugger-cyg0dxb6czfafzaz.b01.azurefd.net/coreclr-debug-2-95-0/coreclr-debug-osx-x64.zip", "installPath": ".debugger/x86_64", "platforms": [ "darwin" @@ -462,12 +462,12 @@ "./vsdbg" ], "installTestPath": "./.debugger/x86_64/vsdbg-ui", - "integrity": "D1817389B6A1254BDDD8798AD866D6E1AC47740D05E138C060C387C0A53A7925" + "integrity": "72A0BFD3F43D7B3C5CC2091BFB5385BF767370AC59FE88548E28912714FEB4D7" }, { "id": "Debugger", "description": ".NET Core Debugger (macOS / arm64)", - "url": "https://vsdebugger-cyg0dxb6czfafzaz.b01.azurefd.net/coreclr-debug-2-90-0/coreclr-debug-osx-arm64.zip", + "url": "https://vsdebugger-cyg0dxb6czfafzaz.b01.azurefd.net/coreclr-debug-2-95-0/coreclr-debug-osx-arm64.zip", "installPath": ".debugger/arm64", "platforms": [ "darwin" @@ -480,12 +480,12 @@ "./vsdbg" ], "installTestPath": "./.debugger/arm64/vsdbg-ui", - "integrity": "089C742676FD1627ECCF3AAF1643ECCFC654FCED9C0D1E803780CB9C2E1FE355" + "integrity": "08DFFB990A9CBD1A74405C0FB601C3136021E4CBB7ADB2ACEA9A36EBFEB651FE" }, { "id": "Debugger", "description": ".NET Core Debugger (linux / ARM)", - "url": "https://vsdebugger-cyg0dxb6czfafzaz.b01.azurefd.net/coreclr-debug-2-90-0/coreclr-debug-linux-arm.zip", + "url": "https://vsdebugger-cyg0dxb6czfafzaz.b01.azurefd.net/coreclr-debug-2-95-0/coreclr-debug-linux-arm.zip", "installPath": ".debugger", "platforms": [ "linux" @@ -498,12 +498,12 @@ "./vsdbg" ], "installTestPath": "./.debugger/vsdbg-ui", - "integrity": "64DF1D83556A3E33664122B10D94787AF10E54129362D6E8A63F8AA3B47035D3" + "integrity": "1D7E7A1B260347C5D6BFF4BC63FF23A01315B3E180356B3F6E3A974677A3D9C4" }, { "id": "Debugger", "description": ".NET Core Debugger (linux / ARM64)", - "url": "https://vsdebugger-cyg0dxb6czfafzaz.b01.azurefd.net/coreclr-debug-2-90-0/coreclr-debug-linux-arm64.zip", + "url": "https://vsdebugger-cyg0dxb6czfafzaz.b01.azurefd.net/coreclr-debug-2-95-0/coreclr-debug-linux-arm64.zip", "installPath": ".debugger", "platforms": [ "linux" @@ -516,12 +516,12 @@ "./vsdbg" ], "installTestPath": "./.debugger/vsdbg-ui", - "integrity": "578A61AE844470B7D1814AA8A0A49E21069F68CA16F661648AF85F68DC08BC9D" + "integrity": "27C2301B9DB13FBF26579788084981ED4C516646D296ECD8CAE40E0FDDE5C042" }, { "id": "Debugger", "description": ".NET Core Debugger (linux musl / x64)", - "url": "https://vsdebugger-cyg0dxb6czfafzaz.b01.azurefd.net/coreclr-debug-2-90-0/coreclr-debug-linux-musl-x64.zip", + "url": "https://vsdebugger-cyg0dxb6czfafzaz.b01.azurefd.net/coreclr-debug-2-95-0/coreclr-debug-linux-musl-x64.zip", "installPath": ".debugger", "platforms": [ "linux-musl" @@ -534,12 +534,12 @@ "./vsdbg" ], "installTestPath": "./.debugger/vsdbg-ui", - "integrity": "5636C90B08D2849C13E198036B467F73080694CC9D5BF7422B04EA25B27633F9" + "integrity": "DD8BC256154E2BD13974D0ACDA2B2EA58593ABB7A553270487A74E0CDDA83249" }, { "id": "Debugger", "description": ".NET Core Debugger (linux musl / ARM64)", - "url": "https://vsdebugger-cyg0dxb6czfafzaz.b01.azurefd.net/coreclr-debug-2-90-0/coreclr-debug-linux-musl-arm64.zip", + "url": "https://vsdebugger-cyg0dxb6czfafzaz.b01.azurefd.net/coreclr-debug-2-95-0/coreclr-debug-linux-musl-arm64.zip", "installPath": ".debugger", "platforms": [ "linux-musl" @@ -552,12 +552,12 @@ "./vsdbg" ], "installTestPath": "./.debugger/vsdbg-ui", - "integrity": "BF668378285B814949F39718D559D976C7ED0C1575A248370F282210AF513B2E" + "integrity": "1EC09737FA083099F2A03B9B7DF70E813B602A4FCAB50B3FD0CB6F2C46D127F1" }, { "id": "Debugger", "description": ".NET Core Debugger (linux / x64)", - "url": "https://vsdebugger-cyg0dxb6czfafzaz.b01.azurefd.net/coreclr-debug-2-90-0/coreclr-debug-linux-x64.zip", + "url": "https://vsdebugger-cyg0dxb6czfafzaz.b01.azurefd.net/coreclr-debug-2-95-0/coreclr-debug-linux-x64.zip", "installPath": ".debugger", "platforms": [ "linux" @@ -570,7 +570,7 @@ "./vsdbg" ], "installTestPath": "./.debugger/vsdbg-ui", - "integrity": "085CDC403578B24F8335BAFA1B7D62E48FFFEE80419DFA41C6D48D8DBADF95D7" + "integrity": "2B0920ADEC91DA9CE18026CD020488A603C904B4DBE80B30B61337F38B6533F9" }, { "id": "RazorOmnisharp", @@ -5626,9 +5626,6 @@ "[xaml]": { "editor.wordBasedSuggestions": "off" }, - "[csharp]": { - "editor.formatOnType": true - }, "explorer.fileNesting.patterns": { "*.cs": "${capture}.designer.cs,${capture}.g.cs,${capture}.generated.cs,${capture}.run.json,${capture}.settings.json,${capture}.settings.*.json", "*.csproj": "${capture}.csproj.user", diff --git a/package.nls.cs.json b/package.nls.cs.json index 5d2093feb8..e72714a742 100644 --- a/package.nls.cs.json +++ b/package.nls.cs.json @@ -65,8 +65,8 @@ "configuration.dotnet.projects.enableFileBasedPrograms": "Umožňuje využívat prostředí „programů založených na souborech“ (dotnet run app.cs) ve verzi Preview.", "configuration.dotnet.quickInfo.showRemarksInQuickInfo": "Zobrazit informace o poznámkách při zobrazení symbolu.", "configuration.dotnet.server.componentPaths": "Umožňuje přepsat cestu ke složce pro integrované komponenty jazykového serveru (například přepsat cestu .roslynDevKit v adresáři rozšíření tak, aby používala místně sestavené komponenty).", - "configuration.dotnet.server.componentPaths.razorDevKit": "Overrides the folder path for the Razor Dev Kit component of the language server", - "configuration.dotnet.server.componentPaths.razorExtension": "Overrides the folder path for the Razor extension component of the language server", + "configuration.dotnet.server.componentPaths.razorDevKit": "Přepíše cestu ke složce pro komponentu Razor Dev Kit jazykového serveru", + "configuration.dotnet.server.componentPaths.razorExtension": "Přepíše cestu ke složce pro komponentu rozšíření Razor jazykového serveru", "configuration.dotnet.server.componentPaths.roslynCopilot": "Přepíše cestu ke složce pro komponentu .roslynCopilot jazykového serveru.", "configuration.dotnet.server.componentPaths.roslynDevKit": "Přepíše cestu ke složce pro komponentu .roslynDevKit jazykového serveru.", "configuration.dotnet.server.componentPaths.xamlTools": "Přepíše cestu ke složce pro komponentu .xamlTools jazykového serveru.", diff --git a/package.nls.de.json b/package.nls.de.json index 0f03515996..e50cdc6477 100644 --- a/package.nls.de.json +++ b/package.nls.de.json @@ -65,8 +65,8 @@ "configuration.dotnet.projects.enableFileBasedPrograms": "Aktiviert die Vorschau für die Erfahrung „dateibasierte Programme“ (dotnet run app.cs).", "configuration.dotnet.quickInfo.showRemarksInQuickInfo": "Beschreibungsinformationen beim Anzeigen des Symbols anzeigen.", "configuration.dotnet.server.componentPaths": "Ermöglicht das Überschreiben des Ordnerpfads für eingebaute Komponenten des Sprachservers (z. B. Überschreiben des Pfads .roslynDevKit im Erweiterungsverzeichnis, um lokal erstellte Komponenten zu verwenden)", - "configuration.dotnet.server.componentPaths.razorDevKit": "Overrides the folder path for the Razor Dev Kit component of the language server", - "configuration.dotnet.server.componentPaths.razorExtension": "Overrides the folder path for the Razor extension component of the language server", + "configuration.dotnet.server.componentPaths.razorDevKit": "Überschreibt den Ordnerpfad für die Razor-Dev-Kit-Komponente des Sprachservers", + "configuration.dotnet.server.componentPaths.razorExtension": "Überschreibt den Ordnerpfad für die Razor-Erweiterungskomponente des Sprachservers", "configuration.dotnet.server.componentPaths.roslynCopilot": "Überschreibt den Ordnerpfad für die .roslynCopilot-Komponente des Sprachservers", "configuration.dotnet.server.componentPaths.roslynDevKit": "Überschreibt den Ordnerpfad für die Komponente .roslynDevKit des Sprachservers", "configuration.dotnet.server.componentPaths.xamlTools": "Überschreibt den Ordnerpfad für die Komponente .xamlTools des Sprachservers", diff --git a/package.nls.es.json b/package.nls.es.json index 6d2c249d7e..4aa159049c 100644 --- a/package.nls.es.json +++ b/package.nls.es.json @@ -65,8 +65,8 @@ "configuration.dotnet.projects.enableFileBasedPrograms": "Habilita la experiencia de vista previa de \"programas basados en archivos\" (dotnet run app.cs).", "configuration.dotnet.quickInfo.showRemarksInQuickInfo": "Mostrar información de comentarios cuando se muestra el símbolo.", "configuration.dotnet.server.componentPaths": "Permite invalidar la ruta de acceso de carpeta para los componentes integrados del servidor de lenguaje (por ejemplo, invalidar la ruta de acceso .roslynDevKit en el directorio de extensión para usar componentes compilados localmente).", - "configuration.dotnet.server.componentPaths.razorDevKit": "Overrides the folder path for the Razor Dev Kit component of the language server", - "configuration.dotnet.server.componentPaths.razorExtension": "Overrides the folder path for the Razor extension component of the language server", + "configuration.dotnet.server.componentPaths.razorDevKit": "Invalida la ruta de acceso de la carpeta para el componente Razor Dev Kit del servidor de lenguaje", + "configuration.dotnet.server.componentPaths.razorExtension": "Invalida la ruta de acceso de la carpeta para el componente de extensión Razor del servidor de lenguaje", "configuration.dotnet.server.componentPaths.roslynCopilot": "Invalida la ruta de acceso de la carpeta para el componente .roslynCopilot del servidor de lenguaje", "configuration.dotnet.server.componentPaths.roslynDevKit": "Invalida la ruta de acceso de la carpeta para el componente .roslynDevKit del servidor de lenguaje.", "configuration.dotnet.server.componentPaths.xamlTools": "Invalida la ruta de acceso de la carpeta para el componente .xamlTools del servidor de lenguaje.", diff --git a/package.nls.fr.json b/package.nls.fr.json index c23e5ae650..d9f8a18e40 100644 --- a/package.nls.fr.json +++ b/package.nls.fr.json @@ -65,8 +65,8 @@ "configuration.dotnet.projects.enableFileBasedPrograms": "Active l’expérience de prévisualisation des « programmes basés sur des fichiers » (dotnet run app.cs).", "configuration.dotnet.quickInfo.showRemarksInQuickInfo": "Afficher les informations sur les remarques lors de l’affichage du symbole.", "configuration.dotnet.server.componentPaths": "Permet de remplacer le chemin d’accès au dossier des composants intégrés du serveur de langage (par exemple, remplacer le chemin d’accès .roslynDevKit dans le répertoire d’extension pour utiliser les composants générés localement).", - "configuration.dotnet.server.componentPaths.razorDevKit": "Overrides the folder path for the Razor Dev Kit component of the language server", - "configuration.dotnet.server.componentPaths.razorExtension": "Overrides the folder path for the Razor extension component of the language server", + "configuration.dotnet.server.componentPaths.razorDevKit": "Remplace le chemin d’accès du dossier pour le composant du Kit de développement Razor du serveur de langage", + "configuration.dotnet.server.componentPaths.razorExtension": "Remplace le chemin d’accès du dossier pour le composant d’extension Razor du serveur de langage", "configuration.dotnet.server.componentPaths.roslynCopilot": "Remplace le chemin d’accès du dossier pour le composant .roslynCopilot du serveur de langage", "configuration.dotnet.server.componentPaths.roslynDevKit": "Remplace le chemin d’accès au dossier du composant .roslynDevKit du serveur de langage", "configuration.dotnet.server.componentPaths.xamlTools": "Remplace le chemin d’accès du dossier pour le composant .xamlTools du serveur de langage", diff --git a/package.nls.it.json b/package.nls.it.json index c88bd3fff9..328f36d6e6 100644 --- a/package.nls.it.json +++ b/package.nls.it.json @@ -65,8 +65,8 @@ "configuration.dotnet.projects.enableFileBasedPrograms": "Abilita l'esperienza di anteprima di \"programmi basati su file\" (dotnet run app.cs).", "configuration.dotnet.quickInfo.showRemarksInQuickInfo": "Mostra le informazioni sulle note quando viene visualizzato il simbolo.", "configuration.dotnet.server.componentPaths": "Consente di eseguire l'override del percorso della cartella per i componenti predefiniti del server di linguaggio (ad esempio, eseguire l'override del percorso .roslynDevKit nella directory delle estensioni per usare componenti compilati in locale)", - "configuration.dotnet.server.componentPaths.razorDevKit": "Overrides the folder path for the Razor Dev Kit component of the language server", - "configuration.dotnet.server.componentPaths.razorExtension": "Overrides the folder path for the Razor extension component of the language server", + "configuration.dotnet.server.componentPaths.razorDevKit": "Esegue l'override del percorso della cartella per il componente Razor Dev Kit del server di linguaggio", + "configuration.dotnet.server.componentPaths.razorExtension": "Esegue l'override del percorso della cartella per il componente di estensione Razor del server di linguaggio", "configuration.dotnet.server.componentPaths.roslynCopilot": "Esegue l'override del percorso della cartella per il componente roslynCopilot del server di linguaggio", "configuration.dotnet.server.componentPaths.roslynDevKit": "Esegue l'override del percorso della cartella per il componente .roslynDevKit del server di linguaggio", "configuration.dotnet.server.componentPaths.xamlTools": "Esegue l'override del percorso della cartella per il componente .xamlTools del server di linguaggio", diff --git a/package.nls.ja.json b/package.nls.ja.json index f54264d384..661b43dd1a 100644 --- a/package.nls.ja.json +++ b/package.nls.ja.json @@ -65,8 +65,8 @@ "configuration.dotnet.projects.enableFileBasedPrograms": "プレビューの \"ファイル ベースのプログラム\" (dotnet run app.cs) エクスペリエンスを有効にします。", "configuration.dotnet.quickInfo.showRemarksInQuickInfo": "シンボルを表示するときに注釈情報を表示します。", "configuration.dotnet.server.componentPaths": "言語サーバーの組み込みコンポーネントのフォルダー パスをオーバーライドできます (たとえば、ローカルにビルドされたコンポーネントを使用するように拡張ディレクトリの .roslynDevKit パスをオーバーライドする)", - "configuration.dotnet.server.componentPaths.razorDevKit": "Overrides the folder path for the Razor Dev Kit component of the language server", - "configuration.dotnet.server.componentPaths.razorExtension": "Overrides the folder path for the Razor extension component of the language server", + "configuration.dotnet.server.componentPaths.razorDevKit": "言語サーバーの Razor Dev Kit コンポーネントのフォルダー パスを上書きします", + "configuration.dotnet.server.componentPaths.razorExtension": "言語サーバーの Razor 拡張機能コンポーネントのフォルダー パスを上書きします", "configuration.dotnet.server.componentPaths.roslynCopilot": "言語サーバーの .roslynCopilot コンポーネントのフォルダー パスをオーバーライドします", "configuration.dotnet.server.componentPaths.roslynDevKit": "言語サーバーの .roslynDevKit コンポーネントのフォルダー パスをオーバーライドします", "configuration.dotnet.server.componentPaths.xamlTools": "言語サーバーの .xamlTools コンポーネントのフォルダー パスをオーバーライドします", diff --git a/package.nls.ko.json b/package.nls.ko.json index ff4fa483c0..fd74ce02cc 100644 --- a/package.nls.ko.json +++ b/package.nls.ko.json @@ -65,8 +65,8 @@ "configuration.dotnet.projects.enableFileBasedPrograms": "미리 보기 \"파일 기반 프로그램\"(dotnet run app.cs) 환경을 활성화합니다.", "configuration.dotnet.quickInfo.showRemarksInQuickInfo": "기호를 표시할 때 설명 정보를 표시합니다.", "configuration.dotnet.server.componentPaths": "언어 서버의 기본 제공 구성 요소에 대한 폴더 경로를 재정의할 수 있습니다(예: 로컬로 빌드된 구성 요소를 사용하도록 확장 디렉터리의 .roslynDevKit 경로 재정의).", - "configuration.dotnet.server.componentPaths.razorDevKit": "Overrides the folder path for the Razor Dev Kit component of the language server", - "configuration.dotnet.server.componentPaths.razorExtension": "Overrides the folder path for the Razor extension component of the language server", + "configuration.dotnet.server.componentPaths.razorDevKit": "언어 서버의 Razor Dev Kit 구성 요소에 대한 폴더 경로를 재정의합니다.", + "configuration.dotnet.server.componentPaths.razorExtension": "언어 서버의 Razor 확장 구성 요소에 대한 폴더 경로를 재정의합니다.", "configuration.dotnet.server.componentPaths.roslynCopilot": "언어 서버의 .roslynCopilot 구성 요소에 대한 폴더 경로를 덮어씁니다.", "configuration.dotnet.server.componentPaths.roslynDevKit": "언어 서버의 .roslynDevKit 구성 요소에 대한 폴더 경로를 재정의합니다.", "configuration.dotnet.server.componentPaths.xamlTools": "언어 서버의 .xamlTools 구성 요소에 대한 폴더 경로를 재정의합니다.", diff --git a/package.nls.pl.json b/package.nls.pl.json index b78f221e02..bdb6666e81 100644 --- a/package.nls.pl.json +++ b/package.nls.pl.json @@ -65,8 +65,8 @@ "configuration.dotnet.projects.enableFileBasedPrograms": "Włącza podgląd środowiska „programy oparte na plikach” (dotnet run app.cs).", "configuration.dotnet.quickInfo.showRemarksInQuickInfo": "Pokaż informacje o uwagach podczas wyświetlania symbolu.", "configuration.dotnet.server.componentPaths": "Umożliwia zastąpienie ścieżki folderu dla wbudowanych składników serwera języka (na przykład przesłonięcie ścieżki roslynDevKit w katalogu rozszerzenia w celu użycia składników skompilowanych lokalnie)", - "configuration.dotnet.server.componentPaths.razorDevKit": "Overrides the folder path for the Razor Dev Kit component of the language server", - "configuration.dotnet.server.componentPaths.razorExtension": "Overrides the folder path for the Razor extension component of the language server", + "configuration.dotnet.server.componentPaths.razorDevKit": "Zastępuje ścieżkę folderu składnika Razor Dev Kit serwera języka", + "configuration.dotnet.server.componentPaths.razorExtension": "Zastępuje ścieżkę folderu składnika rozszerzenia Razor serwera języka", "configuration.dotnet.server.componentPaths.roslynCopilot": "Przesłania ścieżkę folderu dla składnika .roslynCopilot serwera językowego", "configuration.dotnet.server.componentPaths.roslynDevKit": "Przesłania ścieżkę folderu dla składnika roslynDevKit serwera językowego", "configuration.dotnet.server.componentPaths.xamlTools": "Zastępuje ścieżkę folderu dla składnika xamlTools serwera języka", diff --git a/package.nls.pt-br.json b/package.nls.pt-br.json index 3732b1d020..4eb622bbed 100644 --- a/package.nls.pt-br.json +++ b/package.nls.pt-br.json @@ -65,8 +65,8 @@ "configuration.dotnet.projects.enableFileBasedPrograms": "Habilita a experiência de prévia \"programas baseados em arquivo\" (dotnet run app.cs).", "configuration.dotnet.quickInfo.showRemarksInQuickInfo": "Mostrar informações de comentários ao exibir o símbolo.", "configuration.dotnet.server.componentPaths": "Permite substituir o caminho da pasta para componentes internos do servidor de linguagem (por exemplo, substituir o caminho .roslynDevKit no diretório de extensão para usar componentes compilados localmente)", - "configuration.dotnet.server.componentPaths.razorDevKit": "Overrides the folder path for the Razor Dev Kit component of the language server", - "configuration.dotnet.server.componentPaths.razorExtension": "Overrides the folder path for the Razor extension component of the language server", + "configuration.dotnet.server.componentPaths.razorDevKit": "Substitui o caminho da pasta para o componente do Kit de Desenvolvimento do Razor do servidor de linguagem", + "configuration.dotnet.server.componentPaths.razorExtension": "Substitui o caminho da pasta para o componente de extensão Razor do servidor de linguagem", "configuration.dotnet.server.componentPaths.roslynCopilot": "Substitui o caminho da pasta para o componente .roslynCopilot do servidor de idiomas", "configuration.dotnet.server.componentPaths.roslynDevKit": "Substitui o caminho da pasta para o componente .roslynDevKit do servidor de linguagem", "configuration.dotnet.server.componentPaths.xamlTools": "Substitui o caminho da pasta para o componente .xamlTools do servidor de linguagem", diff --git a/package.nls.ru.json b/package.nls.ru.json index f8f6a2f242..1a7018c80a 100644 --- a/package.nls.ru.json +++ b/package.nls.ru.json @@ -65,8 +65,8 @@ "configuration.dotnet.projects.enableFileBasedPrograms": "Включает предварительный просмотр \"программ на основе файлов\" (dotnet run app.cs).", "configuration.dotnet.quickInfo.showRemarksInQuickInfo": "Показывать примечания при отображении символа.", "configuration.dotnet.server.componentPaths": "Позволяет переопределить путь к папке для встроенных компонентов языкового сервера (например, переопределить путь .roslynDevKit в каталоге расширения для использования локально созданных компонентов).", - "configuration.dotnet.server.componentPaths.razorDevKit": "Overrides the folder path for the Razor Dev Kit component of the language server", - "configuration.dotnet.server.componentPaths.razorExtension": "Overrides the folder path for the Razor extension component of the language server", + "configuration.dotnet.server.componentPaths.razorDevKit": "Переопределяет путь к папке для компонента Razor Dev Kit языкового сервера", + "configuration.dotnet.server.componentPaths.razorExtension": "Переопределяет путь к папке для компонента расширения Razor языкового сервера", "configuration.dotnet.server.componentPaths.roslynCopilot": "Переопределяет путь к папке для компонента .roslynCopilot языкового сервера", "configuration.dotnet.server.componentPaths.roslynDevKit": "Переопределяет путь к папке для компонента .roslynDevKit языкового сервера.", "configuration.dotnet.server.componentPaths.xamlTools": "Переопределяет путь к папке для компонента .xamlTools языкового сервера.", diff --git a/package.nls.tr.json b/package.nls.tr.json index a411cd7067..99ac9f5a44 100644 --- a/package.nls.tr.json +++ b/package.nls.tr.json @@ -65,8 +65,8 @@ "configuration.dotnet.projects.enableFileBasedPrograms": "\"Dosya tabanlı programlar\" (dotnet run app.cs) önizleme deneyimini etkinleştirir.", "configuration.dotnet.quickInfo.showRemarksInQuickInfo": "Simge görüntülendiğinde açıklama bilgilerini göster.", "configuration.dotnet.server.componentPaths": "Dil sunucusundaki yerleşik bileşenlerin klasör yolunu geçersiz kılmaya olanak tanır (örneğin, yerel olarak oluşturulan bileşenleri kullanmak için uzantı dizinindeki .roslynDevKit yolunu geçersiz kılın)", - "configuration.dotnet.server.componentPaths.razorDevKit": "Overrides the folder path for the Razor Dev Kit component of the language server", - "configuration.dotnet.server.componentPaths.razorExtension": "Overrides the folder path for the Razor extension component of the language server", + "configuration.dotnet.server.componentPaths.razorDevKit": "Dil sunucusundaki Razor Geliştirme Paketi bileşeninin klasör yolunu geçersiz kılar", + "configuration.dotnet.server.componentPaths.razorExtension": "Dil sunucusundaki Razor uzantısı bileşeninin klasör yolunu geçersiz kılar", "configuration.dotnet.server.componentPaths.roslynCopilot": "Dil sunucusunun .roslynCopilot bileşeninin klasör yolunu geçersiz kılar", "configuration.dotnet.server.componentPaths.roslynDevKit": "Dil sunucusundaki .roslynDevKit bileşeninin klasör yolunu geçersiz kılar", "configuration.dotnet.server.componentPaths.xamlTools": "Dil sunucusundaki .xamlTools bileşeninin klasör yolunu geçersiz kılar", diff --git a/package.nls.zh-cn.json b/package.nls.zh-cn.json index 885fa2f58e..419f5ac4d1 100644 --- a/package.nls.zh-cn.json +++ b/package.nls.zh-cn.json @@ -65,8 +65,8 @@ "configuration.dotnet.projects.enableFileBasedPrograms": "启用预览“基于文件的程序”(dotnet run app.cs)体验。", "configuration.dotnet.quickInfo.showRemarksInQuickInfo": "显示符号时显示备注信息。", "configuration.dotnet.server.componentPaths": "允许替代语言服务器内置组件的文件夹路径(例如,替代扩展目录中的 .roslynDevKit 路径以使用本地生成的组件)", - "configuration.dotnet.server.componentPaths.razorDevKit": "Overrides the folder path for the Razor Dev Kit component of the language server", - "configuration.dotnet.server.componentPaths.razorExtension": "Overrides the folder path for the Razor extension component of the language server", + "configuration.dotnet.server.componentPaths.razorDevKit": "替代语言服务器的 Razor 开发工具包组件的文件夹路径", + "configuration.dotnet.server.componentPaths.razorExtension": "替代语言服务器的 Razor 扩展组件的文件夹路径", "configuration.dotnet.server.componentPaths.roslynCopilot": "替代语言服务器的 .roslynCopilot 组件的文件夹路径", "configuration.dotnet.server.componentPaths.roslynDevKit": "替代语言服务器的 .roslynDevKit 组件的文件夹路径", "configuration.dotnet.server.componentPaths.xamlTools": "替代语言服务器的 .xamlTools 组件的文件夹路径", diff --git a/package.nls.zh-tw.json b/package.nls.zh-tw.json index 9cda6e9072..6890d5296a 100644 --- a/package.nls.zh-tw.json +++ b/package.nls.zh-tw.json @@ -65,8 +65,8 @@ "configuration.dotnet.projects.enableFileBasedPrograms": "啟用「檔案型程式」 (dotnet run app.cs) 的預覽體驗。", "configuration.dotnet.quickInfo.showRemarksInQuickInfo": "顯示符號時顯示備註資訊。", "configuration.dotnet.server.componentPaths": "允許覆寫語言伺服器內建元件的資料夾路徑 (例如,覆寫延伸模組目錄中的 .roslynDevKit 路徑,以使用本機建置的元件)", - "configuration.dotnet.server.componentPaths.razorDevKit": "Overrides the folder path for the Razor Dev Kit component of the language server", - "configuration.dotnet.server.componentPaths.razorExtension": "Overrides the folder path for the Razor extension component of the language server", + "configuration.dotnet.server.componentPaths.razorDevKit": "覆寫語言伺服器 Razor 開發套件元件的資料夾路徑", + "configuration.dotnet.server.componentPaths.razorExtension": "覆寫語言伺服器 Razor 延伸模組元件的資料夾路徑", "configuration.dotnet.server.componentPaths.roslynCopilot": "覆寫語言伺服器 .roslynCopilot 元件的資料夾路徑", "configuration.dotnet.server.componentPaths.roslynDevKit": "覆寫語言伺服器 .roslynDevKit 元件的資料夾路徑", "configuration.dotnet.server.componentPaths.xamlTools": "覆寫語言伺服器 .xamlTools 元件的資料夾路徑", diff --git a/src/installRuntimeDependencies.ts b/src/installRuntimeDependencies.ts index 7218d6c931..3cdab86cd2 100644 --- a/src/installRuntimeDependencies.ts +++ b/src/installRuntimeDependencies.ts @@ -8,7 +8,7 @@ import { PackageInstallation, LogPlatformInfo, InstallationSuccess } from './sha import { EventStream } from './eventStream'; import { getRuntimeDependenciesPackages } from './tools/runtimeDependencyPackageUtils'; import { getAbsolutePathPackagesToInstall } from './packageManager/getAbsolutePathPackagesToInstall'; -import IInstallDependencies from './packageManager/IInstallDependencies'; +import { DependencyInstallationStatus, IInstallDependencies } from './packageManager/IInstallDependencies'; import { AbsolutePathPackage } from './packageManager/absolutePathPackage'; export async function installRuntimeDependencies( @@ -19,26 +19,39 @@ export async function installRuntimeDependencies( platformInfo: PlatformInformation, useFramework: boolean, requiredPackageIds: string[] -): Promise { +): Promise { const runTimeDependencies = getRuntimeDependenciesPackages(packageJSON); const packagesToInstall = await getAbsolutePathPackagesToInstall(runTimeDependencies, platformInfo, extensionPath); + + // PackagesToInstall will only return packages that are not already installed. However, + // we need to return the installation status of all required packages, so we need to + // track which required packages are already installed, so that we can return true for them. + const installedPackages = requiredPackageIds.filter( + (id) => packagesToInstall.find((pkg) => pkg.id === id) === undefined + ); + const installedPackagesResults = installedPackages.reduce((acc, id) => ({ ...acc, [id]: true }), {}); + const filteredPackages = filterOmniSharpPackage(packagesToInstall, useFramework); const filteredRequiredPackages = filteredRequiredPackage(requiredPackageIds, filteredPackages); - if (filteredRequiredPackages.length > 0) { - eventStream.post(new PackageInstallation('C# dependencies')); - // Display platform information and RID - eventStream.post(new LogPlatformInfo(platformInfo)); + if (filteredRequiredPackages.length === 0) { + return installedPackagesResults; + } + + eventStream.post(new PackageInstallation('C# dependencies')); + // Display platform information and RID + eventStream.post(new LogPlatformInfo(platformInfo)); + + const installationResults = await installDependencies(filteredRequiredPackages); - if (await installDependencies(filteredRequiredPackages)) { - eventStream.post(new InstallationSuccess()); - } else { - return false; - } + const failedPackages = Object.entries(installationResults) + .filter(([, installed]) => !installed) + .map(([name]) => name); + if (failedPackages.length === 0) { + eventStream.post(new InstallationSuccess()); } - //All the required packages are already downloaded and installed - return true; + return { ...installedPackagesResults, ...installationResults }; } function filterOmniSharpPackage(packages: AbsolutePathPackage[], useFramework: boolean) { diff --git a/src/lsptoolshost/extensions/builtInComponents.ts b/src/lsptoolshost/extensions/builtInComponents.ts index af657fa165..4f67c80e28 100644 --- a/src/lsptoolshost/extensions/builtInComponents.ts +++ b/src/lsptoolshost/extensions/builtInComponents.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import * as vscode from 'vscode'; import * as fs from 'fs'; import * as path from 'path'; import { LanguageServerOptions } from '../../shared/options'; @@ -11,6 +12,7 @@ interface ComponentInfo { defaultFolderName: string; optionName: string; componentDllPaths: string[]; + isOptional?: boolean; } export const componentInfo: { [key: string]: ComponentInfo } = { @@ -41,15 +43,27 @@ export const componentInfo: { [key: string]: ComponentInfo } = { defaultFolderName: '.roslynCopilot', optionName: 'roslynCopilot', componentDllPaths: ['Microsoft.VisualStudio.Copilot.Roslyn.LanguageServer.dll'], + isOptional: true, }, }; -export function getComponentPaths(componentName: string, options: LanguageServerOptions | undefined): string[] { +export function getComponentPaths( + componentName: string, + options: LanguageServerOptions | undefined, + channel?: vscode.LogOutputChannel +): string[] { const component = componentInfo[componentName]; const baseFolder = getComponentFolderPath(component, options); const paths = component.componentDllPaths.map((dllPath) => path.join(baseFolder, dllPath)); for (const dllPath of paths) { if (!fs.existsSync(dllPath)) { + if (component.isOptional) { + // Component is optional and doesn't exist - log warning and return empty array + if (channel) { + channel.warn(`Optional component '${componentName}' could not be found at '${dllPath}'.`); + } + return []; + } throw new Error(`Component DLL not found: ${dllPath}`); } } diff --git a/src/lsptoolshost/server/roslynLanguageServer.ts b/src/lsptoolshost/server/roslynLanguageServer.ts index 8d1951d1f4..6ddc1ccadc 100644 --- a/src/lsptoolshost/server/roslynLanguageServer.ts +++ b/src/lsptoolshost/server/roslynLanguageServer.ts @@ -651,7 +651,7 @@ export class RoslynLanguageServer { : razorOptions.razorServerPath; let razorComponentPath = ''; - getComponentPaths('razorExtension', languageServerOptions).forEach((extPath) => { + getComponentPaths('razorExtension', languageServerOptions, channel).forEach((extPath) => { additionalExtensionPaths.push(extPath); razorComponentPath = path.dirname(extPath); }); @@ -695,10 +695,10 @@ export class RoslynLanguageServer { // Set command enablement as soon as we know devkit is available. await vscode.commands.executeCommand('setContext', 'dotnet.server.activationContext', 'RoslynDevKit'); - const csharpDevKitArgs = this.getCSharpDevKitExportArgs(additionalExtensionPaths); + const csharpDevKitArgs = this.getCSharpDevKitExportArgs(additionalExtensionPaths, channel); args = args.concat(csharpDevKitArgs); - await this.setupDevKitEnvironment(dotnetInfo.env, csharpDevkitExtension, additionalExtensionPaths); + await this.setupDevKitEnvironment(dotnetInfo.env, csharpDevkitExtension, additionalExtensionPaths, channel); } else { // C# Dev Kit is not installed - continue C#-only activation. channel.info('Activating C# standalone...'); @@ -1012,10 +1012,13 @@ export class RoslynLanguageServer { ); } - private static getCSharpDevKitExportArgs(additionalExtensionPaths: string[]): string[] { + private static getCSharpDevKitExportArgs( + additionalExtensionPaths: string[], + channel: vscode.LogOutputChannel + ): string[] { const args: string[] = []; - const devKitDepsPath = getComponentPaths('roslynDevKit', languageServerOptions); + const devKitDepsPath = getComponentPaths('roslynDevKit', languageServerOptions, channel); if (devKitDepsPath.length > 1) { throw new Error('Expected only one devkit deps path'); } @@ -1026,7 +1029,7 @@ export class RoslynLanguageServer { // Also include the Xaml Dev Kit extensions, if enabled. if (languageServerOptions.enableXamlTools) { - getComponentPaths('xamlTools', languageServerOptions).forEach((path) => + getComponentPaths('xamlTools', languageServerOptions, channel).forEach((path) => additionalExtensionPaths.push(path) ); } @@ -1086,7 +1089,8 @@ export class RoslynLanguageServer { private static async setupDevKitEnvironment( env: NodeJS.ProcessEnv, csharpDevkitExtension: vscode.Extension, - additionalExtensionPaths: string[] + additionalExtensionPaths: string[], + channel: vscode.LogOutputChannel ): Promise { const exports: CSharpDevKitExports = await csharpDevkitExtension.activate(); @@ -1096,7 +1100,7 @@ export class RoslynLanguageServer { await exports.setupTelemetryEnvironmentAsync(env); } - getComponentPaths('roslynCopilot', languageServerOptions).forEach((extPath) => { + getComponentPaths('roslynCopilot', languageServerOptions, channel).forEach((extPath) => { additionalExtensionPaths.push(extPath); }); } diff --git a/src/main.ts b/src/main.ts index 977e415f5f..434e2e9c52 100644 --- a/src/main.ts +++ b/src/main.ts @@ -17,7 +17,7 @@ import { vscodeNetworkSettingsProvider } from './networkSettings'; import createOptionStream from './shared/observables/createOptionStream'; import { AbsolutePathPackage } from './packageManager/absolutePathPackage'; import { downloadAndInstallPackages } from './packageManager/downloadAndInstallPackages'; -import IInstallDependencies from './packageManager/IInstallDependencies'; +import { IInstallDependencies } from './packageManager/IInstallDependencies'; import { installRuntimeDependencies } from './installRuntimeDependencies'; import { isValidDownload } from './packageManager/isValidDownload'; import { MigrateOptions } from './shared/migrateOptions'; @@ -86,7 +86,7 @@ export async function activate( const networkSettingsProvider = vscodeNetworkSettingsProvider(vscode); const useFramework = useOmnisharpServer && omnisharpOptions.useModernNet !== true; const installDependencies: IInstallDependencies = async (dependencies: AbsolutePathPackage[]) => - downloadAndInstallPackages(dependencies, networkSettingsProvider, eventStream, isValidDownload); + downloadAndInstallPackages(dependencies, networkSettingsProvider, eventStream, isValidDownload, reporter); const runtimeDependenciesExist = await installRuntimeDependencies( context.extension.packageJSON, @@ -119,7 +119,7 @@ export async function activate( } else { const getCoreClrDebugPromise = async (languageServerStartedPromise: Promise) => { let coreClrDebugPromise = Promise.resolve(); - if (runtimeDependenciesExist) { + if (runtimeDependenciesExist['Debugger']) { // activate coreclr-debug coreClrDebugPromise = coreclrdebug.activate( context.extension, diff --git a/src/omnisharp/omnisharpDownloader.ts b/src/omnisharp/omnisharpDownloader.ts index 03be20748f..dd0ea5bab0 100644 --- a/src/omnisharp/omnisharpDownloader.ts +++ b/src/omnisharp/omnisharpDownloader.ts @@ -19,6 +19,7 @@ import { getRuntimeDependenciesPackages } from '../tools/runtimeDependencyPackag import { getAbsolutePathPackagesToInstall } from '../packageManager/getAbsolutePathPackagesToInstall'; import { isValidDownload } from '../packageManager/isValidDownload'; import { LatestBuildDownloadStart } from './omnisharpLoggingEvents'; +import { ITelemetryReporter } from '../shared/telemetryReporter'; export class OmnisharpDownloader { public constructor( @@ -26,7 +27,8 @@ export class OmnisharpDownloader { private eventStream: EventStream, private packageJSON: any, private platformInfo: PlatformInformation, - private extensionPath: string + private extensionPath: string, + private reporter?: ITelemetryReporter ) {} public async DownloadAndInstallOmnisharp( @@ -51,14 +53,17 @@ export class OmnisharpDownloader { if (packagesToInstall.length > 0) { this.eventStream.post(new PackageInstallation(`OmniSharp Version = ${version}`)); this.eventStream.post(new LogPlatformInfo(this.platformInfo)); - if ( - await downloadAndInstallPackages( - packagesToInstall, - this.networkSettingsProvider, - this.eventStream, - isValidDownload - ) - ) { + const installationResults = await downloadAndInstallPackages( + packagesToInstall, + this.networkSettingsProvider, + this.eventStream, + isValidDownload, + this.reporter + ); + const failedPackages = Object.entries(installationResults) + .filter(([, installed]) => !installed) + .map(([name]) => name); + if (failedPackages.length === 0) { this.eventStream.post(new InstallationSuccess()); return true; } diff --git a/src/omnisharp/omnisharpLanguageServer.ts b/src/omnisharp/omnisharpLanguageServer.ts index 619a10ba1a..1c5325c328 100644 --- a/src/omnisharp/omnisharpLanguageServer.ts +++ b/src/omnisharp/omnisharpLanguageServer.ts @@ -154,7 +154,8 @@ export async function activateOmniSharpLanguageServer( eventStream, context.extension.packageJSON, platformInfo, - context.extension.extensionPath + context.extension.extensionPath, + reporter ); await razorOmnisharpDownloader.DownloadAndInstallRazorOmnisharp( @@ -178,7 +179,8 @@ export async function activateOmniSharpLanguageServer( networkSettingsProvider, eventStream, context.extension.extensionPath, - omnisharpChannel + omnisharpChannel, + reporter ); } @@ -189,7 +191,8 @@ async function activate( provider: NetworkSettingsProvider, eventStream: EventStream, extensionPath: string, - outputChannel: vscode.OutputChannel + outputChannel: vscode.OutputChannel, + reporter: ITelemetryReporter ) { const disposables = new CompositeDisposable(); @@ -211,7 +214,8 @@ async function activate( omnisharpDotnetResolver, context, outputChannel, - languageMiddlewareFeature + languageMiddlewareFeature, + reporter ); const advisor = new Advisor(server); // create before server is started const testManager = new TestManager(server, eventStream, languageMiddlewareFeature); diff --git a/src/omnisharp/server.ts b/src/omnisharp/server.ts index bc60e6f8b8..49a2cc879d 100644 --- a/src/omnisharp/server.ts +++ b/src/omnisharp/server.ts @@ -34,6 +34,7 @@ import TestManager from './features/dotnetTest'; import { findLaunchTargets } from './launcher'; import { ProjectConfigurationMessage } from '../shared/projectConfiguration'; import { commonOptions, omnisharpOptions, razorOptions } from '../shared/options'; +import { ITelemetryReporter } from '../shared/telemetryReporter'; enum ServerState { Starting, @@ -117,14 +118,16 @@ export class OmniSharpServer { private dotnetResolver: IHostExecutableResolver, private context: ExtensionContext, private outputChannel: OutputChannel, - private languageMiddlewareFeature: LanguageMiddlewareFeature + private languageMiddlewareFeature: LanguageMiddlewareFeature, + reporter: ITelemetryReporter ) { const downloader = new OmnisharpDownloader( networkSettingsProvider, this.eventStream, this.packageJSON, platformInfo, - extensionPath + extensionPath, + reporter ); this._omnisharpManager = new OmnisharpManager(downloader, platformInfo); this.updateProjectDebouncer.pipe(debounceTime(1500)).subscribe(async (_) => { diff --git a/src/packageManager/IInstallDependencies.ts b/src/packageManager/IInstallDependencies.ts index 6ca5a476f1..d4c12b3cfc 100644 --- a/src/packageManager/IInstallDependencies.ts +++ b/src/packageManager/IInstallDependencies.ts @@ -5,6 +5,8 @@ import { AbsolutePathPackage } from './absolutePathPackage'; -export default interface IInstallDependencies { - (packages: AbsolutePathPackage[]): Promise; +export type DependencyInstallationStatus = { [name: string]: boolean }; + +export interface IInstallDependencies { + (packages: AbsolutePathPackage[]): Promise; } diff --git a/src/packageManager/downloadAndInstallPackages.ts b/src/packageManager/downloadAndInstallPackages.ts index a148a666e4..da39e0e352 100644 --- a/src/packageManager/downloadAndInstallPackages.ts +++ b/src/packageManager/downloadAndInstallPackages.ts @@ -16,15 +16,19 @@ import { mkdirpSync } from 'fs-extra'; import { PackageInstallStart } from '../shared/loggingEvents'; import { DownloadValidator } from './isValidDownload'; import { CancellationToken } from 'vscode'; +import { ITelemetryReporter } from '../shared/telemetryReporter'; +import { DependencyInstallationStatus } from './IInstallDependencies'; export async function downloadAndInstallPackages( packages: AbsolutePathPackage[], provider: NetworkSettingsProvider, eventStream: EventStream, downloadValidator: DownloadValidator, + telemetryReporter?: ITelemetryReporter, token?: CancellationToken -): Promise { +): Promise { eventStream.post(new PackageInstallStart()); + const results: DependencyInstallationStatus = {}; for (const pkg of packages) { let installationStage = 'touchBeginFile'; try { @@ -48,12 +52,16 @@ export async function downloadAndInstallPackages( await InstallZip(buffer, pkg.description, pkg.installPath, pkg.binaries, eventStream); installationStage = 'touchLockFile'; await touchInstallFile(pkg.installPath, InstallFileType.Lock); + results[pkg.id] = true; break; } else { eventStream.post(new IntegrityCheckFailure(pkg.description, pkg.url, willTryInstallingPackage())); + results[pkg.id] = false; } } } catch (error) { + results[pkg.id] = false; + if (error instanceof NestedError) { const packageError = new PackageError(error.message, pkg, error.err); eventStream.post(new InstallationFailure(installationStage, packageError)); @@ -61,7 +69,8 @@ export async function downloadAndInstallPackages( eventStream.post(new InstallationFailure(installationStage, error)); } - return false; + // Send telemetry for the failure + sendInstallationFailureTelemetry(pkg, installationStage, error); } finally { try { if (await installFileExists(pkg.installPath, InstallFileType.Begin)) { @@ -73,5 +82,26 @@ export async function downloadAndInstallPackages( } } - return true; + return results; + + function sendInstallationFailureTelemetry(pkg: AbsolutePathPackage, installationStage: string, error: any): void { + if (!telemetryReporter) { + return; + } + + const telemetryProperties: { [key: string]: string } = { + installStage: installationStage, + packageId: pkg.id, + }; + + if (error instanceof NestedError && error.err instanceof PackageError) { + telemetryProperties['error.message'] = error.err.message; + telemetryProperties['error.packageUrl'] = error.err.pkg.url; + } else if (error instanceof PackageError) { + telemetryProperties['error.message'] = error.message; + telemetryProperties['error.packageUrl'] = error.pkg.url; + } + + telemetryReporter.sendTelemetryEvent('PackageInstallationFailed', telemetryProperties); + } } diff --git a/src/razor/razorOmnisharpDownloader.ts b/src/razor/razorOmnisharpDownloader.ts index 965f7cf99a..83ffd4edc5 100644 --- a/src/razor/razorOmnisharpDownloader.ts +++ b/src/razor/razorOmnisharpDownloader.ts @@ -11,6 +11,7 @@ import { downloadAndInstallPackages } from '../packageManager/downloadAndInstall import { getRuntimeDependenciesPackages } from '../tools/runtimeDependencyPackageUtils'; import { getAbsolutePathPackagesToInstall } from '../packageManager/getAbsolutePathPackagesToInstall'; import { isValidDownload } from '../packageManager/isValidDownload'; +import { ITelemetryReporter } from '../shared/telemetryReporter'; export class RazorOmnisharpDownloader { public constructor( @@ -18,7 +19,8 @@ export class RazorOmnisharpDownloader { private eventStream: EventStream, private packageJSON: any, private platformInfo: PlatformInformation, - private extensionPath: string + private extensionPath: string, + private reporter?: ITelemetryReporter ) {} public async DownloadAndInstallRazorOmnisharp(version: string): Promise { @@ -33,14 +35,17 @@ export class RazorOmnisharpDownloader { if (packagesToInstall.length > 0) { this.eventStream.post(new PackageInstallation(`Razor OmniSharp Version = ${version}`)); this.eventStream.post(new LogPlatformInfo(this.platformInfo)); - if ( - await downloadAndInstallPackages( - packagesToInstall, - this.networkSettingsProvider, - this.eventStream, - isValidDownload - ) - ) { + const installationResults = await downloadAndInstallPackages( + packagesToInstall, + this.networkSettingsProvider, + this.eventStream, + isValidDownload, + this.reporter + ); + const failedPackages = Object.entries(installationResults) + .filter(([, installed]) => !installed) + .map(([name]) => name); + if (failedPackages.length === 0) { this.eventStream.post(new InstallationSuccess()); return true; } diff --git a/src/razor/src/extension.ts b/src/razor/src/extension.ts index 8fdac6c67b..a2555ac0b7 100644 --- a/src/razor/src/extension.ts +++ b/src/razor/src/extension.ts @@ -104,7 +104,7 @@ export async function activate( await setupDevKitEnvironment(dotnetInfo.env, csharpDevkitExtension, logger); if (vscode.env.isTelemetryEnabled) { - const razorComponentPaths = getComponentPaths('razorDevKit', undefined); + const razorComponentPaths = getComponentPaths('razorDevKit', undefined, logger.outputChannel); if (razorComponentPaths.length !== 1) { logger.logError('Failed to find Razor DevKit telemetry extension path.', undefined); } else { diff --git a/tasks/offlinePackagingTasks.ts b/tasks/offlinePackagingTasks.ts index 531e0b7adf..af16c0e1a0 100644 --- a/tasks/offlinePackagingTasks.ts +++ b/tasks/offlinePackagingTasks.ts @@ -280,8 +280,19 @@ async function installPackageJsonDependency( codeExtensionPath ); const provider = () => new NetworkSettings('', true); - if (!(await downloadAndInstallPackages(packagesToInstall, provider, eventStream, isValidDownload, token))) { - throw Error('Failed to download package.'); + const installationResults = await downloadAndInstallPackages( + packagesToInstall, + provider, + eventStream, + isValidDownload, + undefined, + token + ); + const failedPackages = Object.entries(installationResults) + .filter(([, installed]) => !installed) + .map(([name]) => name); + if (failedPackages.length > 0) { + throw Error('The following packages failed to install: ' + failedPackages.join(', ')); } } diff --git a/test/omnisharp/omnisharpUnitTests/installRuntimeDependencies.test.ts b/test/omnisharp/omnisharpUnitTests/installRuntimeDependencies.test.ts index e1a3b89f70..0ce27b8f82 100644 --- a/test/omnisharp/omnisharpUnitTests/installRuntimeDependencies.test.ts +++ b/test/omnisharp/omnisharpUnitTests/installRuntimeDependencies.test.ts @@ -5,7 +5,7 @@ import { describe, test, expect, beforeEach } from '@jest/globals'; import { installRuntimeDependencies } from '../../../src/installRuntimeDependencies'; -import IInstallDependencies from '../../../src/packageManager/IInstallDependencies'; +import { IInstallDependencies } from '../../../src/packageManager/IInstallDependencies'; import { EventStream } from '../../../src/eventStream'; import { PlatformInformation } from '../../../src/shared/platform'; import TestEventBus from './testAssets/testEventBus'; @@ -28,7 +28,8 @@ describe(`${installRuntimeDependencies.name}`, () => { beforeEach(() => { eventStream = new EventStream(); eventBus = new TestEventBus(eventStream); - installDependencies = async () => Promise.resolve(true); + installDependencies = async (packages) => + Promise.resolve(packages.reduce((acc, pkg) => ({ ...acc, [pkg.id]: true }), {})); }); describe('When all the dependencies already exist', () => { @@ -48,7 +49,9 @@ describe(`${installRuntimeDependencies.name}`, () => { useFramework, ['Debugger', 'Omnisharp', 'Razor'] ); - expect(installed).toBe(true); + expect(installed['Debugger']).toBe(true); + expect(installed['Omnisharp']).toBe(true); + expect(installed['Razor']).toBe(true); }); test("Doesn't log anything to the eventStream", async () => { @@ -90,7 +93,7 @@ describe(`${installRuntimeDependencies.name}`, () => { let inputPackage: AbsolutePathPackage[]; installDependencies = async (packages) => { inputPackage = packages; - return Promise.resolve(true); + return Promise.resolve(packages.reduce((acc, pkg) => ({ ...acc, [pkg.id]: true }), {})); }; const installed = await installRuntimeDependencies( @@ -102,7 +105,7 @@ describe(`${installRuntimeDependencies.name}`, () => { useFramework, ['myPackage'] ); - expect(installed).toBe(true); + expect(installed['myPackage']).toBe(true); isNotNull(inputPackage!); expect(inputPackage).toHaveLength(1); expect(inputPackage[0]).toStrictEqual( @@ -111,7 +114,8 @@ describe(`${installRuntimeDependencies.name}`, () => { }); test('Returns false when installDependencies returns false', async () => { - installDependencies = async () => Promise.resolve(false); + installDependencies = async (packages) => + Promise.resolve(packages.reduce((acc, pkg) => ({ ...acc, [pkg.id]: false }), {})); const installed = await installRuntimeDependencies( packageJSON, extensionPath, @@ -121,7 +125,7 @@ describe(`${installRuntimeDependencies.name}`, () => { useFramework, ['myPackage'] ); - expect(installed).toBe(false); + expect(installed['myPackage']).toBe(false); }); }); }); diff --git a/version.json b/version.json index 7a429fa0e4..61ed86f69a 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "2.94", + "version": "2.96", "publicReleaseRefSpec": [ "^refs/heads/release$", "^refs/heads/prerelease$",