Skip to content

Commit

Permalink
feat: add support for working dir
Browse files Browse the repository at this point in the history
  • Loading branch information
kristof-mattei committed Oct 10, 2023
1 parent 12c3a1b commit 6e102d0
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 45 deletions.
53 changes: 27 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,19 @@ to install the most recent `nightly` clippy version.
on: push
name: Clippy check
jobs:
clippy_check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
components: clippy
override: true
- uses: actions-rs/clippy-check@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --all-features
clippy_check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
components: clippy
override: true
- uses: actions-rs/clippy-check@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --all-features
```
### With stable clippy
Expand All @@ -40,23 +40,24 @@ jobs:
on: push
name: Clippy check
jobs:
clippy_check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- run: rustup component add clippy
- uses: actions-rs/clippy-check@v1
with:
args: --all-features
clippy_check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- run: rustup component add clippy
- uses: actions-rs/clippy-check@v1
with:
args: --all-features
```
## Inputs
| Name | Required | Description | Type | Default |
| ------------| :------: | ---------------------------------------------------------------------------------------------------------------------------------------| ------ | --------|
| `toolchain` | | Rust toolchain to use; override or system default toolchain will be used if omitted | string | |
| `args` | | Arguments for the `cargo clippy` command | string | |
| `use-cross` | | Use [`cross`](https://github.com/rust-embedded/cross) instead of `cargo` | bool | false |
| Name | Required | Description | Type | Default |
| ------------------- | :------: | ----------------------------------------------------------------------------------- | ------ | ------- |
| `toolchain` | | Rust toolchain to use; override or system default toolchain will be used if omitted | string | |
| `args` | | Arguments for the `cargo clippy` command | string | |
| `use-cross` | | Use [`cross`](https://github.com/rust-embedded/cross) instead of `cargo` | bool | false |
| `working-directory` | | Specify where rust directory is | string | . |

For extra details about the `toolchain`, `args` and `use-cross` inputs,
see [`cargo` Action](https://github.com/actions-rs/cargo#inputs) documentation.
Expand Down
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ inputs:
use-cross:
description: Use cross instead of cargo
required: false
working-directory:
description: Specify where rust directory is. By default runs in root directory
required: false

runs:
using: "node20"
Expand Down
26 changes: 17 additions & 9 deletions src/clippy.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { join } from "path";

import * as core from "@actions/core";
import * as exec from "@actions/exec";
import { Cargo, Cross } from "@actions-rs-plus/core";
Expand Down Expand Up @@ -56,19 +58,25 @@ async function runClippy(actionInput: input.ParsedInput, program: Program): Prom
const args = buildArgs(actionInput);
const outputParser = new OutputParser();

const options: exec.ExecOptions = {
ignoreReturnCode: true,
failOnStdErr: false,
listeners: {
stdline: (line: string) => {
outputParser.tryParseClippyLine(line);
},
},
};

if (actionInput.workingDirectory) {
options.cwd = join(process.cwd(), actionInput.workingDirectory);
}

let exitCode = 0;

try {
core.startGroup("Executing cargo clippy (JSON output)");
exitCode = await program.call(args, {
ignoreReturnCode: true,
failOnStdErr: false,
listeners: {
stdline: (line: string) => {
outputParser.tryParseClippyLine(line);
},
},
});
exitCode = await program.call(args, options);
} finally {
core.endGroup();
}
Expand Down
4 changes: 3 additions & 1 deletion src/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export interface ParsedInput {
toolchain: string | undefined;
args: string[];
useCross: boolean;
workingDirectory: string | undefined;
}

export function get(): ParsedInput {
Expand All @@ -18,6 +19,7 @@ export function get(): ParsedInput {
return {
args: stringArgv(input.getInput("args")),
useCross: input.getInputBool("use-cross"),
toolchain: toolchain !== "" ? toolchain : undefined,
workingDirectory: input.getInput("working-directory") || undefined,
toolchain: toolchain || undefined,
};
}
18 changes: 14 additions & 4 deletions src/outputParser.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { join } from "path";

import * as core from "@actions/core";

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

export class OutputParser {
private readonly _workingDirectory: string | null;
private readonly _uniqueAnnotations: Map<string, AnnotationWithMessageAndLevel>;
private readonly _stats: Stats;

public constructor() {
public constructor(workingDirectory?: string) {
this._workingDirectory = workingDirectory ?? null;
this._uniqueAnnotations = new Map();
this._stats = {
ice: 0,
Expand Down Expand Up @@ -47,7 +51,7 @@ export class OutputParser {

const cargoMessage = contents as CargoMessage;

const parsedAnnotation = OutputParser.makeAnnotation(cargoMessage);
const parsedAnnotation = this.makeAnnotation(cargoMessage);

const key = JSON.stringify(parsedAnnotation);

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

let path = primarySpan.file_name;

if (this._workingDirectory) {
path = join(this._workingDirectory, path);
}

const annotation: AnnotationWithMessageAndLevel = {
level: OutputParser.parseLevel(contents.message.level),
message: contents.message.rendered,
properties: {
file: primarySpan.file_name,
file: path,
startLine: primarySpan.line_start,
endLine: primarySpan.line_end,
title: contents.message.message,
Expand Down
5 changes: 5 additions & 0 deletions src/tests/clippy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ describe("clippy", () => {
toolchain: "stable",
args: [],
useCross: false,
workingDirectory: undefined,
};

await expect(run(actionInput)).resolves.toBeUndefined();
Expand All @@ -29,6 +30,7 @@ describe("clippy", () => {
toolchain: "stable",
args: [],
useCross: true,
workingDirectory: undefined,
};

await expect(run(actionInput)).resolves.toBeUndefined();
Expand All @@ -54,6 +56,7 @@ describe("clippy", () => {
toolchain: "stable",
args: [],
useCross: false,
workingDirectory: undefined,
};

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

await expect(run(actionInput)).resolves.toBeUndefined();
Expand Down Expand Up @@ -115,6 +119,7 @@ describe("clippy", () => {
toolchain: "stable",
args: [],
useCross: false,
workingDirectory: "./my/sources/are/here",
};

await expect(run(actionInput)).resolves.toBeUndefined();
Expand Down
10 changes: 5 additions & 5 deletions src/tests/input.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,26 @@ describe("input", () => {
});

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

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

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

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

test("get 5, parses arguments", () => {
process.env["INPUT_ARGS"] = "--all-features --all-targets";
expect(get()).toStrictEqual({ args: ["--all-features", "--all-targets"], toolchain: undefined, useCross: false });
expect(get()).toStrictEqual({ args: ["--all-features", "--all-targets"], toolchain: undefined, useCross: false, workingDirectory: undefined });
});
});
30 changes: 30 additions & 0 deletions src/tests/outputParser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,35 @@ describe("outputParser", () => {
}).toThrow(/Unable to find primary span for message/);
});

it("parses annotations into AnnotationWithMessageAndLevel", () => {
const outputParser = new OutputParser("./my/sources/are/here");

outputParser.tryParseClippyLine(
JSON.stringify({
reason: defaultMessage.reason,
message: {
...defaultMessage.message,
level: "error",
},
}),
);

expect(outputParser.annotations).toEqual([
{
level: 0,
message: "rendered",
properties: {
endColumn: 15,
endLine: 30,
file: "my/sources/are/here/main.rs",
startColumn: 10,
startLine: 30,
title: "message",
},
},
]);
});

it("parses annotations into AnnotationWithMessageAndLevel", () => {
const outputParser = new OutputParser();

Expand All @@ -146,6 +175,7 @@ describe("outputParser", () => {
},
}),
);

outputParser.tryParseClippyLine(
JSON.stringify({
reason: defaultMessage.reason,
Expand Down

0 comments on commit 6e102d0

Please sign in to comment.