Nuke.Unreal
Build Unreal apps in Style.
Loading...
Searching...
No Matches
BuildCommon.cs
1using System;
2using Nuke.Common.IO;
3using System.Runtime.CompilerServices;
4using Nuke.Common;
5using System.Collections;
6using System.Collections.Generic;
7using Nuke.Common.Utilities.Collections;
8using System.Linq;
9using Nuke.Common.Utilities;
10using System.IO;
11using System.Reflection;
12using Serilog;
13using System.Text.RegularExpressions;
14using Nuke.Cola;
15using System.Runtime.InteropServices;
16
17namespace Nuke.Unreal;
18
19/// <summary>
20/// Extra build related utilities not necessarily associated with Unreal tasks
21/// </summary>
22public static class BuildCommon
23{
24 /// <summary>
25 /// Get the contents folder Nuke.Unreal is shipped with. This is usually contained in the local
26 /// nuget installation of Nuke.Unreal, but may vary depending on the circumstances.
27 /// </summary>
28 public static AbsolutePath GetContentsFolder()
29 {
30 var executingAssemblyFolder = (AbsolutePath) Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
31
32 if (Directory.Exists(executingAssemblyFolder / "Templates"))
33 {
34 return executingAssemblyFolder;
35 }
36
37 var nukeUnrealAssemblyFolder = (AbsolutePath) Path.GetDirectoryName(typeof(BuildCommon).Assembly.Location);
38 if (Directory.Exists(nukeUnrealAssemblyFolder / "Templates"))
39 {
40 return nukeUnrealAssemblyFolder;
41 }
42
43 var contentFolder = nukeUnrealAssemblyFolder
44 .DescendantsAndSelf(p => p.Parent, d => Path.GetPathRoot(d) != d)
45 .FirstOrDefault(p => Directory.Exists(p / "content"));
46
47 Assert.NotNullOrEmpty(contentFolder, "Couldn't find contents folder of Nuke.Unreal.");
48 return contentFolder!;
49 }
50
51 /// <summary>
52 /// Returns false on known folders which are intermediate results of Engine operations,
53 /// therefore its contents must not be modified by the user.
54 /// </summary>
55 /// <param name="path"></param>
56 /// <returns></returns>
57 public static bool IsProjectFolder(this AbsolutePath path)
58 => !path.Name.StartsWith('.')
59 && !path.Name.StartsWith("Nuke.")
60 && path.Name != "Intermediate"
61 && path.Name != "Binaries"
62 && path.Name != "ThirdParty"
63 && path.Name != "Saved";
64
65 /// <summary>
66 /// Gives a recursive folder tree filtering out known intermediate folders
67 /// </summary>
68 /// <param name="origin"></param>
69 /// <param name="filter">Extra filtering function</param>
70 public static IEnumerable<AbsolutePath> SubTreeProject(this AbsolutePath origin, Func<AbsolutePath, bool>? filter = null) =>
71 origin.SubTree(sd => filter?.Invoke(sd) ?? true && sd.IsProjectFolder());
72
73 /// <summary>
74 /// Look for something in subtree of a folder or in parent folders based on a predicate.
75 /// </summary>
76 public static bool LookAroundFor(Func<string, bool> predicate, out AbsolutePath? result) =>
77 PathExtensions.LookAroundFor(predicate, out result, IsProjectFolder);
78
79 /// <summary>
80 /// Get the owning parent folder of an arbitrarily deep subfolder based on wildcard filtering of
81 /// files in parent folder. The closest match will be returned.
82 /// </summary>
83 /// <param name="path"></param>
84 /// <param name="ownerPattern"></param>
85 /// <returns>Owning parent folder or null if there's no match.</returns>
86 public static AbsolutePath? GetOwner(this AbsolutePath path, string ownerPattern)
87 => path
88 .DescendantsAndSelf(d => d.Parent, d => Path.GetPathRoot(d) != d)
89 .SelectMany(p => p.GlobFiles(ownerPattern))
90 .FirstOrDefault();
91
92 /// <summary>
93 /// Get the Unreal plugin owning the given subfolder.
94 /// </summary>
95 public static AbsolutePath? GetOwningPlugin(this AbsolutePath path)
96 => path
97 .DescendantsAndSelf(d => d.Parent, d => Path.GetPathRoot(d) != d)
98 .SelectMany(p => p.GlobFiles("*.uplugin"))
99 .FirstOrDefault();
100
101 /// <summary>
102 /// Get the Unreal project owning the given subfolder.
103 /// </summary>
104 public static AbsolutePath? GetOwningProject(this AbsolutePath path)
105 => path
106 .DescendantsAndSelf(d => d.Parent, d => Path.GetPathRoot(d) != d)
107 .SelectMany(p => p.GlobFiles("*.uproject"))
108 .FirstOrDefault();
109
110 /// <summary>
111 /// Get the Unreal module owning the given subfolder.
112 /// </summary>
113 public static AbsolutePath? GetOwningModule(this AbsolutePath path)
114 => path
115 .DescendantsAndSelf(d => d.Parent, d => Path.GetPathRoot(d) != d)
116 .SelectMany(p => p.GlobFiles("*.Build.cs"))
117 .FirstOrDefault();
118
119 /// <summary>
120 /// Create a short path symlink for input path to work around the 260 character path length
121 /// limitation cursing Windows from the 80's to present day.
122 /// </summary>
123 public static AbsolutePath Shorten(this AbsolutePath longPath, bool allPlatforms = false)
124 {
125 var result = longPath;
126 if (allPlatforms || RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
127 {
128 Log.Information("Creating short symlink on {0} for {1}", longPath.GetRoot(), longPath);
129 result = longPath.GetRoot() / Guid.NewGuid().ToString("N")[..16];
130 result.Links(longPath);
131 }
132 return result;
133 }
134}
Extra build related utilities not necessarily associated with Unreal tasks.
static ? AbsolutePath GetOwningPlugin(this AbsolutePath path)
Get the Unreal plugin owning the given subfolder.
static bool LookAroundFor(Func< string, bool > predicate, out AbsolutePath? result)
Look for something in subtree of a folder or in parent folders based on a predicate.
static IEnumerable< AbsolutePath > SubTreeProject(this AbsolutePath origin, Func< AbsolutePath, bool >? filter=null)
Gives a recursive folder tree filtering out known intermediate folders.
static bool IsProjectFolder(this AbsolutePath path)
Returns false on known folders which are intermediate results of Engine operations,...
static ? AbsolutePath GetOwningModule(this AbsolutePath path)
Get the Unreal module owning the given subfolder.
static ? AbsolutePath GetOwner(this AbsolutePath path, string ownerPattern)
Get the owning parent folder of an arbitrarily deep subfolder based on wildcard filtering of files in...
static ? AbsolutePath GetOwningProject(this AbsolutePath path)
Get the Unreal project owning the given subfolder.
static AbsolutePath GetContentsFolder()
Get the contents folder Nuke.Unreal is shipped with. This is usually contained in the local nuget ins...
static AbsolutePath Shorten(this AbsolutePath longPath, bool allPlatforms=false)
Create a short path symlink for input path to work around the 260 character path length limitation cu...