Remove P2PHelpers and simplify constructors in MsbuildProject
This commit is contained in:
parent
26442c8769
commit
1f56e84b7e
5 changed files with 126 additions and 156 deletions
|
@ -14,22 +14,15 @@ namespace Microsoft.DotNet.Tools
|
|||
{
|
||||
internal class MsbuildProject
|
||||
{
|
||||
const string ProjectItemElementType = "ProjectReference";
|
||||
|
||||
public ProjectRootElement Project { get; private set; }
|
||||
public string ProjectPath { get; private set; }
|
||||
public string ProjectDirectory { get; private set; }
|
||||
|
||||
private MsbuildProject(ProjectRootElement project, string projectPath, string projectDirectory)
|
||||
private MsbuildProject(ProjectRootElement project)
|
||||
{
|
||||
Project = project;
|
||||
ProjectPath = projectPath;
|
||||
ProjectDirectory = PathUtility.EnsureTrailingSlash(projectDirectory);
|
||||
}
|
||||
|
||||
private MsbuildProject(ProjectRootElement project, string projectPath)
|
||||
{
|
||||
Project = project;
|
||||
ProjectPath = projectPath;
|
||||
ProjectDirectory = PathUtility.EnsureTrailingSlash(new FileInfo(projectPath).DirectoryName);
|
||||
ProjectDirectory = PathUtility.EnsureTrailingSlash(Project.DirectoryPath);
|
||||
}
|
||||
|
||||
public static MsbuildProject FromFileOrDirectory(string fileOrDirectory)
|
||||
|
@ -57,7 +50,7 @@ namespace Microsoft.DotNet.Tools
|
|||
throw new GracefulException(LocalizableStrings.ProjectIsInvalid, projectPath);
|
||||
}
|
||||
|
||||
return new MsbuildProject(project, Path.GetFullPath(projectPath));
|
||||
return new MsbuildProject(project);
|
||||
}
|
||||
|
||||
public static MsbuildProject FromDirectory(string projectDirectory)
|
||||
|
@ -66,7 +59,6 @@ namespace Microsoft.DotNet.Tools
|
|||
try
|
||||
{
|
||||
dir = new DirectoryInfo(projectDirectory);
|
||||
projectDirectory = dir.FullName;
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
|
@ -102,7 +94,122 @@ namespace Microsoft.DotNet.Tools
|
|||
throw new GracefulException(LocalizableStrings.FoundInvalidProject, projectFile.FullName);
|
||||
}
|
||||
|
||||
return new MsbuildProject(project, projectFile.FullName, projectDirectory);
|
||||
return new MsbuildProject(project);
|
||||
}
|
||||
|
||||
public int AddProjectToProjectReferences(string framework, IEnumerable<string> refs)
|
||||
{
|
||||
int numberOfAddedReferences = 0;
|
||||
|
||||
ProjectItemGroupElement itemGroup = Project.FindUniformOrCreateItemGroupWithCondition(ProjectItemElementType, framework);
|
||||
foreach (var @ref in refs.Select((r) => NormalizeSlashes(r)))
|
||||
{
|
||||
if (Project.HasExistingItemWithCondition(framework, @ref))
|
||||
{
|
||||
Reporter.Output.WriteLine(string.Format(LocalizableStrings.ProjectAlreadyHasAreference, @ref));
|
||||
continue;
|
||||
}
|
||||
|
||||
numberOfAddedReferences++;
|
||||
itemGroup.AppendChild(Project.CreateItemElement(ProjectItemElementType, @ref));
|
||||
|
||||
Reporter.Output.WriteLine(string.Format(LocalizableStrings.ReferenceAddedToTheProject, @ref));
|
||||
}
|
||||
|
||||
return numberOfAddedReferences;
|
||||
}
|
||||
|
||||
public int RemoveProjectToProjectReferences(string framework, IEnumerable<string> refs)
|
||||
{
|
||||
int totalNumberOfRemovedReferences = 0;
|
||||
|
||||
foreach (var @ref in refs)
|
||||
{
|
||||
totalNumberOfRemovedReferences += RemoveProjectToProjectReferenceAlternatives(framework, @ref);
|
||||
}
|
||||
|
||||
return totalNumberOfRemovedReferences;
|
||||
}
|
||||
|
||||
public void ConvertPathsToRelative(ref List<string> references)
|
||||
{
|
||||
references = references.Select((r) => PathUtility.GetRelativePath(ProjectDirectory, Path.GetFullPath(r))).ToList();
|
||||
}
|
||||
|
||||
public static string NormalizeSlashes(string path)
|
||||
{
|
||||
return path.Replace('/', '\\');
|
||||
}
|
||||
|
||||
public static void EnsureAllReferencesExist(List<string> references)
|
||||
{
|
||||
var notExisting = new List<string>();
|
||||
foreach (var r in references)
|
||||
{
|
||||
if (!File.Exists(r))
|
||||
{
|
||||
notExisting.Add(r);
|
||||
}
|
||||
}
|
||||
|
||||
if (notExisting.Count > 0)
|
||||
{
|
||||
throw new GracefulException(
|
||||
string.Join(
|
||||
Environment.NewLine,
|
||||
notExisting.Select((r) => string.Format(LocalizableStrings.ReferenceDoesNotExist, r))));
|
||||
}
|
||||
}
|
||||
|
||||
private int RemoveProjectToProjectReferenceAlternatives(string framework, string reference)
|
||||
{
|
||||
int numberOfRemovedRefs = 0;
|
||||
foreach (var r in GetIncludeAlternativesForRemoval(reference))
|
||||
{
|
||||
foreach (var existingItem in 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
|
||||
// path references 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 IEnumerable<string> GetIncludeAlternativesForRemoval(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(ProjectDirectory, fullPath));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// There is ProjectRootElement.TryOpen but it does not work as expected
|
||||
|
|
|
@ -95,7 +95,7 @@ namespace Microsoft.DotNet.Tools
|
|||
|
||||
private static string NormalizeIncludeForComparison(string include)
|
||||
{
|
||||
return P2PHelpers.NormalizeSlashesForMsbuild(include.ToLower());
|
||||
return MsbuildProject.NormalizeSlashes(include.ToLower());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,135 +0,0 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Microsoft.Build.Construction;
|
||||
using Microsoft.Build.Evaluation;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.DotNet.Tools
|
||||
{
|
||||
internal static class P2PHelpers
|
||||
{
|
||||
const string ProjectItemElementType = "ProjectReference";
|
||||
|
||||
public static void EnsureAllReferencesExist(List<string> references)
|
||||
{
|
||||
var notExisting = new List<string>();
|
||||
foreach (var r in references)
|
||||
{
|
||||
if (!File.Exists(r))
|
||||
{
|
||||
notExisting.Add(r);
|
||||
}
|
||||
}
|
||||
|
||||
if (notExisting.Count > 0)
|
||||
{
|
||||
throw new GracefulException(
|
||||
string.Join(
|
||||
Environment.NewLine,
|
||||
notExisting.Select((r) => string.Format(LocalizableStrings.ReferenceDoesNotExist, r))));
|
||||
}
|
||||
}
|
||||
|
||||
public static void ConvertPathsToRelative(string root, ref List<string> references)
|
||||
{
|
||||
root = PathUtility.EnsureTrailingSlash(Path.GetFullPath(root));
|
||||
references = references.Select((r) => PathUtility.GetRelativePath(root, Path.GetFullPath(r))).ToList();
|
||||
}
|
||||
|
||||
public static string NormalizeSlashesForMsbuild(string path)
|
||||
{
|
||||
return path.Replace('/', '\\');
|
||||
}
|
||||
|
||||
public static int AddProjectToProjectReferences(ProjectRootElement root, string framework, IEnumerable<string> refs)
|
||||
{
|
||||
int numberOfAddedReferences = 0;
|
||||
|
||||
ProjectItemGroupElement itemGroup = root.FindUniformOrCreateItemGroupWithCondition(ProjectItemElementType, framework);
|
||||
foreach (var @ref in refs.Select((r) => NormalizeSlashesForMsbuild(r)))
|
||||
{
|
||||
if (root.HasExistingItemWithCondition(framework, @ref))
|
||||
{
|
||||
Reporter.Output.WriteLine(string.Format(LocalizableStrings.ProjectAlreadyHasAreference, @ref));
|
||||
continue;
|
||||
}
|
||||
|
||||
numberOfAddedReferences++;
|
||||
itemGroup.AppendChild(root.CreateItemElement(ProjectItemElementType, @ref));
|
||||
|
||||
Reporter.Output.WriteLine(string.Format(LocalizableStrings.ReferenceAddedToTheProject, @ref));
|
||||
}
|
||||
|
||||
return numberOfAddedReferences;
|
||||
}
|
||||
|
||||
public static int RemoveProjectToProjectReferences(MsbuildProject msbuildProject, string framework, IEnumerable<string> refs)
|
||||
{
|
||||
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
|
||||
// path references 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -56,12 +56,11 @@ namespace Microsoft.DotNet.Tools.Add.ProjectToProjectReference
|
|||
List<string> references = app.RemainingArguments;
|
||||
if (!forceOption.HasValue())
|
||||
{
|
||||
P2PHelpers.EnsureAllReferencesExist(references);
|
||||
P2PHelpers.ConvertPathsToRelative(msbuildProj.ProjectDirectory, ref references);
|
||||
MsbuildProject.EnsureAllReferencesExist(references);
|
||||
msbuildProj.ConvertPathsToRelative(ref references);
|
||||
}
|
||||
|
||||
int numberOfAddedReferences = P2PHelpers.AddProjectToProjectReferences(
|
||||
msbuildProj.Project,
|
||||
int numberOfAddedReferences = msbuildProj.AddProjectToProjectReferences(
|
||||
frameworkOption.Value(),
|
||||
references);
|
||||
|
||||
|
|
|
@ -50,8 +50,7 @@ namespace Microsoft.DotNet.Tools.Remove.ProjectToProjectReference
|
|||
|
||||
List<string> references = app.RemainingArguments;
|
||||
|
||||
int numberOfRemovedReferences = P2PHelpers.RemoveProjectToProjectReferences(
|
||||
msbuildProj,
|
||||
int numberOfRemovedReferences = msbuildProj.RemoveProjectToProjectReferences(
|
||||
frameworkOption.Value(),
|
||||
references);
|
||||
|
||||
|
|
Loading…
Reference in a new issue