This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
#if UNITY_EDITOR
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ShrinkSDK.Installer
|
||||
{
|
||||
internal static class ShrinkSdkManifestStore
|
||||
{
|
||||
internal static string ManifestPath => Path.Combine(
|
||||
Path.GetFullPath(Path.Combine(Application.dataPath, "..")),
|
||||
"Packages",
|
||||
"manifest.json");
|
||||
|
||||
internal static bool HasShrinkSdkRegistry()
|
||||
{
|
||||
var manifest = ReadManifest();
|
||||
return GetShrinkSdkRegistry(manifest) != null;
|
||||
}
|
||||
|
||||
internal static void EnsureShrinkSdkRegistry()
|
||||
{
|
||||
var manifest = ReadManifest();
|
||||
var registries = manifest["scopedRegistries"] as JArray;
|
||||
if (registries == null)
|
||||
{
|
||||
registries = new JArray();
|
||||
manifest["scopedRegistries"] = registries;
|
||||
}
|
||||
|
||||
var conflictingRegistry = registries
|
||||
.OfType<JObject>()
|
||||
.FirstOrDefault(registry =>
|
||||
!UrlEquals((string?)registry["url"], ShrinkSdkPackageCatalog.RegistryUrl) &&
|
||||
(registry["scopes"] as JArray)?.Values<string>().Any(scope =>
|
||||
string.Equals(scope, ShrinkSdkPackageCatalog.RegistryScope, StringComparison.Ordinal)) == true);
|
||||
|
||||
if (conflictingRegistry != null)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Packages/manifest.json already maps com.cneicy to another scoped registry. Resolve that registry explicitly before installing ShrinkSDK.");
|
||||
}
|
||||
|
||||
var registry = GetShrinkSdkRegistry(manifest);
|
||||
if (registry == null)
|
||||
{
|
||||
registry = new JObject
|
||||
{
|
||||
["name"] = ShrinkSdkPackageCatalog.RegistryName,
|
||||
["url"] = ShrinkSdkPackageCatalog.RegistryUrl,
|
||||
["scopes"] = new JArray(ShrinkSdkPackageCatalog.RegistryScope)
|
||||
};
|
||||
registries.Add(registry);
|
||||
}
|
||||
else
|
||||
{
|
||||
registry["name"] = ShrinkSdkPackageCatalog.RegistryName;
|
||||
registry["url"] = ShrinkSdkPackageCatalog.RegistryUrl;
|
||||
var scopes = registry["scopes"] as JArray ?? new JArray();
|
||||
if (!scopes.Values<string>().Any(scope =>
|
||||
string.Equals(scope, ShrinkSdkPackageCatalog.RegistryScope, StringComparison.Ordinal)))
|
||||
{
|
||||
scopes.Add(ShrinkSdkPackageCatalog.RegistryScope);
|
||||
}
|
||||
|
||||
registry["scopes"] = scopes;
|
||||
}
|
||||
|
||||
AtomicWrite(manifest.ToString(Formatting.Indented) + Environment.NewLine);
|
||||
}
|
||||
|
||||
private static JObject ReadManifest()
|
||||
{
|
||||
if (!File.Exists(ManifestPath))
|
||||
{
|
||||
throw new FileNotFoundException("Unity package manifest was not found.", ManifestPath);
|
||||
}
|
||||
|
||||
return JObject.Parse(File.ReadAllText(ManifestPath, Encoding.UTF8));
|
||||
}
|
||||
|
||||
private static JObject? GetShrinkSdkRegistry(JObject manifest)
|
||||
{
|
||||
return (manifest["scopedRegistries"] as JArray)?
|
||||
.OfType<JObject>()
|
||||
.FirstOrDefault(registry => UrlEquals((string?)registry["url"], ShrinkSdkPackageCatalog.RegistryUrl));
|
||||
}
|
||||
|
||||
private static bool UrlEquals(string? left, string right)
|
||||
{
|
||||
return string.Equals(NormalizeUrl(left), NormalizeUrl(right), StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private static string NormalizeUrl(string? url)
|
||||
{
|
||||
return (url ?? string.Empty).Trim().TrimEnd('/') + "/";
|
||||
}
|
||||
|
||||
private static void AtomicWrite(string content)
|
||||
{
|
||||
var directory = Path.GetDirectoryName(ManifestPath);
|
||||
if (string.IsNullOrWhiteSpace(directory))
|
||||
{
|
||||
throw new InvalidOperationException("Unity package manifest directory could not be resolved.");
|
||||
}
|
||||
|
||||
var temporaryPath = Path.Combine(directory, ".manifest.shrinksdk.tmp");
|
||||
File.WriteAllText(temporaryPath, content, new UTF8Encoding(false));
|
||||
try
|
||||
{
|
||||
File.Replace(temporaryPath, ManifestPath, null);
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (File.Exists(temporaryPath))
|
||||
{
|
||||
File.Delete(temporaryPath);
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user