| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- // Copyright (c) .NET Foundation. All rights reserved.
- // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using Microsoft.Build.Framework;
- using Microsoft.Build.Utilities;
- namespace RepoTasks
- {
- public class JoinItems : Task
- {
- [Required]
- public ITaskItem[] Left { get; set; }
- [Required]
- public ITaskItem[] Right { get; set; }
- // The metadata to use as the new item spec. If not specified, LeftKey is used.
- public string LeftItemSpec { get; set; }
- // LeftKey and RightKey: The metadata to join on. If not set, then use the ItemSpec
- public string LeftKey { get; set; }
- public string RightKey { get; set; }
- // LeftMetadata and RightMetadata: The metadata names to include in the result. Specify "*" to include all metadata
- public string[] LeftMetadata { get; set; }
- public string[] RightMetadata { get; set; }
- [Output]
- public ITaskItem[] JoinResult { get; private set; }
- public override bool Execute()
- {
- bool useAllLeftMetadata = LeftMetadata != null && LeftMetadata.Length == 1 && LeftMetadata[0] == "*";
- bool useAllRightMetadata = RightMetadata != null && RightMetadata.Length == 1 && RightMetadata[0] == "*";
- var newItemSpec = string.IsNullOrEmpty(LeftItemSpec)
- ? LeftKey
- : LeftItemSpec;
- JoinResult = Left.Join(Right,
- item => GetKeyValue(LeftKey, item),
- item => GetKeyValue(RightKey, item),
- (left, right) =>
- {
- // If including all metadata from left items and none from right items, just return left items directly
- if (useAllLeftMetadata &&
- string.IsNullOrEmpty(LeftKey) &&
- string.IsNullOrEmpty(LeftItemSpec) &&
- (RightMetadata == null || RightMetadata.Length == 0))
- {
- return left;
- }
- // If including all metadata from right items and none from left items, just return the right items directly
- if (useAllRightMetadata &&
- string.IsNullOrEmpty(RightKey) &&
- string.IsNullOrEmpty(LeftItemSpec) &&
- (LeftMetadata == null || LeftMetadata.Length == 0))
- {
- return right;
- }
- var ret = new TaskItem(GetKeyValue(newItemSpec, left));
- // Weird ordering here is to prefer left metadata in all cases, as CopyToMetadata doesn't overwrite any existing metadata
- if (useAllLeftMetadata)
- {
- // CopyMetadata adds an OriginalItemSpec, which we don't want. So we subsequently remove it
- left.CopyMetadataTo(ret);
- ret.RemoveMetadata("OriginalItemSpec");
- }
- if (!useAllRightMetadata && RightMetadata != null)
- {
- foreach (string name in RightMetadata)
- {
- ret.SetMetadata(name, right.GetMetadata(name));
- }
- }
- if (!useAllLeftMetadata && LeftMetadata != null)
- {
- foreach (string name in LeftMetadata)
- {
- ret.SetMetadata(name, left.GetMetadata(name));
- }
- }
- if (useAllRightMetadata)
- {
- // CopyMetadata adds an OriginalItemSpec, which we don't want. So we subsequently remove it
- right.CopyMetadataTo(ret);
- ret.RemoveMetadata("OriginalItemSpec");
- }
- return (ITaskItem)ret;
- },
- StringComparer.OrdinalIgnoreCase).ToArray();
- return true;
- }
- static string GetKeyValue(string key, ITaskItem item)
- {
- if (string.IsNullOrEmpty(key))
- {
- return item.ItemSpec;
- }
- else
- {
- return item.GetMetadata(key);
- }
- }
- }
- }
|