Example #1
0
        /// <summary>
        /// Renames/moves a file.
        /// </summary>
        /// <param name="OldName">Old name</param>
        /// <param name="NewName">New name</param>
        /// <returns>True if the operation was successful, false otherwise.</returns>
        public static bool SafeRenameFile(string OldName, string NewName, bool bQuiet = false)
        {
            if (!bQuiet)
            {
                Log.TraceLog("SafeRenameFile {0} {1}", OldName, NewName);
            }
            const int MaxAttempts = 10;
            int       Attempts    = 0;

            bool Result = true;

            do
            {
                Result = true;
                try
                {
                    if (File.Exists(OldName))
                    {
                        FileAttributes Attributes = File.GetAttributes(OldName);
                        if ((Attributes & FileAttributes.ReadOnly) != 0)
                        {
                            File.SetAttributes(OldName, Attributes & ~FileAttributes.ReadOnly);
                        }
                    }
                    File.Move(OldName, NewName);
                }
                catch (Exception Ex)
                {
                    if (File.Exists(OldName) == true || File.Exists(NewName) == false)
                    {
                        Log.TraceWarning("Failed to rename {0} to {1}", OldName, NewName);
                        Log.TraceWarning(LogUtils.FormatException(Ex));
                        Result = false;
                    }
                }
            }while (Result == false && ++Attempts < MaxAttempts);

            return(Result);
        }
        /// <summary>
        /// Kills all child processes of the specified process.
        /// </summary>
        /// <param name="ProcessId">Process id</param>
        public static void KillAllDescendants(Process ProcessToKill)
        {
            bool bKilledAChild;

            do
            {
                bKilledAChild = false;
                // For some reason Process.GetProcesses() sometimes returns the same process twice
                // So keep track of all processes we already tried to kill
                var KilledPids = new HashSet <int>();
                var AllProcs   = Process.GetProcesses();
                foreach (Process KillCandidate in AllProcs)
                {
                    var VisitedPids = new HashSet <int>();
                    if (ProcessManager.CanBeKilled(KillCandidate.ProcessName) &&
                        !KilledPids.Contains(KillCandidate.Id) &&
                        IsOurDescendant(ProcessToKill, KillCandidate.Id, VisitedPids))
                    {
                        KilledPids.Add(KillCandidate.Id);
                        CommandUtils.LogLog("Trying to kill descendant pid={0}, name={1}", KillCandidate.Id, KillCandidate.ProcessName);
                        try
                        {
                            KillCandidate.Kill();
                            bKilledAChild = true;
                        }
                        catch (Exception Ex)
                        {
                            if (!KillCandidate.HasExited)
                            {
                                CommandUtils.LogWarning("Failed to kill descendant:");
                                CommandUtils.LogWarning(LogUtils.FormatException(Ex));
                            }
                        }
                        break;                          // exit the loop as who knows what else died, so let's get processes anew
                    }
                }
            } while (bKilledAChild);
        }
