diff --git a/Slnx/DescendantConfiguration.cs b/Slnx/DescendantConfiguration.cs deleted file mode 100644 index 6ad0ce4..0000000 --- a/Slnx/DescendantConfiguration.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace Slnx -{ - /// - /// Represents a "<Configuration>" like tag. - /// - public class DescendantConfiguration - { - /// - /// Solution where this configuration applies to. - /// - public string? Solution { get; init; } - - /// - /// Project where this configuration applies to. - /// - public string? Project { get; init; } - - /// - /// Initializes a new instance of the class. - /// - /// Solution where this configuration applies to. - /// Project where this configuration applies to. - public DescendantConfiguration(string? solution, string? project) - { - Solution = solution; - Project = project; - } - } -} diff --git a/Slnx/Folder.cs b/Slnx/Folder.cs deleted file mode 100644 index 67439f3..0000000 --- a/Slnx/Folder.cs +++ /dev/null @@ -1,260 +0,0 @@ -namespace Slnx -{ - /// - /// Represents a folder in the same level as the solution. - /// - public class Folder - { - /// - /// Gets an instance of with no content and name "(Folder Name)". - /// - public static Folder Empty => new("(Folder Name)", Array.Empty(), Array.Empty(), Array.Empty()); - - /// - /// Name of the folder. - /// - public string Name { get; set; } - - /// - /// Nested projects in the folder. If this is , then there - /// are no descendant projects. - /// - public List? DescendantProjects { get; set; } - - /// - /// Nested folders in the folder. If this is , then there - /// are no descendant folders. - /// - public List? DescendantFolders { get; set; } - - /// - /// Files in the folder. If this is , then there - /// are no descendant files. - /// - public List? DescendantFiles { get; set; } - - /// - /// Initializes a new instance of the class. - /// - /// Folder name. - /// All projects. - /// All folders. - /// All files. - public Folder(string name, Project[] projects, Folder[] folders, string[] files) - { - Name = name; - DescendantProjects = projects.Length == 0 ? null : new List(projects); - DescendantFolders = folders.Length == 0 ? null : new List(folders); - DescendantFiles = files.Length == 0 ? null : new List(files); - } - - /// - /// Initializes a new instance of the class. - /// - /// The name of the folder. - /// - /// Properties , , - /// and will be . - /// - public Folder(string name) : this(name, Array.Empty(), Array.Empty(), Array.Empty()) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The name of the folder. - /// All projects. - /// - /// Properties and - /// will be . - /// - public Folder(string name, Project[] projects) : this(name, projects, Array.Empty(), Array.Empty()) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The name of the folder. - /// All folders. - /// - /// Properties and - /// will be . - /// - public Folder(string name, Folder[] folders) : this(name, Array.Empty(), folders, Array.Empty()) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The name of the folder. - /// All files. - /// - /// Properties and - /// will be . - /// - public Folder(string name, string[] files) : this(name, Array.Empty(), Array.Empty(), files) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The name of the folder. - /// All folders. - /// All files. - /// - /// Property will be . - /// - public Folder(string name, Folder[] folders, string[] files) : this(name, Array.Empty(), folders, files) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The name of the folder. - /// All folders. - /// All projects. - /// - /// Property will be . - /// - public Folder(string name, Folder[] folders, Project[] projects) : this(name, projects, folders, Array.Empty()) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The name of the folder. - /// All projects. - /// All files. - /// - /// Property will be . - /// - public Folder(string name, Project[] project, string[] files) : this(name, project, Array.Empty(), files) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The name of the folder. - /// All projects. - /// All folders. - /// - /// Property will be . - /// - public Folder(string name, Project[] project, Folder[] folders) : this(name, project, folders, Array.Empty()) - { - } - - /// - /// Adds a given array of projects to this instance of . - /// - /// An array of projects to add. - /// Current instance of after adding the given projects. - public Folder AddProjects(Project[] projects) - { - DescendantProjects ??= new List(); - - foreach (Project project in projects) - { - DescendantProjects.Add(project); - } - - return this; - } - - /// - /// Adds a single project to this instance of . - /// - /// A project that will be added. - /// Current instance of after adding the given project. - public Folder AddProject(Project project) - { - DescendantProjects ??= new List(); - DescendantProjects.Add(project); - return this; - } - - /// - /// Adds a given array of files to this instance of . - /// - /// An array of files to add. - /// Current instance of after adding the given files. - public Folder AddFiles(string[] files) - { - DescendantFiles ??= new List(); - foreach (string file in files) - { - DescendantFiles.Add(file); - } - return this; - } - - /// - /// Adds a single file to this instance of . - /// - /// A file that will be added. - /// Current instance of after adding the given file. - public Folder AddFile(string file) - { - DescendantFiles ??= new List(); - DescendantFiles.Add(file); - return this; - } - - /// - /// Adds a given array of folders to this instance of . - /// - /// An array of folders to add. - /// Current instance of after adding the given folder. - public Folder AddFolders(Folder[] folders) - { - DescendantFolders ??= new List(); - foreach (Folder folder in folders) - { - DescendantFolders.Add(folder); - } - return this; - } - - /// - /// Adds a single folder to this instance of . - /// - /// A folder that will be added. - /// Current instance of after adding the given folder. - public Folder AddFolder(Folder folder) - { - DescendantFolders ??= new List(); - DescendantFolders.Add(folder); - return this; - } - - /// - /// Adds a new project without any configuration to this instance of - /// - /// The path to the project. - /// - /// A tuple that contains two elements: - /// - /// - /// Item 1 (): Current instance of - /// after adding the project. - /// - /// - /// Item 2 (): The project that was added. - /// - /// - /// - public (Folder, Project) AddProjectWithPathOnly(string path) - { - var project = new Project(path); - AddProject(project); - return (this, project); - } - } -} diff --git a/Slnx/Project.cs b/Slnx/Project.cs deleted file mode 100644 index 51a3e30..0000000 --- a/Slnx/Project.cs +++ /dev/null @@ -1,88 +0,0 @@ -namespace Slnx -{ - /// - /// Represents a single project found in the SLNX file. - /// - public class Project - { - /// - /// Checks if the project file exists. - /// - public bool Exists => File.Exists(System.IO.Path.Combine(Directory.GetCurrentDirectory(), Path)); - - /// - /// Path to the project file. - /// - public string Path { get; set; } - - /// - /// Type of the project. - /// - public ProjectType Type { get; set; } - - /// - /// Extension of the project file. If the extension isn't present, the - /// value is null. - /// - public string? Extension { get; set; } - - /// - /// Checks if the property has an extension. - /// - public bool HasExtension => Extension != null; - - /// - /// Gets the type of the project from the GUID. The value is always null - /// unless the XML attribute "Type" exists. - /// - public Guid? TypeGuid { get; set; } - - /// - /// Descendant configuration. - /// - public DescendantConfiguration? Configuration { get; set; } - - /// - /// Initializes a new instance of the class. - /// - /// Path to the project file. - /// The GUID indicating its type. - /// The configuration. - public Project(string path, Guid? typeGuid = null, DescendantConfiguration? config = null) - { - Path = path; - - string typeString = (path.Contains('/') ? path.Split('/').Last() - : path.Contains('\\') ? path.Split('\\').Last() - : path).TrimStart('.'); - typeString = typeString.Contains('.') ? typeString.Split('.').Last() : typeString; - - Type = typeString.FromExtension(); - Extension = path.Contains('.') ? path.Split('.').Last() : null; - TypeGuid = typeGuid; - Configuration = config; - } - - /// - /// Changes the type GUID of this project to and returns it. - /// - /// The type GUID. - /// Current instance of with the given type GUID. - public Project WithTypeGuid(Guid typeGuid) - { - TypeGuid = typeGuid; - return this; - } - - /// - /// Changes the descendant configuration of this project to and returns it. - /// - /// The descendant project configuration. - /// Current instance of with the given configuration. - public Project WithConfiguration(DescendantConfiguration? configuration) - { - Configuration = configuration; - return this; - } - } -} diff --git a/Slnx/ProjectType.cs b/Slnx/ProjectType.cs deleted file mode 100644 index a5c2ea6..0000000 --- a/Slnx/ProjectType.cs +++ /dev/null @@ -1,78 +0,0 @@ -namespace Slnx -{ - /// - /// Represents the type of a project file. - /// - public enum ProjectType - { - /// - /// C# Project (*.csproj) - /// - CSharp = 0, - - /// - /// Visual C++ Project (*.vcxproj) - /// - VC = 1, - - /// - /// VB.NET Project (*.vbproj) - /// - VisualBasic = 2, - - /// - /// F# Project (*.fsproj) - /// - FSharp = 3, - - /// - /// Microsoft Installer Project (*.vdproj) - /// - Installer = 4, - - /// - /// Shared Project (*.shproj) - /// - Shared = 5, - - /// - /// Database Project (*.dbproj) - /// - Database = 6, - - /// - /// Docker Compose Project (*.dcproj) - /// - DockerCompose = 7, - - /// - /// SQL Project (*.sqlproj) - /// - Sql = 8, - - /// - /// JavaScript Application/ECMAScript Project (*.esproj) - /// - JavaScript = 9, - - /// - /// .NET Core 2015 Project (*.xproj) - /// - NetCore2015 = 10, - - /// - /// Common MSBuild Project (*.msbuildproj) - /// - Common = 11, - - /// - /// Project (*.proj) - /// - Project = 12, - - /// - /// Any project type which is not defined. - /// - Unknown = 0xFF - } -} diff --git a/Slnx/ProjectTypeExtensions.cs b/Slnx/ProjectTypeExtensions.cs deleted file mode 100644 index aafd5ce..0000000 --- a/Slnx/ProjectTypeExtensions.cs +++ /dev/null @@ -1,56 +0,0 @@ -namespace Slnx -{ - /// - /// Extension methods for . - /// - public static class ProjectTypeExtensions - { - /// - /// Returns the extension for the project type. - /// - /// Type of the project. - /// A file extension for that project type, excluding the period. - public static string GetExtension(this ProjectType projectType) - => (byte)projectType switch - { - 0 => "csproj", - 1 => "vcxproj", - 2 => "vbproj", - 3 => "fsproj", - 4 => "vdproj", - 5 => "shproj", - 6 => "dbproj", - 7 => "dcproj", - 8 => "sqlproj", - 9 => "esproj", - 10 => "xproj", - 11 => "msbuildproj", - 12 => "proj", - _ => string.Empty - }; - - /// - /// Returns the project type for the project extension. - /// - /// Extension of the project, excluding the period. - /// A type of the project from the extension. - public static ProjectType FromExtension(this string extension) - => (ProjectType)(byte)(extension.ToLowerInvariant() switch - { - "csproj" => 0, - "vcxproj" => 1, - "vbproj" => 2, - "fsproj" => 3, - "vdproj" => 4, - "shproj" => 5, - "dbproj" => 6, - "dcproj" => 7, - "sqlproj" => 8, - "esproj" => 9, - "xproj" => 10, - "msbuildproj" => 11, - "proj" => 12, - _ => 0xFF - }); - } -} diff --git a/Slnx/Slnx.csproj b/Slnx/Slnx.csproj deleted file mode 100644 index 6f038a7..0000000 --- a/Slnx/Slnx.csproj +++ /dev/null @@ -1,33 +0,0 @@ - - - - net6.0 - enable - enable - Slnx.dll - 2.0.1.0 - winscripter - True - Slnx - winscripter - SLNX Parser: Reader and Writer for the (currently) in-preview Visual Studio -XML-based solution format found in Visual Studio 2022 17.10 Preview 3. - Copyright (c) winscripter, 2024 - https://github.com/winscripter/Slnx - https://github.com/winscripter/Slnx - MIT - True - README.md - VisualStudio, Solution, Sln, Slnx - 2.0.1 - Changed configuration from Debug to Release. No changes to the library were made. - - - - - True - \ - - - - diff --git a/Slnx/SlnxFactory.cs b/Slnx/SlnxFactory.cs deleted file mode 100644 index 610fd08..0000000 --- a/Slnx/SlnxFactory.cs +++ /dev/null @@ -1,55 +0,0 @@ -namespace Slnx -{ - /// - /// Builds a SLNX file. - /// - public class SlnxFactory - { - /// - /// All folders. - /// - public List Folders { get; init; } - - /// - /// All projects. - /// - public List Projects { get; init; } - - /// - /// Initializes a new instance of the class. - /// - public SlnxFactory() - { - Folders = new List(); - Projects = new List(); - } - - /// - /// Converts this instance of into . - /// - /// An instance of . - public SlnxModel AsModel() => new(Projects.ToArray(), Folders.ToArray()); - - /// - /// Adds a new folder to the SLNX file. - /// - /// The folder to add. - /// Current instance of after adding a folder. - public SlnxFactory AddFolder(Folder folder) - { - Folders.Add(folder); - return this; - } - - /// - /// Adds a new project to the SLNX file. - /// - /// The project to add. - /// Current instance of after adding a project. - public SlnxFactory AddProjectWithPathOnly(string path) - { - Projects.Add(new Project(path)); - return this; - } - } -} diff --git a/Slnx/SlnxModel.cs b/Slnx/SlnxModel.cs deleted file mode 100644 index 7fdde4f..0000000 --- a/Slnx/SlnxModel.cs +++ /dev/null @@ -1,173 +0,0 @@ -using System.Text; -using System.Xml; -using System.Xml.Linq; - -namespace Slnx -{ - /// - /// Represents information about a SLNX file. - /// - public class SlnxModel - { - /// - /// Gets all projects in the same level as the SLNX. - /// - public Project[]? TopLevelProjects { get; set; } - - /// - /// Gets all folders in the same level as the SLNX. - /// - public Folder[]? TopLevelFolders { get; set; } - - /// - /// Initializes a new instance of the class. - /// - /// A list of projects. - /// A list of folders. - public SlnxModel(Project[] projects, Folder[] folders) - { - TopLevelProjects = projects.Length == 0 ? null : projects; - TopLevelFolders = folders.Length == 0 ? null : folders; - } - - /// - /// Loads and parses a SLNX file. - /// - /// The string contents of the SLNX file. Use . - /// Information about that SLNX file. - public static SlnxModel Load(string slnxContent) => SlnxParser.ParseSlnx(slnxContent); - - /// - /// Stores the data of this instance of into a SLNX file. - /// - /// - /// Output file. Can be anything but it is recommended for the - /// extension to end with .slnx. - /// - /// Settings for the style of the output XML. If the value is , default parameters are used. - /// - /// The output file will be attempted to be deleted if it exists. - /// - public void Store(string outputFile, XmlWriterSettings? settings = null) - { - settings ??= XmlPrivate.DefaultSettings; - - if (File.Exists(outputFile)) - { - File.Delete(outputFile); - } - - string result = Store(settings); - File.AppendAllText(outputFile, result.ToString()); - } - - /// - /// Converts this instance of to the string representation - /// of the SLNX file with same projects and folders. - /// - /// Settings for the style of the output XML. If the value is , default parameters are used. - /// A string that represents the SLNX file with projects, folders, and other metadata from this instance of . - public string Store(XmlWriterSettings? xmlWriterSettings = null) - { - xmlWriterSettings ??= XmlPrivate.DefaultSettings; - TextBuilderInternal innerContent = TextBuilderInternal.CreateNew(); - - innerContent.WriteLine(""); - innerContent.IndentUp(); - - if (TopLevelProjects != null) - { - foreach (Project project in TopLevelProjects) - { - EmitProject(project); - } - } - - if (TopLevelFolders != null) - { - foreach (Folder folder in TopLevelFolders) - { - EmitFolder(folder); - } - } - - innerContent.IndentDown(); - innerContent.WriteLine(""); - - // Format the result - var value = innerContent.GetBuilder().ToString(); - string result = XDocument.Parse(value).FormatIndented(xmlWriterSettings!); - - return result; - - void EmitProject(Project project) - { - innerContent.WriteIndented($""); - } - else - { - innerContent.Write(">"); - innerContent.IndentUp(); - - innerContent.WriteIndented($""); - - innerContent.WriteLineIndented(""); - innerContent.IndentDown(); - } - - innerContent.IndentDown(); - } - - void EmitFolder(Folder folder) - { - innerContent.WriteLineIndented($""); - innerContent.IndentUp(); - - foreach (string descendantFile in folder.DescendantFiles ?? new List()) - { - innerContent.WriteLineIndented($""); - } - - foreach (Project project in folder.DescendantProjects ?? new List()) - { - EmitProject(project); - } - - if (folder.DescendantFolders != null) - { - if (folder.DescendantFolders.Count > 0) - { - foreach (Folder folder2 in folder.DescendantFolders) - { - EmitFolder(folder2); - } - } - } - - innerContent.IndentDown(); - innerContent.WriteLineIndented(""); - innerContent.IndentUp(); - } - } - } -} diff --git a/Slnx/SlnxParser.cs b/Slnx/SlnxParser.cs deleted file mode 100644 index 5b70709..0000000 --- a/Slnx/SlnxParser.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System.Text; -using System.Xml.Linq; - -namespace Slnx -{ - internal static class SlnxParser - { - public static SlnxModel ParseSlnx(string slnxContent) - { - var doc = XDocument.Parse(slnxContent); - var root = doc.Root ?? throw new SolutionException("Root tag is missing."); - - var folders = new List(); - var projects = new List(); - - foreach (var childTag in root.Elements()) - { - switch (childTag.Name.LocalName) - { - case "Folder": - folders.Add(ParseFolder(childTag)); - break; - case "Project": - projects.Add(ParseProject(childTag)); - break; - case "File": - throw new SolutionException("A File element cannot be at the root level. Please add it into the Solution Items folder first."); - default: - throw new SolutionException($"Unrecognized tag \"{childTag.Name.LocalName}\""); - } - } - - return new SlnxModel(projects.ToArray(), folders.ToArray()); - } - - private static Folder ParseFolder(XElement folderElement) - { - var name = folderElement.Attribute("Name")?.Value ?? throw new SolutionException("Missing attribute \"Name\""); - var projects = folderElement.Elements("Project").Select(ParseProject).ToArray(); - var folders = folderElement.Elements("Folder").Select(ParseFolder).ToArray(); - var files = folderElement.Elements("File").Select(ParseFile).ToArray(); - - return new Folder(name, projects, folders, files); - } - - private static string ParseFile(XElement fileElement) - { - var path = fileElement.Attribute("Path")?.Value ?? throw new SolutionException("Missing attribute \"Path\""); - - return path; - } - - private static Project ParseProject(XElement projectElement) - { - var path = projectElement.Attribute("Path")?.Value ?? throw new SolutionException("Missing attribute \"Path\""); - - var typeGuid = projectElement.Attribute("TypeGuid") != null - ? Guid.Parse(projectElement.Attribute("TypeGuid")!.Value) - : (Guid?)null; - var configElement = projectElement.Element("Configuration"); - var config = configElement != null ? ParseConfiguration(configElement) : (DescendantConfiguration?)null; - - return new Project(path, typeGuid, config); - } - - private static DescendantConfiguration ParseConfiguration(XElement configElement) - { - var solution = configElement.Attribute("Solution")?.Value; - var project = configElement.Attribute("Project")?.Value; - - return new DescendantConfiguration(solution, project); - } - } -} diff --git a/Slnx/SolutionException.cs b/Slnx/SolutionException.cs deleted file mode 100644 index c1eddba..0000000 --- a/Slnx/SolutionException.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace Slnx -{ - /// - /// Represents an error related to SLNX syntax or its infrastructure. - /// - internal class SolutionException : Exception - { - /// - /// Initializes a new instance of the class. - /// - /// Exception message. - public SolutionException(string message) : base(message) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// Exception message. - /// An inner exception. - public SolutionException(string message, Exception innerException) : base(message, innerException) - { - } - } -} diff --git a/Slnx/TextBuilderInternal.cs b/Slnx/TextBuilderInternal.cs deleted file mode 100644 index 30686bc..0000000 --- a/Slnx/TextBuilderInternal.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System.Text; - -namespace Slnx -{ - /// - /// Internal class used by Slnx to write text with indentation. - /// - internal class TextBuilderInternal - { - private readonly StringBuilder _sb; - private int _indent = 0; - private const int IndentBy = 4; - - public TextBuilderInternal(StringBuilder sb) - { - _sb = sb; - } - - public void IndentUp() - { - _indent += IndentBy; - } - - public void IndentDown() - { - _indent -= IndentBy; - - if (_indent < 0) _indent = 0; - } - - public void Write(string text) - { - _sb.Append($"{text}"); - } - - public void WriteLine(string text) - { - _sb.AppendLine($"{text}"); - } - - public void WriteIndented(string text) - { - _sb.Append($"{new string(' ', _indent)}{text}"); - } - - public void WriteLineIndented(string text) - { - _sb.AppendLine($"{new string(' ', _indent)}{text}"); - } - - public StringBuilder GetBuilder() - { - return _sb; - } - - public void SetContent(string text) - { - _sb.Clear(); - _sb.Append(text); - } - - public static TextBuilderInternal CreateNew() - { - return new TextBuilderInternal(new StringBuilder()); - } - } -} diff --git a/Slnx/XmlPrivate.cs b/Slnx/XmlPrivate.cs deleted file mode 100644 index 257a553..0000000 --- a/Slnx/XmlPrivate.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Text; -using System.Xml; -using System.Xml.Linq; - -namespace Slnx -{ - internal static class XmlPrivate - { - public static XmlWriterSettings DefaultSettings => new() - { - Indent = true, - IndentChars = " ", // 4 spaces - NewLineChars = "\r\n", - NewLineHandling = NewLineHandling.Replace, - Encoding = new UTF8Encoding(false), - OmitXmlDeclaration = true - }; - - internal static string FormatIndented(this XNode node, XmlWriterSettings settings) - { - using var sw = new StringWriter(); - - using (var xmlWriter = XmlWriter.Create(sw, settings)) - { - node.WriteTo(xmlWriter); - } - - return sw.ToString(); - } - } -}