| File: MakeDir.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 System.Collections.Generic; using System.IO; using Microsoft.Build.Framework; #nullable disable namespace Microsoft.Build.Tasks { /// <summary> /// A task that creates a directory /// </summary> [MSBuildMultiThreadableTask] public class MakeDir : TaskExtension, IIncrementalTask, IMultiThreadableTask { [Required] public ITaskItem[] Directories { get { ArgumentNullException.ThrowIfNull(_directories, nameof(Directories)); return _directories; } set => _directories = value; } [Output] public ITaskItem[] DirectoriesCreated { get; private set; } public bool FailIfNotIncremental { get; set; } /// <inheritdoc /> public TaskEnvironment TaskEnvironment { get; set; } = TaskEnvironment.Fallback; private ITaskItem[] _directories; #region ITask Members /// <summary> /// Executes the MakeDir task. Create the directory. /// </summary> public override bool Execute() { var items = new List<ITaskItem>(); var directoriesSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); foreach (ITaskItem directory in Directories) { // Sometimes people pass in an item transform like @(myitem->'%(RelativeDir)') in order // to create a bunch of directories for a set of items. But if the item // is in the current project directory, %(RelativeDir) evaluates to empty-string. So, // here we check for that case. if (directory.ItemSpec.Length > 0) { AbsolutePath? absolutePath = null; try { // For speed, eliminate duplicates caused by poor targets authoring, don't absolutize yet to save allocation if (!directoriesSet.Contains(directory.ItemSpec)) { absolutePath = TaskEnvironment.GetAbsolutePath(FileUtilities.FixFilePath(directory.ItemSpec)); // Only log a message if we actually need to create the folder if (!FileUtilities.DirectoryExistsNoThrow(absolutePath)) { if (FailIfNotIncremental) { Log.LogErrorFromResources("MakeDir.Comment", absolutePath.Value.OriginalValue); } else { // Do not log a fake command line as well, as it's superfluous, and also potentially expensive Log.LogMessageFromResources(MessageImportance.Normal, "MakeDir.Comment", absolutePath.Value.OriginalValue); Directory.CreateDirectory(absolutePath); } } items.Add(directory); } } catch (Exception e) when (ExceptionHandling.IsIoRelatedException(e)) { Log.LogErrorWithCodeFromResources("MakeDir.Error", absolutePath?.OriginalValue ?? directory.ItemSpec, e.Message); } // Add even on failure to avoid reattempting directoriesSet.Add(directory.ItemSpec); } } DirectoriesCreated = items.ToArray(); return !Log.HasLoggedErrors; } #endregion } }