Example #3
0
        /// <summary>
        /// Creates the TraceListener used for file logging.
        /// We cannot simply use a TextWriterTraceListener because we need more flexibility when the file cannot be created.
        /// TextWriterTraceListener lazily creates the file, silently failing when it cannot.
        /// </summary>
        /// <returns>The newly created TraceListener, or null if it could not be created.</returns>
        private static TraceListener CreateLogFileListener(out string LogFilename)
        {
            StreamWriter LogFile       = null;
            const int    MaxAttempts   = 10;
            int          Attempt       = 0;
            var          TempLogFolder = Path.GetTempPath();

            do
            {
                if (Attempt == 0)
                {
                    LogFilename = CommandUtils.CombinePaths(TempLogFolder, "Log.txt");
                }
                else
                {
                    LogFilename = CommandUtils.CombinePaths(TempLogFolder, String.Format("Log_{0}.txt", Attempt));
                }
                try
                {
                    // We do not need to set AutoFlush on the StreamWriter because we set Trace.AutoFlush, which calls it for us.
                    // Not only would this be redundant, StreamWriter AutoFlush does not flush the encoder, while a direct call to
                    // StreamWriter.Flush() will, which is what the Trace system with AutoFlush = true will do.
                    // Internally, FileStream constructor opens the file with good arguments for writing to log files.
                    return(new TextWriterTraceListener(new StreamWriter(LogFilename), "AutomationFileLogListener"));
                }
                catch (Exception Ex)
                {
                    if (Attempt == (MaxAttempts - 1))
                    {
                        // Clear out the LogFilename to indicate we were not able to write one.
                        LogFilename = null;
                        UnrealBuildTool.Log.TraceWarning("Unable to create log file: {0}", LogFilename);
                        UnrealBuildTool.Log.TraceWarning(LogUtils.FormatException(Ex));
                    }
                }
            } while (LogFile == null && ++Attempt < MaxAttempts);
            return(null);
        }
        public void SaveStatus(BuildNode NodeToDo, string Suffix, string NodeStoreName, bool bSaveSharedTempStorage, string GameNameIfAny, string JobStepIDForFailure = null)
        {
            string Contents = "Just a status record: " + Suffix;

            if (!String.IsNullOrEmpty(JobStepIDForFailure) && CommandUtils.IsBuildMachine)
            {
                try
                {
                    Contents = RunECTool(String.Format("getProperties --jobStepId {0} --recurse 1", JobStepIDForFailure), true);
                }
                catch (Exception Ex)
                {
                    CommandUtils.Log(System.Diagnostics.TraceEventType.Warning, "Failed to get properties for jobstep to save them.");
                    CommandUtils.Log(System.Diagnostics.TraceEventType.Warning, LogUtils.FormatException(Ex));
                }
            }
            string RecordOfSuccess = CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine", "Saved", "Logs", NodeToDo.Name + Suffix + ".log");

            CommandUtils.CreateDirectory(Path.GetDirectoryName(RecordOfSuccess));
            CommandUtils.WriteAllText(RecordOfSuccess, Contents);
            TempStorage.StoreToTempStorage(CommandUtils.CmdEnv, NodeStoreName + Suffix, new List <string> {
                RecordOfSuccess
            }, !bSaveSharedTempStorage, GameNameIfAny);
        }
Example #5
0
        public void SaveStatus(TempStorageNodeInfo TempStorageNodeInfo, bool bSaveSharedTempStorage, string JobStepIDForFailure = null)
        {
            string Contents = "Just a status record: " + TempStorageNodeInfo.NodeStorageName;

            if (!String.IsNullOrEmpty(JobStepIDForFailure) && CommandUtils.IsBuildMachine)
            {
                try
                {
                    Contents = RunECTool(String.Format("getProperties --jobStepId {0} --recurse 1", JobStepIDForFailure), true);
                }
                catch (Exception Ex)
                {
                    CommandUtils.LogWarning("Failed to get properties for jobstep to save them.");
                    CommandUtils.LogWarning(LogUtils.FormatException(Ex));
                }
            }
            string RecordOfSuccess = CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine", "Saved", "Logs", TempStorageNodeInfo.NodeStorageName + ".log");

            CommandUtils.CreateDirectory(Path.GetDirectoryName(RecordOfSuccess));
            CommandUtils.WriteAllText(RecordOfSuccess, Contents);
            TempStorage.StoreToTempStorage(TempStorageNodeInfo, new List <string> {
                RecordOfSuccess
            }, !bSaveSharedTempStorage, CommandUtils.CmdEnv.LocalRoot);
        }
