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