Nuke.Unreal
Build Unreal apps in Style.
Loading...
Searching...
No Matches
ToolConfig.cs
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Threading.Tasks;
5using Nuke.Common.Tooling;
6using Nuke.Common.Utilities;
7using Serilog;
8
10
11/// <summary>
12/// The base class for generated strongly typed tool configurators providing base
13/// functionalities like argument and subtool management
14/// </summary>
15public abstract class ToolConfig : Options
16{
17 /// <summary>
18 /// The C# friendly name of the tool which will be used inside configurators
19 /// </summary>
20 public abstract string Name { get; }
21
22 /// <summary>
23 /// The name which will be rendered onto command line.
24 /// </summary>
25 public abstract string CliName { get; }
26
27 /// <summary>
28 /// Compatibility with either Unreal Engine 4 or 5 or both.
29 /// If tool is configured to run with an incompatible engine its entire configuration
30 /// will be ignored.
31 /// </summary>
32 public abstract UnrealCompatibility Compatibility { get; }
33
34 protected List<UnrealToolArgument> UsingArguments = [];
35 protected readonly Dictionary<string, ToolConfig> UsingSubtools = [];
36
37 protected virtual ToolConfig[] Configs => [];
38
39 public virtual void AppendArgument(UnrealToolArgument arg)
40 {
41 var meta = arg.GetMeta();
42 bool allowMultiple = meta.AllowMultiple || meta.IsRawText;
43 if (!allowMultiple)
44 {
45 UsingArguments = UsingArguments
46 .Where(a => !a.Name.EqualsOrdinalIgnoreCase(arg.Name))
47 .ToList();
48 }
49 UsingArguments.Add(arg);
50 }
51
52 public virtual void AppendArgument(string arg, UnrealToolArgumentMeta? meta = null)
53 {
54 AppendArgument(UnrealToolArgument.Parse(arg, meta)!);
55 }
56
57 public virtual void AppendSubtool(ToolConfig subtool)
58 {
59 UsingSubtools.TryAdd(subtool.Name, subtool);
60 }
61
62 /// <summary>
63 /// Gether the arguments and subtools and render a command line output
64 /// </summary>
65 /// <param name="ueVersion"></param>
66 /// <returns>The command line output to be passed to the wrapped tool</returns>
67 public virtual string Gather(EngineVersion ueVersion)
68 {
69 var compatibleName = ueVersion.SemanticalVersion.Major > 4
70 ? CliName.Replace("UE4", "Unreal")
71 : CliName;
72
73 var subtools = UsingSubtools.Values
74 .Where(v => ueVersion.IsCompatibleWith(v.Compatibility))
75 .Select(v => v.Gather(ueVersion));
76
77 foreach (var subtool in UsingSubtools.Values.Where(v => !ueVersion.IsCompatibleWith(v.Compatibility)))
78 {
79 Log.Warning(
80 "The tool {0} ({1}) is only compatible with {2} therefore it is ignored (current compatibility: {3})",
81 subtool.Name,
82 subtool.CliName,
83 subtool.Compatibility,
84 ueVersion.Compatibility
85 );
86 }
87
88 var args = UsingArguments
89 .Where(v => ueVersion.IsCompatibleWith(v.GetMeta().Compatibility))
90 .Select(v => v.Gather(ueVersion));
91
92 foreach (var arg in UsingArguments.Where(v => !ueVersion.IsCompatibleWith(v.GetMeta().Compatibility)))
93 {
94 Log.Warning(
95 "The argument {0} is only compatible with {1} therefore it is ignored (current compatibility: {2})",
96 arg.Name,
97 arg.GetMeta().Compatibility,
98 ueVersion.Compatibility
99 );
100 }
101
102 return (compatibleName + " " + string.Join(' ', subtools.Concat(args))).Trim();
103 }
104}
105
106public static class ToolConfigExtensions
107{
108 /// <summary>
109 /// Convenience function for conditionally configuring a tool
110 /// </summary>
111 /// <param name="config"></param>
112 /// <param name="condition"></param>
113 /// <param name="true">Execute delegate when condition is true</param>
114 /// <param name="false">Execute delegate when condition is false</param>
115 /// <typeparam name="T"></typeparam>
116 /// <returns>The same configurator as the input one</returns>
117 public static T If<T>(this T config, bool condition, Action<T>? @true = null, Action<T>? @false = null) where T : ToolConfig
118 {
119 if (condition) @true?.Invoke(config);
120 else @false?.Invoke(config);
121 return config;
122 }
123
124 /// <summary>
125 /// Convenience function to apply potentially stacking command line arguments for each element in an enumerable
126 /// </summary>
127 /// <param name="config"></param>
128 /// <param name="collection"></param>
129 /// <param name="body">Execute delegate for each item of `collection`</param>
130 /// <typeparam name="T"></typeparam>
131 /// <typeparam name="I"></typeparam>
132 /// <returns>The same configurator as the input one</returns>
133 public static T For<T, I>(this T config, IEnumerable<I> collection, Action<I, T> body) where T : ToolConfig
134 {
135 foreach (var item in collection)
136 {
137 body?.Invoke(item, config);
138 }
139 return config;
140 }
141
142 /// <summary>
143 /// Append arbitrary arguments to target configurator.
144 /// Arguments will be parsed for (NAME)[=:]?(VALUE)? structure, and quoted if necessary
145 /// </summary>
146 /// <param name="config"></param>
147 /// <param name="arguments"></param>
148 /// <typeparam name="T"></typeparam>
149 /// <returns>The same configurator as the input one</returns>
150 public static T Append<T>(this T config, params string[] arguments) where T : ToolConfig =>
151 Append(config, arguments.AsEnumerable());
152
153 /// <summary>
154 /// Append arbitrary arguments to target configurator.
155 /// Arguments will be parsed for (NAME)[=:]?(VALUE)? structure, and quoted if necessary
156 /// </summary>
157 /// <param name="config"></param>
158 /// <param name="arguments"></param>
159 /// <typeparam name="T"></typeparam>
160 /// <returns>The same configurator as the input one</returns>
161 public static T Append<T>(this T config, IEnumerable<string?> arguments) where T : ToolConfig
162 {
163 foreach(var arg in arguments)
164 {
165 if (arg == null) continue;
166 config.AppendArgument(arg);
167 }
168 return config;
169 }
170
171 /// <summary>
172 /// Append arbitrary arguments to target configurator.
173 /// Arguments will be passed as is
174 /// </summary>
175 /// <param name="config"></param>
176 /// <param name="arguments"></param>
177 /// <typeparam name="T"></typeparam>
178 /// <returns>The same configurator as the input one</returns>
179 public static T AppendRaw<T>(this T config, params string[] arguments) where T : ToolConfig =>
180 AppendRaw(config, arguments.AsEnumerable());
181
182 /// <summary>
183 /// Append arbitrary arguments to target configurator.
184 /// Arguments will be passed as is
185 /// </summary>
186 /// <param name="config"></param>
187 /// <param name="arguments"></param>
188 /// <typeparam name="T"></typeparam>
189 /// <returns>The same configurator as the input one</returns>
190 public static T AppendRaw<T>(this T config, IEnumerable<string> arguments) where T : ToolConfig
191 {
192 foreach(var arg in arguments)
193 {
194 config.AppendArgument(new UnrealToolArgument(
195 Name: arg,
196 Meta: new(IsRawText: true)
197 ));
198 }
199 return config;
200 }
201}
High level representation of an Unreal Engine version.
bool IsCompatibleWith(UnrealCompatibility compatibility)
Check if given compatibility mask applies to this version too.
static T Append< T >(this T config, params string[] arguments)
Append arbitrary arguments to target configurator. Arguments will be parsed for (NAME)[=:]?...
static T For< T, I >(this T config, IEnumerable< I > collection, Action< I, T > body)
Convenience function to apply potentially stacking command line arguments for each element in an enum...
static T If< T >(this T config, bool condition, Action< T >? @true=null, Action< T >? @false=null)
Convenience function for conditionally configuring a tool.
static T AppendRaw< T >(this T config, params string[] arguments)
Append arbitrary arguments to target configurator. Arguments will be passed as is.
The base class for generated strongly typed tool configurators providing base functionalities like ar...
Definition ToolConfig.cs:16
UnrealCompatibility Compatibility
Compatibility with either Unreal Engine 4 or 5 or both. If tool is configured to run with an incompat...
Definition ToolConfig.cs:32
string Name
The C# friendly name of the tool which will be used inside configurators.
Definition ToolConfig.cs:20
string CliName
The name which will be rendered onto command line.
Definition ToolConfig.cs:25
virtual string Gather(EngineVersion ueVersion)
Gether the arguments and subtools and render a command line output.
Definition ToolConfig.cs:67
partial record class UnrealToolArgument(string Name, string? Value=null, char Setter='=', UnrealToolArgumentMeta? Meta=null)
Argument for an Unreal tool.
record class UnrealToolArgumentMeta(UnrealCompatibility Compatibility=UnrealCompatibility.All, bool AllowMultiple=false, bool IsRawText=false)
Properties guiding how to process the argument.
UnrealCompatibility
A flag enum representation for checking the Unreal version compatibility of various features....