using System;
using System.IO;
using System.Linq;
using System.Text;
using UnityEditor.VersionControl;
using UnityEngine;
namespace Unity.VisualScripting
{
public static class VersionControlUtility
{
// Perforce and other VCS have a lock mechanism that usually
// only makes the file writable once checked out. We need to
// check them out before writing to them for auto-generated files.
public static void Unlock(string path)
{
Ensure.That(nameof(path)).IsNotNull(path);
UnityAPI.Await
(
() =>
{
// The API changed in 2019, adding a third optional ChangeSet parameter
// which defaults to null but breaks the compiled signature below
// Furthermore, we can't even so much as have the call in the body of this method,
// or it will fail even if the if branch evaluates to false. So we
if (File.Exists(path) && Provider.enabled && Provider.isActive && Provider.hasCheckoutSupport)
{
try
{
var provider = typeof(Provider);
if (EditorApplicationUtility.unityVersion >= "2019.1.0")
{
var method = provider.GetMethods()
.FirstOrDefault
(
m => m.Name == "Checkout" &&
m.GetParameters().Length == 3 &&
m.GetParameters()[0].ParameterType == typeof(string) &&
m.GetParameters()[1].ParameterType == typeof(CheckoutMode)
);
if (method == null)
{
throw new MissingMemberException(provider.FullName, "Checkout");
}
method.InvokeOptimized(null, PathUtility.FromProject(path), CheckoutMode.Both, null);
}
else
{
var method = provider.GetMethods()
.FirstOrDefault
(
m => m.Name == "Checkout" &&
m.GetParameters().Length == 2 &&
m.GetParameters()[0].ParameterType == typeof(string) &&
m.GetParameters()[1].ParameterType == typeof(CheckoutMode)
);
if (method == null)
{
throw new MissingMemberException(provider.FullName, "Checkout");
}
method.InvokeOptimized(null, PathUtility.FromProject(path), CheckoutMode.Both);
}
}
catch (Exception ex)
{
Debug.LogWarning($"Failed to automatically checkout file from version control:\n{path}\n{ex}");
}
}
if (File.Exists(path))
{
var info = new FileInfo(path);
if (info.IsReadOnly)
{
var sb = new StringBuilder();
sb.AppendLine($"File '{info.Name}' is read-only despite attempted checkout. Manually forcing to writable.");
sb.AppendLine($"This may cause version control issues. Please report the following debug information:");
sb.AppendLine($"File Exists: {File.Exists(path)}");
sb.AppendLine($"Provider.enabled: {Provider.enabled}");
sb.AppendLine($"Provider.isActive: {Provider.isActive}");
sb.AppendLine($"Provider.hasCheckoutSupport: {Provider.hasCheckoutSupport}");
Debug.LogWarning(sb.ToString());
info.IsReadOnly = false;
}
}
}
);
}
}
}