Files
UnrealEngineUWP/Engine/Source/Programs/AutomationTool/AutomationUtils/Distiller.cs
Peter Sauerbrei dc1d815f84 refactored the logging system for UAT/UBT to be more like UE4
we now use an enum similar to UE4 with Fatal, Error, Warning, Display, Log, Verbose, and VeryVerbose
Log will only go to the log file unless -verbose is passed on the command line
reduced some of the output from UAT to be Log only

[CL 2631062 by Peter Sauerbrei in Main branch]
2015-07-23 14:51:46 -04:00

265 lines
11 KiB
C#

// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using UnrealBuildTool;
namespace AutomationTool
{
public partial class CommandUtils
{
/// <summary>
/// Given a path to a file, strips off the base directory part of the path
/// </summary>
/// <param name="FilePath">The full path</param>
/// <param name="BaseDirectory">The base directory, which must be the first part of the path</param>
/// <returns>The part of the path after the base directory</returns>
public static string StripBaseDirectory(string InFilePath, string InBaseDirectory)
{
var FilePath = CombinePaths(InFilePath);
var BaseDirectory = CombinePaths(InBaseDirectory);
if (!FilePath.StartsWith(BaseDirectory, StringComparison.InvariantCultureIgnoreCase))
{
throw new AutomationException("Cannot strip the base directory {0} from {1} because it doesn't start with the base directory.", BaseDirectory, FilePath);
}
if (BaseDirectory.EndsWith("/") || BaseDirectory.EndsWith("\\"))
{
return FilePath.Substring(BaseDirectory.Length);
}
return FilePath.Substring(BaseDirectory.Length + 1);
}
/// <summary>
/// Given a path to a "source" file, re-roots the file path to be located under the "destination" folder. The part of the source file's path after the root folder is unchanged.
/// </summary>
/// <param name="FilePath"></param>
/// <param name="BaseDirectory"></param>
/// <param name="NewBaseDirectory"></param>
/// <returns></returns>
public static string MakeRerootedFilePath(string FilePath, string BaseDirectory, string NewBaseDirectory)
{
var RelativeFile = StripBaseDirectory(FilePath, BaseDirectory);
var DestFile = CombinePaths(NewBaseDirectory, RelativeFile);
return DestFile;
}
}
public class Distiller
{
public string SourceBaseDir;
public string DestBaseDir;
public string DestBaseDirSymbols;
public DateTime DestinationTime;
public List<UnrealTargetPlatform> AllLegalPlatforms;
public List<string> RejectStrings;
public Distiller(string InDestBaseDir, string InDestBaseDirSymbols = null, string InSourceBaseDir = null, DateTime? InDestinationTime = null, List<UnrealTargetPlatform> InAllLegalPlatforms = null, bool AllowNoRedist = false)
{
DestBaseDir = CommandUtils.CombinePaths(InDestBaseDir);
SourceBaseDir = InSourceBaseDir;
if (SourceBaseDir == null)
{
SourceBaseDir = CommandUtils.CmdEnv.LocalRoot;
}
SourceBaseDir = CommandUtils.CombinePaths(SourceBaseDir);
if (InDestinationTime == null)
{
DestinationTime = DateTime.Now;
}
else
{
DestinationTime = InDestinationTime.Value;
}
DestBaseDirSymbols = InDestBaseDirSymbols;
if (DestBaseDirSymbols != null)
{
DestBaseDirSymbols = CommandUtils.CombinePaths(DestBaseDirSymbols);
}
AllLegalPlatforms = InAllLegalPlatforms;
if (AllLegalPlatforms == null)
{
AllLegalPlatforms = new List<UnrealTargetPlatform>();
foreach (UnrealTargetPlatform Plat in Enum.GetValues(typeof(UnrealTargetPlatform)))
{
AllLegalPlatforms.Add(Plat);
}
}
RejectStrings = new List<string>
{
CommandUtils.CombinePaths("/CarefullyRedist/"),
CommandUtils.CombinePaths("/NotForLicensees/"),
};
if (!AllowNoRedist)
{
RejectStrings.Add(CommandUtils.CombinePaths("/NoRedist/"));
}
foreach (UnrealTargetPlatform Plat in Enum.GetValues(typeof(UnrealTargetPlatform)))
{
if (!AllLegalPlatforms.Contains(Plat))
{
RejectStrings.Add(CommandUtils.CombinePaths("/" + Plat.ToString() + "/"));
}
}
if (!AllLegalPlatforms.Contains(UnrealTargetPlatform.Win64) && !AllLegalPlatforms.Contains(UnrealTargetPlatform.Win32))
{
RejectStrings.Add(CommandUtils.CombinePaths("/Windows/"));
}
}
public static bool RejectFileOnSubstring(string FileToCopy, string RejectString, string Root = null)
{
var Search = CommandUtils.CombinePaths(FileToCopy);
if (Root == null)
{
Root = CommandUtils.CmdEnv.LocalRoot;
}
if (Search.StartsWith(CommandUtils.CombinePaths(Root), StringComparison.InvariantCultureIgnoreCase))
{
Search = CommandUtils.CombinePaths("/", CommandUtils.StripBaseDirectory(FileToCopy, Root)); // lots of rejects are like "/path/" so we need to be sure we start with a slash
}
if (Search.IndexOf(CommandUtils.CombinePaths(RejectString), 0, StringComparison.InvariantCultureIgnoreCase) >= 0)
{
return true;
}
return false;
}
public bool RejectFile(string FileToCopy, string Root = null)
{
bool Result = false;
foreach (var RejectOn in RejectStrings)
{
if (RejectFileOnSubstring(FileToCopy, RejectOn, Root == null ? SourceBaseDir : Root))
{
Result = true;
break;
}
}
if (Result)
{
CommandUtils.LogVerbose("Rejecting file {0}", FileToCopy);
}
return Result;
}
public static bool IsSymbolFile(UnrealTargetPlatform ForPlatform, string FileToCopy)
{
var DebugExts = Platform.Platforms[ForPlatform].GetDebugFileExtentions();
foreach (var DebugExt in DebugExts)
{
if (Path.GetExtension(FileToCopy).Equals(DebugExt, StringComparison.InvariantCultureIgnoreCase))
{
return true;
}
}
return false;
}
public bool IsSymbolFile(string FileToCopy)
{
foreach (var ForPlatform in AllLegalPlatforms)
{
if (IsSymbolFile(ForPlatform, FileToCopy))
{
return true;
}
}
return false;
}
public string CopyFileToDest(string FileToCopy, bool MoveSymbols = true)
{
if (!CommandUtils.FileExists_NoExceptions(FileToCopy))
{
throw new AutomationException("Can't distill {0}; it doesn't exist", FileToCopy);
}
{
FileInfo FileInfo = new FileInfo(FileToCopy);
FileToCopy = CommandUtils.CombinePaths(FileInfo.FullName);
}
string Dest;
if (MoveSymbols && !String.IsNullOrEmpty(DestBaseDirSymbols) && IsSymbolFile(FileToCopy))
{
Dest = CommandUtils.MakeRerootedFilePath(FileToCopy, SourceBaseDir, DestBaseDirSymbols);
}
else
{
Dest = CommandUtils.MakeRerootedFilePath(FileToCopy, SourceBaseDir, DestBaseDir);
}
if (CommandUtils.FileExists_NoExceptions(Dest))
{
throw new AutomationException("Can't distill to {0}; it already exists", Dest);
}
CommandUtils.CopyFile(FileToCopy, Dest);
{
FileInfo FileInfo = new FileInfo(Dest);
FileInfo.IsReadOnly = false;
FileInfo.CreationTime = DestinationTime;
FileInfo.LastWriteTime = DestinationTime;
Dest = CommandUtils.CombinePaths(FileInfo.FullName);
}
if (!CommandUtils.FileExists_NoExceptions(Dest))
{
throw new AutomationException("Couldn't distill {0} to {1}", FileToCopy, Dest);
}
return Dest;
}
public List<string> Distill(string FullPathAndWildcard, bool bRecursive = false, bool bAllowMissing = false, bool MoveSymbols = true, params string[] Exclusions)
{
var FilesToCopy = new List<string>();
string AbsFile = CommandUtils.CombinePaths(FullPathAndWildcard);
CommandUtils.LogVerbose("Distilling {0}", AbsFile);
string PathOnly = Path.GetDirectoryName(AbsFile);
if (!CommandUtils.DirectoryExists_NoExceptions(PathOnly))
{
if (bAllowMissing)
{
return FilesToCopy;
}
throw new AutomationException("Path {0} was used to distill {1} but it doesn't exist.", PathOnly, AbsFile);
}
var Files = CommandUtils.FindFiles(Path.GetFileName(AbsFile), bRecursive, PathOnly);
var Exclude = new List<string>();
foreach (var Excl in Exclusions)
{
if (!Excl.Contains("/") && !Excl.Contains("\\"))
{
var ExFiles = CommandUtils.FindFiles(Excl, bRecursive, PathOnly);
Exclude.AddRange(ExFiles);
}
}
foreach (var FileToCopy in Files)
{
bool bOk = !Exclude.Contains(FileToCopy) && !RejectFile(FileToCopy, PathOnly);
foreach (var Excl in Exclusions)
{
if (Excl.Contains("/") || Excl.Contains("\\"))
{
if (Excl.Contains("*") || Excl.Contains("?"))
{
throw new AutomationException("Exclusion {0} is illegal, must either be a substring or a wildcard without a path", Excl);
}
bOk = bOk && !RejectFileOnSubstring(FileToCopy, Excl, PathOnly);
}
}
if (bOk)
{
FilesToCopy.Add(CopyFileToDest(FileToCopy, MoveSymbols));
}
}
if (FilesToCopy.Count < 1 && !bAllowMissing)
{
throw new AutomationException("Distill {0} did not produce any files. Recursive option was {1}.", AbsFile, bRecursive.ToString());
}
return FilesToCopy;
}
}
}