From 767824779016d4c1f2a21e335308da7aca472d1f Mon Sep 17 00:00:00 2001 From: Paul Balaji Date: Fri, 28 Aug 2020 18:37:34 +0100 Subject: [PATCH] Refactor and test `BuildContext` (#1461) --- CHANGELOG.md | 5 + .../Config/BuildConfiguration.asset | 54 ++++---- .../BuildSystem/UnityWorkerMenuGenerator.cs | 17 +-- .../AssemblyInfo.cs | 1 + .../Configuration/BuildConfig.cs | 20 ++- .../Configuration/BuildConfigEditor.cs | 18 ++- .../Configuration/BuildContext.cs | 54 +++----- .../BuildContextSettings.cs} | 117 ++++++++++++------ .../BuildContextSettings.cs.meta | 3 + .../Configuration/BuildEnvironmentConfig.cs | 51 +++++++- .../Configuration/BuildTargetConfig.cs | 42 +++++-- .../Configuration/WorkerBuildData.cs | 14 ++- .../io.improbable.gdk.buildsystem/Tests.meta | 8 ++ .../Tests/BuildConfigUtils.cs | 20 +++ .../Tests/BuildConfigUtils.cs.meta | 3 + .../Tests/BuildContextTestBase.cs | 40 ++++++ .../BuildContextTestBase.cs.meta} | 2 +- .../Tests/CloudBuildContextTests.cs | 113 +++++++++++++++++ .../Tests/CloudBuildContextTests.cs.meta | 3 + .../Improbable.Gdk.BuildSystem.Tests.asmdef | 31 +++++ ...probable.Gdk.BuildSystem.Tests.asmdef.meta | 7 ++ .../Tests/LocalBuildContextTests.cs | 113 +++++++++++++++++ .../Tests/LocalBuildContextTests.cs.meta | 3 + .../WorkerBuilder.cs | 18 ++- 24 files changed, 606 insertions(+), 151 deletions(-) rename workers/unity/Packages/io.improbable.gdk.buildsystem/{Util/CommandlineParser.cs => Configuration/BuildContextSettings.cs} (59%) create mode 100644 workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/BuildContextSettings.cs.meta create mode 100644 workers/unity/Packages/io.improbable.gdk.buildsystem/Tests.meta create mode 100644 workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/BuildConfigUtils.cs create mode 100644 workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/BuildConfigUtils.cs.meta create mode 100644 workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/BuildContextTestBase.cs rename workers/unity/Packages/io.improbable.gdk.buildsystem/{Util/CommandlineParser.cs.meta => Tests/BuildContextTestBase.cs.meta} (83%) create mode 100644 workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/CloudBuildContextTests.cs create mode 100644 workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/CloudBuildContextTests.cs.meta create mode 100644 workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/Improbable.Gdk.BuildSystem.Tests.asmdef create mode 100644 workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/Improbable.Gdk.BuildSystem.Tests.asmdef.meta create mode 100644 workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/LocalBuildContextTests.cs create mode 100644 workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/LocalBuildContextTests.cs.meta diff --git a/CHANGELOG.md b/CHANGELOG.md index a6c8c0aab4..77af69b33e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,10 +21,15 @@ - Multithreaded component serialization through `SystemBase` jobs. [#1454](https://github.com/spatialos/gdk-for-unity/pull/1454) - Upgrade Unity Burst to 1.3.5. [#1467](https://github.com/spatialos/gdk-for-unity/pull/1467) - Removed outline and background around component info button in the Worker Inspector. [#1468](https://github.com/spatialos/gdk-for-unity/pull/1468) +- Refactored the `BuildContext` class. [#1461](https://github.com/spatialos/gdk-for-unity/pull/1461) + - Introduced a `BuildContextSettings` struct, which is required by `GetBuildContexts`. + - Changed `BuildConfig` class visibility from `internal` to `public`. + - Added more testing around `BuildContext`. ### Fixed - Fixed an issue where authority changes returned by `ComponentUpdateSystem.GetAuthorityChangesReceived()` were returned in order from newest to oldest. [#1465](https://github.com/spatialos/gdk-for-unity/pull/1465) +- Fixed a bug where the build system would throw a null reference exception if you don't have a configuration for a worker type. [#1461](https://github.com/spatialos/gdk-for-unity/pull/1461) ## `0.3.10` - 2020-08-18 diff --git a/workers/unity/Assets/Playground/Config/BuildConfiguration.asset b/workers/unity/Assets/Playground/Config/BuildConfiguration.asset index 59f76b7c10..bb042df933 100644 --- a/workers/unity/Assets/Playground/Config/BuildConfiguration.asset +++ b/workers/unity/Assets/Playground/Config/BuildConfiguration.asset @@ -22,49 +22,49 @@ MonoBehaviour: Deprecated: 0 Enabled: 1 Required: 0 - ScriptingImplementation: 0 + scriptingImplementation: 0 - Options: 0 Deprecated: 0 Enabled: 0 Required: 0 - ScriptingImplementation: 0 + scriptingImplementation: 0 - Options: 0 Deprecated: 0 Enabled: 0 Required: 0 - ScriptingImplementation: 1 + scriptingImplementation: 1 CloudBuildConfig: BuildTargets: - Options: 0 Deprecated: 1 Enabled: 1 Required: 0 - ScriptingImplementation: 0 + scriptingImplementation: 0 - Options: 0 Deprecated: 0 Enabled: 1 Required: 0 - ScriptingImplementation: 0 + scriptingImplementation: 0 - Options: 16384 Deprecated: 0 Enabled: 0 Required: 0 - ScriptingImplementation: 0 + scriptingImplementation: 0 - Options: 0 Deprecated: 0 Enabled: 1 Required: 0 - ScriptingImplementation: 0 + scriptingImplementation: 0 - Options: 0 Deprecated: 0 Enabled: 0 Required: 0 - ScriptingImplementation: 0 + scriptingImplementation: 0 - Options: 0 Deprecated: 0 Enabled: 0 Required: 0 - ScriptingImplementation: 1 + scriptingImplementation: 1 - WorkerType: UnityGameLogic ScenesForWorker: - {fileID: 102900000, guid: 8c0c8d31c7a7905409ce6be1f36f162e, type: 3} @@ -74,49 +74,49 @@ MonoBehaviour: Deprecated: 0 Enabled: 1 Required: 0 - ScriptingImplementation: 0 + scriptingImplementation: 0 - Options: 0 Deprecated: 0 Enabled: 0 Required: 0 - ScriptingImplementation: 0 + scriptingImplementation: 0 - Options: 0 Deprecated: 0 Enabled: 0 Required: 0 - ScriptingImplementation: 1 + scriptingImplementation: 1 CloudBuildConfig: BuildTargets: - Options: 0 Deprecated: 1 Enabled: 0 Required: 0 - ScriptingImplementation: 0 + scriptingImplementation: 0 - Options: 0 Deprecated: 0 Enabled: 0 Required: 0 - ScriptingImplementation: 0 + scriptingImplementation: 0 - Options: 16384 Deprecated: 0 Enabled: 1 Required: 1 - ScriptingImplementation: 0 + scriptingImplementation: 0 - Options: 0 Deprecated: 0 Enabled: 0 Required: 0 - ScriptingImplementation: 0 + scriptingImplementation: 0 - Options: 0 Deprecated: 0 Enabled: 0 Required: 0 - ScriptingImplementation: 0 + scriptingImplementation: 0 - Options: 0 Deprecated: 0 Enabled: 0 Required: 0 - ScriptingImplementation: 1 + scriptingImplementation: 1 - WorkerType: MobileClient ScenesForWorker: - {fileID: 102900000, guid: 82ccd0fd96a2ba24f88d0c7d01592f2e, type: 3} @@ -126,47 +126,47 @@ MonoBehaviour: Deprecated: 0 Enabled: 0 Required: 0 - ScriptingImplementation: 0 + scriptingImplementation: 0 - Options: 1 Deprecated: 0 Enabled: 1 Required: 0 - ScriptingImplementation: 0 + scriptingImplementation: 0 - Options: 1 Deprecated: 0 Enabled: 1 Required: 0 - ScriptingImplementation: 1 + scriptingImplementation: 1 CloudBuildConfig: BuildTargets: - Options: 0 Deprecated: 1 Enabled: 0 Required: 0 - ScriptingImplementation: 0 + scriptingImplementation: 0 - Options: 0 Deprecated: 0 Enabled: 0 Required: 0 - ScriptingImplementation: 0 + scriptingImplementation: 0 - Options: 16384 Deprecated: 0 Enabled: 0 Required: 0 - ScriptingImplementation: 0 + scriptingImplementation: 0 - Options: 0 Deprecated: 0 Enabled: 0 Required: 0 - ScriptingImplementation: 0 + scriptingImplementation: 0 - Options: 0 Deprecated: 0 Enabled: 1 Required: 0 - ScriptingImplementation: 0 + scriptingImplementation: 0 - Options: 0 Deprecated: 0 Enabled: 1 Required: 0 - ScriptingImplementation: 1 + scriptingImplementation: 1 isInitialised: 1 diff --git a/workers/unity/Packages/io.improbable.gdk.buildsystem/.codegen/Source/Generators/BuildSystem/UnityWorkerMenuGenerator.cs b/workers/unity/Packages/io.improbable.gdk.buildsystem/.codegen/Source/Generators/BuildSystem/UnityWorkerMenuGenerator.cs index 0c490db3b7..89d99d2f36 100644 --- a/workers/unity/Packages/io.improbable.gdk.buildsystem/.codegen/Source/Generators/BuildSystem/UnityWorkerMenuGenerator.cs +++ b/workers/unity/Packages/io.improbable.gdk.buildsystem/.codegen/Source/Generators/BuildSystem/UnityWorkerMenuGenerator.cs @@ -45,13 +45,13 @@ public static CodeWriter Generate(List workerTypes) buildWorkerMenu.Annotate($@"MenuItem(EditorConfig.ParentMenu + ""/"" + LocalMenu + ""/{workerType}"", false, EditorConfig.MenuOffset + {i})") .Method($"public static void BuildLocal{workerType}()", () => new[] { - $@"MenuBuildLocal(new[] {{ {workerTypeString} }});" + $"MenuBuild(BuildContextSettings.Local({workerTypeString}));" }); buildWorkerMenu.Annotate($@"MenuItem(EditorConfig.ParentMenu + ""/"" + CloudMenu + ""/{workerType}"", false, EditorConfig.MenuOffset + {i})") .Method($"public static void BuildCloud{workerType}()", () => new[] { - $@"MenuBuildCloud(new[] {{ {workerTypeString} }});" + $"MenuBuild(BuildContextSettings.Cloud({workerTypeString}));" }); allMenuOptionValidators.Annotate($@"MenuItem(EditorConfig.ParentMenu + ""/"" + LocalMenu + ""/{workerType}"", true, EditorConfig.MenuOffset + {i})") @@ -66,13 +66,13 @@ public static CodeWriter Generate(List workerTypes) buildWorkerMenu.Annotate($@"MenuItem(EditorConfig.ParentMenu + ""/"" + LocalMenu + ""/All workers"", false, EditorConfig.MenuOffset + {workerTypes.Count})") .Method("public static void BuildLocalAll()", () => new[] { - "MenuBuildLocal(AllWorkers);" + "MenuBuild(BuildContextSettings.Local(AllWorkers));" }); buildWorkerMenu.Annotate($@"MenuItem(EditorConfig.ParentMenu + ""/"" + CloudMenu + ""/All workers"", false, EditorConfig.MenuOffset + {workerTypes.Count})") .Method("public static void BuildCloudAll()", () => new[] { - "MenuBuildCloud(AllWorkers);" + "MenuBuild(BuildContextSettings.Cloud(AllWorkers));" }); buildWorkerMenu.Annotate($@"MenuItem(EditorConfig.ParentMenu + ""/Clean all workers"", false, EditorConfig.MenuOffset + {workerTypes.Count})") @@ -81,14 +81,9 @@ public static CodeWriter Generate(List workerTypes) "MenuCleanAll();" }); - buildWorkerMenu.Method("private static void MenuBuildLocal(string[] filteredWorkerTypes)", () => new[] + buildWorkerMenu.Method("private static void MenuBuild(BuildContextSettings buildContextSettings)", () => new[] { - "WorkerBuilder.MenuBuild(BuildEnvironment.Local, filteredWorkerTypes);" - }); - - buildWorkerMenu.Method("private static void MenuBuildCloud(string[] filteredWorkerTypes)", () => new[] - { - "WorkerBuilder.MenuBuild(BuildEnvironment.Cloud, filteredWorkerTypes);" + "WorkerBuilder.MenuBuild(buildContextSettings);" }); buildWorkerMenu.Method("private static void MenuCleanAll()", () => new[] diff --git a/workers/unity/Packages/io.improbable.gdk.buildsystem/AssemblyInfo.cs b/workers/unity/Packages/io.improbable.gdk.buildsystem/AssemblyInfo.cs index 7257c5dff5..79b843107d 100644 --- a/workers/unity/Packages/io.improbable.gdk.buildsystem/AssemblyInfo.cs +++ b/workers/unity/Packages/io.improbable.gdk.buildsystem/AssemblyInfo.cs @@ -1,3 +1,4 @@ using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("Improbable.Gdk.Generated.BuildSystem")] +[assembly: InternalsVisibleTo("Improbable.Gdk.BuildSystem.Tests")] diff --git a/workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/BuildConfig.cs b/workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/BuildConfig.cs index 6eb205322a..cce810bf75 100644 --- a/workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/BuildConfig.cs +++ b/workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/BuildConfig.cs @@ -7,15 +7,15 @@ namespace Improbable.Gdk.BuildSystem.Configuration { [CreateAssetMenu(fileName = "SpatialOS Build Configuration", menuName = BuildConfigEditor.BuildConfigurationMenu)] - internal class BuildConfig : SingletonScriptableObject + public class BuildConfig : SingletonScriptableObject { [SerializeField] - public List WorkerBuildConfigurations = + internal List WorkerBuildConfigurations = new List(); [SerializeField] private bool isInitialised; - public BuildEnvironmentConfig GetEnvironmentConfigForWorker(string workerType, BuildEnvironment environment) + internal BuildEnvironmentConfig GetEnvironmentConfigForWorker(string workerType, BuildEnvironment environment) { var config = WorkerBuildConfigurations.FirstOrDefault(x => x.WorkerType == workerType); if (config == null) @@ -56,8 +56,18 @@ private void ResetToDefault() WorkerBuildData.GetCurrentBuildTargetConfig()), CloudBuildConfig = new BuildEnvironmentConfig( WorkerBuildData.AllBuildTargets, - new BuildTargetConfig(BuildTarget.StandaloneOSX, BuildOptions.Development, enabled: true, required: false), - new BuildTargetConfig(BuildTarget.StandaloneWindows64, BuildOptions.Development, enabled: true, required: false)) + new BuildTargetConfig(BuildTarget.StandaloneOSX) + { + Options = BuildOptions.Development, + Enabled = true, + Required = false + }, + new BuildTargetConfig(BuildTarget.StandaloneWindows64) + { + Options = BuildOptions.Development, + Enabled = true, + Required = false + }) }, new WorkerBuildConfiguration { diff --git a/workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/BuildConfigEditor.cs b/workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/BuildConfigEditor.cs index c0ff34443d..337b2e714b 100644 --- a/workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/BuildConfigEditor.cs +++ b/workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/BuildConfigEditor.cs @@ -575,13 +575,17 @@ private void DrawEnvironmentInspector(BuildEnvironment environment, { foldoutState.Icon = new GUIContent(EditorGUIUtility.IconContent(BuildConfigEditorStyle.BuiltInErrorIcon)) - { tooltip = "Missing build support for one or more build targets." }; + { + tooltip = "Missing build support for one or more build targets." + }; } else if (environmentConfiguration.BuildTargets.Any(IsBuildTargetWarning)) { foldoutState.Icon = new GUIContent(EditorGUIUtility.IconContent(BuildConfigEditorStyle.BuiltInWarningIcon)) - { tooltip = "Missing build support for one or more build targets." }; + { + tooltip = "Missing build support for one or more build targets." + }; } else { @@ -721,8 +725,14 @@ private void DrawBuildTargets(BuildEnvironmentConfig env, int hash) { RecordUndo("Worker build options"); - env.BuildTargets[selectedTargetIndex] = - new BuildTargetConfig(buildTarget.Target, options, enabled, required, deprecated: false, scriptingImplementation); + env.BuildTargets[selectedTargetIndex] = new BuildTargetConfig(buildTarget.Target) + { + Options = options, + Enabled = enabled, + Required = required, + Deprecated = false, + ScriptingImplementation = scriptingImplementation + }; selectedBuildTarget.Choices = null; } diff --git a/workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/BuildContext.cs b/workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/BuildContext.cs index 6e3c736ba4..cc17f79418 100644 --- a/workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/BuildContext.cs +++ b/workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/BuildContext.cs @@ -2,7 +2,6 @@ using System.Linq; using UnityEditor; using UnityEditor.Build; -using UnityEngine; namespace Improbable.Gdk.BuildSystem.Configuration { @@ -14,60 +13,37 @@ public struct BuildContext public ScriptingImplementation ScriptingImplementation; public iOSSdkVersion? IOSSdkVersion; - public static List GetBuildContexts(IEnumerable wantedWorkerTypes, - BuildEnvironment buildEnvironment, ScriptingImplementation? scriptImplementation = null, - ICollection buildTargetFilter = null, iOSSdkVersion? iosSdkVersion = null) + public static List GetBuildContexts(BuildConfig buildConfig, BuildContextSettings contextSettings) { - var spatialOsBuildConfiguration = BuildConfig.GetInstance(); var result = new List(); - foreach (var workerType in wantedWorkerTypes) + foreach (var workerType in contextSettings.WantedWorkerTypes) { var environmentConfig = - spatialOsBuildConfiguration.GetEnvironmentConfigForWorker(workerType, buildEnvironment); + buildConfig.GetEnvironmentConfigForWorker(workerType, contextSettings.BuildEnvironment); - // Filter targets for CI - var targetConfigs = environmentConfig.BuildTargets - .Where(t => t.Enabled && (buildTargetFilter?.Contains(t.Target) ?? true)) - .ToList(); - - // Filter out any deprecated targets - var supportedTargets = targetConfigs - .Where(c => !c.Deprecated) - .ToList(); - - // Which build targets are not supported by current install? - var missingTargets = supportedTargets - .Where(c => !BuildSupportChecker.CanBuildTarget(c.Target)) - .ToList(); - - // Error on missing required build support - if (missingTargets.Any(c => c.Required)) + if (environmentConfig == null) { - var targetNames = string.Join(", ", missingTargets - .Where(c => c.Required) - .Select(c => c.Target.ToString())); - throw new BuildFailedException( - $"Build failed for {workerType}. Cannot build for required ({targetNames}) because build support is not installed in the Unity Editor."); + continue; } - // Log builds we're skipping - if (missingTargets.Count > 0) + IEnumerable supportedTargets; + try { - var targetNames = string.Join(", ", missingTargets.Select(c => c.Target.ToString())); - Debug.LogWarning( - $"Skipping ({targetNames}) because build support is not installed in the Unity Editor and the build target is not marked as 'Required'."); - - supportedTargets.RemoveAll(t => missingTargets.Contains(t)); + supportedTargets = environmentConfig.GetSupportedTargets(contextSettings); + } + catch (BuildFailedException exception) + { + throw new BuildFailedException($"Build failed for {workerType}. {exception.Message}"); } result.AddRange(supportedTargets.Select(targetConfig => new BuildContext { WorkerType = workerType, - BuildEnvironment = buildEnvironment, - ScriptingImplementation = scriptImplementation ?? targetConfig.ScriptingImplementation, + BuildEnvironment = contextSettings.BuildEnvironment, + ScriptingImplementation = contextSettings.ScriptImplementation ?? targetConfig.ScriptingImplementation, BuildTargetConfig = targetConfig, - IOSSdkVersion = (targetConfig.Target == BuildTarget.iOS) ? iosSdkVersion : null + IOSSdkVersion = (targetConfig.Target == BuildTarget.iOS) ? contextSettings.IOSSdkVersion : null })); } diff --git a/workers/unity/Packages/io.improbable.gdk.buildsystem/Util/CommandlineParser.cs b/workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/BuildContextSettings.cs similarity index 59% rename from workers/unity/Packages/io.improbable.gdk.buildsystem/Util/CommandlineParser.cs rename to workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/BuildContextSettings.cs index df4cd53f55..2b5e30c3a4 100644 --- a/workers/unity/Packages/io.improbable.gdk.buildsystem/Util/CommandlineParser.cs +++ b/workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/BuildContextSettings.cs @@ -1,22 +1,91 @@ using System; using System.Collections.Generic; using System.Linq; -using Improbable.Gdk.BuildSystem.Configuration; using Improbable.Gdk.Core; using UnityEditor; -namespace Improbable.Gdk.BuildSystem +namespace Improbable.Gdk.BuildSystem.Configuration { - public static class CommandlineParser + public struct BuildContextSettings { - internal static string[] GetWorkerTypesToBuild(CommandLineArgs args) + public IEnumerable WantedWorkerTypes; + public BuildEnvironment BuildEnvironment; + public ScriptingImplementation? ScriptImplementation; + public ICollection BuildTargetFilter; + public iOSSdkVersion? IOSSdkVersion; + + public BuildContextSettings(IEnumerable wantedWorkerTypes, BuildEnvironment buildEnvironment, + ScriptingImplementation? scriptImplementation = null, ICollection buildTargetFilter = null, + iOSSdkVersion? iosSdkVersion = null) + { + WantedWorkerTypes = wantedWorkerTypes; + BuildEnvironment = buildEnvironment; + ScriptImplementation = scriptImplementation; + BuildTargetFilter = buildTargetFilter; + IOSSdkVersion = iosSdkVersion; + } + + public static BuildContextSettings Local(params string[] wantedWorkerTypes) + { + return new BuildContextSettings(wantedWorkerTypes, BuildEnvironment.Local); + } + + public static BuildContextSettings Cloud(params string[] wantedWorkerTypes) + { + return new BuildContextSettings(wantedWorkerTypes, BuildEnvironment.Cloud); + } + + public static BuildContextSettings FromCommandLine(CommandLineArgs args) + { + return new BuildContextSettings + { + WantedWorkerTypes = GetWorkerTypesToBuild(args), + BuildEnvironment = GetBuildEnvironment(args), + ScriptImplementation = GetScriptingImplementation(args), + BuildTargetFilter = GetBuildTargetFilter(args), + IOSSdkVersion = GetTargetIOSSdk(args) + }; + } + + private static string[] GetWorkerTypesToBuild(CommandLineArgs args) { var workerTypesArg = args.GetCommandLineValue("buildWorkerTypes", "UnityClient,UnityGameLogic"); var wantedWorkerTypes = workerTypesArg.Split(','); return wantedWorkerTypes; } - internal static List GetBuildTargetFilter(CommandLineArgs args) + private static BuildEnvironment GetBuildEnvironment(CommandLineArgs args) + { + var buildEnvironmentArg = args.GetCommandLineValue("buildEnvironment", "local").ToLower(); + + switch (buildEnvironmentArg) + { + case "cloud": + return BuildEnvironment.Cloud; + case "local": + return BuildEnvironment.Local; + default: + throw new ArgumentOutOfRangeException(nameof(buildEnvironmentArg), buildEnvironmentArg, + "Unknown build environment"); + } + } + + private static ScriptingImplementation GetScriptingImplementation(CommandLineArgs args) + { + var wantedScriptingBackend = args.GetCommandLineValue("scriptingBackend", "mono").ToLower(); + switch (wantedScriptingBackend) + { + case "mono": + return ScriptingImplementation.Mono2x; + case "il2cpp": + return ScriptingImplementation.IL2CPP; + default: + throw new ArgumentOutOfRangeException(nameof(wantedScriptingBackend), wantedScriptingBackend, + "Unknown scripting backend"); + } + } + + private static List GetBuildTargetFilter(CommandLineArgs args) { var buildTargetFilterArg = string.Empty; if (!args.TryGetCommandLineValue("buildTargetFilter", ref buildTargetFilterArg)) @@ -49,38 +118,7 @@ internal static List GetBuildTargetFilter(CommandLineArgs args) }).ToList(); } - internal static ScriptingImplementation GetScriptingImplementation(CommandLineArgs args) - { - var wantedScriptingBackend = args.GetCommandLineValue("scriptingBackend", "mono").ToLower(); - switch (wantedScriptingBackend) - { - case "mono": - return ScriptingImplementation.Mono2x; - case "il2cpp": - return ScriptingImplementation.IL2CPP; - default: - throw new ArgumentOutOfRangeException(nameof(wantedScriptingBackend), wantedScriptingBackend, - "Unknown scripting backend"); - } - } - - internal static BuildEnvironment GetBuildEnvironment(CommandLineArgs args) - { - var buildEnvironmentArg = args.GetCommandLineValue("buildEnvironment", "local").ToLower(); - - switch (buildEnvironmentArg) - { - case "cloud": - return BuildEnvironment.Cloud; - case "local": - return BuildEnvironment.Local; - default: - throw new ArgumentOutOfRangeException(nameof(buildEnvironmentArg), buildEnvironmentArg, - "Unknown build environment"); - } - } - - internal static iOSSdkVersion GetTargetIOSSdk(CommandLineArgs args) + private static iOSSdkVersion GetTargetIOSSdk(CommandLineArgs args) { var targetIOSSdkArg = args.GetCommandLineValue("targetiOSSdk", string.Empty).ToLower(); if (string.IsNullOrEmpty(targetIOSSdkArg)) @@ -99,5 +137,10 @@ internal static iOSSdkVersion GetTargetIOSSdk(CommandLineArgs args) "Unknown target iOS SDK"); } } + + public bool Matches(BuildTarget target) + { + return BuildTargetFilter?.Contains(target) ?? true; + } } } diff --git a/workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/BuildContextSettings.cs.meta b/workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/BuildContextSettings.cs.meta new file mode 100644 index 0000000000..ed4c6dc6a4 --- /dev/null +++ b/workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/BuildContextSettings.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b11385fdd5c943408923ccf422ba8691 +timeCreated: 1597938648 \ No newline at end of file diff --git a/workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/BuildEnvironmentConfig.cs b/workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/BuildEnvironmentConfig.cs index 8f2b4bbf0f..40b7f0a1a3 100644 --- a/workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/BuildEnvironmentConfig.cs +++ b/workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/BuildEnvironmentConfig.cs @@ -2,6 +2,8 @@ using System.Collections.Generic; using System.Linq; using UnityEditor; +using UnityEditor.Build; +using UnityEngine; namespace Improbable.Gdk.BuildSystem.Configuration { @@ -37,11 +39,54 @@ public BuildEnvironmentConfig(IEnumerable availableTargets, params } else { - BuildTargets.Add(new BuildTargetConfig(available, - WorkerBuildData.BuildTargetDefaultOptions[available], enabled: false, - required: false, deprecated: BuildSupportChecker.IsDeprecatedTarget(available))); + BuildTargets.Add(new BuildTargetConfig(available) + { + Options = WorkerBuildData.BuildTargetDefaultOptions[available], + Enabled = false, + Required = false, + Deprecated = BuildSupportChecker.IsDeprecatedTarget(available) + }); } } } + + public IEnumerable GetSupportedTargets(BuildContextSettings contextSettings) + { + // Filter targets for CI + var targetConfigs = BuildTargets + .Where(t => t.Enabled && contextSettings.Matches(t.Target)) + .ToList(); + + // Filter out any deprecated targets + var supportedTargets = targetConfigs + .Where(c => !c.Deprecated) + .ToList(); + + // Which build targets are not supported by current install? + var missingTargets = supportedTargets + .Where(c => !BuildSupportChecker.CanBuildTarget(c.Target)) + .ToList(); + + // Error on missing required build support + if (missingTargets.Any(c => c.Required)) + { + var targetNames = string.Join(", ", missingTargets + .Where(c => c.Required) + .Select(c => c.Target.ToString())); + throw new BuildFailedException($"Cannot build for required ({targetNames}) because build support is not installed in the Unity Editor."); + } + + // Log builds we're skipping + if (missingTargets.Count > 0) + { + var targetNames = string.Join(", ", missingTargets.Select(c => c.Target.ToString())); + Debug.LogWarning( + $"Skipping ({targetNames}) because build support is not installed in the Unity Editor and the build target is not marked as 'Required'."); + + supportedTargets.RemoveAll(t => missingTargets.Contains(t)); + } + + return supportedTargets; + } } } diff --git a/workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/BuildTargetConfig.cs b/workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/BuildTargetConfig.cs index 86a42ad347..26860ffc87 100644 --- a/workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/BuildTargetConfig.cs +++ b/workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/BuildTargetConfig.cs @@ -1,5 +1,6 @@ using System; using UnityEditor; +using UnityEngine; namespace Improbable.Gdk.BuildSystem.Configuration { @@ -17,7 +18,18 @@ public struct BuildTargetConfig /// /// The target to build. /// - [NonSerialized] public BuildTarget Target; + public BuildTarget Target + { + get => buildTarget; + set + { + buildTarget = value; + if (buildTarget == BuildTarget.iOS) + { + scriptingImplementation = ScriptingImplementation.IL2CPP; + } + } + } /// /// Is this target deprecated? @@ -38,7 +50,15 @@ public struct BuildTargetConfig /// /// The backend scripting implementation. /// - public ScriptingImplementation ScriptingImplementation; + public ScriptingImplementation ScriptingImplementation + { + get => scriptingImplementation; + // If build target is iOS then force the Scripting Implementation to be IL2CPP (as Mono is not supported) + set => scriptingImplementation = Target == BuildTarget.iOS ? ScriptingImplementation.IL2CPP : value; + } + + private BuildTarget buildTarget; + [SerializeField] private ScriptingImplementation scriptingImplementation; internal string Label { @@ -68,17 +88,17 @@ internal string Label /// /// Creates a new instance of a build target and its options. /// - public BuildTargetConfig(BuildTarget target, BuildOptions options, - bool enabled, bool required, bool deprecated = false, ScriptingImplementation scriptingImplementation = ScriptingImplementation.Mono2x) + public BuildTargetConfig(BuildTarget target) : this() { - Enabled = enabled; - Required = required; - Target = target; - Options = options; - Deprecated = deprecated; + // Set default settings + Options = BuildOptions.None; + Enabled = true; + Required = false; + Deprecated = false; + ScriptingImplementation = ScriptingImplementation.Mono2x; - // If build target is iOS then force the Scripting Implementation to be IL2CPP (as Mono is not supported) - ScriptingImplementation = target == BuildTarget.iOS ? ScriptingImplementation.IL2CPP : scriptingImplementation; + // Set the build target + Target = target; } } } diff --git a/workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/WorkerBuildData.cs b/workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/WorkerBuildData.cs index 3df6f182e1..cc0d6ae447 100644 --- a/workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/WorkerBuildData.cs +++ b/workers/unity/Packages/io.improbable.gdk.buildsystem/Configuration/WorkerBuildData.cs @@ -113,12 +113,22 @@ internal WorkerBuildData(string workerType, BuildTarget buildTarget) internal static BuildTargetConfig GetCurrentBuildTargetConfig() { - return new BuildTargetConfig(CurrentBuildPlatform, BuildTargetDefaultOptions[CurrentBuildPlatform], enabled: true, required: false); + return new BuildTargetConfig(CurrentBuildPlatform) + { + Options = BuildTargetDefaultOptions[CurrentBuildPlatform], + Enabled = true, + Required = false + }; } internal static BuildTargetConfig GetLinuxBuildTargetConfig() { - return new BuildTargetConfig(BuildTarget.StandaloneLinux64, BuildTargetDefaultOptions[BuildTarget.StandaloneLinux64], enabled: true, required: false); + return new BuildTargetConfig(BuildTarget.StandaloneLinux64) + { + Options = BuildTargetDefaultOptions[BuildTarget.StandaloneLinux64], + Enabled = true, + Required = false + }; } } } diff --git a/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests.meta b/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests.meta new file mode 100644 index 0000000000..a6a0cb5d75 --- /dev/null +++ b/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a7ab4b5faee040c9bc76dfc90316a861 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/BuildConfigUtils.cs b/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/BuildConfigUtils.cs new file mode 100644 index 0000000000..b836291853 --- /dev/null +++ b/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/BuildConfigUtils.cs @@ -0,0 +1,20 @@ +using Improbable.Gdk.BuildSystem.Configuration; + +namespace Improbable.Gdk.BuildSystem.Tests +{ + internal static class BuildConfigUtils + { + internal static BuildConfig AddWorker(this BuildConfig buildConfig, string workerType, BuildTargetConfig[] localConfigs, BuildTargetConfig[] cloudConfigs) + { + var workerConfig = new WorkerBuildConfiguration + { + WorkerType = workerType, + LocalBuildConfig = new BuildEnvironmentConfig(WorkerBuildData.LocalBuildTargets, localConfigs), + CloudBuildConfig = new BuildEnvironmentConfig(WorkerBuildData.AllBuildTargets, cloudConfigs) + }; + + buildConfig.WorkerBuildConfigurations.Add(workerConfig); + return buildConfig; + } + } +} diff --git a/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/BuildConfigUtils.cs.meta b/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/BuildConfigUtils.cs.meta new file mode 100644 index 0000000000..77efe5817f --- /dev/null +++ b/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/BuildConfigUtils.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 8c177433049f4969827fb011d4470f85 +timeCreated: 1598280270 \ No newline at end of file diff --git a/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/BuildContextTestBase.cs b/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/BuildContextTestBase.cs new file mode 100644 index 0000000000..0d9f329639 --- /dev/null +++ b/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/BuildContextTestBase.cs @@ -0,0 +1,40 @@ +using Improbable.Gdk.BuildSystem.Configuration; +using UnityEditor; +using UnityEngine; + +namespace Improbable.Gdk.BuildSystem.Tests +{ + public class BuildContextTestBase + { + internal const string ClientType = "UnityClient"; + internal const string ServerType = "UnityGameLogic"; + internal const string MobileClientType = "MobileClient"; + internal const string InvalidWorkerType = "DummyWorkerType"; + + internal const BuildTarget WindowsTarget = BuildTarget.StandaloneWindows64; + internal const BuildTarget MacTarget = BuildTarget.StandaloneOSX; + internal const BuildTarget LinuxTarget = BuildTarget.StandaloneLinux64; + +#if UNITY_EDITOR_WIN + internal const BuildTarget LocalTarget = WindowsTarget; +#elif UNITY_EDITOR_OSX + internal const BuildTarget LocalTarget = MacTarget; +#endif + + internal const BuildTarget AndroidTarget = BuildTarget.Android; + internal const BuildTarget IOSTarget = BuildTarget.iOS; + + internal static readonly BuildConfig EmptyBuildConfig = ScriptableObject.CreateInstance(); + + internal static readonly BuildConfig ValidBuildConfig = ScriptableObject.CreateInstance() + .AddWorker(ServerType, + localConfigs: new[] { new BuildTargetConfig(LocalTarget) }, + cloudConfigs: new[] { new BuildTargetConfig(LinuxTarget) }) + .AddWorker(ClientType, + localConfigs: new[] { new BuildTargetConfig(LocalTarget) }, + cloudConfigs: new[] { new BuildTargetConfig(WindowsTarget), new BuildTargetConfig(MacTarget) }) + .AddWorker(MobileClientType, + localConfigs: new[] { new BuildTargetConfig(BuildTarget.Android), new BuildTargetConfig(BuildTarget.iOS) }, + cloudConfigs: new[] { new BuildTargetConfig(BuildTarget.Android), new BuildTargetConfig(BuildTarget.iOS) }); + } +} diff --git a/workers/unity/Packages/io.improbable.gdk.buildsystem/Util/CommandlineParser.cs.meta b/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/BuildContextTestBase.cs.meta similarity index 83% rename from workers/unity/Packages/io.improbable.gdk.buildsystem/Util/CommandlineParser.cs.meta rename to workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/BuildContextTestBase.cs.meta index 20c07d8bc4..255a1b3c21 100644 --- a/workers/unity/Packages/io.improbable.gdk.buildsystem/Util/CommandlineParser.cs.meta +++ b/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/BuildContextTestBase.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: aa29fe14f7ce4d2687ed1286578cda8e +guid: 35cdac2955797ba409e22d0643e3a0fa MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/CloudBuildContextTests.cs b/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/CloudBuildContextTests.cs new file mode 100644 index 0000000000..4d71a8ca9d --- /dev/null +++ b/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/CloudBuildContextTests.cs @@ -0,0 +1,113 @@ +using System.Collections.Generic; +using Improbable.Gdk.BuildSystem.Configuration; +using NUnit.Framework; +using UnityEditor; + +namespace Improbable.Gdk.BuildSystem.Tests +{ + [TestFixture] + public class CloudBuildContextTests : BuildContextTestBase + { + [TestCase(ClientType, 2, WindowsTarget, MacTarget)] + [TestCase(ClientType, 1, WindowsTarget, LinuxTarget)] + [TestCase(ServerType, 1, LinuxTarget)] + [TestCase(MobileClientType, 2, AndroidTarget, IOSTarget)] + [TestCase(MobileClientType, 1, IOSTarget)] + public void GetBuildContexts_for_valid_worker_type_with_valid_filter_returns_expected_number_of_cloud_contexts(string workerType, int expectedContexts, params BuildTarget[] buildTargetFilter) + { + var buildContextFilter = BuildContextSettings.Cloud(workerType); + buildContextFilter.BuildTargetFilter = buildTargetFilter; + + List buildContexts = null; + Assert.DoesNotThrow(() => + { + buildContexts = BuildContext.GetBuildContexts(ValidBuildConfig, buildContextFilter); + }); + + Assert.AreEqual(expectedContexts, buildContexts.Count); + } + + [TestCase(ClientType, LinuxTarget)] + [TestCase(ServerType, WindowsTarget)] + [TestCase(MobileClientType, LinuxTarget)] + public void GetBuildContexts_for_valid_worker_type_with_invalid_filter_returns_zero_cloud_contexts(string workerType, params BuildTarget[] buildTargetFilter) + { + var buildContextFilter = BuildContextSettings.Cloud(workerType); + buildContextFilter.BuildTargetFilter = buildTargetFilter; + + List buildContexts = null; + Assert.DoesNotThrow(() => + { + buildContexts = BuildContext.GetBuildContexts(ValidBuildConfig, buildContextFilter); + }); + + Assert.AreEqual(0, buildContexts.Count); + } + + [TestCase(ClientType, WindowsTarget, MacTarget)] + [TestCase(ServerType, LinuxTarget)] + [TestCase(MobileClientType, AndroidTarget, IOSTarget)] + public void GetBuildContexts_for_valid_worker_type_without_filter_returns_all_expected_cloud_contexts(string workerType, params BuildTarget[] expectedTargets) + { + var buildContextFilter = BuildContextSettings.Cloud(workerType); + + List buildContexts = null; + Assert.DoesNotThrow(() => + { + buildContexts = BuildContext.GetBuildContexts(ValidBuildConfig, buildContextFilter); + }); + + Assert.AreEqual(expectedTargets.Length, buildContexts.Count); + + for (var i = 0; i < buildContexts.Count; i++) + { + Assert.AreEqual(workerType, buildContexts[i].WorkerType); + Assert.AreEqual(expectedTargets[i], buildContexts[i].BuildTargetConfig.Target); + } + } + + [TestCase(InvalidWorkerType, WindowsTarget, MacTarget, LinuxTarget)] + public void GetBuildContexts_for_unknown_worker_type_with_valid_filter_returns_zero_cloud_contexts(string workerType, params BuildTarget[] buildTargetFilter) + { + var buildContextFilter = BuildContextSettings.Cloud(workerType); + buildContextFilter.BuildTargetFilter = buildTargetFilter; + + List buildContexts = null; + Assert.DoesNotThrow(() => + { + buildContexts = BuildContext.GetBuildContexts(ValidBuildConfig, buildContextFilter); + }); + + Assert.AreEqual(0, buildContexts.Count); + } + + [TestCase(InvalidWorkerType, LinuxTarget)] + public void GetBuildContexts_for_unknown_worker_type_with_invalid_filter_returns_zero_cloud_contexts(string workerType, params BuildTarget[] buildTargetFilter) + { + var buildContextFilter = BuildContextSettings.Cloud(workerType); + buildContextFilter.BuildTargetFilter = buildTargetFilter; + + List buildContexts = null; + Assert.DoesNotThrow(() => + { + buildContexts = BuildContext.GetBuildContexts(ValidBuildConfig, buildContextFilter); + }); + + Assert.AreEqual(0, buildContexts.Count); + } + + [TestCase(InvalidWorkerType)] + public void GetBuildContexts_for_unknown_worker_type_without_filter_returns_zero_cloud_contexts(string workerType) + { + var buildContextFilter = BuildContextSettings.Cloud(workerType); + + List buildContexts = null; + Assert.DoesNotThrow(() => + { + buildContexts = BuildContext.GetBuildContexts(EmptyBuildConfig, buildContextFilter); + }); + + Assert.AreEqual(0, buildContexts.Count); + } + } +} diff --git a/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/CloudBuildContextTests.cs.meta b/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/CloudBuildContextTests.cs.meta new file mode 100644 index 0000000000..03b398372d --- /dev/null +++ b/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/CloudBuildContextTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b3ba00c2ea844357bf0960185b1f8832 +timeCreated: 1598279537 \ No newline at end of file diff --git a/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/Improbable.Gdk.BuildSystem.Tests.asmdef b/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/Improbable.Gdk.BuildSystem.Tests.asmdef new file mode 100644 index 0000000000..3ef14550ab --- /dev/null +++ b/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/Improbable.Gdk.BuildSystem.Tests.asmdef @@ -0,0 +1,31 @@ +{ + "name": "Improbable.Gdk.BuildSystem.Tests", + "references": [ + "Improbable.Gdk.Core", + "Improbable.Gdk.BuildSystem", + "Unity.Entities", + "Unity.Entities.Hybrid", + "Improbable.Gdk.TestUtils", + "Improbable.Gdk.TestUtils.Editor", + "Improbable.Gdk.Tools", + "UnityEngine.TestRunner", + "UnityEditor.TestRunner", + "Improbable.Gdk.Core.Editor" + ], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": true, + "precompiledReferences": [ + "nunit.framework.dll", + "Improbable.Worker.CInterop.dll" + ], + "autoReferenced": false, + "defineConstraints": [ + "UNITY_INCLUDE_TESTS" + ], + "versionDefines": [], + "noEngineReferences": false +} diff --git a/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/Improbable.Gdk.BuildSystem.Tests.asmdef.meta b/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/Improbable.Gdk.BuildSystem.Tests.asmdef.meta new file mode 100644 index 0000000000..bd578149ca --- /dev/null +++ b/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/Improbable.Gdk.BuildSystem.Tests.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 2e3c66d8172519a47b091383549dd31c +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/LocalBuildContextTests.cs b/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/LocalBuildContextTests.cs new file mode 100644 index 0000000000..08db60a852 --- /dev/null +++ b/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/LocalBuildContextTests.cs @@ -0,0 +1,113 @@ +using System.Collections.Generic; +using Improbable.Gdk.BuildSystem.Configuration; +using NUnit.Framework; +using UnityEditor; +using UnityEngine; + +namespace Improbable.Gdk.BuildSystem.Tests +{ + [TestFixture] + public class LocalBuildContextTests : BuildContextTestBase + { + [TestCase(ClientType, 1, LocalTarget)] + [TestCase(ServerType, 1, LocalTarget)] + [TestCase(MobileClientType, 2, AndroidTarget, IOSTarget)] + [TestCase(MobileClientType, 1, IOSTarget)] + public void GetBuildContexts_for_valid_worker_type_with_valid_filter_returns_expected_number_of_local_contexts(string workerType, int expectedContexts, params BuildTarget[] buildTargetFilter) + { + var buildContextFilter = BuildContextSettings.Local(workerType); + buildContextFilter.BuildTargetFilter = buildTargetFilter; + + List buildContexts = null; + Assert.DoesNotThrow(() => + { + buildContexts = BuildContext.GetBuildContexts(ValidBuildConfig, buildContextFilter); + }); + + Assert.AreEqual(expectedContexts, buildContexts.Count); + } + + [TestCase(ClientType, LinuxTarget)] + [TestCase(ServerType, LinuxTarget)] + [TestCase(MobileClientType, LinuxTarget)] + public void GetBuildContexts_for_valid_worker_type_with_invalid_filter_returns_zero_local_contexts(string workerType, params BuildTarget[] buildTargetFilter) + { + var buildContextFilter = BuildContextSettings.Local(workerType); + buildContextFilter.BuildTargetFilter = buildTargetFilter; + + List buildContexts = null; + Assert.DoesNotThrow(() => + { + buildContexts = BuildContext.GetBuildContexts(ValidBuildConfig, buildContextFilter); + }); + + Assert.AreEqual(0, buildContexts.Count); + } + + [TestCase(ClientType, LocalTarget)] + [TestCase(ServerType, LocalTarget)] + [TestCase(MobileClientType, AndroidTarget, IOSTarget)] + public void GetBuildContexts_for_valid_worker_type_without_filter_returns_all_expected_local_contexts(string workerType, params BuildTarget[] expectedTargets) + { + var buildContextFilter = BuildContextSettings.Local(workerType); + + List buildContexts = null; + Assert.DoesNotThrow(() => + { + buildContexts = BuildContext.GetBuildContexts(ValidBuildConfig, buildContextFilter); + }); + + Assert.AreEqual(expectedTargets.Length, buildContexts.Count); + + for (var i = 0; i < buildContexts.Count; i++) + { + Assert.AreEqual(workerType, buildContexts[i].WorkerType); + Assert.AreEqual(expectedTargets[i], buildContexts[i].BuildTargetConfig.Target); + } + } + + [TestCase(InvalidWorkerType, LocalTarget)] + public void GetBuildContexts_for_unknown_worker_type_with_valid_filter_returns_zero_local_contexts(string workerType, params BuildTarget[] buildTargetFilter) + { + var buildContextFilter = BuildContextSettings.Local(workerType); + buildContextFilter.BuildTargetFilter = buildTargetFilter; + + List buildContexts = null; + Assert.DoesNotThrow(() => + { + buildContexts = BuildContext.GetBuildContexts(ValidBuildConfig, buildContextFilter); + }); + + Assert.AreEqual(0, buildContexts.Count); + } + + [TestCase(InvalidWorkerType, LinuxTarget)] + public void GetBuildContexts_for_unknown_worker_type_with_invalid_filter_returns_zero_local_contexts(string workerType, params BuildTarget[] buildTargetFilter) + { + var buildContextFilter = BuildContextSettings.Local(workerType); + buildContextFilter.BuildTargetFilter = buildTargetFilter; + + List buildContexts = null; + Assert.DoesNotThrow(() => + { + buildContexts = BuildContext.GetBuildContexts(ValidBuildConfig, buildContextFilter); + }); + + Assert.AreEqual(0, buildContexts.Count); + } + + [TestCase(InvalidWorkerType)] + public void GetBuildContexts_for_unknown_worker_type_without_filter_returns_zero_local_contexts(string workerType) + { + var buildContextFilter = BuildContextSettings.Local(workerType); + + List buildContexts = null; + Assert.DoesNotThrow(() => + { + buildContexts = BuildContext.GetBuildContexts(EmptyBuildConfig, buildContextFilter); + }); + + Assert.AreEqual(0, buildContexts.Count); + } + } +} diff --git a/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/LocalBuildContextTests.cs.meta b/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/LocalBuildContextTests.cs.meta new file mode 100644 index 0000000000..5b743632ca --- /dev/null +++ b/workers/unity/Packages/io.improbable.gdk.buildsystem/Tests/LocalBuildContextTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b83fd3aa1069441a8efb07e9f1b8ae40 +timeCreated: 1597938241 \ No newline at end of file diff --git a/workers/unity/Packages/io.improbable.gdk.buildsystem/WorkerBuilder.cs b/workers/unity/Packages/io.improbable.gdk.buildsystem/WorkerBuilder.cs index 79e25e0481..bd6f4f9a9a 100644 --- a/workers/unity/Packages/io.improbable.gdk.buildsystem/WorkerBuilder.cs +++ b/workers/unity/Packages/io.improbable.gdk.buildsystem/WorkerBuilder.cs @@ -30,20 +30,15 @@ public static void Build() var args = CommandLineArgs.FromCommandLine(); // Parse command line arguments - var buildTargetFilter = CommandlineParser.GetBuildTargetFilter(args); - var wantedWorkerTypes = CommandlineParser.GetWorkerTypesToBuild(args); - var scriptImplementation = CommandlineParser.GetScriptingImplementation(args); - var buildEnvironment = CommandlineParser.GetBuildEnvironment(args); - var targetIOSSdkVersion = CommandlineParser.GetTargetIOSSdk(args); + var buildContextFilter = BuildContextSettings.FromCommandLine(args); // Create BuildContext for each worker - var buildContexts = BuildContext.GetBuildContexts(wantedWorkerTypes, buildEnvironment, scriptImplementation, - buildTargetFilter, targetIOSSdkVersion); + var buildConfig = BuildConfig.GetInstance(); + var buildContexts = BuildContext.GetBuildContexts(buildConfig, buildContextFilter); if (buildContexts.Count == 0) { - throw new BuildFailedException( - $"Attempted a build with no valid targets!"); + throw new BuildFailedException("Attempted a build with no valid targets!"); } BuildWorkers(buildContexts); @@ -60,14 +55,15 @@ public static void Build() } } - internal static void MenuBuild(BuildEnvironment environment, params string[] workerTypes) + internal static void MenuBuild(BuildContextSettings buildContextSettings) { // Delaying build by a frame to ensure the editor has re-rendered the UI to avoid odd glitches. EditorApplication.delayCall += () => { try { - var buildContexts = BuildContext.GetBuildContexts(workerTypes, environment); + var buildConfig = BuildConfig.GetInstance(); + var buildContexts = BuildContext.GetBuildContexts(buildConfig, buildContextSettings); BuildWorkers(buildContexts); } catch (Exception e)