@joshmossas/nx-cargo 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/.babelrc +3 -0
  2. package/.eslintrc.json +34 -0
  3. package/README.md +39 -0
  4. package/build.config.ts +10 -0
  5. package/dist/index.cjs +100 -0
  6. package/dist/index.d.cts +5 -0
  7. package/dist/index.d.mts +5 -0
  8. package/dist/index.d.ts +5 -0
  9. package/dist/index.mjs +79 -0
  10. package/executors.json +25 -0
  11. package/generators.json +25 -0
  12. package/jest.config.ts +17 -0
  13. package/package.json +30 -0
  14. package/project.json +53 -0
  15. package/src/common/index.spec.ts +183 -0
  16. package/src/common/index.ts +358 -0
  17. package/src/common/schema.d.ts +111 -0
  18. package/src/executors/build/executor.ts +21 -0
  19. package/src/executors/build/schema.d.ts +39 -0
  20. package/src/executors/build/schema.json +77 -0
  21. package/src/executors/clippy/executor.ts +18 -0
  22. package/src/executors/clippy/schema.d.ts +34 -0
  23. package/src/executors/clippy/schema.json +29 -0
  24. package/src/executors/run/executor.ts +19 -0
  25. package/src/executors/run/schema.d.ts +32 -0
  26. package/src/executors/run/schema.json +77 -0
  27. package/src/executors/test/executor.ts +19 -0
  28. package/src/executors/test/schema.d.ts +22 -0
  29. package/src/executors/test/schema.json +73 -0
  30. package/src/generators/binary/files/Cargo.toml__template__ +8 -0
  31. package/src/generators/binary/files/src/main.rs__template__ +3 -0
  32. package/src/generators/binary/generator.spec.ts +75 -0
  33. package/src/generators/binary/generator.ts +76 -0
  34. package/src/generators/binary/schema.d.ts +6 -0
  35. package/src/generators/binary/schema.json +35 -0
  36. package/src/generators/init/files/Cargo.toml +2 -0
  37. package/src/generators/init/files/rust-toolchain.toml__template__ +2 -0
  38. package/src/generators/init/files/rustfmt.toml +0 -0
  39. package/src/generators/init/generator.spec.ts +49 -0
  40. package/src/generators/init/generator.ts +55 -0
  41. package/src/generators/init/schema.d.ts +7 -0
  42. package/src/generators/init/schema.json +14 -0
  43. package/src/generators/library/files/Cargo.toml__template__ +8 -0
  44. package/src/generators/library/files/src/lib.rs__template__ +13 -0
  45. package/src/generators/library/generator.spec.ts +96 -0
  46. package/src/generators/library/generator.ts +78 -0
  47. package/src/generators/library/schema.d.ts +6 -0
  48. package/src/generators/library/schema.json +35 -0
  49. package/src/graph/index.ts +189 -0
  50. package/src/index.ts +1 -0
  51. package/tsconfig.json +13 -0
  52. package/tsconfig.lib.json +12 -0
  53. package/tsconfig.spec.json +20 -0
