PackageReference
This commit is contained in:
parent
19f295113a
commit
bf45ab19ca
12 changed files with 434 additions and 89 deletions
|
@ -16,6 +16,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration
|
||||||
new MigrateRuntimeOptionsRule(),
|
new MigrateRuntimeOptionsRule(),
|
||||||
new MigratePublishOptionsRule(),
|
new MigratePublishOptionsRule(),
|
||||||
new MigrateProjectDependenciesRule(),
|
new MigrateProjectDependenciesRule(),
|
||||||
|
new MigratePackageDependenciesRule(),
|
||||||
new MigrateConfigurationsRule(),
|
new MigrateConfigurationsRule(),
|
||||||
new MigrateScriptsRule(),
|
new MigrateScriptsRule(),
|
||||||
new TemporaryMutateProjectJsonRule(),
|
new TemporaryMutateProjectJsonRule(),
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
// 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 NuGet.Frameworks;
|
||||||
|
|
||||||
|
namespace Microsoft.DotNet.ProjectJsonMigration
|
||||||
|
{
|
||||||
|
public static class MigrationNuGetFrameworkExtensions
|
||||||
|
{
|
||||||
|
public static string GetMSBuildCondition(this NuGetFramework framework)
|
||||||
|
{
|
||||||
|
return $" '$(TargetFramework)' == '{framework.GetTwoDigitShortFolderName()}' ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,7 +18,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration
|
||||||
|
|
||||||
public ProjectPropertyGroupElement CommonPropertyGroup { get; }
|
public ProjectPropertyGroupElement CommonPropertyGroup { get; }
|
||||||
|
|
||||||
public IEnumerable<ProjectContext> ProjectContexts { get; }
|
public List<ProjectContext> ProjectContexts { get; }
|
||||||
|
|
||||||
public ProjectContext DefaultProjectContext
|
public ProjectContext DefaultProjectContext
|
||||||
{
|
{
|
||||||
|
@ -36,7 +36,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration
|
||||||
ProjectRootElement projectXproj=null)
|
ProjectRootElement projectXproj=null)
|
||||||
{
|
{
|
||||||
ProjectXproj = projectXproj;
|
ProjectXproj = projectXproj;
|
||||||
ProjectContexts = projectContexts;
|
ProjectContexts = projectContexts.ToList();
|
||||||
OutputMSBuildProject = outputMSBuildProject;
|
OutputMSBuildProject = outputMSBuildProject;
|
||||||
CommonItemGroup = commonItemGroup;
|
CommonItemGroup = commonItemGroup;
|
||||||
CommonPropertyGroup = commonPropertyGroup;
|
CommonPropertyGroup = commonPropertyGroup;
|
||||||
|
|
|
@ -5,15 +5,17 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.Build.Construction;
|
using Microsoft.Build.Construction;
|
||||||
using Microsoft.DotNet.ProjectModel;
|
using Microsoft.DotNet.ProjectModel;
|
||||||
|
using Microsoft.DotNet.ProjectModel.Graph;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using Microsoft.DotNet.Tools.Common;
|
using Microsoft.DotNet.Tools.Common;
|
||||||
|
using NuGet.Frameworks;
|
||||||
using NuGet.LibraryModel;
|
using NuGet.LibraryModel;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.ProjectJsonMigration
|
namespace Microsoft.DotNet.ProjectJsonMigration
|
||||||
{
|
{
|
||||||
public class ProjectDependencyFinder
|
internal class ProjectDependencyFinder
|
||||||
{
|
{
|
||||||
public IEnumerable<ProjectDependency> ResolveProjectDependencies(string projectDir, string xprojFile = null)
|
public IEnumerable<ProjectDependency> ResolveProjectDependencies(string projectDir, string xprojFile = null)
|
||||||
{
|
{
|
||||||
|
@ -41,13 +43,57 @@ namespace Microsoft.DotNet.ProjectJsonMigration
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public IEnumerable<ProjectDependency> ResolveProjectDependenciesForFramework(
|
||||||
public IEnumerable<ProjectDependency> ResolveProjectDependencies(
|
Project project,
|
||||||
ProjectContext projectContext,
|
NuGetFramework framework,
|
||||||
IEnumerable<string> preResolvedProjects=null)
|
IEnumerable<string> preResolvedProjects=null)
|
||||||
{
|
{
|
||||||
preResolvedProjects = preResolvedProjects ?? new HashSet<string>();
|
preResolvedProjects = preResolvedProjects ?? new HashSet<string>();
|
||||||
|
|
||||||
|
var possibleProjectDependencies =
|
||||||
|
FindPossibleProjectDependencies(project.ProjectFilePath);
|
||||||
|
|
||||||
|
var projectDependencies = new List<ProjectDependency>();
|
||||||
|
|
||||||
|
IEnumerable<ProjectLibraryDependency> projectFileDependenciesForFramework;
|
||||||
|
if (framework == null)
|
||||||
|
{
|
||||||
|
projectFileDependenciesForFramework = project.Dependencies;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
projectFileDependenciesForFramework = project.GetTargetFramework(framework).Dependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var projectFileDependency in projectFileDependenciesForFramework)
|
||||||
|
{
|
||||||
|
var dependencyName = projectFileDependency.Name;
|
||||||
|
|
||||||
|
ProjectDependency projectDependency;
|
||||||
|
if (!possibleProjectDependencies.TryGetValue(dependencyName, out projectDependency))
|
||||||
|
{
|
||||||
|
if (projectFileDependency.LibraryRange.TypeConstraint == LibraryDependencyTarget.Project
|
||||||
|
&& !preResolvedProjects.Contains(dependencyName))
|
||||||
|
{
|
||||||
|
MigrationErrorCodes
|
||||||
|
.MIGRATE1014($"Unresolved project dependency ({dependencyName})").Throw();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
projectDependencies.Add(projectDependency);
|
||||||
|
}
|
||||||
|
|
||||||
|
return projectDependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<ProjectDependency> ResolveProjectDependencies(ProjectContext projectContext, IEnumerable<string> preResolvedProjects=null)
|
||||||
|
{
|
||||||
|
preResolvedProjects = preResolvedProjects ?? new HashSet<string>();
|
||||||
|
|
||||||
var projectExports = projectContext.CreateExporter("_").GetDependencies();
|
var projectExports = projectContext.CreateExporter("_").GetDependencies();
|
||||||
var possibleProjectDependencies =
|
var possibleProjectDependencies =
|
||||||
FindPossibleProjectDependencies(projectContext.ProjectFile.ProjectFilePath);
|
FindPossibleProjectDependencies(projectContext.ProjectFile.ProjectFilePath);
|
||||||
|
|
|
@ -40,6 +40,8 @@ namespace Microsoft.DotNet.ProjectJsonMigration
|
||||||
throw new ArgumentNullException();
|
throw new ArgumentNullException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var projectDependencies = ResolveTransitiveClosureProjectDependencies(rootSettings.ProjectDirectory, rootSettings.ProjectXProjFilePath);
|
||||||
|
|
||||||
MigrateProject(rootSettings);
|
MigrateProject(rootSettings);
|
||||||
|
|
||||||
if (skipProjectReferences)
|
if (skipProjectReferences)
|
||||||
|
@ -47,8 +49,6 @@ namespace Microsoft.DotNet.ProjectJsonMigration
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var projectDependencies = ResolveTransitiveClosureProjectDependencies(rootSettings.ProjectDirectory, rootSettings.ProjectXProjFilePath);
|
|
||||||
|
|
||||||
foreach(var project in projectDependencies)
|
foreach(var project in projectDependencies)
|
||||||
{
|
{
|
||||||
var projectDir = Path.GetDirectoryName(project.ProjectFilePath);
|
var projectDir = Path.GetDirectoryName(project.ProjectFilePath);
|
||||||
|
|
|
@ -0,0 +1,221 @@
|
||||||
|
// 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 System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using Microsoft.Build.Construction;
|
||||||
|
using Microsoft.DotNet.ProjectJsonMigration.Transforms;
|
||||||
|
using Microsoft.DotNet.ProjectModel;
|
||||||
|
using Microsoft.DotNet.ProjectModel.Graph;
|
||||||
|
using Microsoft.DotNet.Tools.Common;
|
||||||
|
using NuGet.Frameworks;
|
||||||
|
using NuGet.LibraryModel;
|
||||||
|
|
||||||
|
namespace Microsoft.DotNet.ProjectJsonMigration.Rules
|
||||||
|
{
|
||||||
|
public class MigratePackageDependenciesRule : IMigrationRule
|
||||||
|
{
|
||||||
|
private readonly ITransformApplicator _transformApplicator;
|
||||||
|
private readonly ProjectDependencyFinder _projectDependencyFinder;
|
||||||
|
private string _projectDirectory;
|
||||||
|
|
||||||
|
public MigratePackageDependenciesRule(ITransformApplicator transformApplicator = null)
|
||||||
|
{
|
||||||
|
_transformApplicator = transformApplicator ?? new TransformApplicator();
|
||||||
|
_projectDependencyFinder = new ProjectDependencyFinder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Apply(MigrationSettings migrationSettings, MigrationRuleInputs migrationRuleInputs)
|
||||||
|
{
|
||||||
|
CleanExistingPackageReferences(migrationRuleInputs.OutputMSBuildProject);
|
||||||
|
|
||||||
|
_projectDirectory = migrationSettings.ProjectDirectory;
|
||||||
|
var project = migrationRuleInputs.DefaultProjectContext.ProjectFile;
|
||||||
|
|
||||||
|
var tfmDependencyMap = new Dictionary<string, IEnumerable<ProjectLibraryDependency>>();
|
||||||
|
var targetFrameworks = project.GetTargetFrameworks();
|
||||||
|
|
||||||
|
// Inject Sdk dependency
|
||||||
|
PackageDependencyInfoTransform.Transform(new PackageDependencyInfo
|
||||||
|
{
|
||||||
|
Name = ConstantPackageNames.CSdkPackageName,
|
||||||
|
Version = migrationSettings.SdkPackageVersion
|
||||||
|
});
|
||||||
|
|
||||||
|
// Migrate Direct Deps first
|
||||||
|
MigrateDependencies(
|
||||||
|
project,
|
||||||
|
migrationRuleInputs.OutputMSBuildProject,
|
||||||
|
null,
|
||||||
|
project.Dependencies,
|
||||||
|
migrationRuleInputs.ProjectXproj);
|
||||||
|
|
||||||
|
foreach (var targetFramework in targetFrameworks)
|
||||||
|
{
|
||||||
|
MigrateImports(migrationRuleInputs.CommonItemGroup, targetFramework);
|
||||||
|
|
||||||
|
MigrateDependencies(
|
||||||
|
project,
|
||||||
|
migrationRuleInputs.OutputMSBuildProject,
|
||||||
|
targetFramework.FrameworkName,
|
||||||
|
project.Dependencies,
|
||||||
|
migrationRuleInputs.ProjectXproj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MigrateImports(ProjectItemGroupElement commonItemGroup, TargetFrameworkInformation targetFramework)
|
||||||
|
{
|
||||||
|
var transform = ImportsTransformation.Transform(targetFramework);
|
||||||
|
if (transform != null)
|
||||||
|
{
|
||||||
|
transform.Condition = targetFramework.FrameworkName.GetMSBuildCondition();
|
||||||
|
_transformApplicator.Execute(transform, commonItemGroup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CleanExistingPackageReferences(ProjectRootElement outputMSBuildProject)
|
||||||
|
{
|
||||||
|
var packageRefs = outputMSBuildProject.Items.Where(i => i.ItemType == "PackageReference").ToList();
|
||||||
|
|
||||||
|
foreach (var packageRef in packageRefs)
|
||||||
|
{
|
||||||
|
var parent = packageRef.Parent;
|
||||||
|
packageRef.Parent.RemoveChild(packageRef);
|
||||||
|
parent.RemoveIfEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MigrateDependencies(
|
||||||
|
Project project,
|
||||||
|
ProjectRootElement output,
|
||||||
|
NuGetFramework framework,
|
||||||
|
IEnumerable<ProjectLibraryDependency> dependencies,
|
||||||
|
ProjectRootElement xproj)
|
||||||
|
{
|
||||||
|
var projectDependencies = new HashSet<string>(GetAllProjectReferenceNames(project, framework, xproj));
|
||||||
|
var packageDependencies = dependencies.Where(d => !projectDependencies.Contains(d.Name));
|
||||||
|
|
||||||
|
string condition = framework?.GetMSBuildCondition() ?? "";
|
||||||
|
var itemGroup = output.ItemGroups.FirstOrDefault(i => i.Condition == condition)
|
||||||
|
?? output.AddItemGroup();
|
||||||
|
itemGroup.Condition = condition;
|
||||||
|
|
||||||
|
foreach (var packageDependency in packageDependencies)
|
||||||
|
{
|
||||||
|
AddItemTransform<ProjectLibraryDependency> transform;
|
||||||
|
|
||||||
|
if (packageDependency.LibraryRange.TypeConstraint == LibraryDependencyTarget.Reference)
|
||||||
|
{
|
||||||
|
transform = FrameworkDependencyTransform;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
transform = PackageDependencyTransform();
|
||||||
|
if (packageDependency.Type == LibraryDependencyType.Build)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Build type!!!");
|
||||||
|
transform = transform.WithMetadata("PrivateAssets", "all");
|
||||||
|
}
|
||||||
|
else if (packageDependency.SuppressParent != LibraryIncludeFlagUtils.DefaultSuppressParent)
|
||||||
|
{
|
||||||
|
var metadataValue = ReadLibraryIncludeFlags(packageDependency.SuppressParent);
|
||||||
|
transform = transform.WithMetadata("PrivateAssets", metadataValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: include/exclude
|
||||||
|
if (packageDependency.IncludeType != LibraryIncludeFlags.All)
|
||||||
|
{
|
||||||
|
var metadataValue = ReadLibraryIncludeFlags(packageDependency.IncludeType);
|
||||||
|
transform = transform.WithMetadata("IncludeAssets", metadataValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_transformApplicator.Execute(transform.Transform(packageDependency), itemGroup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string ReadLibraryIncludeFlags(LibraryIncludeFlags includeFlags)
|
||||||
|
{
|
||||||
|
if ((includeFlags & LibraryIncludeFlags.All) == LibraryIncludeFlags.All)
|
||||||
|
{
|
||||||
|
return "All";
|
||||||
|
}
|
||||||
|
|
||||||
|
var flagString = "";
|
||||||
|
var allFlagsAndNames = new List<Tuple<string, LibraryIncludeFlags>>
|
||||||
|
{
|
||||||
|
Tuple.Create("Analyzers", LibraryIncludeFlags.Analyzers),
|
||||||
|
Tuple.Create("Build", LibraryIncludeFlags.Build),
|
||||||
|
Tuple.Create("Compile", LibraryIncludeFlags.Compile),
|
||||||
|
Tuple.Create("ContentFiles", LibraryIncludeFlags.ContentFiles),
|
||||||
|
Tuple.Create("Native", LibraryIncludeFlags.Native),
|
||||||
|
Tuple.Create("Runtime", LibraryIncludeFlags.Runtime)
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var flagAndName in allFlagsAndNames)
|
||||||
|
{
|
||||||
|
var name = flagAndName.Item1;
|
||||||
|
var flag = flagAndName.Item2;
|
||||||
|
|
||||||
|
if ((includeFlags & flag) == flag)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(flagString))
|
||||||
|
{
|
||||||
|
flagString += ";";
|
||||||
|
}
|
||||||
|
flagString += name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return flagString;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<string> GetAllProjectReferenceNames(Project project, NuGetFramework framework, ProjectRootElement xproj)
|
||||||
|
{
|
||||||
|
var csprojReferenceItems = _projectDependencyFinder.ResolveXProjProjectDependencies(xproj);
|
||||||
|
var migratedXProjDependencyPaths = csprojReferenceItems.SelectMany(p => p.Includes());
|
||||||
|
var migratedXProjDependencyNames = new HashSet<string>(migratedXProjDependencyPaths.Select(p => Path.GetFileNameWithoutExtension(
|
||||||
|
PathUtility.GetPathWithDirectorySeparator(p))));
|
||||||
|
var projectDependencies = _projectDependencyFinder.ResolveProjectDependenciesForFramework(
|
||||||
|
project,
|
||||||
|
framework,
|
||||||
|
preResolvedProjects: migratedXProjDependencyNames);
|
||||||
|
|
||||||
|
return projectDependencies.Select(p => p.Name).Concat(migratedXProjDependencyNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
private AddItemTransform<ProjectLibraryDependency> FrameworkDependencyTransform => new AddItemTransform<ProjectLibraryDependency>(
|
||||||
|
"Reference",
|
||||||
|
dep => dep.Name,
|
||||||
|
dep => "",
|
||||||
|
dep => true);
|
||||||
|
|
||||||
|
private Func<AddItemTransform<ProjectLibraryDependency>> PackageDependencyTransform => () => new AddItemTransform<ProjectLibraryDependency>(
|
||||||
|
"PackageReference",
|
||||||
|
dep => dep.Name,
|
||||||
|
dep => "",
|
||||||
|
dep => true)
|
||||||
|
.WithMetadata("Version", r => r.LibraryRange.VersionRange.OriginalString);
|
||||||
|
|
||||||
|
private AddItemTransform<PackageDependencyInfo> PackageDependencyInfoTransform => new AddItemTransform<PackageDependencyInfo>(
|
||||||
|
"PackageReference",
|
||||||
|
dep => dep.Name,
|
||||||
|
dep => "",
|
||||||
|
dep => true)
|
||||||
|
.WithMetadata("Version", r => r.Version);
|
||||||
|
|
||||||
|
private AddItemTransform<TargetFrameworkInformation> ImportsTransformation => new AddItemTransform<TargetFrameworkInformation>(
|
||||||
|
"PackageTargetFallback",
|
||||||
|
t => $"$(PackageTargetFallback);{string.Join(";", t.Imports)}",
|
||||||
|
t => "",
|
||||||
|
t => t.Imports.Any());
|
||||||
|
|
||||||
|
private class PackageDependencyInfo
|
||||||
|
{
|
||||||
|
public string Name {get; set;}
|
||||||
|
public string Version {get; set;}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Newtonsoft.Json.Serialization;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.ProjectJsonMigration.Rules
|
namespace Microsoft.DotNet.ProjectJsonMigration.Rules
|
||||||
{
|
{
|
||||||
|
@ -21,73 +22,11 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
|
||||||
{
|
{
|
||||||
public void Apply(MigrationSettings migrationSettings, MigrationRuleInputs migrationRuleInputs)
|
public void Apply(MigrationSettings migrationSettings, MigrationRuleInputs migrationRuleInputs)
|
||||||
{
|
{
|
||||||
bool shouldRenameOldProject = PathsAreEqual(migrationSettings.OutputDirectory, migrationSettings.ProjectDirectory);
|
|
||||||
|
|
||||||
if (!shouldRenameOldProject && File.Exists(Path.Combine(migrationSettings.OutputDirectory, "project.json")))
|
|
||||||
{
|
|
||||||
// TODO: should there be a setting to overwrite anything in output directory?
|
|
||||||
throw new Exception("Existing project.json found in output directory.");
|
|
||||||
}
|
|
||||||
|
|
||||||
var sourceProjectFile = Path.Combine(migrationSettings.ProjectDirectory, "project.json");
|
var sourceProjectFile = Path.Combine(migrationSettings.ProjectDirectory, "project.json");
|
||||||
var destinationProjectFile = Path.Combine(migrationSettings.OutputDirectory, "project.json");
|
|
||||||
if (shouldRenameOldProject)
|
|
||||||
{
|
|
||||||
var renamedProjectFile = Path.Combine(migrationSettings.ProjectDirectory, "project.migrated.json");
|
|
||||||
File.Move(sourceProjectFile, renamedProjectFile);
|
|
||||||
sourceProjectFile = renamedProjectFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
var json = CreateDestinationProjectFile(sourceProjectFile, destinationProjectFile);
|
var renamedProjectFile = Path.Combine(migrationSettings.ProjectDirectory, "project.migrated.json");
|
||||||
InjectSdkReference(json, ConstantPackageNames.CSdkPackageName, migrationSettings.SdkPackageVersion);
|
File.Move(sourceProjectFile, renamedProjectFile);
|
||||||
RemoveRuntimesNode(json);
|
sourceProjectFile = renamedProjectFile;
|
||||||
|
|
||||||
File.WriteAllText(destinationProjectFile, json.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private JObject CreateDestinationProjectFile(string sourceProjectFile, string destinationProjectFile)
|
|
||||||
{
|
|
||||||
File.Copy(sourceProjectFile, destinationProjectFile);
|
|
||||||
return JObject.Parse(File.ReadAllText(destinationProjectFile));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InjectSdkReference(JObject json, string sdkPackageName, string sdkPackageVersion)
|
|
||||||
{
|
|
||||||
JToken dependenciesNode;
|
|
||||||
if (json.TryGetValue("dependencies", out dependenciesNode))
|
|
||||||
{
|
|
||||||
var dependenciesNodeObject = dependenciesNode.Value<JObject>();
|
|
||||||
dependenciesNodeObject.Add(sdkPackageName, sdkPackageVersion);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var dependenciesNodeObject = new JObject();
|
|
||||||
dependenciesNodeObject.Add(sdkPackageName, sdkPackageVersion);
|
|
||||||
|
|
||||||
json.Add("dependencies", dependenciesNodeObject);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RemoveRuntimesNode(JObject json)
|
|
||||||
{
|
|
||||||
json.Remove("runtimes");
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool PathsAreEqual(params string[] paths)
|
|
||||||
{
|
|
||||||
var normalizedPaths = paths.Select(path => Path.GetFullPath(path).TrimEnd(Path.DirectorySeparatorChar)).ToList();
|
|
||||||
|
|
||||||
for (int i=1; i<normalizedPaths.Count(); ++i)
|
|
||||||
{
|
|
||||||
var path1 = normalizedPaths[i - 1];
|
|
||||||
var path2 = normalizedPaths[i];
|
|
||||||
if (!string.Equals(path1, path2, StringComparison.Ordinal))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -278,6 +278,11 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
|
|
||||||
var dependencyValue = dependency.Value;
|
var dependencyValue = dependency.Value;
|
||||||
var dependencyTypeValue = LibraryDependencyType.Default;
|
var dependencyTypeValue = LibraryDependencyType.Default;
|
||||||
|
|
||||||
|
var dependencyIncludeFlagsValue = LibraryIncludeFlags.All;
|
||||||
|
var dependencyExcludeFlagsValue = LibraryIncludeFlags.None;
|
||||||
|
var suppressParentFlagsValue = LibraryIncludeFlagUtils.DefaultSuppressParent;
|
||||||
|
|
||||||
var target = isGacOrFrameworkReference ? LibraryDependencyTarget.Reference : LibraryDependencyTarget.All;
|
var target = isGacOrFrameworkReference ? LibraryDependencyTarget.Reference : LibraryDependencyTarget.All;
|
||||||
string dependencyVersionAsString = null;
|
string dependencyVersionAsString = null;
|
||||||
|
|
||||||
|
@ -298,6 +303,23 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
var targetStr = dependencyValue.Value<string>("target");
|
var targetStr = dependencyValue.Value<string>("target");
|
||||||
target = LibraryDependencyTargetUtils.Parse(targetStr);
|
target = LibraryDependencyTargetUtils.Parse(targetStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IEnumerable<string> strings;
|
||||||
|
if (TryGetStringEnumerable(dependencyValue["include"], out strings))
|
||||||
|
{
|
||||||
|
dependencyIncludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(strings);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TryGetStringEnumerable(dependencyValue["exclude"], out strings))
|
||||||
|
{
|
||||||
|
dependencyExcludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(strings);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TryGetStringEnumerable(dependencyValue["suppressParent"], out strings))
|
||||||
|
{
|
||||||
|
// This overrides any settings that came from the type property.
|
||||||
|
suppressParentFlagsValue = LibraryIncludeFlagUtils.GetFlags(strings);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (dependencyValue.Type == JTokenType.String)
|
else if (dependencyValue.Type == JTokenType.String)
|
||||||
{
|
{
|
||||||
|
@ -327,6 +349,9 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the dependency flags are: Include flags - Exclude flags
|
||||||
|
var includeFlags = dependencyIncludeFlagsValue & ~dependencyExcludeFlagsValue;
|
||||||
|
|
||||||
var lineInfo = (IJsonLineInfo)dependencyValue;
|
var lineInfo = (IJsonLineInfo)dependencyValue;
|
||||||
results.Add(new ProjectLibraryDependency
|
results.Add(new ProjectLibraryDependency
|
||||||
{
|
{
|
||||||
|
@ -335,6 +360,8 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
dependencyVersionRange,
|
dependencyVersionRange,
|
||||||
target),
|
target),
|
||||||
Type = dependencyTypeValue,
|
Type = dependencyTypeValue,
|
||||||
|
IncludeType = includeFlags,
|
||||||
|
SuppressParent = suppressParentFlagsValue,
|
||||||
SourceFilePath = projectPath,
|
SourceFilePath = projectPath,
|
||||||
SourceLine = lineInfo.LineNumber,
|
SourceLine = lineInfo.LineNumber,
|
||||||
SourceColumn = lineInfo.LinePosition
|
SourceColumn = lineInfo.LinePosition
|
||||||
|
@ -472,7 +499,8 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
Dependencies = new List<ProjectLibraryDependency>(),
|
Dependencies = new List<ProjectLibraryDependency>(),
|
||||||
CompilerOptions = compilerOptions,
|
CompilerOptions = compilerOptions,
|
||||||
Line = lineInfo.LineNumber,
|
Line = lineInfo.LineNumber,
|
||||||
Column = lineInfo.LinePosition
|
Column = lineInfo.LinePosition,
|
||||||
|
Imports = GetImports(frameworkValue)
|
||||||
};
|
};
|
||||||
|
|
||||||
var frameworkDependencies = new List<ProjectLibraryDependency>();
|
var frameworkDependencies = new List<ProjectLibraryDependency>();
|
||||||
|
@ -508,6 +536,26 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IEnumerable<string> GetImports(JObject frameworkValue)
|
||||||
|
{
|
||||||
|
var prop = frameworkValue.Property("imports");
|
||||||
|
if (prop == null)
|
||||||
|
{
|
||||||
|
return Enumerable.Empty<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prop.Type == JTokenType.Array)
|
||||||
|
{
|
||||||
|
return prop.Value<IEnumerable<string>>();
|
||||||
|
}
|
||||||
|
else if (prop.Type == JTokenType.String)
|
||||||
|
{
|
||||||
|
return new [] { prop.Value<string>() };
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private static CommonCompilerOptions GetCompilationOptions(JObject rawObject, Project project)
|
private static CommonCompilerOptions GetCompilationOptions(JObject rawObject, Project project)
|
||||||
{
|
{
|
||||||
var compilerName = rawObject.Value<string>("compilerName");
|
var compilerName = rawObject.Value<string>("compilerName");
|
||||||
|
@ -819,5 +867,29 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
lineInfo.LineNumber,
|
lineInfo.LineNumber,
|
||||||
lineInfo.LinePosition));
|
lineInfo.LinePosition));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool TryGetStringEnumerable(JToken token, out IEnumerable<string> result)
|
||||||
|
{
|
||||||
|
IEnumerable<string> values;
|
||||||
|
if (token == null)
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (token.Type == JTokenType.String)
|
||||||
|
{
|
||||||
|
values = new[]
|
||||||
|
{
|
||||||
|
token.Value<string>()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
values = token.Value<string[]>();
|
||||||
|
}
|
||||||
|
result = values
|
||||||
|
.SelectMany(value => value.Split(new[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,5 +22,7 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
public string WrappedProject { get; set; }
|
public string WrappedProject { get; set; }
|
||||||
|
|
||||||
public string AssemblyPath { get; set; }
|
public string AssemblyPath { get; set; }
|
||||||
|
|
||||||
|
public IEnumerable<string> Imports { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
// 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.DotNet.Tools.Test.Utilities;
|
||||||
|
using System.Linq;
|
||||||
|
using Xunit;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Microsoft.DotNet.ProjectJsonMigration.Rules;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Microsoft.DotNet.ProjectJsonMigration.Tests
|
||||||
|
{
|
||||||
|
public class GivenThatIWantToMigratePackageDependencies : TestBase
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void It_migrates_basic_PackageReference()
|
||||||
|
{
|
||||||
|
var mockProj = RunPackageDependenciesRuleOnPj(@"
|
||||||
|
{
|
||||||
|
""dependencies"": {
|
||||||
|
""APackage"" : ""1.0.0-preview"",
|
||||||
|
""BPackage"" : ""1.0.0""
|
||||||
|
}
|
||||||
|
}");
|
||||||
|
|
||||||
|
Console.WriteLine(mockProj.RawXml);
|
||||||
|
|
||||||
|
EmitsPackageReferences(mockProj, Tuple.Create("APackage", "1.0.0-preview", ""), Tuple.Create("BPackage", "1.0.0", ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EmitsPackageReferences(ProjectRootElement mockProj, params Tuple<string, string, string>[] packageSpecs)
|
||||||
|
{
|
||||||
|
foreach (var packageSpec in packageSpecs)
|
||||||
|
{
|
||||||
|
var packageName = packageSpec.Item1;
|
||||||
|
var packageVersion = packageSpec.Item2;
|
||||||
|
var packageTFM = packageSpec.Item3;
|
||||||
|
|
||||||
|
var items = mockProj.Items
|
||||||
|
.Where(i => i.ItemType == "PackageReference")
|
||||||
|
.Where(i => string.IsNullOrEmpty(packageTFM) || i.ConditionChain().Any(c => c.Contains(packageTFM)))
|
||||||
|
.Where(i => i.Include == packageName)
|
||||||
|
.Where(i => i.GetMetadataWithName("Version").Value == packageVersion);
|
||||||
|
|
||||||
|
items.Should().HaveCount(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ProjectRootElement RunPackageDependenciesRuleOnPj(string s, string testDirectory = null)
|
||||||
|
{
|
||||||
|
testDirectory = testDirectory ?? Temp.CreateDirectory().Path;
|
||||||
|
return TemporaryProjectFileRuleRunner.RunRules(new IMigrationRule[]
|
||||||
|
{
|
||||||
|
new MigratePackageDependenciesRule()
|
||||||
|
}, s, testDirectory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.DotNet.ProjectJsonMigration.Transforms;
|
|
||||||
|
|
||||||
namespace Microsoft.DotNet.ProjectJsonMigration.Tests
|
|
||||||
{
|
|
||||||
public class GivenAnIncludeContextTransformation
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -241,8 +241,10 @@ namespace Microsoft.DotNet.Migration.Tests
|
||||||
File.Delete(Path.Combine(projectDirectory, "project.lock.json"));
|
File.Delete(Path.Combine(projectDirectory, "project.lock.json"));
|
||||||
|
|
||||||
MigrateProject(projectDirectory);
|
MigrateProject(projectDirectory);
|
||||||
Restore(projectDirectory);
|
|
||||||
BuildMSBuild(projectDirectory, projectName);
|
DeleteXproj(projectDirectory);
|
||||||
|
Restore3(projectDirectory);
|
||||||
|
BuildMSBuild(projectDirectory);
|
||||||
|
|
||||||
var msbuildBuildOutputs = new HashSet<string>(CollectBuildOutputs(projectDirectory));
|
var msbuildBuildOutputs = new HashSet<string>(CollectBuildOutputs(projectDirectory));
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue