Exemple #1
0
        /// <summary>
        /// Populates the milestone tableo to be equivalent to the current set of milestones on GitHub.
        /// </summary>
        public async Task PopulateMilestones(RoachRepoId repoId, CancellationToken cancellationtoken = default(CancellationToken))
        {
            var milestones = await _storageQueryUtil.GetMilestones(repoId, RoachItemFilter.All, cancellationtoken);

            var map = milestones.ToDictionary(x => x.Number);

            var list = new List <RoachMilestoneEntity>();

            foreach (var milestone in await _githubQueryUtil.GetMilestones(repoId))
            {
                var isOpen = milestone.State == ItemState.Open;

                RoachMilestone r;
                if (!map.TryGetValue(milestone.Number, out r) ||
                    r.Title != milestone.Title ||
                    r.IsOpen != isOpen)
                {
                    r = new RoachMilestone(repoId, milestone.Number, milestone.Title, isOpen);
                    list.Add(new RoachMilestoneEntity(r));
                }
            }

            if (list.Count > 0)
            {
                // TODO: Need to thread through the CancellationToken here.
                await AzureUtil.InsertBatchUnordered(_milestoneTable, list);
            }
        }
Exemple #2
0
        public async Task <List <Issue> > GetIssues(RoachRepoId repo, RepositoryIssueRequest request, int pageSize = DefaultPageSize)
        {
            var list    = new List <Issue>();
            var options = new ApiOptions()
            {
                PageCount = 1,
                StartPage = 1,
                PageSize  = pageSize
            };

            var done   = false;
            var issues = _client.Issue;

            do
            {
                var pageIssues = request != null
                    ? await issues.GetAllForRepository(repo.Owner, repo.Name, request, options)
                    : await issues.GetAllForRepository(repo.Owner, repo.Name, options);

                list.AddRange(pageIssues);
                if (pageIssues.Count < pageSize)
                {
                    done = true;
                }
                else
                {
                    options.StartPage++;
                }
            } while (!done);

            return(list);
        }
Exemple #3
0
        /// <summary>
        /// Get all issues in the specified label which don't have an assignee and / or a milestone.
        /// </summary>
        public async Task <List <RoachIssue> > GetTriageIssues(RoachRepoId repoId, string label, CancellationToken cancellationToken)
        {
            var unassignedFilter = TableQuery.CombineFilters(
                TableQuery.GenerateFilterCondition(nameof(TableEntity.PartitionKey), QueryComparisons.Equal, EntityKeyUtil.ToKey(repoId)),
                TableOperators.And,
                TableQuery.GenerateFilterCondition(nameof(RoachIssueEntity.Assignee), QueryComparisons.Equal, TheBugsConstants.UnassignedName));
            var unassignedList = await AzureUtil.QueryAsync(_issueTable, new TableQuery <RoachIssueEntity>().Where(unassignedFilter), cancellationToken);

            var unknownMilestoneFilter = TableQuery.CombineFilters(
                TableQuery.GenerateFilterCondition(nameof(TableEntity.PartitionKey), QueryComparisons.Equal, EntityKeyUtil.ToKey(repoId)),
                TableOperators.And,
                TableQuery.GenerateFilterConditionForInt(nameof(RoachIssueEntity.MilestoneNumber), QueryComparisons.Equal, RoachMilestoneId.NoneNumber));
            var unknownMilestoneList = await AzureUtil.QueryAsync(_issueTable, new TableQuery <RoachIssueEntity>().Where(unknownMilestoneFilter), cancellationToken);

            var list    = new List <RoachIssue>();
            var hashSet = new HashSet <int>();

            foreach (var entity in unassignedList.Concat(unknownMilestoneList))
            {
                if (hashSet.Add(entity.Number) && entity.Labels.Contains(label) && entity.IssueType == IssueType.Issue)
                {
                    list.Add(entity.Issue);
                }
            }

            return(list);
        }