Example #6
0
        /// <summary>
        /// Kills all running processes.
        /// </summary>
        public static void KillAll()
        {
            List <IProcess> ProcessesToKill = new List <IProcess>();

            lock (SyncObject)
            {
                foreach (var ProcResult in ActiveProcesses)
                {
                    if (!ProcResult.HasExited)
                    {
                        ProcessesToKill.Add(ProcResult);
                    }
                }
                ActiveProcesses.Clear();
            }
            // Remove processes that can't be killed
            for (int ProcessIndex = ProcessesToKill.Count - 1; ProcessIndex >= 0; --ProcessIndex)
            {
                var ProcessName = ProcessesToKill[ProcessIndex].GetProcessName();
                if (!String.IsNullOrEmpty(ProcessName) && !CanBeKilled(ProcessName))
                {
                    CommandUtils.LogLog("Ignoring process \"{0}\" because it can't be killed.", ProcessName);
                    ProcessesToKill.RemoveAt(ProcessIndex);
                }
            }
            CommandUtils.LogLog("Trying to kill {0} spawned processes.", ProcessesToKill.Count);
            foreach (var Proc in ProcessesToKill)
            {
                CommandUtils.LogLog("  {0}", Proc.GetProcessName());
            }
            if (CommandUtils.IsBuildMachine)
            {
                for (int Cnt = 0; Cnt < 9; Cnt++)
                {
                    bool AllDone = true;
                    foreach (var Proc in ProcessesToKill)
                    {
                        try
                        {
                            if (!Proc.HasExited)
                            {
                                AllDone = false;
                                CommandUtils.LogLog("Waiting for process: {0}", Proc.GetProcessName());
                            }
                        }
                        catch (Exception)
                        {
                            CommandUtils.LogWarning("Exception Waiting for process");
                            AllDone = false;
                        }
                    }
                    try
                    {
                        if (ProcessResult.HasAnyDescendants(Process.GetCurrentProcess()))
                        {
                            AllDone = false;
                            CommandUtils.Log("Waiting for descendants of main process...");
                        }
                    }
                    catch (Exception Ex)
                    {
                        CommandUtils.LogWarning("Exception Waiting for descendants of main process. " + Ex);
                        AllDone = false;
                    }

                    if (AllDone)
                    {
                        break;
                    }
                    Thread.Sleep(10000);
                }
            }
            foreach (var Proc in ProcessesToKill)
            {
                var ProcName = Proc.GetProcessName();
                try
                {
                    if (!Proc.HasExited)
                    {
                        CommandUtils.LogLog("Killing process: {0}", ProcName);
                        Proc.StopProcess(false);
                    }
                }
                catch (Exception Ex)
                {
                    CommandUtils.LogWarning("Exception while trying to kill process {0}:", ProcName);
                    CommandUtils.LogWarning(LogUtils.FormatException(Ex));
                }
            }
            try
            {
                if (CommandUtils.IsBuildMachine && ProcessResult.HasAnyDescendants(Process.GetCurrentProcess()))
                {
                    CommandUtils.LogLog("current process still has descendants, trying to kill them...");
                    ProcessResult.KillAllDescendants(Process.GetCurrentProcess());
                }
            }
            catch (Exception)
            {
                CommandUtils.LogWarning("Exception killing descendants of main process");
            }
        }
Example #7
0
 /// <summary>
 /// Wraps an action in an exception block.
 /// Ensures individual actions can be performed and exceptions won't prevent further actions from being executed.
 /// Useful for shutdown code where shutdown may be in several stages and it's important that all stages get a chance to run.
 /// </summary>
 /// <param name="Action"></param>
 private static void NoThrow(System.Action Action, string ActionDesc)
 {
     try
     {
         Action();
     }
     catch (Exception Ex)
     {
         Log.TraceError("Exception performing nothrow action \"{0}\": {1}", ActionDesc, LogUtils.FormatException(Ex));
     }
 }
