Skip to content

Commit

Permalink
Add TypeMapping and actually using SolutionFolder now
Browse files Browse the repository at this point in the history
Closes #3
  • Loading branch information
wgnf committed Sep 6, 2021
1 parent 73d2b50 commit cd9f284
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 41 deletions.
73 changes: 50 additions & 23 deletions src/SlnParser.Tests/IntegrationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using SlnParser.Contracts;
using System.ComponentModel;
using System.IO;
using System.Linq;
using Xunit;

namespace SlnParser.Tests
Expand Down Expand Up @@ -49,59 +50,85 @@ public void Should_Be_Able_To_Parse_SlnParser_Solution_Correctly()
.Should()
.HaveCount(3);

// 1. Project - Classlib
// 1. Project - ClassLib
solution
.Projects[0]
.Projects
.ElementAt(0)
.Should()
.BeOfType<SolutionProject>();
solution
.Projects[0]
.Projects
.ElementAt(0)
.Name
.Should()
.Be("SlnParser");
solution
.Projects[0]
.Projects
.ElementAt(0)
.As<SolutionProject>()
.File
.FullName
.Should()
.Contain(@"SlnParser\SlnParser.csproj");
solution
.Projects
.ElementAt(0)
.ProjectType
.Should()
.Be(ProjectType.CSharpClassLibrary);

// TODO: Will be implemented later on
// 2. Project - Solution Folder
//solution
// .Projects[1]
// .Should()
// .BeOfType<SolutionFolder>();
//solution
// .Projects[1]
// .Name
// .Should()
// .Be("Solution Items");
//solution
// .Projects[1]
// .As<SolutionFolder>()
// .Projects
// .Should()
// .BeEmpty();
solution
.Projects
.ElementAt(1)
.Should()
.BeOfType<SolutionFolder>();
solution
.Projects
.ElementAt(1)
.Name
.Should()
.Be("Solution Items");
solution
.Projects
.ElementAt(1)
.As<SolutionFolder>()
.Projects
.Should()
.BeEmpty();
solution
.Projects
.ElementAt(1)
.ProjectType
.Should()
.Be(ProjectType.SolutionFolder);

// 3. Project - Test Project
solution
.Projects[2]
.Projects
.ElementAt(2)
.Should()
.BeOfType<SolutionProject>();
solution
.Projects[2]
.Projects
.ElementAt(2)
.Name
.Should()
.Be("SlnParser.Tests");
solution
.Projects[2]
.Projects
.ElementAt(2)
.As<SolutionProject>()
.File
.FullName
.Should()
.Contain(@"SlnParser.Tests\SlnParser.Tests.csproj");
solution
.Projects
.ElementAt(2)
.ProjectType
.Should()
.Be(ProjectType.CSharpClassLibrary);
}

[Fact]
Expand Down
9 changes: 9 additions & 0 deletions src/SlnParser/Contracts/Helper/IProjectTypeMapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System;

namespace SlnParser.Contracts.Helper
{
public interface IProjectTypeMapper
{
ProjectType Map(Guid typeGuid);
}
}
12 changes: 11 additions & 1 deletion src/SlnParser/Contracts/ProjectType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ public enum ProjectType
/// <summary>
/// The <see cref="ProjectType"/> is not known
/// </summary>
Unknown
Unknown,

/// <summary>
/// A Solution Folder
/// </summary>
SolutionFolder,

/// <summary>
/// A C# Class Library
/// </summary>
CSharpClassLibrary
}
}
2 changes: 1 addition & 1 deletion src/SlnParser/Contracts/Solution.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@ public Solution()
/// <summary>
/// The <see cref="IProject"/>s contained in the solution
/// </summary>
public IList<IProject> Projects { get; set; }
public IReadOnlyCollection<IProject> Projects { get; internal set; }
}
}
8 changes: 3 additions & 5 deletions src/SlnParser/Contracts/SolutionFolder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,17 @@ public class SolutionFolder : IProject
/// <param name="name">The name</param>
/// <param name="projectTypeGuid">The project-type id</param>
/// <param name="projectType">The well-known project-type</param>
/// <param name="projects">The contained <see cref="IProject"/>s</param>
public SolutionFolder(
Guid id,
string name,
Guid projectTypeGuid,
ProjectType projectType,
IList<IProject> projects)
ProjectType projectType)
{
Id = id;
Name = name;
ProjectTypeGuid = projectTypeGuid;
ProjectType = projectType;
Projects = new ReadOnlyCollection<IProject>(projects);
Projects = new Collection<IProject>();
}

