예제 #1
0
        /// <summary>
        /// Executes the tool with the given arguments
        /// </summary>
        /// <param name="Arguments">Command line arguments</param>
        /// <returns>Exit code</returns>
        public override int Execute(CommandLineArguments Arguments)
        {
            // Output a message if there are any arguments that are still unused
            Arguments.ApplyTo(this);
            Arguments.CheckAllArgumentsUsed();

            // If the -AllPlatforms argument is specified, add all the known platforms into the list
            if (bAllPlatforms)
            {
                Platforms.UnionWith(UnrealTargetPlatform.GetValidPlatforms());
            }

            // Output a line for each registered platform
            foreach (UnrealTargetPlatform Platform in Platforms)
            {
                UEBuildPlatform BuildPlatform = UEBuildPlatform.GetBuildPlatform(Platform, true);
                if (BuildPlatform != null && BuildPlatform.HasRequiredSDKsInstalled() == SDKStatus.Valid)
                {
                    Log.TraceInformation("##PlatformValidate: {0} VALID", Platform.ToString());
                }
                else
                {
                    Log.TraceInformation("##PlatformValidate: {0} INVALID", Platform.ToString());
                }
            }
            return(0);
        }
        public override int Execute(CommandLineArguments Arguments)
        {
            Arguments.ApplyTo(this);
            Arguments.CheckAllArgumentsUsed();

            // Run the PostBuildSync command
            IOSPostBuildSyncTarget Target = BinaryFormatterUtils.Load <IOSPostBuildSyncTarget>(InputFile);

            IOSToolChain.PostBuildSync(Target);

            return(0);
        }
예제 #3
0
        /// <summary>
        /// Execute the tool mode
        /// </summary>
        /// <param name="Arguments">Command line arguments</param>
        /// <returns>Exit code</returns>
        public override int Execute(CommandLineArguments Arguments)
        {
            // Apply the arguments
            Arguments.ApplyTo(this);
            Arguments.CheckAllArgumentsUsed();

            // Execute the deploy
            TargetReceipt Receipt = TargetReceipt.Read(ReceiptFile);

            Log.WriteLine(LogEventType.Console, "Deploying {0} {1} {2}...", Receipt.TargetName, Receipt.Platform, Receipt.Configuration);
            UEBuildPlatform.GetBuildPlatform(Receipt.Platform).Deploy(Receipt);

            return((int)CompilationResult.Succeeded);
        }
예제 #4
0
        /// <summary>
        /// Entry point for this command
        /// </summary>
        /// <returns></returns>
        public override int Execute(CommandLineArguments Arguments)
        {
            Arguments.ApplyTo(this);
            Arguments.CheckAllArgumentsUsed();

            switch (Type)
            {
            case DocumentationType.BuildConfiguration:
                XmlConfig.WriteDocumentation(OutputFile);
                break;

            case DocumentationType.ModuleRules:
                RulesDocumentation.WriteDocumentation(typeof(ModuleRules), OutputFile);
                break;

            case DocumentationType.TargetRules:
                RulesDocumentation.WriteDocumentation(typeof(TargetRules), OutputFile);
                break;

            default:
                throw new BuildException("Invalid documentation type: {0}", Type);
            }
            return(0);
        }
