| File: TaskEnvironmentExtensions.cs | Web Access |
| Project: src\msbuild\src\Tasks\Microsoft.Build.Tasks.csproj (Microsoft.Build.Tasks.Core) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; namespace Microsoft.Build.Tasks { /// <summary> /// Extension methods for <see cref="TaskEnvironment"/> and <see cref="AbsolutePath"/> used by built-in tasks. /// </summary> internal static class TaskEnvironmentExtensions { /// <summary> /// Returns the canonical form of an <see cref="AbsolutePath"/> (resolving ".." segments, etc.), /// or the original absolute path if canonicalization fails. /// <see cref="System.IO.Path.GetFullPath(string)"/> on .NET Framework validates path characters and throws /// <see cref="ArgumentException"/> for illegal characters (e.g. <c>|</c>, <c><</c>, <c>></c>). /// .NET Core is more permissive and delegates character validation to the OS. /// </summary> /// <param name="absolutePath">The absolute path to canonicalize.</param> /// <param name="log">Optional logger. When provided, a low-importance diagnostic message is logged on failure.</param> internal static AbsolutePath GetCanonicalFormNoThrow(this AbsolutePath absolutePath, TaskLoggingHelper? log = null) { try { return absolutePath.GetCanonicalForm(); } catch (Exception e) { log?.LogMessageFromResources(MessageImportance.Low, "General.FailedToCanonicalizePath", absolutePath.Value, e.Message); return absolutePath; } } /// <summary> /// Absolutizes each non-empty path in the array using <see cref="TaskEnvironment.GetAbsolutePath"/>. /// Returns <see langword="null"/> if <paramref name="paths"/> is <see langword="null"/>. /// Empty or null entries are passed through unchanged. /// </summary> internal static AbsolutePath[]? GetAbsolutePathsOrNull(this TaskEnvironment taskEnvironment, string[]? paths) { if (paths is null) { return null; } var result = new AbsolutePath[paths.Length]; for (int i = 0; i < paths.Length; i++) { result[i] = string.IsNullOrEmpty(paths[i]) ? new AbsolutePath(paths[i], ignoreRootedCheck: true) : taskEnvironment.GetAbsolutePath(paths[i]); } return result; } /// <summary> /// Returns the absolute path string for <paramref name="path"/>, or the input unchanged /// when it is null or empty. Useful for tolerating optional path inputs that callers may /// later combine with other path segments. /// </summary> internal static string GetAbsolutePathOrEmpty(this TaskEnvironment taskEnvironment, string path) => string.IsNullOrEmpty(path) ? path : taskEnvironment.GetAbsolutePath(path).Value; /// <summary> /// Converts an array of <see cref="AbsolutePath"/> to a string array of <see cref="AbsolutePath.Value"/>s. /// Returns <see langword="null"/> if <paramref name="paths"/> is <see langword="null"/>. /// </summary> internal static string[]? ToStringArray(this AbsolutePath[]? paths) { if (paths is null) { return null; } var result = new string[paths.Length]; for (int i = 0; i < paths.Length; i++) { result[i] = paths[i].Value; } return result; } /// <summary> /// Converts an array of <see cref="AbsolutePath"/> to a string array of <see cref="AbsolutePath.OriginalValue"/>s /// (the user-supplied path before any absolutization/canonicalization). /// Returns <see langword="null"/> if <paramref name="paths"/> is <see langword="null"/>. /// </summary> internal static string[]? ToOriginalValueArray(this AbsolutePath[]? paths) { if (paths is null) { return null; } var result = new string[paths.Length]; for (int i = 0; i < paths.Length; i++) { result[i] = paths[i].OriginalValue; } return result; } } }