Exemple #4
0
        public async Task <List <RoachMilestone> > GetMilestones(RoachRepoId repoId, RoachItemFilter filter = RoachItemFilter.All, CancellationToken cancellationToken = default(CancellationToken))
        {
            var util = FilterUtil.PartitionKey(RoachMilestoneEntity.GetPartitionKey(repoId));

            switch (filter)
            {
            case RoachItemFilter.All:
                // Nothing to do:
                break;

            case RoachItemFilter.Closed:
                util = util.And(FilterUtil.Column(nameof(RoachMilestoneEntity.IsOpen), false));
                break;

            case RoachItemFilter.Open:
                util = util.And(FilterUtil.Column(nameof(RoachMilestoneEntity.IsOpen), true));
                break;

            default:
                throw new Exception($"Bad enum value {filter}");
            }


            var list = await AzureUtil.QueryAsync <RoachMilestoneEntity>(
                _milestoneTable,
                util,
                cancellationToken);

            return(list.Select(x => x.Milestone).OrderBy(x => x.Title).ToList());
        }
Exemple #5
0
        private async Task <List <RoachIssueEntity> > GetIssuesInMilestone(RoachRepoId repoId, int milestone, CancellationToken cancellationToken)
        {
            var filter = FilterUtil
                         .PartitionKey(RoachIssueEntity.GetPartitionKey(repoId))
                         .And(FilterUtil.Column(nameof(RoachIssueEntity.MilestoneNumber), milestone));

            return(await AzureUtil.QueryAsync <RoachIssueEntity>(_issueTable, filter, cancellationToken));
        }
Exemple #6
0
 private RepoInitUtil(RoachRepoId id, GitHubClient githubClient, CloudTableClient client)
 {
     _repoId         = id;
     _client         = githubClient;
     _issueTable     = client.GetTableReference(TableNames.RoachIssueTable);
     _milestoneTable = client.GetTableReference(TableNames.RoachMilestoneTable);
     _statusTable    = client.GetTableReference(TableNames.RoachStatusTable);
 }
Exemple #7
0
        public async Task <IReadOnlyList <Milestone> > GetMilestones(RoachRepoId repoId)
        {
            var request = new MilestoneRequest()
            {
                State = ItemStateFilter.All
            };

            return(await _client.Issue.Milestone.GetAllForRepository(repoId.Owner, repoId.Name, request));
        }
Exemple #8
0
        public async Task <IReadOnlyList <Issue> > GetIssuesChangedSince(RoachRepoId repoId, DateTimeOffset since)
        {
            var request = new RepositoryIssueRequest()
            {
                Since = since,
                State = ItemStateFilter.All,
            };

            return(await _client.Issue.GetAllForRepository(repoId.Owner, repoId.Name, request));
        }
Exemple #9
0
        public async Task <List <RoachIssue> > GetIssues(RoachRepoId repoId, string assignee, List <int> milestones, CancellationToken cancellationToken)
        {
            IEnumerable <RoachIssueEntity> list = await GetIssuesInMilestones(repoId, milestones, cancellationToken);

            if (assignee != null)
            {
                list = list.Where(x => x.Assignee == assignee);
            }

            return(list.Select(x => x.Issue).ToList());
        }
Exemple #10
0
        /// <summary>
        /// Populates the issues tables to reflect changes that occured since the see cref="since"/> parameter.
        /// </summary>
        public async Task PopulateIssuesSince(RoachRepoId repoId, DateTimeOffset since, CancellationToken cancellationtoken = default(CancellationToken))
        {
            var changedIssues = await _githubQueryUtil.GetIssuesChangedSince(repoId, since);

            var issueList = new List <RoachIssueEntity>(capacity: changedIssues.Count);

            foreach (var changedIssue in changedIssues)
            {
                var issue = new RoachIssue(repoId, changedIssue);
                issueList.Add(new RoachIssueEntity(issue));
            }

            // TODO: Need to thread through the CancellationToken here.
            await AzureUtil.InsertBatchUnordered(_issueTable, issueList);
        }
