Skip to content

Commit

Permalink
Merge pull request #56 from JohnCampionJr/debugging
Browse files Browse the repository at this point in the history
VS Code Debugging Improvements
  • Loading branch information
liborpansky authored Jan 6, 2021
2 parents 71da49f + 49bd296 commit 44afe67
Show file tree
Hide file tree
Showing 6 changed files with 284 additions and 46 deletions.
86 changes: 49 additions & 37 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,65 @@
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (web)",
"name": ".NET Core & Vue Server",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"logging": {
"moduleLoad": false
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development",
"VUE_DEV_SERVER_PROGRESS": "true"
},
"cwd": "${workspaceFolder}",
"preLaunchTask": "build-vue-cli-serve",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/bin/Debug/net5.0/AspNetCoreVueStarter.dll",
"args": [],
"cwd": "${workspaceFolder}",
"args": [
"/mode:attach"
],
"stopAtEntry": false,
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
},
// Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser
"serverReadyAction": {
"action": "openExternally",
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
"action": "startDebugging",
"pattern": "\\bNow listening on:\\s+(https?://\\S+)",
"name": "Chrome Browser"
},
// this will kill any stray vue-cli processes, as the .NET app can't shut them down when it is killed by the debugger
"postDebugTask": "kill"
},
{
"name": ".NET Core Web",
"type": "coreclr",
"request": "launch",
"logging": {
"moduleLoad": false
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"cwd": "${workspaceFolder}",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/bin/Debug/net5.0/AspNetCoreVueStarter.dll",
"args": [
"/mode:start"
],
"stopAtEntry": false,
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
}
},
// Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser
"serverReadyAction": {
"action": "startDebugging",
"pattern": "\\bNow listening on:\\s+(https?://\\S+)",
"name": "Chrome Browser"
},
// this will kill any stray vue-cli processes, as the .NET app can't shut them down when it is killed by the debugger
"postDebugTask": "kill"
},
{
"name": ".NET Core Attach",
Expand All @@ -33,47 +72,20 @@
"processId": "${command:pickProcess}"
},
{
"name": "Launch Chrome",
"name": "Chrome Browser",
"type": "chrome",
"request": "launch",
"url": "http://localhost:5000",
"webRoot": "${workspaceFolder}/ClientApp",
"breakOnLoad": true,
"sourceMaps": true,
"sourceMapPathOverrides": {
"webpack:///*": "${webRoot}/*",
"webpack:///./*": "${webRoot}/*",
"webpack:///src/*": "${webRoot}/*"
}
},
{
"name": "Launch Firefox",
"name": "Firefox Browser",
"type": "firefox",
"request": "launch",
"url": "http://localhost:5000",
"webRoot": "${workspaceFolder}/ClientApp",
"pathMappings": [
{
"url": "webpack:///src/",
"path": "${webRoot}/"
}
]
}
],
"compounds": [
{
"name": "Debug SPA and API (Chrome)",
"configurations": [
".NET Core Launch (web)",
"Launch Chrome"
]
},
{
"name": "Debug SPA and API (Firefox)",
"configurations": [
".NET Core Launch (web)",
"Launch Firefox"
]
"webRoot": "${workspaceFolder}/ClientApp"
}
]
}
66 changes: 66 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,72 @@
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "kill",
"command": "dotnet",
"type": "process",
"args": [
"run",
"${workspaceFolder}/bin/Debug/net5.0/AspNetCoreVueStarter.dll",
"/mode:kill"
],
"presentation": {
"echo": false,
"reveal": "never",
"focus": false,
"panel": "shared",
"showReuseMessage": true,
"clear": false
},
"problemMatcher": []
},
{
"label": "vue-cli-serve",
"command": "npm",
"type": "shell",
"isBackground": true,
"options": {
"cwd": "${workspaceFolder}/ClientApp/",
"env": {
"VUE_DEV_SERVER_PROGRESS": "true"
}
},
"args": [
"run",
"serve"
],
"presentation": {
"echo": false,
"reveal": "always",
"focus": false,
"panel": "dedicated",
"showReuseMessage": false,
"clear": true
},
"problemMatcher": [
{
"pattern": [
{
"regexp": ".",
"file": 1,
"location": 2,
"message": 3
}
],
"background": {
"activeOnStart": true,
"beginsPattern": ".",
"endsPattern": "App running at",
}
}
]
},
{
"label": "build-vue-cli-serve",
"dependsOn": ["build", "vue-cli-serve"],
"dependsOrder": "sequence",
}

]
}
2 changes: 1 addition & 1 deletion ClientApp/vue.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ module.exports = {
},
transpileDependencies: ['vuetify'],
devServer: {
progress: false
progress: !!process.env.VUE_DEV_SERVER_PROGRESS
}
}
145 changes: 145 additions & 0 deletions CommandLine.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
// original source: https://www.codeproject.com/Articles/3111/C-NET-Command-Line-Arguments-Parser