Example #8
0
        /// <summary>
        /// Copies a file.
        /// </summary>
        /// <param name="SourceName">Source name</param>
        /// <param name="TargetName">Target name</param>
        /// <returns>True if the operation was successful, false otherwise.</returns>
        public static bool SafeCopyFile(string SourceName, string TargetName, bool bQuiet = false, List <string> IniKeyBlacklist = null, List <string> IniSectionBlacklist = null)
        {
            if (!bQuiet)
            {
                Log.TraceLog("SafeCopyFile {0} {1}", SourceName, TargetName);
            }
            const int MaxAttempts = 10;
            int       Attempts    = 0;

            bool Result = true;

            do
            {
                Result = true;
                bool Retry = true;
                try
                {
                    bool bSkipSizeCheck = false;
                    if (IniKeyBlacklist != null && Path.GetExtension(SourceName) == ".ini")
                    {
                        FilterIniFile(SourceName, TargetName, IniKeyBlacklist, IniSectionBlacklist);
                        // ini files may change size, don't check
                        bSkipSizeCheck = true;
                    }
                    else
                    {
                        if (File.Exists(SourceName))
                        {
                            File.Copy(SourceName, TargetName, overwrite: true);
                        }
                        else
                        {
                            Log.TraceInformation("Skip copying file {0} because it doesn't exist.", SourceName);
                        }
                    }
                    Retry = !File.Exists(TargetName);
                    if (!Retry)
                    {
                        FileInfo SourceInfo = new FileInfo(SourceName);
                        FileInfo TargetInfo = new FileInfo(TargetName);
                        if (!bSkipSizeCheck && SourceInfo.Length != TargetInfo.Length)
                        {
                            Log.TraceInformation("Size mismatch {0} = {1} to {2} = {3}", SourceName, SourceInfo.Length, TargetName, TargetInfo.Length);
                            Retry = true;
                        }
                        // Timestamps should be no more than 2 seconds out - assuming this as exFAT filesystems store timestamps at 2 second intervals:
                        // http://ntfs.com/exfat-time-stamp.htm
                        if (!((SourceInfo.LastWriteTimeUtc - TargetInfo.LastWriteTimeUtc).TotalSeconds < 2 && (SourceInfo.LastWriteTimeUtc - TargetInfo.LastWriteTimeUtc).TotalSeconds > -2))
                        {
                            Log.TraceInformation("Date mismatch {0} = {1} to {2} = {3}", SourceName, SourceInfo.LastWriteTimeUtc, TargetName, TargetInfo.LastWriteTimeUtc);
                            Retry = true;
                        }
                    }
                }
                catch (Exception Ex)
                {
                    Log.TraceInformation("SafeCopyFile Exception was {0}", LogUtils.FormatException(Ex));
                    Retry = true;
                }

                if (Retry)
                {
                    if (Attempts + 1 < MaxAttempts)
                    {
                        Log.TraceInformation("Failed to copy {0} to {1}, deleting, waiting 10s and retrying.", SourceName, TargetName);
                        if (File.Exists(TargetName))
                        {
                            SafeDeleteFile(TargetName);
                        }
                        Thread.Sleep(10000);
                    }
                    else
                    {
                        Log.TraceError("Failed to copy {0} to {1}", SourceName, TargetName);
                    }
                    Result = false;
                }
            }while (Result == false && ++Attempts < MaxAttempts);

            return(Result);
        }
Example #9
0
        /// <summary>
        /// Copies a file.
        /// </summary>
        /// <param name="SourceName">Source name</param>
        /// <param name="TargetName">Target name</param>
        /// <returns>True if the operation was successful, false otherwise.</returns>
        public static bool SafeCopyFile(string SourceName, string TargetName, bool bQuiet = false)
        {
            if (!bQuiet)
            {
                Log.WriteLine(TraceEventType.Information, "SafeCopyFile {0} {1}", SourceName, TargetName);
            }
            const int MaxAttempts = 10;
            int       Attempts    = 0;

            bool Result = true;

            do
            {
                Result = true;
                bool Retry = true;
                try
                {
                    File.Copy(SourceName, TargetName, overwrite: true);
                    Retry = !File.Exists(TargetName);
                    if (!Retry)
                    {
                        FileInfo SourceInfo = new FileInfo(SourceName);
                        FileInfo TargetInfo = new FileInfo(TargetName);
                        if (SourceInfo.Length != TargetInfo.Length)
                        {
                            Log.WriteLine(TraceEventType.Warning, "Size mismatch {0} = {1} to {2} = {3}", SourceName, SourceInfo.Length, TargetName, TargetInfo.Length);
                            Retry = true;
                        }
                        if (!((SourceInfo.LastWriteTimeUtc - TargetInfo.LastWriteTimeUtc).TotalSeconds < 1 && (SourceInfo.LastWriteTimeUtc - TargetInfo.LastWriteTimeUtc).TotalSeconds > -1))
                        {
                            Log.WriteLine(TraceEventType.Warning, "Date mismatch {0} = {1} to {2} = {3}", SourceName, SourceInfo.LastWriteTimeUtc, TargetName, TargetInfo.LastWriteTimeUtc);
                            Retry = true;
                        }
                    }
                }
                catch (Exception Ex)
                {
                    Log.WriteLine(System.Diagnostics.TraceEventType.Warning, "SafeCopyFile Exception was {0}", LogUtils.FormatException(Ex));
                    Retry = true;
                }

                if (Retry)
                {
                    if (Attempts + 1 < MaxAttempts)
                    {
                        Log.WriteLine(TraceEventType.Warning, "Failed to copy {0} to {1}, deleting, waiting 10s and retrying.", SourceName, TargetName);
                        if (File.Exists(TargetName))
                        {
                            SafeDeleteFile(TargetName);
                        }
                        Thread.Sleep(10000);
                    }
                    else
                    {
                        Log.WriteLine(TraceEventType.Warning, "Failed to copy {0} to {1}", SourceName, TargetName);
                    }
                    Result = false;
                }
            }           while (Result == false && ++Attempts < MaxAttempts);

            return(Result);
        }
