Skip to content

Commit 1ceb048

Browse files
authored
Pass args to TS generator tool using response file (#178)
1 parent 248214d commit 1ceb048

6 files changed

Lines changed: 222 additions & 103 deletions

File tree

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
using System;
5+
using System.Diagnostics;
6+
using System.Threading;
7+
8+
namespace Microsoft.JavaScript.NodeApi;
9+
10+
// Only checking the environment variable for debugging.
11+
#pragma warning disable RS1035 // The symbol 'Environment' is banned for use by analyzers.
12+
13+
internal class DebugHelper
14+
{
15+
[Conditional("DEBUG")]
16+
public static void AttachDebugger(string environmentVariableName)
17+
{
18+
string? debugValue = Environment.GetEnvironmentVariable(environmentVariableName);
19+
if (string.Equals(debugValue, "VS", StringComparison.OrdinalIgnoreCase))
20+
{
21+
// Launch the Visual Studio debugger.
22+
Debugger.Launch();
23+
}
24+
else if (!string.IsNullOrEmpty(debugValue))
25+
{
26+
Process currentProcess = Process.GetCurrentProcess();
27+
string processName = currentProcess.ProcessName;
28+
int processId = currentProcess.Id;
29+
Console.WriteLine("###################### DEBUG ######################");
30+
31+
int waitSeconds = 20;
32+
string waitingMessage = string.Empty;
33+
if (Console.IsOutputRedirected)
34+
{
35+
Console.WriteLine(
36+
$"Process \"{processName}\" ({processId}) is " +
37+
$"waiting {waitSeconds} seconds for debugger.");
38+
}
39+
else
40+
{
41+
Console.WriteLine(
42+
$"Process \"{processName}\" ({processId}) is waiting for debugger.");
43+
waitingMessage = "Press any key to continue without debugging... ";
44+
Console.Write(waitingMessage + $"({waitSeconds})");
45+
}
46+
47+
Stopwatch stopwatch = Stopwatch.StartNew();
48+
int remainingSeconds = waitSeconds;
49+
while (!Debugger.IsAttached)
50+
{
51+
if (!Console.IsOutputRedirected && Console.KeyAvailable)
52+
{
53+
Console.ReadKey(true);
54+
Console.WriteLine();
55+
return;
56+
}
57+
else if (stopwatch.Elapsed > TimeSpan.FromSeconds(waitSeconds))
58+
{
59+
Console.WriteLine(
60+
$"Debugger did not attach after {waitSeconds} seconds. Continuing.");
61+
return;
62+
}
63+
64+
Thread.Sleep(100);
65+
66+
if (remainingSeconds > waitSeconds - (int)stopwatch.Elapsed.TotalSeconds)
67+
{
68+
remainingSeconds = waitSeconds - (int)stopwatch.Elapsed.TotalSeconds;
69+
70+
if (!Console.IsOutputRedirected)
71+
{
72+
Console.CursorLeft = waitingMessage.Length;
73+
Console.Write($"({remainingSeconds:D2})");
74+
}
75+
}
76+
}
77+
78+
if (!Console.IsOutputRedirected)
79+
{
80+
Console.CursorLeft = waitingMessage.Length;
81+
Console.WriteLine(" ");
82+
}
83+
84+
Debugger.Break();
85+
}
86+
}
87+
}

src/NodeApi.DotNetHost/ManagedHost.cs

Lines changed: 1 addition & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
using System.Reflection;
1212
using System.Runtime.CompilerServices;
1313
using System.Runtime.InteropServices;
14-
using System.Threading;
1514
using Microsoft.JavaScript.NodeApi.Interop;
1615
using Microsoft.JavaScript.NodeApi.Runtime;
1716
using static Microsoft.JavaScript.NodeApi.Runtime.JSRuntime;
@@ -210,7 +209,7 @@ public static napi_value InitializeModule(napi_env env, napi_value exports)
210209
Trace($" .NET Runtime version: {Environment.Version}");
211210
#endif
212211

213-
AttachDebugger();
212+
DebugHelper.AttachDebugger("DEBUG_NODE_API_RUNTIME");
214213

215214
JSRuntime runtime = new NodejsRuntime();
216215

@@ -638,70 +637,4 @@ public override void TraceEvent(
638637
params object?[]? args)
639638
=> WriteLine(string.Format(format ?? string.Empty, args ?? []));
640639
}
641-
642-
[Conditional("DEBUG")]
643-
private static void AttachDebugger()
644-
{
645-
string? debugValue = Environment.GetEnvironmentVariable("DEBUG_NODE_API_RUNTIME");
646-
if (string.Equals(debugValue, "VS", StringComparison.OrdinalIgnoreCase))
647-
{
648-
// Launch the Visual Studio debugger.
649-
Debugger.Launch();
650-
}
651-
else if (!string.IsNullOrEmpty(debugValue))
652-
{
653-
Process currentProcess = Process.GetCurrentProcess();
654-
string processName = currentProcess.ProcessName;
655-
int processId = currentProcess.Id;
656-
Console.WriteLine("###################### DEBUG ######################");
657-
Console.WriteLine($"Process \"{processName}\" ({processId}) is waiting for debugger.");
658-
659-
int waitSeconds = 20;
660-
string waitingMessage = "Press any key to continue without debugging... ";
661-
662-
if (!Console.IsOutputRedirected)
663-
{
664-
Console.Write(waitingMessage + $"({waitSeconds})");
665-
}
666-
667-
Stopwatch stopwatch = Stopwatch.StartNew();
668-
int remainingSeconds = waitSeconds;
669-
while (!Debugger.IsAttached)
670-
{
671-
if (Console.KeyAvailable)
672-
{
673-
Console.ReadKey(true);
674-
Console.WriteLine();
675-
return;
676-
}
677-
else if (stopwatch.Elapsed > TimeSpan.FromSeconds(waitSeconds))
678-
{
679-
Console.WriteLine(
680-
$"Debugger did not attach after {waitSeconds} seconds. Continuing.");
681-
return;
682-
}
683-
684-
Thread.Sleep(100);
685-
686-
if (remainingSeconds > waitSeconds - (int)stopwatch.Elapsed.TotalSeconds)
687-
{
688-
remainingSeconds = waitSeconds - (int)stopwatch.Elapsed.TotalSeconds;
689-
690-
if (!Console.IsOutputRedirected)
691-
{
692-
Console.CursorLeft = waitingMessage.Length;
693-
Console.Write($"({remainingSeconds:D2})");
694-
}
695-
}
696-
}
697-
698-
if (!Console.IsOutputRedirected)
699-
{
700-
Console.CursorLeft = waitingMessage.Length;
701-
Console.WriteLine(" ");
702-
}
703-
704-
Debugger.Break();
705-
}
706-
}
707640
}

