@aws/nx-plugin 1.1.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 +31 -29
- package/generators.json +16 -0
- package/migrations.json +6 -1
- package/package.json +1 -1
- package/src/agentcore-harness/generator.d.ts +1 -1
- package/src/greengrass/component/common.d.ts +60 -0
- package/src/greengrass/component/common.js +191 -0
- package/src/greengrass/component/common.js.map +1 -0
- package/src/greengrass/component/dependencies.d.ts +101 -0
- package/src/greengrass/component/dependencies.js +37 -0
- package/src/greengrass/component/dependencies.js.map +1 -0
- package/src/greengrass/component/generator.d.ts +174 -0
- package/src/greengrass/component/generator.js +32 -0
- package/src/greengrass/component/generator.js.map +1 -0
- package/src/greengrass/component/metadata.d.ts +2 -0
- package/src/greengrass/component/metadata.js +14 -0
- package/src/greengrass/component/metadata.js.map +1 -0
- package/src/greengrass/component/python/__snapshots__/generator.spec.ts.snap +450 -0
- package/src/greengrass/component/python/files/component/main.py.template +60 -0
- package/src/greengrass/component/python/files/component/recipe.yaml.template +30 -0
- package/src/greengrass/component/python/files/gdk/gdk-config.json.template +13 -0
- package/src/greengrass/component/python/files/tests/test___componentSnakeCase__.py.template +37 -0
- package/src/greengrass/component/python/generator.d.ts +15 -0
- package/src/greengrass/component/python/generator.js +192 -0
- package/src/greengrass/component/python/generator.js.map +1 -0
- package/src/greengrass/component/schema.d.js +6 -0
- package/src/greengrass/component/schema.d.js.map +1 -0
- package/src/greengrass/component/schema.d.ts +18 -0
- package/src/greengrass/component/schema.json +82 -0
- package/src/greengrass/component/typescript/__snapshots__/generator.spec.ts.snap +275 -0
- package/src/greengrass/component/typescript/files/component/recipe.yaml.template +41 -0
- package/src/greengrass/component/typescript/files/entrypoint/main.ts.template +58 -0
- package/src/greengrass/component/typescript/files/gdk/gdk-config.json.template +13 -0
- package/src/greengrass/component/typescript/files/scripts/vendor-crt-addon.ts.template +115 -0
- package/src/greengrass/component/typescript/generator.d.ts +16 -0
- package/src/greengrass/component/typescript/generator.js +194 -0
- package/src/greengrass/component/typescript/generator.js.map +1 -0
- package/src/infra/app/generator.d.ts +1 -1
- package/src/init/generator.d.ts +1 -1
- package/src/internal/test-matrix/generator.js +48 -1
- package/src/internal/test-matrix/generator.js.map +1 -1
- package/src/license/dependency-check/pre-approved.js +2 -1
- package/src/license/dependency-check/pre-approved.js.map +1 -1
- package/src/migrations/latest/ts-agent-guardrails-terraform-version-retention/metadata.json +3 -0
- package/src/migrations/latest/ts-agent-guardrails-terraform-version-retention/migration.d.ts +6 -0
- package/src/migrations/latest/ts-agent-guardrails-terraform-version-retention/migration.js +118 -0
- package/src/migrations/latest/ts-agent-guardrails-terraform-version-retention/migration.js.map +1 -0
- package/src/open-api/py-client/generator.d.ts +1 -1
- package/src/preset/__snapshots__/generator.spec.ts.snap +4 -0
- package/src/preset/generator.d.ts +1 -1
- package/src/py/agent/a2a-connection/generator.d.ts +1 -1
- package/src/py/agent/gateway-connection/generator.d.ts +1 -1
- package/src/py/agent/guardrails/__snapshots__/generator.spec.ts.snap +3813 -0
- package/src/py/agent/guardrails/files/langchain/guardrail.py.template +135 -0
- package/src/py/agent/guardrails/files/strands/guardrail.py.template +93 -0
- package/src/py/agent/guardrails/generator.d.ts +10 -0
- package/src/py/agent/guardrails/generator.js +175 -0
- package/src/py/agent/guardrails/generator.js.map +1 -0
- package/src/py/agent/guardrails/runtime-check/run_checks.py +250 -0
- package/src/py/agent/guardrails/schema.d.js +6 -0
- package/src/py/agent/guardrails/schema.d.js.map +1 -0
- package/src/py/agent/guardrails/schema.d.ts +9 -0
- package/src/py/agent/guardrails/schema.json +25 -0
- package/src/py/agent/mcp-connection/generator.d.ts +1 -1
- package/src/py/agent/react-connection/generator.d.ts +1 -1
- package/src/py/fast-api/react/generator.d.ts +1 -1
- package/src/py/project/generator.js +2 -0
- package/src/py/project/generator.js.map +1 -1
- package/src/sdk/greengrass.d.ts +6 -0
- package/src/sdk/greengrass.js +6 -0
- package/src/sdk/greengrass.js.map +1 -0
- package/src/sdk/py.d.ts +2 -0
- package/src/sdk/py.js +1 -0
- package/src/sdk/py.js.map +1 -1
- package/src/smithy/project/generator.d.ts +1 -1
- package/src/smithy/react-connection/generator.d.ts +1 -1
- package/src/terraform/project/generator.d.ts +1 -1
- package/src/trpc/react/generator.d.ts +1 -1
- package/src/ts/agent/a2a-connection/generator.d.ts +1 -1
- package/src/ts/agent/gateway-connection/generator.d.ts +1 -1
- package/src/ts/agent/guardrails/__snapshots__/generator.spec.ts.snap +54 -3
- package/src/ts/agent/guardrails/generator.js +2 -1
- package/src/ts/agent/guardrails/generator.js.map +1 -1
- package/src/ts/agent/mcp-connection/generator.d.ts +1 -1
- package/src/ts/agent/react-connection/generator.d.ts +1 -1
- package/src/ts/astro-docs/generator.d.ts +1 -1
- package/src/ts/dcr-proxy/generator.d.ts +1 -1
- package/src/ts/dynamodb/generator.d.ts +1 -1
- package/src/ts/lambda-function/generator.d.ts +1 -1
- package/src/ts/lib/generator.d.ts +1 -1
- package/src/ts/nx-generator/generator.d.ts +1 -1
- package/src/ts/nx-migration/generator.d.ts +1 -1
- package/src/ts/nx-plugin/generator.d.ts +1 -1
- package/src/ts/rdb/generator.d.ts +1 -1
- package/src/ts/react-website/agui/generator.d.ts +1 -1
- package/src/utils/__snapshots__/shared-greengrass-scripts.spec.ts.snap +1279 -0
- package/src/utils/files/common/scripts/src/greengrass/build-artifact.ts.template +236 -0
- package/src/utils/files/common/scripts/src/greengrass/component-logs.ts.template +48 -0
- package/src/utils/files/common/scripts/src/greengrass/deploy-local.ts.template +497 -0
- package/src/utils/files/common/scripts/src/greengrass/recipe-utils.ts.template +356 -0
- package/src/utils/files/common/scripts/src/greengrass/zip-writer.ts.template +121 -0
- package/src/utils/files/terraform/src/core/runtime-config/read/read.tf.template +3 -3
- package/src/utils/files/terraform/src/metrics/metrics.tf.template +1 -1
- package/src/utils/greengrass/constants.d.ts +58 -0
- package/src/utils/greengrass/constants.js +63 -0
- package/src/utils/greengrass/constants.js.map +1 -0
- package/src/utils/greengrass/naming.d.ts +46 -0
- package/src/utils/greengrass/naming.js +67 -0
- package/src/utils/greengrass/naming.js.map +1 -0
- package/src/utils/greengrass/recipe.d.ts +143 -0
- package/src/utils/greengrass/recipe.js +119 -0
- package/src/utils/greengrass/recipe.js.map +1 -0
- package/src/utils/greengrass-constructs/files/cdk/app/greengrass-component/__componentDirName__.ts.template +42 -0
- package/src/utils/greengrass-constructs/files/cdk/core/greengrass/artifact-bucket.ts.template +82 -0
- package/src/utils/greengrass-constructs/files/cdk/core/greengrass/component-version.ts.template +370 -0
- package/src/utils/greengrass-constructs/files/cdk/core/greengrass/deployment.ts.template +276 -0
- package/src/utils/greengrass-constructs/files/cdk/core/greengrass/index.ts.template +5 -0
- package/src/utils/greengrass-constructs/files/cdk/core/greengrass/next-version.ts.template +119 -0
- package/src/utils/greengrass-constructs/files/cdk/core/greengrass/recipe.ts.template +90 -0
- package/src/utils/greengrass-constructs/files/next-version/__nextVersionFileName__.template +195 -0
- package/src/utils/greengrass-constructs/files/terraform/app/greengrass-component/__componentDirName__/__componentDirName__.tf.template +26 -0
- package/src/utils/greengrass-constructs/files/terraform/core/greengrass/artifact-bucket/main.tf.template +204 -0
- package/src/utils/greengrass-constructs/files/terraform/core/greengrass/component-version/main.tf.template +156 -0
- package/src/utils/greengrass-constructs/files/terraform/core/greengrass/deployment/main.tf.template +186 -0
- package/src/utils/greengrass-constructs/greengrass-constructs.d.ts +57 -0
- package/src/utils/greengrass-constructs/greengrass-constructs.js +154 -0
- package/src/utils/greengrass-constructs/greengrass-constructs.js.map +1 -0
- package/src/utils/guardrail-constructs/files/terraform/app/guardrails/__nameKebabCase__/__nameKebabCase__-guardrail.tf.template +18 -1
- package/src/utils/guardrail-constructs/guardrail-constructs.d.ts +5 -0
- package/src/utils/guardrail-constructs/guardrail-constructs.js +8 -0
- package/src/utils/guardrail-constructs/guardrail-constructs.js.map +1 -1
- package/src/utils/guardrail-constructs/guardrail-wiring.d.ts +7 -0
- package/src/utils/guardrail-constructs/guardrail-wiring.js +6 -5
- package/src/utils/guardrail-constructs/guardrail-wiring.js.map +1 -1
- package/src/utils/nx.d.ts +15 -0
- package/src/utils/nx.js +32 -0
- package/src/utils/nx.js.map +1 -1
- package/src/utils/shared-greengrass-scripts.d.ts +21 -0
- package/src/utils/shared-greengrass-scripts.js +43 -0
- package/src/utils/shared-greengrass-scripts.js.map +1 -0
- package/src/utils/test/fake-aws/fake_aws.py +205 -0
- package/src/utils/test/python-dependencies.d.ts +6 -0
- package/src/utils/test/python-dependencies.js +19 -0
- package/src/utils/test/python-dependencies.js.map +1 -1
- package/src/utils/test/warm-python-cache.js +5 -1
- package/src/utils/test/warm-python-cache.js.map +1 -1
- package/src/utils/versions.d.ts +7 -0
- package/src/utils/versions.js +7 -0
- package/src/utils/versions.js.map +1 -1
- /package/src/{ts/agent/guardrails/files/agent → utils/guardrail-constructs/files/policy}/guardrail.json.template +0 -0
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { join, relative } from 'node:path';
|
|
3
|
+
import yaml from 'js-yaml';
|
|
4
|
+
import { loadRecipe, validateManifestArchitectures, validateRecipe } from './recipe-utils<% if (esm) { %>.js<% } %>';
|
|
5
|
+
import { writeZip, type ZipEntry } from './zip-writer<% if (esm) { %>.js<% } %>';
|
|
6
|
+
|
|
7
|
+
/*
|
|
8
|
+
* Usage: build-artifact.ts <project-root> <component-dir> <dist> [bundle-dir] [--platforms=<arch>,<arch>]
|
|
9
|
+
*
|
|
10
|
+
* <project-root> path to the host project (e.g. a Python project root)
|
|
11
|
+
* <component-dir> the component's directory name under <project-root>/greengrass/,
|
|
12
|
+
* which also becomes the artifact zip's base name
|
|
13
|
+
* <dist> the component's dist root: reads <dist>/vendor (produced by
|
|
14
|
+
* the "-vendor" target this target depends on) and writes
|
|
15
|
+
* <dist>/greengrass-build/{recipes,artifacts}
|
|
16
|
+
* <bundle-dir> optional: a directory of already-bundled deployable code
|
|
17
|
+
* (e.g. a TypeScript rolldown bundle output). When given and
|
|
18
|
+
* it exists, its contents are zipped at the archive root
|
|
19
|
+
* INSTEAD of <project-root>/greengrass/<component-dir>/ and
|
|
20
|
+
* <dist>/vendor - a compiled bundle is the deployable
|
|
21
|
+
* content, so the TypeScript source that produced it must
|
|
22
|
+
* not also ship. <project-root>/greengrass/<component-dir>/package.json,
|
|
23
|
+
* when present, is included too (the minimal manifest an
|
|
24
|
+
* Install lifecycle step's `npm install` needs for a native
|
|
25
|
+
* dependency the bundle marked external).
|
|
26
|
+
* --platforms optional: a comma-separated list of manifest architecture
|
|
27
|
+
* tokens (e.g. "amd64,aarch64"). When given, <dist>/vendor/<arch>
|
|
28
|
+
* is read per architecture and one <component-dir>-<arch>.zip
|
|
29
|
+
* is written per architecture, and every recipe manifest
|
|
30
|
+
* declaring one of these architectures must pair with that
|
|
31
|
+
* architecture's own zip. Cannot be combined with
|
|
32
|
+
* <bundle-dir>. Without it, behaviour is exactly as before:
|
|
33
|
+
* flat <dist>/vendor, one <component-dir>.zip.
|
|
34
|
+
*
|
|
35
|
+
* Without <bundle-dir>, everything under <project-root>/greengrass/<component-dir>/
|
|
36
|
+
* is packaged except recipe.yaml and gdk-config.json, which are framework
|
|
37
|
+
* metadata, not deployed code, and __pycache__ and .lock, which are tool
|
|
38
|
+
* staging output.
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
const log = (msg: string): void => console.error(`[build-artifact] ${msg}`);
|
|
42
|
+
|
|
43
|
+
function usage(): never {
|
|
44
|
+
log(
|
|
45
|
+
'Usage: build-artifact.ts <project-root> <component-dir> <dist> [bundle-dir] [--platforms=<arch>,<arch>]',
|
|
46
|
+
);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Every file under `dir`, recursively, excluding top-level names in `exclude`
|
|
52
|
+
* and `__pycache__` directories at any depth.
|
|
53
|
+
*/
|
|
54
|
+
function collectFiles(dir: string, exclude: ReadonlySet<string>): string[] {
|
|
55
|
+
const results: string[] = [];
|
|
56
|
+
const walk = (current: string, isRoot: boolean): void => {
|
|
57
|
+
for (const entry of readdirSync(current)) {
|
|
58
|
+
if (entry === '__pycache__' || (isRoot && exclude.has(entry))) continue;
|
|
59
|
+
const fullPath = join(current, entry);
|
|
60
|
+
if (statSync(fullPath).isDirectory()) {
|
|
61
|
+
walk(fullPath, false);
|
|
62
|
+
} else {
|
|
63
|
+
results.push(fullPath);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
walk(dir, true);
|
|
68
|
+
return results;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Zip entries for every file under `dir`, named relative to `dir` with forward slashes. */
|
|
72
|
+
function entriesFrom(dir: string, exclude: ReadonlySet<string>): ZipEntry[] {
|
|
73
|
+
return collectFiles(dir, exclude).map((filePath) => ({
|
|
74
|
+
name: relative(dir, filePath).split('\\').join('/'),
|
|
75
|
+
data: readFileSync(filePath),
|
|
76
|
+
}));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function main(): void {
|
|
80
|
+
const argv = process.argv.slice(2);
|
|
81
|
+
const PLATFORMS_FLAG = '--platforms=';
|
|
82
|
+
const platforms = argv
|
|
83
|
+
.filter((a) => a.startsWith(PLATFORMS_FLAG))
|
|
84
|
+
.flatMap((a) => a.slice(PLATFORMS_FLAG.length).split(','))
|
|
85
|
+
.map((a) => a.trim())
|
|
86
|
+
.filter((a) => a.length > 0);
|
|
87
|
+
const [projectRoot, componentDirName, dist, bundleDir] = argv.filter(
|
|
88
|
+
(a) => !a.startsWith(PLATFORMS_FLAG),
|
|
89
|
+
);
|
|
90
|
+
if (!projectRoot || !componentDirName || !dist) {
|
|
91
|
+
usage();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (platforms.length > 0 && bundleDir) {
|
|
95
|
+
log(
|
|
96
|
+
'--platforms cannot be combined with a bundle-dir: per-architecture copies of one bundle would all hold identical bytes. Drop --platforms and serve both architectures from a single artifact with two manifests.',
|
|
97
|
+
);
|
|
98
|
+
process.exit(1);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const componentDir = join(projectRoot, 'greengrass', componentDirName);
|
|
103
|
+
const recipePath = join(componentDir, 'recipe.yaml');
|
|
104
|
+
const baseNameByArchitecture = Object.fromEntries(
|
|
105
|
+
platforms.map((arch) => [arch, `${componentDirName}-${arch}`]),
|
|
106
|
+
);
|
|
107
|
+
const artifactBaseNames =
|
|
108
|
+
platforms.length === 0
|
|
109
|
+
? [componentDirName]
|
|
110
|
+
: platforms.map((arch) => baseNameByArchitecture[arch]);
|
|
111
|
+
|
|
112
|
+
let componentName: string;
|
|
113
|
+
let componentVersion: string;
|
|
114
|
+
let recipe: ReturnType<typeof loadRecipe>;
|
|
115
|
+
try {
|
|
116
|
+
recipe = loadRecipe(recipePath);
|
|
117
|
+
({ componentName, componentVersion } = validateRecipe(
|
|
118
|
+
recipe,
|
|
119
|
+
artifactBaseNames,
|
|
120
|
+
));
|
|
121
|
+
// Only meaningful per architecture, so only checked when this build knows
|
|
122
|
+
// which architecture each zip is for.
|
|
123
|
+
if (platforms.length > 0) {
|
|
124
|
+
validateManifestArchitectures(recipe, baseNameByArchitecture);
|
|
125
|
+
}
|
|
126
|
+
} catch (e) {
|
|
127
|
+
log((e as Error).message);
|
|
128
|
+
process.exit(1);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const vendorDir = join(dist, 'vendor');
|
|
133
|
+
// Recipe and artifact paths are named by version, so a rebuild after a
|
|
134
|
+
// version bump would otherwise accumulate stale siblings - and the
|
|
135
|
+
// GreengrassComponentVersion construct requires exactly one resolved
|
|
136
|
+
// recipe. Start from an empty greengrass-build every run.
|
|
137
|
+
rmSync(join(dist, 'greengrass-build'), { recursive: true, force: true });
|
|
138
|
+
const artifactDir = join(
|
|
139
|
+
dist,
|
|
140
|
+
'greengrass-build',
|
|
141
|
+
'artifacts',
|
|
142
|
+
componentName,
|
|
143
|
+
componentVersion,
|
|
144
|
+
);
|
|
145
|
+
const recipesDir = join(dist, 'greengrass-build', 'recipes');
|
|
146
|
+
mkdirSync(artifactDir, { recursive: true });
|
|
147
|
+
mkdirSync(recipesDir, { recursive: true });
|
|
148
|
+
|
|
149
|
+
if (platforms.length > 0) {
|
|
150
|
+
// Multi-architecture: one zip per architecture, each holding the
|
|
151
|
+
// component's own files plus that architecture's own vendored wheels.
|
|
152
|
+
for (const arch of platforms) {
|
|
153
|
+
const archVendorDir = join(vendorDir, arch);
|
|
154
|
+
if (!existsSync(archVendorDir)) {
|
|
155
|
+
log(
|
|
156
|
+
`Missing vendored dependencies for "${arch}" at "${archVendorDir}" - run the component's "-vendor" target first (it writes one directory per architecture when the component targets more than one).`,
|
|
157
|
+
);
|
|
158
|
+
process.exit(1);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const entries = [
|
|
162
|
+
...entriesFrom(
|
|
163
|
+
componentDir,
|
|
164
|
+
new Set(['recipe.yaml', 'gdk-config.json', '.lock']),
|
|
165
|
+
),
|
|
166
|
+
...entriesFrom(archVendorDir, new Set(['.lock'])),
|
|
167
|
+
];
|
|
168
|
+
if (entries.length === 0) {
|
|
169
|
+
log(
|
|
170
|
+
`Nothing to package for "${arch}": "${componentDir}" has no deployable files and "${archVendorDir}" has no vendored dependencies`,
|
|
171
|
+
);
|
|
172
|
+
process.exit(1);
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
const zipPath = join(artifactDir, `${componentDirName}-${arch}.zip`);
|
|
176
|
+
writeZip(entries, zipPath);
|
|
177
|
+
log(`wrote ${zipPath}`);
|
|
178
|
+
}
|
|
179
|
+
} else {
|
|
180
|
+
let entries: ZipEntry[];
|
|
181
|
+
if (bundleDir && existsSync(bundleDir)) {
|
|
182
|
+
// A pre-bundled language (e.g. TypeScript via rolldown): the bundle
|
|
183
|
+
// output is the deployable content, so the source that produced it is
|
|
184
|
+
// never packaged.
|
|
185
|
+
entries = entriesFrom(bundleDir, new Set(['.lock']));
|
|
186
|
+
const packageJsonPath = join(componentDir, 'package.json');
|
|
187
|
+
if (existsSync(packageJsonPath)) {
|
|
188
|
+
// Ships alongside the bundle only when an Install lifecycle step needs
|
|
189
|
+
// it (e.g. `npm install` for a native dependency the bundle marked
|
|
190
|
+
// external) - absent for a fully self-contained bundle.
|
|
191
|
+
entries.push({
|
|
192
|
+
name: 'package.json',
|
|
193
|
+
data: readFileSync(packageJsonPath),
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
} else {
|
|
197
|
+
// Framework metadata that ships alongside the recipe but never inside
|
|
198
|
+
// the deployed artifact. A package.json here is the user's own, so it is
|
|
199
|
+
// packaged like any other source file - only bundle mode treats one as
|
|
200
|
+
// framework metadata.
|
|
201
|
+
entries = entriesFrom(
|
|
202
|
+
componentDir,
|
|
203
|
+
new Set(['recipe.yaml', 'gdk-config.json', '.lock']),
|
|
204
|
+
);
|
|
205
|
+
if (existsSync(vendorDir)) {
|
|
206
|
+
// requirements.txt is the "-vendor" target's own intermediate, not
|
|
207
|
+
// something the device needs.
|
|
208
|
+
entries.push(
|
|
209
|
+
...entriesFrom(vendorDir, new Set(['requirements.txt', '.lock'])),
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
if (entries.length === 0) {
|
|
214
|
+
log(
|
|
215
|
+
`Nothing to package: "${bundleDir && existsSync(bundleDir) ? bundleDir : componentDir}" has no deployable files and "${vendorDir}" does not exist`,
|
|
216
|
+
);
|
|
217
|
+
process.exit(1);
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const zipPath = join(artifactDir, `${componentDirName}.zip`);
|
|
222
|
+
writeZip(entries, zipPath);
|
|
223
|
+
log(`wrote ${zipPath}`);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// The BUCKET_NAME/COMPONENT_NAME/COMPONENT_VERSION artifact URI placeholders
|
|
227
|
+
// are left exactly as authored - a later IaC step substitutes them.
|
|
228
|
+
const recipeOutPath = join(
|
|
229
|
+
recipesDir,
|
|
230
|
+
`${componentName}-${componentVersion}.yaml`,
|
|
231
|
+
);
|
|
232
|
+
writeFileSync(recipeOutPath, yaml.dump(recipe, { lineWidth: -1 }));
|
|
233
|
+
log(`wrote ${recipeOutPath}`);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
main();
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
* Usage: component-logs.ts <component-name>
|
|
6
|
+
*
|
|
7
|
+
* <component-name> the recipe's ComponentName, e.g. "com.example.MyComponent"
|
|
8
|
+
*
|
|
9
|
+
* Tails <GREENGRASS_ROOT>/logs/<component-name>.log in follow mode. Ctrl-C
|
|
10
|
+
* (SIGINT) stops it - this target never exits on its own.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const log = (msg: string): void => console.error(`[component-logs] ${msg}`);
|
|
14
|
+
|
|
15
|
+
function usage(): never {
|
|
16
|
+
log('Usage: component-logs.ts <component-name>');
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function main(): void {
|
|
21
|
+
const [componentName] = process.argv.slice(2);
|
|
22
|
+
if (!componentName) {
|
|
23
|
+
usage();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const greengrassRoot = process.env.GREENGRASS_ROOT || '/greengrass/v2';
|
|
27
|
+
const logPath = join(greengrassRoot, 'logs', `${componentName}.log`);
|
|
28
|
+
|
|
29
|
+
log(`Tailing ${logPath} - Ctrl-C to stop`);
|
|
30
|
+
const tail = spawn('tail', ['-n', '200', '-f', logPath], {
|
|
31
|
+
stdio: 'inherit',
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const stop = (): void => {
|
|
35
|
+
tail.kill();
|
|
36
|
+
process.exit(0);
|
|
37
|
+
};
|
|
38
|
+
process.on('SIGINT', stop);
|
|
39
|
+
process.on('SIGTERM', stop);
|
|
40
|
+
|
|
41
|
+
tail.on('exit', (code) => process.exit(code ?? 0));
|
|
42
|
+
tail.on('error', (err) => {
|
|
43
|
+
log(`Failed to start tail: ${err.message}`);
|
|
44
|
+
process.exit(1);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
main();
|