public bool IsProductDependency(
            string sourceRepositoryName,
            string sourceBranchName,
            string targetRepositoryName,
            string targetBranchName)
        {
            // Take latest target builds ordered by DateProduced
            var latestTargetBuildsQuery = Builds
                                          .Where(b =>
                                                 (b.GitHubRepository == targetRepositoryName && b.GitHubBranch == targetBranchName) ||
                                                 (b.AzureDevOpsRepository == targetRepositoryName && b.AzureDevOpsBranch == targetBranchName))
                                          .OrderByDescending(b => b.DateProduced);

            // For each build return its Id and HasProductDependencies flag saying
            // if there are any build dependencies in this build that come from source
            // and have IsProduct flag set.
            var buildDependenciesQuery = latestTargetBuildsQuery
                                         .Select(b => new
            {
                Id = b.Id,
                HasProductDependencies = BuildDependencies
                                         .Any(d =>
                                              ((d.DependentBuild.GitHubRepository == sourceRepositoryName &&
                                                d.DependentBuild.GitHubBranch == sourceBranchName) ||
                                               (d.DependentBuild.AzureDevOpsRepository == sourceRepositoryName &&
                                                d.DependentBuild.AzureDevOpsBranch == sourceBranchName)) &&
                                              d.Build == b &&
                                              d.IsProduct)
            });

            // Take the most recent build. Can be null if there are no target builds yet.
            var latestBuild = buildDependenciesQuery.FirstOrDefault();

            return(latestBuild?.HasProductDependencies ?? false);
        }
예제 #2
0
        public static LoadSaveResult LoadBuildData(string bstr)
        {
#if !DEBUG
            try
#endif
            {
                // upgrade:
                bstr = bstr.Replace("\"b_hp\"", "\"hp\"");
                bstr = bstr.Replace("\"b_atk\"", "\"atk\"");
                bstr = bstr.Replace("\"b_def\"", "\"def\"");
                bstr = bstr.Replace("\"b_spd\"", "\"spd\"");
                bstr = bstr.Replace("\"b_crate\"", "\"critical_rate\"");
                bstr = bstr.Replace("\"b_cdmg\"", "\"critical_damage\"");
                bstr = bstr.Replace("\"b_acc\"", "\"accuracy\"");
                bstr = bstr.Replace("\"b_res\"", "\"res\"");

                var bs = JsonConvert.DeserializeObject <List <Build> >(bstr);
                foreach (var b in bs.OrderBy(b => b.Priority))
                {
                    Builds.Add(b);
                }
                foreach (var b in Builds.Where(b => b.Type == BuildType.Link))
                {
                    b.LinkBuild = Program.Builds.FirstOrDefault(bu => bu.ID == b.LinkId);
                }
            }
#if !DEBUG
            catch (Exception e) {
                File.WriteAllText("error_build.txt", e.ToString());
                throw new InvalidOperationException("Error occurred loading Build JSON.\r\n" + e.GetType() + "\r\nInformation is saved to error_build.txt");
            }
#endif

            if (Program.Builds.Count > 0 && (Program.Data?.Monsters == null))
            {
                // backup, just in case
                string destFile = Path.Combine("", string.Format("{0}.backup{1}", "builds", ".json"));
                int    num      = 2;
                while (File.Exists(destFile))
                {
                    destFile = Path.Combine("", string.Format("{0}.backup{1}{2}", "builds", num, ".json"));
                    num++;
                }

                File.Copy("builds.json", destFile);
                return(LoadSaveResult.Failure);
            }

            SanitizeBuilds();

            return(LoadSaveResult.Success);
        }
