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
|
internal class MsbuildProject
|
||||||
{
|
{
|
||||||
|
const string ProjectItemElementType = "ProjectReference";
|
||||||
|
|
||||||
public ProjectRootElement Project { get; private set; }
|
public ProjectRootElement Project { get; private set; }
|
||||||
public string ProjectPath { get; private set; }
|
|
||||||
public string ProjectDirectory { get; private set; }
|
public string ProjectDirectory { get; private set; }
|
||||||
|
|
||||||
private MsbuildProject(ProjectRootElement project, string projectPath, string projectDirectory)
|
private MsbuildProject(ProjectRootElement project)
|
||||||
{
|
{
|
||||||
Project = project;
|
Project = project;
|
||||||
ProjectPath = projectPath;
|
ProjectDirectory = PathUtility.EnsureTrailingSlash(Project.DirectoryPath);
|
||||||
ProjectDirectory = PathUtility.EnsureTrailingSlash(projectDirectory);
|
|
||||||
}
|
|
||||||
|
|
||||||
private MsbuildProject(ProjectRootElement project, string projectPath)
|
|
||||||
{
|
|
||||||
Project = project;
|
|
||||||
ProjectPath = projectPath;
|
|
||||||
ProjectDirectory = PathUtility.EnsureTrailingSlash(new FileInfo(projectPath).DirectoryName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MsbuildProject FromFileOrDirectory(string fileOrDirectory)
|
public static MsbuildProject FromFileOrDirectory(string fileOrDirectory)
|
||||||
|
@ -57,7 +50,7 @@ namespace Microsoft.DotNet.Tools
|
||||||
throw new GracefulException(LocalizableStrings.ProjectIsInvalid, projectPath);
|
throw new GracefulException(LocalizableStrings.ProjectIsInvalid, projectPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new MsbuildProject(project, Path.GetFullPath(projectPath));
|
return new MsbuildProject(project);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MsbuildProject FromDirectory(string projectDirectory)
|
public static MsbuildProject FromDirectory(string projectDirectory)
|
||||||
|
@ -66,7 +59,6 @@ namespace Microsoft.DotNet.Tools
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
dir = new DirectoryInfo(projectDirectory);
|
dir = new DirectoryInfo(projectDirectory);
|
||||||
projectDirectory = dir.FullName;
|
|
||||||
}
|
}
|
||||||
catch (ArgumentException)
|
catch (ArgumentException)
|
||||||
{
|
{
|
||||||
|
@ -102,7 +94,122 @@ namespace Microsoft.DotNet.Tools
|
||||||
throw new GracefulException(LocalizableStrings.FoundInvalidProject, projectFile.FullName);
|
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
|
// 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)
|
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;
|
List<string> references = app.RemainingArguments;
|
||||||
if (!forceOption.HasValue())
|
if (!forceOption.HasValue())
|
||||||
{
|
{
|
||||||
P2PHelpers.EnsureAllReferencesExist(references);
|
MsbuildProject.EnsureAllReferencesExist(references);
|
||||||
P2PHelpers.ConvertPathsToRelative(msbuildProj.ProjectDirectory, ref references);
|
msbuildProj.ConvertPathsToRelative(ref references);
|
||||||
}
|
}
|
||||||
|
|
||||||
int numberOfAddedReferences = P2PHelpers.AddProjectToProjectReferences(
|
int numberOfAddedReferences = msbuildProj.AddProjectToProjectReferences(
|
||||||
msbuildProj.Project,
|
|
||||||
frameworkOption.Value(),
|
frameworkOption.Value(),
|
||||||
references);
|
references);
|
||||||
|
|
||||||
|
|
|
@ -50,8 +50,7 @@ namespace Microsoft.DotNet.Tools.Remove.ProjectToProjectReference
|
||||||
|
|
||||||
List<string> references = app.RemainingArguments;
|
List<string> references = app.RemainingArguments;
|
||||||
|
|
||||||
int numberOfRemovedReferences = P2PHelpers.RemoveProjectToProjectReferences(
|
int numberOfRemovedReferences = msbuildProj.RemoveProjectToProjectReferences(
|
||||||
msbuildProj,
|
|
||||||
frameworkOption.Value(),
|
frameworkOption.Value(),
|
||||||
references);
|
references);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue