Skip to content

Commit

Permalink
+ comments | improved logic
Browse files Browse the repository at this point in the history
  • Loading branch information
Chase-William committed Feb 7, 2024
1 parent 109f31f commit 21a4918
Show file tree
Hide file tree
Showing 35 changed files with 522 additions and 627 deletions.
70 changes: 42 additions & 28 deletions src/DotDocs.Build/Build/BuildInstance.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using DotDocs.Build.Exceptions;
using DotDocs.Build.Util;
using DotDocs.Models;
using Microsoft.Build.Logging.StructuredLogger;
using System.Collections.Immutable;
Expand All @@ -15,16 +14,28 @@ public class BuildInstance //: IDisposable
{
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();

ProjectDocument rootProject;

public ProjectBuildInstance RootProjectBuildInstance { get; private set; }

ImmutableArray<string> allAssemblyPaths;
/// <summary>
/// The root project's document file i.e. (.csproj file).
/// </summary>
private readonly ProjectDocument rootProject;

List<ProjectBuildInstance> allProjectBuildInstances = new();
public ImmutableArray<ProjectBuildInstance> AllProjectBuildInstances
=> allProjectBuildInstances.ToImmutableArray();
/// <summary>
/// The root project i.e. (.csproj file) that all other projects support.
/// </summary>
public ProjectBuildInstance? RootProjectBuildInstance { get; private set; }
/// <summary>
/// All the assemblies used to support the compilation of this project.
/// </summary>
ImmutableArray<string> AllAssemblyPaths { get; set; } = new();
/// <summary>
/// All projects' build instances.
/// </summary>
List<ProjectBuildInstance> AllProjectBuildInstances { get; set; } = new();

/// <summary>
/// Creates an
/// </summary>
/// <param name="rootProject"></param>
public BuildInstance(ProjectDocument rootProject)
{
Logger.Debug("Params: [{rootProjectLbl}: {rootProjectValue}]", nameof(rootProject), rootProject);
Expand Down Expand Up @@ -70,7 +81,7 @@ public BuildInstance Build()
var mainBuild = build.FindLastChild<Project>();
var target = mainBuild
.FindFirstChild<Target>(c => c.Name == "FindReferenceAssembliesForReferences");
allAssemblyPaths = target.Children
AllAssemblyPaths = target.Children
.Select(item => ((Item)((AddItem)item).FirstChild).Text)
.ToImmutableArray();

Expand All @@ -81,10 +92,10 @@ public BuildInstance Build()
.FindLastChild<ProjectEvaluation>(p => p.Name.Equals(projectName));

RootProjectBuildInstance = ProjectBuildInstance
.From(projectEval, allProjectBuildInstances);
.From(projectEval, AllProjectBuildInstances);

// Add the root node as it will never be added otherwise
allProjectBuildInstances.Add(RootProjectBuildInstance);
AllProjectBuildInstances.Add(RootProjectBuildInstance);
}
catch (Exception ex)
{
Expand All @@ -99,22 +110,26 @@ public BuildInstance Build()
/// Generates models for all of the projects, assemblies, and types.
/// </summary>
/// <returns>The root project.</returns>
public ProjectModel GetRootProject(
Dictionary<string, ProjectModel> projects
) {
Logger.Trace("Getting the root project by recursively building up each project from the farthest leaf inward.");
public ImmutableArray<(string docs, Assembly binary)> GetAssemblies() {
Logger.Trace("Getting the root project by recursively building up each project from the farthest leaf inward.");

var rootProject = Load(RootProjectBuildInstance, allAssemblyPaths, projects);
// The root is not added until here
projects.Add(rootProject.Name, rootProject);
return rootProject;
}
var projects = new Dictionary<string, ProjectModel>();

//public void Dispose()
//{
// foreach (var build in allProjectBuildInstances)
// build.Dispose();
//}
var rootProject = Load(
RootProjectBuildInstance,
AllAssemblyPaths,
projects);

int index = 0;
var assemblies = new (string docs, Assembly asm)[projects.Values.Count + 1]; // Leave room for the root project

// Gather all assembles into collection
foreach (var proj in projects.Values)
assemblies[index++] = new(proj.DocumentationFilePath, proj.Assembly);
assemblies[index] = new(rootProject.DocumentationFilePath, rootProject.Assembly);

return assemblies.ToImmutableArray();
}

/// <summary>
/// Recursive function that creates the project tree recursively in a BDF fashion.
Expand Down Expand Up @@ -164,8 +179,7 @@ Dictionary<string, ProjectModel> projects
// Initialize the MetadataLoadContext for reflection only introspection
// Call the Apply method to apply assembmly info/build results to the model
// Return to caller
return projModel;
//.Apply(build.InitMetadataLoadCtx(asmPaths));
return projModel;
}
}
}
3 changes: 1 addition & 2 deletions src/DotDocs.Build/Build/ProjectBuildInstance.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using DotDocs.Build.Util;
using DotDocs.Models;
using DotDocs.Models;
using LoxSmoke.DocXml;
using Microsoft.Build.Logging.StructuredLogger;
using Microsoft.Build.Utilities;
Expand Down
4 changes: 2 additions & 2 deletions src/DotDocs.Build/ProjectDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ private ProjectDocument(string projectFile)
/// <summary>
/// Mutates this project and its dependency projects recursively so that documentation files are generated during compilation.
/// </summary>
public void EnableDocumentationGeneration()
public void EnableAllDocumentationGeneration()
{
Logger.Trace("Enabling documentation generation for project file: {projectfile}", ProjectFilePath);
// Enable documenation generation on current project
Expand All @@ -55,7 +55,7 @@ public void EnableDocumentationGeneration()


foreach (var dependency in Dependencies)
dependency.EnableDocumentationGeneration();
dependency.EnableAllDocumentationGeneration();
}