src/NodeApi.Generator/ModuleGenerator.cs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,10 @@ public class ModuleGenerator : SourceGenerator, ISourceGenerator
4040

4141
public void Initialize(GeneratorInitializationContext context)
4242
{
43-
#if DEBUG
44-
#pragma warning disable RS1035 // The symbol 'Environment' is banned for use by analyzers.
45-
// Note source generators are not covered by normal debugging,
43+
// Note source generators cannot be directly launched in a debugger,
4644
// because the generator runs at build time, not at application run-time.
4745
// Set the environment variable to trigger debugging at build time.
48-
49-
if (Environment.GetEnvironmentVariable("DEBUG_NODE_API_GENERATOR") != null)
50-
{
51-
System.Diagnostics.Debugger.Launch();
52-
}
53-
#pragma warning restore RS1035
54-
#endif
46+
DebugHelper.AttachDebugger("DEBUG_NODE_API_GENERATOR");
5547
}
5648

5749
public void Execute(GeneratorExecutionContext context)

src/NodeApi.Generator/NodeApi.Generator.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
<SelfContained>false</SelfContained>
1212
</PropertyGroup>
1313

14+
<ItemGroup>
15+
<Compile Include="../NodeApi.DotNetHost/DebugHelper.cs" Link="DebugHelper.cs" />
16+
</ItemGroup>
17+
1418
<ItemGroup>
1519
<!-- Package the generator and dependencies in the analyzer directory of the nuget package -->
1620
<!-- Use the .NET 6 targeted assembly as the analyzer for broader compatibility. (There's no difference in functionality.) -->

src/NodeApi.Generator/NodeApi.Generator.targets

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,20 @@
3131
Outputs="$(TargetDir)$(NodeApiTypeDefinitionsFileName)"
3232
Condition=" '$(GenerateNodeApiTypeDefinitions)' == 'true' AND Exists('$(TargetPath)') "
3333
>
34-
<Exec Command="dotnet &quot;$(NodeApiGeneratorAssemblyPath)&quot; --assembly &quot;$(TargetPath)&quot; --packs &quot;@(TargetingPack)&quot; --reference &quot;@(ReferencePathWithRefAssemblies)&quot; --typedefs &quot;$(TargetDir)$(NodeApiTypeDefinitionsFileName)&quot; $(NodeApiTypeDefinitionsGeneratorOptions)"
34+
<PropertyGroup>
35+
<NodeApiGeneratorResponseFile>$(IntermediateOutputPath)$(NodeApiGeneratorAssemblyName).rsp</NodeApiGeneratorResponseFile>
36+
<_NodeApiGeneratorTargetingPacks>@(TargetingPack, '%3B')</_NodeApiGeneratorTargetingPacks>
37+
<_NodeApiGeneratorAssemblyReferences>@(ReferencePathWithRefAssemblies, '%3B')</_NodeApiGeneratorAssemblyReferences>
38+
</PropertyGroup>
39+
40+
<WriteLinesToFile File="$(NodeApiGeneratorResponseFile)" Lines="--assembly &quot;$(TargetPath)&quot;" Overwrite="true" />
41+
<WriteLinesToFile File="$(NodeApiGeneratorResponseFile)" Lines="--packs &quot;$(_NodeApiGeneratorTargetingPacks)&quot;" />
42+
<WriteLinesToFile File="$(NodeApiGeneratorResponseFile)" Lines="--reference &quot;$(_NodeApiGeneratorAssemblyReferences)&quot;" />
43+
<WriteLinesToFile File="$(NodeApiGeneratorResponseFile)" Lines="--typedefs &quot;$(TargetDir)$(NodeApiTypeDefinitionsFileName)&quot;" />
44+
<WriteLinesToFile File="$(NodeApiGeneratorResponseFile)" Lines="$(NodeApiTypeDefinitionsGeneratorOptions)" />
45+
46+
<!-- Run the generator using args from the response file. Note the '@' indicates the response file NOT an MSBuild item-list. -->
47+
<Exec Command="dotnet &quot;$(NodeApiGeneratorAssemblyPath)&quot; &quot;@$(NodeApiGeneratorResponseFile)&quot;"
3548
ConsoleToMSBuild="true" />
3649
</Target>
3750

@@ -101,7 +114,20 @@
101114
<_NodeApiAllTypeDefs Include="@(NodeApiSystemReferenceAssembly->'$(TargetDir)%(Identity).d.ts')" />
102115
</ItemGroup>
103116

104-
<Exec Command="dotnet &quot;$(NodeApiGeneratorAssemblyPath)&quot; $(_SuppressTSGenerationWarnings) --assemblies &quot;@(_NodeApiAllReferenceAssemblies)&quot; --packs &quot;@(TargetingPack)&quot; --typedefs &quot;@(_NodeApiAllTypeDefs)&quot; $(NodeApiTypeDefinitionsGeneratorOptions)"
117+
<PropertyGroup>
118+
<NodeApiGeneratorResponseFile>$(IntermediateOutputPath)$(NodeApiGeneratorAssemblyName).rsp</NodeApiGeneratorResponseFile>
119+
<_NodeApiGeneratorTargetingPacks>@(TargetingPack, '%3B')</_NodeApiGeneratorTargetingPacks>
120+
<_NodeApiGeneratorAssemblyReferences>@(_NodeApiAllReferenceAssemblies, '%3B')</_NodeApiGeneratorAssemblyReferences>
121+
<_NodeApiGeneratorTypeDefs>@(_NodeApiAllTypeDefs, '%3B')</_NodeApiGeneratorTypeDefs>
122+
</PropertyGroup>
123+
124+
<WriteLinesToFile File="$(NodeApiGeneratorResponseFile)" Lines="--assemblies &quot;$(_NodeApiGeneratorAssemblyReferences)&quot;" Overwrite="true" />
125+
<WriteLinesToFile File="$(NodeApiGeneratorResponseFile)" Lines="--packs &quot;$(_NodeApiGeneratorTargetingPacks)&quot;" />
126+
<WriteLinesToFile File="$(NodeApiGeneratorResponseFile)" Lines="--typedefs &quot;$(_NodeApiGeneratorTypeDefs)&quot;" />
127+
<WriteLinesToFile File="$(NodeApiGeneratorResponseFile)" Lines="$(NodeApiTypeDefinitionsGeneratorOptions)" />
128+
129+
<!-- Run the generator using args from the response file. Note the '@' indicates the response file NOT an MSBuild item-list. -->
130+
<Exec Command="dotnet &quot;$(NodeApiGeneratorAssemblyPath)&quot; &quot;@$(NodeApiGeneratorResponseFile)&quot;"
105131
ConsoleToMSBuild="true" />
106132
</Target>
107133

0 commit comments

Comments
 (0)