예제 #5
0
        /// <summary>
        /// Execute the command
        /// </summary>
        /// <param name="Arguments">List of command line arguments</param>
        /// <returns>Always zero, or throws an exception</returns>
        public override int Execute(CommandLineArguments Arguments)
        {
            Arguments.ApplyTo(this);
            Arguments.CheckAllArgumentsUsed();

            Log.TraceInformation("{0}", OutputFile.GetFileName());

            // Read the input files
            string[]        InputFileLines = FileReference.ReadAllLines(InputFileList);
            FileReference[] InputFiles     = InputFileLines.Select(x => x.Trim()).Where(x => x.Length > 0).Select(x => new FileReference(x)).ToArray();

            // Create the combined output file, and print the diagnostics to the log
            HashSet <string> UniqueItems = new HashSet <string>();

            using (StreamWriter RawWriter = new StreamWriter(OutputFile.FullName))
            {
                foreach (FileReference InputFile in InputFiles)
                {
                    string[] Lines = File.ReadAllLines(InputFile.FullName);
                    for (int LineIdx = 0; LineIdx < Lines.Length; LineIdx++)
                    {
                        string Line = Lines[LineIdx];
                        if (!String.IsNullOrWhiteSpace(Line) && UniqueItems.Add(Line))
                        {
                            bool bCanParse = false;

                            string[] Tokens = Line.Split(new string[] { "<#~>" }, StringSplitOptions.None);
                            if (Tokens.Length >= 9)
                            {
                                //string Trial = Tokens[1];
                                string LineNumberStr  = Tokens[2];
                                string FileName       = Tokens[3];
                                string WarningCode    = Tokens[5];
                                string WarningMessage = Tokens[6];
                                string FalseAlarmStr  = Tokens[7];
                                string LevelStr       = Tokens[8];

                                int  LineNumber;
                                bool bFalseAlarm;
                                int  Level;
                                if (int.TryParse(LineNumberStr, out LineNumber) && bool.TryParse(FalseAlarmStr, out bFalseAlarm) && int.TryParse(LevelStr, out Level))
                                {
                                    bCanParse = true;

                                    // Ignore anything in ThirdParty folders
                                    if (FileName.Replace('/', '\\').IndexOf("\\ThirdParty\\", StringComparison.InvariantCultureIgnoreCase) == -1)
                                    {
                                        // Output the line to the raw output file
                                        RawWriter.WriteLine(Line);

                                        // Output the line to the log
                                        if (!bFalseAlarm && Level == 1)
                                        {
                                            Log.WriteLine(LogEventType.Warning, LogFormatOptions.NoSeverityPrefix, "{0}({1}): warning {2}: {3}", FileName, LineNumber, WarningCode, WarningMessage);
                                        }
                                    }
                                }
                            }

                            if (!bCanParse)
                            {
                                Log.WriteLine(LogEventType.Warning, LogFormatOptions.NoSeverityPrefix, "{0}({1}): warning: Unable to parse PVS output line '{2}' (tokens=|{3}|)", InputFile, LineIdx + 1, Line, String.Join("|", Tokens));
                            }
                        }
                    }
                }
            }
            Log.TraceInformation("Written {0} {1} to {2}.", UniqueItems.Count, (UniqueItems.Count == 1)? "diagnostic" : "diagnostics", OutputFile.FullName);
            return(0);
        }
