File: src\GetLicenseFilePath.cs
Web Access
Project: Microsoft.DotNet.Arcade.Sdk.csproj (Microsoft.DotNet.Arcade.Sdk)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

namespace Microsoft.DotNet.Arcade.Sdk;

/// <summary>
/// Finds a license file in the given directory.
/// File is considered a license file if its name matches 'license(.txt|.md|)', ignoring case.
/// </summary>
[MSBuildMultiThreadableTask]
public class GetLicenseFilePath : Task, IMultiThreadableTask
{
    /// <summary>Injected by MSBuild so paths resolve against the project directory in multithreaded builds.</summary>
    public TaskEnvironment TaskEnvironment { get; set; } = TaskEnvironment.Fallback;

    /// <summary>
    /// Full path to the directory to search for the license file.
    /// </summary>
    [Required]
    public string Directory { get; set; }

    /// <summary>
    /// Full path to the license file, or empty if it is not found.
    /// </summary>
    [Output]
    public string Path { get; private set; }

    public override bool Execute()
    {
        const string fileName = "license";

        var options = new EnumerationOptions
        {
            MatchCasing = MatchCasing.CaseInsensitive,
            RecurseSubdirectories = false,
            MatchType = MatchType.Simple
        };

        options.AttributesToSkip |= FileAttributes.Directory;

        AbsolutePath directory = TaskEnvironment.GetAbsolutePath(Directory);

        IEnumerable<string> enumerateFiles(string extension) =>
            System.IO.Directory.EnumerateFileSystemEntries(directory, fileName + extension, options);

        var matches = 
            (from extension in new[] { ".txt", ".md", "" }
             from path in enumerateFiles(extension)
             select path).ToArray();

        if (matches.Length == 0)
        {
            Log.LogError($"No license file found in '{Directory}'.");
        }
        else if (matches.Length > 1)
        {
            Log.LogError($"Multiple license files found in '{Directory}': '{string.Join("', '", matches)}'.");
        }
        else 
        {
            Path = matches[0];
        }

        return !Log.HasLoggedErrors;
    }
}