Skip to content

Commit

Permalink
feat: use new settings file
Browse files Browse the repository at this point in the history
Put native configuration in a new settings file
Catch UnauthorizedAccessException on windows when deleting files as on Windows you cannot delete a file thats in use, and Unity cannot unload native files
  • Loading branch information
robin-moss committed Dec 6, 2021
1 parent f05c9be commit 0408846
Show file tree
Hide file tree
Showing 8 changed files with 137 additions and 99 deletions.
20 changes: 0 additions & 20 deletions Assets/NuGet.config
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,4 @@
<add key="repositoryPath" value="./Packages" />
<add key="DefaultPushSource" value="http://www.nuget.org/api/v2/" />
</config>
<nativeRuntimesMapping>
<platform name="win7-x64">
<buildTarget name="StandaloneWindows64" />
</platform>
<platform name="win7-x86">
<buildTarget name="StandaloneWindows" />
</platform>
<platform name="win-x64">
<buildTarget name="StandaloneWindows64" />
</platform>
<platform name="win-x86">
<buildTarget name="StandaloneWindows" />
</platform>
<platform name="linux-x64">
<buildTarget name="StandaloneLinux64" />
</platform>
<platform name="osx-x64">
<buildTarget name="StandaloneOSX" />
</platform>
</nativeRuntimesMapping>
</configuration>
9 changes: 0 additions & 9 deletions Assets/NuGet.meta

This file was deleted.

64 changes: 2 additions & 62 deletions Assets/NuGet/Editor/NugetConfigFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,6 @@ public class NugetConfigFile
/// </summary>
public bool ReadOnlyPackageFiles { get; set; }

/// <summary>
/// Gets or sets the mapping from NuGet runtimes folder naming convention to Unity BuildTargets
/// </summary>
public Dictionary<string, List<BuildTarget>> NativeRuntimesMappings { get; set; }

/// <summary>
/// The incomplete path that is saved. The path is expanded and made public via the property above.
/// </summary>
Expand Down Expand Up @@ -157,28 +152,12 @@ public void Save(string filepath)
config.Add(addElement);
}

XElement nativeRuntimesMapping = new XElement("nativeRuntimesMapping");
foreach (var mapping in NativeRuntimesMappings)
{
var platform = new XElement("platform");
platform.Add(new XAttribute("name", mapping.Key));

foreach (var target in mapping.Value)
{
var buildTarget = new XElement("buildTarget");
buildTarget.Add(new XAttribute("name", target.ToString()));
platform.Add(buildTarget);
}
nativeRuntimesMapping.Add(platform);
}

XElement configuration = new XElement("configuration");
configuration.Add(packageSources);
configuration.Add(disabledPackageSources);
configuration.Add(packageSourceCredentials);
configuration.Add(activePackageSource);
configuration.Add(config);
configuration.Add(nativeRuntimesMapping);

configFile.Add(configuration);

Expand Down Expand Up @@ -211,17 +190,7 @@ public static NugetConfigFile Load(string filePath)
configFile.PackageSources = new List<NugetPackageSource>();
configFile.InstallFromCache = true;
configFile.ReadOnlyPackageFiles = false;
configFile.NativeRuntimesMappings =
new Dictionary<string, List<BuildTarget>>()
{
{"win7-x64", new List<BuildTarget> {BuildTarget.StandaloneWindows64}},
{"win7-x86", new List<BuildTarget> {BuildTarget.StandaloneWindows}},
{"win-x64", new List<BuildTarget> {BuildTarget.StandaloneWindows64}},
{"win-x86", new List<BuildTarget> {BuildTarget.StandaloneWindows}},
{"linux-x64", new List<BuildTarget> {BuildTarget.StandaloneLinux64}},
{"osx-x64", new List<BuildTarget> {BuildTarget.StandaloneOSX}},
};


XDocument file = XDocument.Load(filePath);

// Force disable
Expand Down Expand Up @@ -337,36 +306,7 @@ public static NugetConfigFile Load(string filePath)
}
}

// Read native runtime mappings
XElement nativeRuntimesMapping = file.Root.Element("nativeRuntimesMapping");
if (nativeRuntimesMapping != null)
{
configFile.NativeRuntimesMappings = new Dictionary<string, List<BuildTarget>>();
var platforms = nativeRuntimesMapping.Elements("platform");
foreach (var platform in platforms)
{
var platformName = platform.Attribute("name").Value;
var buildTargets = new List<BuildTarget>();
var targets = platform.Elements("buildTarget");

foreach (var target in targets)
{
var targetName = target.Attribute("name").Value;
BuildTarget parsedTarget;
if (BuildTarget.TryParse(targetName, true, out parsedTarget))
{
buildTargets.Add(parsedTarget);
}
else
{
Debug.LogWarning(string.Format("{0} of {1} not found", targetName, platformName));
}
}
configFile.NativeRuntimesMappings.Add(platformName, buildTargets);
}
}

