| File: SlnfFileHelper.cs | Web Access |
| Project: src\sdk\src\Cli\dotnet\dotnet.csproj (dotnet) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #nullable disable using System; using System.IO; using System.Text.Json; using System.Text.Json.Serialization; using Microsoft.DotNet.Cli.Utils; namespace Microsoft.DotNet.Cli; [JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.Never)] [JsonSerializable(typeof(SlnfFileHelper.SlnfRoot))] internal partial class SlnfJsonSerializerContext : JsonSerializerContext; /// <summary> /// Utilities for working with solution filter (.slnf) files /// </summary> public static class SlnfFileHelper { /// <summary> /// File extension for solution filter files /// </summary> public const string SlnfExtension = ".slnf"; /// <summary> /// Normalizes path separators from backslashes to the OS-specific directory separator /// </summary> /// <param name="path">The path to normalize</param> /// <returns>Path with OS-specific separators</returns> public static string NormalizePathSeparatorsToOS(string path) { return path.Replace('\\', Path.DirectorySeparatorChar).Replace('/', Path.DirectorySeparatorChar); } /// <summary> /// Normalizes path separators to backslashes (as used in .slnf files) /// </summary> /// <param name="path">The path to normalize</param> /// <returns>Path with backslash separators</returns> public static string NormalizePathSeparatorsToBackslash(string path) { return path.Replace(Path.DirectorySeparatorChar, '\\'); } internal class SlnfSolution { [JsonPropertyName("path")] public string Path { get; set; } [JsonPropertyName("projects")] public List<string> Projects { get; set; } = new(); } internal class SlnfRoot { [JsonPropertyName("solution")] public SlnfSolution Solution { get; set; } = new(); } /// <summary> /// Creates a new solution filter file /// </summary> /// <param name="slnfPath">Path to the solution filter file to create</param> /// <param name="parentSolutionPath">Path to the parent solution file</param> /// <param name="projects">List of project paths to include (relative to the parent solution)</param> public static void CreateSolutionFilter(string slnfPath, string parentSolutionPath, IEnumerable<string> projects = null) { var slnfDirectory = Path.GetDirectoryName(Path.GetFullPath(slnfPath)) ?? string.Empty; var parentSolutionFullPath = Path.GetFullPath(parentSolutionPath, slnfDirectory); var relativeSolutionPath = Path.GetRelativePath(slnfDirectory, parentSolutionFullPath); // Normalize path separators to backslashes (as per slnf format) relativeSolutionPath = NormalizePathSeparatorsToBackslash(relativeSolutionPath); var root = new SlnfRoot { Solution = new SlnfSolution { Path = relativeSolutionPath, Projects = projects?.Select(NormalizePathSeparatorsToBackslash).ToList() ?? new List<string>() } }; var json = JsonSerializer.Serialize(root, SlnfJsonSerializerContext.Default.SlnfRoot); File.WriteAllText(slnfPath, json); } /// <summary> /// Saves a solution filter file with the given projects /// </summary> /// <param name="slnfPath">Path to the solution filter file</param> /// <param name="parentSolutionPath">Path to the parent solution (stored in the slnf file)</param> /// <param name="projects">List of project paths (relative to the parent solution)</param> public static void SaveSolutionFilter(string slnfPath, string parentSolutionPath, IEnumerable<string> projects) { var slnfDirectory = Path.GetDirectoryName(Path.GetFullPath(slnfPath)) ?? string.Empty; // Normalize the parent solution path to be relative to the slnf file var relativeSolutionPath = parentSolutionPath; if (Path.IsPathRooted(parentSolutionPath)) { relativeSolutionPath = Path.GetRelativePath(slnfDirectory, parentSolutionPath); } // Normalize path separators to backslashes (as per slnf format) relativeSolutionPath = NormalizePathSeparatorsToBackslash(relativeSolutionPath); var root = new SlnfRoot { Solution = new SlnfSolution { Path = relativeSolutionPath, Projects = projects.Select(NormalizePathSeparatorsToBackslash).ToList() } }; var json = JsonSerializer.Serialize(root, SlnfJsonSerializerContext.Default.SlnfRoot); File.WriteAllText(slnfPath, json); } }