using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json.Linq;
using UnityEngine;
namespace Unity.Pipeline.Editor.Commands.PackageManager
{
///
/// Reads the project's UPM manifest (Packages/manifest.json) dependencies as a flat
/// name → version map, satisfying CLI-203's "return manifest state". The JSON parsing is split into
/// a pure seam so it is unit-testable without a live project;
/// resolves the project path and is main-thread only (it reads
/// ).
///
public static class PackageManifest
{
/// Project-relative path to the UPM manifest.
public const string RelativePath = "Packages/manifest.json";
/// Absolute path to the manifest for the current project. Main thread only.
public static string ManifestPath
{
get
{
var projectRoot = Path.GetDirectoryName(Application.dataPath);
return Path.Combine(projectRoot, "Packages", "manifest.json");
}
}
///
/// Parse the dependencies object of a manifest.json document into a name → version map.
/// Returns an empty map for null/empty input or a manifest without dependencies.
///
public static Dictionary ReadDependencies(string manifestJson)
{
var result = new Dictionary();
if (string.IsNullOrWhiteSpace(manifestJson))
return result;
var root = JObject.Parse(manifestJson);
if (root["dependencies"] is JObject deps)
{
foreach (var kv in deps)
result[kv.Key] = kv.Value?.ToString();
}
return result;
}
///
/// Read the current project's manifest dependencies. Returns false with
/// set when the manifest is missing or unreadable.
///
public static bool TryRead(out Dictionary dependencies, out string error)
{
dependencies = null;
error = null;
try
{
var path = ManifestPath;
if (!File.Exists(path))
{
error = $"manifest not found at {path}";
return false;
}
dependencies = ReadDependencies(File.ReadAllText(path));
return true;
}
catch (Exception ex)
{
error = ex.Message;
return false;
}
}
}
}