Skip to content

Commit

Permalink
Add property indicating if a project can be deployed by Visual Studio (
Browse files Browse the repository at this point in the history
…#55)

Automatically set for .sfproj projects.

Fixes #53
  • Loading branch information
jeffkl authored May 23, 2019
1 parent 951bec9 commit 56de9d5
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 14 deletions.
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Use the following properties and items to customize the generated Solution file.
|-----------------------------|--------------------------------------------------|
| IncludeInSolutionFile | Indicates whether or not a project should be included in a generated Solution file. | `true` or `false` | `true` |
| SlnGenFolders | Indicates whether or not a hierarchy of folders should be created. If `false`, the projects are in a flat list. | `true` or `false` | `true` |
| SlnGenIsDeployable | Indicates whether or not a project is considered deployable by Visual Studio. | `true` or `false` | `false` <br />Service Fabric projects are automatically set to `true` |

| Item | Description |
|-----------------------------|--------------------------------------------------|
Expand Down
14 changes: 7 additions & 7 deletions src/SlnGen.Build.Tasks.UnitTests/SlnFileTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public void LotsOfProjects()
// pick random and shuffled configurations and platforms
List<string> projectConfigurations = configurations.OrderBy(a => Guid.NewGuid()).Take(randomGenerator.Next(1, configurations.Length)).ToList();
List<string> projectPlatforms = platforms.OrderBy(a => Guid.NewGuid()).Take(randomGenerator.Next(1, platforms.Length)).ToList();
projects[i] = new SlnProject(GetTempFileName(), $"Project{i:D6}", Guid.NewGuid(), Guid.NewGuid(), projectConfigurations, projectPlatforms, isMainProject: i == 0);
projects[i] = new SlnProject(GetTempFileName(), $"Project{i:D6}", Guid.NewGuid(), Guid.NewGuid(), projectConfigurations, projectPlatforms, isMainProject: i == 0, isDeployable: false);
}