Example #10
0
        public static int Main()
        {
            var CommandLine = SharedUtils.ParseCommandLine();

            LogUtils.InitLogging(CommandLine);

            ErrorCodes ReturnCode = ErrorCodes.Error_Success;

            try
            {
                HostPlatform.Initialize();

                Log.TraceVerbose("Running on {0} as a {1}-bit process.", HostPlatform.Current.GetType().Name, Environment.Is64BitProcess ? 64 : 32);

                XmlConfigLoader.Init();

                // Log if we're running from the launcher
                var ExecutingAssemblyLocation = CommandUtils.CombinePaths(Assembly.GetExecutingAssembly().Location);
                if (String.Compare(ExecutingAssemblyLocation, CommandUtils.CombinePaths(InternalUtils.ExecutingAssemblyLocation), true) != 0)
                {
                    Log.WriteLine(TraceEventType.Information, "Executed from AutomationToolLauncher ({0})", ExecutingAssemblyLocation);
                }
                Log.WriteLine(TraceEventType.Information, "CWD={0}", Environment.CurrentDirectory);

                // Hook up exit callbacks
                var Domain = AppDomain.CurrentDomain;
                Domain.ProcessExit  += Domain_ProcessExit;
                Domain.DomainUnload += Domain_ProcessExit;
                HostPlatform.Current.SetConsoleCtrlHandler(ProgramCtrlHandler);

                var Version = InternalUtils.ExecutableVersion;
                Log.WriteLine(TraceEventType.Verbose, "{0} ver. {1}", Version.ProductName, Version.ProductVersion);

                // Don't allow simultaneous execution of AT (in the same branch)
                InternalUtils.RunSingleInstance(MainProc, CommandLine);
            }
            catch (Exception Ex)
            {
                // Catch all exceptions and propagate the ErrorCode if we are given one.
                Log.WriteLine(TraceEventType.Error, "AutomationTool terminated with exception:");
                Log.WriteLine(TraceEventType.Error, LogUtils.FormatException(Ex));
                // set the exit code of the process
                if (Ex is AutomationException)
                {
                    ReturnCode = (Ex as AutomationException).ErrorCode;
                }
                else
                {
                    ReturnCode = ErrorCodes.Error_Unknown;
                }
            }
            finally
            {
                // In all cases, do necessary shut down stuff, but don't let any additional exceptions leak out while trying to shut down.

                // Make sure there's no directories on the stack.
                NoThrow(() => CommandUtils.ClearDirStack(), "Clear Dir Stack");

                // Try to kill process before app domain exits to leave the other KillAll call to extreme edge cases
                NoThrow(() => { if (ShouldKillProcesses && !Utils.IsRunningOnMono)
                                {
                                    ProcessManager.KillAll();
                                }
                        }, "Kill All Processes");

                Log.WriteLine(TraceEventType.Information, "AutomationTool exiting with ExitCode={0}", ReturnCode);

                // Can't use NoThrow here because the code logs exceptions. We're shutting down logging!
                LogUtils.ShutdownLogging();
            }

            // STOP: No code beyond the return statement should go beyond this point!
            // Nothing should happen after the finally block above is finished.
            return((int)ReturnCode);
        }
