From e08408f6ef837875cbd99afc61c921b4e98550ba Mon Sep 17 00:00:00 2001 From: Matt Ward Date: Wed, 16 May 2012 21:51:20 +0100 Subject: [PATCH] Implement missing parts of EnvDTE Project and ProjectItems to support T4 scaffolding. --- .../Project/Src/EnvDTE/Configuration.cs | 7 +- .../Src/EnvDTE/ConfigurationManager.cs | 7 +- .../Src/EnvDTE/DirectoryProjectItems.cs | 2 +- .../Project/Src/EnvDTE/Project.cs | 30 ++++-- .../Project/Src/EnvDTE/ProjectItem.cs | 1 + .../Project/Src/EnvDTE/ProjectItems.cs | 23 +++-- .../Src/EnvDTE/ProjectItemsInsideProject.cs | 6 ++ .../Project/Src/EnvDTE/ProjectProperty.cs | 54 +++++++++-- .../Test/Src/EnvDTE/ProjectItemTests.cs | 14 +++ .../Test/Src/EnvDTE/ProjectItemsTests.cs | 97 +++++++++++++++++++ .../Test/Src/EnvDTE/ProjectPropertyTests.cs | 59 +++++++++++ .../Test/Src/EnvDTE/ProjectTests.cs | 33 +++++++ .../Test/Src/Helpers/TestableProject.cs | 6 ++ 13 files changed, 309 insertions(+), 30 deletions(-) diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/Configuration.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/Configuration.cs index 021619c919..ada8d24a7b 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/Configuration.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/Configuration.cs @@ -7,12 +7,15 @@ namespace ICSharpCode.PackageManagement.EnvDTE { public class Configuration : MarshalByRefObject { - public Configuration() + Project project; + + public Configuration(Project project) { + this.project = project; } public Properties Properties { - get { throw new NotImplementedException(); } + get { return project.Properties; } } } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ConfigurationManager.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ConfigurationManager.cs index acc21c5ca2..78317fc3f5 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ConfigurationManager.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ConfigurationManager.cs @@ -7,12 +7,15 @@ namespace ICSharpCode.PackageManagement.EnvDTE { public class ConfigurationManager : MarshalByRefObject { - public ConfigurationManager() + Configuration activeConfiguration; + + public ConfigurationManager(Project project) { + activeConfiguration = new Configuration(project); } public Configuration ActiveConfiguration { - get { throw new NotImplementedException(); } + get { return activeConfiguration; } } } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/DirectoryProjectItems.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/DirectoryProjectItems.cs index 5497cbce16..0d76dce23e 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/DirectoryProjectItems.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/DirectoryProjectItems.cs @@ -11,7 +11,7 @@ namespace ICSharpCode.PackageManagement.EnvDTE ProjectItem projectItem; public DirectoryProjectItems(ProjectItem projectItem) - : base(projectItem.ContainingProject, new PackageManagementFileService()) + : base(projectItem.ContainingProject, projectItem, new PackageManagementFileService()) { this.projectItem = projectItem; } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/Project.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/Project.cs index 3114000ee1..bf0cea65b8 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/Project.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/Project.cs @@ -36,7 +36,7 @@ namespace ICSharpCode.PackageManagement.EnvDTE CreateProperties(); Object = new ProjectObject(this); - ProjectItems = new ProjectItems(this, fileService); + ProjectItems = new ProjectItems(this, this, fileService); } public Project() @@ -54,7 +54,7 @@ namespace ICSharpCode.PackageManagement.EnvDTE } public virtual string UniqueName { - get { throw new NotImplementedException(); } + get { return Path.GetFileName(FileName); } } public virtual string FileName { @@ -136,16 +136,24 @@ namespace ICSharpCode.PackageManagement.EnvDTE projectService.RemoveProjectItem(MSBuildProject, referenceItem); } - internal void AddFile(string include) + internal void AddFileUsingPathRelativeToProject(string include) + { + var fileProjectItem = CreateFileProjectItemUsingPathRelativeToProject(include); + projectService.AddProjectItem(MSBuildProject, fileProjectItem); + } + + internal ProjectItem AddFileUsingFullPath(string path) { - var fileProjectItem = CreateFileProjectItem(include); + FileProjectItem fileProjectItem = CreateFileProjectItemUsingFullPath(path); + fileProjectItem.FileName = path; projectService.AddProjectItem(MSBuildProject, fileProjectItem); + return new ProjectItem(this, fileProjectItem); } - FileProjectItem CreateFileProjectItem(string include) + FileProjectItem CreateFileProjectItemUsingPathRelativeToProject(string include) { ItemType itemType = GetDefaultItemType(include); - return CreateFileProjectItem(itemType, include); + return CreateFileProjectItemUsingPathRelativeToProject(itemType, include); } ItemType GetDefaultItemType(string include) @@ -153,13 +161,18 @@ namespace ICSharpCode.PackageManagement.EnvDTE return MSBuildProject.GetDefaultItemType(include); } - FileProjectItem CreateFileProjectItem(ItemType itemType, string include) + FileProjectItem CreateFileProjectItemUsingPathRelativeToProject(ItemType itemType, string include) { var fileProjectItem = new FileProjectItem(MSBuildProject, itemType); fileProjectItem.Include = include; return fileProjectItem; } + FileProjectItem CreateFileProjectItemUsingFullPath(string path) + { + return CreateFileProjectItemUsingPathRelativeToProject(Path.GetFileName(path)); + } + internal IList GetAllPropertyNames() { var names = new List(); @@ -167,6 +180,7 @@ namespace ICSharpCode.PackageManagement.EnvDTE foreach (ProjectPropertyElement propertyElement in MSBuildProject.MSBuildProjectFile.Properties) { names.Add(propertyElement.Name); } + names.Add("OutputFileName"); } return names; } @@ -176,7 +190,7 @@ namespace ICSharpCode.PackageManagement.EnvDTE } public virtual ConfigurationManager ConfigurationManager { - get { throw new NotImplementedException(); } + get { return new ConfigurationManager(this); } } internal virtual string GetLowercaseFileExtension() diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectItem.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectItem.cs index 05d97ff459..0152ec73c2 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectItem.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectItem.cs @@ -108,6 +108,7 @@ namespace ICSharpCode.PackageManagement.EnvDTE public void Delete() { ContainingProject.DeleteFile(projectItem.FileName); + ContainingProject.Save(); } } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectItems.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectItems.cs index 28f882f46a..10fdfef809 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectItems.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectItems.cs @@ -5,6 +5,7 @@ using System; using System.Collections; using System.Collections.Generic; using System.IO; +using System.Linq; namespace ICSharpCode.PackageManagement.EnvDTE { @@ -12,11 +13,13 @@ namespace ICSharpCode.PackageManagement.EnvDTE { Project project; IPackageManagementFileService fileService; + object parent; - public ProjectItems(Project project, IPackageManagementFileService fileService) + public ProjectItems(Project project, object parent, IPackageManagementFileService fileService) { this.project = project; this.fileService = fileService; + this.parent = parent; } public ProjectItems() @@ -24,14 +27,14 @@ namespace ICSharpCode.PackageManagement.EnvDTE } public virtual object Parent { - get { throw new NotImplementedException(); } + get { return parent; } } public virtual void AddFromFileCopy(string filePath) { string include = Path.GetFileName(filePath); CopyFileIntoProject(filePath, include); - project.AddFile(include); + project.AddFileUsingPathRelativeToProject(include); project.Save(); } @@ -72,15 +75,15 @@ namespace ICSharpCode.PackageManagement.EnvDTE internal virtual ProjectItem Item(int index) { - throw new NotImplementedException(); + var items = new ProjectItemsInsideProject(project); + return items.GetItem(index - 1); } public virtual ProjectItem Item(object index) { -// if (index is int) { -// return Item((int)index); -// } -// return null; + if (index is int) { + return Item((int)index); + } return Item(index as string); } @@ -91,7 +94,9 @@ namespace ICSharpCode.PackageManagement.EnvDTE public virtual ProjectItem AddFromFile(string fileName) { - throw new NotImplementedException(); + ProjectItem projectItem = project.AddFileUsingFullPath(fileName); + project.Save(); + return projectItem; } public virtual int Count { diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectItemsInsideProject.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectItemsInsideProject.cs index 70f1bcc735..53ef0fa3ff 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectItemsInsideProject.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectItemsInsideProject.cs @@ -141,5 +141,11 @@ namespace ICSharpCode.PackageManagement.EnvDTE { return GetEnumerator(); } + + internal ProjectItem GetItem(int index) + { + List projectItems = GetProjectItems().ToList(); + return projectItems[index]; + } } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectProperty.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectProperty.cs index a75d4daa83..8f63e63381 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectProperty.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectProperty.cs @@ -2,6 +2,7 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; +using System.IO; using ICSharpCode.SharpDevelop.Project; namespace ICSharpCode.PackageManagement.EnvDTE @@ -18,32 +19,44 @@ namespace ICSharpCode.PackageManagement.EnvDTE protected override object GetValue() { - string value = project.MSBuildProject.GetUnevalatedProperty(Name); + string value = GetMSBuildProjectProperty(Name); if (value != null) { return value; } - if (IsTargetFrameworkMoniker(Name)) { + if (IsTargetFrameworkMoniker()) { return GetTargetFrameworkMoniker(); - } else if (IsFullPath(Name)) { + } else if (IsFullPath()) { return GetFullPath(); + } else if (IsOutputFileName()) { + return GetOutputFileName(); } return EmptyStringIfNull(value); } - bool IsTargetFrameworkMoniker(string name) + string GetMSBuildProjectProperty(string name) { - return IsCaseInsensitiveMatch(name, "TargetFrameworkMoniker"); + return MSBuildProject.GetUnevalatedProperty(name); } - bool IsFullPath(string name) + bool IsTargetFrameworkMoniker() { - return IsCaseInsensitiveMatch(name, "FullPath"); + return IsCaseInsensitiveMatch(Name, "TargetFrameworkMoniker"); + } + + bool IsFullPath() + { + return IsCaseInsensitiveMatch(Name, "FullPath"); + } + + bool IsOutputFileName() + { + return IsCaseInsensitiveMatch(Name, "OutputFileName"); } bool IsCaseInsensitiveMatch(string a, string b) { - return String.Equals(a, b, StringComparison.InvariantCultureIgnoreCase); + return String.Equals(a, b, StringComparison.OrdinalIgnoreCase); } string GetTargetFrameworkMoniker() @@ -61,6 +74,31 @@ namespace ICSharpCode.PackageManagement.EnvDTE return MSBuildProject.Directory; } + string GetOutputFileName() + { + return String.Format("{0}{1}", MSBuildProject.AssemblyName, GetOutputTypeFileExtension()); + } + + string GetOutputTypeFileExtension() + { + string outputTypeProperty = GetMSBuildProjectProperty("OutputType"); + OutputType outputType = GetOutputType(outputTypeProperty); + return CompilableProject.GetExtension(outputType); + } + + OutputType GetOutputType(string outputTypeProperty) + { + if (outputTypeProperty == null) { + return OutputType.Exe; + } + + OutputType outputType = OutputType.Exe; + if (Enum.TryParse(outputTypeProperty, true, out outputType)) { + return outputType; + } + return OutputType.Exe; + } + string EmptyStringIfNull(string value) { if (value != null) { diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectItemTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectItemTests.cs index 55e0d00c63..84e3baf73b 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectItemTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectItemTests.cs @@ -136,5 +136,19 @@ namespace PackageManagement.Tests.EnvDTE Assert.AreEqual(@"d:\projects\myproject\src\program.cs", project.FakeFileService.PathPassedToRemoveFile); } + + [Test] + public void Delete_ProjectItemIsFile_ProjectIsSaved() + { + CreateProjectItems(); + msbuildProject.FileName = @"d:\projects\myproject\myproject.csproj"; + msbuildProject.AddFile(@"src\program.cs"); + ProjectItem directoryItem = projectItems.Item("src"); + ProjectItem fileItem = directoryItem.ProjectItems.Item("program.cs"); + + fileItem.Delete(); + + Assert.IsTrue(msbuildProject.IsSaved); + } } } diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectItemsTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectItemsTests.cs index 23cc83dc26..f451841996 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectItemsTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectItemsTests.cs @@ -331,5 +331,102 @@ namespace PackageManagement.Tests.EnvDTE Assert.AreEqual(1, count); } + + [Test] + public void Parent_GetProjectItemsParentForFileProjectItem_ReturnsFileProjectItem() + { + CreateProjectItems(); + msbuildProject.AddFile("Program.cs"); + + var projectItem = projectItems.Item("program.cs") as DTE.ProjectItem; + object parent = projectItem.ProjectItems.Parent; + + Assert.AreEqual(projectItem, parent); + } + + [Test] + public void Parent_GetProjectItemsParentForDirectoryProjectItem_ReturnsDirectoryProjectItem() + { + CreateProjectItems(); + msbuildProject.AddFile(@"src\Program.cs"); + var projectItem = projectItems.Item("src") as DTE.ProjectItem; + + object parent = projectItem.ProjectItems.Parent; + + Assert.AreEqual(projectItem, parent); + } + + [Test] + public void Item_GetProjectItemByIndex_ReturnsFileInsideProject() + { + CreateProjectItems(); + msbuildProject.AddFile("Program.cs"); + + var projectItem = projectItems.Item(1) as DTE.ProjectItem; + string projectItemName = projectItem.Name; + + Assert.AreEqual("Program.cs", projectItemName); + } + + [Test] + public void AddFromFile_FullFileNameIsInsideProject_FileIsAddedToProject() + { + CreateProjectItems(); + msbuildProject.FileName = @"d:\projects\myproject\myproject.csproj"; + string fileName = @"d:\projects\myproject\tools\test.cs"; + + msbuildProject.ItemTypeToReturnFromGetDefaultItemType = ItemType.Page; + projectItems.AddFromFile(fileName); + + var fileItem = msbuildProject.Items[0] as FileProjectItem; + + Assert.AreEqual(@"tools\test.cs", fileItem.Include); + Assert.AreEqual(@"d:\projects\myproject\tools\test.cs", fileItem.FileName); + Assert.AreEqual(ItemType.Page, fileItem.ItemType); + Assert.AreEqual(msbuildProject, fileItem.Project); + } + + [Test] + public void AddFromFile_FullFileNameIsInsideProject_ProjectIsSaved() + { + CreateProjectItems(); + msbuildProject.FileName = @"d:\projects\myproject\myproject\myproject.csproj"; + string fileName = @"d:\projects\myproject\packages\tools\test.cs"; + + projectItems.AddFromFile(fileName); + + bool saved = msbuildProject.IsSaved; + + Assert.IsTrue(saved); + } + + [Test] + public void AddFromFile_FullFileNameIsInsideProject_ProjectItemReturned() + { + CreateProjectItems(); + msbuildProject.FileName = @"d:\projects\myproject\myproject\myproject.csproj"; + string fileName = @"d:\projects\myproject\tools\test.cs"; + + msbuildProject.ItemTypeToReturnFromGetDefaultItemType = ItemType.Page; + DTE.ProjectItem item = projectItems.AddFromFile(fileName); + + string fullPath = (string)item.Properties.Item("FullPath").Value; + + Assert.AreEqual("test.cs", item.Name); + Assert.AreEqual(@"d:\projects\myproject\tools\test.cs", fullPath); + } + + [Test] + public void AddFromFile_FullFileNameIsInsideProject_FileNameUsedToDetermineProjectItemType() + { + CreateProjectItems(); + msbuildProject.FileName = @"d:\projects\myproject\myproject\myproject.csproj"; + string fileName = @"d:\projects\myproject\tools\test.cs"; + + projectItems.AddFromFile(fileName); + + Assert.AreEqual("test.cs", msbuildProject.FileNamePassedToGetDefaultItemType); + } + } } diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectPropertyTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectPropertyTests.cs index 43d7508f1c..7af44ae698 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectPropertyTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectPropertyTests.cs @@ -152,5 +152,64 @@ namespace PackageManagement.Tests.EnvDTE string expectedFullPath = @"d:\projects\MyProject"; Assert.AreEqual(expectedFullPath, fullPath); } + + [Test] + public void Value_GetOutputFileNameProperty_ReturnsOutputAssemblyFileNameWithoutPath() + { + CreateProperties(); + msbuildProject.AssemblyName = "MyProject"; + msbuildProject.SetProperty("OutputType", "Exe"); + + string fileName = (string)project.Properties.Item("OutputFileName").Value; + + Assert.AreEqual(@"MyProject.exe", fileName); + } + + [Test] + public void Properties_GetOutputFileNamePropertyInLowerCase_ReturnsOutputAssemblyFileNameWithoutPath() + { + CreateProperties(); + msbuildProject.AssemblyName = "MyProject"; + msbuildProject.SetProperty("OutputType", "Library"); + + string fileName = (string)project.Properties.Item("outputfilename").Value; + + Assert.AreEqual(@"MyProject.dll", fileName); + } + + [Test] + public void Properties_GetOutputFileNamePropertyWhenOutputTypeIsMissing_ReturnsOutputAssemblyFileNameWithExeFileExtension() + { + CreateProperties(); + msbuildProject.AssemblyName = "MyProject"; + + string fileName = (string)project.Properties.Item("outputfilename").Value; + + Assert.AreEqual(@"MyProject.exe", fileName); + } + + [Test] + public void Properties_GetOutputFileNamePropertyWhenOutputTypeValueIsInLowerCase_ReturnsOutputAssemblyFileNameWithoutPath() + { + CreateProperties(); + msbuildProject.AssemblyName = "MyProject"; + msbuildProject.SetProperty("OutputType", "winexe"); + + string fileName = (string)project.Properties.Item("OutputFileName").Value; + + Assert.AreEqual(@"MyProject.exe", fileName); + } + + [Test] + public void Properties_GetOutputFileNamePropertyWhenOutputTypeValueIsInvalid_ReturnsOutputAssemblyFileNameWithExeFileExtension() + { + CreateProperties(); + msbuildProject.AssemblyName = "MyProject"; + msbuildProject.SetProperty("OutputType", "invalid"); + + string fileName = (string)project.Properties.Item("OutputFileName").Value; + + Assert.AreEqual(@"MyProject.exe", fileName); + } } } diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectTests.cs index 2141a08845..62a23df6ce 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectTests.cs @@ -132,5 +132,38 @@ namespace PackageManagement.Tests.EnvDTE Assert.AreEqual(String.Empty, kind); } + + [Test] + public void UniqueName_ProjectFileNameHasFullPath_ReturnsProjectFileNameWithoutDirectoryPart() + { + CreateProject(); + msbuildProject.FileName = @"d:\projects\myproject\MyProject.csproj"; + + string name = project.UniqueName; + + Assert.AreEqual("MyProject.csproj", name); + } + + [Test] + public void ProjectItemsParent_ParentOfProjectsProjectItems_ReturnsTheProject() + { + CreateProject(); + + object parent = project.ProjectItems.Parent; + + Assert.AreEqual(project, parent); + } + + [Test] + public void ConfigurationManager_ActiveConfigurationOutputPathProperty_ReturnsOutputPathForProject() + { + CreateProject(); + msbuildProject.SetProperty("OutputPath", @"bin\debug\"); + Configuration activeConfig = project.ConfigurationManager.ActiveConfiguration; + + string outputPath = (string)activeConfig.Properties.Item("OutputPath").Value; + + Assert.AreEqual(@"bin\debug\", outputPath); + } } } diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/TestableProject.cs b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/TestableProject.cs index bf96278fe9..9134ce04da 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/TestableProject.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/TestableProject.cs @@ -11,6 +11,7 @@ namespace PackageManagement.Tests.Helpers public class TestableProject : MSBuildBasedProject { public bool IsSaved; + string assemblyName; public ItemType ItemTypeToReturnFromGetDefaultItemType { get { return TestableProjectBehaviour.ItemTypeToReturnFromGetDefaultItemType; } @@ -61,5 +62,10 @@ namespace PackageManagement.Tests.Helpers ProjectService.AddProjectItem(this, fileProjectItem); return fileProjectItem; } + + public override string AssemblyName { + get { return assemblyName; } + set { assemblyName = value; } + } } }