aboutsummaryrefslogtreecommitdiff
path: root/src/Projects
diff options
context:
space:
mode:
Diffstat (limited to 'src/Projects')
-rw-r--r--src/Projects/DotnetProject.cs38
-rw-r--r--src/Projects/DotnetProjectDom.cs60
-rw-r--r--src/Projects/LeafProject.cs37
-rw-r--r--src/Projects/ModuleProject.cs118
-rw-r--r--src/Projects/NativeProjectDom.cs57
5 files changed, 310 insertions, 0 deletions
diff --git a/src/Projects/DotnetProject.cs b/src/Projects/DotnetProject.cs
new file mode 100644
index 0000000..5ee1ed0
--- /dev/null
+++ b/src/Projects/DotnetProject.cs
@@ -0,0 +1,38 @@
+
+using System;
+using System.IO;
+using System.Threading.Tasks;
+
+using VNLib.Tools.Build.Executor.Model;
+
+namespace VNLib.Tools.Build.Executor.Projects
+{
+
+ internal sealed class DotnetProject : ModuleProject
+ {
+ public override IProjectData ProjectData { get; }
+
+
+ public DotnetProject(FileInfo projectFile, string projectName):base(projectFile, projectName)
+ {
+ //Create the porject dom
+ ProjectData = new DotnetProjectDom();
+ }
+
+ ///<inheritdoc/>
+ public override async Task LoadAsync(TaskfileVars vars)
+ {
+ //Load project dom
+ await base.LoadAsync(vars);
+
+ //Set .NET specific vars
+ TaskVars.Set("TARGET_FRAMEWORK", ProjectData["TargetFramework"] ?? string.Empty);
+ TaskVars.Set("PROJ_ASM_NAME", ProjectData["AssemblyName"] ?? string.Empty);
+ }
+
+ public override string ToString() => ProjectName;
+
+ public override void Dispose()
+ { }
+ }
+} \ No newline at end of file
diff --git a/src/Projects/DotnetProjectDom.cs b/src/Projects/DotnetProjectDom.cs
new file mode 100644
index 0000000..9b44747
--- /dev/null
+++ b/src/Projects/DotnetProjectDom.cs
@@ -0,0 +1,60 @@
+
+using System;
+using System.IO;
+using System.Xml;
+using System.Collections.Generic;
+
+using VNLib.Tools.Build.Executor.Model;
+
+namespace VNLib.Tools.Build.Executor.Projects
+{
+
+ internal sealed class DotnetProjectDom : IProjectData
+ {
+ private readonly XmlDocument _dom;
+
+ public DotnetProjectDom()
+ {
+ _dom = new();
+ }
+
+ public void Load(Stream stream)
+ {
+ _dom.Load(stream);
+ }
+
+ private XmlNode? project => _dom["Project"];
+
+ public string? Description => GetProperty("Description");
+ public string? Authors => GetProperty("Authors");
+ public string? Copyright => GetProperty("Copyright");
+ public string? VersionString => GetProperty("Version");
+ public string? CompanyName => GetProperty("Company");
+ public string? Product => GetProperty("Product");
+ public string? RepoUrl => GetProperty("RepositoryUrl");
+
+ public string? this[string index] => GetProperty(index);
+
+ public string? GetProperty(string name) => GetItemAtPath($"PropertyGroup/{name}");
+
+ public string? GetItemAtPath(string path) => project!.SelectSingleNode(path)?.InnerText;
+
+ public string[] GetProjectRefs()
+ {
+ //Get the item group attr
+ XmlNodeList? projectRefs = project?.SelectNodes("ItemGroup/ProjectReference");
+
+ if (projectRefs != null)
+ {
+ List<string> refs = new();
+ foreach (XmlNode projRef in projectRefs)
+ {
+ //Get the project ref via its include attribute
+ refs.Add(projRef.Attributes["Include"].Value!);
+ }
+ return refs.ToArray();
+ }
+ return Array.Empty<string>();
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Projects/LeafProject.cs b/src/Projects/LeafProject.cs
new file mode 100644
index 0000000..9b155cf
--- /dev/null
+++ b/src/Projects/LeafProject.cs
@@ -0,0 +1,37 @@
+using System.IO;
+using System.Threading.Tasks;
+
+using VNLib.Tools.Build.Executor.Constants;
+using VNLib.Tools.Build.Executor.Model;
+
+namespace VNLib.Tools.Build.Executor.Projects
+{
+ internal sealed class LeafProject(BuildConfig config, FileInfo projectFile) : ModuleProject(projectFile)
+ {
+ ///<inheritdoc/>
+ public override IProjectData ProjectData { get; } = new NativeProjectDom();
+
+ ///<inheritdoc/>
+ protected override FileInfo? PackageInfoFile => new(Path.Combine(WorkingDir.FullName, "package.json"));
+
+ public override async Task LoadAsync(TaskfileVars vars)
+ {
+ await base.LoadAsync(vars);
+
+ //Set the project name to the product name if set, otherwise use the working dir name
+ ProjectName = ProjectData.Product ?? WorkingDir.Name;
+
+ //Get the binary dir from the project file, or use the default
+ string? binaryDir = ProjectData["output_dir"] ?? ProjectData["output"] ?? config.ProjectBinDir;
+
+ //Overide the project name from the pacakge file if set
+ TaskVars.Set("PROJECT_NAME", ProjectName);
+ TaskVars.Set("BINARY_DIR", binaryDir);
+ }
+
+ public override string ToString() => ProjectName;
+
+ public override void Dispose()
+ { }
+ }
+} \ No newline at end of file
diff --git a/src/Projects/ModuleProject.cs b/src/Projects/ModuleProject.cs
new file mode 100644
index 0000000..4643aa0
--- /dev/null
+++ b/src/Projects/ModuleProject.cs
@@ -0,0 +1,118 @@
+using System;
+using System.IO;
+using System.Threading.Tasks;
+
+using VNLib.Tools.Build.Executor.Model;
+using VNLib.Tools.Build.Executor.Extensions;
+
+namespace VNLib.Tools.Build.Executor.Projects
+{
+ internal abstract class ModuleProject : IProject
+ {
+ ///<inheritdoc/>
+ public FileInfo ProjectFile { get; }
+
+ ///<inheritdoc/>
+ public string ProjectName { get; protected set; }
+
+ ///<inheritdoc/>
+ public abstract IProjectData ProjectData { get; }
+
+ ///<inheritdoc/>
+ public bool UpToDate { get; set; }
+
+ ///<inheritdoc/>
+ public DirectoryInfo WorkingDir { get; protected set; }
+
+ ///<inheritdoc/>
+ public TaskfileVars TaskVars { get; protected set; }
+
+ ///<inheritdoc/>
+ public string? TaskfileName { get; protected set; }
+
+ /// <summary>
+ /// Gets the package info file for the project
+ /// </summary>
+ protected virtual FileInfo? PackageInfoFile { get; }
+
+ public ModuleProject(FileInfo projectFile, string? projectName = null)
+ {
+ ProjectFile = projectFile;
+
+ //Default project name to the file name
+ ProjectName = projectName ?? Path.GetFileNameWithoutExtension(ProjectFile.Name);
+
+ //Default up-to-date false
+ UpToDate = false;
+
+ //Default working dir to the project file's directory
+ WorkingDir = ProjectFile.Directory!;
+
+ TaskVars = null!;
+ }
+
+ ///<inheritdoc/>
+ public virtual async Task LoadAsync(TaskfileVars vars)
+ {
+ TaskVars = vars;
+
+ await LoadProjectDom();
+
+ //Set some local environment variables
+
+ //Set local environment variables
+ TaskVars.Set("PROJECT_NAME", ProjectName);
+ TaskVars.Set("PROJECT_DIR", WorkingDir.FullName);
+ TaskVars.Set("IS_PROJECT", bool.TrueString);
+
+ //Store project vars
+ TaskVars.Set("PROJ_VERSION", ProjectData.VersionString ?? string.Empty);
+ TaskVars.Set("PROJ_DESCRIPTION", ProjectData.Description ?? string.Empty);
+ TaskVars.Set("PROJ_AUTHOR", ProjectData.Authors ?? string.Empty);
+ TaskVars.Set("PROJ_COPYRIGHT", ProjectData.Copyright ?? string.Empty);
+ TaskVars.Set("PROJ_COMPANY", ProjectData.CompanyName ?? string.Empty);
+ TaskVars.Set("RPOJ_URL", ProjectData.RepoUrl ?? string.Empty);
+
+ TaskVars.Set("SAFE_PROJ_NAME", this.GetSafeProjectName());
+ }
+
+ /// <summary>
+ /// Loads the project's XML dom from its msbuild project file
+ /// </summary>
+ /// <returns>A task that resolves when the dom is built</returns>
+ public async Task LoadProjectDom()
+ {
+ using MemoryStream ms = new();
+
+ FileInfo dom = ProjectFile;
+
+ if (PackageInfoFile?.Exists == true)
+ {
+ dom = PackageInfoFile;
+ }
+
+ try
+ {
+ //Get the project file
+ await using (FileStream projData = dom.OpenRead())
+ {
+ await projData.CopyToAsync(ms);
+ }
+
+ //reset stream
+ ms.Seek(0, SeekOrigin.Begin);
+
+ //Load the project dom
+ ProjectData.Load(ms);
+ }
+ catch (Exception ex)
+ {
+ throw new Exception($"Failed to load project dom file {dom.FullName}", ex);
+ }
+ }
+
+ public abstract void Dispose();
+
+ public override string ToString() => ProjectName;
+ }
+} \ No newline at end of file
diff --git a/src/Projects/NativeProjectDom.cs b/src/Projects/NativeProjectDom.cs
new file mode 100644
index 0000000..f23a4a5
--- /dev/null
+++ b/src/Projects/NativeProjectDom.cs
@@ -0,0 +1,57 @@
+using System;
+using System.IO;
+using System.Text.Json;
+using System.Collections.Generic;
+
+using VNLib.Tools.Build.Executor.Model;
+
+namespace VNLib.Tools.Build.Executor.Projects
+{
+ internal sealed class NativeProjectDom : IProjectData
+ {
+ private Dictionary<string, string> _properties;
+
+ internal NativeProjectDom()
+ {
+ _properties = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
+ }
+
+ public string? this[string index] => _properties.GetValueOrDefault(index);
+
+ public string? Description => this["description"];
+ public string? Authors => this["author"];
+ public string? Copyright => this["copyright"];
+ public string? VersionString => this["version"];
+ public string? CompanyName => this["company"];
+ public string? Product => this["name"];
+ public string? RepoUrl => this["repository"];
+ public string? OutputDir => this["output_dir"];
+
+ public string[] GetProjectRefs()
+ {
+ return Array.Empty<string>();
+ }
+
+ public void Load(Stream stream)
+ {
+ //Read the json file
+ using JsonDocument doc = JsonDocument.Parse(stream, new JsonDocumentOptions
+ {
+ CommentHandling = JsonCommentHandling.Skip,
+ AllowTrailingCommas = true,
+ });
+
+ //Clear old properties
+ _properties.Clear();
+
+ //Load new properties that are strings only
+ foreach (JsonProperty prop in doc.RootElement.EnumerateObject())
+ {
+ if(prop.Value.ValueKind == JsonValueKind.String)
+ {
+ _properties[prop.Name] = prop.Value.GetString() ?? string.Empty;
+ }
+ }
+ }
+ }
+} \ No newline at end of file