dotnet-remove-p2p implementation complete - no tests

This commit is contained in:
Krzysztof Wicher 2016-11-29 14:00:44 -08:00
parent 6a703ffa73
commit 78d95b423e
4 changed files with 68 additions and 7 deletions

View file

@ -24,5 +24,7 @@ namespace Microsoft.DotNet.Tools
public const string ReferenceDoesNotExist = "Reference `{0}` does not exist."; public const string ReferenceDoesNotExist = "Reference `{0}` does not exist.";
public const string SpecifyAtLeastOneReferenceToAdd = "You must specify at least one reference to add."; public const string SpecifyAtLeastOneReferenceToAdd = "You must specify at least one reference to add.";
public const string SpecifyAtLeastOneReferenceToRemove = "You must specify at least one reference to remove."; public const string SpecifyAtLeastOneReferenceToRemove = "You must specify at least one reference to remove.";
public const string ProjectReferenceCouldNotBeFound = "Project reference `{0}` could not be found.";
public const string ProjectReferenceRemoved = "Project reference `{0}` removed.";
} }
} }

View file

@ -14,6 +14,8 @@ namespace Microsoft.DotNet.Tools
{ {
internal static class P2PHelpers internal static class P2PHelpers
{ {
const string ProjectItemElementType = "ProjectReference";
public static void EnsureAllReferencesExist(List<string> references) public static void EnsureAllReferencesExist(List<string> references)
{ {
var notExisting = new List<string>(); var notExisting = new List<string>();
@ -45,10 +47,9 @@ namespace Microsoft.DotNet.Tools
return path.Replace('/', '\\'); return path.Replace('/', '\\');
} }
public static int AddProjectToProjectReference(ProjectRootElement root, string framework, IEnumerable<string> refs) public static int AddProjectToProjectReferences(ProjectRootElement root, string framework, IEnumerable<string> refs)
{ {
int numberOfAddedReferences = 0; int numberOfAddedReferences = 0;
const string ProjectItemElementType = "ProjectReference";
ProjectItemGroupElement itemGroup = root.FindUniformOrCreateItemGroupWithCondition(ProjectItemElementType, framework); ProjectItemGroupElement itemGroup = root.FindUniformOrCreateItemGroupWithCondition(ProjectItemElementType, framework);
foreach (var @ref in refs.Select((r) => NormalizeSlashesForMsbuild(r))) foreach (var @ref in refs.Select((r) => NormalizeSlashesForMsbuild(r)))
@ -68,9 +69,67 @@ namespace Microsoft.DotNet.Tools
return numberOfAddedReferences; return numberOfAddedReferences;
} }
public static int RemoveProjectToProjectReference(ProjectRootElement root, string framework, IEnumerable<string> refs) public static int RemoveProjectToProjectReferences(MsbuildProject msbuildProject, string framework, IEnumerable<string> refs)
{ {
throw new NotImplementedException(); int totalNumberOfRemovedReferences = 0;
foreach (var @ref in refs)
{
totalNumberOfRemovedReferences += RemoveProjectToProjectReferenceAlternatives(msbuildProject, framework, @ref);
}
return totalNumberOfRemovedReferences;
}
private static int RemoveProjectToProjectReferenceAlternatives(MsbuildProject msbuildProject, string framework, string reference)
{
int numberOfRemovedRefs = 0;
foreach (var r in GetIncludeAlternativesForRemoval(msbuildProject, reference))
{
foreach (var existingItem in msbuildProject.Project.FindExistingItemsWithCondition(framework, r))
{
ProjectElementContainer itemGroup = existingItem.Parent;
itemGroup.RemoveChild(existingItem);
if (itemGroup.Children.Count == 0)
{
itemGroup.Parent.RemoveChild(itemGroup);
}
numberOfRemovedRefs++;
Reporter.Output.WriteLine(string.Format(LocalizableStrings.ProjectReferenceRemoved, r));
}
}
if (numberOfRemovedRefs == 0)
{
Reporter.Output.WriteLine(string.Format(LocalizableStrings.ProjectReferenceCouldNotBeFound, reference));
}
return numberOfRemovedRefs;
}
// Easiest way to explain rationale for this function is on the example. Let's consider following directory structure:
// .../a/b/p.proj <project>
// .../a/d/ref.proj <reference>
// .../a/e/f/ <current working directory>
// Project = /some/path/a/b/p.proj
//
// We do not know the format of passed reference so
// directories to consider for removal are following:
// - full path to ref.proj [/some/path/a/d/ref.proj]
// - string which is passed as reference is relative to project [../d/ref.proj]
// - string which is passed as reference is relative to current dir [../../d/ref.proj]
private static IEnumerable<string> GetIncludeAlternativesForRemoval(MsbuildProject msbuildProject, string reference)
{
// We do not care about duplicates in case when i.e. reference is already full path
var ret = new List<string>();
ret.Add(reference);
string fullPath = Path.GetFullPath(reference);
ret.Add(fullPath);
ret.Add(PathUtility.GetRelativePath(msbuildProject.ProjectDirectory, fullPath));
return ret;
} }
} }
} }

View file

@ -60,7 +60,7 @@ namespace Microsoft.DotNet.Tools.Add.ProjectToProjectReference
P2PHelpers.ConvertPathsToRelative(msbuildProj.ProjectDirectory, ref references); P2PHelpers.ConvertPathsToRelative(msbuildProj.ProjectDirectory, ref references);
} }
int numberOfAddedReferences = P2PHelpers.AddProjectToProjectReference( int numberOfAddedReferences = P2PHelpers.AddProjectToProjectReferences(
msbuildProj.Project, msbuildProj.Project,
frameworkOption.Value(), frameworkOption.Value(),
references); references);

View file

@ -50,8 +50,8 @@ namespace Microsoft.DotNet.Tools.Remove.ProjectToProjectReference
List<string> references = app.RemainingArguments; List<string> references = app.RemainingArguments;
int numberOfRemovedReferences = P2PHelpers.RemoveProjectToProjectReference( int numberOfRemovedReferences = P2PHelpers.RemoveProjectToProjectReferences(
msbuildProj.Project, msbuildProj,
frameworkOption.Value(), frameworkOption.Value(),
references); references);