@@ -0,0 +1,358 @@
1
+ import {
2
+ ExecutorContext,
3
+ Tree,
4
+ getWorkspaceLayout,
5
+ names as nxNames,
6
+ } from "@nx/devkit";
7
+ import * as chalk from "chalk";
8
+ import * as cp from "child_process";
9
+ import { kebabCase } from "lodash";
10
+
11
+ import {
12
+ CompilationOptions,
13
+ DisplayOptions,
14
+ EnvironmentOptions,
15
+ FeatureSelection,
16
+ ManifestOptions,
17
+ OutputOptions,
18
+ } from "./schema";
19
+
20
+ import ClippyCliOptions from "../executors/clippy/schema";
21
+
22
+ export interface GeneratorOptions {
23
+ projectName: string;
24
+ moduleName: string;
25
+ projectRoot: string;
26
+ projectDirectory: string;
27
+ parsedTags: string[];
28
+ edition: number;
29
+ }
30
+
31
+ // prettier-ignore
32
+ export type CargoOptions = Partial<
33
+ & FeatureSelection
34
+ & CompilationOptions
35
+ & OutputOptions
36
+ & DisplayOptions
37
+ & ManifestOptions
38
+ & EnvironmentOptions
39
+ & { [key: string]: unknown }
40
+ >;
41
+
42
+ interface GeneratorCLIOptions {
43
+ name: string;
44
+ directory?: string;
45
+ tags?: string;
46
+ edition?: number;
47
+ }
48
+
49
+ interface Names {
50
+ name: string;
51
+ className: string;
52
+ propertyName: string;
53
+ constantName: string;
54
+ fileName: string;
55
+ snakeName: string;
56
+ }
57
+
58
+ export enum Target {
59
+ Build,
60
+ Run,
61
+ Test,
62
+ Clippy,
63
+ }
64
+
65
+ export function cargoNames(name: string): Names {
66
+ let result = nxNames(name) as Names;
67
+ result.snakeName = result.constantName.toLowerCase();
68
+
69
+ return result;
70
+ }
71
+
72
+ export function normalizeGeneratorOptions<T extends GeneratorCLIOptions>(
73
+ projectType: "application" | "library",
74
+ host: Tree,
75
+ opts: T
76
+ ): T & GeneratorOptions {
77
+ let layout = getWorkspaceLayout(host);
78
+ let names = cargoNames(opts.name);
79
+ let moduleName = names.snakeName;
80
+
81
+ // Only convert project/file name casing if it's invalid
82
+ let projectName = /^[-_a-zA-Z0-9]+$/.test(opts.name)
83
+ ? opts.name
84
+ : names.snakeName;
85
+
86
+ let fileName = /^[-_a-zA-Z0-9]+$/.test(opts.name)
87
+ ? opts.name
88
+ : names.fileName;
89
+
90
+ let rootDir = {
91
+ application: layout.appsDir,
92
+ library: layout.libsDir,
93
+ }[projectType];
94
+
95
+ let projectDirectory = opts.directory
96
+ ? `${nxNames(opts.directory).fileName}/${fileName}`
97
+ : fileName;
98
+
99
+ let projectRoot = `${rootDir}/${projectDirectory}`;
100
+ let parsedTags = opts.tags?.split(",").map(s => s.trim()) ?? [];
101
+ let edition = opts.edition ?? 2021;
102
+
103
+ return {
104
+ ...opts,
105
+ projectName,
106
+ moduleName,
107
+ projectRoot,
108
+ projectDirectory,
109
+ parsedTags,
110
+ edition,
111
+ };
112
+ }
113
+
114
+ export function updateWorkspaceMembers(host: Tree, opts: GeneratorOptions) {
115
+ let updated = host
116
+ .read("Cargo.toml")!
117
+ .toString()
118
+ .split("\n")
119
+ .reduce((accum, line) => {
120
+ let trimmed = line.trim();
121
+ let match: RegExpMatchArray | null;
122
+
123
+ if ((match = trimmed.match(/^members\s*=\s*\[(.*)\]$/))) {
124
+ let members = match[1]
125
+ .split(",")
126
+ .map(m => m.trim())
127
+ .filter(Boolean);
128
+
129
+ members.push(`"${opts.projectRoot}"`);
130
+ accum.push(`members = [`, ...members.map(m => " " + m), `]`);
131
+ } else if ((match = trimmed.match(/^members\s*=\s*\[$/))) {
132
+ accum.push(line, ` "${opts.projectRoot}",`);
133
+ } else {
134
+ accum.push(line);
135
+ }
136
+
137
+ return accum;
138
+ }, [] as string[])
139
+ .join("\n");
140
+
141
+ host.write("Cargo.toml", updated);
142
+ }
143
+
144
+ /**
145
+ * @returns a tuple of `[args, env?]`
146
+ */
147
+ export function parseCargoArgs<T extends CargoOptions>(
148
+ target: Target,
149
+ options: T,
150
+ ctx: ExecutorContext,
151
+ ): [string[], Record<string, string|undefined>?] {
152
+ let opts = { ...options };
153
+ let args = [] as string[];
154
+
155
+ let env = extractEnv(opts);
156
+
157
+ if (opts.toolchain)
158
+ processArg(args, opts, "toolchain", `+${opts.toolchain}`);
159
+
160
+ // prettier-ignore
161
+ switch (target) {
162
+ case Target.Build: args.push("build"); break;
163
+ case Target.Test: args.push("test"); break;
164
+ case Target.Run: args.push("run"); break;
165
+ case Target.Clippy: args.push("clippy"); break;
166
+ }
167
+
168
+ if (!ctx.projectName) {
169
+ throw new Error("Expected project name to be non-null");
170
+ }
171
+
172
+ let passThroughArgs = target === Target.Clippy
173
+ ? parseClippyArgs(opts)
174
+ : null;
175
+
176
+ let packageName = (opts["package"] as undefined | string) ?? ctx.projectName;
177
+ if ("package" in opts)
178
+ delete opts["package"];
179
+
180
+ let projects = ctx.projectsConfigurations?.projects ?? ctx.workspace?.projects;
181
+ if (!projects) {
182
+ throw new Error("Failed to find projects map from executor context");
183
+ }
184
+
185
+ if (opts.bin) {
186
+ processArg(
187
+ args, opts, "bin",
188
+ "-p", packageName,
189
+ "--bin", opts.bin,
190
+ );
191
+ } else if (
192
+ target === Target.Build
193
+ && projects[ctx.projectName].projectType === "application"
194
+ ) {
195
+ args.push("--bin", packageName);
196
+ } else {
197
+ args.push("-p", packageName);
198
+ }
199
+
200
+ if (opts.features) {
201
+ let argsToAdd = opts.features === "all"
202
+ ? ["--all-features"]
203
+ : ["--features", opts.features];
204
+
205
+ processArg(args, opts, "features", ...argsToAdd);
206
+ }
207
+
208
+ if (opts.noDefaultFeatures)
209
+ processArg(args, opts, "noDefaultFeatures", "--no-default-features");
210
+
211
+ if (opts.target)
212
+ processArg(args, opts, "target", "--target", opts.target);
213
+
214
+ if (opts.release != null) {
215
+ if (opts.release) {
216
+ args.push("--profile", "release");
217
+
218
+ if (opts["profile"]) {
219
+ let label = chalk.bold.yellowBright.inverse(" WARNING ");
220
+ console.log(
221
+ `${label} Conflicting options found: "release" and "profile" `
222
+ + `-- "profile" will be overridden`
223
+ );
224
+ delete opts["profile"];
225
+ }
226
+ }
227
+ delete opts.release;
228
+ }
229
+
230
+ if (opts.targetDir)
231
+ processArg(args, opts, "targetDir", "--target-dir", opts.targetDir);
232
+
233
+ if ("outDir" in opts && !!(opts as any)["outDir"]) {
234
+ if (args[0] !== "+nightly") {
235
+ if (args[0].startsWith("+")) {
236
+ let label = chalk.bold.yellowBright.inverse(" WARNING ");
237
+ let original = args[0].replace(/^\+/, "");
238
+ let message =
239
+ `'outDir' option can only be used with 'nightly' toolchain, ` +
240
+ `but toolchain '${original}' was already specified. ` +
241
+ `Overriding '${original}' => 'nightly'.`;
242
+
243
+ console.log(`${label} ${message}`);
244
+
245
+ args[0] = "+nightly";
246
+ } else {
247
+ args.unshift("+nightly");
248
+ }
249
+ }
250
+ args.push("-Z", "unstable-options", "--out-dir", (opts as any)["outDir"]);
251
+ delete (opts as any)["outDir"];
252
+ }
253
+
254
+ if (opts.verbose)
255
+ processArg(args, opts, "verbose", "-v");
256
+
257
+ if (opts.veryVerbose)
258
+ processArg(args, opts, "veryVerbose", "-vv");
259
+
260
+ if (opts.quiet)
261
+ processArg(args, opts, "quiet", "-q");
262
+
263
+ if (opts.messageFormat)
264
+ processArg(args, opts, "messageFormat", "--message-format", opts.messageFormat);
265
+
266
+ if (opts.locked)
267
+ processArg(args, opts, "locked", "--locked");
268
+
269
+ if (opts.frozen)
270
+ processArg(args, opts, "frozen", "--frozen");
271
+
272
+ if (opts.offline)
273
+ processArg(args, opts, "offline", "--offline");
274
+
275
+ // For the sake of future-proofing in the absence of updates to this plugin,
276
+ // pass any remaining options straight through to `cargo`
277
+ for (let [key, value] of Object.entries(opts)) {
278
+ if (value !== false) {
279
+ args.push(`--${kebabCase(key)}`);
280
+
281
+ if (value !== true)
282
+ args.push(String(value));
283
+ }
284
+ }
285
+
286
+ if (passThroughArgs) {
287
+ args.push("--", ...passThroughArgs);
288
+ }
289
+
290
+ return [args, env];
291
+ }
292
+
293
+ function parseClippyArgs(opts: ClippyCliOptions): string[] {
294
+ let args = [];
295
+
296
+ if (opts.failOnWarnings || opts.failOnWarnings == null) {
297
+ delete opts.failOnWarnings;
298
+ args.push("-D", "warnings");
299
+ }
300
+ if (opts.noDeps || opts.noDeps == null) {
301
+ delete opts.noDeps;
302
+ args.push("--no-deps");
303
+ }
304
+ if (opts.fix) {
305
+ delete opts.fix;
306
+ args.push("--fix");
307
+ }
308
+
309
+ return args;
310
+ }
311
+
312
+ function extractEnv(opts: CargoOptions): Record<string, string|undefined> | undefined {
313
+ if ("env" in opts && opts.env != null) {
314
+ let env = {
315
+ ...process.env,
316
+ ...opts.env,
317
+ };
318
+
319
+ delete opts.env;
320
+
321
+ return env;
322
+ }
323
+ }
324
+
325
+ function processArg(
326
+ args: string[],
327
+ opts: CargoOptions,
328
+ key: keyof CargoOptions,
329
+ ...argsToAdd: string[]
330
+ ) {
331
+ args.push(...argsToAdd);
332
+ delete opts[key];
333
+ }
334
+
335
+ export function runCargo(
336
+ args: string[],
337
+ ctx: ExecutorContext,
338
+ env?: Record<string, string|undefined>,
339
+ ) {
340
+ console.log(chalk.dim`> cargo ${
341
+ args.map(arg => / /.test(arg) ? `"${arg}"` : arg)
342
+ .join(" ")
343
+ }`);
344
+
345
+ return new Promise<void>((resolve, reject) => {
346
+ cp.spawn("cargo", args, {
347
+ cwd: ctx.root,
348
+ shell: true,
349
+ stdio: "inherit",
350
+ env,
351
+ })
352
+ .on("error", reject)
353
+ .on("close", code => {
354
+ if (code) reject(new Error(`Cargo failed with exit code ${code}`));
355
+ else resolve();
356
+ });
357
+ });
358
+ }
@@ -0,0 +1,111 @@
1
+ export interface PackageSelection {
2
+ /** Specify the Cargo package, if different from the Nx project name. */
3
+ package?: string;
4
+ }
5
+
6
+ export interface FeatureSelection {
7
+ /** Space or comma separated list of features to activate, or "all". */
8
+ features?: string;
9
+ /** Do not activate the `default` feature of the package. */
10
+ noDefaultFeatures?: boolean;
11
+ }
12
+
13
+ export interface CompilationOptions {
14
+ /**
15
+ * Build for the given architecture. The default is the host architecture. The general
16
+ * format of the triple is `<arch><sub>-<vendor>-<sys>-<abi>`. Run
17
+ * `rustc --print target-list` for a list of supported targets.
18
+ *
19
+ * This may also be specified with the `build.target` [config value](https://doc.rust-lang.org/cargo/reference/config.html).
20
+ *
21
+ * Note that specifying this flag makes Cargo run in a different mode where the target
22
+ * artifacts are placed in a separate directory. See the [build cache](https://doc.rust-lang.org/cargo/guide/build-cache.html)
23
+ * documentation for more details.
24
+ */
25
+ target?: string;
26
+ /**
27
+ * Specify a custom `[[bin]]` binary target. Uses the project name if this is
28
+ * not specified and the Nx `projectType` is "application".
29
+ */
30
+ bin?: string;
31
+ /**
32
+ * Build optimized artifacts with the `release` profile. See the [PROFILES](https://doc.rust-lang.org/cargo/commands/cargo-build.html#profiles)
33
+ * section for details on how this affects profile selection.
34
+ */
35
+ release?: boolean;
36
+ /**
37
+ * See the [rustup documentation](https://rust-lang.github.io/rustup/overrides.html)
38
+ * for more information about how toolchain overrides work.
39
+ */
40
+ toolchain?: string;
41
+ }
42
+
43
+ export interface OutputOptions {
44
+ /**
45
+ * Directory for all generated artifacts and intermediate files. May also be specified
46
+ * with the `CARGO_TARGET_DIR` environment variable, or the `build.target-dir` [config
47
+ * value](https://doc.rust-lang.org/cargo/reference/config.html). Defaults to `target`
48
+ * in the root of the workspace.
49
+ */
50
+ targetDir?: string;
51
+ }
52
+
53
+ export interface DisplayOptions {
54
+ /**
55
+ * Use verbose output. May also be specified with the term.verbose [config
56
+ * value](https://doc.rust-lang.org/cargo/reference/config.html).
57
+ */
58
+ verbose?: boolean;
59
+ /** Include extra output such as dependency warnings and build script output. */
60
+ veryVerbose?: boolean;
61
+ /** No output printed to stdout. */
62
+ quiet?: boolean;
63
+ /**
64
+ * The output format for diagnostic messages. Can be specified multiple times and
65
+ * consists of comma-separated values. Valid values:
66
+ *
67
+ * * `human` (default): Display in a human-readable text format. Conflicts with
68
+ * `short` and `json`.
69
+ * * `short`: Emit shorter, human-readable text messages. Conflicts with `human` and
70
+ * `json`.
71
+ * * `json`: Emit JSON messages to stdout. See [the reference](https://doc.rust-lang.org/cargo/reference/external-tools.html#json-messages)
72
+ * for more details. Conflicts with `human` and `short`.
73
+ * * `json-diagnostic-short`: Ensure the `rendered` field of JSON messages contains
74
+ * the "short" rendering from rustc. Cannot be used with `human` or `short`.
75
+ * * `json-diagnostic-rendered-ansi`: Ensure the `rendered` field of JSON messages
76
+ * contains embedded ANSI color codes for respecting rustc's default color scheme.
77
+ * Cannot be used with `human` or `short`.
78
+ * * `json-render-diagnostics`: Instruct Cargo to not include rustc diagnostics in in
79
+ * JSON messages printed, but instead Cargo itself should render the JSON
80
+ * diagnostics coming from rustc. Cargo's own JSON diagnostics and others coming
81
+ * from rustc are still emitted. Cannot be used with `human` or `short`.
82
+ */
83
+ messageFormat?: string;
84
+ }
85
+
86
+ export interface ManifestOptions {
87
+ /**
88
+ * Requires that the `Cargo.lock` file is up-to-date. If the lock file is missing, or
89
+ * it needs to be updated, Cargo will exit with an error.
90
+ */
91
+ locked?: boolean;
92
+ /**
93
+ * Like `locked`, but prevents Cargo from attempting to access the network to determine
94
+ * if `Cargo.lock` is out-of-date.
95
+ */
96
+ frozen?: boolean;
97
+ /**
98
+ * Prevents Cargo from accessing the network for any reason. Without this flag, Cargo
99
+ * will stop with an error if it needs to access the network and the network is not
100
+ * available. With this flag, Cargo will attempt to proceed without the network if
101
+ * possible.
102
+ */
103
+ offline?: boolean;
104
+ }
105
+
106
+ export interface EnvironmentOptions {
107
+ /**
108
+ * Specify environment variables to set while running the Cargo command.
109
+ */
110
+ env?: Record<string, string>;
111
+ }
@@ -0,0 +1,21 @@
1
+ import { ExecutorContext } from "@nx/devkit";
2
+
3
+ import { Target, parseCargoArgs, runCargo } from "../../common";
4
+ import CLIOptions from "./schema";
5
+
6
+ export default async function (opts: CLIOptions, ctx: ExecutorContext) {
7
+ try {
8
+ let [args, env] = opts.run
9
+ ? parseCargoArgs(Target.Run, opts, ctx)
10
+ : parseCargoArgs(Target.Build, opts, ctx);
11
+
12
+ await runCargo(args, ctx, env);
13
+
14
+ return { success: true };
15
+ } catch (err) {
16
+ return {
17
+ success: false,
18
+ reason: err?.message,
19
+ };
20
+ }
21
+ }
@@ -0,0 +1,39 @@
1
+ import {
2
+ CompilationOptions,
3
+ DisplayOptions,
4
+ FeatureSelection,
5
+ OutputOptions,
6
+ ManifestOptions,
7
+ PackageSelection,
8
+ EnvironmentOptions,
9
+ } from "../../common/schema";
10
+
11
+ // prettier-ignore
12
+ type Options =
13
+ & PackageSelection
14
+ & FeatureSelection
15
+ & CompilationOptions
16
+ & OutputOptions
17
+ & DisplayOptions
18
+ & ManifestOptions
19
+ & EnvironmentOptions
20
+ & { [key: string]: unknown }
21
+ & {
22
+ /**
23
+ * Copy final artifacts to this directory.
24
+ *
25
+ * This option is unstable and available only on the [nightly channel](https://doc.rust-lang.org/book/appendix-07-nightly-rust.html)
26
+ * and requires the `-Z unstable-options` flag to enable. See https://github.com/rust-lang/cargo/issues/6790
27
+ * for more information.
28
+ */
29
+ outDir?: string;
30
+ /**
31
+ * Run `cargo run ...` instead of `cargo build ...`.
32
+ *
33
+ * @deprecated
34
+ * Remove this property and use the `@nxrs/cargo:run` executor instead of `@nxrs/cargo:build`.
35
+ */
36
+ run?: boolean;
37
+ };
38
+
39
+ export default Options;
@@ -0,0 +1,77 @@
1
+ {
2
+ "version": 2,
3
+ "outputCapture": "direct-nodejs",
4
+ "$schema": "http://json-schema.org/schema",
5
+ "title": "Build executor",
6
+ "description": "",
7
+ "type": "object",
8
+ "properties": {
9
+ "package": {
10
+ "type": "string",
11
+ "description": "Specify the Cargo package, if different from the Nx project name."
12
+ },
13
+ "features": {
14
+ "type": "string",
15
+ "description": "Space or comma separated list of features to activate, or \"all\"."
16
+ },
17
+ "noDefaultFeatures": {
18
+ "type": "boolean",
19
+ "description": "Do not activate the `default` feature of the package."
20
+ },
21
+ "target": {
22
+ "type": "string",
23
+ "description": "Build for the given architecture. The default is the host architecture. The general format of the triple is `<arch><sub>-<vendor>-<sys>-<abi>`. Run `rustc --print target-list` for a list of supported targets.\n\nThis may also be specified with the `build.target` [config value](https://doc.rust-lang.org/cargo/reference/config.html).\n\nNote that specifying this flag makes Cargo run in a different mode where the target artifacts are placed in a separate directory. See the [build cache](https://doc.rust-lang.org/cargo/guide/build-cache.html) documentation for more details."
24
+ },
25
+ "release": {
26
+ "type": "boolean",
27
+ "description": "Build optimized artifacts with the `release` profile. See the [PROFILES](https://doc.rust-lang.org/cargo/commands/cargo-build.html#profiles) section for details on how this affects profile selection."
28
+ },
29
+ "targetDir": {
30
+ "type": "string",
31
+ "description": "Directory for all generated artifacts and intermediate files. May also be specified with the `CARGO_TARGET_DIR` environment variable, or the `build.target-dir` [config value](https://doc.rust-lang.org/cargo/reference/config.html). Defaults to `target` in the root of the workspace."
32
+ },
33
+ "outDir": {
34
+ "type": "string",
35
+ "description": "Copy final artifacts to this directory.\n\nThis option is unstable and available only on the [nightly channel](https://doc.rust-lang.org/book/appendix-07-nightly-rust.html). See https://github.com/rust-lang/cargo/issues/6790 for more information."
36
+ },
37
+ "verbose": {
38
+ "type": "boolean",
39
+ "description": "Use verbose output. May also be specified with the term.verbose [config value](https://doc.rust-lang.org/cargo/reference/config.html).",
40
+ "alias": "v"
41
+ },
42
+ "veryVerbose": {
43
+ "type": "boolean",
44
+ "description": "Include extra output such as dependency warnings and build script output."
45
+ },
46
+ "quiet": {
47
+ "type": "boolean",
48
+ "description": "No output printed to stdout.",
49
+ "alias": "q"
50
+ },
51
+ "messageFormat": {
52
+ "type": "string",
53
+ "description": "The output format for diagnostic messages. Can be specified multiple times and consists of comma-separated values. Valid values:\n * `human` (default): Display in a human-readable text format. Conflicts with `short` and `json`.\n * `short`: Emit shorter, human-readable text messages. Conflicts with `human` and `json`.\n * `json`: Emit JSON messages to stdout. See [the reference](https://doc.rust-lang.org/cargo/reference/external-tools.html#json-messages) for more details. Conflicts with `human` and `short`.\n * `json-diagnostic-short`: Ensure the `rendered` field of JSON messages contains the \"short\" rendering from rustc. Cannot be used with `human` or `short`.\n * `json-diagnostic-rendered-ansi`: Ensure the `rendered` field of JSON messages contains embedded ANSI color codes for respecting rustc's default color scheme. Cannot be used with `human` or `short`.\n * `json-render-diagnostics`: Instruct Cargo to not include rustc diagnostics in JSON messages printed, but instead Cargo itself should render the JSON diagnostics coming from rustc. Cargo's own JSON diagnostics and others coming from rustc are still emitted. Cannot be used with `human` or `short`."
54
+ },
55
+ "locked": {
56
+ "type": "boolean",
57
+ "description": "Requires that the `Cargo.lock` file is up-to-date. If the lock file is missing, or it needs to be updated, Cargo will exit with an error."
58
+ },
59
+ "frozen": {
60
+ "type": "boolean",
61
+ "description": "Like `locked`, but prevents Cargo from attempting to access the network to determine if `Cargo.lock` is out-of-date."
62
+ },
63
+ "offline": {
64
+ "type": "boolean",
65
+ "description": "Prevents Cargo from accessing the network for any reason. Without this flag, Cargo will stop with an error if it needs to access the network and the network is not available. With this flag, Cargo will attempt to proceed without the network if possible."
66
+ },
67
+ "toolchain": {
68
+ "type": "string",
69
+ "description": "See the [rustup documentation](https://rust-lang.github.io/rustup/overrides.html) for more information about how toolchain overrides work."
70
+ },
71
+ "env": {
72
+ "type": "object",
73
+ "description": "Specify environment variables to set while running the Cargo command."
74
+ }
75
+ },
76
+ "required": []
77
+ }
@@ -0,0 +1,18 @@
1
+ import { ExecutorContext } from "@nx/devkit";
2
+ import { parseCargoArgs, runCargo, Target } from "../../common";
3
+ import CLIOptions from "./schema";
4
+
5
+ export default async function (opts: CLIOptions, ctx: ExecutorContext) {
6
+ try {
7
+ let [args, env] = parseCargoArgs(Target.Clippy, opts, ctx);
8
+
9
+ await runCargo(args, ctx, env);
10
+
11
+ return { success: true };
12
+ } catch (err) {
13
+ return {
14
+ success: false,
15
+ reason: err?.message,
16
+ };
17
+ }
18
+ }
@@ -0,0 +1,34 @@
1
+ import {
2
+ CompilationOptions,
3
+ DisplayOptions,
4
+ EnvironmentOptions,
5
+ FeatureSelection,
6
+ ManifestOptions,
7
+ PackageSelection,
8
+ } from "../../common/schema";
9
+
10
+ type Options =
11
+ & PackageSelection
12
+ & FeatureSelection
13
+ & CompilationOptions
14
+ & DisplayOptions
15
+ & ManifestOptions
16
+ & EnvironmentOptions
17
+ & { [key: string]: unknown }
18
+ & {
19
+ /** Automatically fix code where possible. */
20
+ fix?: boolean;
21
+ /**
22
+ * Return with a non-zero exit code when lint warnings are encountered.
23
+ * @default true
24
+ */
25
+ failOnWarnings?: boolean;
26
+ /**
27
+ * By default, Clippy will run on the selected project **and** any dependencies that
28
+ * are members of the workspace. To run Clippy **only** on this project, use this flag.
29
+ * @default true
30
+ */
31
+ noDeps?: boolean;
32
+ };
33
+
34
+ export default Options;
@@ -0,0 +1,29 @@
1
+ {
2
+ "version": 2,
3
+ "outputCapture": "direct-nodejs",
4
+ "$schema": "http://json-schema.org/schema",
5
+ "title": "Clippy executor",
6
+ "description": "",
7
+ "type": "object",
8
+ "properties": {
9
+ "fix": {
10
+ "type": "boolean",
11
+ "description": "Automatically fix code where possible."
12
+ },
13
+ "failOnWarnings": {
14
+ "type": "boolean",
15
+ "description": "Return with a non-zero exit code when lint warnings are encountered.",
16
+ "default": true
17
+ },
18
+ "noDeps": {
19
+ "type": "boolean",
20
+ "description": "By default, Clippy will run on the selected project **and** any dependencies that are members of the workspace. To run Clippy **only** on this project, use this flag.",
21
+ "default": true
22
+ },
23
+ "env": {
24
+ "type": "object",
25
+ "description": "Specify environment variables to set while running the Cargo command."
26
+ }
27
+ },
28
+ "required": []
29
+ }