Game/Library/PackageCache/com.unity.package-manager-ui@2.0.13/Editor/Sources/Services/Packages/Package.cs
2021-01-16 18:29:12 +01:00

225 lines
8.3 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
namespace UnityEditor.PackageManager.UI
{
// History of a single package
internal class Package : IEquatable<Package>
{
static public bool ShouldProposeLatestVersions
{
get
{
// Until we figure out a way to test this properly, alway show standard behavior
// return InternalEditorUtility.IsUnityBeta() && !Unsupported.IsDeveloperMode();
return false;
}
}
// There can only be one package add/remove operation.
private static IBaseOperation addRemoveOperationInstance;
public static bool AddRemoveOperationInProgress
{
get { return addRemoveOperationInstance != null && !addRemoveOperationInstance.IsCompleted; }
}
internal const string packageManagerUIName = "com.unity.package-manager-ui";
private readonly string packageName;
private IEnumerable<PackageInfo> source;
internal Package(string packageName, IEnumerable<PackageInfo> infos)
{
if (string.IsNullOrEmpty(packageName))
throw new ArgumentException("Cannot be empty or null", "packageName");
if (!infos.Any())
throw new ArgumentException("Cannot be empty", "infos");
this.packageName = packageName;
UpdateSource(infos);
}
internal void UpdateSource(IEnumerable<PackageInfo> source)
{
this.source = source;
#if UNITY_2018_3_OR_NEWER
if (IsPackageManagerUI)
this.source = this.source.Where(p => p != null && p.Version.Major >= 2);
#endif
}
public PackageInfo Current { get { return Versions.FirstOrDefault(package => package.IsCurrent); } }
// This is the latest verified or official release (eg: 1.3.2). Not necessarily the latest verified release (eg: 1.2.4) or that latest candidate (eg: 1.4.0-beta)
public PackageInfo LatestUpdate
{
get
{
// We want to show the absolute latest when in beta mode
if (ShouldProposeLatestVersions)
return Latest;
// Override with current when it's version locked
var current = Current;
if (current != null && current.IsVersionLocked)
return current;
// Get all the candidates versions (verified, release, preview) that are newer than current
var verified = Verified;
var latestRelease = LatestRelease;
var latestPreview = Versions.LastOrDefault(package => package.IsPreview);
var candidates = new List<PackageInfo>
{
verified,
latestRelease,
latestPreview,
}.Where(package => package != null && (current == null || current == package || current.Version < package.Version)).ToList();
if (candidates.Contains(verified))
return verified;
if ((current == null || !current.IsVerified) && candidates.Contains(latestRelease))
return latestRelease;
if ((current == null || current.IsPreview) && candidates.Contains(latestPreview))
return latestPreview;
// Show current if it exists, otherwise latest user visible, and then otherwise show the absolute latest
return current ?? Latest;
}
}
public PackageInfo LatestPatch
{
get
{
if (Current == null)
return null;
// Get all version that have the same Major/Minor
var versions = Versions.Where(package => package.Version.Major == Current.Version.Major && package.Version.Minor == Current.Version.Minor);
return versions.LastOrDefault();
}
}
// This is the very latest version, including pre-releases (eg: 1.4.0-beta).
internal PackageInfo Latest { get { return Versions.FirstOrDefault(package => package.IsLatest) ?? Versions.LastOrDefault(); } }
// Returns the current version if it exist, otherwise returns the latest user visible version.
internal PackageInfo VersionToDisplay { get { return Current ?? LatestUpdate; } }
// Every version available for this package
internal IEnumerable<PackageInfo> Versions { get { return source.OrderBy(package => package.Version); } }
// Every version that's not a pre-release (eg: not beta/alpha/preview).
internal IEnumerable<PackageInfo> ReleaseVersions
{
get { return Versions.Where(package => !package.IsPreRelease); }
}
internal PackageInfo LatestRelease { get {return ReleaseVersions.LastOrDefault();}}
internal PackageInfo Verified { get {return Versions.FirstOrDefault(package => package.IsVerified);}}
internal bool IsAfterCurrentVersion(PackageInfo packageInfo) { return Current == null || (packageInfo != null && packageInfo.Version > Current.Version); }
internal bool IsBuiltIn {get { return Versions.Any() && Versions.First().IsBuiltIn; }}
internal bool IsUnityPackage { get { return VersionToDisplay.IsUnityPackage; } }
public string Name { get { return packageName; } }
public bool IsPackageManagerUI
{
get { return Name == packageManagerUIName; }
}
public bool Equals(Package other)
{
if (other == null)
return false;
return packageName == other.packageName;
}
public override int GetHashCode()
{
return packageName.GetHashCode();
}
[SerializeField]
internal readonly OperationSignal<IAddOperation> AddSignal = new OperationSignal<IAddOperation>();
private Action OnAddOperationFinalizedEvent;
internal void Add(PackageInfo packageInfo)
{
if (packageInfo == Current || AddRemoveOperationInProgress)
return;
var operation = OperationFactory.Instance.CreateAddOperation();
addRemoveOperationInstance = operation;
OnAddOperationFinalizedEvent = () =>
{
AddSignal.Operation = null;
operation.OnOperationFinalized -= OnAddOperationFinalizedEvent;
PackageCollection.Instance.FetchListOfflineCache(true);
};
operation.OnOperationFinalized += OnAddOperationFinalizedEvent;
AddSignal.SetOperation(operation);
operation.AddPackageAsync(packageInfo);
}
internal void Update()
{
Add(Latest);
}
internal static void AddFromLocalDisk(string path)
{
if (AddRemoveOperationInProgress)
return;
var packageJson = PackageJsonHelper.Load(path);
if (null == packageJson)
{
Debug.LogError(string.Format("Invalid package path: cannot find \"{0}\".", path));
return;
}
var operation = OperationFactory.Instance.CreateAddOperation();
addRemoveOperationInstance = operation;
operation.AddPackageAsync(packageJson.PackageInfo);
}
[SerializeField]
internal readonly OperationSignal<IRemoveOperation> RemoveSignal = new OperationSignal<IRemoveOperation>();
private Action OnRemoveOperationFinalizedEvent;
public void Remove()
{
if (Current == null || AddRemoveOperationInProgress)
return;
var operation = OperationFactory.Instance.CreateRemoveOperation();
addRemoveOperationInstance = operation;
OnRemoveOperationFinalizedEvent = () =>
{
RemoveSignal.Operation = null;
operation.OnOperationFinalized -= OnRemoveOperationFinalizedEvent;
PackageCollection.Instance.FetchListOfflineCache(true);
};
operation.OnOperationFinalized += OnRemoveOperationFinalizedEvent;
RemoveSignal.SetOperation(operation);
operation.RemovePackageAsync(Current);
}
}
}