mirror of
https://github.com/Ellpeck/GameBundle.git
synced 2024-11-25 18:08:34 +01:00
Compare commits
5 commits
3fd8f41b35
...
db1a53291e
Author | SHA1 | Date | |
---|---|---|---|
db1a53291e | |||
5ebbd8e46b | |||
4d686a3169 | |||
1142252015 | |||
b3218532e8 |
8 changed files with 314 additions and 280 deletions
|
@ -14,7 +14,7 @@
|
||||||
<PackageIcon>Logo.png</PackageIcon>
|
<PackageIcon>Logo.png</PackageIcon>
|
||||||
<PackAsTool>true</PackAsTool>
|
<PackAsTool>true</PackAsTool>
|
||||||
<ToolCommandName>gamebundle</ToolCommandName>
|
<ToolCommandName>gamebundle</ToolCommandName>
|
||||||
<VersionPrefix>1.5.0</VersionPrefix>
|
<VersionPrefix>1.5.2</VersionPrefix>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -2,7 +2,8 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using CommandLine;
|
using CommandLine;
|
||||||
|
|
||||||
namespace GameBundle {
|
namespace GameBundle;
|
||||||
|
|
||||||
public class Options {
|
public class Options {
|
||||||
|
|
||||||
[Option('s', "source", HelpText = "The location of the .csproj file that should be built and bundled. By default, the current directory is scanned for one")]
|
[Option('s', "source", HelpText = "The location of the .csproj file that should be built and bundled. By default, the current directory is scanned for one")]
|
||||||
|
@ -62,6 +63,9 @@ namespace GameBundle {
|
||||||
public string BuildArgs { get; set; }
|
public string BuildArgs { get; set; }
|
||||||
[Option('n', "name-builds", HelpText = "Name the build output directories by the name of the executable")]
|
[Option('n', "name-builds", HelpText = "Name the build output directories by the name of the executable")]
|
||||||
public bool NameBuilds { get; set; }
|
public bool NameBuilds { get; set; }
|
||||||
|
[Option('N', "name-addition", HelpText = "An additional string of text that should be included in the names of the output directories")]
|
||||||
|
public string NameAddition { get; set; }
|
||||||
|
[Option('V', "include-version", HelpText = "Include the project's version in the names of the output directories")]
|
||||||
|
public bool IncludeVersion { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
|
@ -7,24 +7,25 @@ using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using CommandLine;
|
using CommandLine;
|
||||||
|
|
||||||
namespace GameBundle {
|
namespace GameBundle;
|
||||||
|
|
||||||
internal static class Program {
|
internal static class Program {
|
||||||
|
|
||||||
private static int Main(string[] args) {
|
private static int Main(string[] args) {
|
||||||
return new Parser(c => {
|
return new Parser(c => {
|
||||||
c.HelpWriter = Console.Error;
|
c.HelpWriter = Console.Error;
|
||||||
c.EnableDashDash = true;
|
c.EnableDashDash = true;
|
||||||
}).ParseArguments<Options>(args).MapResult(Run, _ => -1);
|
}).ParseArguments<Options>(args).MapResult(Program.Run, _ => -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int Run(Options options) {
|
private static int Run(Options options) {
|
||||||
// make sure all of the required tools are installed
|
// make sure all of the required tools are installed
|
||||||
if (RunProcess(options, "dotnet", "tool restore", AppDomain.CurrentDomain.BaseDirectory) != 0) {
|
if (Program.RunProcess(options, "dotnet", "tool restore", AppDomain.CurrentDomain.BaseDirectory) != 0) {
|
||||||
Console.WriteLine("dotnet tool restore failed, aborting");
|
Console.WriteLine("dotnet tool restore failed, aborting");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
var proj = GetProjectFile(options);
|
var proj = Program.GetProjectFile(options);
|
||||||
if (proj == null || !proj.Exists) {
|
if (proj == null || !proj.Exists) {
|
||||||
Console.WriteLine("Project file not found, aborting");
|
Console.WriteLine("Project file not found, aborting");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -36,16 +37,16 @@ namespace GameBundle {
|
||||||
// regular builds
|
// regular builds
|
||||||
new("windows", "win", options.WindowsRid, options.BuildWindows),
|
new("windows", "win", options.WindowsRid, options.BuildWindows),
|
||||||
new("linux", "linux", options.LinuxRid, options.BuildLinux),
|
new("linux", "linux", options.LinuxRid, options.BuildLinux),
|
||||||
new("mac", "mac", options.MacRid, options.BuildMac, false, d => options.MacBundle ? CreateMacBundle(options, d) : 0),
|
new("mac", "mac", options.MacRid, options.BuildMac, false, d => options.MacBundle ? Program.CreateMacBundle(options, d) : 0),
|
||||||
// arm builds
|
// arm builds
|
||||||
new("windows arm", "win-arm", options.WindowsArmRid, options.BuildWindowsArm, true),
|
new("windows arm", "win-arm", options.WindowsArmRid, options.BuildWindowsArm, true),
|
||||||
new("linux arm", "linux-arm", options.LinuxArmRid, options.BuildLinuxArm, true),
|
new("linux arm", "linux-arm", options.LinuxArmRid, options.BuildLinuxArm, true),
|
||||||
new("mac arm", "mac-arm", options.MacArmRid, options.BuildMacArm, true, d => options.MacBundle ? CreateMacBundle(options, d) : 0)
|
new("mac arm", "mac-arm", options.MacArmRid, options.BuildMacArm, true, d => options.MacBundle ? Program.CreateMacBundle(options, d) : 0)
|
||||||
};
|
};
|
||||||
foreach (var config in toBuild) {
|
foreach (var config in toBuild) {
|
||||||
if (config.ShouldBuild) {
|
if (config.ShouldBuild) {
|
||||||
Console.WriteLine($"Bundling for {config.DisplayName}");
|
Console.WriteLine($"Bundling for {config.DisplayName}");
|
||||||
var res = Publish(options, proj, config);
|
var res = Program.Publish(options, proj, config);
|
||||||
if (res != 0)
|
if (res != 0)
|
||||||
return res;
|
return res;
|
||||||
builtAnything = true;
|
builtAnything = true;
|
||||||
|
@ -59,8 +60,8 @@ namespace GameBundle {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int Publish(Options options, FileInfo proj, BuildConfig config) {
|
private static int Publish(Options options, FileInfo proj, BuildConfig config) {
|
||||||
var buildDir = GetBuildDir(options, config.DirectoryName);
|
var buildDir = Program.GetBuildDir(options, config.DirectoryName);
|
||||||
var publishResult = RunProcess(options, "dotnet", $"publish \"{proj.FullName}\" -o \"{buildDir.FullName}\" -r {config.Rid} --self-contained -c {options.BuildConfig} /p:PublishTrimmed={options.Trim} {options.BuildArgs}");
|
var publishResult = Program.RunProcess(options, "dotnet", $"publish \"{proj.FullName}\" -o \"{buildDir.FullName}\" -r {config.Rid} --self-contained -c {options.BuildConfig} /p:PublishTrimmed={options.Trim} {options.BuildArgs}");
|
||||||
if (publishResult != 0)
|
if (publishResult != 0)
|
||||||
return publishResult;
|
return publishResult;
|
||||||
|
|
||||||
|
@ -68,24 +69,31 @@ namespace GameBundle {
|
||||||
if (!options.SkipLib && !config.SkipLib) {
|
if (!options.SkipLib && !config.SkipLib) {
|
||||||
var excludes = $"\"{string.Join(";", options.ExcludedFiles)}\"";
|
var excludes = $"\"{string.Join(";", options.ExcludedFiles)}\"";
|
||||||
var log = options.Verbose ? "Detail" : "Error";
|
var log = options.Verbose ? "Detail" : "Error";
|
||||||
var beautyResult = RunProcess(options, "dotnet", $"ncbeauty --loglevel={log} --force=True --noflag=True \"{buildDir.FullName}\" \"{options.LibFolder}\" {excludes}", AppDomain.CurrentDomain.BaseDirectory);
|
var beautyResult = Program.RunProcess(options, "dotnet", $"ncbeauty --loglevel={log} --force=True --noflag=True \"{buildDir.FullName}\" \"{options.LibFolder}\" {excludes}", AppDomain.CurrentDomain.BaseDirectory);
|
||||||
if (beautyResult != 0)
|
if (beautyResult != 0)
|
||||||
return beautyResult;
|
return beautyResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add version if named builds are enabled
|
||||||
|
if (options.IncludeVersion) {
|
||||||
|
var version = Program.GetBuildVersion(buildDir);
|
||||||
|
if (version == null) {
|
||||||
|
Console.WriteLine("Couldn't determine build version, aborting");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
var dest = Path.Combine(buildDir.Parent.FullName, $"{version}-{buildDir.Name}");
|
||||||
|
Program.MoveDirectory(options, buildDir, dest);
|
||||||
|
}
|
||||||
|
|
||||||
// Rename build folder if named builds are enabled
|
// Rename build folder if named builds are enabled
|
||||||
if (options.NameBuilds) {
|
if (options.NameBuilds) {
|
||||||
var name = GetBuildName(options, buildDir);
|
var name = Program.GetBuildName(buildDir);
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
Console.WriteLine("Couldn't determine build name, aborting");
|
Console.WriteLine("Couldn't determine build name, aborting");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
var dest = Path.Combine(buildDir.Parent.FullName, $"{name}-{buildDir.Name}");
|
var dest = Path.Combine(buildDir.Parent.FullName, $"{name}-{buildDir.Name}");
|
||||||
if (Directory.Exists(dest))
|
Program.MoveDirectory(options, buildDir, dest);
|
||||||
Directory.Delete(dest, true);
|
|
||||||
buildDir.MoveTo(dest);
|
|
||||||
if (options.Verbose)
|
|
||||||
Console.WriteLine($"Moved build directory to {buildDir.FullName}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run any additional actions like creating the mac bundle
|
// Run any additional actions like creating the mac bundle
|
||||||
|
@ -133,13 +141,13 @@ namespace GameBundle {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int CreateMacBundle(Options options, DirectoryInfo buildDir) {
|
private static int CreateMacBundle(Options options, DirectoryInfo buildDir) {
|
||||||
var buildName = GetBuildName(options, buildDir);
|
var buildName = Program.GetBuildName(buildDir);
|
||||||
var app = buildDir.CreateSubdirectory($"{buildName}.app");
|
var app = buildDir.CreateSubdirectory($"{buildName}.app");
|
||||||
var contents = app.CreateSubdirectory("Contents");
|
var contents = app.CreateSubdirectory("Contents");
|
||||||
var resources = contents.CreateSubdirectory("Resources");
|
var resources = contents.CreateSubdirectory("Resources");
|
||||||
var macOs = contents.CreateSubdirectory("MacOS");
|
var macOs = contents.CreateSubdirectory("MacOS");
|
||||||
var resRegex = options.MacBundleResources.Select(GlobRegex).ToArray();
|
var resRegex = options.MacBundleResources.Select(Program.GlobRegex).ToArray();
|
||||||
var ignoreRegex = options.MacBundleIgnore.Select(GlobRegex).ToArray();
|
var ignoreRegex = options.MacBundleIgnore.Select(Program.GlobRegex).ToArray();
|
||||||
|
|
||||||
if (options.Verbose)
|
if (options.Verbose)
|
||||||
Console.WriteLine($"Creating app bundle {app}");
|
Console.WriteLine($"Creating app bundle {app}");
|
||||||
|
@ -176,23 +184,44 @@ namespace GameBundle {
|
||||||
return new Regex(s.Replace(".", "[.]").Replace("*", ".*").Replace("?", "."));
|
return new Regex(s.Replace(".", "[.]").Replace("*", ".*").Replace("?", "."));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DirectoryInfo GetBuildDir(Options options, string osName) {
|
private static DirectoryInfo GetBuildDir(Options options, string name) {
|
||||||
return new DirectoryInfo(Path.Combine(Path.GetFullPath(options.OutputDirectory), osName));
|
if (options.NameAddition != null)
|
||||||
|
name = $"{options.NameAddition}-{name}";
|
||||||
|
return new DirectoryInfo(Path.Combine(Path.GetFullPath(options.OutputDirectory), name));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetBuildName(Options options, DirectoryInfo buildDir) {
|
private static string GetBuildName(DirectoryInfo buildDir) {
|
||||||
// determine build name based on the names of the exe or binary that have a matching dll file
|
return Path.GetFileNameWithoutExtension(Program.GetAssemblyFile(buildDir)?.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetBuildVersion(DirectoryInfo buildDir) {
|
||||||
|
var assemblyFile = Program.GetAssemblyFile(buildDir);
|
||||||
|
if (assemblyFile == null)
|
||||||
|
return null;
|
||||||
|
var version = FileVersionInfo.GetVersionInfo(assemblyFile.FullName);
|
||||||
|
return version.ProductVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static FileInfo GetAssemblyFile(DirectoryInfo buildDir) {
|
||||||
var files = buildDir.GetFiles();
|
var files = buildDir.GetFiles();
|
||||||
foreach (var file in files) {
|
foreach (var file in files) {
|
||||||
if (file.Extension != ".exe" && file.Extension != string.Empty)
|
if (file.Extension != ".dll")
|
||||||
continue;
|
continue;
|
||||||
var name = Path.GetFileNameWithoutExtension(file.Name);
|
// the assembly is (most likely) the dll file that has a matching binary or exe file in the same location
|
||||||
if (files.Any(f => f.Extension == ".dll" && Path.GetFileNameWithoutExtension(f.Name) == name))
|
if (files.Any(f => f.Extension is ".exe" or "" && Path.GetFileNameWithoutExtension(f.Name) == Path.GetFileNameWithoutExtension(file.Name)))
|
||||||
return name;
|
return file;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void MoveDirectory(Options options, DirectoryInfo dir, string dest) {
|
||||||
|
if (Directory.Exists(dest))
|
||||||
|
Directory.Delete(dest, true);
|
||||||
|
dir.MoveTo(dest!);
|
||||||
|
if (options.Verbose)
|
||||||
|
Console.WriteLine($"Moved build directory to {dir.FullName}");
|
||||||
|
}
|
||||||
|
|
||||||
private readonly struct BuildConfig {
|
private readonly struct BuildConfig {
|
||||||
|
|
||||||
public readonly string DisplayName;
|
public readonly string DisplayName;
|
||||||
|
@ -214,4 +243,3 @@ namespace GameBundle {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
|
@ -1 +1,2 @@
|
||||||
"../GameBundle/bin/Debug/net6.0/GameBundle.exe" -wlmWL -bzn -s Test.csproj -o bin/Bundled -v --mac-bundle-ignore macmain.txt
|
rmdir /S /Q "bin/Bundled"
|
||||||
|
"../GameBundle/bin/Debug/net6.0/GameBundle.exe" -wlmWL -bznV -s Test.csproj -o bin/Bundled -v --mac-bundle-ignore macmain.txt -N beta
|
|
@ -2,19 +2,20 @@ using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using MLEM.Startup;
|
using MLEM.Startup;
|
||||||
|
|
||||||
namespace Test {
|
namespace Test;
|
||||||
|
|
||||||
public class GameImpl : MlemGame {
|
public class GameImpl : MlemGame {
|
||||||
|
|
||||||
public static GameImpl Instance { get; private set; }
|
public static GameImpl Instance { get; private set; }
|
||||||
private Texture2D texture;
|
private Texture2D texture;
|
||||||
|
|
||||||
public GameImpl() {
|
public GameImpl() {
|
||||||
Instance = this;
|
GameImpl.Instance = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadContent() {
|
protected override void LoadContent() {
|
||||||
base.LoadContent();
|
base.LoadContent();
|
||||||
this.texture = LoadContent<Texture2D>("Textures/Test");
|
this.texture = MlemGame.LoadContent<Texture2D>("Textures/Test");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void DoDraw(GameTime gameTime) {
|
protected override void DoDraw(GameTime gameTime) {
|
||||||
|
@ -26,4 +27,3 @@ namespace Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
|
@ -1,7 +1,8 @@
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using MLEM.Misc;
|
using MLEM.Misc;
|
||||||
|
|
||||||
namespace Test {
|
namespace Test;
|
||||||
|
|
||||||
public static class Program {
|
public static class Program {
|
||||||
|
|
||||||
public static void Main() {
|
public static void Main() {
|
||||||
|
@ -11,4 +12,3 @@ namespace Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
|
@ -6,6 +6,7 @@
|
||||||
<PublishReadyToRun>false</PublishReadyToRun>
|
<PublishReadyToRun>false</PublishReadyToRun>
|
||||||
<TieredCompilation>false</TieredCompilation>
|
<TieredCompilation>false</TieredCompilation>
|
||||||
<AssemblyName>Test Project</AssemblyName>
|
<AssemblyName>Test Project</AssemblyName>
|
||||||
|
<Version>1.2.3</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
Loading…
Reference in a new issue