// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.IO; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; namespace Microsoft.DotNet.Build.Tasks { public sealed class TarGzFileCreateFromDirectory : ToolTask { /// /// The path to the directory to be archived. /// [Required] public string SourceDirectory { get; set; } /// /// The path of the archive to be created. /// [Required] public string DestinationArchive { get; set; } /// /// Indicates if the destination archive should be overwritten if it already exists. /// public bool OverwriteDestination { get; set; } /// /// If zipping an entire folder without exclusion patterns, whether to include the folder in the archive. /// public bool IncludeBaseDirectory { get; set; } /// /// An item group of regular expressions for content to exclude from the archive. /// public ITaskItem[] ExcludePatterns { get; set; } protected override bool ValidateParameters() { base.ValidateParameters(); var retVal = true; if (File.Exists(DestinationArchive)) { if (OverwriteDestination == true) { Log.LogMessage(MessageImportance.Low, $"{DestinationArchive} will be overwritten"); } else { Log.LogError($"'{DestinationArchive}' already exists. Did you forget to set '{nameof(OverwriteDestination)}' to true?"); retVal = false; } } SourceDirectory = Path.GetFullPath(SourceDirectory); SourceDirectory = SourceDirectory.EndsWith(Path.DirectorySeparatorChar.ToString()) ? SourceDirectory : SourceDirectory + Path.DirectorySeparatorChar; if (!Directory.Exists(SourceDirectory)) { Log.LogError($"SourceDirectory '{SourceDirectory} does not exist."); retVal = false; } return retVal; } public override bool Execute() { return base.Execute(); } protected override string ToolName { get { return "tar"; } } protected override MessageImportance StandardOutputLoggingImportance { get { return MessageImportance.High; } // or else the output doesn't get logged by default } protected override string GenerateFullPathToTool() { return "tar"; } protected override string GenerateCommandLineCommands() { return $"{GetDestinationArchive()} {GetSourceSpecification()}"; } private string GetSourceSpecification() { if (IncludeBaseDirectory) { var parentDirectory = Directory.GetParent(SourceDirectory).Parent.FullName; var sourceDirectoryName = Path.GetFileName(Path.GetDirectoryName(SourceDirectory)); return $"--directory {parentDirectory} {sourceDirectoryName} {GetExcludes()}"; } else { return $"--directory {SourceDirectory} {GetExcludes()} \".\""; } } private string GetDestinationArchive() { return $"-czf {DestinationArchive}"; } private string GetExcludes() { var excludes = String.Empty; if (ExcludePatterns != null) { foreach (var excludeTaskItem in ExcludePatterns) { excludes += $" --exclude {excludeTaskItem.ItemSpec}"; } } return excludes; } protected override void LogToolCommand(string message) { base.LogToolCommand($"{base.GetWorkingDirectory()}> {message}"); } } }