Example #11
0
        public static List <string> FindTempStorageManifests(CommandEnvironment Env, string StorageBlockName, bool LocalOnly = false, bool SharedOnly = false, string GameFolder = "")
        {
            var Files = new List <string>();

            var LocalFiles  = LocalTempStorageManifestFilename(Env, StorageBlockName);
            var LocalParent = Path.GetDirectoryName(LocalFiles);
            var WildCard    = Path.GetFileName(LocalFiles);

            int IndexOfStar = WildCard.IndexOf("*");

            if (IndexOfStar < 0 || WildCard.LastIndexOf("*") != IndexOfStar)
            {
                throw new AutomationException("Wildcard {0} either has no star or it has more than one.", WildCard);
            }

            string PreStarWildcard  = WildCard.Substring(0, IndexOfStar);
            string PostStarWildcard = Path.GetFileNameWithoutExtension(WildCard.Substring(IndexOfStar + 1));

            if (!SharedOnly && DirectoryExists_NoExceptions(LocalParent))
            {
                foreach (var ThisFile in CommandUtils.FindFiles_NoExceptions(WildCard, true, LocalParent))
                {
                    Log("  Found local file {0}", ThisFile);
                    int IndexOfWildcard = ThisFile.IndexOf(PreStarWildcard);
                    if (IndexOfWildcard < 0)
                    {
                        throw new AutomationException("File {0} didn't contain {1}.", ThisFile, PreStarWildcard);
                    }
                    int LastIndexOfWildcardTail = ThisFile.LastIndexOf(PostStarWildcard);
                    if (LastIndexOfWildcardTail < 0 || LastIndexOfWildcardTail < IndexOfWildcard + PreStarWildcard.Length)
                    {
                        throw new AutomationException("File {0} didn't contain {1} or it was before the prefix", ThisFile, PostStarWildcard);
                    }
                    string StarReplacement = ThisFile.Substring(IndexOfWildcard + PreStarWildcard.Length, LastIndexOfWildcardTail - IndexOfWildcard - PreStarWildcard.Length);
                    if (StarReplacement.Length < 1)
                    {
                        throw new AutomationException("Dir {0} didn't have any string to fit the star in the wildcard {1}", ThisFile, WildCard);
                    }
                    if (!Files.Contains(StarReplacement))
                    {
                        Files.Add(StarReplacement);
                    }
                }
            }

            if (!LocalOnly)
            {
                var SharedFiles  = SharedTempStorageManifestFilename(Env, StorageBlockName, GameFolder);
                var SharedParent = Path.GetDirectoryName(Path.GetDirectoryName(SharedFiles));

                if (DirectoryExists_NoExceptions(SharedParent))
                {
                    string[] Dirs = null;

                    try
                    {
                        Dirs = Directory.GetDirectories(SharedParent, Path.GetFileNameWithoutExtension(SharedFiles), SearchOption.TopDirectoryOnly);
                    }
                    catch (Exception Ex)
                    {
                        Log("Unable to Find Directories in {0} with wildcard {1}", SharedParent, Path.GetFileNameWithoutExtension(SharedFiles));
                        Log(" Exception was {0}", LogUtils.FormatException(Ex));
                    }
                    if (Dirs != null)
                    {
                        foreach (var ThisSubDir in Dirs)
                        {
                            int IndexOfWildcard = ThisSubDir.IndexOf(PreStarWildcard);
                            if (IndexOfWildcard < 0)
                            {
                                throw new AutomationException("Dir {0} didn't contain {1}.", ThisSubDir, PreStarWildcard);
                            }
                            int LastIndexOfWildcardTail = ThisSubDir.LastIndexOf(PostStarWildcard);
                            if (LastIndexOfWildcardTail < 0 || LastIndexOfWildcardTail < IndexOfWildcard + PreStarWildcard.Length)
                            {
                                throw new AutomationException("Dir {0} didn't contain {1} or it was before the prefix", ThisSubDir, PostStarWildcard);
                            }
                            string StarReplacement = ThisSubDir.Substring(IndexOfWildcard + PreStarWildcard.Length, LastIndexOfWildcardTail - IndexOfWildcard - PreStarWildcard.Length);
                            if (StarReplacement.Length < 1)
                            {
                                throw new AutomationException("Dir {0} didn't have any string to fit the star in the wildcard {1}", ThisSubDir, WildCard);
                            }
                            // these are a bunch of false positives
                            if (StarReplacement.Contains("-"))
                            {
                                continue;
                            }
                            if (!Files.Contains(StarReplacement))
                            {
                                Files.Add(StarReplacement);
                            }
                        }
                    }
                }
            }

            var OutFiles = new List <string>();

            foreach (var StarReplacement in Files)
            {
                var NewBlock = StorageBlockName.Replace("*", StarReplacement);

                if (TempStorageExists(Env, NewBlock, GameFolder, LocalOnly, true))
                {
                    OutFiles.Add(StarReplacement);
                }
            }
            return(OutFiles);
        }
