dotnet-installer/src/Microsoft.DotNet.ProjectJsonMigration/transforms/IncludeContextTransform.cs

185 lines
8.3 KiB
C#

// 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.DotNet.Internal.ProjectModel.Files;
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Build.Construction;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.ProjectJsonMigration.Models;
using Microsoft.DotNet.Tools.Common;
namespace Microsoft.DotNet.ProjectJsonMigration.Transforms
{
internal class IncludeContextTransform : ConditionalTransform<IncludeContext, IEnumerable<ProjectItemElement>>
{
protected virtual Func<string, AddItemTransform<IncludeContext>> IncludeFilesExcludeFilesTransformGetter =>
(itemName) =>
new AddItemTransform<IncludeContext>(
itemName,
includeContext => FormatGlobPatternsForMsbuild(includeContext.IncludeFiles.OrEmptyIfNull()
.Where((pattern) => !ExcludePatternRule(pattern)),
includeContext.SourceBasePath),
includeContext => FormatGlobPatternsForMsbuild(includeContext.ExcludeFiles, includeContext.SourceBasePath),
includeContext => includeContext != null
&& includeContext.IncludeFiles != null
&& includeContext.IncludeFiles.Where((pattern) => !ExcludePatternRule(pattern)).Count() > 0);
protected virtual Func<string, AddItemTransform<IncludeContext>> IncludeExcludeTransformGetter =>
(itemName) => new AddItemTransform<IncludeContext>(
itemName,
includeContext =>
{
var fullIncludeSet = includeContext.IncludePatterns.OrEmptyIfNull()
.Union(includeContext.CustomIncludePatterns.OrEmptyIfNull());
if (_emitBuiltInIncludes)
{
fullIncludeSet = fullIncludeSet.Union(includeContext.BuiltInsInclude.OrEmptyIfNull());
}
fullIncludeSet = fullIncludeSet.Where((pattern) => !ExcludePatternRule(pattern));
return FormatGlobPatternsForMsbuild(fullIncludeSet, includeContext.SourceBasePath);
},
includeContext =>
{
var fullExcludeSet = includeContext.ExcludePatterns.OrEmptyIfNull()
.Union(includeContext.BuiltInsExclude.OrEmptyIfNull())
.Union(includeContext.ExcludeFiles.OrEmptyIfNull());
return FormatGlobPatternsForMsbuild(fullExcludeSet, includeContext.SourceBasePath);
},
includeContext =>
{
return includeContext != null &&
(
(includeContext.IncludePatterns != null && includeContext.IncludePatterns.Where((pattern) => !ExcludePatternRule(pattern)).Count() > 0)
||
(includeContext.CustomIncludePatterns != null && includeContext.CustomIncludePatterns.Where((pattern) => !ExcludePatternRule(pattern)).Count() > 0)
||
(_emitBuiltInIncludes &&
includeContext.BuiltInsInclude != null &&
includeContext.BuiltInsInclude.Count > 0)
);
});
private Func<string, string, AddItemTransform<IncludeContext>> MappingsIncludeFilesExcludeFilesTransformGetter =>
(itemName, targetPath) => AddMappingToTransform(IncludeFilesExcludeFilesTransformGetter(itemName), targetPath);
private Func<string, string, AddItemTransform<IncludeContext>> MappingsIncludeExcludeTransformGetter =>
(itemName, targetPath) => AddMappingToTransform(IncludeExcludeTransformGetter(itemName), targetPath);
private Func<AddItemTransform<IncludeContext>, string, AddItemTransform<IncludeContext>> _mappingsToTransfrom;
private readonly string _itemName;
private bool _transformMappings;
protected Func<string, bool> ExcludePatternRule { get; }
private bool _emitBuiltInIncludes;
private readonly List<ItemMetadataValue<IncludeContext>> _metadata = new List<ItemMetadataValue<IncludeContext>>();
public IncludeContextTransform(
string itemName,
bool transformMappings = true,
Func<IncludeContext, bool> condition = null,
bool emitBuiltInIncludes = true,
Func<string, bool> excludePatternsRule = null) : base(condition)
{
_itemName = itemName;
_transformMappings = transformMappings;
_emitBuiltInIncludes = emitBuiltInIncludes;
ExcludePatternRule = excludePatternsRule ?? ((pattern) => false);
_mappingsToTransfrom = (addItemTransform, targetPath) =>
{
var msbuildLinkMetadataValue = ConvertTargetPathToMsbuildMetadata(targetPath);
return addItemTransform.WithMetadata("Link", msbuildLinkMetadataValue);
};
}
public IncludeContextTransform WithMetadata(
string metadataName,
string metadataValue,
string condition = null)
{
_metadata.Add(new ItemMetadataValue<IncludeContext>(metadataName, metadataValue, condition));
return this;
}
public IncludeContextTransform WithMetadata(
string metadataName,
Func<IncludeContext, string> metadataValueFunc,
string condition = null)
{
_metadata.Add(new ItemMetadataValue<IncludeContext>(
metadataName,
metadataValueFunc,
condition: condition));
return this;
}
public IncludeContextTransform WithMappingsToTransform(
Func<AddItemTransform<IncludeContext>, string, AddItemTransform<IncludeContext>> mappingsToTransfrom)
{
_mappingsToTransfrom = mappingsToTransfrom;
return this;
}
private IEnumerable<Tuple<AddItemTransform<IncludeContext>, IncludeContext>> CreateTransformSet(IncludeContext source)
{
var transformSet = new List<Tuple<AddItemTransform<IncludeContext>, IncludeContext>>
{
Tuple.Create(IncludeFilesExcludeFilesTransformGetter(_itemName), source),
Tuple.Create(IncludeExcludeTransformGetter(_itemName), source)
};
if (source == null)
{
return transformSet;
}
// Mappings must be executed before the transform set to prevent a the
// non-mapped items that will merge with mapped items from being encompassed
foreach (var mappingEntry in source.Mappings.OrEmptyIfNull())
{
var targetPath = mappingEntry.Key;
var includeContext = mappingEntry.Value;
transformSet.Insert(0,
Tuple.Create(
MappingsIncludeExcludeTransformGetter(_itemName, targetPath),
includeContext));
transformSet.Insert(0,
Tuple.Create(
MappingsIncludeFilesExcludeFilesTransformGetter(_itemName, targetPath),
includeContext));
}
foreach (var metadataElement in _metadata)
{
foreach (var transform in transformSet)
{
transform.Item1.WithMetadata(metadataElement);
}
}
return transformSet;
}
public override IEnumerable<ProjectItemElement> ConditionallyTransform(IncludeContext source)
{
var transformSet = CreateTransformSet(source);
return transformSet.Select(t => t.Item1.Transform(t.Item2));
}
private AddItemTransform<IncludeContext> AddMappingToTransform(
AddItemTransform<IncludeContext> addItemTransform,
string targetPath)
{
return _mappingsToTransfrom(addItemTransform, targetPath);
}
}
}