diff --git a/CHANGELOG.md b/CHANGELOG.md index 907068219..260f5d857 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,8 +12,13 @@ * As a workaround, make an edit within the file before using Rename Symbol. ## 1.23.17 (Not released yet) +* Greatly improved download experience: when the C# extension is downloaded from the VS Code Marketplace, it will include all of its dependencies already ([#4775](https://github.com/OmniSharp/omnisharp-vscode/issues/4775)) * Fix decompilation authorization check ([#4817](https://github.com/OmniSharp/omnisharp-vscode/issues/4817), PR: [#4821](https://github.com/OmniSharp/omnisharp-vscode/pull/4821)) * Fix typo in Readme.md (PR: [#4819](https://github.com/OmniSharp/omnisharp-vscode/pull/4819)) +* Debugger changes: + * The debugger itself runs on .NET 6 RC2 + * Enhanced support for launchSettings.json ([#3121](https://github.com/OmniSharp/omnisharp-vscode/issues/3121)) + * Fixed process listing on Windows 11 (PR: [#4848](https://github.com/OmniSharp/omnisharp-vscode/pull/4848)) _(Many thanks to [@eternalphane](https://github.com/eternalphane))_ ## 1.23.16 (Oct 12th, 2021) * Show decompilation authorization once per install. ([#3982](https://github.com/OmniSharp/omnisharp-vscode/issues/3982), PR: [#4760](https://github.com/OmniSharp/omnisharp-vscode/pull/4760)) diff --git a/debugger-launchjson.md b/debugger-launchjson.md index fe5b1ec04..c694d4e9c 100644 --- a/debugger-launchjson.md +++ b/debugger-launchjson.md @@ -108,9 +108,26 @@ Environment variables may be passed to your program using this schema: "myVariableName":"theValueGoesHere" } -NOTE: Environment variables can also be configured through a `${cwd}/Properties/launchSettings.json` file, which is useful for environment variables that should be set in all development scenarios -- when the project is started from the command line (`dotnet run`), from Visual Studio Code, or Visual Studio. +## Console (terminal) window + +The `"console"` setting controls what console (terminal) window the target app is launched into. It can be set to any of these values -- + +`"internalConsole"` (default) : the target process's console output (stdout/stderr) goes to the VS Code Debug Console. This is useful for executables that take their input from the network, files, etc. But this does **NOT** work for applications that want to read from the console (ex: `Console.ReadLine`). + +`"integratedTerminal"` : the target process will run inside [VS Code's integrated terminal](https://code.visualstudio.com/docs/editor/integrated-terminal). Click the 'Terminal' tab in the tab group beneath the editor to interact with your application. Alternatively add `"internalConsoleOptions": "neverOpen"` to make it so that the default foreground tab is the terminal tab. + +`"externalTerminal"`: the target process will run inside its own external terminal. + +## launchSettings.json support -Example Properties/launchSettings.json file: +In addition to launch.json, launch options can be configured through a {cwd}/Properties/launchSettings.json file. The advantage of +launchSettings.json is that it allows settings to be shared between Visual Studio Code, full Visual Studio, and `dotnet run`. + +To configure which launchSettings.json profile to use (or to prevent it from being used), set the `launchSettingsProfile` option: + + "launchSettingsProfile": "ProfileNameGoesHere" + +Which would then, for example, use `myVariableName` from this example launchSettings.json file: ```json { @@ -125,15 +142,17 @@ Example Properties/launchSettings.json file: } ``` -## Console (terminal) window - -The `"console"` setting controls what console (terminal) window the target app is launched into. It can be set to any of these values -- +If `launchSettingsProfile` is NOT specified, the first profile with `"commandName": "Project"` will be used. -`"internalConsole"` (default) : the target process's console output (stdout/stderr) goes to the VS Code Debug Console. This is useful for executables that take their input from the network, files, etc. But this does **NOT** work for applications that want to read from the console (ex: `Console.ReadLine`). +If `launchSettingsProfile` is set to null/an empty string, then Properties/launchSettings.json will be ignored. -`"integratedTerminal"` : the target process will run inside [VS Code's integrated terminal](https://code.visualstudio.com/docs/editor/integrated-terminal). Click the 'Terminal' tab in the tab group beneath the editor to interact with your application. Alternatively add `"internalConsoleOptions": "neverOpen"` to make it so that the default foreground tab is the terminal tab. - -`"externalTerminal"`: the target process will run inside its own external terminal. +Restrictions: +1. The launchSettings.json file must be in {cwd}/Properties/launchSettings.json +2. Only profiles with `"commandName": "Project"` are supported. +3. Only `environmentVariables`, `applicationUrl` and `commandLineArgs` properties are supported +4. Settings in launch.json will take precedence over settings in launchSettings.json, so for example, if `args` +is already set to something other than an empty string/array in `launch.json` then the launchSettings.json +content will be ignored. ## Source File Map You can optionally configure how source files are opened by providing a map using this form: diff --git a/package.json b/package.json index 67191b92c..ce9449a14 100644 --- a/package.json +++ b/package.json @@ -217,8 +217,7 @@ { "id": "Debugger", "description": ".NET Core Debugger (Windows / x64)", - "url": "https://download.visualstudio.microsoft.com/download/pr/49f44239-bd47-4fb5-91be-4c91d7638fff/b490d6a6de4ec50e2bd22f690489ef6c/coreclr-debug-win7-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-23-14/coreclr-debug-win7-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-23-17/coreclr-debug-win7-x64.zip", "installPath": ".debugger", "platforms": [ "win32" @@ -227,13 +226,12 @@ "x86_64" ], "installTestPath": "./.debugger/vsdbg-ui.exe", - "integrity": "9EA16813520F5E74535739DAD1E9E72465D7F496A6C8465AEA3EF57C86CF320C" + "integrity": "DEE5667896B7399AB0AAA1A1CC10C6FB2B7D8F47AB17C12E40ABA97677AB90D3" }, { "id": "Debugger", "description": ".NET Core Debugger (Windows / ARM64)", - "url": "https://download.visualstudio.microsoft.com/download/pr/49f44239-bd47-4fb5-91be-4c91d7638fff/82a75a9c89a2e5087908651b602d7d01/coreclr-debug-win10-arm64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-23-14/coreclr-debug-win10-arm64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-23-17/coreclr-debug-win10-arm64.zip", "installPath": ".debugger", "platforms": [ "win32" @@ -242,13 +240,12 @@ "arm64" ], "installTestPath": "./.debugger/vsdbg-ui.exe", - "integrity": "FD9A1B46DA9C7226828595826F6CE215DF769C5111D02DB567494A1EB095E155" + "integrity": "30BF86A94A1362465B539DC42995BF2E066F0656B2FF53D259B9ADB2A50DBF3E" }, { "id": "Debugger", "description": ".NET Core Debugger (macOS / x64)", - "url": "https://download.visualstudio.microsoft.com/download/pr/49f44239-bd47-4fb5-91be-4c91d7638fff/c1122f7141735472d9583c1124024c55/coreclr-debug-osx-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-23-14/coreclr-debug-osx-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-23-17/coreclr-debug-osx-x64.zip", "installPath": ".debugger/x86_64", "platforms": [ "darwin" @@ -262,13 +259,12 @@ "./vsdbg" ], "installTestPath": "./.debugger/x86_64/vsdbg-ui", - "integrity": "554436E48F02C994BD05AD365EFFF9E242710C49CD2BDE695DBABD222098E323" + "integrity": "EAFB7B0F3489B9F2D89C2BC4CB855729398D25D6F2A6587913732018B9BBB362" }, { "id": "Debugger", "description": ".NET Core Debugger (macOS / arm64)", - "url": "https://download.visualstudio.microsoft.com/download/pr/49f44239-bd47-4fb5-91be-4c91d7638fff/96a88189c7904a517f3bb59b2dba8bd1/coreclr-debug-osx-arm64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-23-14/coreclr-debug-osx-arm64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-23-17/coreclr-debug-osx-arm64.zip", "installPath": ".debugger/arm64", "platforms": [ "darwin" @@ -281,13 +277,12 @@ "./vsdbg" ], "installTestPath": "./.debugger/arm64/vsdbg-ui", - "integrity": "40395770CDBA25FD67D2A5B8630F16146B293EAE8A07205DF1646D1805F87384" + "integrity": "AB272AD7F519FA1564A3C9AA7052D5ADD972A6DDAD7A2B6CA0DF775A7F83704C" }, { "id": "Debugger", "description": ".NET Core Debugger (linux / ARM)", - "url": "https://download.visualstudio.microsoft.com/download/pr/49f44239-bd47-4fb5-91be-4c91d7638fff/f346e34bb51c0595cf7f4727cac76907/coreclr-debug-linux-arm.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-23-14/coreclr-debug-linux-arm.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-23-17/coreclr-debug-linux-arm.zip", "installPath": ".debugger", "platforms": [ "linux" @@ -300,13 +295,12 @@ "./vsdbg" ], "installTestPath": "./.debugger/vsdbg-ui", - "integrity": "4283432742665B400B1807A76770475B2CA43895C7E7870D85E34C3ADF4D1B3F" + "integrity": "C03F6DBE1F84717483C016F67AC92C56391798BAB4EE41D58521588D5EDF1ED0" }, { "id": "Debugger", "description": ".NET Core Debugger (linux / ARM64)", - "url": "https://download.visualstudio.microsoft.com/download/pr/49f44239-bd47-4fb5-91be-4c91d7638fff/7a723bfbda6d196c52084226b6835b36/coreclr-debug-linux-arm64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-23-14/coreclr-debug-linux-arm64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-23-17/coreclr-debug-linux-arm64.zip", "installPath": ".debugger", "platforms": [ "linux" @@ -319,13 +313,12 @@ "./vsdbg" ], "installTestPath": "./.debugger/vsdbg-ui", - "integrity": "7C266186F481159BFC40406BF4CE479FC4144179C69128B01CD3E1E3062E8AB4" + "integrity": "4C3564FE7FBD7403E7B987C44FC4B6E532D177BF179321595D892D7239D1293D" }, { "id": "Debugger", "description": ".NET Core Debugger (linux / x64)", - "url": "https://download.visualstudio.microsoft.com/download/pr/49f44239-bd47-4fb5-91be-4c91d7638fff/dd019b4c839f458596e26bfcfe6a3e7f/coreclr-debug-linux-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-23-14/coreclr-debug-linux-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-23-17/coreclr-debug-linux-x64.zip", "installPath": ".debugger", "platforms": [ "linux" @@ -338,7 +331,7 @@ "./vsdbg" ], "installTestPath": "./.debugger/vsdbg-ui", - "integrity": "F389283020F345DA4BAC1067E9D8E5B28BD4306338C651075D07285D0600BE30" + "integrity": "3CF4619DB967FA71FE04615D1A171B9C03E6CA97335BAC3C0E04116490B73336" }, { "id": "Razor", @@ -1238,6 +1231,18 @@ "description": "Attribute 'externalConsole' is deprecated, use 'console' instead.", "default": false }, + "launchSettingsProfile": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "If specified, indicates the name of the profile in {cwd}/Properties/launchSettings.json to use. This is ignored if launchSettings.json is not found. If this is set to null or an empty string then launchSettings.json is ignored. If this value is not specified the first 'Project' profile will be used.", + "default": "" + }, "sourceFileMap": { "type": "object", "description": "Optional source file mappings passed to the debug engine. Example: '{ \"C:\\foo\":\"/home/user/foo\" }'", @@ -2344,6 +2349,18 @@ "description": "Attribute 'externalConsole' is deprecated, use 'console' instead.", "default": false }, + "launchSettingsProfile": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "If specified, indicates the name of the profile in {cwd}/Properties/launchSettings.json to use. This is ignored if launchSettings.json is not found. If this is set to null or an empty string then launchSettings.json is ignored. If this value is not specified the first 'Project' profile will be used.", + "default": "" + }, "sourceFileMap": { "type": "object", "description": "Optional source file mappings passed to the debug engine. Example: '{ \"C:\\foo\":\"/home/user/foo\" }'", @@ -3750,4 +3767,4 @@ } ] } -} +} \ No newline at end of file diff --git a/src/tools/OptionsSchema.json b/src/tools/OptionsSchema.json index 8dc938413..b1624ab48 100644 --- a/src/tools/OptionsSchema.json +++ b/src/tools/OptionsSchema.json @@ -323,6 +323,18 @@ "description": "Attribute 'externalConsole' is deprecated, use 'console' instead.", "default": false }, + "launchSettingsProfile": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "If specified, indicates the name of the profile in {cwd}/Properties/launchSettings.json to use. This is ignored if launchSettings.json is not found. If this is set to null or an empty string then launchSettings.json is ignored. If this value is not specified the first 'Project' profile will be used.", + "default": "" + }, "sourceFileMap": { "type": "object", "description": "Optional source file mappings passed to the debug engine. Example: '{ \"C:\\foo\":\"/home/user/foo\" }'", diff --git a/src/tools/UpdatePackageDependencies.ts b/src/tools/UpdatePackageDependencies.ts index bf1bb758e..ecb5f665b 100644 --- a/src/tools/UpdatePackageDependencies.ts +++ b/src/tools/UpdatePackageDependencies.ts @@ -28,8 +28,9 @@ export async function updatePackageDependencies(): Promise { const newPrimaryUrls = process.env["NEW_DEPS_URLS"]; const newVersion = process.env["NEW_DEPS_VERSION"]; + const packageId = process.env["NEW_DEPS_ID"]; - if (!newPrimaryUrls || !newVersion) { + if ((!packageId && !newPrimaryUrls) || !newVersion) { console.log(); console.log("'npm run gulp updatePackageDependencies' will update package.json with new URLs of dependencies."); console.log(); @@ -37,57 +38,21 @@ export async function updatePackageDependencies(): Promise { const setEnvVarPrefix = os.platform() === 'win32' ? "set " : "export "; const setEnvVarQuote = os.platform() === 'win32' ? "" : "\'"; console.log(` ${setEnvVarPrefix}NEW_DEPS_URLS=${setEnvVarQuote}https://example1/foo-osx.zip,https://example1/foo-win.zip,https://example1/foo-linux.zip${setEnvVarQuote}`); + console.log("-or-"); + console.log(` ${setEnvVarPrefix}NEW_DEPS_ID=${setEnvVarQuote}Debugger${setEnvVarQuote}`); + console.log("-and-"); console.log(` ${setEnvVarPrefix}NEW_DEPS_VERSION=${setEnvVarQuote}1.2.3${setEnvVarQuote}`); console.log(" npm run gulp updatePackageDependencies"); console.log(); return; } - const newPrimaryUrlArray = newPrimaryUrls.split(','); - for (let urlToUpdate of newPrimaryUrlArray) { - if (!urlToUpdate.startsWith("https://")) { - throw new Error("Unexpected 'NEW_DEPS_URLS' value. All URLs should start with 'https://'."); - } - } - if (! /^[0-9]+\.[0-9]+\.[0-9]+$/.test(newVersion)) { throw new Error("Unexpected 'NEW_DEPS_VERSION' value. Expected format similar to: 1.2.3."); } let packageJSON: PackageJSONFile = JSON.parse(fs.readFileSync('package.json').toString()); - // map from lowercase filename to Package - const mapFileNameToDependency: { [key: string]: Package } = {}; - - // First build the map - packageJSON.runtimeDependencies.forEach(dependency => { - let fileName = getLowercaseFileNameFromUrl(dependency.url); - let existingDependency = mapFileNameToDependency[fileName]; - if (existingDependency !== undefined) { - throw new Error(`Multiple dependencies found with filename '${fileName}': '${existingDependency.url}' and '${dependency.url}'.`); - } - mapFileNameToDependency[fileName] = dependency; - }); - - let findDependencyToUpdate = (url: string): Package => { - let fileName = getLowercaseFileNameFromUrl(url); - let dependency = mapFileNameToDependency[fileName]; - if (dependency === undefined) { - throw new Error(`Unable to update item for url '${url}'. No 'runtimeDependency' found with filename '${fileName}'.`); - } - return dependency; - }; - - // First quickly make sure we could match up the URL to an existing item. - for (let urlToUpdate of newPrimaryUrlArray) { - const dependency = findDependencyToUpdate(urlToUpdate); - //Fallback url should contain a version - verifyVersionSubstringCount(dependency.fallbackUrl, true); - verifyVersionSubstringCount(dependency.installPath); - verifyVersionSubstringCount(dependency.installTestPath); - } - - // Next take another pass to try and update to the URL const eventStream = new EventStream(); eventStream.subscribe((event: Event.BaseEvent) => { switch (event.type) { @@ -104,9 +69,7 @@ export async function updatePackageDependencies(): Promise { return getBufferIntegrityHash(buffer); }; - for (let urlToUpdate of newPrimaryUrlArray) { - let dependency = findDependencyToUpdate(urlToUpdate); - dependency.url = urlToUpdate; + const updateDependency = async (dependency: Package): Promise => { dependency.integrity = await downloadAndGetHash(dependency.url); dependency.fallbackUrl = replaceVersion(dependency.fallbackUrl, newVersion); dependency.installPath = replaceVersion(dependency.installPath, newVersion); @@ -124,6 +87,80 @@ export async function updatePackageDependencies(): Promise { throw new Error(`File downloaded from primary URL '${dependency.url}' doesn't match '${dependency.fallbackUrl}'.`); } } + }; + + if (newPrimaryUrls) { + const newPrimaryUrlArray = newPrimaryUrls.split(','); + for (let urlToUpdate of newPrimaryUrlArray) { + if (!urlToUpdate.startsWith("https://")) { + throw new Error("Unexpected 'NEW_DEPS_URLS' value. All URLs should start with 'https://'."); + } + } + + // map from lowercase filename to Package + const mapFileNameToDependency: { [key: string]: Package } = {}; + + // First build the map + packageJSON.runtimeDependencies.forEach(dependency => { + let fileName = getLowercaseFileNameFromUrl(dependency.url); + let existingDependency = mapFileNameToDependency[fileName]; + if (existingDependency !== undefined) { + throw new Error(`Multiple dependencies found with filename '${fileName}': '${existingDependency.url}' and '${dependency.url}'.`); + } + mapFileNameToDependency[fileName] = dependency; + }); + + let findDependencyToUpdate = (url: string): Package => { + let fileName = getLowercaseFileNameFromUrl(url); + let dependency = mapFileNameToDependency[fileName]; + if (dependency === undefined) { + throw new Error(`Unable to update item for url '${url}'. No 'runtimeDependency' found with filename '${fileName}'.`); + } + return dependency; + }; + + // First quickly make sure we could match up the URL to an existing item. + for (let urlToUpdate of newPrimaryUrlArray) { + const dependency = findDependencyToUpdate(urlToUpdate); + //Fallback url should contain a version + verifyVersionSubstringCount(dependency.fallbackUrl, true); + verifyVersionSubstringCount(dependency.installPath); + verifyVersionSubstringCount(dependency.installTestPath); + } + + for (let urlToUpdate of newPrimaryUrlArray) { + let dependency = findDependencyToUpdate(urlToUpdate); + dependency.url = urlToUpdate; + + await updateDependency(dependency); + } + } + else { + let packageFound = false; + // First quickly make sure that 'url' contains a version + for (let dependency of packageJSON.runtimeDependencies) { + if (dependency.id !== packageId) { + continue; + } + packageFound = true; + verifyVersionSubstringCount(dependency.url, true); + verifyVersionSubstringCount(dependency.fallbackUrl, true); + verifyVersionSubstringCount(dependency.installPath); + verifyVersionSubstringCount(dependency.installTestPath); + } + if (!packageFound) { + throw new Error(`Failed to find package with 'id' of '${packageId}'.`); + } + + // Now update the versions + for (let dependency of packageJSON.runtimeDependencies) { + if (dependency.id !== packageId) { + continue; + } + + dependency.url = replaceVersion(dependency.url, newVersion); + await updateDependency(dependency); + } } let content = JSON.stringify(packageJSON, null, 2);