Exemplo n.º 1
0
    public List <ISharedCookedBuild> FindBestBuilds()
    {
        // Attempt manifest searching first
        ConfigHierarchy Hierarchy = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, DirectoryReference.FromFile(ProjectFile), UnrealTargetPlatform.Win64);

        IEnumerable <string> RawSharedCookedSources = null;

        Hierarchy.TryGetValues("SharedCookedBuildSettings", "SharedCookedSources", out RawSharedCookedSources);
        if (RawSharedCookedSources == null)
        {
            throw new AutomationException("Unable to locate shared cooked builds. SharedCookedSources not set in Engine.ini [SharedCookedBuildSettings]");
        }

        List <Dictionary <string, string> > ParsedSharedCookSources = new List <Dictionary <string, string> >();

        foreach (string RawConfig in RawSharedCookedSources)
        {
            Dictionary <string, string> ParsedSource = null;
            if (ConfigHierarchy.TryParse(RawConfig, out ParsedSource))
            {
                ParsedSharedCookSources.Add(ParsedSource);
            }
        }

        List <ISharedCookedBuild> CandidateBuilds = new List <ISharedCookedBuild>();

        // If existing sync is present, stick to it. Read version out of sync file
        foreach (string Platform in TargetPlatforms)
        {
            FileReference SyncedBuildFile = new FileReference(CommandUtils.CombinePaths(InstallPath.FullName, Platform, SyncedBuildFileName));
            if (FileReference.Exists(SyncedBuildFile))
            {
                string[] SyncedBuildInfo = FileReference.ReadAllLines(SyncedBuildFile);
                int      SyncedCL        = int.Parse(SyncedBuildInfo[0]);
                if (IsValidCL(SyncedCL, BuildType, LocalSync))
                {
                    CandidateBuilds.Add(new ExistingSharedCookedBuild()
                    {
                        CL = SyncedCL, Platform = Platform
                    });
                }
            }
        }

        foreach (Dictionary <string, string> Source in ParsedSharedCookSources)
        {
            SharedCookSource SourceType = (SharedCookSource)Enum.Parse(typeof(SharedCookSource), Source["Type"], true);
            foreach (string Platform in TargetPlatforms)
            {
                if (SourceType == SharedCookSource.Manifest)
                {
                    CandidateBuilds.AddRange(FindValidManifestBuilds(Source["Path"], Platform));
                }
                else if (SourceType == SharedCookSource.LooseFiles)
                {
                    CandidateBuilds.AddRange(FindValidLooseBuilds(Source["Path"], Platform));
                }
            }
        }

        // Strip all failed searches
        CandidateBuilds.RemoveAll(x => x == null);

        // Make sure we have a matching CL for all target platforms, regardless of source
        List <int> OrderedDistinctCLs = CandidateBuilds.Select(x => x.CL).Distinct().OrderByDescending(i => i).ToList();
        int        BestCL             = -1;

        foreach (int CL in OrderedDistinctCLs)
        {
            // Ensure we have a platform for each
            HashSet <string> CLPlatforms = new HashSet <string>(CandidateBuilds.Where(x => x.CL == CL).Select(x => x.Platform).ToList());
            if (CLPlatforms.SetEquals(TargetPlatforms))
            {
                BestCL = CL;
                break;
            }
        }

        if (BestCL < 0)
        {
            CommandUtils.LogError("Could not locate valid shared cooked build for all target platforms");
            CommandUtils.LogError("Current CL: {0}, Current Code CL: {1}", LocalSync.Changelist, LocalSync.CompatibleChangelist);
        }

        return(CandidateBuilds.Where(x => x.CL == BestCL).ToList());
    }