using System;
using System.Collections.Specialized;
using System.Text.RegularExpressions;

namespace CommandLine
{
public static class Arguments
{

public static bool TryGetOptions(string[] args, bool inConsole, out string mode, out ushort port, out bool https)
{
var arguments = Parse(args);
var validArgs = true;

mode = arguments["m"] ?? arguments["mode"] ?? "start";
https = arguments["http"] == null && arguments["https"] != null;
var portString = arguments["p"] ?? arguments["port"] ?? "8080";

if (mode != "start" && mode != "attach" && mode != "kill")
{
if (inConsole)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Invalid mode; Allowed values are start | attach | kill");
Console.ResetColor();
}
validArgs = false;
}

if (!ushort.TryParse(portString, out port) || port < 80)
{
if (inConsole)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Invalid port number specified.");
Console.ResetColor();
}
validArgs = false;
}

if (arguments["h"] != null || arguments["help"] != null) validArgs = false;

if (inConsole && !validArgs)
{
Console.WriteLine();
Console.WriteLine(" Mode Argument Options (Defaults to start)");
Console.WriteLine(" -m | --mode start -> Start the SPA server and proxy to that.");
Console.WriteLine(" -m | --mode attach -> Attach to existing SPA server");
Console.WriteLine(" -m | --mode kill -> Shutdown any existing SPA server on the specified port (used after debugging in VS Code)");
Console.WriteLine();
Console.WriteLine(" Port Argument (Defaults to 8080)");
Console.WriteLine(" -p | --port 8080 -> Specify what port to start or attach to, minimum of 80");
Console.WriteLine();
Console.WriteLine(" HTTPS (Defaults to false)");
Console.WriteLine(" -https -> Uses HTTPS");
Console.WriteLine();

}

return validArgs;

}

public static StringDictionary Parse(string[] args)
{
var parameters = new StringDictionary();
Regex splitter = new Regex(@"^-{1,2}|^/|=|:",
RegexOptions.IgnoreCase | RegexOptions.Compiled);

Regex remover = new Regex(@"^['""]?(.*?)['""]?$",
RegexOptions.IgnoreCase | RegexOptions.Compiled);

string parameter = null;
string[] parts;

// Valid parameters forms:
// {-,/,--}param{ ,=,:}((",')value(",'))
// Examples:
// -param1 value1 --param2 /param3:"Test-:-work"
// /param4=happy -param5 '--=nice=--'
foreach (string txt in args)
{
// Look for new parameters (-,/ or --) and a
// possible enclosed value (=,:)
parts = splitter.Split(txt, 3);

switch (parts.Length)
{
// Found a value (for the last parameter
// found (space separator))
case 1:
if (parameter != null)
{
if (!parameters.ContainsKey(parameter))
{
parts[0] =
remover.Replace(parts[0], "$1");

parameters.Add(parameter, parts[0]);
}
parameter = null;
}
// else Error: no parameter waiting for a value (skipped)
break;

// Found just a parameter
case 2:
// The last parameter is still waiting.
// With no value, set it to true.
if (parameter != null && !parameters.ContainsKey(parameter))
parameters.Add(parameter, "true");

parameter = parts[1];
break;

// Parameter with enclosed value
case 3:
// The last parameter is still waiting.
// With no value, set it to true.
if (parameter != null && !parameters.ContainsKey(parameter))
parameters.Add(parameter, "true");

parameter = parts[1];

// Remove possible enclosing characters (",')
if (!parameters.ContainsKey(parameter))
{
parts[2] = remover.Replace(parts[2], "$1");
parameters.Add(parameter, parts[2]);
}

parameter = null;
break;
}
}
// In case a parameter is still waiting
if (parameter != null && !parameters.ContainsKey(parameter))
parameters.Add(parameter, "true");

return parameters;
}
}
}
14 changes: 9 additions & 5 deletions Program.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using VueCliMiddleware;

namespace AspNetCoreVueStarter
{
public class Program
{
public static void Main(string[] args)
{
if (!CommandLine.Arguments.TryGetOptions(args, true, out string mode, out ushort port, out bool https)) return;

if (mode == "kill") {
Console.WriteLine($"Killing process serving port {port}...");
PidUtils.KillPort(port, true, true);
return;
}

CreateHostBuilder(args).Build().Run();
}

Expand Down
Loading

0 comments on commit 44afe67

Please sign in to comment.