2016-08-22 12:21:34 -07:00
|
|
|
|
// 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;
|
2016-08-22 12:21:34 -07:00
|
|
|
|
using System.Collections.Generic;
|
2016-08-23 13:50:05 -07:00
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
2016-08-22 12:21:34 -07:00
|
|
|
|
using Microsoft.Build.Construction;
|
2016-08-23 13:50:05 -07:00
|
|
|
|
using Microsoft.DotNet.ProjectJsonMigration.Transforms;
|
2016-08-22 12:21:34 -07:00
|
|
|
|
using Microsoft.DotNet.ProjectModel;
|
|
|
|
|
using Microsoft.DotNet.ProjectModel.Graph;
|
|
|
|
|
using Microsoft.DotNet.Tools.Common;
|
2016-09-21 21:14:48 -07:00
|
|
|
|
using NuGet.Frameworks;
|
2016-08-22 12:21:34 -07:00
|
|
|
|
|
2016-08-23 13:50:05 -07:00
|
|
|
|
namespace Microsoft.DotNet.ProjectJsonMigration.Rules
|
2016-08-22 12:21:34 -07:00
|
|
|
|
{
|
|
|
|
|
public class MigrateProjectDependenciesRule : IMigrationRule
|
|
|
|
|
{
|
|
|
|
|
private readonly ITransformApplicator _transformApplicator;
|
2016-09-21 21:14:48 -07:00
|
|
|
|
private readonly ProjectDependencyFinder _projectDependencyFinder;
|
2016-08-22 12:21:34 -07:00
|
|
|
|
private string _projectDirectory;
|
|
|
|
|
|
2016-08-23 13:50:05 -07:00
|
|
|
|
public MigrateProjectDependenciesRule(ITransformApplicator transformApplicator = null)
|
2016-08-22 12:21:34 -07:00
|
|
|
|
{
|
|
|
|
|
_transformApplicator = transformApplicator ?? new TransformApplicator();
|
2016-09-21 21:14:48 -07:00
|
|
|
|
_projectDependencyFinder = new ProjectDependencyFinder();
|
2016-08-22 12:21:34 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Apply(MigrationSettings migrationSettings, MigrationRuleInputs migrationRuleInputs)
|
|
|
|
|
{
|
|
|
|
|
_projectDirectory = migrationSettings.ProjectDirectory;
|
|
|
|
|
|
2016-09-21 17:27:02 -07:00
|
|
|
|
var migratedXProjDependencyPaths = MigrateXProjProjectDependencies(migrationSettings, migrationRuleInputs);
|
2016-09-22 17:44:34 -07:00
|
|
|
|
var migratedXProjDependencyNames = new HashSet<string>(migratedXProjDependencyPaths.Select(p => Path.GetFileNameWithoutExtension(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-21 17:27:02 -07:00
|
|
|
|
private IEnumerable<string> MigrateXProjProjectDependencies(MigrationSettings migrationSettings, MigrationRuleInputs migrationRuleInputs)
|
|
|
|
|
{
|
|
|
|
|
var xproj = migrationRuleInputs.ProjectXproj;
|
|
|
|
|
if (xproj == null)
|
|
|
|
|
{
|
|
|
|
|
MigrationTrace.Instance.WriteLine($"{nameof(MigrateProjectDependenciesRule)}: No xproj file given.");
|
|
|
|
|
return Enumerable.Empty<string>();
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-22 12:51:23 -07:00
|
|
|
|
var csprojTransformedReferences = new List<ProjectItemElement>();
|
|
|
|
|
|
|
|
|
|
var csprojReferenceItems = xproj.Items
|
|
|
|
|
.Where(i => i.ItemType == "ProjectReference")
|
|
|
|
|
.Where(p =>
|
|
|
|
|
p.Includes().Any(
|
|
|
|
|
include => string.Equals(Path.GetExtension(include), ".csproj", StringComparison.OrdinalIgnoreCase)));
|
|
|
|
|
|
|
|
|
|
foreach (var csprojReferenceItem in csprojReferenceItems)
|
2016-09-21 17:27:02 -07:00
|
|
|
|
{
|
2016-09-22 12:51:23 -07:00
|
|
|
|
var conditionChain = csprojReferenceItem.ConditionChain();
|
|
|
|
|
var condition = string.Join(" and ", conditionChain);
|
2016-09-21 17:27:02 -07:00
|
|
|
|
|
2016-09-22 12:51:23 -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-21 17:27:02 -07:00
|
|
|
|
|
2016-09-22 12:51:23 -07:00
|
|
|
|
MigrationTrace.Instance.WriteLine($"{nameof(MigrateProjectDependenciesRule)}: Migrating {csprojTransformedReferences.Count()} xproj to csproj references");
|
2016-09-21 17:27:02 -07:00
|
|
|
|
|
2016-09-22 12:51:23 -07:00
|
|
|
|
foreach (var csprojTransformedReference in csprojTransformedReferences)
|
2016-09-21 17:27:02 -07:00
|
|
|
|
{
|
2016-09-22 12:51:23 -07:00
|
|
|
|
_transformApplicator.Execute(csprojTransformedReference, migrationRuleInputs.CommonItemGroup);
|
2016-09-21 17:27:02 -07:00
|
|
|
|
}
|
|
|
|
|
|
2016-09-22 12:51:23 -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,
|
2016-09-22 17:44:34 -07:00
|
|
|
|
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
|
|
|
|
{
|
2016-09-22 17:44:34 -07:00
|
|
|
|
var projectDependencies = _projectDependencyFinder.ResolveProjectDependencies(projectContext, migratedXProjDependencyNames);
|
2016-09-21 21:14:48 -07:00
|
|
|
|
var projectExports = projectContext.CreateExporter("_").GetDependencies();
|
|
|
|
|
|
2016-09-22 17:44:34 -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[]
|
2016-08-22 12:21:34 -07:00
|
|
|
|
{
|
|
|
|
|
AutoUnifyTransform.Transform(true),
|
|
|
|
|
DesignTimeAutoUnifyTransform.Transform(true)
|
|
|
|
|
};
|
|
|
|
|
|
2016-08-23 13:50:05 -07:00
|
|
|
|
foreach (var propertyTransformResult in propertyTransformResults)
|
2016-08-22 12:21:34 -07:00
|
|
|
|
{
|
2016-08-23 13:50:05 -07:00
|
|
|
|
_transformApplicator.Execute(propertyTransformResult, commonPropertyGroup);
|
2016-08-22 12:21:34 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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>(
|
2016-08-22 12:21:34 -07:00
|
|
|
|
"ProjectReference",
|
2016-09-21 21:14:48 -07:00
|
|
|
|
dep =>
|
2016-08-22 12:21:34 -07:00
|
|
|
|
{
|
2016-09-21 21:14:48 -07:00
|
|
|
|
var projectDir = Path.GetDirectoryName(dep.ProjectFilePath);
|
2016-08-22 12:21:34 -07:00
|
|
|
|
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);
|
2016-08-22 12:21:34 -07:00
|
|
|
|
}
|
|
|
|
|
}
|