Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions src/solutions/solution-problems.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,22 @@ describe('SolutionProblems', () => {
});
});

it('creates merge diagnostic action for current toolbox message wording', () => {
const configPath = 'C:/CubeMX/CubeMX/RTE/CMSIS/RTX_Config.c';
const result = solutionProblems['createMergeDiagnosticAction'](
`update recommended for file '${configPath}' from component 'CMSIS:RTOS2:Keil RTX5&Source'.\nMerge content from update file, rename update file to base file and remove previous base file`,
layerPath,
);

expect(result).toEqual({
message: "update recommended for config file 'RTX_Config.c' from component 'CMSIS:RTOS2:Keil RTX5&Source'.",
code: {
value: 'Open in Merge View',
target: vscode.Uri.parse(`command:${MERGE_FILE_COMMAND_ID}?${encodeURIComponent(JSON.stringify([configPath]))}`),
},
});
});

it('returns undefined merge diagnostic action for non-merge messages', () => {
const result = solutionProblems['createMergeDiagnosticAction'](
"component 'Arm::Device@2.3.4' is missing",
Expand Down Expand Up @@ -347,6 +363,31 @@ describe('SolutionProblems', () => {
}
);

it.each(['required', 'recommended', 'suggested', 'mandatory'] as const)(
'renders merge diagnostics for current toolbox wording with %s update levels',
async updateLevel => {
await solutionProblems.activate({ subscriptions: [] } as unknown as ExtensionContext);
const setSpy = jest.spyOn(vscode.languages.createDiagnosticCollection(), 'set');

await eventHub.fireConvertCompleted({
severity: 'warning',
detection: false,
logMessages: {
success: true,
errors: [],
warnings: [`mylayer.clayer.yml - update ${updateLevel} for file '/packs/Component/${updateLevel}.c'; merge content from update file, rename update file to base file and remove previous base file`],
info: [],
},
});
await waitTimeout();

const [, diagnostics] = setSpy.mock.calls[0] as unknown as [vscode.Uri, readonly vscode.Diagnostic[] | undefined];
expect(diagnostics?.[0].message).toBe(
`update ${updateLevel} for config file '${updateLevel}.c' has a new version available for merge.`
);
}
);

it('keeps non-merge diagnostics on the generic action path', async () => {
await solutionProblems.activate({ subscriptions: [] } as unknown as ExtensionContext);
const setSpy = jest.spyOn(vscode.languages.createDiagnosticCollection(), 'set');
Expand Down
35 changes: 25 additions & 10 deletions src/solutions/solution-problems.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,18 @@ export const enrichLogMessagesFromToolOutput = async (logMessages: LogMessages,

export const MERGE_VIEW_LINK_LABEL = 'Open in Merge View';
export type MergeUpdateLevel = 'required' | 'recommended' | 'suggested' | 'mandatory';
const mergeMessageRegex = /file\s+'([^']+)'\s+update\s+(required|recommended|suggested|mandatory)/i;
const mergeMessagePatterns = [
{
pattern: /file\s+'([^']+)'\s+update\s+(required|recommended|suggested|mandatory)/i,
getLocalPath: (match: RegExpExecArray) => match[1],
getUpdateLevel: (match: RegExpExecArray) => match[2],
},
{
pattern: /update\s+(required|recommended|suggested|mandatory)\s+for\s+file\s+'([^']+)'/i,
getLocalPath: (match: RegExpExecArray) => match[2],
getUpdateLevel: (match: RegExpExecArray) => match[1],
},
] as const;
const mergeComponentRegex = /(?:for|from)\s+component\s+'([^']+)'/i;
export interface MergeMessageMatch {
localPath: string;
Expand Down Expand Up @@ -311,17 +322,21 @@ export class SolutionProblemsImpl implements SolutionProblems {
}

private parseMergeMessage(line: string): MergeMessageMatch | undefined {
const match = mergeMessageRegex.exec(line);
if (!match || match.index === undefined) {
return undefined;
for (const item of mergeMessagePatterns) {
const match = item.pattern.exec(line);
if (!match || match.index === undefined) {
continue;
}

return {
localPath: item.getLocalPath(match),
updateLevel: item.getUpdateLevel(match).toLowerCase() as MergeUpdateLevel,
matchStart: match.index,
matchLength: match[0].length,
};
Comment thread
mguzmanm marked this conversation as resolved.
}

return {
localPath: match[1],
updateLevel: match[2].toLowerCase() as MergeUpdateLevel,
matchStart: match.index,
matchLength: match[0].length,
};
return undefined;
}

private createMergeDiagnosticMessage(localPath: string, updateLevel: MergeUpdateLevel, componentId: string | undefined): string {
Expand Down
Loading