forked from raulsntos/godot-dotnet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
GenerateCommand.cs
97 lines (76 loc) · 3.35 KB
/
GenerateCommand.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
using System;
using System.CommandLine;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Godot.BindingsGenerator.Logging;
using Godot.BindingsGenerator.ApiDump;
namespace Godot.BindingsGenerator;
internal sealed class GenerateCommand : CliRootCommand
{
private static readonly CliOption<FileInfo> _extensionApiPathOption = new(
name: "--extension-api"
)
{
Description = "Path to the extension API dump JSON file.",
Arity = ArgumentArity.ExactlyOne,
};
private static readonly CliOption<FileInfo> _extensionInterfacePathOption = new(
name: "--extension-interface"
)
{
Description = "Path to the extension interface header file.",
Arity = ArgumentArity.ExactlyOne,
};
private static readonly CliOption<DirectoryInfo?> _outputPathOption = new(
name: "--output", aliases: ["-o"])
{
Description = "Path to the directory where the C# bindings will be generated.",
Arity = ArgumentArity.ZeroOrOne,
};
private static readonly CliOption<DirectoryInfo?> _testOutputPathOption = new(
name: "--test-output")
{
Description = "Path to the directory where the C# tests will be generated.",
Arity = ArgumentArity.ZeroOrOne,
};
public GenerateCommand()
{
Options.Add(_extensionApiPathOption);
Options.Add(_extensionInterfacePathOption);
Options.Add(_outputPathOption);
Options.Add(_testOutputPathOption);
SetAction(HandleCommand);
}
private async Task<int> HandleCommand(ParseResult parseResult, CancellationToken cancellationToken = default)
{
var startTime = DateTime.Now;
var extensionApiPath = parseResult.GetValue(_extensionApiPathOption)
?? throw new InvalidOperationException("Godot extension API dump file path needs to be specified.");
var extensionInterfacePath = parseResult.GetValue(_extensionInterfacePathOption)
?? throw new InvalidOperationException("Godot extension interface header file path needs to be specified.");
var outputPath = parseResult.GetValue(_outputPathOption)
?? new DirectoryInfo(Path.Join(Environment.CurrentDirectory, "Generated"));
var testOutputPath = parseResult.GetValue(_testOutputPathOption);
var logger = ConsoleLogger.Instance;
ClangGenerator.Generate(extensionInterfacePath.FullName, outputPath.FullName, testOutputPath?.FullName, logger);
using var stream = extensionApiPath.OpenRead();
var api = await GodotApi.DeserializeAsync(stream, cancellationToken);
if (api is null || string.IsNullOrWhiteSpace(api.Header.VersionFullName))
{
logger.LogError("Error parsing the Godot extension API dump.");
return -1;
}
logger.LogInformation($"Generating C# bindings for '{api.Header.VersionFullName}'.");
BindingsGenerator.Generate(api, outputPath.FullName, logger: logger);
string timeElapsed = FormatTimeSpan(DateTime.Now - startTime);
logger.LogInformation($"\nTime Elapsed {timeElapsed}");
return 0;
static string FormatTimeSpan(TimeSpan timeSpan)
{
string timeSpanStr = timeSpan.ToString();
int prettyLength = int.Min(11, timeSpanStr.Length);
return timeSpanStr[..prettyLength];
}
}
}