use vs persistence
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
using Microsoft.VisualStudio.SolutionPersistence.Model;
|
||||
|
||||
namespace SharpIDE.Application.Features.SolutionDiscovery.VsPersistence;
|
||||
|
||||
public class IntermediateSolutionModel
|
||||
{
|
||||
public required string Name { get; set; }
|
||||
public required string FilePath { get; set; }
|
||||
public required List<IntermediateProjectModel> Projects { get; set; }
|
||||
public required List<IntermediateSlnFolderModel> SolutionFolders { get; set; }
|
||||
}
|
||||
|
||||
public class IntermediateSlnFolderModel
|
||||
{
|
||||
public required SolutionFolderModel Model { get; set; }
|
||||
public required List<IntermediateSlnFolderModel> Folders { get; set; }
|
||||
public required List<IntermediateProjectModel> Projects { get; set; }
|
||||
}
|
||||
|
||||
public class IntermediateProjectModel
|
||||
{
|
||||
public required SolutionProjectModel Model { get; set; }
|
||||
public required string FullFilePath { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
namespace SharpIDE.Application.Features.SolutionDiscovery.VsPersistence;
|
||||
|
||||
public class SharpIdeSolutionModel
|
||||
{
|
||||
public required string Name { get; set; }
|
||||
public required string FilePath { get; set; }
|
||||
public required List<SharpIdeProjectModel> Projects { get; set; }
|
||||
public required List<SharpIdeSolutionFolder> Folders { get; set; }
|
||||
}
|
||||
public class SharpIdeSolutionFolder
|
||||
{
|
||||
public required string Name { get; set; }
|
||||
public required List<SharpIdeSolutionFolder> Folders { get; set; }
|
||||
public required List<SharpIdeProjectModel> Projects { get; set; }
|
||||
}
|
||||
public class SharpIdeProjectModel
|
||||
{
|
||||
public required string Name { get; set; }
|
||||
public required string FilePath { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
using Ardalis.GuardClauses;
|
||||
using Microsoft.VisualStudio.SolutionPersistence.Model;
|
||||
using Microsoft.VisualStudio.SolutionPersistence.Serializer;
|
||||
|
||||
namespace SharpIDE.Application.Features.SolutionDiscovery.VsPersistence;
|
||||
|
||||
public class VsPersistenceMapper
|
||||
{
|
||||
public static async Task<SharpIdeSolutionModel> GetSolutionModel(string solutionFilePath, CancellationToken cancellationToken = default)
|
||||
{
|
||||
// This intermediate model is pretty much useless, but I have left it around as we grab the project nodes with it, which we might use later.
|
||||
var intermediateModel = await GetIntermediateModel(solutionFilePath, cancellationToken);
|
||||
|
||||
var solutionName = Path.GetFileName(solutionFilePath);
|
||||
var solutionModel = new SharpIdeSolutionModel
|
||||
{
|
||||
Name = solutionName,
|
||||
FilePath = solutionFilePath,
|
||||
Projects = intermediateModel.Projects.Select(GetSharpIdeProjectModel).ToList(),
|
||||
Folders = intermediateModel.SolutionFolders.Select(s => new SharpIdeSolutionFolder
|
||||
{
|
||||
Name = s.Model.Name,
|
||||
Folders = s.Folders.Select(GetSharpIdeSolutionFolder).ToList(),
|
||||
Projects = s.Projects.Select(GetSharpIdeProjectModel).ToList()
|
||||
}).ToList(),
|
||||
};
|
||||
|
||||
return solutionModel;
|
||||
}
|
||||
private static SharpIdeProjectModel GetSharpIdeProjectModel(IntermediateProjectModel projectModel) => new SharpIdeProjectModel()
|
||||
{
|
||||
Name = projectModel.Model.DisplayName!,
|
||||
FilePath = projectModel.Model.FilePath,
|
||||
};
|
||||
|
||||
private static SharpIdeSolutionFolder GetSharpIdeSolutionFolder(IntermediateSlnFolderModel folderModel) => new SharpIdeSolutionFolder()
|
||||
{
|
||||
Name = folderModel.Model.Name,
|
||||
Folders = folderModel.Folders.Select(GetSharpIdeSolutionFolder).ToList(),
|
||||
Projects = folderModel.Projects.Select(GetSharpIdeProjectModel).ToList()
|
||||
};
|
||||
|
||||
public static async Task<IntermediateSolutionModel> GetIntermediateModel(string solutionFilePath,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var serializer = SolutionSerializers.GetSerializerByMoniker(solutionFilePath);
|
||||
Guard.Against.Null(serializer, nameof(serializer));
|
||||
var vsSolution = await serializer.OpenAsync(solutionFilePath, cancellationToken);
|
||||
|
||||
var rootFolders = vsSolution.SolutionFolders
|
||||
.Where(f => f.Parent is null)
|
||||
.Select(f => BuildFolderTree(f, vsSolution.SolutionFolders, vsSolution.SolutionProjects))
|
||||
.ToList();
|
||||
|
||||
var solutionModel = new IntermediateSolutionModel
|
||||
{
|
||||
Name = Path.GetFileName(solutionFilePath),
|
||||
FilePath = solutionFilePath,
|
||||
Projects = vsSolution.SolutionProjects.Where(p => p.Parent is null).Select(s => new IntermediateProjectModel
|
||||
{
|
||||
Model = s,
|
||||
FullFilePath = Path.GetFullPath(s.FilePath)
|
||||
}).ToList(),
|
||||
SolutionFolders = rootFolders
|
||||
};
|
||||
return solutionModel;
|
||||
}
|
||||
|
||||
private static IntermediateSlnFolderModel BuildFolderTree(SolutionFolderModel folder,
|
||||
IReadOnlyList<SolutionFolderModel> allSolutionFolders, IReadOnlyList<SolutionProjectModel> allSolutionProjects)
|
||||
{
|
||||
var childFolders = allSolutionFolders
|
||||
.Where(f => f.Parent == folder)
|
||||
.Select(f => BuildFolderTree(f, allSolutionFolders, allSolutionProjects))
|
||||
.ToList();
|
||||
|
||||
var projectsInFolder = allSolutionProjects
|
||||
.Where(p => p.Parent == folder)
|
||||
.Select(s => new IntermediateProjectModel
|
||||
{
|
||||
Model = s,
|
||||
FullFilePath = Path.GetFullPath(s.FilePath)
|
||||
})
|
||||
.ToList();
|
||||
|
||||
return new IntermediateSlnFolderModel
|
||||
{
|
||||
Model = folder,
|
||||
Folders = childFolders,
|
||||
Projects = projectsInFolder
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user