Exemple #11
0
        private async Task <List <RoachIssueEntity> > GetIssuesInMilestones(RoachRepoId repoId, List <int> milestones, CancellationToken cancellationToken)
        {
            if (milestones == null || milestones.Count == 0)
            {
                // Return all of the issues
                return(await AzureUtil.QueryAsync <RoachIssueEntity>(_issueTable, FilterUtil.PartitionKey(RoachIssueEntity.GetPartitionKey(repoId)), cancellationToken));
            }

            var list = new List <RoachIssueEntity>();

            foreach (var milestone in milestones)
            {
                list.AddRange(await GetIssuesInMilestone(repoId, milestone, cancellationToken));
            }

            return(list);
        }
Exemple #12
0
        public static async Task GitHubIssueChanged(
            [QueueTrigger(QueueNames.IssueChanged)] string rawMessage,
            [Table(TableNames.RoachIssueTable)] CloudTable table,
            CancellationToken cancellationToken)
        {
            var issueMessage = JsonConvert.DeserializeObject <IssueMessage>(rawMessage);

            var repoId      = RoachRepoId.ParseFullName(issueMessage.RepoFullName);
            var issueId     = new RoachIssueId(repoId, issueMessage.Number);
            var milestoneId = new RoachMilestoneId(repoId, issueMessage.MilestoneNumber);
            var isOpen      = issueMessage.State == "open";
            var updatedAt   = issueMessage.UpdatedAt != null
                ? DateTimeOffset.Parse(issueMessage.UpdatedAt)
                : (DateTimeOffset?)null;

            var roachIssue  = new RoachIssue(issueId, issueMessage.Assignee ?? TheBugsConstants.UnassignedName, milestoneId, issueMessage.Title, isOpen, issueMessage.Labels, updatedAt);
            var issueEntity = new RoachIssueEntity(roachIssue);
            var operation   = TableOperation.InsertOrReplace(issueEntity);
            await table.ExecuteAsync(TableOperation.InsertOrReplace(issueEntity), cancellationToken);
        }
Exemple #13
0
 public static EntityKey GetEntityKey(RoachRepoId id) => new EntityKey(id.Owner, id.Name);
Exemple #14
0
        public async Task <IEnumerable <Milestone> > GetMilestones(RoachRepoId repoId, IEnumerable <string> milestoneTitles)
        {
            var all = await GetMilestones(repoId);

            return(all.Where(x => milestoneTitles.Contains(x.Title)));
        }
Exemple #15
0
 private static async Task InitRepo(GitHubClient client, CloudStorageAccount account, RoachRepoId id)
 {
     await RepoInitUtil.Initialize(id, client, account, Console.Out);
 }
Exemple #16
0
 internal IssueStatus(RoachRepoId repoId, int number, DateTimeOffset?updatedAt)
 {
     RepoId    = repoId;
     Number    = number;
     UpdatedAt = updatedAt;
 }
Exemple #17
0
        public async Task <IEnumerable <Milestone> > GetMilestones(RoachRepoId repoId, IEnumerable <int> milestoneNumbers)
        {
            var all = await GetMilestones(repoId);

            return(all.Where(x => milestoneNumbers.Contains(x.Number)));
        }
Exemple #18
0
 public RoachStatusEntity(RoachRepoId repoId, DateTimeOffset lastBulkUpdate)
 {
     this.SetEntityKey(GetEntityKey(repoId));
     SetLastBulkUpdate(lastBulkUpdate);
 }
Exemple #19
0
 public static async Task Initialize(RoachRepoId id, GitHubClient githubClient, CloudStorageAccount account, TextWriter logger)
 {
     var util = new RepoInitUtil(id, githubClient, account.CreateCloudTableClient());
     await util.Go(logger);
 }
Exemple #20
0
 public static string GetPartitionKey(RoachRepoId repoId) => EntityKeyUtil.ToKey(repoId);
Exemple #21
0
 public static string ToKey(RoachRepoId id)
 {
     return($"{id.Owner}-{id.Name}");
 }