/// <summary>
Expand Down
140 changes: 0 additions & 140 deletions src/DotDocs.Build/Repository.cs

This file was deleted.

117 changes: 117 additions & 0 deletions src/DotDocs.Build/Solution.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
using DotDocs.Build.Build;
using System.Collections.Immutable;
using System.Reflection;

namespace DotDocs.Build
{
/// <summary>
/// A class providing tools to interact and mutate a real repository and its project files on disk.
/// </summary>
public class Solution
{
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();

/// <summary>
/// The results of the entire build.
/// </summary>
// internal BuildInstance? build;

/// <summary>
/// The directory of the solution.
/// </summary>
public string Dir { get; private set; }

/// <summary>
/// All project groups in the solution.
/// </summary>
public ImmutableArray<ProjectDocument> DependencyGraph { get; private set; }

/// <summary>
/// The select root project of a group to be documented.
/// </summary>
// public ProjectDocument? SelectedRootProject { get; private set; }

/// <summary>
/// Creates a new solution.
/// </summary>
/// <param name="path">Location of the solution file.</param>
private Solution(string path)
{
Logger.Debug("Params: [{pathLbl}: {pathValue}]", nameof(path), path);
Dir = path;
}

public static Solution From(string path)
{
if (!Directory.Exists(path)) // Ensure path exists
throw new DirectoryNotFoundException(path);

var solution = new Solution(path);
solution.MakeProjectGraph();

return solution;
}

/// <summary>
/// Creates a dependency graph for each project group.
/// </summary>
/// <returns></returns>
private void MakeProjectGraph()
{
Logger.Trace("Making the project dependency graph.");

// Locate all solution and project files
var projectFiles = Directory.GetFiles(Dir, "*.csproj", SearchOption.AllDirectories);
DependencyGraph = FindRootProjects(projectFiles.ToList())
.ToImmutableArray();
}

/// <summary>
/// Ensures each project file has documentation generation enabled in the .csproj file.
/// </summary>
/// <returns></returns>
public static void EnableDocumentationGeneration(ProjectDocument project)
{
Logger.Trace("Beginning recursive loop to enable documentation generation on all projects.");

ArgumentNullException.ThrowIfNull(project);

project.EnableAllDocumentationGeneration();
}

/// <summary>
/// Builds active project via the property <see cref="SelectedRootProject"/>.
/// </summary>
/// <returns></returns>
public static BuildInstance Build(ProjectDocument project)
{
ArgumentNullException.ThrowIfNull(project);
return new BuildInstance(project)
.Build();
}

/// <summary>
/// Returns all .csproj files that are the root project of a possibly larger project structure.
/// </summary>
/// <returns></returns>
static IEnumerable<ProjectDocument> FindRootProjects(List<string> projectFiles)
{
var projects = new List<ProjectDocument>();

while (projectFiles.Count != 0)
{
var proj = projectFiles.First();

if (!File.Exists(projectFiles.First()))
{
var ex = new FileNotFoundException($"The following project file path does not exist: {proj}");
Logger.Fatal(ex);
throw ex;
}

projects.Add(ProjectDocument.From(proj, projectFiles, projects));
}
return projects.Where(proj => proj.Parent == null).ToArray();
}
}
}
Loading

0 comments on commit 21a4918

Please sign in to comment.