return configFile;
return configFile;
}

/// <summary>
Expand Down
67 changes: 62 additions & 5 deletions Assets/NuGet/Editor/NugetHelper.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// To support play mode testing we have to use assembly defs, so to keep the methods internal we'll make
// the test assemblies able to see the internal methods
Expand Down Expand Up @@ -37,6 +38,11 @@ public static class NugetHelper
/// The path to the nuget.config file.
/// </summary>
public static readonly string NugetConfigFilePath = Path.Combine(Application.dataPath, "./NuGet.config");

/// <summary>
/// The path to the settings.json file
/// </summary>
public static readonly string SettingsFilePath = Path.Combine(Application.dataPath, "./NuGet/settings.json");

/// <summary>
/// The path to the packages.config file.
Expand All @@ -55,8 +61,15 @@ public static class NugetHelper

/// <summary>
/// The loaded NuGet.config file that holds the settings for NuGet.
/// <seealso cref="SettingsFile"/>
/// </summary>
public static NugetConfigFile NugetConfigFile { get; private set; }

/// <summary>
/// The loaded settings.json file that holds settings for NuGetForUnity.
/// <seealso cref="NugetConfigFile"/>
/// </summary>
public static Settings SettingsFile { get; private set; }

/// <summary>
/// Backing field for the packages.config file.
Expand Down Expand Up @@ -141,6 +154,20 @@ static NugetHelper()
}
}

public static void LoadSettingFile()
{
if (File.Exists(SettingsFilePath))
{
SettingsFile = Settings.Load(SettingsFilePath);
}
else
{
Debug.LogFormat("No settings.json file found. Creating default at {0}", SettingsFilePath);
SettingsFile = Settings.CreateDefault(SettingsFilePath);
AssetDatabase.Refresh();
}
}

/// <summary>
/// Loads the NuGet.config file.
/// </summary>
Expand Down Expand Up @@ -866,7 +893,22 @@ private static void DeleteDirectory(string directoryPath)
directoryInfo.Attributes = FileAttributes.Normal;

// recursively delete the directory
directoryInfo.Delete(true);
try
{
directoryInfo.Delete(true);
}
catch (UnauthorizedAccessException e)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && e.Message.Contains(".dll"))
{
Debug.LogError("Windows was unable to delete all the files, if you are using Native files this is because the file is in use by Unity. Please restart Unity to remove all the files");
}
else
{
throw;
}
}

}

/// <summary>
Expand All @@ -878,7 +920,22 @@ private static void DeleteFile(string filePath)
if (File.Exists(filePath))
{
File.SetAttributes(filePath, FileAttributes.Normal);
File.Delete(filePath);
try
{
File.Delete(filePath);
}
catch (UnauthorizedAccessException e)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && e.Message.Contains(".dll"))
{
Debug.LogError(
"Windows was unable to delete all the files, if you are using Native files this is because the file is in use by Unity. Please restart Unity to remove all the files");
}
else
{
throw;
}
}
}
}