예제 #3
0
        public async Task <IList <Build> > GetBuildGraphAsync(int buildId)
        {
            var dependencyEntity                   = Model.FindEntityType(typeof(BuildDependency));
            var buildIdColumnName                  = dependencyEntity.FindProperty(nameof(BuildDependency.BuildId)).Relational().ColumnName;
            var dependencyIdColumnName             = dependencyEntity.FindProperty(nameof(BuildDependency.DependentBuildId)).Relational().ColumnName;
            var isProductColumnName                = dependencyEntity.FindProperty(nameof(BuildDependency.IsProduct)).Relational().ColumnName;
            var timeToInclusionInMinutesColumnName = dependencyEntity.FindProperty(nameof(BuildDependency.TimeToInclusionInMinutes)).Relational().ColumnName;
            var edgeTable = dependencyEntity.Relational().TableName;

            var edges = BuildDependencies.FromSql($@"
WITH traverse AS (
        SELECT
            {buildIdColumnName},
            {dependencyIdColumnName},
            {isProductColumnName},
            {timeToInclusionInMinutesColumnName},
            0 as Depth
        from {edgeTable}
        WHERE {buildIdColumnName} = @id
    UNION ALL
        SELECT
            {edgeTable}.{buildIdColumnName},
            {edgeTable}.{dependencyIdColumnName},
            {edgeTable}.{isProductColumnName},
            {edgeTable}.{timeToInclusionInMinutesColumnName},
            traverse.Depth + 1
        FROM {edgeTable}
        INNER JOIN traverse
        ON {edgeTable}.{buildIdColumnName} = traverse.{dependencyIdColumnName}
        WHERE traverse.{isProductColumnName} = 1 -- The thing we previously traversed was a product dependency
            AND traverse.Depth < 10 -- Don't load all the way back because of incorrect isProduct columns
)
SELECT DISTINCT {buildIdColumnName}, {dependencyIdColumnName}, {isProductColumnName}, {timeToInclusionInMinutesColumnName}
FROM traverse;",
                                                  new SqlParameter("id", buildId));

            List <BuildDependency> things = await edges.ToListAsync();

            var buildIds = new HashSet <int>(things.SelectMany(t => new[] { t.BuildId, t.DependentBuildId }));

            buildIds.Add(buildId); // Make sure we always include the requested build, even if it has no edges.

            IQueryable <Build> builds = from build in Builds
                                        where buildIds.Contains(build.Id)
                                        select build;

            Dictionary <int, Build> dict = await builds.ToDictionaryAsync(b => b.Id,
                                                                          b =>
            {
                b.DependentBuildIds = new List <BuildDependency>();
                return(b);
            });

            foreach (var edge in things)
            {
                dict[edge.BuildId].DependentBuildIds.Add(edge);
            }

            // Gather subscriptions used by this build.
            Build primaryBuild       = Builds.First(b => b.Id == buildId);
            var   validSubscriptions = await Subscriptions.Where(s => (s.TargetRepository == primaryBuild.AzureDevOpsRepository || s.TargetRepository == primaryBuild.GitHubRepository) &&
                                                                 (s.TargetBranch == primaryBuild.AzureDevOpsBranch || s.TargetBranch == primaryBuild.GitHubBranch ||
                                                                  $"refs/heads/{s.TargetBranch}" == primaryBuild.AzureDevOpsBranch || $"refs/heads/{s.TargetBranch}" == primaryBuild.GitHubBranch)).ToListAsync();

            // Use the subscriptions to determine what channels are relevant for this build, so just grab the unique channel ID's from valid suscriptions
            var channelIds = validSubscriptions.GroupBy(x => x.ChannelId).Select(y => y.First()).Select(s => s.ChannelId);

            // Acquire list of builds in valid channels
            var channelBuildIds = await BuildChannels.Where(b => channelIds.Any(c => c == b.ChannelId)).Select(s => s.BuildId).ToListAsync();

            var possibleBuilds = await Builds.Where(b => channelBuildIds.Any(c => c == b.Id)).ToListAsync();

            // Calculate total number of builds that are newer.
            foreach (var id in dict.Keys)
            {
                var build = dict[id];
                // Get newer builds data for this channel.
                var newer = possibleBuilds.Where(b => b.GitHubRepository == build.GitHubRepository &&
                                                 b.AzureDevOpsRepository == build.AzureDevOpsRepository &&
                                                 b.DateProduced > build.DateProduced);
                dict[id].Staleness = newer.Count();
            }
            return(dict.Values.ToList());
        }
예제 #4
0
 public static List <Build> GetBuildsById(string buildTypeId)
 {
     return(Builds.Where(b => b.BuildTypeId == buildTypeId).ToList());
 }