Skip to content

Commit 811972e

Browse files
authored
Merge pull request #3799 from github/koesie10/modernize-query-history-labels
Use standard configuration variable format for history item labels
2 parents 71cd892 + eeeeadd commit 811972e

File tree

3 files changed

+494
-217
lines changed

3 files changed

+494
-217
lines changed

extensions/ql-vscode/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,8 +302,8 @@
302302
"properties": {
303303
"codeQL.queryHistory.format": {
304304
"type": "string",
305-
"default": "%q on %d - %s %r [%t]",
306-
"markdownDescription": "Default string for how to label query history items.\n* %t is the time of the query\n* %q is the human-readable query name\n* %f is the query file name\n* %d is the database name\n* %r is the number of results\n* %s is a status string"
305+
"default": "${queryName} on ${databaseName} - ${status} ${resultCount} [${startTime}]",
306+
"markdownDescription": "Default string for how to label query history items.\n\nThe following variables are supported:\n* **${startTime}** - the time of the query\n* **${queryName}** - the human-readable query name\n* **${queryFileBasename}** - the query file's base name\n* **${queryLanguage}** - the query language\n* **${databaseName}** - the database name\n* **${resultCount}** - the number of results\n* **${status}** - a status string"
307307
},
308308
"codeQL.queryHistory.ttl": {
309309
"type": "number",

extensions/ql-vscode/src/query-history/history-item-label-provider.ts

Lines changed: 74 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -12,39 +12,63 @@ import type { VariantAnalysisHistoryItem } from "./variant-analysis-history-item
1212
import { assertNever } from "../common/helpers-pure";
1313
import { pluralize } from "../common/word";
1414
import { humanizeQueryStatus } from "./query-status";
15+
import { substituteConfigVariables } from "../common/config-template";
1516

16-
interface InterpolateReplacements {
17-
t: string; // Start time
18-
q: string; // Query name
19-
d: string; // Database/repositories count
20-
r: string; // Result count/Empty
21-
s: string; // Status
22-
f: string; // Query file name
23-
l: string; // Query language
24-
"%": "%"; // Percent sign
25-
}
17+
type LabelVariables = {
18+
startTime: string;
19+
queryName: string;
20+
databaseName: string;
21+
resultCount: string;
22+
status: string;
23+
queryFileBasename: string;
24+
queryLanguage: string;
25+
};
26+
27+
const legacyVariableInterpolateReplacements: Record<
28+
keyof LabelVariables,
29+
string
30+
> = {
31+
startTime: "t",
32+
queryName: "q",
33+
databaseName: "d",
34+
resultCount: "r",
35+
status: "s",
36+
queryFileBasename: "f",
37+
queryLanguage: "l",
38+
};
39+
40+
// If any of the "legacy" variables are used, we need to use legacy interpolation.
41+
const legacyLabelRegex = new RegExp(
42+
`%([${Object.values(legacyVariableInterpolateReplacements).join("")}%])`,
43+
"g",
44+
);
2645

2746
export class HistoryItemLabelProvider {
2847
constructor(private config: QueryHistoryConfig) {
2948
/**/
3049
}
3150

3251
getLabel(item: QueryHistoryInfo) {
33-
let replacements: InterpolateReplacements;
52+
let variables: LabelVariables;
3453
switch (item.t) {
3554
case "local":
36-
replacements = this.getLocalInterpolateReplacements(item);
55+
variables = this.getLocalVariables(item);
3756
break;
3857
case "variant-analysis":
39-
replacements = this.getVariantAnalysisInterpolateReplacements(item);
58+
variables = this.getVariantAnalysisVariables(item);
4059
break;
4160
default:
4261
assertNever(item);
4362
}
4463

45-
const rawLabel = item.userSpecifiedLabel ?? (this.config.format || "%q");
64+
const rawLabel =
65+
item.userSpecifiedLabel ?? (this.config.format || "${queryName}");
4666

47-
return this.interpolate(rawLabel, replacements);
67+
if (legacyLabelRegex.test(rawLabel)) {
68+
return this.legacyInterpolate(rawLabel, variables);
69+
}
70+
71+
return substituteConfigVariables(rawLabel, variables).replace(/\s+/g, " ");
4872
}
4973

5074
/**
@@ -59,55 +83,60 @@ export class HistoryItemLabelProvider {
5983
: getRawQueryName(item);
6084
}
6185

62-
private interpolate(
86+
private legacyInterpolate(
6387
rawLabel: string,
64-
replacements: InterpolateReplacements,
88+
variables: LabelVariables,
6589
): string {
66-
const label = rawLabel.replace(
67-
/%(.)/g,
68-
(match, key: keyof InterpolateReplacements) => {
69-
const replacement = replacements[key];
70-
return replacement !== undefined ? replacement : match;
90+
const replacements = Object.entries(variables).reduce(
91+
(acc, [key, value]) => {
92+
acc[
93+
legacyVariableInterpolateReplacements[key as keyof LabelVariables]
94+
] = value;
95+
return acc;
7196
},
97+
{
98+
"%": "%",
99+
} as Record<string, string>,
72100
);
73101

102+
const label = rawLabel.replace(/%(.)/g, (match, key: string) => {
103+
const replacement = replacements[key];
104+
return replacement !== undefined ? replacement : match;
105+
});
106+
74107
return label.replace(/\s+/g, " ");
75108
}
76109

77-
private getLocalInterpolateReplacements(
78-
item: LocalQueryInfo,
79-
): InterpolateReplacements {
110+
private getLocalVariables(item: LocalQueryInfo): LabelVariables {
80111
const { resultCount = 0, message = "in progress" } =
81112
item.completedQuery || {};
82113
return {
83-
t: item.startTime,
84-
q: item.getQueryName(),
85-
d: item.databaseName,
86-
r: `(${resultCount} results)`,
87-
s: message,
88-
f: item.getQueryFileName(),
89-
l: this.getLanguageLabel(item),
90-
"%": "%",
114+
startTime: item.startTime,
115+
queryName: item.getQueryName(),
116+
databaseName: item.databaseName,
117+
resultCount: `(${resultCount} results)`,
118+
status: message,
119+
queryFileBasename: item.getQueryFileName(),
120+
queryLanguage: this.getLanguageLabel(item),
91121
};
92122
}
93123

94-
private getVariantAnalysisInterpolateReplacements(
124+
private getVariantAnalysisVariables(
95125
item: VariantAnalysisHistoryItem,
96-
): InterpolateReplacements {
126+
): LabelVariables {
97127
const resultCount = item.resultCount
98128
? `(${pluralize(item.resultCount, "result", "results")})`
99129
: "";
100130
return {
101-
t: new Date(item.variantAnalysis.executionStartTime).toLocaleString(
102-
env.language,
103-
),
104-
q: `${item.variantAnalysis.query.name} (${item.variantAnalysis.language})`,
105-
d: buildRepoLabel(item),
106-
r: resultCount,
107-
s: humanizeQueryStatus(item.status),
108-
f: basename(item.variantAnalysis.query.filePath),
109-
l: this.getLanguageLabel(item),
110-
"%": "%",
131+
startTime: new Date(
132+
item.variantAnalysis.executionStartTime,
133+
).toLocaleString(env.language),
134+
queryName: `${item.variantAnalysis.query.name} (${item.variantAnalysis.language})`,
135+
databaseName: buildRepoLabel(item),
136+
resultCount,
137+
status: humanizeQueryStatus(item.status),
138+
queryFileBasename: basename(item.variantAnalysis.query.filePath),
139+
queryLanguage: this.getLanguageLabel(item),
111140
};
112141
}
113142

0 commit comments

Comments
 (0)