ValidateProjectInSolution(projects);
Expand All @@ -41,8 +41,8 @@ public void LotsOfProjects()
[Fact]
public void MultipleProjects()
{
SlnProject projectA = new SlnProject(GetTempFileName(), "ProjectA", new Guid("C95D800E-F016-4167-8E1B-1D3FF94CE2E2"), new Guid("88152E7E-47E3-45C8-B5D3-DDB15B2F0435"), new[] { "Debug" }, new[] { "x64" }, isMainProject: true);
SlnProject projectB = new SlnProject(GetTempFileName(), "ProjectB", new Guid("EAD108BE-AC70-41E6-A8C3-450C545FDC0E"), new Guid("F38341C3-343F-421A-AE68-94CD9ADCD32F"), new[] { "Debug" }, new[] { "x64" }, isMainProject: false);
SlnProject projectA = new SlnProject(GetTempFileName(), "ProjectA", new Guid("C95D800E-F016-4167-8E1B-1D3FF94CE2E2"), new Guid("88152E7E-47E3-45C8-B5D3-DDB15B2F0435"), new[] { "Debug" }, new[] { "x64" }, isMainProject: true, isDeployable: false);
SlnProject projectB = new SlnProject(GetTempFileName(), "ProjectB", new Guid("EAD108BE-AC70-41E6-A8C3-450C545FDC0E"), new Guid("F38341C3-343F-421A-AE68-94CD9ADCD32F"), new[] { "Debug" }, new[] { "x64" }, isMainProject: false, isDeployable: false);

ValidateProjectInSolution(projectA, projectB);
}
Expand All @@ -52,9 +52,9 @@ public void NoFolders()
{
SlnProject[] projects =
{
new SlnProject(GetTempFileName(), "ProjectA", new Guid("C95D800E-F016-4167-8E1B-1D3FF94CE2E2"), new Guid("88152E7E-47E3-45C8-B5D3-DDB15B2F0435"), new[] { "Debug" }, new[] { "x64" }, isMainProject: true),
new SlnProject(GetTempFileName(), "ProjectB", new Guid("EAD108BE-AC70-41E6-A8C3-450C545FDC0E"), new Guid("F38341C3-343F-421A-AE68-94CD9ADCD32F"), new[] { "Debug" }, new[] { "x64" }, isMainProject: false),
new SlnProject(GetTempFileName(), "ProjectC", new Guid("00C5B0C0-E19C-48C5-818D-E8CD4FA2A915"), new Guid("F38341C3-343F-421A-AE68-94CD9ADCD32F"), new[] { "Debug" }, new[] { "x64" }, isMainProject: false)
new SlnProject(GetTempFileName(), "ProjectA", new Guid("C95D800E-F016-4167-8E1B-1D3FF94CE2E2"), new Guid("88152E7E-47E3-45C8-B5D3-DDB15B2F0435"), new[] { "Debug" }, new[] { "x64" }, isMainProject: true, isDeployable: false),
new SlnProject(GetTempFileName(), "ProjectB", new Guid("EAD108BE-AC70-41E6-A8C3-450C545FDC0E"), new Guid("F38341C3-343F-421A-AE68-94CD9ADCD32F"), new[] { "Debug" }, new[] { "x64" }, isMainProject: false, isDeployable: false),
new SlnProject(GetTempFileName(), "ProjectC", new Guid("00C5B0C0-E19C-48C5-818D-E8CD4FA2A915"), new Guid("F38341C3-343F-421A-AE68-94CD9ADCD32F"), new[] { "Debug" }, new[] { "x64" }, isMainProject: false, isDeployable: false)
};

ValidateProjectInSolution((s, p) => p.ParentProjectGuid.ShouldBe(null), projects, false);
Expand All @@ -79,7 +79,7 @@ public void SaveToCustomLocationCreatesDirectory()
[Fact]
public void SingleProject()
{
SlnProject projectA = new SlnProject(GetTempFileName(), "ProjectA", new Guid("C95D800E-F016-4167-8E1B-1D3FF94CE2E2"), new Guid("88152E7E-47E3-45C8-B5D3-DDB15B2F0435"), new[] { "Debug" }, new[] { "x64" }, isMainProject: true);
SlnProject projectA = new SlnProject(GetTempFileName(), "ProjectA", new Guid("C95D800E-F016-4167-8E1B-1D3FF94CE2E2"), new Guid("88152E7E-47E3-45C8-B5D3-DDB15B2F0435"), new[] { "Debug" }, new[] { "x64" }, isMainProject: true, isDeployable: false);

ValidateProjectInSolution(projectA);
}
Expand Down
8 changes: 4 additions & 4 deletions src/SlnGen.Build.Tasks.UnitTests/SlnHierarchyTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ public void HierarchyIsCorrectlyFormed()

List<SlnProject> projects = new List<SlnProject>
{
new SlnProject(@"D:\foo\bar\baz\baz.csproj", "baz", Guid.NewGuid(), SlnProject.DefaultLegacyProjectTypeGuid, configurations, platforms, false),
new SlnProject(@"D:\foo\bar\baz1\baz1.csproj", "baz1", Guid.NewGuid(), SlnProject.DefaultLegacyProjectTypeGuid, configurations, platforms, false),
new SlnProject(@"D:\foo\bar\baz2\baz2.csproj", "baz2", Guid.NewGuid(), SlnProject.DefaultLegacyProjectTypeGuid, configurations, platforms, false),
new SlnProject(@"D:\foo\bar1\bar1.csproj", "bar1", Guid.NewGuid(), SlnProject.DefaultLegacyProjectTypeGuid, configurations, platforms, false)
new SlnProject(@"D:\foo\bar\baz\baz.csproj", "baz", Guid.NewGuid(), SlnProject.DefaultLegacyProjectTypeGuid, configurations, platforms, false, isDeployable: false),
new SlnProject(@"D:\foo\bar\baz1\baz1.csproj", "baz1", Guid.NewGuid(), SlnProject.DefaultLegacyProjectTypeGuid, configurations, platforms, false, isDeployable: false),
new SlnProject(@"D:\foo\bar\baz2\baz2.csproj", "baz2", Guid.NewGuid(), SlnProject.DefaultLegacyProjectTypeGuid, configurations, platforms, false, isDeployable: false),
new SlnProject(@"D:\foo\bar1\bar1.csproj", "bar1", Guid.NewGuid(), SlnProject.DefaultLegacyProjectTypeGuid, configurations, platforms, false, isDeployable: false)
};

SlnHierarchy hierarchy = new SlnHierarchy(projects);
Expand Down
31 changes: 30 additions & 1 deletion src/SlnGen.Build.Tasks.UnitTests/SlnProjectTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,15 @@ public void GetProjectTypeGuidLegacyProject(string extension)
case "":
actualProject.ProjectTypeGuid.ShouldBe(SlnProject.DefaultLegacyProjectTypeGuid);
break;

case ".csproj":
actualProject.ProjectTypeGuid.ShouldBe(new Guid("FAE04EC0-301F-11D3-BF4B-00C04F79EFBC"));
break;

case ".vbproj":
actualProject.ProjectTypeGuid.ShouldBe(new Guid("F184B08F-C81C-45F6-A57F-5ABD9991F28F"));
break;

default:
actualProject.ProjectTypeGuid.ShouldBe(SlnProject.KnownProjectTypeGuids[extension]);
break;
Expand All @@ -121,18 +124,34 @@ public void GetProjectTypeGuidSdkProject(string extension)
case "":
actualProject.ProjectTypeGuid.ShouldBe(SlnProject.DefaultNetSdkProjectTypeGuid);
break;

case ".csproj":
actualProject.ProjectTypeGuid.ShouldBe(new Guid("9A19103F-16F7-4668-BE54-9A1E7A4F7556"));
break;

case ".vbproj":
actualProject.ProjectTypeGuid.ShouldBe(new Guid("778DAE3C-4631-46EA-AA77-85C1314464D9"));
break;

default:
actualProject.ProjectTypeGuid.ShouldBe(SlnProject.KnownProjectTypeGuids[extension]);
break;
}
}

