nx-lifecycle 1.2.1 → 1.3.0

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.
package/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  <div style="text-align:center">
2
2
 
3
3
  # nx-lifecycle
4
+
4
5
  [Nx](https://nx.dev/) plugin that derives every `dependsOn` from declared lifecycle stages (build, test, …) and the targets bound to them.
5
6
 
6
7
  [![npm package](https://badge.fury.io/js/nx-lifecycle.svg)](https://www.npmjs.com/package/nx-lifecycle)
@@ -20,17 +21,17 @@ Guides and the full reference are on the [docs site](https://jacobley.github.io/
20
21
 
21
22
  - [Install](#install)
22
23
  - [Plugin](#plugin)
23
- - [Overriding inferred targets](#overriding-inferred-targets)
24
- - [Limitations](#limitations)
25
- - [Migrating from the executor](#migrating-from-the-executor)
24
+ - [Overriding inferred targets](#overriding-inferred-targets)
25
+ - [Limitations](#limitations)
26
+ - [Migrating from the executor](#migrating-from-the-executor)
26
27
  - [Executor](#executor)
27
28
  - [Configuration](#configuration)
28
- - [stages](#stages)
29
- - [bindings](#bindings)
30
- - [check](#check)
31
- - [dryRun](#dryrun)
29
+ - [stages](#stages)
30
+ - [bindings](#bindings)
31
+ - [check](#check)
32
+ - [dryRun](#dryrun)
32
33
  - [CLI](#cli)
33
- - [explain](#explain)
34
+ - [explain](#explain)
34
35
  - [Compared to alternatives](#compared-to-alternatives)
35
36
 
36
37
  ## Install
@@ -117,6 +118,8 @@ Every time Nx builds the project graph, the plugin checks the merged configurati
117
118
 
118
119
  ## Executor
119
120
 
121
+ Use the [plugin](#plugin) unless the workspace develops `nx-lifecycle` itself, or you want every `dependsOn` visible in the files.
122
+
120
123
  Register it as a target in a `project.json`. Because `lifecycle` manages dependencies for the rest of your targets, it should live in a project outside your normal build/test graph — for example, a root-level management package. See [Nx-lifecycle's own monorepo config](https://github.com/JacobLey/leyman/blob/main/leyman/main/lifecycle.json) for a real example.
121
124
 
122
125
  ```json
@@ -212,10 +215,10 @@ Required. No default.
212
215
 
213
216
  Declares the abstract workflow stages that `nx-lifecycle` will own. Each key is a stage name; the value configures that stage's structure and upstream dependencies.
214
217
 
215
- | Field | Type | Default | Description |
216
- |-------|------|---------|-------------|
217
- | `hooks` | `string[]` | — | Ordered list of sub-steps within the stage. The resulting target names are `stage:hook` (e.g. `build:run`). If omitted, the stage has no sub-steps and is referenced directly by name. |
218
- | `dependsOn` | `dependsOn[]` | — | Upstream dependencies for this stage, using the same format as Nx's native [`dependsOn`](https://nx.dev/reference/project-configuration#dependson): `"build"` (this project's stage), `"^build"` (the stage of every dependency project), `{ "target": "build", "projects": ["my-server"] }`. Can name a stage or any other target, but not another stage's anchor or hook (`^build:post` is rejected: depend on `build`). |
218
+ | Field | Type | Default | Description |
219
+ | ----------- | ------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
220
+ | `hooks` | `string[]` | — | Ordered list of sub-steps within the stage. The resulting target names are `stage:hook` (e.g. `build:run`). If omitted, the stage has no sub-steps and is referenced directly by name. |
221
+ | `dependsOn` | `dependsOn[]` | — | Upstream dependencies for this stage, using the same format as Nx's native [`dependsOn`](https://nx.dev/reference/project-configuration#dependson): `"build"` (this project's stage), `"^build"` (the stage of every dependency project), `{ "target": "build", "projects": ["my-server"] }`. Can name a stage or any other target, but not another stage's anchor or hook (`^build:post` is rejected: depend on `build`). |
219
222
 
220
223
  **Note:** If a stage declares `hooks`, bindings must reference a specific hook (`build:run`), not the stage name alone (`build`). A stage without hooks still generates an anchor: `lint:_ → eslint → lint`.
221
224
 
@@ -289,7 +292,7 @@ Multiple targets from different languages or toolchains can bind to the same hoo
289
292
  }
290
293
  ```
291
294
 
292
- A binding applies to every project that defines the target, through `targetDefaults` or its own `project.json`. A project opts in by defining it (e.g. `"tsc": {}`). A warning is logged for a binding that no `project.json` declares, since it is usually a typo. Targets inferred by Nx plugins are not declared in `project.json`, so they trigger the warning too.
295
+ A binding applies to every project that defines the target, through `targetDefaults` or its own `project.json`. A project opts in by defining it (e.g. `"tsc": {}`). A warning is logged for a binding that no `project.json` declares, since it is usually a typo. Targets inferred by Nx plugins are not declared in `project.json`, so they trigger the warning too. The plugin's `"warnUnusedBindings": false` turns it off, for bindings that cover targets projects add later.
293
296
 
294
297
  #### Project-specific dependencies
295
298
 
@@ -312,8 +315,8 @@ Use this sparingly. If many projects need the same dependency, it belongs in the
312
315
 
313
316
  Executor only.
314
317
 
315
- | Type | Default |
316
- |------|---------|
318
+ | Type | Default |
319
+ | --------- | ------------------------------- |
317
320
  | `boolean` | `true` in CI, `false` otherwise |
318
321
 
319
322
  When `true`, the executor writes nothing and fails if `nx.json` or any `project.json` is out of sync with what `nx-lifecycle` would generate. Use this in CI to verify that generated configs are committed and up to date before deployment proceeds.
@@ -322,8 +325,8 @@ When `true`, the executor writes nothing and fails if `nx.json` or any `project.
322
325
 
323
326
  Executor only.
324
327
 
325
- | Type | Default |
326
- |------|---------|
328
+ | Type | Default |
329
+ | --------- | ------- |
327
330
  | `boolean` | `false` |
328
331
 
329
332
  When `true`, performs all computation but skips writing any files. Can still fail when `check` is `true`.
@@ -337,12 +340,12 @@ pnpx nx-lifecycle --help
337
340
  pnpx nx-lifecycle --config-file ./my-lifecycle.json --dry-run
338
341
  ```
339
342
 
340
- | Flag | Type | Default | Description |
341
- |------|------|---------|-------------|
342
- | `--config-file` | `string` | `lifecycle.json` | Path to the lifecycle config file. |
343
- | `--dry-run` | `boolean` | `false` | Compute changes without writing files. |
344
- | `--check`, `--ci` | `boolean` | `true` in CI | Fail if any file is out of sync. |
345
- | `--cwd` | `string` | `.` | Directory other paths are resolved from. |
343
+ | Flag | Type | Default | Description |
344
+ | ----------------- | --------- | ---------------- | ---------------------------------------- |
345
+ | `--config-file` | `string` | `lifecycle.json` | Path to the lifecycle config file. |
346
+ | `--dry-run` | `boolean` | `false` | Compute changes without writing files. |
347
+ | `--check`, `--ci` | `boolean` | `true` in CI | Fail if any file is out of sync. |
348
+ | `--cwd` | `string` | `.` | Directory other paths are resolved from. |
346
349
 
347
350
  ### `explain`
348
351
 
@@ -132,7 +132,7 @@ export const createDependencies = (options, context)=>{
132
132
  ].join('\n'));
133
133
  }
134
134
  for (const targetName of lifecyclePlan.registeredTargets.keys()){
135
- if (!definedTargets.has(targetName)) {
135
+ if (options?.warnUnusedBindings !== false && !definedTargets.has(targetName)) {
136
136
  logger.warn(`Bound target ${targetName} is not defined in any project. Is it a typo?`);
137
137
  }
138
138
  }
@@ -36,6 +36,7 @@ declare const lifecyclePluginOptionsSchema: import("juniper").ObjectSchema<{
36
36
  hooks: import("juniper").ArraySchema<string, [], never, unknown, false, 0>;
37
37
  }, never, boolean, import("juniper").EmptyIndex, unknown, false>, import("juniper").EmptyIndex, unknown, false>;
38
38
  bindings: import("juniper").ObjectSchema<{}, never, import("juniper").StringSchema<string, false>, import("juniper").EmptyIndex, unknown, false>;
39
+ warnUnusedBindings: import("juniper").BooleanSchema<false>;
39
40
  }, "bindings" | "stages", false, import("juniper").EmptyIndex, unknown, false>;
40
41
  export type LifecyclePluginOptions = SchemaType<typeof lifecyclePluginOptionsSchema>;
41
42
  export declare const assertLifecyclePluginOptions: JuniperValidator<LifecyclePluginOptions>['assert'];
@@ -1,4 +1,4 @@
1
- import { objectSchema } from 'juniper';
1
+ import { booleanSchema, objectSchema } from 'juniper';
2
2
  import { makeValidator } from 'juniper-validator';
3
3
  import { bindingsSchema, stagesSchema } from '../lifecycle/schema.js';
4
4
  const lifecyclePluginOptionsSchema = objectSchema({
@@ -6,7 +6,11 @@ const lifecyclePluginOptionsSchema = objectSchema({
6
6
  description: 'Infer Nx targets as high level workflows',
7
7
  properties: {
8
8
  stages: stagesSchema,
9
- bindings: bindingsSchema
9
+ bindings: bindingsSchema,
10
+ warnUnusedBindings: booleanSchema({
11
+ description: 'Warn about a binding no project defines the target of, which is usually a typo. Turn it off when bindings are written for targets projects add later.',
12
+ default: true
13
+ })
10
14
  },
11
15
  required: [
12
16
  'stages',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nx-lifecycle",
3
- "version": "1.2.1",
3
+ "version": "1.3.0",
4
4
  "description": "Nx plugin that derives every dependsOn from declared lifecycle stages (build, test, …) and the targets bound to them.",
5
5
  "engines": {
6
6
  "node": ">=24"
@@ -62,22 +62,23 @@
62
62
  "dependencies": {
63
63
  "@nx/devkit": "^23.3.1",
64
64
  "ci-info": "^4.4.0",
65
- "entry-script": "^4.1.2",
65
+ "entry-script": "^4.2.0",
66
66
  "fast-equals": "^6.2.1",
67
- "format-file": "^1.2.0",
68
- "haywire": "^2.0.4",
67
+ "format-file": "^1.3.0",
68
+ "haywire": "^2.0.6",
69
69
  "haywire-launcher": "^1.1.1",
70
- "juniper": "^2.5.0",
71
- "juniper-validator": "^0.5.1",
70
+ "juniper": "^2.7.0",
71
+ "juniper-validator": "^0.6.0",
72
72
  "nx": "^23.3.1",
73
- "parse-cwd": "^2.0.3",
74
- "unknown-error": "^0.1.1",
73
+ "parse-cwd": "^2.1.0",
74
+ "unknown-error": "^0.2.0",
75
75
  "yargs": "^18.2.0"
76
76
  },
77
77
  "devDependencies": {
78
- "@biomejs/biome": "^2.6.3",
79
- "@leyman/eslint-config": "^0.0.1",
80
- "@leyman/expect": "^0.0.1",
78
+ "@biomejs/biome": "^2.6.4",
79
+ "@leyman/configs": "^0.1.0",
80
+ "@leyman/eslint-config": "^0.1.1",
81
+ "@leyman/expect": "^0.1.0",
81
82
  "@swc/cli": "^0.8.1",
82
83
  "@swc/core": "^1.16.20",
83
84
  "@types/mocha": "^10.0.10",
@@ -85,13 +86,15 @@
85
86
  "@types/sinon": "^22.0.2",
86
87
  "@types/yargs": "^17.0.35",
87
88
  "@typescript/native": "npm:typescript@^7.0.2",
88
- "barrelify": "^2.2.3",
89
+ "barrelify": "^2.2.5",
89
90
  "c8": "^12.0.0",
90
91
  "eslint": "^10.13.0",
91
92
  "expect-type": "^1.4.0",
92
- "load-populate-files": "^1.1.3",
93
+ "fast-check": "^4.10.2",
94
+ "juniper-arbitrary": "^0.2.0",
95
+ "load-populate-files": "^1.1.5",
93
96
  "mocha": "^12.0.3",
94
- "mocha-chain": "^1.0.2",
97
+ "mocha-chain": "^1.1.0",
95
98
  "sinon": "^22.1.0",
96
99
  "typescript": "npm:@typescript/typescript6@^6.0.2"
97
100
  }