@aws/nx-plugin 1.0.2 → 1.0.4
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/LICENSE-THIRD-PARTY +30 -14
- package/migrations.json +22 -17
- package/package.json +7 -7
- package/src/agentcore-gateway/__snapshots__/generator.spec.ts.snap +3 -3
- package/src/infra/app/__snapshots__/generator.spec.ts.snap +3 -3
- package/src/license/dependency-check/collectors/npm-collector.d.ts +14 -0
- package/src/license/dependency-check/collectors/npm-collector.js +35 -1
- package/src/license/dependency-check/collectors/npm-collector.js.map +1 -1
- package/src/migrations/v1.0.0-rc.98/0001-sandbox-pattern-nested-stacks/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.98/0002-shadcn-cn-package/migration.js.map +1 -0
- package/src/migrations/v1.0.2/0001-terraform-harness-environment-variables/migration.js.map +1 -0
- package/src/migrations/v1.0.3/0001-terraform-init-target/metadata.json +3 -0
- package/src/migrations/v1.0.3/0001-terraform-init-target/migration.d.ts +6 -0
- package/src/migrations/v1.0.3/0001-terraform-init-target/migration.js +153 -0
- package/src/migrations/v1.0.3/0001-terraform-init-target/migration.js.map +1 -0
- package/src/preset/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/py/agent/__snapshots__/generator.constructs.spec.ts.snap +7 -7
- package/src/py/agent/__snapshots__/generator.frameworks.spec.ts.snap +9 -9
- package/src/py/agent/__snapshots__/generator.protocols.spec.ts.snap +8 -8
- package/src/py/dynamodb/__snapshots__/generator.spec.ts.snap +3 -3
- package/src/py/fast-api/__snapshots__/generator.terraform.spec.ts.snap +27 -27
- package/src/py/lambda-function/__snapshots__/generator.spec.ts.snap +6 -6
- package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +8 -8
- package/src/py/rdb/__snapshots__/generator.spec.ts.snap +10 -10
- package/src/sdk/open-api.d.ts +2 -2
- package/src/sdk/open-api.js +1 -1
- package/src/sdk/open-api.js.map +1 -1
- package/src/smithy/project/__snapshots__/generator.spec.ts.snap +16 -16
- package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +19 -19
- package/src/terraform/project/generator.js +52 -44
- package/src/terraform/project/generator.js.map +1 -1
- package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +27 -27
- package/src/ts/agent/__snapshots__/generator.spec.ts.snap +8 -8
- package/src/ts/dcr-proxy/__snapshots__/generator.spec.ts.snap +3 -3
- package/src/ts/dynamodb/__snapshots__/generator.spec.ts.snap +3 -3
- package/src/ts/lambda-function/__snapshots__/generator.spec.ts.snap +6 -6
- package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +4 -4
- package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +18 -18
- package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +28 -28
- package/src/ts/react-website/cognito-auth/__snapshots__/generator.terraform.spec.ts.snap +3 -3
- package/src/utils/docker.d.ts +1 -1
- package/src/utils/test-migration.d.ts +20 -0
- package/src/utils/test-migration.js +32 -0
- package/src/utils/test-migration.js.map +1 -0
- package/src/utils/versions.d.ts +99 -99
- package/src/utils/versions.js +92 -92
- package/src/utils/versions.js.map +1 -1
- package/src/migrations/latest/sandbox-pattern-nested-stacks/migration.js.map +0 -1
- package/src/migrations/latest/shadcn-cn-package/migration.js.map +0 -1
- package/src/migrations/latest/terraform-harness-environment-variables/migration.js.map +0 -1
- /package/src/migrations/{latest/sandbox-pattern-nested-stacks → v1.0.0-rc.98/0001-sandbox-pattern-nested-stacks}/metadata.json +0 -0
- /package/src/migrations/{latest/sandbox-pattern-nested-stacks → v1.0.0-rc.98/0001-sandbox-pattern-nested-stacks}/migration.d.ts +0 -0
- /package/src/migrations/{latest/sandbox-pattern-nested-stacks → v1.0.0-rc.98/0001-sandbox-pattern-nested-stacks}/migration.js +0 -0
- /package/src/migrations/{latest/shadcn-cn-package → v1.0.0-rc.98/0002-shadcn-cn-package}/metadata.json +0 -0
- /package/src/migrations/{latest/shadcn-cn-package → v1.0.0-rc.98/0002-shadcn-cn-package}/migration.d.ts +0 -0
- /package/src/migrations/{latest/shadcn-cn-package → v1.0.0-rc.98/0002-shadcn-cn-package}/migration.js +0 -0
- /package/src/migrations/{latest/terraform-harness-environment-variables → v1.0.2/0001-terraform-harness-environment-variables}/metadata.json +0 -0
- /package/src/migrations/{latest/terraform-harness-environment-variables → v1.0.2/0001-terraform-harness-environment-variables}/migration.d.ts +0 -0
- /package/src/migrations/{latest/terraform-harness-environment-variables → v1.0.2/0001-terraform-harness-environment-variables}/migration.js +0 -0
package/LICENSE-THIRD-PARTY
CHANGED
|
@@ -108,7 +108,7 @@ THE SOFTWARE.
|
|
|
108
108
|
|
|
109
109
|
---
|
|
110
110
|
|
|
111
|
-
The following software may be included in this product: @astral-sh/ruff-wasm-nodejs (0.16.
|
|
111
|
+
The following software may be included in this product: @astral-sh/ruff-wasm-nodejs (0.16.9)
|
|
112
112
|
This software contains the following license and notice below:
|
|
113
113
|
|
|
114
114
|
MIT License
|
|
@@ -3898,7 +3898,7 @@ SOFTWARE.
|
|
|
3898
3898
|
|
|
3899
3899
|
---
|
|
3900
3900
|
|
|
3901
|
-
The following software may be included in this product: @modelcontextprotocol/sdk (1.30.
|
|
3901
|
+
The following software may be included in this product: @modelcontextprotocol/sdk (1.30.1)
|
|
3902
3902
|
This software contains the following license and notice below:
|
|
3903
3903
|
|
|
3904
3904
|
MIT License
|
|
@@ -4247,7 +4247,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
4247
4247
|
|
|
4248
4248
|
---
|
|
4249
4249
|
|
|
4250
|
-
The following software may be included in this product: @nxlv/python (23.
|
|
4250
|
+
The following software may be included in this product: @nxlv/python (23.1.1)
|
|
4251
4251
|
This software contains the following license and notice below:
|
|
4252
4252
|
|
|
4253
4253
|
MIT License
|
|
@@ -4274,7 +4274,7 @@ SOFTWARE.
|
|
|
4274
4274
|
|
|
4275
4275
|
---
|
|
4276
4276
|
|
|
4277
|
-
The following software may be included in this product: @oxc-project/types (0.
|
|
4277
|
+
The following software may be included in this product: @oxc-project/types (0.150.0)
|
|
4278
4278
|
This software contains the following license and notice below:
|
|
4279
4279
|
|
|
4280
4280
|
MIT License
|
|
@@ -6352,6 +6352,22 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|
|
6352
6352
|
|
|
6353
6353
|
---
|
|
6354
6354
|
|
|
6355
|
+
The following software may be included in this product: chalk-template (1.1.2)
|
|
6356
|
+
This software contains the following license and notice below:
|
|
6357
|
+
|
|
6358
|
+
MIT License
|
|
6359
|
+
|
|
6360
|
+
Copyright (c) Josh Junon
|
|
6361
|
+
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
|
|
6362
|
+
|
|
6363
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6364
|
+
|
|
6365
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6366
|
+
|
|
6367
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
6368
|
+
|
|
6369
|
+
---
|
|
6370
|
+
|
|
6355
6371
|
The following software may be included in this product: character-entities (2.0.2)
|
|
6356
6372
|
This software contains the following license and notice below:
|
|
6357
6373
|
|
|
@@ -8741,7 +8757,7 @@ THE SOFTWARE.
|
|
|
8741
8757
|
|
|
8742
8758
|
---
|
|
8743
8759
|
|
|
8744
|
-
The following software may be included in this product: fs-extra (11.4.
|
|
8760
|
+
The following software may be included in this product: fs-extra (11.4.1)
|
|
8745
8761
|
This software contains the following license and notice below:
|
|
8746
8762
|
|
|
8747
8763
|
(The MIT License)
|
|
@@ -9018,7 +9034,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
9018
9034
|
|
|
9019
9035
|
---
|
|
9020
9036
|
|
|
9021
|
-
The following software may be included in this product: hono (4.13.
|
|
9037
|
+
The following software may be included in this product: hono (4.13.8)
|
|
9022
9038
|
This software contains the following license and notice below:
|
|
9023
9039
|
|
|
9024
9040
|
MIT License
|
|
@@ -12387,7 +12403,7 @@ SOFTWARE.
|
|
|
12387
12403
|
|
|
12388
12404
|
---
|
|
12389
12405
|
|
|
12390
|
-
The following software may be included in this product: nanoid (3.3.
|
|
12406
|
+
The following software may be included in this product: nanoid (3.3.19)
|
|
12391
12407
|
This software contains the following license and notice below:
|
|
12392
12408
|
|
|
12393
12409
|
The MIT License (MIT)
|
|
@@ -13258,7 +13274,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
13258
13274
|
|
|
13259
13275
|
---
|
|
13260
13276
|
|
|
13261
|
-
The following software may be included in this product: postcss (8.5.
|
|
13277
|
+
The following software may be included in this product: postcss (8.5.28)
|
|
13262
13278
|
This software contains the following license and notice below:
|
|
13263
13279
|
|
|
13264
13280
|
The MIT License (MIT)
|
|
@@ -13528,7 +13544,7 @@ THE SOFTWARE.
|
|
|
13528
13544
|
|
|
13529
13545
|
---
|
|
13530
13546
|
|
|
13531
|
-
The following software may be included in this product: react (19.
|
|
13547
|
+
The following software may be included in this product: react (19.3.0)
|
|
13532
13548
|
This software contains the following license and notice below:
|
|
13533
13549
|
|
|
13534
13550
|
MIT License
|
|
@@ -13555,7 +13571,7 @@ SOFTWARE.
|
|
|
13555
13571
|
|
|
13556
13572
|
---
|
|
13557
13573
|
|
|
13558
|
-
The following software may be included in this product: react-dom (19.
|
|
13574
|
+
The following software may be included in this product: react-dom (19.3.0)
|
|
13559
13575
|
This software contains the following license and notice below:
|
|
13560
13576
|
|
|
13561
13577
|
MIT License
|
|
@@ -14149,7 +14165,7 @@ SOFTWARE.
|
|
|
14149
14165
|
|
|
14150
14166
|
---
|
|
14151
14167
|
|
|
14152
|
-
The following software may be included in this product: rolldown (1.2.
|
|
14168
|
+
The following software may be included in this product: rolldown (1.2.9)
|
|
14153
14169
|
This software contains the following license and notice below:
|
|
14154
14170
|
|
|
14155
14171
|
MIT License
|
|
@@ -14346,7 +14362,7 @@ SOFTWARE.
|
|
|
14346
14362
|
|
|
14347
14363
|
---
|
|
14348
14364
|
|
|
14349
|
-
The following software may be included in this product: scheduler (0.
|
|
14365
|
+
The following software may be included in this product: scheduler (0.28.0)
|
|
14350
14366
|
This software contains the following license and notice below:
|
|
14351
14367
|
|
|
14352
14368
|
MIT License
|
|
@@ -16072,7 +16088,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
16072
16088
|
|
|
16073
16089
|
---
|
|
16074
16090
|
|
|
16075
|
-
The following software may be included in this product: vite (8.
|
|
16091
|
+
The following software may be included in this product: vite (8.3.1)
|
|
16076
16092
|
This software contains the following license and notice below:
|
|
16077
16093
|
|
|
16078
16094
|
# Vite core license
|
|
@@ -19446,7 +19462,7 @@ OTHER DEALINGS IN THE SOFTWARE.
|
|
|
19446
19462
|
|
|
19447
19463
|
---
|
|
19448
19464
|
|
|
19449
|
-
The following software may be included in this product: zod (4.5
|
|
19465
|
+
The following software may be included in this product: zod (4.6.5)
|
|
19450
19466
|
This software contains the following license and notice below:
|
|
19451
19467
|
|
|
19452
19468
|
MIT License
|
package/migrations.json
CHANGED
|
@@ -2,21 +2,6 @@
|
|
|
2
2
|
"$schema": "http://json-schema.org/schema",
|
|
3
3
|
"name": "@aws/nx-plugin",
|
|
4
4
|
"generators": {
|
|
5
|
-
"latest-sandbox-pattern-nested-stacks": {
|
|
6
|
-
"version": "1.0.0-rc.98",
|
|
7
|
-
"description": "Update the deploy-sandbox and destroy-sandbox stage patterns to match stacks nested below the stage's stacks, so cdk destroy removes the website WebACL stack",
|
|
8
|
-
"implementation": "./src/migrations/latest/sandbox-pattern-nested-stacks/migration"
|
|
9
|
-
},
|
|
10
|
-
"latest-shadcn-cn-package": {
|
|
11
|
-
"version": "1.0.0-rc.98",
|
|
12
|
-
"description": "Move the shared shadcn package's components onto the cn package the shadcn registry now depends on",
|
|
13
|
-
"implementation": "./src/migrations/latest/shadcn-cn-package/migration"
|
|
14
|
-
},
|
|
15
|
-
"latest-terraform-harness-environment-variables": {
|
|
16
|
-
"version": "1.0.2",
|
|
17
|
-
"description": "Send an empty map rather than null for a vended Terraform AgentCore Harness module's environment_variables, so the first apply does not fail after creating the Harness",
|
|
18
|
-
"implementation": "./src/migrations/latest/terraform-harness-environment-variables/migration"
|
|
19
|
-
},
|
|
20
5
|
"v1.0.0-rc.50-0001-modernize-function-props-cast": {
|
|
21
6
|
"version": "1.0.0-rc.50",
|
|
22
7
|
"description": "Replace the legacy angle-bracket FunctionProps type assertion with the modern as syntax in generated API constructs",
|
|
@@ -372,8 +357,28 @@
|
|
|
372
357
|
"description": "Add build, lint, format and typecheck targets plus a tsconfig.json to AgentCore Gateway and Harness projects",
|
|
373
358
|
"implementation": "./src/migrations/v1.0.0-rc.97/0006-script-project-quality-gates/migration"
|
|
374
359
|
},
|
|
375
|
-
"
|
|
360
|
+
"v1.0.0-rc.98-0001-sandbox-pattern-nested-stacks": {
|
|
361
|
+
"version": "1.0.0-rc.98",
|
|
362
|
+
"description": "Update the deploy-sandbox and destroy-sandbox stage patterns to match stacks nested below the stage's stacks, so cdk destroy removes the website WebACL stack",
|
|
363
|
+
"implementation": "./src/migrations/v1.0.0-rc.98/0001-sandbox-pattern-nested-stacks/migration"
|
|
364
|
+
},
|
|
365
|
+
"v1.0.0-rc.98-0002-shadcn-cn-package": {
|
|
366
|
+
"version": "1.0.0-rc.98",
|
|
367
|
+
"description": "Move the shared shadcn package's components onto the cn package the shadcn registry now depends on",
|
|
368
|
+
"implementation": "./src/migrations/v1.0.0-rc.98/0002-shadcn-cn-package/migration"
|
|
369
|
+
},
|
|
370
|
+
"v1.0.2-0001-terraform-harness-environment-variables": {
|
|
376
371
|
"version": "1.0.2",
|
|
372
|
+
"description": "Send an empty map rather than null for a vended Terraform AgentCore Harness module's environment_variables, so the first apply does not fail after creating the Harness",
|
|
373
|
+
"implementation": "./src/migrations/v1.0.2/0001-terraform-harness-environment-variables/migration"
|
|
374
|
+
},
|
|
375
|
+
"v1.0.3-0001-terraform-init-target": {
|
|
376
|
+
"version": "1.0.3",
|
|
377
|
+
"description": "Add the terraform-init target to Terraform projects so the shared provider plugin cache has a single writer",
|
|
378
|
+
"implementation": "./src/migrations/v1.0.3/0001-terraform-init-target/migration"
|
|
379
|
+
},
|
|
380
|
+
"sync-vended-versions": {
|
|
381
|
+
"version": "1.0.4",
|
|
377
382
|
"description": "Sync vended dependency versions and the tracked plugin version to those vended by this release",
|
|
378
383
|
"implementation": "./src/utils/version-upgrade-migration/migration"
|
|
379
384
|
}
|
|
@@ -479,7 +484,7 @@
|
|
|
479
484
|
}
|
|
480
485
|
},
|
|
481
486
|
"nx-23.2.1-nx-packages": {
|
|
482
|
-
"version": "1.0.
|
|
487
|
+
"version": "1.0.1",
|
|
483
488
|
"packages": {
|
|
484
489
|
"nx": {
|
|
485
490
|
"version": "23.2.1",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aws/nx-plugin",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/awslabs/nx-plugin-for-aws.git",
|
|
@@ -40,17 +40,17 @@
|
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@apidevtools/swagger-parser": "12.1.0",
|
|
43
|
-
"@astral-sh/ruff-wasm-nodejs": "0.16.
|
|
43
|
+
"@astral-sh/ruff-wasm-nodejs": "0.16.9",
|
|
44
44
|
"@biomejs/js-api": "6.0.0",
|
|
45
|
-
"@biomejs/wasm-nodejs": "2.5.
|
|
45
|
+
"@biomejs/wasm-nodejs": "2.5.14",
|
|
46
46
|
"@getgrit/gritql": "0.0.3",
|
|
47
47
|
"@iarna/toml": "2.2.5",
|
|
48
|
-
"@modelcontextprotocol/sdk": "1.30.
|
|
48
|
+
"@modelcontextprotocol/sdk": "1.30.1",
|
|
49
49
|
"@nx/devkit": "23.2.1",
|
|
50
50
|
"@nx/js": "23.2.1",
|
|
51
51
|
"@nx/react": "23.2.1",
|
|
52
52
|
"@nx/vite": "23.2.1",
|
|
53
|
-
"@nxlv/python": "23.
|
|
53
|
+
"@nxlv/python": "23.1.1",
|
|
54
54
|
"@phenomnomnominal/tsquery": "6.2.0",
|
|
55
55
|
"@types/estree": "1.0.9",
|
|
56
56
|
"@types/js-yaml": "4.0.9",
|
|
@@ -79,9 +79,9 @@
|
|
|
79
79
|
"typescript": "6.0.3",
|
|
80
80
|
"unified": "11.0.5",
|
|
81
81
|
"unist-util-visit": "5.1.0",
|
|
82
|
-
"vite": "8.
|
|
82
|
+
"vite": "8.3.1",
|
|
83
83
|
"vitest": "4.1.11",
|
|
84
|
-
"zod": "4.5
|
|
84
|
+
"zod": "4.6.5"
|
|
85
85
|
},
|
|
86
86
|
"devDependencies": {
|
|
87
87
|
"@types/semver": "7.8.0"
|
|
@@ -7,15 +7,15 @@ exports[`agentcore-gateway generator > protocol: http > omits protocol_type from
|
|
|
7
7
|
required_providers {
|
|
8
8
|
aws = {
|
|
9
9
|
source = "hashicorp/aws"
|
|
10
|
-
version = "6.
|
|
10
|
+
version = "6.66.0"
|
|
11
11
|
}
|
|
12
12
|
time = {
|
|
13
13
|
source = "hashicorp/time"
|
|
14
|
-
version = "0.14.
|
|
14
|
+
version = "0.14.2"
|
|
15
15
|
}
|
|
16
16
|
random = {
|
|
17
17
|
source = "hashicorp/random"
|
|
18
|
-
version = "3.9.
|
|
18
|
+
version = "3.9.1"
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
}
|
|
@@ -50,7 +50,7 @@ exports[`infra generator > should configure Checkov target correctly > checkov-t
|
|
|
50
50
|
"default",
|
|
51
51
|
],
|
|
52
52
|
"options": {
|
|
53
|
-
"command": "uvx --from checkov==3.3.
|
|
53
|
+
"command": "uvx --from checkov==3.3.20 checkov --config-file {projectRoot}/checkov.yml --directory dist/{projectRoot}/cdk.out --framework cloudformation",
|
|
54
54
|
},
|
|
55
55
|
"outputs": [
|
|
56
56
|
"{workspaceRoot}/dist/{projectRoot}/checkov",
|
|
@@ -150,7 +150,7 @@ exports[`infra generator > should configure project.json with correct targets >
|
|
|
150
150
|
"default",
|
|
151
151
|
],
|
|
152
152
|
"options": {
|
|
153
|
-
"command": "uvx --from checkov==3.3.
|
|
153
|
+
"command": "uvx --from checkov==3.3.20 checkov --config-file {projectRoot}/checkov.yml --directory dist/{projectRoot}/cdk.out --framework cloudformation",
|
|
154
154
|
},
|
|
155
155
|
"outputs": [
|
|
156
156
|
"{workspaceRoot}/dist/{projectRoot}/checkov",
|
|
@@ -762,7 +762,7 @@ exports[`infra generator > should handle custom project names correctly > custom
|
|
|
762
762
|
"default",
|
|
763
763
|
],
|
|
764
764
|
"options": {
|
|
765
|
-
"command": "uvx --from checkov==3.3.
|
|
765
|
+
"command": "uvx --from checkov==3.3.20 checkov --config-file {projectRoot}/checkov.yml --directory dist/{projectRoot}/cdk.out --framework cloudformation",
|
|
766
766
|
},
|
|
767
767
|
"outputs": [
|
|
768
768
|
"{workspaceRoot}/dist/{projectRoot}/checkov",
|
|
@@ -7,4 +7,18 @@ export interface NpmDependency {
|
|
|
7
7
|
export interface NpmCollectorOptions {
|
|
8
8
|
start: string;
|
|
9
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* Resolve a license that only names a file into the license that file grants.
|
|
12
|
+
*
|
|
13
|
+
* license-checker reads a package's license file only when the package declares
|
|
14
|
+
* no license, so a package declaring `SEE LICENSE IN LICENSE` is reported as
|
|
15
|
+
* `Custom: LICENSE` and evaluates to UNKNOWN even when the file grants a
|
|
16
|
+
* pre-approved license. Read the file license-checker already located and run
|
|
17
|
+
* its text detection over it, which returns an SPDX id with the trailing `*`
|
|
18
|
+
* marking a license guessed from text.
|
|
19
|
+
*
|
|
20
|
+
* The reference is kept when the file can't be read, or when detection can't
|
|
21
|
+
* name a license, so the dependency is still reported as UNKNOWN.
|
|
22
|
+
*/
|
|
23
|
+
export declare const resolveFileReferencedLicense: (rawLicense: string, licenseFile: string | undefined) => string;
|
|
10
24
|
export declare const collectNpmDependencies: (options: NpmCollectorOptions) => Promise<NpmDependency[]>;
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/ import { existsSync, readFileSync } from "fs";
|
|
5
5
|
import * as licenseChecker from "license-checker-rseidelsohn";
|
|
6
|
+
// license-checker's own license-from-text detection, which it applies to
|
|
7
|
+
// packages that declare no license. Reused here so a `SEE LICENSE IN <file>`
|
|
8
|
+
// package resolves the same way, rather than through a second implementation.
|
|
9
|
+
import { getLicenseTitle } from "license-checker-rseidelsohn/lib/getLicenseTitle.js";
|
|
6
10
|
import { join } from "path";
|
|
7
11
|
const NAME_VERSION_RE = /^(@?[^@]+)@(.+)$/;
|
|
8
12
|
const splitNameVersion = (identifier)=>{
|
|
@@ -27,6 +31,36 @@ const flattenLicense = (raw)=>{
|
|
|
27
31
|
}
|
|
28
32
|
return raw;
|
|
29
33
|
};
|
|
34
|
+
/**
|
|
35
|
+
* A license that names a file instead of a license: the SPDX form
|
|
36
|
+
* `SEE LICENSE IN <file>`, or the `Custom: <file>` license-checker reports it
|
|
37
|
+
* as.
|
|
38
|
+
*/ const FILE_REFERENCE_RE = /^(?:custom:|see\s+license\s+in)\s+(.+)$/i;
|
|
39
|
+
/**
|
|
40
|
+
* Resolve a license that only names a file into the license that file grants.
|
|
41
|
+
*
|
|
42
|
+
* license-checker reads a package's license file only when the package declares
|
|
43
|
+
* no license, so a package declaring `SEE LICENSE IN LICENSE` is reported as
|
|
44
|
+
* `Custom: LICENSE` and evaluates to UNKNOWN even when the file grants a
|
|
45
|
+
* pre-approved license. Read the file license-checker already located and run
|
|
46
|
+
* its text detection over it, which returns an SPDX id with the trailing `*`
|
|
47
|
+
* marking a license guessed from text.
|
|
48
|
+
*
|
|
49
|
+
* The reference is kept when the file can't be read, or when detection can't
|
|
50
|
+
* name a license, so the dependency is still reported as UNKNOWN.
|
|
51
|
+
*/ export const resolveFileReferencedLicense = (rawLicense, licenseFile)=>{
|
|
52
|
+
if (!licenseFile || !FILE_REFERENCE_RE.test(rawLicense.trim())) {
|
|
53
|
+
return rawLicense;
|
|
54
|
+
}
|
|
55
|
+
let detected = null;
|
|
56
|
+
try {
|
|
57
|
+
detected = getLicenseTitle(readFileSync(licenseFile, 'utf-8'));
|
|
58
|
+
} catch {
|
|
59
|
+
return rawLicense;
|
|
60
|
+
}
|
|
61
|
+
if (!detected || detected === 'Undefined' || FILE_REFERENCE_RE.test(detected)) return rawLicense;
|
|
62
|
+
return detected;
|
|
63
|
+
};
|
|
30
64
|
export const collectNpmDependencies = async (options)=>{
|
|
31
65
|
const nodeModules = join(options.start, 'node_modules');
|
|
32
66
|
if (!existsSync(nodeModules)) {
|
|
@@ -58,7 +92,7 @@ export const collectNpmDependencies = async (options)=>{
|
|
|
58
92
|
out.push({
|
|
59
93
|
name,
|
|
60
94
|
version,
|
|
61
|
-
rawLicense: flattenLicense(info.licenses),
|
|
95
|
+
rawLicense: resolveFileReferencedLicense(flattenLicense(info.licenses), info.licenseFile),
|
|
62
96
|
path: info.path
|
|
63
97
|
});
|
|
64
98
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/license/dependency-check/collectors/npm-collector.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { existsSync, readFileSync } from 'fs';\nimport * as licenseChecker from 'license-checker-rseidelsohn';\nimport { join } from 'path';\n\nexport interface NpmDependency {\n name: string;\n version: string;\n rawLicense: string;\n path?: string;\n}\n\nexport interface NpmCollectorOptions {\n start: string;\n}\n\nconst NAME_VERSION_RE = /^(@?[^@]+)@(.+)$/;\n\nconst splitNameVersion = (\n identifier: string,\n): { name: string; version: string } => {\n const match = identifier.match(NAME_VERSION_RE);\n if (!match) {\n return { name: identifier, version: '0.0.0' };\n }\n return { name: match[1], version: match[2] };\n};\n\nconst flattenLicense = (raw: string | string[] | undefined | null): string => {\n if (!raw) return '';\n if (Array.isArray(raw)) {\n if (raw.length === 0) return '';\n if (raw.length === 1) return raw[0];\n return `(${raw.join(' OR ')})`;\n }\n return raw;\n};\n\nexport const collectNpmDependencies = async (\n options: NpmCollectorOptions,\n): Promise<NpmDependency[]> => {\n const nodeModules = join(options.start, 'node_modules');\n if (!existsSync(nodeModules)) {\n return [];\n }\n\n const exclude = new Set<string>();\n\n const projectPackageJson = join(options.start, 'package.json');\n if (existsSync(projectPackageJson)) {\n try {\n const pkg = JSON.parse(readFileSync(projectPackageJson, 'utf-8')) as {\n name?: string;\n };\n if (pkg.name) exclude.add(pkg.name);\n } catch {\n // ignore\n }\n }\n\n const packages = await new Promise<licenseChecker.ModuleInfos>(\n (resolve, reject) => {\n licenseChecker.init(\n {\n start: options.start,\n excludePrivatePackages: true,\n },\n (err, results) => {\n if (err) reject(err);\n else resolve(results);\n },\n );\n },\n );\n\n const out: NpmDependency[] = [];\n for (const [identifier, info] of Object.entries(packages)) {\n const { name, version } = splitNameVersion(identifier);\n if (exclude.has(name)) continue;\n out.push({\n name,\n version,\n rawLicense: flattenLicense(info.licenses),\n path: info.path,\n });\n }\n return out;\n};\n"],"names":["existsSync","readFileSync","licenseChecker","join","NAME_VERSION_RE","splitNameVersion","identifier","match","name","version","flattenLicense","raw","Array","isArray","length","collectNpmDependencies","options","nodeModules","start","exclude","Set","projectPackageJson","pkg","JSON","parse","add","packages","Promise","resolve","reject","init","excludePrivatePackages","err","results","out","info","Object","entries","has","push","
|
|
1
|
+
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/license/dependency-check/collectors/npm-collector.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { existsSync, readFileSync } from 'fs';\nimport * as licenseChecker from 'license-checker-rseidelsohn';\n// license-checker's own license-from-text detection, which it applies to\n// packages that declare no license. Reused here so a `SEE LICENSE IN <file>`\n// package resolves the same way, rather than through a second implementation.\nimport { getLicenseTitle } from 'license-checker-rseidelsohn/lib/getLicenseTitle.js';\nimport { join } from 'path';\n\nexport interface NpmDependency {\n name: string;\n version: string;\n rawLicense: string;\n path?: string;\n}\n\nexport interface NpmCollectorOptions {\n start: string;\n}\n\nconst NAME_VERSION_RE = /^(@?[^@]+)@(.+)$/;\n\nconst splitNameVersion = (\n identifier: string,\n): { name: string; version: string } => {\n const match = identifier.match(NAME_VERSION_RE);\n if (!match) {\n return { name: identifier, version: '0.0.0' };\n }\n return { name: match[1], version: match[2] };\n};\n\nconst flattenLicense = (raw: string | string[] | undefined | null): string => {\n if (!raw) return '';\n if (Array.isArray(raw)) {\n if (raw.length === 0) return '';\n if (raw.length === 1) return raw[0];\n return `(${raw.join(' OR ')})`;\n }\n return raw;\n};\n\n/**\n * A license that names a file instead of a license: the SPDX form\n * `SEE LICENSE IN <file>`, or the `Custom: <file>` license-checker reports it\n * as.\n */\nconst FILE_REFERENCE_RE = /^(?:custom:|see\\s+license\\s+in)\\s+(.+)$/i;\n\n/**\n * Resolve a license that only names a file into the license that file grants.\n *\n * license-checker reads a package's license file only when the package declares\n * no license, so a package declaring `SEE LICENSE IN LICENSE` is reported as\n * `Custom: LICENSE` and evaluates to UNKNOWN even when the file grants a\n * pre-approved license. Read the file license-checker already located and run\n * its text detection over it, which returns an SPDX id with the trailing `*`\n * marking a license guessed from text.\n *\n * The reference is kept when the file can't be read, or when detection can't\n * name a license, so the dependency is still reported as UNKNOWN.\n */\nexport const resolveFileReferencedLicense = (\n rawLicense: string,\n licenseFile: string | undefined,\n): string => {\n if (!licenseFile || !FILE_REFERENCE_RE.test(rawLicense.trim())) {\n return rawLicense;\n }\n let detected: string | null = null;\n try {\n detected = getLicenseTitle(readFileSync(licenseFile, 'utf-8'));\n } catch {\n return rawLicense;\n }\n if (!detected || detected === 'Undefined' || FILE_REFERENCE_RE.test(detected))\n return rawLicense;\n return detected;\n};\n\nexport const collectNpmDependencies = async (\n options: NpmCollectorOptions,\n): Promise<NpmDependency[]> => {\n const nodeModules = join(options.start, 'node_modules');\n if (!existsSync(nodeModules)) {\n return [];\n }\n\n const exclude = new Set<string>();\n\n const projectPackageJson = join(options.start, 'package.json');\n if (existsSync(projectPackageJson)) {\n try {\n const pkg = JSON.parse(readFileSync(projectPackageJson, 'utf-8')) as {\n name?: string;\n };\n if (pkg.name) exclude.add(pkg.name);\n } catch {\n // ignore\n }\n }\n\n const packages = await new Promise<licenseChecker.ModuleInfos>(\n (resolve, reject) => {\n licenseChecker.init(\n {\n start: options.start,\n excludePrivatePackages: true,\n },\n (err, results) => {\n if (err) reject(err);\n else resolve(results);\n },\n );\n },\n );\n\n const out: NpmDependency[] = [];\n for (const [identifier, info] of Object.entries(packages)) {\n const { name, version } = splitNameVersion(identifier);\n if (exclude.has(name)) continue;\n out.push({\n name,\n version,\n rawLicense: resolveFileReferencedLicense(\n flattenLicense(info.licenses),\n info.licenseFile,\n ),\n path: info.path,\n });\n }\n return out;\n};\n"],"names":["existsSync","readFileSync","licenseChecker","getLicenseTitle","join","NAME_VERSION_RE","splitNameVersion","identifier","match","name","version","flattenLicense","raw","Array","isArray","length","FILE_REFERENCE_RE","resolveFileReferencedLicense","rawLicense","licenseFile","test","trim","detected","collectNpmDependencies","options","nodeModules","start","exclude","Set","projectPackageJson","pkg","JSON","parse","add","packages","Promise","resolve","reject","init","excludePrivatePackages","err","results","out","info","Object","entries","has","push","licenses","path"],"mappings":"AAAA;;;CAGC,GACD,SAASA,UAAU,EAAEC,YAAY,QAAQ,KAAK;AAC9C,YAAYC,oBAAoB,8BAA8B;AAC9D,yEAAyE;AACzE,6EAA6E;AAC7E,8EAA8E;AAC9E,SAASC,eAAe,QAAQ,qDAAqD;AACrF,SAASC,IAAI,QAAQ,OAAO;AAa5B,MAAMC,kBAAkB;AAExB,MAAMC,mBAAmB,CACvBC;IAEA,MAAMC,QAAQD,WAAWC,KAAK,CAACH;IAC/B,IAAI,CAACG,OAAO;QACV,OAAO;YAAEC,MAAMF;YAAYG,SAAS;QAAQ;IAC9C;IACA,OAAO;QAAED,MAAMD,KAAK,CAAC,EAAE;QAAEE,SAASF,KAAK,CAAC,EAAE;IAAC;AAC7C;AAEA,MAAMG,iBAAiB,CAACC;IACtB,IAAI,CAACA,KAAK,OAAO;IACjB,IAAIC,MAAMC,OAAO,CAACF,MAAM;QACtB,IAAIA,IAAIG,MAAM,KAAK,GAAG,OAAO;QAC7B,IAAIH,IAAIG,MAAM,KAAK,GAAG,OAAOH,GAAG,CAAC,EAAE;QACnC,OAAO,CAAC,CAAC,EAAEA,IAAIR,IAAI,CAAC,QAAQ,CAAC,CAAC;IAChC;IACA,OAAOQ;AACT;AAEA;;;;CAIC,GACD,MAAMI,oBAAoB;AAE1B;;;;;;;;;;;;CAYC,GACD,OAAO,MAAMC,+BAA+B,CAC1CC,YACAC;IAEA,IAAI,CAACA,eAAe,CAACH,kBAAkBI,IAAI,CAACF,WAAWG,IAAI,KAAK;QAC9D,OAAOH;IACT;IACA,IAAII,WAA0B;IAC9B,IAAI;QACFA,WAAWnB,gBAAgBF,aAAakB,aAAa;IACvD,EAAE,OAAM;QACN,OAAOD;IACT;IACA,IAAI,CAACI,YAAYA,aAAa,eAAeN,kBAAkBI,IAAI,CAACE,WAClE,OAAOJ;IACT,OAAOI;AACT,EAAE;AAEF,OAAO,MAAMC,yBAAyB,OACpCC;IAEA,MAAMC,cAAcrB,KAAKoB,QAAQE,KAAK,EAAE;IACxC,IAAI,CAAC1B,WAAWyB,cAAc;QAC5B,OAAO,EAAE;IACX;IAEA,MAAME,UAAU,IAAIC;IAEpB,MAAMC,qBAAqBzB,KAAKoB,QAAQE,KAAK,EAAE;IAC/C,IAAI1B,WAAW6B,qBAAqB;QAClC,IAAI;YACF,MAAMC,MAAMC,KAAKC,KAAK,CAAC/B,aAAa4B,oBAAoB;YAGxD,IAAIC,IAAIrB,IAAI,EAAEkB,QAAQM,GAAG,CAACH,IAAIrB,IAAI;QACpC,EAAE,OAAM;QACN,SAAS;QACX;IACF;IAEA,MAAMyB,WAAW,MAAM,IAAIC,QACzB,CAACC,SAASC;QACRnC,eAAeoC,IAAI,CACjB;YACEZ,OAAOF,QAAQE,KAAK;YACpBa,wBAAwB;QAC1B,GACA,CAACC,KAAKC;YACJ,IAAID,KAAKH,OAAOG;iBACXJ,QAAQK;QACf;IAEJ;IAGF,MAAMC,MAAuB,EAAE;IAC/B,KAAK,MAAM,CAACnC,YAAYoC,KAAK,IAAIC,OAAOC,OAAO,CAACX,UAAW;QACzD,MAAM,EAAEzB,IAAI,EAAEC,OAAO,EAAE,GAAGJ,iBAAiBC;QAC3C,IAAIoB,QAAQmB,GAAG,CAACrC,OAAO;QACvBiC,IAAIK,IAAI,CAAC;YACPtC;YACAC;YACAQ,YAAYD,6BACVN,eAAegC,KAAKK,QAAQ,GAC5BL,KAAKxB,WAAW;YAElB8B,MAAMN,KAAKM,IAAI;QACjB;IACF;IACA,OAAOP;AACT,EAAE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/v1.0.0-rc.98/0001-sandbox-pattern-nested-stacks/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n getProjects,\n type MigrationReturnObject,\n type TargetConfiguration,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { INFRA_APP_GENERATOR_INFO } from '../../../infra/app/generator.js';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\n\n/**\n * Widen the stage pattern of the sandbox targets of ts#infra projects from\n * `<stage>/*` to `<stage>/**`.\n *\n * A single `*` matches the stage's own stacks but nothing below them, so it\n * misses stacks a construct creates inside a stack - such as the `us-east-1`\n * WebACL stack a website creates for its CloudFront distribution.\n * `cdk destroy` only deletes the stacks its pattern selects, so\n * `destroy-sandbox` left that stack, and the WebACL it bills for, deployed.\n */\n\nconst SANDBOX_TARGETS = ['deploy-sandbox', 'destroy-sandbox'];\n\n/** A quoted or bare stage pattern ending in a single `*`, ie `\"my-sandbox/*\"`. */\nconst SINGLE_STAR_PATTERN = /^(\"?)\\S+\\/\\*\\1$/;\n\nconst widen = (token: string): string => token.replace(/\\/\\*(\"?)$/, '/**$1');\n\n/**\n * Whether the command is one of the deploy/destroy commands this generator\n * vends - either a direct `cdk deploy`/`cdk destroy`, or the stage-config\n * script that wraps it. Anything else has been hand-written and is reported\n * rather than rewritten.\n */\nconst isGeneratedCommand = (command: string): boolean =>\n /(^|\\s)cdk\\s+(deploy|destroy)(\\s|$)/.test(command) ||\n command.includes('infra-deploy.ts') ||\n command.includes('infra-destroy.ts');\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n let migrated = false;\n\n for (const [name, project] of getProjects(tree)) {\n if (\n (project.metadata as { generator?: string } | undefined)?.generator !==\n INFRA_APP_GENERATOR_INFO.id\n ) {\n continue;\n }\n\n let projectChanged = false;\n\n for (const targetName of SANDBOX_TARGETS) {\n const target: TargetConfiguration | undefined =\n project.targets?.[targetName];\n const command = target?.options?.command;\n if (!target || typeof command !== 'string') {\n continue;\n }\n\n const args = command.split(/\\s+/);\n // Nothing to widen: already `/**`, or the pattern has been removed. Keeps\n // re-runs - and a project generated after this change - a no-op.\n if (!args.some((arg) => SINGLE_STAR_PATTERN.test(arg))) {\n continue;\n }\n\n if (!isGeneratedCommand(command)) {\n nextSteps.push(\n `${name}: its ${targetName} target has been customised, so it was left as it is. Widen its stage pattern from \"<stage>/*\" to \"<stage>/**\" so it also matches stacks nested below the stage's stacks, such as a website's WebACL stack.`,\n );\n continue;\n }\n\n target.options.command = args\n .map((arg) => (SINGLE_STAR_PATTERN.test(arg) ? widen(arg) : arg))\n .join(' ');\n projectChanged = true;\n }\n\n if (projectChanged) {\n updateProjectConfiguration(tree, name, project);\n migrated = true;\n }\n }\n\n if (migrated) {\n await formatFilesInSubtree(tree);\n }\n\n return { nextSteps };\n}\n"],"names":["getProjects","updateProjectConfiguration","INFRA_APP_GENERATOR_INFO","formatFilesInSubtree","SANDBOX_TARGETS","SINGLE_STAR_PATTERN","widen","token","replace","isGeneratedCommand","command","test","includes","migration","tree","nextSteps","migrated","name","project","metadata","generator","id","projectChanged","targetName","target","targets","options","args","split","some","arg","push","map","join"],"mappings":"AAAA;;;CAGC,GACD,SACEA,WAAW,EAIXC,0BAA0B,QACrB,aAAa;AACpB,SAASC,wBAAwB,QAAQ,kCAAkC;AAC3E,SAASC,oBAAoB,QAAQ,2BAA2B;AAEhE;;;;;;;;;CASC,GAED,MAAMC,kBAAkB;IAAC;IAAkB;CAAkB;AAE7D,gFAAgF,GAChF,MAAMC,sBAAsB;AAE5B,MAAMC,QAAQ,CAACC,QAA0BA,MAAMC,OAAO,CAAC,aAAa;AAEpE;;;;;CAKC,GACD,MAAMC,qBAAqB,CAACC,UAC1B,qCAAqCC,IAAI,CAACD,YAC1CA,QAAQE,QAAQ,CAAC,sBACjBF,QAAQE,QAAQ,CAAC;AAEnB,eAAe,eAAeC,UAC5BC,IAAU;IAEV,MAAMC,YAAsB,EAAE;IAC9B,IAAIC,WAAW;IAEf,KAAK,MAAM,CAACC,MAAMC,QAAQ,IAAIlB,YAAYc,MAAO;QAC/C,IACE,AAACI,QAAQC,QAAQ,EAAyCC,cAC1DlB,yBAAyBmB,EAAE,EAC3B;YACA;QACF;QAEA,IAAIC,iBAAiB;QAErB,KAAK,MAAMC,cAAcnB,gBAAiB;YACxC,MAAMoB,SACJN,QAAQO,OAAO,EAAE,CAACF,WAAW;YAC/B,MAAMb,UAAUc,QAAQE,SAAShB;YACjC,IAAI,CAACc,UAAU,OAAOd,YAAY,UAAU;gBAC1C;YACF;YAEA,MAAMiB,OAAOjB,QAAQkB,KAAK,CAAC;YAC3B,0EAA0E;YAC1E,iEAAiE;YACjE,IAAI,CAACD,KAAKE,IAAI,CAAC,CAACC,MAAQzB,oBAAoBM,IAAI,CAACmB,OAAO;gBACtD;YACF;YAEA,IAAI,CAACrB,mBAAmBC,UAAU;gBAChCK,UAAUgB,IAAI,CACZ,GAAGd,KAAK,MAAM,EAAEM,WAAW,2MAA2M,CAAC;gBAEzO;YACF;YAEAC,OAAOE,OAAO,CAAChB,OAAO,GAAGiB,KACtBK,GAAG,CAAC,CAACF,MAASzB,oBAAoBM,IAAI,CAACmB,OAAOxB,MAAMwB,OAAOA,KAC3DG,IAAI,CAAC;YACRX,iBAAiB;QACnB;QAEA,IAAIA,gBAAgB;YAClBrB,2BAA2Ba,MAAMG,MAAMC;YACvCF,WAAW;QACb;IACF;IAEA,IAAIA,UAAU;QACZ,MAAMb,qBAAqBW;IAC7B;IAEA,OAAO;QAAEC;IAAU;AACrB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/v1.0.0-rc.98/0002-shadcn-cn-package/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n joinPathFragments,\n type MigrationReturnObject,\n readJson,\n type Tree,\n} from '@nx/devkit';\nimport { applyGritQL, matchGritQL } from '../../../utils/ast.js';\nimport {\n addDependenciesToPackageJson,\n removeDependenciesFromPackageJson,\n} from '../../../utils/dependencies.js';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\nimport {\n PACKAGES_DIR,\n SHARED_SHADCN_DIR,\n} from '../../../utils/shared-constructs-constants.js';\nimport { TS_VERSIONS } from '../../../utils/versions.js';\n\n/**\n * Move the shared shadcn package onto the `cn` package.\n *\n * The shadcn registry now serves components importing `cn` from the `cn`\n * package and declares it as a registry dependency, so a component added by\n * `shadcn add` no longer resolves the package's own `#lib/utils` helper. This\n * carries an existing workspace onto that shape: the components import `cn`,\n * `src/lib/utils.ts` becomes the single-line re-export shadcn's own install\n * guide prescribes, which keeps every consumer importing `cn` through\n * `<scope>common-shadcn/lib/utils` working, and clsx / tailwind-merge are\n * dropped now that nothing imports them.\n *\n * How to write a migration:\n * - https://nx.dev/docs/kb/migration-generators\n * - What `nextSteps` means: https://nx.dev/docs/reference/devkit/MigrationReturnObject\n *\n * Guardrails:\n * - Only touches a `packages/common/shadcn` this plugin's generators produced,\n * guarded by `components.json`'s aliases still matching the generated shape.\n * - An import is only rewritten when `cn` is its sole binding, so a file also\n * pulling a user's own helper out of `#lib/utils` keeps resolving through the\n * re-export.\n * - `src/lib/utils.ts` is only rewritten while it still holds the generated\n * `twMerge(clsx(...))` helper; a customised one is reported instead.\n * - clsx / tailwind-merge are only dropped once nothing under `src` imports\n * them.\n * - Idempotent: every write is guarded by the old shape still being present.\n */\n\nconst libraryRoot = joinPathFragments(PACKAGES_DIR, SHARED_SHADCN_DIR);\nconst componentsJsonPath = joinPathFragments(libraryRoot, 'components.json');\nconst packageJsonPath = joinPathFragments(libraryRoot, 'package.json');\nconst srcRoot = joinPathFragments(libraryRoot, 'src');\nconst utilsPath = joinPathFragments(srcRoot, 'lib', 'utils.ts');\n\n/** The aliases today's generators write, which this migration leaves in place. */\nconst generatedAliases: Record<string, string> = {\n components: '#components',\n utils: '#lib/utils',\n hooks: '#hooks',\n lib: '#lib',\n ui: '#components/ui',\n};\n\nconst CN_IMPORT_REWRITE = `\\`import { cn } from '#lib/utils'\\` => \\`import { cn } from 'cn'\\``;\n\n/** The generated helper, whichever way the user's formatter has laid it out. */\nconst GENERATED_CN_HELPER = `\\`twMerge(clsx($_))\\``;\n\nconst importsPackage = (name: string): string => `\\`import $_ from '${name}'\\``;\n\nconst REEXPORT_UTILS = `export { cn } from 'cn';\\n`;\n\nconst DROPPED_PACKAGES = ['clsx', 'tailwind-merge'] as const;\n\n/** Every `.ts`/`.tsx` file in the package's source tree. */\nconst sourceFiles = (tree: Tree, dir: string): string[] => {\n if (!tree.exists(dir)) {\n return [];\n }\n return tree.children(dir).flatMap((entry) => {\n const path = joinPathFragments(dir, entry);\n if (!tree.isFile(path)) {\n return sourceFiles(tree, path);\n }\n return path.endsWith('.ts') || path.endsWith('.tsx') ? [path] : [];\n });\n};\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n if (!tree.exists(componentsJsonPath) || !tree.exists(packageJsonPath)) {\n return { nextSteps };\n }\n\n const aliases =\n readJson<{ aliases?: Record<string, string> }>(tree, componentsJsonPath)\n .aliases ?? {};\n if (Object.entries(generatedAliases).some(([k, v]) => aliases[k] !== v)) {\n return { nextSteps };\n }\n\n const files = sourceFiles(tree, srcRoot);\n\n for (const file of files) {\n await applyGritQL(tree, file, CN_IMPORT_REWRITE);\n }\n\n if (tree.exists(utilsPath)) {\n if (await matchGritQL(tree, utilsPath, GENERATED_CN_HELPER)) {\n tree.write(utilsPath, REEXPORT_UTILS);\n } else if (tree.read(utilsPath, 'utf-8') !== REEXPORT_UTILS) {\n nextSteps.push(\n `${utilsPath}: no longer holds the generated cn helper - left untouched. Re-export cn from the 'cn' package by hand so consumers importing it from here keep working.`,\n );\n }\n }\n\n addDependenciesToPackageJson(\n tree,\n { cn: TS_VERSIONS.cn },\n {},\n packageJsonPath,\n );\n\n const stillImported = new Set<string>();\n for (const file of sourceFiles(tree, srcRoot)) {\n for (const name of DROPPED_PACKAGES) {\n if (await matchGritQL(tree, file, importsPackage(name))) {\n stillImported.add(name);\n }\n }\n }\n\n const dropped = DROPPED_PACKAGES.filter((name) => !stillImported.has(name));\n removeDependenciesFromPackageJson(tree, dropped, dropped, packageJsonPath);\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["joinPathFragments","readJson","applyGritQL","matchGritQL","addDependenciesToPackageJson","removeDependenciesFromPackageJson","formatFilesInSubtree","PACKAGES_DIR","SHARED_SHADCN_DIR","TS_VERSIONS","libraryRoot","componentsJsonPath","packageJsonPath","srcRoot","utilsPath","generatedAliases","components","utils","hooks","lib","ui","CN_IMPORT_REWRITE","GENERATED_CN_HELPER","importsPackage","name","REEXPORT_UTILS","DROPPED_PACKAGES","sourceFiles","tree","dir","exists","children","flatMap","entry","path","isFile","endsWith","migration","nextSteps","aliases","Object","entries","some","k","v","files","file","write","read","push","cn","stillImported","Set","add","dropped","filter","has"],"mappings":"AAAA;;;CAGC,GACD,SACEA,iBAAiB,EAEjBC,QAAQ,QAEH,aAAa;AACpB,SAASC,WAAW,EAAEC,WAAW,QAAQ,wBAAwB;AACjE,SACEC,4BAA4B,EAC5BC,iCAAiC,QAC5B,iCAAiC;AACxC,SAASC,oBAAoB,QAAQ,2BAA2B;AAChE,SACEC,YAAY,EACZC,iBAAiB,QACZ,gDAAgD;AACvD,SAASC,WAAW,QAAQ,6BAA6B;AAEzD;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BC,GAED,MAAMC,cAAcV,kBAAkBO,cAAcC;AACpD,MAAMG,qBAAqBX,kBAAkBU,aAAa;AAC1D,MAAME,kBAAkBZ,kBAAkBU,aAAa;AACvD,MAAMG,UAAUb,kBAAkBU,aAAa;AAC/C,MAAMI,YAAYd,kBAAkBa,SAAS,OAAO;AAEpD,gFAAgF,GAChF,MAAME,mBAA2C;IAC/CC,YAAY;IACZC,OAAO;IACPC,OAAO;IACPC,KAAK;IACLC,IAAI;AACN;AAEA,MAAMC,oBAAoB,CAAC,kEAAkE,CAAC;AAE9F,8EAA8E,GAC9E,MAAMC,sBAAsB,CAAC,qBAAqB,CAAC;AAEnD,MAAMC,iBAAiB,CAACC,OAAyB,CAAC,kBAAkB,EAAEA,KAAK,GAAG,CAAC;AAE/E,MAAMC,iBAAiB,CAAC,0BAA0B,CAAC;AAEnD,MAAMC,mBAAmB;IAAC;IAAQ;CAAiB;AAEnD,0DAA0D,GAC1D,MAAMC,cAAc,CAACC,MAAYC;IAC/B,IAAI,CAACD,KAAKE,MAAM,CAACD,MAAM;QACrB,OAAO,EAAE;IACX;IACA,OAAOD,KAAKG,QAAQ,CAACF,KAAKG,OAAO,CAAC,CAACC;QACjC,MAAMC,OAAOlC,kBAAkB6B,KAAKI;QACpC,IAAI,CAACL,KAAKO,MAAM,CAACD,OAAO;YACtB,OAAOP,YAAYC,MAAMM;QAC3B;QACA,OAAOA,KAAKE,QAAQ,CAAC,UAAUF,KAAKE,QAAQ,CAAC,UAAU;YAACF;SAAK,GAAG,EAAE;IACpE;AACF;AAEA,eAAe,eAAeG,UAC5BT,IAAU;IAEV,MAAMU,YAAsB,EAAE;IAE9B,IAAI,CAACV,KAAKE,MAAM,CAACnB,uBAAuB,CAACiB,KAAKE,MAAM,CAAClB,kBAAkB;QACrE,OAAO;YAAE0B;QAAU;IACrB;IAEA,MAAMC,UACJtC,SAA+C2B,MAAMjB,oBAClD4B,OAAO,IAAI,CAAC;IACjB,IAAIC,OAAOC,OAAO,CAAC1B,kBAAkB2B,IAAI,CAAC,CAAC,CAACC,GAAGC,EAAE,GAAKL,OAAO,CAACI,EAAE,KAAKC,IAAI;QACvE,OAAO;YAAEN;QAAU;IACrB;IAEA,MAAMO,QAAQlB,YAAYC,MAAMf;IAEhC,KAAK,MAAMiC,QAAQD,MAAO;QACxB,MAAM3C,YAAY0B,MAAMkB,MAAMzB;IAChC;IAEA,IAAIO,KAAKE,MAAM,CAAChB,YAAY;QAC1B,IAAI,MAAMX,YAAYyB,MAAMd,WAAWQ,sBAAsB;YAC3DM,KAAKmB,KAAK,CAACjC,WAAWW;QACxB,OAAO,IAAIG,KAAKoB,IAAI,CAAClC,WAAW,aAAaW,gBAAgB;YAC3Da,UAAUW,IAAI,CACZ,GAAGnC,UAAU,wJAAwJ,CAAC;QAE1K;IACF;IAEAV,6BACEwB,MACA;QAAEsB,IAAIzC,YAAYyC,EAAE;IAAC,GACrB,CAAC,GACDtC;IAGF,MAAMuC,gBAAgB,IAAIC;IAC1B,KAAK,MAAMN,QAAQnB,YAAYC,MAAMf,SAAU;QAC7C,KAAK,MAAMW,QAAQE,iBAAkB;YACnC,IAAI,MAAMvB,YAAYyB,MAAMkB,MAAMvB,eAAeC,QAAQ;gBACvD2B,cAAcE,GAAG,CAAC7B;YACpB;QACF;IACF;IAEA,MAAM8B,UAAU5B,iBAAiB6B,MAAM,CAAC,CAAC/B,OAAS,CAAC2B,cAAcK,GAAG,CAAChC;IACrEnB,kCAAkCuB,MAAM0B,SAASA,SAAS1C;IAE1D,MAAMN,qBAAqBsB;IAE3B,OAAO;QAAEU;IAAU;AACrB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/v1.0.2/0001-terraform-harness-environment-variables/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n joinPathFragments,\n type MigrationReturnObject,\n type Tree,\n} from '@nx/devkit';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\nimport {\n PACKAGES_DIR,\n SHARED_TERRAFORM_DIR,\n} from '../../../utils/shared-constructs-constants.js';\n\n/**\n * Stop each vended Terraform AgentCore Harness app module\n * (`app/harnesses/<name>/<name>.tf`) sending a null `environment_variables`.\n *\n * The service stores no environment variables as an empty map and returns one,\n * so a null fails the apply with \"inconsistent values for sensitive attribute\"\n * once the Harness has already been created, leaving it tainted. Every\n * subsequent apply fails the same way.\n *\n * Modules whose assignment has been edited are left untouched and reported via\n * `nextSteps`.\n */\n\nconst TERRAFORM_HARNESS_APP_DIR = `${PACKAGES_DIR}/${SHARED_TERRAFORM_DIR}/src/app/harnesses`;\n\n/** The assignment the generator used to write. */\nconst NULLABLE_ASSIGNMENT = 'environment_variables = var.environment_variables';\n\n/** What it becomes, so the value sent matches what the service returns. */\nconst COALESCED_ASSIGNMENT =\n 'environment_variables = coalesce(var.environment_variables, {})';\n\nconst divergedMessage = (filePath: string) =>\n `${filePath}: its environment_variables assignment has been edited, so it was left as it is. Change it to \\`${COALESCED_ASSIGNMENT}\\` — the AgentCore service returns an empty map when a Harness has no environment variables, and sending null fails the apply after the Harness has been created.`;\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n let migrated = false;\n\n if (!tree.exists(TERRAFORM_HARNESS_APP_DIR)) {\n return { nextSteps }; // This workspace has no Terraform harness modules.\n }\n\n for (const dirName of tree.children(TERRAFORM_HARNESS_APP_DIR)) {\n const filePath = joinPathFragments(\n TERRAFORM_HARNESS_APP_DIR,\n dirName,\n `${dirName}.tf`,\n );\n if (!tree.exists(filePath)) {\n continue; // Not a harness app module directory.\n }\n\n const contents = tree.read(filePath, 'utf-8') ?? '';\n\n if (contents.includes(COALESCED_ASSIGNMENT)) {\n continue; // Already migrated, so a re-run is a no-op.\n }\n\n if (!contents.includes(NULLABLE_ASSIGNMENT)) {\n nextSteps.push(divergedMessage(filePath));\n continue;\n }\n\n tree.write(\n filePath,\n contents.replace(NULLABLE_ASSIGNMENT, COALESCED_ASSIGNMENT),\n );\n migrated = true;\n }\n\n if (migrated) {\n await formatFilesInSubtree(tree, TERRAFORM_HARNESS_APP_DIR);\n }\n\n return { nextSteps };\n}\n"],"names":["joinPathFragments","formatFilesInSubtree","PACKAGES_DIR","SHARED_TERRAFORM_DIR","TERRAFORM_HARNESS_APP_DIR","NULLABLE_ASSIGNMENT","COALESCED_ASSIGNMENT","divergedMessage","filePath","migration","tree","nextSteps","migrated","exists","dirName","children","contents","read","includes","push","write","replace"],"mappings":"AAAA;;;CAGC,GACD,SACEA,iBAAiB,QAGZ,aAAa;AACpB,SAASC,oBAAoB,QAAQ,2BAA2B;AAChE,SACEC,YAAY,EACZC,oBAAoB,QACf,gDAAgD;AAEvD;;;;;;;;;;;CAWC,GAED,MAAMC,4BAA4B,GAAGF,aAAa,CAAC,EAAEC,qBAAqB,kBAAkB,CAAC;AAE7F,gDAAgD,GAChD,MAAME,sBAAsB;AAE5B,yEAAyE,GACzE,MAAMC,uBACJ;AAEF,MAAMC,kBAAkB,CAACC,WACvB,GAAGA,SAAS,gGAAgG,EAAEF,qBAAqB,iKAAiK,CAAC;AAEvS,eAAe,eAAeG,UAC5BC,IAAU;IAEV,MAAMC,YAAsB,EAAE;IAC9B,IAAIC,WAAW;IAEf,IAAI,CAACF,KAAKG,MAAM,CAACT,4BAA4B;QAC3C,OAAO;YAAEO;QAAU,GAAG,mDAAmD;IAC3E;IAEA,KAAK,MAAMG,WAAWJ,KAAKK,QAAQ,CAACX,2BAA4B;QAC9D,MAAMI,WAAWR,kBACfI,2BACAU,SACA,GAAGA,QAAQ,GAAG,CAAC;QAEjB,IAAI,CAACJ,KAAKG,MAAM,CAACL,WAAW;YAC1B,UAAU,sCAAsC;QAClD;QAEA,MAAMQ,WAAWN,KAAKO,IAAI,CAACT,UAAU,YAAY;QAEjD,IAAIQ,SAASE,QAAQ,CAACZ,uBAAuB;YAC3C,UAAU,4CAA4C;QACxD;QAEA,IAAI,CAACU,SAASE,QAAQ,CAACb,sBAAsB;YAC3CM,UAAUQ,IAAI,CAACZ,gBAAgBC;YAC/B;QACF;QAEAE,KAAKU,KAAK,CACRZ,UACAQ,SAASK,OAAO,CAAChB,qBAAqBC;QAExCM,WAAW;IACb;IAEA,IAAIA,UAAU;QACZ,MAAMX,qBAAqBS,MAAMN;IACnC;IAEA,OAAO;QAAEO;IAAU;AACrB"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { type MigrationReturnObject, type Tree } from '@nx/devkit';
|
|
6
|
+
export default function migration(tree: Tree): Promise<MigrationReturnObject>;
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/ import { getProjects, joinPathFragments, updateProjectConfiguration } from "@nx/devkit";
|
|
5
|
+
import { relative } from "path";
|
|
6
|
+
import { TERRAFORM_PROJECT_GENERATOR_INFO } from "../../../terraform/project/generator.js";
|
|
7
|
+
import { formatFilesInSubtree } from "../../../utils/format.js";
|
|
8
|
+
import { sortObjectKeys } from "../../../utils/object.js";
|
|
9
|
+
/**
|
|
10
|
+
* Give the shared Terraform provider plugin cache a single writer.
|
|
11
|
+
*
|
|
12
|
+
* `init`, `test` and `validate` each ran their own `terraform init` against one
|
|
13
|
+
* per-project cache, and Nx schedules them concurrently — `plan` depends on both
|
|
14
|
+
* `init` and `validate`. Two `terraform init` runs filling the cache at once each
|
|
15
|
+
* compute a different hash for the same provider, because the hash covers a
|
|
16
|
+
* directory the other is still writing, and terraform then rejects the mismatch
|
|
17
|
+
* against the lock file: "the cached package ... does not match any of the
|
|
18
|
+
* checksums recorded in the dependency lock file".
|
|
19
|
+
*
|
|
20
|
+
* The new `terraform-init` target runs that init once, and `test`, `validate` and
|
|
21
|
+
* `init` depend on it — `test` and `validate` now run against the `TF_DATA_DIR`
|
|
22
|
+
* it prepared rather than initialising their own.
|
|
23
|
+
*/ const TERRAFORM_INIT = 'terraform-init';
|
|
24
|
+
/** `terraform init` as the pre-fix `test` and `validate` targets ran it. */ const BACKENDLESS_INIT = 'terraform init -backend=false';
|
|
25
|
+
const divergedStep = (projectName, targetName)=>`${projectName}: its '${targetName}' target no longer matches the shape the generator produced - left untouched. Point it at the \`TF_DATA_DIR\` of the new \`${TERRAFORM_INIT}\` target and add \`"dependsOn": ["${TERRAFORM_INIT}"]\`, so its \`terraform init\` no longer races the other targets over the provider cache.`;
|
|
26
|
+
/** Path from a target running in `{projectRoot}/src` back to the workspace root. */ const rootRelativePath = (projectRoot)=>relative(joinPathFragments(projectRoot, 'src'), '.').replace(/\\/g, '/');
|
|
27
|
+
const pluginCacheDirFor = (toRoot)=>joinPathFragments(toRoot, '.terraform', 'plugin-cache', '{projectRoot}');
|
|
28
|
+
const dataDirFor = (toRoot, name)=>joinPathFragments(toRoot, 'dist', '{projectRoot}', name);
|
|
29
|
+
/**
|
|
30
|
+
* The target as the generator vends it: `-backend=false` needs no credentials,
|
|
31
|
+
* so this runs on a fresh workspace before `bootstrap`, and its `TF_DATA_DIR`
|
|
32
|
+
* keeps the `.terraform` it initialises out of `src`.
|
|
33
|
+
*/ const terraformInitTarget = (projectRoot)=>{
|
|
34
|
+
const toRoot = rootRelativePath(projectRoot);
|
|
35
|
+
const pluginCacheDir = pluginCacheDirFor(toRoot);
|
|
36
|
+
return {
|
|
37
|
+
executor: 'nx:run-commands',
|
|
38
|
+
options: {
|
|
39
|
+
commands: [
|
|
40
|
+
{
|
|
41
|
+
command: `shx mkdir -p ${pluginCacheDir}`,
|
|
42
|
+
forwardAllArgs: false
|
|
43
|
+
},
|
|
44
|
+
BACKENDLESS_INIT
|
|
45
|
+
],
|
|
46
|
+
forwardAllArgs: true,
|
|
47
|
+
cwd: '{projectRoot}/src',
|
|
48
|
+
parallel: false,
|
|
49
|
+
env: {
|
|
50
|
+
TF_DATA_DIR: dataDirFor(toRoot, TERRAFORM_INIT),
|
|
51
|
+
TF_PLUGIN_CACHE_DIR: pluginCacheDir
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
/** Every command a target runs, across its options and its configurations. */ const commandsOf = (target)=>[
|
|
57
|
+
target.options,
|
|
58
|
+
...Object.values(target.configurations ?? {})
|
|
59
|
+
].flatMap((holder)=>[
|
|
60
|
+
holder?.command,
|
|
61
|
+
...Array.isArray(holder?.commands) ? holder.commands : []
|
|
62
|
+
]).map((command)=>typeof command === 'string' ? command : command?.command).filter((command)=>typeof command === 'string');
|
|
63
|
+
/**
|
|
64
|
+
* Whether the target still runs the `terraform init` this migration orders. A
|
|
65
|
+
* library's `init` runs it directly and an application's delegates to the vended
|
|
66
|
+
* script.
|
|
67
|
+
*/ const runsTerraformInit = (target)=>commandsOf(target).some((command)=>command.includes('terraform init') || command.includes('scripts/init.ts'));
|
|
68
|
+
/** Creating the plugin cache directory, which `terraform-init` now does. */ const isMakeCacheDir = (command)=>/^(shx mkdir -p|make-dir)\s/.test(command) && command.includes('plugin-cache');
|
|
69
|
+
/**
|
|
70
|
+
* Rewrites `test` or `validate` to run against the `TF_DATA_DIR` `terraform-init`
|
|
71
|
+
* prepared. Only the exact shape the generator produced is rewritten: its own
|
|
72
|
+
* `terraform init` (with the cache directory the plugin-cache fix added ahead of
|
|
73
|
+
* it), then the one terraform command the target exists to run. Anything else is
|
|
74
|
+
* the user's, and is reported instead.
|
|
75
|
+
*/ const migrateInitlessTarget = (target, verb, toRoot)=>{
|
|
76
|
+
const commands = commandsOf(target).filter((command)=>!isMakeCacheDir(command));
|
|
77
|
+
if (commands.length !== 2 || commands[0] !== BACKENDLESS_INIT || commands[1] !== `terraform ${verb}`) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
const options = target.options ?? {};
|
|
81
|
+
const env = options.env ?? {};
|
|
82
|
+
if (env.TF_DATA_DIR !== dataDirFor(toRoot, `terraform-${verb}`)) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
const { TF_DATA_DIR: _dataDir, TF_PLUGIN_CACHE_DIR: _cacheDir, ...rest } = env;
|
|
86
|
+
delete options.commands;
|
|
87
|
+
// `parallel: false` sequenced the init ahead of the command; one command left.
|
|
88
|
+
delete options.parallel;
|
|
89
|
+
target.options = {
|
|
90
|
+
...options,
|
|
91
|
+
command: `terraform ${verb}`,
|
|
92
|
+
env: {
|
|
93
|
+
...rest,
|
|
94
|
+
TF_DATA_DIR: dataDirFor(toRoot, TERRAFORM_INIT)
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
return true;
|
|
98
|
+
};
|
|
99
|
+
export default async function migration(tree) {
|
|
100
|
+
const nextSteps = [];
|
|
101
|
+
for (const [projectName, project] of getProjects(tree)){
|
|
102
|
+
const generator = project.metadata?.generator;
|
|
103
|
+
if (generator !== TERRAFORM_PROJECT_GENERATOR_INFO.id) continue;
|
|
104
|
+
let targets = project.targets ?? {};
|
|
105
|
+
const toRoot = rootRelativePath(project.root);
|
|
106
|
+
let changed = false;
|
|
107
|
+
// Guarded on the target being absent, so a re-run — and a project generated
|
|
108
|
+
// with it — is a no-op.
|
|
109
|
+
if (!targets[TERRAFORM_INIT]) {
|
|
110
|
+
targets = sortObjectKeys({
|
|
111
|
+
...targets,
|
|
112
|
+
[TERRAFORM_INIT]: terraformInitTarget(project.root)
|
|
113
|
+
});
|
|
114
|
+
changed = true;
|
|
115
|
+
}
|
|
116
|
+
for (const targetName of [
|
|
117
|
+
'init',
|
|
118
|
+
'test',
|
|
119
|
+
'validate'
|
|
120
|
+
]){
|
|
121
|
+
const target = targets[targetName];
|
|
122
|
+
if (!target) continue;
|
|
123
|
+
if (target.dependsOn?.includes(TERRAFORM_INIT)) continue;
|
|
124
|
+
// `init` keeps its own backend-configured `terraform init`; `test` and
|
|
125
|
+
// `validate` hand theirs over to `terraform-init`, so nothing is ordered
|
|
126
|
+
// after a target whose shape is no longer recognised.
|
|
127
|
+
const migrated = targetName === 'init' ? runsTerraformInit(target) : migrateInitlessTarget(target, targetName, toRoot);
|
|
128
|
+
if (!migrated) {
|
|
129
|
+
nextSteps.push(divergedStep(projectName, targetName));
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
// Prepended rather than appended, so a migrated workspace matches a
|
|
133
|
+
// freshly generated one.
|
|
134
|
+
target.dependsOn = [
|
|
135
|
+
TERRAFORM_INIT,
|
|
136
|
+
...target.dependsOn ?? []
|
|
137
|
+
];
|
|
138
|
+
changed = true;
|
|
139
|
+
}
|
|
140
|
+
if (changed) {
|
|
141
|
+
updateProjectConfiguration(tree, projectName, {
|
|
142
|
+
...project,
|
|
143
|
+
targets
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
await formatFilesInSubtree(tree);
|
|
148
|
+
return {
|
|
149
|
+
nextSteps
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
//# sourceMappingURL=migration.js.map
|