[Theory]
[InlineData("true", ".csproj", true)]
[InlineData("false", ".csproj", false)]
[InlineData(null, ".csproj", false)]
[InlineData(null, ".sfproj", true)]
[InlineData("false", ".sfproj", false)]
public void IsDeployable(string isDeployable, string projectExtension, bool expected)
{
SlnProject project = CreateAndValidateProject(extension: projectExtension, isDeployable: isDeployable);

project.IsDeployable.ShouldBe(expected);
}

[Theory]
[InlineData(true)]
[InlineData(false)]
Expand Down Expand Up @@ -179,8 +198,18 @@ public void UseFileName()
CreateAndValidateProject(expectedGuid: "{DE681393-7151-459D-862C-918CCD2CB371}");
}

private SlnProject CreateAndValidateProject(bool isMainProject = false, string expectedGuid = null, string expectedName = null, string extension = ".csproj", IDictionary<string, string> globalProperties = null)
private SlnProject CreateAndValidateProject(bool isMainProject = false, string expectedGuid = null, string expectedName = null, string extension = ".csproj", IDictionary<string, string> globalProperties = null, string isDeployable = null)
{
if (!string.IsNullOrWhiteSpace(isDeployable))
{
if (globalProperties == null)
{
globalProperties = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
}

globalProperties["SlnGenIsDeployable"] = isDeployable;
}

Project expectedProject = CreateProject(expectedGuid, expectedName, extension, globalProperties);

SlnProject actualProject = SlnProject.FromProject(expectedProject, new Dictionary<string, Guid>(), isMainProject);
Expand Down
4 changes: 4 additions & 0 deletions src/SlnGen.Build.Tasks/Internal/SlnFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,10 @@ public void Save(TextWriter writer, bool useFolders)
{
writer.WriteLine($@" {project.ProjectGuid.ToSolutionString()}.{configuration}|{platform}.ActiveCfg = {configuration}|{platform}");
writer.WriteLine($@" {project.ProjectGuid.ToSolutionString()}.{configuration}|{platform}.Build.0 = {configuration}|{platform}");
if (project.IsDeployable)
{
writer.WriteLine($@" {project.ProjectGuid.ToSolutionString()}.{configuration}|{platform}.Deploy.0 = {configuration}|{platform}");
}
}
}
}
Expand Down
22 changes: 20 additions & 2 deletions src/SlnGen.Build.Tasks/Internal/SlnProject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,13 @@ internal sealed class SlnProject
[".wixproj"] = new Guid("930C7802-8A8C-48F9-8165-68863BCCD9DD")
};

public SlnProject([NotNull] string fullPath, [NotNull] string name, Guid projectGuid, Guid projectTypeGuid, [NotNull] IEnumerable<string> configurations, [NotNull] IEnumerable<string> platforms, bool isMainProject)
public SlnProject([NotNull] string fullPath, [NotNull] string name, Guid projectGuid, Guid projectTypeGuid, [NotNull] IEnumerable<string> configurations, [NotNull] IEnumerable<string> platforms, bool isMainProject, bool isDeployable)
{
FullPath = fullPath ?? throw new ArgumentNullException(nameof(fullPath));
Name = name ?? throw new ArgumentNullException(nameof(name));
ProjectGuid = projectGuid;
ProjectTypeGuid = projectTypeGuid;
IsDeployable = isDeployable;
IsMainProject = isMainProject;
Configurations = configurations;
Platforms = platforms;
Expand All @@ -68,6 +69,8 @@ public SlnProject([NotNull] string fullPath, [NotNull] string name, Guid project

public string FullPath { get; }

public bool IsDeployable { get; }

public bool IsMainProject { get; }

public string Name { get; }
Expand Down Expand Up @@ -109,7 +112,22 @@ public static SlnProject FromProject([NotNull] Project project, [NotNull] IReadO
throw new FormatException($"property ProjectGuid has an invalid format in {project.FullPath}");
}

return new SlnProject(project.FullPath, name, projectGuid, projectTypeGuid, configurations, platforms, isMainProject);
string isDeployableStr = project.GetPropertyValue("SlnGenIsDeployable");

bool isDeployable = false;

string projectFileExtension = Path.GetExtension(project.FullPath);

if (string.IsNullOrWhiteSpace(isDeployableStr) && !string.IsNullOrWhiteSpace(projectFileExtension) && projectFileExtension.Equals(".sfproj", StringComparison.OrdinalIgnoreCase))
{
isDeployable = true;
}
else
{
isDeployable = isDeployableStr.Equals("true", StringComparison.OrdinalIgnoreCase);
}

return new SlnProject(project.FullPath, name, projectGuid, projectTypeGuid, configurations, platforms, isMainProject, isDeployable);
}

/// <summary>
Expand Down

0 comments on commit 56de9d5

Please sign in to comment.