Example #12
0
        /// <summary>
        /// Compiles all script modules.
        /// </summary>
        /// <param name="Modules">Module project filenames.</param>
        private static void CompileModules(List <string> Modules)
        {
            string DependencyFile = Path.Combine(CommandUtils.CmdEnv.EngineSavedFolder, "UATModuleHashes.xml");

            if (AreDependenciesUpToDate(Modules, DependencyFile) && !GlobalCommandLine.IgnoreDependencies)
            {
                Log.TraceInformation("Dependencies are up to date. Skipping compile.");
                return;
            }

            Log.TraceInformation("Dependencies are out of date. Compiling scripts....");

            // clean old assemblies
            CleanupScriptsAssemblies();

            DateTime StartTime = DateTime.Now;

            string BuildTool = CommandUtils.CmdEnv.MsBuildExe;

            // msbuild (standard on windows, in mono >=5.0 is preferred due to speed and parallel compilation)
            bool UseParallelMsBuild = Path.GetFileNameWithoutExtension(BuildTool).ToLower() == "msbuild";

            if (UseParallelMsBuild)
            {
                string ModulesList = string.Join(";", Modules);

                // Mono has an issue where arugments with semicolons or commas can't be passed through to
                // as arguments so we need to manually construct a temp file with the list of modules
                // see (https://github.com/Microsoft/msbuild/issues/471)
                var UATProjTemplate = CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, @"Engine\Source\Programs\AutomationTool\Scripts\UAT.proj");
                var UATProjFile     = Path.Combine(CommandUtils.CmdEnv.EngineSavedFolder, "UATTempProj.proj");

                string ProjContents = File.ReadAllText(UATProjTemplate);
                ProjContents = ProjContents.Replace("$(Modules)", ModulesList);

                Directory.CreateDirectory(Path.GetDirectoryName(UATProjFile));
                File.WriteAllText(UATProjFile, ProjContents);

                string MsBuildVerbosity = Log.OutputLevel >= LogEventType.Verbose ? "minimal" : "quiet";

                var CmdLine = String.Format("\"{0}\" /p:Configuration={1} /verbosity:{2} /nologo", UATProjFile, BuildConfig, MsBuildVerbosity);
                // suppress the run command because it can be long and intimidating, making the logs around this code harder to read.
                var Result = CommandUtils.Run(BuildTool, CmdLine, Options: CommandUtils.ERunOptions.Default | CommandUtils.ERunOptions.NoLoggingOfRunCommand | CommandUtils.ERunOptions.LoggingOfRunDuration);
                if (Result.ExitCode != 0)
                {
                    throw new AutomationException(String.Format("Failed to build \"{0}\":{1}{2}", UATProjFile, Environment.NewLine, Result.Output));
                }
            }
            else
            {
                // Make sure DefaultScriptsDLLName is compiled first
                var DefaultScriptsProjName = Path.ChangeExtension(DefaultScriptsDLLName, "csproj");

                // Primary modules must be built first
                List <string> PrimaryModules = Modules.Where(M => M.IndexOf(DefaultScriptsProjName, StringComparison.InvariantCultureIgnoreCase) >= 0).ToList();

                foreach (var ModuleName in PrimaryModules)
                {
                    Log.TraceInformation("Building script module: {0}", ModuleName);
                    try
                    {
                        CompileScriptModule(ModuleName);
                    }
                    catch (Exception Ex)
                    {
                        CommandUtils.LogError(LogUtils.FormatException(Ex));
                        throw new AutomationException("Failed to compile module {0}", ModuleName);
                    }
                    break;
                }

                // Second pass, compile everything else
                List <string> SecondaryModules = Modules.Where(M => !PrimaryModules.Contains(M)).ToList();

                // Non-parallel method
                foreach (var ModuleName in SecondaryModules)
                {
                    Log.TraceInformation("Building script module: {0}", ModuleName);
                    try
                    {
                        CompileScriptModule(ModuleName);
                    }
                    catch (Exception Ex)
                    {
                        CommandUtils.LogError(LogUtils.FormatException(Ex));
                        throw new AutomationException("Failed to compile module {0}", ModuleName);
                    }
                }
            }

            TimeSpan Duration = DateTime.Now - StartTime;

            Log.TraceInformation("Compiled {0} modules in {1} secs", Modules.Count, Duration.TotalSeconds);

            HashCollection NewHashes = HashModules(Modules);

            if (NewHashes == null)
            {
                Log.TraceWarning("Failed to save dependency info!");
            }
            else
            {
                NewHashes.SaveToFile(DependencyFile);
                Log.TraceVerbose("Wrote depencencies to {0}", DependencyFile);
            }
        }
