Skip to content

Commit 4649bca

Browse files
committed
refactor: improve review output formatting and centralize logging
- Add logo asset and replace chalk with Logger utility - Enhance markdown and terminal output with contextual information - Add environment-aware code review warnings
1 parent 3466608 commit 4649bca

File tree

4 files changed

+246
-171
lines changed

4 files changed

+246
-171
lines changed

public/logo-color.png

549 KB
Loading

src/cli/commands/helpers.ts

Lines changed: 87 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
import { VcsProvider } from '../../utils/git-service.interface';
1010
import { CodeReviewResult } from '../../providers/provider.types';
1111
import { CreateReviewCommentParams } from '../../services/services.types';
12+
import { Logger } from '../../utils/logger';
1213

1314
export interface ReviewResults {
1415
branchName?: CodeReviewResult[];
@@ -52,12 +53,35 @@ export function printSingleReviewResult(result: CodeReviewResult): void {
5253

5354
export function formatReviewResultsAsMarkdown(
5455
results: CodeReviewResult[],
56+
context?: {
57+
type?: string;
58+
branchName?: string;
59+
commits?: any[];
60+
prDetails?: any;
61+
},
5562
): string {
5663
if (!Array.isArray(results) || results.length === 0) {
57-
return '## 🤖 ReviewCopilot Report\n\n✅ No issues found in this review.\n';
64+
return '✅ No issues found in this review.\n';
5865
}
5966

60-
let comment = '## 🤖 ReviewCopilot Report\n\n';
67+
let comment = '';
68+
69+
if (context?.type === 'branchName' && context.branchName) {
70+
comment += `**Branch:** \`${context.branchName}\`\n\n`;
71+
}
72+
73+
if (
74+
context?.type === 'commitMessages' &&
75+
context.commits &&
76+
context.prDetails
77+
) {
78+
context.commits.forEach((commit: any) => {
79+
const sha = commit.hash;
80+
const url = `https://github.com/${context.prDetails.owner}/${context.prDetails.repo}/commit/${sha}`;
81+
comment += `- [${sha.slice(0, 7)}](${url}): ${commit.message}\n`;
82+
});
83+
comment += '\n';
84+
}
6185

6286
const resultsWithIssues = results.filter(
6387
(result) =>
@@ -70,12 +94,12 @@ export function formatReviewResultsAsMarkdown(
7094
resultsWithIssues.forEach((result) => {
7195
if (result.suggestions.length > 0) {
7296
result.suggestions.forEach((suggestion) => {
73-
comment += `- ${suggestion.message}\n`;
97+
comment += `${suggestion.message}\n`;
7498
});
7599
}
76100

77101
if (result.error) {
78-
comment += `- 🚨 ${result.error.message}\n`;
102+
comment += `🚨 ${result.error.message}\n`;
79103
}
80104

81105
comment += '\n';
@@ -88,19 +112,21 @@ export function formatReviewResultsAsMarkdown(
88112
export async function outputReviewResults(
89113
context: ReviewContext,
90114
results: ReviewResults,
115+
extraContext?: { branchName?: string; commits?: any[] },
91116
): Promise<void> {
92117
context.spinner.text = 'Processing results...';
93118

94119
if (EnvironmentHelpers.isCI) {
95-
await outputToCIPlatform(context, results);
120+
await outputToCIPlatform(context, results, extraContext);
96121
} else {
97-
await outputToTerminal(results);
122+
await outputToTerminal(results, extraContext);
98123
}
99124
}
100125

101126
export async function outputToCIPlatform(
102127
context: ReviewContext,
103128
results: ReviewResults,
129+
extraContext?: { branchName?: string; commits?: any[] },
104130
): Promise<void> {
105131
context.spinner.text = 'Posting review comments...';
106132

@@ -109,7 +135,10 @@ export async function outputToCIPlatform(
109135
}
110136

111137
if (results.branchName) {
112-
const body = formatReviewResultsAsMarkdown(results.branchName);
138+
const body = formatReviewResultsAsMarkdown(results.branchName, {
139+
type: 'branchName',
140+
branchName: extraContext?.branchName,
141+
});
113142

114143
await context.gitService.createIssueComment({
115144
owner: context.prDetails.owner,
@@ -120,7 +149,11 @@ export async function outputToCIPlatform(
120149
}
121150

122151
if (results.commitMessages) {
123-
const body = formatReviewResultsAsMarkdown(results.commitMessages);
152+
const body = formatReviewResultsAsMarkdown(results.commitMessages, {
153+
type: 'commitMessages',
154+
commits: extraContext?.commits,
155+
prDetails: context.prDetails,
156+
});
124157

125158
await context.gitService.createIssueComment({
126159
owner: context.prDetails.owner,
@@ -225,44 +258,78 @@ export async function outputToCIPlatform(
225258
}
226259
}
227260

228-
export async function outputToTerminal(results: ReviewResults): Promise<void> {
261+
export async function outputToTerminal(
262+
results: ReviewResults,
263+
extraContext?: { branchName?: string; commits?: any[]; prDetails?: any },
264+
): Promise<void> {
229265
let hasAnyResults = false;
230266

231267
if (results.branchName) {
232-
console.log(chalk.blue('\n🌿 Branch Name Review Results:'));
233-
console.log('─'.repeat(50));
234-
printReviewResultsToTerminal(results.branchName);
268+
Logger.info('\n🌿 Branch Name Review Results:');
269+
Logger.divider();
270+
printReviewResultsToTerminal(results.branchName, {
271+
type: 'branchName',
272+
branchName: extraContext?.branchName,
273+
});
235274
hasAnyResults = true;
236275
}
237276

238277
if (results.commitMessages && results.commitMessages.length > 0) {
239-
console.log(chalk.blue('\n📝 Commit Messages Review Results:'));
240-
console.log('─'.repeat(50));
241-
printReviewResultsToTerminal(results.commitMessages);
278+
Logger.info('\n📝 Commit Messages Review Results:');
279+
Logger.divider();
280+
printReviewResultsToTerminal(results.commitMessages, {
281+
type: 'commitMessages',
282+
commits: extraContext?.commits,
283+
prDetails: extraContext?.prDetails,
284+
});
242285
hasAnyResults = true;
243286
}
244287

245288
if (results.codeChanges) {
246-
console.log(chalk.blue('\n🔍 Code Changes Review Results:'));
247-
console.log('─'.repeat(50));
289+
Logger.info('\n🔍 Code Changes Review Results:');
290+
Logger.divider();
248291
printReviewResultsToTerminal(results.codeChanges);
249292
hasAnyResults = true;
250293
}
251294

252295
if (!hasAnyResults) {
253-
console.log(chalk.gray('\n📋 No review results to display.'));
296+
Logger.gray('\n📋 No review results to display.');
254297
}
255298
}
256299

257300
export function printReviewResultsToTerminal(
258301
results: CodeReviewResult[],
302+
context?: {
303+
type?: string;
304+
branchName?: string;
305+
commits?: any[];
306+
prDetails?: any;
307+
},
259308
): void {
260309
if (!Array.isArray(results) || results.length === 0) {
261-
console.log(chalk.gray('\n📝 No review results to display.\n'));
310+
Logger.gray('\n📝 No review results to display.\n');
262311
return;
263312
}
264313

265-
console.log('\n📝 Review Results:\n');
314+
if (context?.type === 'branchName' && context.branchName) {
315+
Logger.success(`Branch: ${context.branchName}`);
316+
}
317+
318+
if (
319+
context?.type === 'commitMessages' &&
320+
context.commits &&
321+
context.prDetails
322+
) {
323+
context.commits.forEach((commit: any) => {
324+
const sha = commit.hash;
325+
const url = `https://github.com/${context.prDetails.owner}/${context.prDetails.repo}/commit/${sha}`;
326+
Logger.yellow(`[${sha.slice(0, 7)}] ${commit.message}`);
327+
Logger.gray(url);
328+
});
329+
Logger.white('');
330+
}
331+
332+
Logger.info('\n📝 Review Results:\n');
266333

267334
results.forEach((result) => {
268335
printSingleReviewResult(result);

src/cli/commands/review.ts

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -81,28 +81,36 @@ export async function reviewCommand(
8181

8282
if (context.config.rules.branchName.enabled) {
8383
const results = await reviewBranchName(context);
84-
await outputReviewResults(context, {
85-
branchName: [
86-
{
87-
success: results.success,
88-
suggestions: results.suggestions,
89-
error: results.error,
90-
},
91-
],
92-
});
84+
await outputReviewResults(
85+
context,
86+
{
87+
branchName: [
88+
{
89+
success: results.success,
90+
suggestions: results.suggestions,
91+
error: results.error,
92+
},
93+
],
94+
},
95+
{ branchName: results.branchName },
96+
);
9397
}
9498

9599
if (context.config.rules.commitMessage.enabled) {
96100
const results = await reviewCommitMessages(context);
97-
await outputReviewResults(context, {
98-
commitMessages: [
99-
{
100-
success: results.success,
101-
suggestions: results.suggestions,
102-
error: results.error,
103-
},
104-
],
105-
});
101+
await outputReviewResults(
102+
context,
103+
{
104+
commitMessages: [
105+
{
106+
success: results.success,
107+
suggestions: results.suggestions,
108+
error: results.error,
109+
},
110+
],
111+
},
112+
{ commits: results.commits },
113+
);
106114
}
107115

108116
if (context.config.rules.codeChanges.enabled) {
@@ -167,7 +175,7 @@ async function withReviewErrorHandling(
167175

168176
export async function reviewBranchName(
169177
context: ReviewContext,
170-
): Promise<CodeReviewResult> {
178+
): Promise<CodeReviewResult & { branchName?: string }> {
171179
return withReviewErrorHandling(async () => {
172180
context.spinner.text = 'Reviewing branch name...';
173181
const branchName = await context.vcs.getCurrentBranchName();
@@ -179,19 +187,22 @@ export async function reviewBranchName(
179187
context.config.rules.branchName.prompt,
180188
branchName,
181189
);
182-
return buildSuccessResult([{ message: result, reviewType: 'general' }]);
190+
return {
191+
...buildSuccessResult([{ message: result, reviewType: 'general' }]),
192+
branchName,
193+
};
183194
}, 'Unknown error in branch name review');
184195
}
185196

186197
export async function reviewCommitMessages(
187198
context: ReviewContext,
188-
): Promise<CodeReviewResult> {
199+
): Promise<CodeReviewResult & { commits?: any[] }> {
189200
return withReviewErrorHandling(async () => {
190201
context.spinner.text = 'Getting commit messages...';
191202
const commits = await context.vcs.getPullRequestCommits();
192203
if (!Array.isArray(commits) || commits.length === 0) {
193204
Logger.gray('\nNo commit messages to review.');
194-
return buildSuccessResult([]);
205+
return { ...buildSuccessResult([]), commits: [] };
195206
}
196207

197208
Logger.info(`\nFound ${commits.length} commit message(s) to review:`);
@@ -224,13 +235,28 @@ export async function reviewCommitMessages(
224235
);
225236
}
226237
}
227-
return buildSuccessResult(results.flatMap((result) => result.suggestions));
238+
return {
239+
...buildSuccessResult(results.flatMap((result) => result.suggestions)),
240+
commits,
241+
};
228242
}, 'Failed to get commit messages');
229243
}
230244

231245
export async function reviewCodeChanges(
232246
context: ReviewContext,
233247
): Promise<CodeReviewResult> {
248+
if (!context.prDetails) {
249+
Logger.warning(
250+
'Code changes review is only available in PR/CI environment.',
251+
);
252+
return buildSuccessResult([
253+
{
254+
message: 'Code changes review is only available in PR/CI environment.',
255+
reviewType: 'general',
256+
},
257+
]);
258+
}
259+
234260
return withReviewErrorHandling(async () => {
235261
context.spinner.text = 'Getting code changes...';
236262
const pullRequestReviewInfo = await context.vcs.getPullRequestFiles();

0 commit comments

Comments
 (0)