예제 #6
0
        /// <summary>
        /// Main command entry point
        /// </summary>
        /// <param name="Arguments">The command line arguments</param>
        public override void Exec(CommandLineArguments Arguments)
        {
            // Parse the arguments
            bool               bClean           = Arguments.HasOption("-Clean");
            string             PerforcePort     = Arguments.GetStringOrDefault("-P4Port=", null);
            string             PerforceUser     = Arguments.GetStringOrDefault("-P4User="******"-InputFile=", null);
            FileReference      StateFile        = Arguments.GetFileReference("-StateFile=");
            string             ServerUrl        = Arguments.GetStringOrDefault("-Server=", null);
            bool               bKeepHistory     = Arguments.HasOption("-KeepHistory");
            bool               bReadOnly        = Arguments.HasOption("-ReadOnly");
            DirectoryReference SaveUnmatchedDir = Arguments.GetDirectoryReferenceOrDefault("-SaveUnmatched=", null);

            Arguments.CheckAllArgumentsUsed();

            // Build a mapping from category to matching
            Dictionary <string, PatternMatcher> CategoryNameToMatcher = new Dictionary <string, PatternMatcher>();

            foreach (PatternMatcher Matcher in Matchers)
            {
                CategoryNameToMatcher[Matcher.Category] = Matcher;
            }

            // Complete any interrupted operation to update the state file
            CompleteStateTransaction(StateFile);

            // Read the persistent data file
            BuildHealthState State;

            if (!bClean && FileReference.Exists(StateFile))
            {
                Log.TraceInformation("Reading persistent data from {0}", StateFile);
                State = DeserializeJson <BuildHealthState>(StateFile);
            }
            else
            {
                Log.TraceInformation("Creating new persistent data");
                State = new BuildHealthState();
            }

            // Fixup any issues loaded from disk
            foreach (BuildHealthIssue Issue in State.Issues)
            {
                if (Issue.References == null)
                {
                    Issue.References = new SortedSet <string>();
                }
            }

            // Create the Perforce connection
            PerforceConnection Perforce = new PerforceConnection(PerforcePort, PerforceUser, null);

            // Process the input data
            if (InputFile != null)
            {
                // Parse the input file
                Log.TraceInformation("Reading build results from {0}", InputFile);
                InputData InputData = DeserializeJson <InputData>(InputFile);

                // Parse all the builds and add them to the persistent data
                List <InputJob> InputJobs = InputData.Jobs.OrderBy(x => x.Change).ThenBy(x => x.Stream).ToList();
                Stopwatch       Timer     = Stopwatch.StartNew();
                foreach (InputJob InputJob in InputJobs)
                {
                    // Add a new build for each job step
                    foreach (InputJobStep InputJobStep in InputJob.Steps)
                    {
                        BuildHealthJobStep NewBuild = new BuildHealthJobStep(InputJob.Change, InputJob.Name, InputJob.Url, InputJobStep.Name, InputJobStep.Url, null);
                        State.AddBuild(InputJob.Stream, NewBuild);
                    }

                    // Add all the job steps
                    List <InputJobStep> InputJobSteps = InputJob.Steps.OrderBy(x => x.Name).ToList();
                    foreach (InputJobStep InputJobStep in InputJobSteps)
                    {
                        if (InputJobStep.Diagnostics != null && InputJobStep.Diagnostics.Count > 0)
                        {
                            AddStep(Perforce, State, InputJob, InputJobStep);
                        }
                    }

                    // Remove any steps which are empty
                    InputJob.Steps.RemoveAll(x => x.Diagnostics == null || x.Diagnostics.Count == 0);
                }
                InputJobs.RemoveAll(x => x.Steps.Count == 0);
                Log.TraceInformation("Added jobs in {0}s", Timer.Elapsed.TotalSeconds);

                // If there are any unmatched issues, save out the current state and remaining input
                if (SaveUnmatchedDir != null && InputJobs.Count > 0)
                {
                    DirectoryReference.CreateDirectory(SaveUnmatchedDir);
                    if (FileReference.Exists(StateFile))
                    {
                        FileReference.Copy(StateFile, FileReference.Combine(SaveUnmatchedDir, "State.json"), true);
                    }
                    SerializeJson(FileReference.Combine(SaveUnmatchedDir, "Input.json"), InputData);
                }

                // Try to find the next successful build for each stream, so we can close it as part of updating the server
                for (int Idx = 0; Idx < State.Issues.Count; Idx++)
                {
                    BuildHealthIssue Issue = State.Issues[Idx];
                    foreach (string Stream in Issue.Streams.Keys)
                    {
                        Dictionary <string, BuildHealthJobHistory> StepNameToHistory = Issue.Streams[Stream];
                        foreach (string StepName in StepNameToHistory.Keys)
                        {
                            BuildHealthJobHistory IssueHistory = StepNameToHistory[StepName];
                            if (IssueHistory.FailedBuilds.Count > 0 && IssueHistory.NextSuccessfulBuild == null)
                            {
                                // Find the successful build after this change
                                BuildHealthJobStep LastFailedBuild = IssueHistory.FailedBuilds[IssueHistory.FailedBuilds.Count - 1];
                                IssueHistory.NextSuccessfulBuild = State.FindBuildAfter(Stream, LastFailedBuild.Change, StepName);
                            }
                        }
                    }
                }

                // Find the change two days before the latest change being added
                if (InputData.Jobs.Count > 0 && !bKeepHistory)
                {
                    // Find all the unique change numbers for each stream
                    SortedSet <int> ChangeNumbers = new SortedSet <int>();
                    foreach (List <BuildHealthJobStep> Builds in State.Streams.Values)
                    {
                        ChangeNumbers.UnionWith(Builds.Select(x => x.Change));
                    }

                    // Get the latest change record
                    int          LatestChangeNumber = InputData.Jobs.Min(x => x.Change);
                    ChangeRecord LatestChangeRecord = Perforce.GetChange(GetChangeOptions.None, LatestChangeNumber).Data;

                    // Step forward through all the changelists until we get to one we don't want to delete
                    int DeleteChangeNumber = -1;
                    foreach (int ChangeNumber in ChangeNumbers)
                    {
                        ChangeRecord ChangeRecord = Perforce.GetChange(GetChangeOptions.None, ChangeNumber).Data;
                        if (ChangeRecord.Date > LatestChangeRecord.Date - TimeSpan.FromDays(2))
                        {
                            break;
                        }
                        DeleteChangeNumber = ChangeNumber;
                    }

                    // Remove any builds we no longer want to track
                    foreach (List <BuildHealthJobStep> Builds in State.Streams.Values)
                    {
                        Builds.RemoveAll(x => x.Change <= DeleteChangeNumber);
                    }
                }
            }

            // Mark any issues as resolved
            foreach (BuildHealthIssue Issue in State.Issues)
            {
                if (Issue.IsResolved())
                {
                    if (!Issue.ResolvedAt.HasValue)
                    {
                        Issue.ResolvedAt = DateTime.UtcNow;
                    }
                }
                else
                {
                    if (Issue.ResolvedAt.HasValue)
                    {
                        Issue.ResolvedAt = null;
                    }
                }
            }

            // If we're in read-only mode, don't write anything out
            if (bReadOnly)
            {
                return;
            }

            // Save the persistent data
            Log.TraceInformation("Writing persistent data to {0}", StateFile);
            DirectoryReference.CreateDirectory(StateFile.Directory);
            WriteState(StateFile, State);

            // Synchronize with the server
            if (ServerUrl != null)
            {
                // Post any issue updates
                foreach (BuildHealthIssue Issue in State.Issues)
                {
                    PatternMatcher Matcher;
                    if (!CategoryNameToMatcher.TryGetValue(Issue.Category, out Matcher))
                    {
                        continue;
                    }

                    string Summary = Matcher.GetSummary(Issue);
                    if (Issue.Id == -1)
                    {
                        Log.TraceInformation("Adding issue: {0}", Issue);

                        if (Issue.PendingWatchers.Count == 0)
                        {
                            Log.TraceWarning("(No possible causers)");
                        }

                        CommandTypes.AddIssue IssueBody = new CommandTypes.AddIssue();
                        IssueBody.Project = Issue.Project;
                        IssueBody.Summary = Summary;

                        if (Issue.PendingWatchers.Count == 1)
                        {
                            IssueBody.Owner = Issue.PendingWatchers.First();
                        }

                        using (HttpWebResponse Response = SendHttpRequest(String.Format("{0}/api/issues", ServerUrl), "POST", IssueBody))
                        {
                            int ResponseCode = (int)Response.StatusCode;
                            if (!(ResponseCode >= 200 && ResponseCode <= 299))
                            {
                                throw new Exception("Unable to add issue");
                            }
                            Issue.Id = ParseHttpResponse <CommandTypes.AddIssueResponse>(Response).Id;
                        }

                        Issue.PostedSummary = Summary;
                        WriteState(StateFile, State);
                    }
                    else if (Issue.PostedSummary == null || !String.Equals(Issue.PostedSummary, Summary, StringComparison.Ordinal))
                    {
                        Log.TraceInformation("Updating issue {0}", Issue.Id);

                        CommandTypes.UpdateIssue IssueBody = new CommandTypes.UpdateIssue();
                        IssueBody.Summary = Summary;

                        using (HttpWebResponse Response = SendHttpRequest(String.Format("{0}/api/issues/{1}", ServerUrl, Issue.Id), "PUT", IssueBody))
                        {
                            int ResponseCode = (int)Response.StatusCode;
                            if (!(ResponseCode >= 200 && ResponseCode <= 299))
                            {
                                throw new Exception("Unable to add issue");
                            }
                        }

                        Issue.PostedSummary = Summary;
                        WriteState(StateFile, State);
                    }
                }

                // Add any new builds associated with issues
                Dictionary <string, long> JobStepUrlToId = new Dictionary <string, long>(StringComparer.Ordinal);
                foreach (BuildHealthIssue Issue in State.Issues)
                {
                    foreach (KeyValuePair <string, Dictionary <string, BuildHealthJobHistory> > StreamPair in Issue.Streams)
                    {
                        foreach (BuildHealthJobHistory StreamHistory in StreamPair.Value.Values)
                        {
                            foreach (BuildHealthJobStep Build in StreamHistory.Builds)
                            {
                                if (!Build.bPostedToServer)
                                {
                                    Log.TraceInformation("Adding {0} to issue {1}", Build.JobStepUrl, Issue.Id);

                                    CommandTypes.AddBuild AddBuild = new CommandTypes.AddBuild();
                                    AddBuild.Stream      = StreamPair.Key;
                                    AddBuild.Change      = Build.Change;
                                    AddBuild.JobName     = Build.JobName;
                                    AddBuild.JobUrl      = Build.JobUrl;
                                    AddBuild.JobStepName = Build.JobStepName;
                                    AddBuild.JobStepUrl  = Build.JobStepUrl;
                                    AddBuild.ErrorUrl    = Build.ErrorUrl;
                                    AddBuild.Outcome     = (Build == StreamHistory.PrevSuccessfulBuild || Build == StreamHistory.NextSuccessfulBuild)? CommandTypes.Outcome.Success : CommandTypes.Outcome.Error;

                                    using (HttpWebResponse Response = SendHttpRequest(String.Format("{0}/api/issues/{1}/builds", ServerUrl, Issue.Id), "POST", AddBuild))
                                    {
                                        int ResponseCode = (int)Response.StatusCode;
                                        if (!(ResponseCode >= 200 && ResponseCode <= 299))
                                        {
                                            throw new Exception("Unable to add build");
                                        }
                                        Build.Id = ParseHttpResponse <CommandTypes.AddBuildResponse>(Response).Id;
                                    }

                                    Build.bPostedToServer = true;
                                    WriteState(StateFile, State);
                                }
                                if (Build.Id != -1)
                                {
                                    JobStepUrlToId[Build.JobStepUrl] = Build.Id;
                                }
                            }
                        }
                    }
                }

                // Add any new diagnostics
                foreach (BuildHealthIssue Issue in State.Issues)
                {
                    foreach (BuildHealthDiagnostic Diagnostic in Issue.Diagnostics)
                    {
                        if (!Diagnostic.bPostedToServer)
                        {
                            string Summary = Diagnostic.Message;

                            const int MaxLength = 40;
                            if (Summary.Length > MaxLength)
                            {
                                Summary = Summary.Substring(0, MaxLength).TrimEnd();
                            }

                            Log.TraceInformation("Adding diagnostic '{0}' to issue {1}", Summary, Issue.Id);

                            CommandTypes.AddDiagnostic AddDiagnostic = new CommandTypes.AddDiagnostic();

                            long BuildId;
                            if (Diagnostic.JobStepUrl != null && JobStepUrlToId.TryGetValue(Diagnostic.JobStepUrl, out BuildId))
                            {
                                AddDiagnostic.BuildId = BuildId;
                            }
                            else
                            {
                                Console.WriteLine("ERROR");
                            }

                            AddDiagnostic.Message = Diagnostic.Message;
                            AddDiagnostic.Url     = Diagnostic.ErrorUrl;

                            using (HttpWebResponse Response = SendHttpRequest(String.Format("{0}/api/issues/{1}/diagnostics", ServerUrl, Issue.Id), "POST", AddDiagnostic))
                            {
                                int ResponseCode = (int)Response.StatusCode;
                                if (!(ResponseCode >= 200 && ResponseCode <= 299))
                                {
                                    throw new Exception("Unable to add build");
                                }
                            }

                            Diagnostic.bPostedToServer = true;
                            WriteState(StateFile, State);
                        }
                    }
                }

                // Close any issues which are complete
                for (int Idx = 0; Idx < State.Issues.Count; Idx++)
                {
                    BuildHealthIssue Issue = State.Issues[Idx];
                    if (Issue.ResolvedAt.HasValue != Issue.bPostedResolved)
                    {
                        Log.TraceInformation("Setting issue {0} resolved flag to {1}", Issue.Id, Issue.ResolvedAt.HasValue);

                        CommandTypes.UpdateIssue UpdateBody = new CommandTypes.UpdateIssue();
                        UpdateBody.Resolved = Issue.ResolvedAt.HasValue;

                        using (HttpWebResponse Response = SendHttpRequest(String.Format("{0}/api/issues/{1}", ServerUrl, Issue.Id), "PUT", UpdateBody))
                        {
                            int ResponseCode = (int)Response.StatusCode;
                            if (!(ResponseCode >= 200 && ResponseCode <= 299))
                            {
                                throw new Exception("Unable to delete issue");
                            }
                        }

                        Issue.bPostedResolved = Issue.ResolvedAt.HasValue;
                        WriteState(StateFile, State);
                    }
                }

                // Update watchers on any open builds
                foreach (BuildHealthIssue Issue in State.Issues)
                {
                    while (Issue.PendingWatchers.Count > 0)
                    {
                        CommandTypes.Watcher Watcher = new CommandTypes.Watcher();
                        Watcher.UserName = Issue.PendingWatchers.First();

                        using (HttpWebResponse Response = SendHttpRequest(String.Format("{0}/api/issues/{1}/watchers", ServerUrl, Issue.Id), "POST", Watcher))
                        {
                            int ResponseCode = (int)Response.StatusCode;
                            if (!(ResponseCode >= 200 && ResponseCode <= 299))
                            {
                                throw new Exception("Unable to add watcher");
                            }
                        }

                        Issue.PendingWatchers.Remove(Watcher.UserName);
                        Issue.Watchers.Add(Watcher.UserName);

                        WriteState(StateFile, State);
                    }
                }
            }

            // Remove any issues which have been resolved for 24 hours. We have to keep information about issues that have been fixed for some time; we may be updating the same job
            // multiple times while other steps are running, and we don't want to keep opening new issues for it. Also, it can take time for changes to propagate between streams.
            DateTime RemoveIssueTime = DateTime.UtcNow - TimeSpan.FromHours(24.0);

            for (int Idx = 0; Idx < State.Issues.Count; Idx++)
            {
                BuildHealthIssue Issue = State.Issues[Idx];
                if (Issue.ResolvedAt.HasValue && Issue.ResolvedAt.Value < RemoveIssueTime)
                {
                    State.Issues.RemoveAt(Idx--);
                    WriteState(StateFile, State);
                    continue;
                }
            }

            // TODO: VERIFY ISSUES ARE CLOSED
        }