Example #13
0
        public static int Main()
        {
            var CommandLine = SharedUtils.ParseCommandLine();

            HostPlatform.Initialize();

            LogUtils.InitLogging(CommandLine);
            Log.WriteLine(TraceEventType.Information, "Running on {0}", HostPlatform.Current.GetType().Name);

            XmlConfigLoader.Init();

            // Log if we're running from the launcher
            var ExecutingAssemblyLocation = CommandUtils.CombinePaths(Assembly.GetExecutingAssembly().Location);

            if (String.Compare(ExecutingAssemblyLocation, CommandUtils.CombinePaths(InternalUtils.ExecutingAssemblyLocation), true) != 0)
            {
                Log.WriteLine(TraceEventType.Information, "Executed from AutomationToolLauncher ({0})", ExecutingAssemblyLocation);
            }
            Log.WriteLine(TraceEventType.Information, "CWD={0}", Environment.CurrentDirectory);

            // Hook up exit callbacks
            var Domain = AppDomain.CurrentDomain;

            Domain.ProcessExit  += Domain_ProcessExit;
            Domain.DomainUnload += Domain_ProcessExit;
            HostPlatform.Current.SetConsoleCtrlHandler(ProgramCtrlHandler);

            var Version = InternalUtils.ExecutableVersion;

            Log.WriteLine(TraceEventType.Verbose, "{0} ver. {1}", Version.ProductName, Version.ProductVersion);

            try
            {
                // Don't allow simultaneous execution of AT (in the same branch)
                ReturnCode = InternalUtils.RunSingleInstance(MainProc, CommandLine);
            }
            catch (Exception Ex)
            {
                Log.WriteLine(TraceEventType.Error, "AutomationTool terminated with exception:");
                Log.WriteLine(TraceEventType.Error, LogUtils.FormatException(Ex));
                Log.WriteLine(TraceEventType.Error, Ex.Message);
                if (ReturnCode == 0)
                {
                    ReturnCode = (int)ErrorCodes.Error_Unknown;
                }
            }

            // Make sure there's no directiories on the stack.
            CommandUtils.ClearDirStack();
            Environment.ExitCode = ReturnCode;

            // Try to kill process before app domain exits to leave the other KillAll call to extreme edge cases
            if (ShouldKillProcesses && !Utils.IsRunningOnMono)
            {
                ProcessManager.KillAll();
            }

            Log.WriteLine(TraceEventType.Information, "AutomationTool exiting with ExitCode={0}", ReturnCode);
            LogUtils.CloseFileLogging();

            return(ReturnCode);
        }