Expand Down Expand Up @@ -915,7 +972,7 @@ internal static void UninstallAll()
public static void Uninstall(NugetPackageIdentifier package, bool refreshAssets = true)
{
LogVerbose("Uninstalling: {0} {1}", package.Id, package.Version);

// update the package.config file
PackagesConfigFile.RemovePackage(package);
PackagesConfigFile.Save(PackagesConfigFilePath);
Expand Down Expand Up @@ -1306,7 +1363,7 @@ private static void HandleRuntimes(NugetPackageIdentifier package, string runtim
foreach (var runtimeDir in runtimes)
{
var platform = new DirectoryInfo(runtimeDir).Name;
if (!NugetConfigFile.NativeRuntimesMappings.ContainsKey(platform))
if (!SettingsFile.NativeRuntimesMappings.ContainsKey(platform))
{
LogVerbose("Runtime {0} of package {1} is not supported", platform, package);
Directory.Delete(runtimeDir, true);
Expand All @@ -1316,7 +1373,7 @@ private static void HandleRuntimes(NugetPackageIdentifier package, string runtim
var platformAndArch = platform.Split('-');
var arch = platformAndArch[1];

var compatibleTargets = NugetConfigFile.NativeRuntimesMappings[platform];
var compatibleTargets = SettingsFile.NativeRuntimesMappings[platform];
var incompatibleTargets = NotObsoleteBuildTargets.Except(compatibleTargets).ToList();

var nativeFiles = Directory.GetFiles(Path.Combine(runtimeDir, "native"));
Expand Down
48 changes: 48 additions & 0 deletions Assets/NuGet/Editor/Settings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using Newtonsoft.Json;
using UnityEditor;

namespace NugetForUnity
{
public class Settings
{
/// <summary>
/// Gets or sets the mapping from NuGet runtimes folder naming convention to Unity BuildTargets
/// </summary>
public Dictionary<string, List<BuildTarget>> NativeRuntimesMappings { get; set; }

public void Save(string filepath)
{
var contents = JsonConvert.SerializeObject(this, new Newtonsoft.Json.Converters.StringEnumConverter());
File.WriteAllText(filepath, contents, new UTF8Encoding());
}

public static Settings Load(string filepath)
{
var contents = File.ReadAllText(filepath, new UTF8Encoding());
return JsonConvert.DeserializeObject<Settings>(contents, new Newtonsoft.Json.Converters.StringEnumConverter());
}

public static Settings CreateDefault(string filepath)
{
var settings = new Settings();

var nativeRuntimes = new Dictionary<string, List<BuildTarget>>
{
{ "win7-x64", new List<BuildTarget>() { BuildTarget.StandaloneWindows64 } },
{ "win7-x86", new List<BuildTarget>() { BuildTarget.StandaloneWindows } },
{ "win-x64", new List<BuildTarget>() { BuildTarget.StandaloneWindows64 } },
{ "win-x86", new List<BuildTarget>() { BuildTarget.StandaloneWindows } },
{ "linux-x64", new List<BuildTarget>() { BuildTarget.StandaloneLinux64 } },
{ "osc-x64", new List<BuildTarget>() { BuildTarget.StandaloneOSX } }
};

settings.NativeRuntimesMappings = nativeRuntimes;
settings.Save(filepath);

return settings;
}
}
}
3 changes: 3 additions & 0 deletions Assets/NuGet/Editor/Settings.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Assets/PlayTests/NuGetPlayTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ public void Setup()

// For windows we end up importing two identical DLLs temporarily, this causes an error log that NUnit detects
// and would fail the test if we don't tell it to ignore the Failing messages
NugetHelper.LoadNugetConfigFile();
NugetHelper.LoadSettingFile();
LogAssert.ignoreFailingMessages = true;
NugetHelper.InstallIdentifier(sqlite);
Assert.IsTrue(NugetHelper.IsInstalled(sqlite), "The package was NOT installed: {0} {1}", sqlite.Id,
Expand All @@ -67,8 +69,6 @@ public void Setup()

public void Cleanup()
{
// Need to reinitialise NugetHelper, but not sure why
NugetHelper.LoadNugetConfigFile();
NugetHelper.Uninstall(sqlite);
Assert.IsFalse(NugetHelper.IsInstalled(sqlite), "The packages are STILL installed: {0} {1}", sqlite.Id,
sqlite.Version);
Expand Down
21 changes: 20 additions & 1 deletion Assets/Tests/Editor/NuGetTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using NUnit.Framework;
using System.Collections.Generic;
using NUnit.Framework;
using NugetForUnity;
using System.IO;
using UnityEditor;
Expand All @@ -15,6 +16,7 @@ public void SimpleRestoreTest()
public void LoadConfigFileTest()
{
NugetHelper.LoadNugetConfigFile();
NugetHelper.LoadSettingFile();
}

[Test]
Expand Down Expand Up @@ -190,4 +192,21 @@ public void VersionOutOfRangeTest(string versionRange, string version)

Assert.IsFalse(id.InRange(version), "{0} WAS in range of {1}!", version, versionRange);
}

[Test]
[TestCase("win7-x64", BuildTarget.StandaloneWindows64)]
[TestCase("win7-x86", BuildTarget.StandaloneWindows)]
[TestCase("win-x64", BuildTarget.StandaloneWindows64)]
[TestCase("win-x86", BuildTarget.StandaloneWindows)]
[TestCase("linux-x64", BuildTarget.StandaloneLinux64)]
[TestCase("osc-x64", BuildTarget.StandaloneOSX)]
public void NativeSettingsTest(string key, BuildTarget buildTarget)
{
NugetHelper.LoadSettingFile();
var nativeRuntimes = NugetHelper.SettingsFile.NativeRuntimesMappings;

Assert.IsTrue(nativeRuntimes.ContainsKey(key), $"Native mappings is missing {key}");
Assert.IsTrue(nativeRuntimes[key].Contains(buildTarget),
$"Native mapping for {key} is missing build target {buildTarget}");
}
}

0 comments on commit 0408846

Please sign in to comment.