예제 #7
0
        public override void Exec(CommandLineArguments Arguments)
        {
            // Parse the server URL
            string ServerUrl = Arguments.GetStringOrDefault("-Server=", null) ?? Environment.GetEnvironmentVariable("UGS_METADATA_SERVER_URL");

            if (String.IsNullOrEmpty(ServerUrl))
            {
                throw new CommandLineArgumentException("Missing -Server=... argument");
            }

            // Create the command url
            StringBuilder CommandUrl = new StringBuilder();

            CommandUrl.AppendFormat("{0}{1}", ServerUrl, Resource);

            // Replace all the arguments that are embedded into the resource name
            foreach (string ResourceArg in ParseArgumentNamesFromResource(Resource))
            {
                string Value = Arguments.GetString(String.Format("-{0}=", ResourceArg));
                CommandUrl.Replace("{" + ResourceArg + "}", Value);
            }

            // Add all the required and optional parameters
            List <string> QueryParams = new List <string>();

            if (OptionalParams != null)
            {
                foreach (string OptionalParam in OptionalParams)
                {
                    string Value = Arguments.GetStringOrDefault(String.Format("-{0}=", OptionalParam), null);
                    if (Value != null)
                    {
                        QueryParams.Add(String.Format("{0}={1}", OptionalParam, Value));
                    }
                }
            }

            // Append the parameters to the URL
            for (int Idx = 0; Idx < QueryParams.Count; Idx++)
            {
                if (Idx == 0)
                {
                    CommandUrl.Append("?");
                }
                else
                {
                    CommandUrl.Append("&");
                }
                CommandUrl.Append(QueryParams[Idx]);
            }

            // Parse additional options for the message body
            string BodyText = null;

            if (BodyType != null)
            {
                object BodyObject = ParseObject(Arguments, BodyType);
                BodyText = new JavaScriptSerializer().Serialize(BodyObject);
            }

            // Make sure there are no unused arguments
            Arguments.CheckAllArgumentsUsed();

            // Create the request
            HttpWebRequest Request = (HttpWebRequest)WebRequest.Create(CommandUrl.ToString());

            Request.ContentType = "application/json";
            Request.Method      = Verb;
            if (BodyText != null)
            {
                byte[] BodyData = Encoding.UTF8.GetBytes(BodyText);
                using (Stream RequestStream = Request.GetRequestStream())
                {
                    RequestStream.Write(BodyData, 0, BodyData.Length);
                }
            }

            // Read the response
            HttpWebResponse Response = (HttpWebResponse)Request.GetResponse();

            Console.WriteLine("Response: {0} ({1})", (int)Response.StatusCode, Response.StatusDescription);
            using (StreamReader ResponseReader = new StreamReader(Response.GetResponseStream(), Encoding.UTF8))
            {
                string ResponseContent = ResponseReader.ReadToEnd();
                if (!String.IsNullOrEmpty(ResponseContent))
                {
                    Console.WriteLine(Json.Format(ResponseContent));
                }
            }
        }
