Skip to content

Commit 6e102d0

Browse files
feat: add support for working dir
1 parent 12c3a1b commit 6e102d0

8 files changed

+104
-45
lines changed

README.md

+27-26
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,19 @@ to install the most recent `nightly` clippy version.
1919
on: push
2020
name: Clippy check
2121
jobs:
22-
clippy_check:
23-
runs-on: ubuntu-latest
24-
steps:
25-
- uses: actions/checkout@v1
26-
- uses: actions-rs/toolchain@v1
27-
with:
28-
toolchain: nightly
29-
components: clippy
30-
override: true
31-
- uses: actions-rs/clippy-check@v1
32-
with:
33-
token: ${{ secrets.GITHUB_TOKEN }}
34-
args: --all-features
22+
clippy_check:
23+
runs-on: ubuntu-latest
24+
steps:
25+
- uses: actions/checkout@v1
26+
- uses: actions-rs/toolchain@v1
27+
with:
28+
toolchain: nightly
29+
components: clippy
30+
override: true
31+
- uses: actions-rs/clippy-check@v1
32+
with:
33+
token: ${{ secrets.GITHUB_TOKEN }}
34+
args: --all-features
3535
```
3636
3737
### With stable clippy
@@ -40,23 +40,24 @@ jobs:
4040
on: push
4141
name: Clippy check
4242
jobs:
43-
clippy_check:
44-
runs-on: ubuntu-latest
45-
steps:
46-
- uses: actions/checkout@v1
47-
- run: rustup component add clippy
48-
- uses: actions-rs/clippy-check@v1
49-
with:
50-
args: --all-features
43+
clippy_check:
44+
runs-on: ubuntu-latest
45+
steps:
46+
- uses: actions/checkout@v1
47+
- run: rustup component add clippy
48+
- uses: actions-rs/clippy-check@v1
49+
with:
50+
args: --all-features
5151
```
5252
5353
## Inputs
5454
55-
| Name | Required | Description | Type | Default |
56-
| ------------| :------: | ---------------------------------------------------------------------------------------------------------------------------------------| ------ | --------|
57-
| `toolchain` | | Rust toolchain to use; override or system default toolchain will be used if omitted | string | |
58-
| `args` | | Arguments for the `cargo clippy` command | string | |
59-
| `use-cross` | | Use [`cross`](https://github.com/rust-embedded/cross) instead of `cargo` | bool | false |
55+
| Name | Required | Description | Type | Default |
56+
| ------------------- | :------: | ----------------------------------------------------------------------------------- | ------ | ------- |
57+
| `toolchain` | | Rust toolchain to use; override or system default toolchain will be used if omitted | string | |
58+
| `args` | | Arguments for the `cargo clippy` command | string | |
59+
| `use-cross` | | Use [`cross`](https://github.com/rust-embedded/cross) instead of `cargo` | bool | false |
60+
| `working-directory` | | Specify where rust directory is | string | . |
6061

6162
For extra details about the `toolchain`, `args` and `use-cross` inputs,
6263
see [`cargo` Action](https://github.com/actions-rs/cargo#inputs) documentation.

action.yml

+3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ inputs:
1515
use-cross:
1616
description: Use cross instead of cargo
1717
required: false
18+
working-directory:
19+
description: Specify where rust directory is. By default runs in root directory
20+
required: false
1821

1922
runs:
2023
using: "node20"

src/clippy.ts

+17-9
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { join } from "path";
2+
13
import * as core from "@actions/core";
24
import * as exec from "@actions/exec";
35
import { Cargo, Cross } from "@actions-rs-plus/core";
@@ -56,19 +58,25 @@ async function runClippy(actionInput: input.ParsedInput, program: Program): Prom
5658
const args = buildArgs(actionInput);
5759
const outputParser = new OutputParser();
5860

61+
const options: exec.ExecOptions = {
62+
ignoreReturnCode: true,
63+
failOnStdErr: false,
64+
listeners: {
65+
stdline: (line: string) => {
66+
outputParser.tryParseClippyLine(line);
67+
},
68+
},
69+
};
70+
71+
if (actionInput.workingDirectory) {
72+
options.cwd = join(process.cwd(), actionInput.workingDirectory);
73+
}
74+
5975
let exitCode = 0;
6076

6177
try {
6278
core.startGroup("Executing cargo clippy (JSON output)");
63-
exitCode = await program.call(args, {
64-
ignoreReturnCode: true,
65-
failOnStdErr: false,
66-
listeners: {
67-
stdline: (line: string) => {
68-
outputParser.tryParseClippyLine(line);
69-
},
70-
},
71-
});
79+
exitCode = await program.call(args, options);
7280
} finally {
7381
core.endGroup();
7482
}

src/input.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export interface ParsedInput {
66
toolchain: string | undefined;
77
args: string[];
88
useCross: boolean;
9+
workingDirectory: string | undefined;
910
}
1011

1112
export function get(): ParsedInput {
@@ -18,6 +19,7 @@ export function get(): ParsedInput {
1819
return {
1920
args: stringArgv(input.getInput("args")),
2021
useCross: input.getInputBool("use-cross"),
21-
toolchain: toolchain !== "" ? toolchain : undefined,
22+
workingDirectory: input.getInput("working-directory") || undefined,
23+
toolchain: toolchain || undefined,
2224
};
2325
}

src/outputParser.ts

+14-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
1+
import { join } from "path";
2+
13
import * as core from "@actions/core";
24

35
import type { AnnotationWithMessageAndLevel, CargoMessage, MaybeCargoMessage, Stats } from "./schema";
46
import { AnnotationLevel } from "./schema";
57

68
export class OutputParser {
9+
private readonly _workingDirectory: string | null;
710
private readonly _uniqueAnnotations: Map<string, AnnotationWithMessageAndLevel>;
811
private readonly _stats: Stats;
912

10-
public constructor() {
13+
public constructor(workingDirectory?: string) {
14+
this._workingDirectory = workingDirectory ?? null;
1115
this._uniqueAnnotations = new Map();
1216
this._stats = {
1317
ice: 0,
@@ -47,7 +51,7 @@ export class OutputParser {
4751

4852
const cargoMessage = contents as CargoMessage;
4953

50-
const parsedAnnotation = OutputParser.makeAnnotation(cargoMessage);
54+
const parsedAnnotation = this.makeAnnotation(cargoMessage);
5155

5256
const key = JSON.stringify(parsedAnnotation);
5357

@@ -93,7 +97,7 @@ export class OutputParser {
9397
/// Convert parsed JSON line into the GH annotation object
9498
///
9599
/// https://developer.github.com/v3/checks/runs/#annotations-object
96-
private static makeAnnotation(contents: CargoMessage): AnnotationWithMessageAndLevel {
100+
private makeAnnotation(contents: CargoMessage): AnnotationWithMessageAndLevel {
97101
const primarySpan = contents.message.spans.find((span) => {
98102
return span.is_primary;
99103
});
@@ -103,11 +107,17 @@ export class OutputParser {
103107
throw new Error("Unable to find primary span for message");
104108
}
105109

110+
let path = primarySpan.file_name;
111+
112+
if (this._workingDirectory) {
113+
path = join(this._workingDirectory, path);
114+
}
115+
106116
const annotation: AnnotationWithMessageAndLevel = {
107117
level: OutputParser.parseLevel(contents.message.level),
108118
message: contents.message.rendered,
109119
properties: {
110-
file: primarySpan.file_name,
120+
file: path,
111121
startLine: primarySpan.line_start,
112122
endLine: primarySpan.line_end,
113123
title: contents.message.message,

src/tests/clippy.test.ts

+5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ describe("clippy", () => {
1717
toolchain: "stable",
1818
args: [],
1919
useCross: false,
20+
workingDirectory: undefined,
2021
};
2122

2223
await expect(run(actionInput)).resolves.toBeUndefined();
@@ -29,6 +30,7 @@ describe("clippy", () => {
2930
toolchain: "stable",
3031
args: [],
3132
useCross: true,
33+
workingDirectory: undefined,
3234
};
3335

3436
await expect(run(actionInput)).resolves.toBeUndefined();
@@ -54,6 +56,7 @@ describe("clippy", () => {
5456
toolchain: "stable",
5557
args: [],
5658
useCross: false,
59+
workingDirectory: undefined,
5760
};
5861

5962
await expect(run(actionInput)).rejects.toThrow(/Clippy had exited with the (\d)+ exit code/);
@@ -78,6 +81,7 @@ describe("clippy", () => {
7881
toolchain: "stable",
7982
args: [],
8083
useCross: false,
84+
workingDirectory: undefined,
8185
};
8286

8387
await expect(run(actionInput)).resolves.toBeUndefined();
@@ -115,6 +119,7 @@ describe("clippy", () => {
115119
toolchain: "stable",
116120
args: [],
117121
useCross: false,
122+
workingDirectory: "./my/sources/are/here",
118123
};
119124

120125
await expect(run(actionInput)).resolves.toBeUndefined();

src/tests/input.test.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,26 @@ describe("input", () => {
1212
});
1313

1414
test("get 1, parses defaults", () => {
15-
expect(get()).toStrictEqual({ args: [], toolchain: undefined, useCross: false });
15+
expect(get()).toStrictEqual({ args: [], toolchain: undefined, useCross: false, workingDirectory: undefined });
1616
});
1717

1818
test("get 2, can use cross", () => {
1919
process.env["INPUT_USE-CROSS"] = "true";
20-
expect(get()).toStrictEqual({ args: [], toolchain: undefined, useCross: true });
20+
expect(get()).toStrictEqual({ args: [], toolchain: undefined, useCross: true, workingDirectory: undefined });
2121
});
2222

2323
test("get 3, parses toolchain", () => {
2424
process.env["INPUT_TOOLCHAIN"] = "nightly";
25-
expect(get()).toStrictEqual({ args: [], toolchain: "nightly", useCross: false });
25+
expect(get()).toStrictEqual({ args: [], toolchain: "nightly", useCross: false, workingDirectory: undefined });
2626
});
2727

2828
test("get 4, parses +toolchain to toolchain", () => {
2929
process.env["INPUT_TOOLCHAIN"] = "+nightly";
30-
expect(get()).toStrictEqual({ args: [], toolchain: "nightly", useCross: false });
30+
expect(get()).toStrictEqual({ args: [], toolchain: "nightly", useCross: false, workingDirectory: undefined });
3131
});
3232

3333
test("get 5, parses arguments", () => {
3434
process.env["INPUT_ARGS"] = "--all-features --all-targets";
35-
expect(get()).toStrictEqual({ args: ["--all-features", "--all-targets"], toolchain: undefined, useCross: false });
35+
expect(get()).toStrictEqual({ args: ["--all-features", "--all-targets"], toolchain: undefined, useCross: false, workingDirectory: undefined });
3636
});
3737
});

src/tests/outputParser.test.ts

+30
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,35 @@ describe("outputParser", () => {
134134
}).toThrow(/Unable to find primary span for message/);
135135
});
136136

137+
it("parses annotations into AnnotationWithMessageAndLevel", () => {
138+
const outputParser = new OutputParser("./my/sources/are/here");
139+
140+
outputParser.tryParseClippyLine(
141+
JSON.stringify({
142+
reason: defaultMessage.reason,
143+
message: {
144+
...defaultMessage.message,
145+
level: "error",
146+
},
147+
}),
148+
);
149+
150+
expect(outputParser.annotations).toEqual([
151+
{
152+
level: 0,
153+
message: "rendered",
154+
properties: {
155+
endColumn: 15,
156+
endLine: 30,
157+
file: "my/sources/are/here/main.rs",
158+
startColumn: 10,
159+
startLine: 30,
160+
title: "message",
161+
},
162+
},
163+
]);
164+
});
165+
137166
it("parses annotations into AnnotationWithMessageAndLevel", () => {
138167
const outputParser = new OutputParser();
139168

@@ -146,6 +175,7 @@ describe("outputParser", () => {
146175
},
147176
}),
148177
);
178+
149179
outputParser.tryParseClippyLine(
150180
JSON.stringify({
151181
reason: defaultMessage.reason,

0 commit comments

Comments
 (0)