dotnet-installer/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateProjectDependenciesRule.cs

161 lines
6.8 KiB
C#
Raw Normal View History

// 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.
2016-09-21 17:27:02 -07:00
using System;
using System.Collections.Generic;
2016-08-23 13:50:05 -07:00
using System.IO;
using System.Linq;
using Microsoft.Build.Construction;
2016-08-23 13:50:05 -07:00
using Microsoft.DotNet.ProjectJsonMigration.Transforms;
using Microsoft.DotNet.ProjectModel;
using Microsoft.DotNet.Tools.Common;
2016-09-21 21:14:48 -07:00
using NuGet.Frameworks;
2016-08-23 13:50:05 -07:00
namespace Microsoft.DotNet.ProjectJsonMigration.Rules
{
public class MigrateProjectDependenciesRule : IMigrationRule
{
private readonly ITransformApplicator _transformApplicator;
2016-09-21 21:14:48 -07:00
private readonly ProjectDependencyFinder _projectDependencyFinder;
private string _projectDirectory;
2016-08-23 13:50:05 -07:00
public MigrateProjectDependenciesRule(ITransformApplicator transformApplicator = null)
{
_transformApplicator = transformApplicator ?? new TransformApplicator();
2016-09-21 21:14:48 -07:00
_projectDependencyFinder = new ProjectDependencyFinder();
}
public void Apply(MigrationSettings migrationSettings, MigrationRuleInputs migrationRuleInputs)
{
_projectDirectory = migrationSettings.ProjectDirectory;
2016-09-23 14:48:54 -07:00
var migratedXProjDependencyPaths = MigrateXProjProjectDependencies(migrationRuleInputs);
var migratedXProjDependencyNames = new HashSet<string>(migratedXProjDependencyPaths.Select(p => Path.GetFileNameWithoutExtension(
PathUtility.GetPathWithDirectorySeparator(p))));
2016-09-21 17:27:02 -07:00
2016-09-21 21:14:48 -07:00
AddPropertyTransformsToCommonPropertyGroup(migrationRuleInputs.CommonPropertyGroup);
MigrateProjectJsonProjectDependencies(
migrationRuleInputs.ProjectContexts,
migratedXProjDependencyNames,
migrationRuleInputs.OutputMSBuildProject);
}
2016-09-23 14:48:54 -07:00
private IEnumerable<string> MigrateXProjProjectDependencies(MigrationRuleInputs migrationRuleInputs)
2016-09-21 17:27:02 -07:00
{
2016-09-23 14:48:54 -07:00
var csprojReferenceItems = _projectDependencyFinder.ResolveXProjProjectDependencies(migrationRuleInputs.ProjectXproj);
if (!csprojReferenceItems.Any())
2016-09-21 17:27:02 -07:00
{
return Enumerable.Empty<string>();
}
var csprojTransformedReferences = new List<ProjectItemElement>();
foreach (var csprojReferenceItem in csprojReferenceItems)
2016-09-21 17:27:02 -07:00
{
var conditionChain = csprojReferenceItem.ConditionChain();
var condition = string.Join(" and ", conditionChain);
2016-09-21 17:27:02 -07:00
var referenceInclude = string.Join(";", csprojReferenceItem.Includes()
.Where(include =>
string.Equals(Path.GetExtension(include), ".csproj", StringComparison.OrdinalIgnoreCase)));
var transformItem = ProjectDependencyStringTransform.Transform(referenceInclude);
transformItem.Condition = condition;
csprojTransformedReferences.Add(transformItem);
}
2016-09-23 14:48:54 -07:00
MigrationTrace.Instance.WriteLine($"{nameof(MigrateProjectDependenciesRule)}: Migrating {csprojTransformedReferences.Count()} xproj to csproj references");
2016-09-21 17:27:02 -07:00
foreach (var csprojTransformedReference in csprojTransformedReferences)
2016-09-21 17:27:02 -07:00
{
_transformApplicator.Execute(csprojTransformedReference, migrationRuleInputs.CommonItemGroup);
2016-09-21 17:27:02 -07:00
}
return csprojTransformedReferences.SelectMany(r => r.Includes());
2016-09-21 17:27:02 -07:00
}
public void MigrateProjectJsonProjectDependencies(
2016-09-21 21:14:48 -07:00
IEnumerable<ProjectContext> projectContexts,
HashSet<string> migratedXProjDependencyNames,
2016-09-21 21:14:48 -07:00
ProjectRootElement outputMSBuildProject)
2016-09-21 17:27:02 -07:00
{
2016-09-21 21:14:48 -07:00
foreach (var projectContext in projectContexts)
2016-09-21 17:27:02 -07:00
{
var projectDependencies = _projectDependencyFinder.ResolveProjectDependencies(projectContext, migratedXProjDependencyNames);
2016-09-21 21:14:48 -07:00
var projectDependencyTransformResults = projectDependencies.Select(p => ProjectDependencyTransform.Transform(p));
2016-09-21 21:14:48 -07:00
if (projectDependencyTransformResults.Any())
{
AddProjectDependenciesToNewItemGroup(
outputMSBuildProject.AddItemGroup(),
projectDependencyTransformResults,
projectContext.TargetFramework);
2016-09-21 17:27:02 -07:00
}
}
2016-08-23 13:50:05 -07:00
}
2016-09-21 21:14:48 -07:00
private void AddProjectDependenciesToNewItemGroup(
ProjectItemGroupElement itemGroup,
IEnumerable<ProjectItemElement> projectDependencyTransformResults,
NuGetFramework targetFramework)
2016-08-23 13:50:05 -07:00
{
2016-09-21 21:14:48 -07:00
if (targetFramework != null)
{
itemGroup.Condition = $" '$(TargetFrameworkIdentifier),Version=$(TargetFrameworkVersion)' == '{targetFramework.DotNetFrameworkName}' ";
}
2016-08-23 13:50:05 -07:00
foreach (var projectDependencyTransformResult in projectDependencyTransformResults)
{
_transformApplicator.Execute(projectDependencyTransformResult, itemGroup);
}
}
private void AddPropertyTransformsToCommonPropertyGroup(ProjectPropertyGroupElement commonPropertyGroup)
{
var propertyTransformResults = new[]
{
AutoUnifyTransform.Transform(true),
DesignTimeAutoUnifyTransform.Transform(true)
};
2016-08-23 13:50:05 -07:00
foreach (var propertyTransformResult in propertyTransformResults)
{
2016-08-23 13:50:05 -07:00
_transformApplicator.Execute(propertyTransformResult, commonPropertyGroup);
}
}
private AddPropertyTransform<bool> AutoUnifyTransform => new AddPropertyTransform<bool>(
"AutoUnify",
"true",
b => true);
private AddPropertyTransform<bool> DesignTimeAutoUnifyTransform => new AddPropertyTransform<bool>(
"DesignTimeAutoUnify",
"true",
b => true);
2016-09-21 21:14:48 -07:00
private AddItemTransform<ProjectDependency> ProjectDependencyTransform => new AddItemTransform<ProjectDependency>(
"ProjectReference",
2016-09-21 21:14:48 -07:00
dep =>
{
2016-09-21 21:14:48 -07:00
var projectDir = Path.GetDirectoryName(dep.ProjectFilePath);
var migratedProjectFileName = Path.GetFileName(projectDir) + ".csproj";
var relativeProjectDir = PathUtility.GetRelativePath(_projectDirectory + "/", projectDir);
return Path.Combine(relativeProjectDir, migratedProjectFileName);
},
2016-09-21 21:14:48 -07:00
dep => "",
dep => true);
2016-09-21 17:27:02 -07:00
private AddItemTransform<string> ProjectDependencyStringTransform => new AddItemTransform<string>(
"ProjectReference",
path => path,
path => "",
path => true);
}
}