예제 #8
0
        /// <summary>
        /// Execute the command, having obtained the appropriate mutex
        /// </summary>
        /// <param name="Arguments">Command line arguments</param>
        /// <returns>Exit code</returns>
        private int ExecuteInternal(CommandLineArguments Arguments)
        {
            // Read the target info
            WriteMetadataTargetInfo TargetInfo = BinaryFormatterUtils.Load <WriteMetadataTargetInfo>(Arguments.GetFileReference("-Input="));
            bool bNoManifestChanges            = Arguments.HasOption("-NoManifestChanges");
            int  VersionNumber = Arguments.GetInteger("-Version=");

            Arguments.CheckAllArgumentsUsed();

            // Make sure the version number is correct
            if (VersionNumber != CurrentVersionNumber)
            {
                throw new BuildException("Version number to WriteMetadataMode is incorrect (expected {0}, got {1})", CurrentVersionNumber, VersionNumber);
            }

            // Check if we need to set a build id
            TargetReceipt Receipt = TargetInfo.Receipt;

            if (String.IsNullOrEmpty(Receipt.Version.BuildId))
            {
                // Check if there's an existing version file. If it exists, try to merge in any manifests that are valid (and reuse the existing build id)
                BuildVersion PreviousVersion;
                if (TargetInfo.VersionFile != null && BuildVersion.TryRead(TargetInfo.VersionFile, out PreviousVersion))
                {
                    // Check if we can reuse the existing manifests. This prevents unnecessary builds when switching between projects.
                    Dictionary <FileReference, ModuleManifest> PreviousFileToManifest = new Dictionary <FileReference, ModuleManifest>();
                    if (TryRecyclingManifests(PreviousVersion.BuildId, TargetInfo.FileToManifest.Keys, PreviousFileToManifest))
                    {
                        // Merge files from the existing manifests with the new ones
                        foreach (KeyValuePair <FileReference, ModuleManifest> Pair in PreviousFileToManifest)
                        {
                            ModuleManifest TargetManifest = TargetInfo.FileToManifest[Pair.Key];
                            MergeManifests(Pair.Value, TargetManifest);
                        }

                        // Update the build id to use the current one
                        Receipt.Version.BuildId = PreviousVersion.BuildId;
                    }
                }

                // If the build id is still not set, generate a new one from a GUID
                if (String.IsNullOrEmpty(Receipt.Version.BuildId))
                {
                    Receipt.Version.BuildId = Guid.NewGuid().ToString();
                }
            }
            else
            {
                // Read all the manifests and merge them into the new ones, if they have the same build id
                foreach (KeyValuePair <FileReference, ModuleManifest> Pair in TargetInfo.FileToManifest)
                {
                    ModuleManifest SourceManifest;
                    if (TryReadManifest(Pair.Key, out SourceManifest) && SourceManifest.BuildId == Receipt.Version.BuildId)
                    {
                        MergeManifests(SourceManifest, Pair.Value);
                    }
                }
            }

            // Update the build id in all the manifests, and write them out
            foreach (KeyValuePair <FileReference, ModuleManifest> Pair in TargetInfo.FileToManifest)
            {
                FileReference ManifestFile = Pair.Key;
                if (!UnrealBuildTool.IsFileInstalled(ManifestFile))
                {
                    ModuleManifest Manifest = Pair.Value;
                    Manifest.BuildId = Receipt.Version.BuildId;

                    if (!FileReference.Exists(ManifestFile))
                    {
                        // If the file doesn't already exist, just write it out
                        DirectoryReference.CreateDirectory(ManifestFile.Directory);
                        Manifest.Write(ManifestFile);
                    }
                    else
                    {
                        // Otherwise write it to a buffer first
                        string OutputText;
                        using (StringWriter Writer = new StringWriter())
                        {
                            Manifest.Write(Writer);
                            OutputText = Writer.ToString();
                        }

                        // And only write it to disk if it's been modified. Note that if a manifest is out of date, we should have generated a new build id causing the contents to differ.
                        string CurrentText = FileReference.ReadAllText(ManifestFile);
                        if (CurrentText != OutputText)
                        {
                            if (bNoManifestChanges)
                            {
                                Log.TraceError("Build modifies {0}. This is not permitted. Before:\n    {1}\nAfter:\n    {2}", ManifestFile, CurrentText.Replace("\n", "\n    "), OutputText.Replace("\n", "\n    "));
                            }
                            else
                            {
                                FileReference.WriteAllText(ManifestFile, OutputText);
                            }
                        }
                    }
                }
            }

            // Write out the version file, if it's changed. Since this file is next to the executable, it may be used by multiple targets, and we should avoid modifying it unless necessary.
            if (TargetInfo.VersionFile != null && !UnrealBuildTool.IsFileInstalled(TargetInfo.VersionFile))
            {
                DirectoryReference.CreateDirectory(TargetInfo.VersionFile.Directory);

                StringWriter Writer = new StringWriter();
                Receipt.Version.Write(Writer);

                string Text = Writer.ToString();
                if (!FileReference.Exists(TargetInfo.VersionFile) || File.ReadAllText(TargetInfo.VersionFile.FullName) != Text)
                {
                    File.WriteAllText(TargetInfo.VersionFile.FullName, Text);
                }
            }

            // Write out the receipt
            if (!UnrealBuildTool.IsFileInstalled(TargetInfo.ReceiptFile))
            {
                DirectoryReference.CreateDirectory(TargetInfo.ReceiptFile.Directory);
                Receipt.Write(TargetInfo.ReceiptFile);
            }

            return(0);
        }