/// <inheritdoc/>
Expand All @@ -46,6 +44,6 @@ public SolutionFolder(
/// <summary>
/// The contained <see cref="IProject"/>s in the Solution Folder
/// </summary>
public IReadOnlyCollection<IProject> Projects { get; }
public IReadOnlyCollection<IProject> Projects { get; internal set; }
}
}
48 changes: 37 additions & 11 deletions src/SlnParser/Helper/ProjectParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,45 @@
using SlnParser.Contracts.Helper;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;

namespace SlnParser.Helper
{
internal class ProjectParser : IProjectParser
{
private readonly IProjectTypeMapper _projectTypeMapper;

public ProjectParser()
{
_projectTypeMapper = new ProjectTypeMapper();
}

public void Enrich(Solution solution, IEnumerable<string> fileContents)
{
if (solution == null) throw new ArgumentNullException(nameof(solution));
if (fileContents == null) throw new ArgumentNullException(nameof(fileContents));

var flatProjectList = new List<IProject>();
var flatProjectList = GetProjectsFlat(fileContents);
solution.Projects = flatProjectList.ToList().AsReadOnly();
}

private IEnumerable<IProject> GetProjectsFlat(IEnumerable<string> fileContents)
{
var flatProjectList = new Collection<IProject>();
foreach (var line in fileContents)
ProcessLine(line, flatProjectList);

solution.Projects = flatProjectList;
return flatProjectList;
}
private static void ProcessLine(string line, IList<IProject> flatProjectList)

private void ProcessLine(string line, ICollection<IProject> flatProjectList)
{
if (!line.StartsWith("Project(\"{")) return;

// c.f.: regexr.com/650df
// c.f.: https://regexr.com/650df
const string pattern = @"Project\(""\{(?<projectTypeGuid>[A-Za-z0-9\-]+)\}""\) = ""(?<projectName>.+)"", ""(?<projectPath>.+)"", ""\{(?<projectGuid>[A-Za-z0-9\-]+)\}";
var match = Regex.Match(line, pattern);
if (!match.Success) return;
Expand All @@ -38,12 +54,22 @@ private static void ProcessLine(string line, IList<IProject> flatProjectList)
var projectGuid = Guid.Parse(projectGuidString);
var projectFile = new FileInfo(projectPath);

var project = new SolutionProject(
projectGuid,
projectName,
projectTypeGuid,
ProjectType.Unknown,
projectFile);
var projectType = _projectTypeMapper.Map(projectTypeGuid);

IProject project;
if (projectType == ProjectType.SolutionFolder)
project = new SolutionFolder(
projectGuid,
projectName,
projectTypeGuid,
projectType);
else
project = new SolutionProject(
projectGuid,
projectName,
projectTypeGuid,
projectType,
projectFile);

flatProjectList.Add(project);
}
Expand Down
34 changes: 34 additions & 0 deletions src/SlnParser/Helper/ProjectTypeMapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using SlnParser.Contracts;
using SlnParser.Contracts.Helper;
using System;
using System.Collections.Generic;

namespace SlnParser.Helper
{
public class ProjectTypeMapper : IProjectTypeMapper
{
private readonly IDictionary<Guid, ProjectType> _mapping;

public ProjectTypeMapper()
{
_mapping = GetMapping();
}

public ProjectType Map(Guid typeGuid)
{
return _mapping.ContainsKey(typeGuid)
? _mapping[typeGuid]
: ProjectType.Unknown;
}

private static IDictionary<Guid, ProjectType> GetMapping()
{
return new Dictionary<Guid, ProjectType>
{
{new Guid("2150E333-8FDC-42A3-9474-1A3956D46DE8"), ProjectType.SolutionFolder},
{new Guid("FAE04EC0-301F-11D3-BF4B-00C04F79EFBC"), ProjectType.CSharpClassLibrary},
{new Guid("9A19103F-16F7-4668-BE54-9A1E7A4F7556"), ProjectType.CSharpClassLibrary}
};
}
}
}

0 comments on commit cd9f284

Please sign in to comment.