using System; using System.IO; using System.Linq; using System.Xml.Linq; namespace Unosquare.Swan.Components { /// /// Represents a CsProjFile (and FsProjFile) parser. /// /// /// Based on https://github.com/maartenba/dotnetcli-init. /// /// The type of CsProjMetadataBase. /// public class CsProjFile : IDisposable where T : CsProjMetadataBase { private readonly Stream _stream; private readonly Boolean _leaveOpen; private readonly XDocument _xmlDocument; /// /// Initializes a new instance of the class. /// /// The filename. public CsProjFile(String filename = null) : this(OpenFile(filename)) { // placeholder } /// /// Initializes a new instance of the class. /// /// The stream. /// if set to true [leave open]. /// Project file is not of the new .csproj type. public CsProjFile(Stream stream, Boolean leaveOpen = false) { this._stream = stream; this._leaveOpen = leaveOpen; this._xmlDocument = XDocument.Load(stream); XElement projectElement = this._xmlDocument.Descendants("Project").FirstOrDefault(); XAttribute sdkAttribute = projectElement?.Attribute("Sdk"); String sdk = sdkAttribute?.Value; if(sdk != "Microsoft.NET.Sdk" && sdk != "Microsoft.NET.Sdk.Web") { throw new ArgumentException("Project file is not of the new .csproj type."); } this.Metadata = Activator.CreateInstance(); this.Metadata.SetData(this._xmlDocument); } /// /// Gets the metadata. /// /// /// The nu get metadata. /// public T Metadata { get; } /// /// Saves this instance. /// public void Save() { this._stream.SetLength(0); this._stream.Position = 0; this._xmlDocument.Save(this._stream); } /// public void Dispose() { if(!this._leaveOpen) { this._stream?.Dispose(); } } private static FileStream OpenFile(String filename) { if(filename == null) { filename = Directory .EnumerateFiles(Directory.GetCurrentDirectory(), "*.csproj", SearchOption.TopDirectoryOnly) .FirstOrDefault(); } if(filename == null) { filename = Directory .EnumerateFiles(Directory.GetCurrentDirectory(), "*.fsproj", SearchOption.TopDirectoryOnly) .FirstOrDefault(); } if(String.IsNullOrWhiteSpace(filename)) { throw new ArgumentNullException(nameof(filename)); } return File.Open(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite); } } }