public async Task <Result> Execute(GetReviewInfo query) { var pastRevisions = ( from r in _session.Query <ReviewRevision>() where r.ReviewId == query._reviewId orderby r.RevisionNumber select new Revision { Number = r.RevisionNumber, Head = r.HeadCommit, Base = r.BaseCommit } ).ToArray(); var project = await _api.Project(query._reviewId.ProjectId); var commentsTree = GetCommentsTree(query); var reviewStatus = await _query.Query(new GetReviewStatus(query._reviewId)); var fileMatrix = await _query.Query(new GetFileMatrix(query._reviewId)); var buildStatuses = await _api.GetBuildStatuses(query._reviewId.ProjectId, reviewStatus.CurrentHead); var commitStatus = await _query.Query(new GetCommitStatus(query._reviewId)); var author = reviewStatus.Author; return(new Result { FilesToReview = fileMatrix.FindFilesToReview(_currentUser.UserName).ToList(), ReviewId = query._reviewId, Title = reviewStatus.Title, ProjectPath = $"{project.Namespace}/{project.Name}", Description = reviewStatus.Description, SourceBranch = reviewStatus.SourceBranch, TargetBranch = reviewStatus.TargetBranch, PastRevisions = pastRevisions, HasProvisionalRevision = !reviewStatus.RevisionForCurrentHead, HeadCommit = reviewStatus.CurrentHead, BaseCommit = reviewStatus.CurrentBase, HeadRevision = reviewStatus.RevisionForCurrentHead ? new RevisionId.Selected(pastRevisions.Last().Number) : (RevisionId) new RevisionId.Hash(reviewStatus.CurrentHead), State = reviewStatus.MergeRequestState, MergeStatus = reviewStatus.MergeStatus, ReviewFinished = commitStatus.State == CommitStatusState.Success, WebUrl = reviewStatus.WebUrl, FileDiscussions = GetFileDiscussions(query, commentsTree), ReviewDiscussions = GetReviewDiscussions(query, commentsTree), Author = author, FileMatrix = fileMatrix, BuildStatuses = buildStatuses, IsAuthor = reviewStatus.Author.Username == _currentUser.UserName }); }
public async Task Handle(ReviewPublishedEvent @event) { var summary = await _query.Query(new GetReviewStatus(@event.ReviewId)); var fileMatrix = await _query.Query(new GetFileMatrix(@event.ReviewId)); (int reviewedAtLatestRevision, int unreviewedAtLatestRevision) = fileMatrix.CalculateStatistics(); var body = $"{_currentUser.Name} posted review on this merge request.\n\n{reviewedAtLatestRevision} files reviewed in latest version, {unreviewedAtLatestRevision} yet to review.\n\n{summary.UnresolvedDiscussions} unresolved discussions\n\nSee full review [here]({_siteBase}/project/{@event.ReviewId.ProjectId}/review/{@event.ReviewId.ReviewId})"; await _api.CreateNewMergeRequestNote(@event.ReviewId.ProjectId, @event.ReviewId.ReviewId, body); }
public async Task <object> Execute(GetCommitStatusInput query) { var fileMatrix = await _queryRunner.Query(new GetFileMatrix(query.ReviewId)); var summary = await _queryRunner.Query(new GetReviewStatus(query.ReviewId)); return(new { Matrix = fileMatrix, UnresolvedDiscussions = summary.UnresolvedDiscussions, ResolvedDiscussions = summary.ResolvedDiscussions, Discussions = summary.Discussions }); }
public async Task <CommitStatus> Execute(GetCommitStatus query) { var cacheKey = CacheKey(query.ReviewId); var summary = await _queryRunner.Query(new GetReviewStatus(query.ReviewId)); if (_cache.TryGetValue <CommitStatus>(cacheKey, out var cachedStatus) && cachedStatus.Commit == summary.CurrentHead) { return(cachedStatus); } var fileMatrix = await _queryRunner.Query(new GetFileMatrix(query.ReviewId)); var reviewFile = await GetReviewFiles(query, summary); var statusInput = new { Matrix = fileMatrix, UnresolvedDiscussions = summary.UnresolvedDiscussions, ResolvedDiscussions = summary.ResolvedDiscussions, Discussions = summary.Discussions }; var commitStatus = new CommitStatus { Commit = summary.CurrentHead, Name = "Code review (CodeSaw)", TargetUrl = $"{_siteBase}/project/{query.ReviewId.ProjectId}/review/{query.ReviewId.ReviewId}" }; try { var result = _node.ExecuteScriptFunction(reviewFile, "status", statusInput); if (result is JObject obj && obj.Property("ok") != null && obj.Property("reasons") != null) { var isOk = obj.Property("ok").Value.Value <bool>(); var reasons = obj.Property("reasons").Value.Values <string>(); commitStatus.State = isOk ? CommitStatusState.Success : CommitStatusState.Pending; commitStatus.Description = string.Join(", ", reasons); } else { commitStatus.State = CommitStatusState.Failed; commitStatus.Description = "Invalid review script output"; } }
public override async Task Handle(UserTicketCreated command) { var existingUser = await _queryRunner.Query(new FindUserByName(command.UserName)); if (existingUser == null) { await _session.SaveAsync(new ReviewUser { UserName = command.UserName, Name = command.GivenName, AvatarUrl = command.AvatarUrl, Token = command.AccessToken }); Console.WriteLine("New user created"); } else { existingUser.Token = command.AccessToken; existingUser.Name = command.GivenName; existingUser.AvatarUrl = command.AvatarUrl; await _session.UpdateAsync(existingUser); Console.WriteLine($"Found existing user with ID {existingUser.Id}, token updated."); } }
public async Task <Result> Execute(GetReviewEmoji query) { var summary = await _queryRunner.Query(new GetReviewStatus(query.ReviewId)); var fileMatrix = await _queryRunner.Query(new GetFileMatrix(query.ReviewId)); var reviewFile = await GetReviewFiles(query, summary); var statusInput = new { Matrix = fileMatrix, summary.UnresolvedDiscussions, summary.ResolvedDiscussions, summary.Discussions }; try { var result = _node.ExecuteScriptFunction(reviewFile, "thumb", statusInput, _currentUser.UserName); var numericResult = result.Value <int?>(); if (numericResult == 1) { return(Result.AddAndRemove(EmojiType.ThumbsUp, EmojiType.ThumbsDown)); } if (numericResult == -1) { return(Result.AddAndRemove(EmojiType.ThumbsDown, EmojiType.ThumbsUp)); } return(Result.Remove(EmojiType.ThumbsUp, EmojiType.ThumbsDown)); } catch (NodeException e) { Log.Warn(e, "Thumb script failed"); } return(new Result() { ToAdd = new EmojiType[0], ToRemove = new EmojiType[0] }); }
public HooksModule(IQueryRunner query, ICommandDispatcher command) : base("/api/admin") { Get("/projects", async _ => await query.Query(new GetProjects())); Post("/project/{projectId}/setup_hooks", async _ => { await command.Execute(new SetupProjectHooks(_.projectId)); return(new { ok = true }); }); }
private async Task Update(ReviewIdentifier reviewId) { var commitStatus = await _query.Query(new GetCommitStatus(reviewId)); using (var innerScope = _scope.BeginLifetimeScope(UseGlobalAccessToken)) { var api = innerScope.Resolve <IRepository>(); await api.SetCommitStatus(reviewId.ProjectId, commitStatus); } }
public ReviewsModule(IQueryRunner query) : base("/api/reviews") { Get("/", async _ => await query.Query(new GetReviewList(new MergeRequestSearchArgs { State = Request.Query.state, OrderBy = Request.Query.orderBy, Sort = Request.Query.sort, Search = Request.Query.search, Scope = "all", Page = Request.Query.page }))); }
public async Task Handle(ReviewPublishedEvent @event) { var mergeRequest = await _api.GetMergeRequestInfo(@event.ReviewId.ProjectId, @event.ReviewId.ReviewId); if (mergeRequest.Author.Username == _user.UserName) { return; } var emoji = await _query.Query(new GetReviewEmoji(@event.ReviewId)); await SetEmojiAward(@event, emoji.ToAdd, emoji.ToRemove); }
public ReviewInfoModule(IQueryRunner query, ICommandDispatcher command, FeatureToggle features) : base("/api/project/{projectId}/review/{reviewId}") { this.AddToLogContext(new Dictionary <string, Func <object> > { ["api.projectId"] = () => ReviewId.ProjectId, ["api.reviewId"] = () => ReviewId.ReviewId }); Get("/info", async _ => await query.Query(new GetReviewInfo(_.projectId, _.reviewId))); Get("/matrix", async _ => await query.Query(new GetFileMatrix(ReviewId))); if (features.For("DiffV3").IsActive) { Get("/diff/{previous_base}/{previous_head}/{current_base}/{current_head}", async _ => await query.Query(new GetFileDiff_Line( ReviewId, new GetFileDiff_Line.HashSet { PreviousBase = (string)_.previous_base, PreviousHead = (string)_.previous_head, CurrentBase = (string)_.current_base, CurrentHead = (string)_.current_head, }, Request.Query.oldPath, Request.Query.newPath ))); } else { Get("/diff/{previous_base}/{previous_head}/{current_base}/{current_head}", async _ => await query.Query(new GetFileDiff( ReviewId, new GetFileDiff.HashSet { PreviousBase = (string)_.previous_base, PreviousHead = (string)_.previous_head, CurrentBase = (string)_.current_base, CurrentHead = (string)_.current_head, }, Request.Query.oldPath, Request.Query.newPath ))); } Get("/discussions/{previous_base}/{previous_head}/{current_base}/{current_head}/{fileId}", async _ => await query.Query(new GetDiffDiscussions( ReviewId, new GetDiffDiscussions.HashSet { PreviousBase = (string)_.previous_base, PreviousHead = (string)_.previous_head, CurrentBase = (string)_.current_base, CurrentHead = (string)_.current_head, }, ClientFileId.Parse((string)_.fileId), (string)Request.Query.fileName ))); Post("/publish", async _ => { try { await command.Execute(this.Bind <PublishReview>()); return(new { ok = true }); } catch (ReviewConcurrencyException) { return(Response.AsJson(new { error = "review_concurrency" }, HttpStatusCode.Conflict)); } }); Post("/merge_request/merge", async _ => { try { await command.Execute(this.Bind <MergePullRequest>()); return(new { }); } catch (MergeFailedException) { return(Response.AsJson(new { error = "merge_failed" }, HttpStatusCode.ImATeapot)); } }); Get("/status", async _ => await query.Query(new GetReviewStatus(ReviewId))); Get("/commit_status_base", async _ => await query.Query(new GetCommitStatusInput(ReviewId))); Get("/emoji", async _ => await query.Query(new GetReviewEmoji(ReviewId))); }
public async Task <ReviewUser> FindByIdAsync(string userId, CancellationToken cancellationToken) { return(await _queries.Query(new FindUserById(userId))); }
public UserModule(IQueryRunner query) : base("/api/user") { Get("/current", async _ => await query.Query(new GetCurrentUser())); }