Files
2025-11-30 08:35:03 +02:00

133 lines
3.5 KiB
C#

using System;
using System.IO;
using Needle.Engine.Utils;
using UnityEngine;
using UnityEngine.Serialization;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace Needle.Engine
{
[Serializable]
public struct Dependency
{
public string Name;
public string Version;
[FormerlySerializedAs("VersionOrPath")]
public string Path;
// the guid is used to find the new path of a dependency
public string Guid;
/// <summary>
/// Add the dependency to the package.json file
/// </summary>
public bool Install(string packageJsonPath)
{
if (string.IsNullOrEmpty(Name)) return false;
if (IsMissingNpmDef())
{
Debug.LogWarning("Can not install dependency \"" + Name + "\" because npmdef was not found in project at \"" + Path + "\"");
return false;
}
if (!System.IO.Path.IsPathRooted(packageJsonPath))
{
packageJsonPath = System.IO.Path.GetFullPath(packageJsonPath);
}
if (TryGetEmbeddedPath(out var path) && File.Exists($"{path}/package.json"))
{
if (PackageUtils.TryReadDependencies(packageJsonPath, out var deps))
{
path = System.IO.Path.GetFullPath(path);
var isLocalPath = Directory.Exists(path);
path = path.RelativeTo(packageJsonPath);
if (isLocalPath && !path.StartsWith("file:"))
path = "file:" + path;
deps[Name] = path;
PackageUtils.TryWriteDependencies(packageJsonPath, deps);
return true;
}
}
else if(!string.IsNullOrWhiteSpace(Version) && !string.IsNullOrEmpty(Name))
{
if (PackageUtils.TryReadDependencies(packageJsonPath, out var deps))
{
// If the dependency is already installed with either a filepath OR a version, we don't need to install it again
// For example: if we install a remote npm package (and the npmdef is installed by that package) we don't need to update the version
// Because then the user can change the version in the web project package.json (e.g. 1.0.0 to 2.0.0)
// And the package will be installed from npm and update the npmdef with the right version
if (!deps.ContainsKey(Name))
{
deps[Name] = Version;
PackageUtils.TryWriteDependencies(packageJsonPath, deps);
}
return true;
}
}
return false;
}
public bool IsMissingNpmDef()
{
ResolvePath();
var path = Path;
if (string.IsNullOrEmpty(path)) return false;
if (path.EndsWith(".npmdef"))
{
if (!File.Exists(path))
{
return true;
}
}
return false;
}
public bool TryGetEmbeddedPath(out string path, bool ignoreMissing = false)
{
path = null;
ResolvePath();
// we want to install the path to the hidden package dir
var versionOrPath = Path;
if (string.IsNullOrEmpty(versionOrPath)) return false;
if (versionOrPath.EndsWith(".npmdef"))
{
if (!ignoreMissing && !File.Exists(versionOrPath))
{
return false;
}
versionOrPath = versionOrPath.Substring(0, versionOrPath.Length - ".npmdef".Length) + "~";
}
path = versionOrPath;
return !string.IsNullOrWhiteSpace(path) && Directory.Exists(path);
}
public bool TryGetNpmPackageDirectoryPath(out string npmPackageDirectoryPath)
{
if (TryGetEmbeddedPath(out var path))
{
npmPackageDirectoryPath = System.IO.Path.GetFullPath(path);
return Directory.Exists(npmPackageDirectoryPath);
}
npmPackageDirectoryPath = null;
return false;
}
private void ResolvePath()
{
#if UNITY_EDITOR
if (!string.IsNullOrEmpty(Guid))
{
var fromGuid = AssetDatabase.GUIDToAssetPath(Guid);
if (!string.IsNullOrEmpty(fromGuid))
Path = fromGuid;
}
#endif
}
}
}