123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- 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);
- }
- }
- }
|