Skip to content

Commit 8265001

Browse files
authored
fix(parser): anchor comment directives correctly and quote injected descriptions (#1896)
1 parent 81cfdd1 commit 8265001

3 files changed

Lines changed: 79 additions & 6 deletions

File tree

src/parser.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -297,12 +297,16 @@ export class Parser {
297297
let index = 0;
298298
if (expandVariables) {
299299
for (const line of fileSplit) {
300-
interactiveMatch = interactiveMatch ?? /#\s?@\s?[Ii]nteractive/.exec(line);
301-
injectSSHAgent = injectSSHAgent ?? /#\s?@\s?[Ii]njectSSHAgent/.exec(line);
302-
noArtifactsToSourceMatch = noArtifactsToSourceMatch ?? /#\s?@\s?NoArtifactsToSource/i.exec(line);
303-
descriptionMatch = descriptionMatch ?? /#\s?@\s?[Dd]escription (?<description>.*)/.exec(line);
300+
if (/^\s*#/.test(line)) {
301+
interactiveMatch = interactiveMatch ?? /#\s?@\s?[Ii]nteractive/.exec(line);
302+
injectSSHAgent = injectSSHAgent ?? /#\s?@\s?[Ii]njectSSHAgent/.exec(line);
303+
noArtifactsToSourceMatch = noArtifactsToSourceMatch ?? /#\s?@\s?NoArtifactsToSource/i.exec(line);
304+
descriptionMatch = descriptionMatch ?? /#\s?@\s?[Dd]escription (?<description>.*)/.exec(line);
305+
index++;
306+
continue;
307+
}
304308

305-
const jobMatch = /\w:/.exec(line);
309+
const jobMatch = /^[^\s#].*:/.exec(line);
306310
if (jobMatch && (interactiveMatch || descriptionMatch || injectSSHAgent || noArtifactsToSourceMatch)) {
307311
if (interactiveMatch) {
308312
fileSplitClone.splice(index + 1, 0, " gclInteractive: true");
@@ -317,7 +321,7 @@ export class Parser {
317321
index++;
318322
}
319323
if (descriptionMatch) {
320-
fileSplitClone.splice(index + 1, 0, ` gclDescription: ${descriptionMatch?.groups?.description ?? ""}`);
324+
fileSplitClone.splice(index + 1, 0, ` gclDescription: ${JSON.stringify(descriptionMatch?.groups?.description ?? "")}`);
321325
index++;
322326
}
323327
interactiveMatch = null;
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
---
2+
# @Description Runs first
3+
firstjob:
4+
script:
5+
- echo "first"
6+
7+
# @Description Upload source maps. Opt in per brand:
8+
# sourcemaps:
9+
# extends: [.foo]
10+
sourcemaps:
11+
script:
12+
- echo "sourcemaps"
13+
14+
# @Description Deploys everything
15+
deploy to prod:
16+
script:
17+
- echo "deploy"
18+
19+
# @Description Builds the image
20+
build/image:
21+
script:
22+
- echo "build"
23+
24+
# @Description Quoted with a colon: and "quotes"
25+
"quoted job":
26+
script:
27+
- echo "quoted"
28+
29+
# @Description Single quoted job
30+
'single quoted':
31+
script:
32+
- echo "single"
33+
34+
# @Description Runs the tests
35+
plainjob:
36+
script:
37+
- echo "test"
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import {WriteStreamsMock} from "../../../src/write-streams.js";
2+
import {handler} from "../../../src/handler.js";
3+
import {initSpawnSpy} from "../../mocks/utils.mock.js";
4+
import {WhenStatics} from "../../mocks/when-statics.js";
5+
6+
beforeAll(() => {
7+
initSpawnSpy(WhenStatics.all);
8+
});
9+
10+
test.concurrent("comment-directive-anchor --list", async () => {
11+
const writeStreams = new WriteStreamsMock();
12+
await handler({
13+
cwd: "tests/test-cases/comment-directive-anchor/",
14+
list: true,
15+
noColor: true,
16+
stateDir: ".gitlab-ci-local-comment-directive-anchor",
17+
}, writeStreams);
18+
19+
const descriptionOf = (jobName: string) => {
20+
const line = writeStreams.stdoutLines.find(l => l.startsWith(`${jobName} `));
21+
expect(line, `no output line for job ${jobName}`).toBeDefined();
22+
return line!.slice(jobName.length).trimStart().replace(/\s{2,}.*$/, "");
23+
};
24+
25+
expect(descriptionOf("firstjob")).toBe("Runs first");
26+
expect(descriptionOf("sourcemaps")).toBe("Upload source maps. Opt in per brand:");
27+
expect(descriptionOf("deploy to prod")).toBe("Deploys everything");
28+
expect(descriptionOf("build/image")).toBe("Builds the image");
29+
expect(descriptionOf("quoted job")).toBe("Quoted with a colon: and \"quotes\"");
30+
expect(descriptionOf("single quoted")).toBe("Single quoted job");
31+
expect(descriptionOf("plainjob")).toBe("Runs the tests");
32+
});

0 commit comments

Comments
 (0)