Skip to content

Commit

Permalink
Add env option in the launch config
Browse files Browse the repository at this point in the history
  • Loading branch information
nikita.romanov committed Dec 9, 2024
1 parent e12c389 commit 88c0c80
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 72 deletions.
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,9 @@
"device": {
"type": "object"
},
"env": {
"type": "object"
},
"profilerMode": {
"type": "string",
"enum": [
Expand Down
4 changes: 2 additions & 2 deletions src/DotNet.Meteor.Common/Android/AndroidDebugBridge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public static List<string> Devices() {
ProcessResult result = new ProcessRunner(adb, new ProcessArgumentBuilder()
.Append("devices")
.Append("-l"))
.WaitForExit();
.WaitForExit(5000);

if (!result.Success)
throw new InvalidOperationException(string.Join(Environment.NewLine, result.StandardError));
Expand Down Expand Up @@ -167,7 +167,7 @@ public static string EmuName(string serial) {
ProcessResult result = new ProcessRunner(adb, new ProcessArgumentBuilder()
.Append("-s", serial)
.Append("emu", "avd", "name"))
.WaitForExit();
.WaitForExit(5000);

if (!result.Success)
return string.Empty;
Expand Down
114 changes: 60 additions & 54 deletions src/DotNet.Meteor.Common/Apple/MonoLauncher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ public static Process TcpTunnel(string serial, int port, IProcessLogger? logger
.Conditional("--use-device-ctl=false", () => !MonoLauncher.UseDeviceCtl), logger)
.Start();
}

public static void InstallDev(string serial, string bundlePath, IProcessLogger? logger = null) {
var tool = AppleSdkLocator.MLaunchTool();
logger?.OnOutputDataReceived(tool.FullName);
Expand All @@ -26,72 +25,79 @@ public static void InstallDev(string serial, string bundlePath, IProcessLogger?
.Conditional("--use-device-ctl=false", () => !MonoLauncher.UseDeviceCtl), logger)
.WaitForExit();
}

public static void LaunchDev(string serial, string bundlePath, IProcessLogger? logger = null) {
private static ProcessRunner LaunchDev(string serial, string bundlePath, IEnumerable<string> arguments, Dictionary<string, string> environment, IProcessLogger? logger = null) {
var tool = AppleSdkLocator.MLaunchTool();
var arguments = new ProcessArgumentBuilder()
var argumentBuilder = new ProcessArgumentBuilder()
.Append( "--launchdev").AppendQuoted(bundlePath)
.Append($"--devname={serial}");
var result = new ProcessRunner(tool, arguments, logger).WaitForExit();
.Append($"--devname={serial}")
.Append( "--wait-for-exit");

if (!result.Success)
throw new InvalidOperationException(string.Join(Environment.NewLine, result.StandardError));
}
foreach (var arg in arguments)
argumentBuilder.Append($"--argument={arg}");
foreach (var env in environment)
argumentBuilder.Append($"--setenv={env.Key}={env.Value}");

public static Process LaunchSim(string serial, string bundlePath, IProcessLogger? logger = null) {
return new ProcessRunner(tool, argumentBuilder, logger);
}
private static ProcessRunner LaunchSim(string serial, string bundlePath, IEnumerable<string> arguments, Dictionary<string, string> environment, IProcessLogger? logger = null) {
var tool = AppleSdkLocator.MLaunchTool();
var arguments = new ProcessArgumentBuilder()
logger?.OnOutputDataReceived(tool.FullName);
var argumentBuilder = new ProcessArgumentBuilder()
.Append( "--launchsim").AppendQuoted(bundlePath)
.Append($"--device=:v2:udid={serial}");
return new ProcessRunner(tool, arguments, logger).Start();
}

public static Process DebugDev(string serial, string bundlePath, int port, IProcessLogger? logger = null) {
var tool = AppleSdkLocator.MLaunchTool();
var arguments = new ProcessArgumentBuilder()
.Append( "--launchdev").AppendQuoted(bundlePath)
.Append($"--devname={serial}")
.Append( "--argument=-monodevelop-port")
.Append($"--argument={port}")
.Append($"--setenv=__XAMARIN_DEBUG_PORT__={port}")
.Append( "--wait-for-exit");
return new ProcessRunner(tool, arguments, logger).Start();
}
foreach (var arg in arguments)
argumentBuilder.Append($"--argument={arg}");
foreach (var env in environment)
argumentBuilder.Append($"--setenv={env.Key}={env.Value}");

public static Process ProfileDev(string serial, string bundlePath, string port, IProcessLogger? logger = null) {
var tool = AppleSdkLocator.MLaunchTool();
var arguments = new ProcessArgumentBuilder()
.Append( "--launchdev").AppendQuoted(bundlePath)
.Append($"--devname={serial}")
.Append( "--argument=-monodevelop-port")
.Append($"--argument={port}")
.Append( "--argument=--connection-mode")
.Append( "--argument=none")
.Append($"--setenv=DOTNET_DiagnosticPorts={port}")
.Append( "--wait-for-exit");
return new ProcessRunner(tool, arguments, logger).Start();
return new ProcessRunner(tool, argumentBuilder, logger);
}

public static Process DebugSim(string serial, string bundlePath, int port, IProcessLogger? logger = null) {
var tool = AppleSdkLocator.MLaunchTool();
logger?.OnOutputDataReceived(tool.FullName);
var arguments = new ProcessArgumentBuilder()
.Append( "--launchsim").AppendQuoted(bundlePath)
.Append( "--argument=-monodevelop-port")
.Append($"--argument={port}")
.Append($"--setenv=__XAMARIN_DEBUG_PORT__={port}")
.Append($"--device=:v2:udid={serial}");
return new ProcessRunner(tool, arguments, logger).Start();
public static Process DebugDev(string serial, string bundlePath, int port, Dictionary<string, string>? environment = null, IProcessLogger? logger = null) {
environment ??= new Dictionary<string, string>();
environment.TryAdd("__XAMARIN_DEBUG_PORT__", $"{port}");
return MonoLauncher.LaunchDev(serial, bundlePath,
arguments: new List<string> {
"-monodevelop-port", $"{port}"
},
environment,
logger
).Start();
}
public static Process DebugSim(string serial, string bundlePath, int port, Dictionary<string, string>? environment = null, IProcessLogger? logger = null) {
environment ??= new Dictionary<string, string>();
environment.TryAdd("__XAMARIN_DEBUG_PORT__", $"{port}");
return MonoLauncher.LaunchSim(serial, bundlePath,
arguments: new List<string> {
"-monodevelop-port", $"{port}"
},
environment,
logger
).Start();
}

public static Process ProfileDev(string serial, string bundlePath, string port, IProcessLogger? logger = null) {
return MonoLauncher.LaunchDev(serial, bundlePath,
arguments: new List<string> {
"-monodevelop-port", $"{port}",
"--connection-mode", "none"
},
environment: new Dictionary<string, string> {
{ "DOTNET_DiagnosticPorts", $"{port}" }
},
logger
).Start();
}
public static Process ProfileSim(string serial, string bundlePath, string port, IProcessLogger? logger = null) {
var tool = AppleSdkLocator.MLaunchTool();
var arguments = new ProcessArgumentBuilder()
.Append( "--launchsim").AppendQuoted(bundlePath)
.Append("--argument", "--connection-mode")
.Append("--argument", "none")
.Append($"--setenv:DOTNET_DiagnosticPorts={port}")
.Append($"--device=:v2:udid={serial}");
return new ProcessRunner(tool, arguments, logger).Start();
return MonoLauncher.LaunchDev(serial, bundlePath,
arguments: new List<string> {
"--connection-mode", "none"
},
environment: new Dictionary<string, string> {
{ "DOTNET_DiagnosticPorts", $"{port}" }
},
logger
).Start();
}
}
8 changes: 6 additions & 2 deletions src/DotNet.Meteor.Common/Processes/ProcessRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,13 @@ public Process Start() {
return process;
}

public ProcessResult WaitForExit() {
public ProcessResult WaitForExit(int timeout = -1) {
Start();
process.WaitForExit();

if (timeout > 0)
process.WaitForExit(timeout);
else
process.WaitForExit();

var exitCode = process.ExitCode;
process.Close();
Expand Down
11 changes: 8 additions & 3 deletions src/DotNet.Meteor.Debug/Agents/DebugLaunchAgent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,14 @@ public override void Connect(SoftDebuggerSession session) {
private void LaunchAppleMobile(DebugSession debugSession) {
if (RuntimeSystem.IsMacOS) {
if (Configuration.Device.IsEmulator) {
var debugProcess = MonoLauncher.DebugSim(Configuration.Device.Serial, Configuration.ProgramPath, Configuration.DebugPort, debugSession);
var debugProcess = MonoLauncher.DebugSim(Configuration.Device.Serial, Configuration.ProgramPath, Configuration.DebugPort, Configuration.EnvironmentVariables, debugSession);
Disposables.Add(() => debugProcess.Terminate());
} else {
var debugPortForwarding = MonoLauncher.TcpTunnel(Configuration.Device.Serial, Configuration.DebugPort, debugSession);
var hotReloadPortForwarding = MonoLauncher.TcpTunnel(Configuration.Device.Serial, Configuration.ReloadHostPort, debugSession);
MonoLauncher.InstallDev(Configuration.Device.Serial, Configuration.ProgramPath, debugSession);

var debugProcess = MonoLauncher.DebugDev(Configuration.Device.Serial, Configuration.ProgramPath, Configuration.DebugPort, debugSession);
var debugProcess = MonoLauncher.DebugDev(Configuration.Device.Serial, Configuration.ProgramPath, Configuration.DebugPort, Configuration.EnvironmentVariables, debugSession);
Disposables.Add(() => debugProcess.Terminate());
Disposables.Add(() => debugPortForwarding.Terminate());
Disposables.Add(() => hotReloadPortForwarding.Terminate());
Expand All @@ -74,8 +74,10 @@ private void LaunchMacCatalyst(IProcessLogger logger) {
var processRunner = new ProcessRunner(tool, new ProcessArgumentBuilder().AppendQuoted(Configuration.ProgramPath));
processRunner.SetEnvironmentVariable("__XAMARIN_DEBUG_HOSTS__", "127.0.0.1");
processRunner.SetEnvironmentVariable("__XAMARIN_DEBUG_PORT__", Configuration.DebugPort.ToString());
var result = processRunner.WaitForExit();
foreach (var env in Configuration.EnvironmentVariables)
processRunner.SetEnvironmentVariable(env.Key, env.Value);

var result = processRunner.WaitForExit();
if (!result.Success)
throw ServerExtensions.GetProtocolException(string.Join(Environment.NewLine, result.StandardError));
}
Expand All @@ -92,6 +94,9 @@ private void LaunchAndroid(IProcessLogger logger) {

AndroidDebugBridge.Install(Configuration.Device.Serial, Configuration.ProgramPath, logger);
AndroidDebugBridge.Shell(Configuration.Device.Serial, "setprop", "debug.mono.connect", $"port={Configuration.DebugPort}");
if (Configuration.EnvironmentVariables.Count != 0)
AndroidDebugBridge.Shell(Configuration.Device.Serial, "setprop", "debug.mono.env", Configuration.EnvironmentVariables.ToEnvString());

AndroidDebugBridge.Shell(Configuration.Device.Serial, "am", "set-debug-app", applicationId);

AndroidFastDev.TryPushAssemblies(Configuration.Device, Configuration.AssetsPath, applicationId, logger);
Expand Down
17 changes: 8 additions & 9 deletions src/DotNet.Meteor.Debug/Agents/NoDebugLaunchAgent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,20 @@ public override void Launch(DebugSession debugSession) {
if (Configuration.Device.IsMacCatalyst)
LaunchMacCatalyst(debugSession);
if (Configuration.Device.IsWindows)
LaunchWindows(debugSession);
throw new NotSupportedException();
}
public override void Connect(SoftDebuggerSession session) {}

private void LaunchAppleMobile(DebugSession debugSession) {
if (RuntimeSystem.IsMacOS) {
if (Configuration.Device.IsEmulator) {
var appProcess = MonoLauncher.DebugSim(Configuration.Device.Serial, Configuration.ProgramPath, Configuration.DebugPort, debugSession);
var appProcess = MonoLauncher.DebugSim(Configuration.Device.Serial, Configuration.ProgramPath, Configuration.DebugPort, Configuration.EnvironmentVariables, debugSession);
Disposables.Add(() => appProcess.Terminate());
} else {
var hotReloadPortForwarding = MonoLauncher.TcpTunnel(Configuration.Device.Serial, Configuration.ReloadHostPort, debugSession);
Disposables.Add(() => hotReloadPortForwarding.Terminate());
MonoLauncher.InstallDev(Configuration.Device.Serial, Configuration.ProgramPath, debugSession);
var appProcess = MonoLauncher.DebugDev(Configuration.Device.Serial, Configuration.ProgramPath, Configuration.DebugPort, debugSession);
var appProcess = MonoLauncher.DebugDev(Configuration.Device.Serial, Configuration.ProgramPath, Configuration.DebugPort, Configuration.EnvironmentVariables, debugSession);
Disposables.Add(() => appProcess.Terminate());
}
} else {
Expand All @@ -43,16 +43,13 @@ private void LaunchAppleMobile(DebugSession debugSession) {
private void LaunchMacCatalyst(IProcessLogger logger) {
var tool = AppleSdkLocator.OpenTool();
var processRunner = new ProcessRunner(tool, new ProcessArgumentBuilder().AppendQuoted(Configuration.ProgramPath));
var result = processRunner.WaitForExit();
foreach (var env in Configuration.EnvironmentVariables)
processRunner.SetEnvironmentVariable(env.Key, env.Value);

var result = processRunner.WaitForExit();
if (!result.Success)
throw ServerExtensions.GetProtocolException(string.Join(Environment.NewLine, result.StandardError));
}
private void LaunchWindows(IProcessLogger logger) {
var program = new FileInfo(Configuration.ProgramPath);
var process = new ProcessRunner(program, new ProcessArgumentBuilder(), logger).Start();
Disposables.Add(() => process.Terminate());
}
private void LaunchAndroid(IProcessLogger logger) {
var applicationId = Configuration.GetApplicationName();
if (Configuration.Device.IsEmulator)
Expand All @@ -65,6 +62,8 @@ private void LaunchAndroid(IProcessLogger logger) {
AndroidDebugBridge.Uninstall(Configuration.Device.Serial, applicationId, logger);

AndroidDebugBridge.Install(Configuration.Device.Serial, Configuration.ProgramPath, logger);
if (Configuration.EnvironmentVariables.Count != 0)
AndroidDebugBridge.Shell(Configuration.Device.Serial, "setprop", "debug.mono.env", Configuration.EnvironmentVariables.ToEnvString());

AndroidFastDev.TryPushAssemblies(Configuration.Device, Configuration.AssetsPath, applicationId, logger);

Expand Down
7 changes: 5 additions & 2 deletions src/DotNet.Meteor.Debug/Extensions/MonoExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,11 @@ public static string ResolveValue(this ObjectValue variable, string value) {
return null;

foreach (var remap in session.Options.SourceCodeMappings) {
if (location.FileName.Contains(remap.Key))
return location.FileName.Replace(remap.Key, remap.Value).ToPlatformPath();
var filePath = location.FileName.ToPlatformPath();
var key = remap.Key.ToPlatformPath();
var value = remap.Value.ToPlatformPath();
if (filePath.StartsWith(key, StringComparison.OrdinalIgnoreCase))
return filePath.Replace(key, value);
}

return location.FileName;
Expand Down
5 changes: 5 additions & 0 deletions src/DotNet.Meteor.Debug/Extensions/ServerExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -208,5 +208,10 @@ private static string ToStackTraceLine(this ExceptionStackFrame? frame) {

return sb.ToString();
}
public static string ToEnvString(this Dictionary<string, string> env) {
//https://github.com/dotnet/android/blob/b1241329f531b985b9c462b3f684e2ca3e0db98d/Documentation/workflow/SystemProperties.md#debugmonoenv
var envString = string.Join('|', env.Select(it => $"{it.Key}={it.Value}"));
return $"'{envString}'";
}
}

3 changes: 3 additions & 0 deletions src/DotNet.Meteor.Debug/LaunchConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class LaunchConfiguration {
public int ReloadHostPort { get; init; }
public int ProfilerPort { get; init; }
public string? TransportId { get; init; }
public Dictionary<string, string> EnvironmentVariables { get; init; }
public DebuggerSessionOptions DebuggerSessionOptions { get; init; }

private ProfilerMode Profiler { get; init; }
Expand All @@ -34,6 +35,8 @@ public LaunchConfiguration(Dictionary<string, JToken> configurationProperties) {
TransportId = configurationProperties.TryGetValue("transportId").ToClass<string>();
DebuggerSessionOptions = configurationProperties.TryGetValue("debuggerOptions")?.ToClass<DebuggerSessionOptions>()
?? ServerExtensions.DefaultDebuggerOptions;
EnvironmentVariables = configurationProperties.TryGetValue("env")?.ToClass<Dictionary<string, string>>()
?? new Dictionary<string, string>();

DebugPort = DebugPort == 0 ? RuntimeSystem.GetFreePort() : DebugPort;
ProfilerPort = ProfilerPort == 0 ? RuntimeSystem.GetFreePort() : ProfilerPort;
Expand Down

0 comments on commit 88c0c80

Please sign in to comment.