예제 #9
0
        /// <summary>
        /// Actual Main function, without exception guards
        /// </summary>
        /// <param name="Args">Command-line arguments</param>
        /// <returns>Exit code</returns>
        static int GuardedMain(string[] Args)
        {
            // Find the index of the first command
            int ModeIndex = 0;

            while (ModeIndex < Args.Length && Args[ModeIndex].StartsWith("-"))
            {
                ModeIndex++;
            }

            // Find all the ToolMode types
            Dictionary <string, Type> ModeNameToType = new Dictionary <string, Type>(StringComparer.OrdinalIgnoreCase);

            foreach (Type Type in Assembly.GetExecutingAssembly().GetTypes())
            {
                ProgramModeAttribute Attribute = Type.GetCustomAttribute <ProgramModeAttribute>();
                if (Attribute != null)
                {
                    ModeNameToType.Add(Attribute.Name, Type);
                }
            }

            // Check if there are any commands specified on the command line.
            if (ModeIndex == Args.Length)
            {
                Log.TraceInformation("BuildAgent");
                Log.TraceInformation("");
                Log.TraceInformation("Utility for managing automated processes on build machines.");
                Log.TraceInformation("");
                Log.TraceInformation("Usage:");
                Log.TraceInformation("    BuildAgent.exe [Command] [-Option1] [-Option2]...");
                Log.TraceInformation("");
                Log.TraceInformation("Commands:");

                PrintCommands(ModeNameToType);

                Log.TraceInformation("");
                Log.TraceInformation("Specify \"Command -Help\" for command-specific help");
                return(0);
            }

            // Get the command name
            string ModeName = Args[ModeIndex];

            // Get the command type
            Type ModeType;

            if (!ModeNameToType.TryGetValue(ModeName, out ModeType))
            {
                Log.TraceError("Unknown command '{0}'.", ModeName);
                Log.TraceInformation("");
                Log.TraceInformation("Available commands");
                PrintCommands(ModeNameToType);
                return(1);
            }

            // Update the mode name to use the correct casing, in case we need it for error messages
            ModeName = ModeType.GetCustomAttribute <ProgramModeAttribute>().Name;

            // Build an argument list for the command, including all the global arguments as well as arguments until the next command
            List <string> ArgumentList = new List <string>();

            for (int Idx = 0; Idx < Args.Length; Idx++)
            {
                if (Idx != ModeIndex)
                {
                    ArgumentList.Add(Args[Idx]);
                }
            }
            CommandLineArguments ModeArguments = new CommandLineArguments(ArgumentList.ToArray());

            // Create the command instance
            ProgramMode Mode = (ProgramMode)Activator.CreateInstance(ModeType);

            // If the help flag is specified, print the help info and exit immediately
            if (ModeArguments.HasOption("-Help"))
            {
                HelpUtils.PrintHelp(ModeName, HelpUtils.GetDescription(ModeType), Mode.GetParameters(ModeArguments));
                return(1);
            }

            // Configure the command
            try
            {
                Mode.Configure(ModeArguments);
                ModeArguments.CheckAllArgumentsUsed();
            }
            catch (CommandLineArgumentException Ex)
            {
                Log.TraceError("{0}: {1}", ModeName, Ex.Message);
                Log.TraceInformation("");
                Log.TraceInformation("Arguments for {0}:", ModeName);

                HelpUtils.PrintTable(Mode.GetParameters(ModeArguments), 4, 24);
                return(1);
            }

            // Execute all the commands
            return(Mode.Execute());
        }
 /// <summary>
 /// Execute the tool mode
 /// </summary>
 /// <param name="Arguments">Command line arguments</param>
 /// <returns>Exit code</returns>
 public override int Execute(CommandLineArguments Arguments)
 {
     // Output a warning if there are any arguments that are still unused
     Arguments.CheckAllArgumentsUsed();
     return(0);
 }