container-superposition 0.1.1
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 +843 -0
- package/dist/scripts/init.d.ts +3 -0
- package/dist/scripts/init.d.ts.map +1 -0
- package/dist/scripts/init.js +1190 -0
- package/dist/scripts/init.js.map +1 -0
- package/dist/scripts/migrate-to-manifests.d.ts +12 -0
- package/dist/scripts/migrate-to-manifests.d.ts.map +1 -0
- package/dist/scripts/migrate-to-manifests.js +230 -0
- package/dist/scripts/migrate-to-manifests.js.map +1 -0
- package/dist/tool/questionnaire/composer.d.ts +6 -0
- package/dist/tool/questionnaire/composer.d.ts.map +1 -0
- package/dist/tool/questionnaire/composer.js +1232 -0
- package/dist/tool/questionnaire/composer.js.map +1 -0
- package/dist/tool/readme/markdown-parser.d.ts +30 -0
- package/dist/tool/readme/markdown-parser.d.ts.map +1 -0
- package/dist/tool/readme/markdown-parser.js +139 -0
- package/dist/tool/readme/markdown-parser.js.map +1 -0
- package/dist/tool/readme/readme-generator.d.ts +9 -0
- package/dist/tool/readme/readme-generator.d.ts.map +1 -0
- package/dist/tool/readme/readme-generator.js +422 -0
- package/dist/tool/readme/readme-generator.js.map +1 -0
- package/dist/tool/schema/custom-loader.d.ts +17 -0
- package/dist/tool/schema/custom-loader.d.ts.map +1 -0
- package/dist/tool/schema/custom-loader.js +149 -0
- package/dist/tool/schema/custom-loader.js.map +1 -0
- package/dist/tool/schema/overlay-loader.d.ts +47 -0
- package/dist/tool/schema/overlay-loader.d.ts.map +1 -0
- package/dist/tool/schema/overlay-loader.js +252 -0
- package/dist/tool/schema/overlay-loader.js.map +1 -0
- package/dist/tool/schema/types.d.ts +212 -0
- package/dist/tool/schema/types.d.ts.map +1 -0
- package/dist/tool/schema/types.js +5 -0
- package/dist/tool/schema/types.js.map +1 -0
- package/docs/README.md +308 -0
- package/docs/architecture.md +233 -0
- package/docs/creating-overlays.md +549 -0
- package/docs/custom-patches.md +540 -0
- package/docs/dependencies.md +279 -0
- package/docs/examples/custom-patches-example.md +85 -0
- package/docs/examples.md +576 -0
- package/docs/messaging-comparison.md +265 -0
- package/docs/messaging-quick-start.md +385 -0
- package/docs/observability-workflow.md +537 -0
- package/docs/overlay-manifest-refactoring.md +214 -0
- package/docs/overlay-metadata-archive.md +54 -0
- package/docs/overlays.md +523 -0
- package/docs/presets-architecture.md +498 -0
- package/docs/presets.md +366 -0
- package/docs/publishing.md +476 -0
- package/docs/quick-reference.md +326 -0
- package/docs/ux.md +170 -0
- package/features/README.md +85 -0
- package/features/cross-distro-packages/README.md +146 -0
- package/features/cross-distro-packages/devcontainer-feature.json +20 -0
- package/features/cross-distro-packages/install.sh +58 -0
- package/features/local-secrets-manager/devcontainer-feature.json +18 -0
- package/features/local-secrets-manager/install.sh +127 -0
- package/features/project-scaffolder/devcontainer-feature.json +24 -0
- package/features/project-scaffolder/install.sh +100 -0
- package/features/team-conventions/devcontainer-feature.json +24 -0
- package/features/team-conventions/install.sh +93 -0
- package/overlays/.registry/README.md +14 -0
- package/overlays/.registry/base-images.yml +26 -0
- package/overlays/.registry/base-templates.yml +7 -0
- package/overlays/README.md +155 -0
- package/overlays/alertmanager/.env.example +5 -0
- package/overlays/alertmanager/README.md +465 -0
- package/overlays/alertmanager/alert-rules.yml +56 -0
- package/overlays/alertmanager/alertmanager.yml +42 -0
- package/overlays/alertmanager/devcontainer.patch.json +12 -0
- package/overlays/alertmanager/docker-compose.yml +20 -0
- package/overlays/alertmanager/overlay.yml +17 -0
- package/overlays/alertmanager/setup.sh +53 -0
- package/overlays/alertmanager/verify.sh +31 -0
- package/overlays/aws-cli/README.md +473 -0
- package/overlays/aws-cli/devcontainer.patch.json +13 -0
- package/overlays/aws-cli/overlay.yml +13 -0
- package/overlays/azure-cli/README.md +551 -0
- package/overlays/azure-cli/devcontainer.patch.json +8 -0
- package/overlays/azure-cli/overlay.yml +13 -0
- package/overlays/bun/README.md +312 -0
- package/overlays/bun/devcontainer.patch.json +41 -0
- package/overlays/bun/overlay.yml +16 -0
- package/overlays/bun/setup.sh +79 -0
- package/overlays/bun/verify.sh +30 -0
- package/overlays/codex/README.md +128 -0
- package/overlays/codex/devcontainer.patch.json +3 -0
- package/overlays/codex/overlay.yml +14 -0
- package/overlays/codex/setup.sh +24 -0
- package/overlays/codex/verify.sh +30 -0
- package/overlays/commitlint/README.md +333 -0
- package/overlays/commitlint/devcontainer.patch.json +8 -0
- package/overlays/commitlint/overlay.yml +16 -0
- package/overlays/commitlint/setup.sh +234 -0
- package/overlays/direnv/README.md +504 -0
- package/overlays/direnv/devcontainer.patch.json +6 -0
- package/overlays/direnv/overlay.yml +13 -0
- package/overlays/direnv/setup.sh +139 -0
- package/overlays/docker-in-docker/README.md +534 -0
- package/overlays/docker-in-docker/devcontainer.patch.json +10 -0
- package/overlays/docker-in-docker/overlay.yml +13 -0
- package/overlays/docker-sock/README.md +256 -0
- package/overlays/docker-sock/devcontainer.patch.json +9 -0
- package/overlays/docker-sock/docker-compose.yml +8 -0
- package/overlays/docker-sock/overlay.yml +13 -0
- package/overlays/dotnet/README.md +147 -0
- package/overlays/dotnet/devcontainer.patch.json +51 -0
- package/overlays/dotnet/global-tools.txt +24 -0
- package/overlays/dotnet/overlay.yml +13 -0
- package/overlays/dotnet/setup.sh +51 -0
- package/overlays/dotnet/verify.sh +26 -0
- package/overlays/gcloud/README.md +269 -0
- package/overlays/gcloud/devcontainer.patch.json +14 -0
- package/overlays/gcloud/overlay.yml +14 -0
- package/overlays/gcloud/verify.sh +52 -0
- package/overlays/git-helpers/README.md +168 -0
- package/overlays/git-helpers/devcontainer.patch.json +33 -0
- package/overlays/git-helpers/overlay.yml +15 -0
- package/overlays/git-helpers/setup.sh +91 -0
- package/overlays/go/README.md +293 -0
- package/overlays/go/devcontainer.patch.json +43 -0
- package/overlays/go/overlay.yml +15 -0
- package/overlays/go/setup.sh +33 -0
- package/overlays/go/verify.sh +40 -0
- package/overlays/grafana/.env.example +9 -0
- package/overlays/grafana/README.md +462 -0
- package/overlays/grafana/dashboard-provider.yml +11 -0
- package/overlays/grafana/dashboards/observability-overview.json +263 -0
- package/overlays/grafana/devcontainer.patch.json +12 -0
- package/overlays/grafana/docker-compose.yml +27 -0
- package/overlays/grafana/grafana-datasources.yml +57 -0
- package/overlays/grafana/overlay.yml +21 -0
- package/overlays/grafana/verify.sh +34 -0
- package/overlays/jaeger/.env.example +7 -0
- package/overlays/jaeger/README.md +867 -0
- package/overlays/jaeger/devcontainer.patch.json +12 -0
- package/overlays/jaeger/docker-compose.yml +17 -0
- package/overlays/jaeger/overlay.yml +19 -0
- package/overlays/java/README.md +267 -0
- package/overlays/java/devcontainer.patch.json +44 -0
- package/overlays/java/overlay.yml +16 -0
- package/overlays/java/setup.sh +41 -0
- package/overlays/java/verify.sh +42 -0
- package/overlays/just/README.md +443 -0
- package/overlays/just/devcontainer.patch.json +3 -0
- package/overlays/just/overlay.yml +13 -0
- package/overlays/just/setup.sh +182 -0
- package/overlays/kubectl-helm/README.md +660 -0
- package/overlays/kubectl-helm/devcontainer.patch.json +10 -0
- package/overlays/kubectl-helm/overlay.yml +13 -0
- package/overlays/loki/.env.example +5 -0
- package/overlays/loki/README.md +1156 -0
- package/overlays/loki/devcontainer.patch.json +12 -0
- package/overlays/loki/docker-compose.yml +18 -0
- package/overlays/loki/loki-config.yaml +45 -0
- package/overlays/loki/overlay.yml +17 -0
- package/overlays/minio/.env.example +9 -0
- package/overlays/minio/README.md +639 -0
- package/overlays/minio/devcontainer.patch.json +30 -0
- package/overlays/minio/docker-compose.yml +28 -0
- package/overlays/minio/overlay.yml +18 -0
- package/overlays/minio/setup.sh +61 -0
- package/overlays/minio/verify.sh +64 -0
- package/overlays/mkdocs/README.md +309 -0
- package/overlays/mkdocs/devcontainer.patch.json +24 -0
- package/overlays/mkdocs/overlay.yml +15 -0
- package/overlays/modern-cli-tools/README.md +556 -0
- package/overlays/modern-cli-tools/devcontainer.patch.json +3 -0
- package/overlays/modern-cli-tools/overlay.yml +13 -0
- package/overlays/modern-cli-tools/setup.sh +153 -0
- package/overlays/mongodb/.env.example +9 -0
- package/overlays/mongodb/README.md +481 -0
- package/overlays/mongodb/devcontainer.patch.json +32 -0
- package/overlays/mongodb/docker-compose.yml +44 -0
- package/overlays/mongodb/overlay.yml +17 -0
- package/overlays/mongodb/verify.sh +48 -0
- package/overlays/mysql/.env.example +11 -0
- package/overlays/mysql/README.md +542 -0
- package/overlays/mysql/devcontainer.patch.json +34 -0
- package/overlays/mysql/docker-compose.yml +55 -0
- package/overlays/mysql/overlay.yml +16 -0
- package/overlays/mysql/verify.sh +48 -0
- package/overlays/nats/.env.example +5 -0
- package/overlays/nats/README.md +762 -0
- package/overlays/nats/devcontainer.patch.json +24 -0
- package/overlays/nats/docker-compose.yml +31 -0
- package/overlays/nats/overlay.yml +18 -0
- package/overlays/nats/verify.sh +50 -0
- package/overlays/ngrok/README.md +503 -0
- package/overlays/ngrok/devcontainer.patch.json +3 -0
- package/overlays/ngrok/overlay.yml +14 -0
- package/overlays/ngrok/setup.sh +125 -0
- package/overlays/nodejs/README.md +192 -0
- package/overlays/nodejs/devcontainer.patch.json +49 -0
- package/overlays/nodejs/global-packages.txt +16 -0
- package/overlays/nodejs/overlay.yml +14 -0
- package/overlays/nodejs/setup.sh +46 -0
- package/overlays/nodejs/verify.sh +32 -0
- package/overlays/otel-collector/.env.example +9 -0
- package/overlays/otel-collector/README.md +1257 -0
- package/overlays/otel-collector/devcontainer.patch.json +28 -0
- package/overlays/otel-collector/docker-compose.yml +22 -0
- package/overlays/otel-collector/otel-collector-config.yaml +68 -0
- package/overlays/otel-collector/overlay.yml +21 -0
- package/overlays/otel-collector/setup.sh +49 -0
- package/overlays/otel-demo-nodejs/.env.example +2 -0
- package/overlays/otel-demo-nodejs/Dockerfile-otel-demo-nodejs +17 -0
- package/overlays/otel-demo-nodejs/README.md +409 -0
- package/overlays/otel-demo-nodejs/devcontainer.patch.json +12 -0
- package/overlays/otel-demo-nodejs/docker-compose.yml +19 -0
- package/overlays/otel-demo-nodejs/overlay.yml +23 -0
- package/overlays/otel-demo-nodejs/package-otel-demo-nodejs.json +20 -0
- package/overlays/otel-demo-nodejs/server-otel-demo-nodejs.js +259 -0
- package/overlays/otel-demo-nodejs/tracing-otel-demo-nodejs.js +57 -0
- package/overlays/otel-demo-nodejs/verify.sh +31 -0
- package/overlays/otel-demo-python/.env.example +2 -0
- package/overlays/otel-demo-python/Dockerfile-otel-demo-python +16 -0
- package/overlays/otel-demo-python/README.md +82 -0
- package/overlays/otel-demo-python/app-otel-demo-python.py +208 -0
- package/overlays/otel-demo-python/devcontainer.patch.json +12 -0
- package/overlays/otel-demo-python/docker-compose.yml +19 -0
- package/overlays/otel-demo-python/overlay.yml +23 -0
- package/overlays/otel-demo-python/requirements-otel-demo-python.txt +4 -0
- package/overlays/otel-demo-python/verify.sh +31 -0
- package/overlays/playwright/README.md +629 -0
- package/overlays/playwright/devcontainer.patch.json +9 -0
- package/overlays/playwright/overlay.yml +13 -0
- package/overlays/postgres/.env.example +6 -0
- package/overlays/postgres/README.md +602 -0
- package/overlays/postgres/devcontainer.patch.json +21 -0
- package/overlays/postgres/docker-compose.yml +22 -0
- package/overlays/postgres/overlay.yml +15 -0
- package/overlays/postgres/verify.sh +45 -0
- package/overlays/powershell/README.md +314 -0
- package/overlays/powershell/devcontainer.patch.json +22 -0
- package/overlays/powershell/overlay.yml +13 -0
- package/overlays/powershell/setup.sh +29 -0
- package/overlays/powershell/verify.sh +38 -0
- package/overlays/pre-commit/README.md +263 -0
- package/overlays/pre-commit/devcontainer.patch.json +9 -0
- package/overlays/pre-commit/overlay.yml +16 -0
- package/overlays/pre-commit/setup.sh +129 -0
- package/overlays/presets/docs-site.yml +118 -0
- package/overlays/presets/fullstack.yml +181 -0
- package/overlays/presets/microservice.yml +118 -0
- package/overlays/presets/web-api.yml +109 -0
- package/overlays/prometheus/.env.example +5 -0
- package/overlays/prometheus/README.md +1246 -0
- package/overlays/prometheus/devcontainer.patch.json +12 -0
- package/overlays/prometheus/docker-compose.yml +22 -0
- package/overlays/prometheus/overlay.yml +17 -0
- package/overlays/prometheus/prometheus.yml +12 -0
- package/overlays/prometheus/verify.sh +34 -0
- package/overlays/promtail/.env.example +2 -0
- package/overlays/promtail/README.md +357 -0
- package/overlays/promtail/devcontainer.patch.json +5 -0
- package/overlays/promtail/docker-compose.yml +16 -0
- package/overlays/promtail/overlay.yml +17 -0
- package/overlays/promtail/promtail-config.yaml +60 -0
- package/overlays/promtail/verify.sh +31 -0
- package/overlays/pulumi/README.md +472 -0
- package/overlays/pulumi/devcontainer.patch.json +13 -0
- package/overlays/pulumi/overlay.yml +14 -0
- package/overlays/pulumi/verify.sh +31 -0
- package/overlays/python/README.md +919 -0
- package/overlays/python/devcontainer.patch.json +41 -0
- package/overlays/python/overlay.yml +12 -0
- package/overlays/python/requirements-overlay.txt +13 -0
- package/overlays/python/setup.sh +47 -0
- package/overlays/python/verify.sh +32 -0
- package/overlays/rabbitmq/.env.example +7 -0
- package/overlays/rabbitmq/README.md +680 -0
- package/overlays/rabbitmq/devcontainer.patch.json +28 -0
- package/overlays/rabbitmq/docker-compose.yml +30 -0
- package/overlays/rabbitmq/overlay.yml +18 -0
- package/overlays/rabbitmq/verify.sh +41 -0
- package/overlays/redis/.env.example +4 -0
- package/overlays/redis/README.md +776 -0
- package/overlays/redis/devcontainer.patch.json +21 -0
- package/overlays/redis/docker-compose.yml +21 -0
- package/overlays/redis/overlay.yml +15 -0
- package/overlays/redis/verify.sh +41 -0
- package/overlays/redpanda/.env.example +10 -0
- package/overlays/redpanda/README.md +703 -0
- package/overlays/redpanda/devcontainer.patch.json +37 -0
- package/overlays/redpanda/docker-compose.yml +67 -0
- package/overlays/redpanda/overlay.yml +21 -0
- package/overlays/redpanda/verify.sh +48 -0
- package/overlays/rust/README.md +299 -0
- package/overlays/rust/devcontainer.patch.json +39 -0
- package/overlays/rust/overlay.yml +15 -0
- package/overlays/rust/setup.sh +36 -0
- package/overlays/rust/verify.sh +51 -0
- package/overlays/sqlite/README.md +584 -0
- package/overlays/sqlite/devcontainer.patch.json +14 -0
- package/overlays/sqlite/overlay.yml +15 -0
- package/overlays/sqlite/setup.sh +27 -0
- package/overlays/sqlite/verify.sh +43 -0
- package/overlays/sqlserver/.env.example +6 -0
- package/overlays/sqlserver/README.md +592 -0
- package/overlays/sqlserver/devcontainer.patch.json +22 -0
- package/overlays/sqlserver/docker-compose.yml +32 -0
- package/overlays/sqlserver/overlay.yml +17 -0
- package/overlays/sqlserver/verify.sh +30 -0
- package/overlays/tempo/.env.example +5 -0
- package/overlays/tempo/README.md +273 -0
- package/overlays/tempo/devcontainer.patch.json +12 -0
- package/overlays/tempo/docker-compose.yml +20 -0
- package/overlays/tempo/overlay.yml +20 -0
- package/overlays/tempo/tempo-config.yaml +32 -0
- package/overlays/tempo/verify.sh +31 -0
- package/overlays/terraform/README.md +389 -0
- package/overlays/terraform/devcontainer.patch.json +15 -0
- package/overlays/terraform/overlay.yml +14 -0
- package/overlays/terraform/verify.sh +63 -0
- package/package.json +74 -0
- package/templates/README.md +285 -0
- package/templates/compose/.devcontainer/devcontainer.json +46 -0
- package/templates/compose/.devcontainer/docker-compose.yml +12 -0
- package/templates/compose/README.md +20 -0
- package/templates/plain/.devcontainer/devcontainer.json +35 -0
- package/templates/plain/README.md +21 -0
- package/tool/README.md +281 -0
- package/tool/schema/base-images.schema.json +43 -0
- package/tool/schema/base-templates.schema.json +34 -0
- package/tool/schema/config.schema.json +71 -0
- package/tool/schema/overlay-manifest.schema.json +86 -0
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* README generation for consolidated devcontainer documentation
|
|
3
|
+
*/
|
|
4
|
+
import * as fs from 'fs';
|
|
5
|
+
import * as path from 'path';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
7
|
+
import { parseMarkdown, findSection, getFirstParagraph, } from './markdown-parser.js';
|
|
8
|
+
// Get __dirname equivalent in ESM
|
|
9
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
+
const __dirname = path.dirname(__filename);
|
|
11
|
+
// Resolve REPO_ROOT that works in both source and compiled output
|
|
12
|
+
const REPO_ROOT_CANDIDATES = [
|
|
13
|
+
path.join(__dirname, '..', '..'), // From source: tool/readme -> root
|
|
14
|
+
path.join(__dirname, '..', '..', '..'), // From dist: dist/tool/readme -> root
|
|
15
|
+
];
|
|
16
|
+
const REPO_ROOT = REPO_ROOT_CANDIDATES.find((candidate) => fs.existsSync(path.join(candidate, 'templates')) &&
|
|
17
|
+
fs.existsSync(path.join(candidate, 'overlays'))) ?? REPO_ROOT_CANDIDATES[0];
|
|
18
|
+
const OVERLAYS_DIR = path.join(REPO_ROOT, 'overlays');
|
|
19
|
+
/**
|
|
20
|
+
* Sections to extract from overlay READMEs
|
|
21
|
+
* These are matched against H2 (##) level headings
|
|
22
|
+
*/
|
|
23
|
+
const SECTIONS_TO_EXTRACT = [
|
|
24
|
+
/^connection\s+information$/i,
|
|
25
|
+
/^common\s+commands$/i,
|
|
26
|
+
/^configuration$/i,
|
|
27
|
+
/^troubleshooting$/i,
|
|
28
|
+
/^use\s+cases$/i,
|
|
29
|
+
];
|
|
30
|
+
/**
|
|
31
|
+
* Extract key information from a section in a concise, readable format
|
|
32
|
+
* Focus on the most important details users need to get started
|
|
33
|
+
*/
|
|
34
|
+
function extractSectionSummary(section) {
|
|
35
|
+
const parts = [];
|
|
36
|
+
// Combine content from section and subsections
|
|
37
|
+
const allContent = [section.content, ...section.subsections.map(s => s.content)].join('\n');
|
|
38
|
+
// For connection information, extract just the essentials
|
|
39
|
+
if (section.title.toLowerCase().includes('connection')) {
|
|
40
|
+
const connectionDetails = [];
|
|
41
|
+
const lines = allContent.split('\n');
|
|
42
|
+
for (const line of lines) {
|
|
43
|
+
const trimmed = line.trim();
|
|
44
|
+
// Match connection details (handle both plain text and comments)
|
|
45
|
+
if (trimmed.match(/^(#\s*)?(Hostname|Host|Port|Database|DB|User|Username|Password|URL|Connection):/i)) {
|
|
46
|
+
const cleaned = trimmed.replace(/^#\s*/, '').replace('Connection string', 'Connection URL');
|
|
47
|
+
connectionDetails.push(`- ${cleaned}`);
|
|
48
|
+
}
|
|
49
|
+
// Also match connection URLs
|
|
50
|
+
else if (trimmed.match(/^(#\s*)?[a-z]+:\/\//)) {
|
|
51
|
+
const cleaned = trimmed.replace(/^#\s*/, '');
|
|
52
|
+
if (cleaned.length < 100) { // Only include short URLs
|
|
53
|
+
connectionDetails.push(`- Connection URL: \`${cleaned}\``);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (connectionDetails.length > 0) {
|
|
58
|
+
// Take first 6 most important details
|
|
59
|
+
parts.push(...connectionDetails.slice(0, 6));
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
parts.push('See full documentation for connection details');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// For commands, list just the main categories
|
|
66
|
+
else if (section.title.toLowerCase().includes('command')) {
|
|
67
|
+
if (section.subsections.length > 0) {
|
|
68
|
+
parts.push('Key command categories:');
|
|
69
|
+
parts.push('');
|
|
70
|
+
const categories = section.subsections.slice(0, 4).map(s => `- ${s.title}`);
|
|
71
|
+
parts.push(...categories);
|
|
72
|
+
if (section.subsections.length > 4) {
|
|
73
|
+
parts.push(`- ...and ${section.subsections.length - 4} more`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
parts.push('See full documentation for available commands');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// For configuration, just mention it exists
|
|
81
|
+
else if (section.title.toLowerCase().includes('config')) {
|
|
82
|
+
parts.push('Configurable via environment variables and configuration files.');
|
|
83
|
+
if (section.subsections.length > 0) {
|
|
84
|
+
parts.push('');
|
|
85
|
+
parts.push('Available settings:');
|
|
86
|
+
section.subsections.slice(0, 3).forEach(s => {
|
|
87
|
+
parts.push(`- ${s.title}`);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// For use cases, list them
|
|
92
|
+
else if (section.title.toLowerCase().includes('use case')) {
|
|
93
|
+
const useCases = [];
|
|
94
|
+
for (const subsection of section.subsections.slice(0, 4)) {
|
|
95
|
+
if (subsection.title) {
|
|
96
|
+
useCases.push(`- **${subsection.title}**`);
|
|
97
|
+
// Add brief description from subsection content if available
|
|
98
|
+
if (subsection.content) {
|
|
99
|
+
const firstLine = subsection.content.split('\n').find(l => l.trim() && !l.trim().startsWith('-'));
|
|
100
|
+
if (firstLine && firstLine.length < 80) {
|
|
101
|
+
useCases.push(` ${firstLine.trim()}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (useCases.length > 0) {
|
|
107
|
+
parts.push(...useCases);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// For troubleshooting, list common issues
|
|
111
|
+
else if (section.title.toLowerCase().includes('troubleshoot')) {
|
|
112
|
+
const issues = [];
|
|
113
|
+
for (const subsection of section.subsections.slice(0, 3)) {
|
|
114
|
+
if (subsection.title) {
|
|
115
|
+
issues.push(`- **${subsection.title}**`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (issues.length > 0) {
|
|
119
|
+
parts.push('Common issues:');
|
|
120
|
+
parts.push(...issues);
|
|
121
|
+
if (section.subsections.length > 3) {
|
|
122
|
+
parts.push(`- ...and ${section.subsections.length - 3} more (see full docs)`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// Default: just show first paragraph
|
|
127
|
+
else {
|
|
128
|
+
if (section.content && section.content.trim()) {
|
|
129
|
+
const firstPara = getFirstParagraph(section.content);
|
|
130
|
+
if (firstPara) {
|
|
131
|
+
parts.push(firstPara);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return parts.join('\n');
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Load and parse overlay README file
|
|
139
|
+
*/
|
|
140
|
+
function loadOverlayDocs(overlayId, metadata) {
|
|
141
|
+
const readmePath = path.join(OVERLAYS_DIR, overlayId, 'README.md');
|
|
142
|
+
if (!fs.existsSync(readmePath)) {
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
const content = fs.readFileSync(readmePath, 'utf-8');
|
|
146
|
+
const sections = parseMarkdown(content);
|
|
147
|
+
// Extract relevant sections with summaries
|
|
148
|
+
const extractedSections = new Map();
|
|
149
|
+
for (const pattern of SECTIONS_TO_EXTRACT) {
|
|
150
|
+
const section = findSection(sections, pattern);
|
|
151
|
+
if (section) {
|
|
152
|
+
// Use summary extraction to keep README concise
|
|
153
|
+
extractedSections.set(section.title, extractSectionSummary(section));
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
// Get description from metadata or first paragraph
|
|
157
|
+
let description = metadata.description || '';
|
|
158
|
+
if (!description && sections.length > 0) {
|
|
159
|
+
description = getFirstParagraph(sections[0].content);
|
|
160
|
+
}
|
|
161
|
+
return {
|
|
162
|
+
id: overlayId,
|
|
163
|
+
name: metadata.name || overlayId,
|
|
164
|
+
description,
|
|
165
|
+
sections: extractedSections,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Generate header section of README
|
|
170
|
+
*/
|
|
171
|
+
function generateHeader(answers) {
|
|
172
|
+
const parts = [];
|
|
173
|
+
const title = answers.containerName || 'Development Environment';
|
|
174
|
+
parts.push(`# ${title}`);
|
|
175
|
+
parts.push('');
|
|
176
|
+
parts.push(`> Generated by Container Superposition on ${new Date().toISOString().split('T')[0]}`);
|
|
177
|
+
let metadata = `> Template: ${answers.stack}`;
|
|
178
|
+
if (answers.baseImage && answers.baseImage !== 'bookworm') {
|
|
179
|
+
// When a custom base image is selected, surface the actual image value instead of "custom"
|
|
180
|
+
if (answers.baseImage === 'custom' && answers.customImage) {
|
|
181
|
+
metadata += ` | Base Image: ${answers.customImage}`;
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
metadata += ` | Base Image: ${answers.baseImage}`;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
if (answers.preset) {
|
|
188
|
+
metadata += ` | Preset: ${answers.preset}`;
|
|
189
|
+
}
|
|
190
|
+
parts.push(metadata);
|
|
191
|
+
parts.push('');
|
|
192
|
+
return parts.join('\n');
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Generate quick start section
|
|
196
|
+
*/
|
|
197
|
+
function generateQuickStart(answers) {
|
|
198
|
+
const parts = [];
|
|
199
|
+
parts.push('## Quick Start');
|
|
200
|
+
parts.push('');
|
|
201
|
+
if (answers.stack === 'compose') {
|
|
202
|
+
parts.push('This development environment uses Docker Compose to orchestrate multiple services.');
|
|
203
|
+
parts.push('');
|
|
204
|
+
parts.push('**Starting the environment:**');
|
|
205
|
+
parts.push('');
|
|
206
|
+
parts.push('1. Open this folder in VS Code');
|
|
207
|
+
parts.push('2. When prompted, click "Reopen in Container"');
|
|
208
|
+
parts.push('3. Wait for the container to build and services to start');
|
|
209
|
+
parts.push('4. Your development environment is ready!');
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
parts.push('This development environment uses a single container image.');
|
|
213
|
+
parts.push('');
|
|
214
|
+
parts.push('**Starting the environment:**');
|
|
215
|
+
parts.push('');
|
|
216
|
+
parts.push('1. Open this folder in VS Code');
|
|
217
|
+
parts.push('2. When prompted, click "Reopen in Container"');
|
|
218
|
+
parts.push('3. Wait for the container to build');
|
|
219
|
+
parts.push('4. Your development environment is ready!');
|
|
220
|
+
}
|
|
221
|
+
parts.push('');
|
|
222
|
+
return parts.join('\n');
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Compute relative path from output directory to repo root for documentation links.
|
|
226
|
+
* If output is outside the repo, falls back to assuming standard .devcontainer location.
|
|
227
|
+
*/
|
|
228
|
+
function getRelativePathToRepo(outputPath) {
|
|
229
|
+
const normalizedOutput = path.normalize(outputPath);
|
|
230
|
+
const normalizedRepo = path.normalize(REPO_ROOT);
|
|
231
|
+
// Check if output path is inside the repository
|
|
232
|
+
if (normalizedOutput.startsWith(normalizedRepo)) {
|
|
233
|
+
// Compute proper relative path
|
|
234
|
+
return path.posix.relative(path.posix.normalize(outputPath.replace(/\\/g, '/')), path.posix.normalize(REPO_ROOT.replace(/\\/g, '/')));
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
// Output is outside repo - assume standard .devcontainer location for links
|
|
238
|
+
// This is a reasonable fallback since overlays won't be accessible anyway
|
|
239
|
+
return '..';
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Generate services section with extracted overlay documentation
|
|
244
|
+
*/
|
|
245
|
+
function generateServices(overlayDocs, overlayMetadata, outputPath) {
|
|
246
|
+
if (overlayDocs.length === 0) {
|
|
247
|
+
return '';
|
|
248
|
+
}
|
|
249
|
+
// Compute relative path from output directory to repo root
|
|
250
|
+
const relativeToRepo = getRelativePathToRepo(outputPath);
|
|
251
|
+
const parts = [];
|
|
252
|
+
parts.push('## Services and Tools');
|
|
253
|
+
parts.push('');
|
|
254
|
+
// Group overlays by category
|
|
255
|
+
const categories = {};
|
|
256
|
+
for (const docs of overlayDocs) {
|
|
257
|
+
const metadata = overlayMetadata.get(docs.id);
|
|
258
|
+
const category = metadata?.category || 'other';
|
|
259
|
+
if (!categories[category]) {
|
|
260
|
+
categories[category] = [];
|
|
261
|
+
}
|
|
262
|
+
categories[category].push(docs);
|
|
263
|
+
}
|
|
264
|
+
// Define category order
|
|
265
|
+
const categoryOrder = ['language', 'database', 'observability', 'cloud', 'dev', 'other'];
|
|
266
|
+
const categoryTitles = {
|
|
267
|
+
language: 'Languages and Frameworks',
|
|
268
|
+
database: 'Databases and Storage',
|
|
269
|
+
observability: 'Observability and Monitoring',
|
|
270
|
+
cloud: 'Cloud and Infrastructure Tools',
|
|
271
|
+
dev: 'Development Tools',
|
|
272
|
+
other: 'Other Services',
|
|
273
|
+
};
|
|
274
|
+
for (const category of categoryOrder) {
|
|
275
|
+
const categoryDocs = categories[category];
|
|
276
|
+
if (!categoryDocs || categoryDocs.length === 0) {
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
// Only show category header if there are multiple categories
|
|
280
|
+
if (Object.keys(categories).length > 1) {
|
|
281
|
+
parts.push(`### ${categoryTitles[category] || category}`);
|
|
282
|
+
parts.push('');
|
|
283
|
+
}
|
|
284
|
+
for (const docs of categoryDocs) {
|
|
285
|
+
// Service name and description
|
|
286
|
+
parts.push(`#### ${docs.name}`);
|
|
287
|
+
parts.push('');
|
|
288
|
+
if (docs.description) {
|
|
289
|
+
parts.push(docs.description);
|
|
290
|
+
parts.push('');
|
|
291
|
+
}
|
|
292
|
+
// Extract and include relevant sections (excluding Troubleshooting to avoid duplication)
|
|
293
|
+
for (const [sectionTitle, sectionContent] of docs.sections) {
|
|
294
|
+
// Skip Troubleshooting section here since it's aggregated later
|
|
295
|
+
if (sectionTitle.toLowerCase().includes('troubleshoot')) {
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
parts.push(`**${sectionTitle}**`);
|
|
299
|
+
parts.push('');
|
|
300
|
+
parts.push(sectionContent);
|
|
301
|
+
parts.push('');
|
|
302
|
+
}
|
|
303
|
+
// Add link to full README using computed relative path
|
|
304
|
+
const overlayReadmePath = path.posix.join(relativeToRepo, 'overlays', docs.id, 'README.md');
|
|
305
|
+
parts.push(`*For complete documentation, see [${docs.name} overlay](${overlayReadmePath})*`);
|
|
306
|
+
parts.push('');
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
return parts.join('\n');
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Generate environment variables section (if .env.example exists)
|
|
313
|
+
*/
|
|
314
|
+
function generateEnvironmentVariables(outputPath) {
|
|
315
|
+
const envExamplePath = path.join(outputPath, '.env.example');
|
|
316
|
+
if (!fs.existsSync(envExamplePath)) {
|
|
317
|
+
return '';
|
|
318
|
+
}
|
|
319
|
+
const parts = [];
|
|
320
|
+
parts.push('## Environment Variables');
|
|
321
|
+
parts.push('');
|
|
322
|
+
parts.push('This project uses environment variables for configuration. A template is provided:');
|
|
323
|
+
parts.push('');
|
|
324
|
+
parts.push('```bash');
|
|
325
|
+
parts.push('cp .env.example .env');
|
|
326
|
+
parts.push('```');
|
|
327
|
+
parts.push('');
|
|
328
|
+
parts.push('Then edit `.env` to customize for your environment.');
|
|
329
|
+
parts.push('');
|
|
330
|
+
parts.push('**Important:** The `.env` file is git-ignored and should not be committed.');
|
|
331
|
+
parts.push('');
|
|
332
|
+
return parts.join('\n');
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Generate troubleshooting section (aggregated from overlays)
|
|
336
|
+
*/
|
|
337
|
+
function generateTroubleshooting(overlayDocs) {
|
|
338
|
+
const troubleshootingDocs = overlayDocs
|
|
339
|
+
.filter((docs) => docs.sections.has('Troubleshooting'))
|
|
340
|
+
.map((docs) => ({ name: docs.name, content: docs.sections.get('Troubleshooting') }));
|
|
341
|
+
if (troubleshootingDocs.length === 0) {
|
|
342
|
+
return '';
|
|
343
|
+
}
|
|
344
|
+
const parts = [];
|
|
345
|
+
parts.push('## Troubleshooting');
|
|
346
|
+
parts.push('');
|
|
347
|
+
for (const { name, content } of troubleshootingDocs) {
|
|
348
|
+
parts.push(`### ${name}`);
|
|
349
|
+
parts.push('');
|
|
350
|
+
parts.push(content);
|
|
351
|
+
parts.push('');
|
|
352
|
+
}
|
|
353
|
+
return parts.join('\n');
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Generate references section
|
|
357
|
+
*/
|
|
358
|
+
function generateReferences(overlayIds, outputPath) {
|
|
359
|
+
// Compute relative path from output directory to repo root
|
|
360
|
+
const relativeToRepo = getRelativePathToRepo(outputPath);
|
|
361
|
+
const parts = [];
|
|
362
|
+
parts.push('## References');
|
|
363
|
+
parts.push('');
|
|
364
|
+
parts.push('**Overlay Documentation:**');
|
|
365
|
+
parts.push('');
|
|
366
|
+
for (const overlayId of overlayIds) {
|
|
367
|
+
const overlayReadmePath = path.posix.join(relativeToRepo, 'overlays', overlayId, 'README.md');
|
|
368
|
+
parts.push(`- [${overlayId}](${overlayReadmePath})`);
|
|
369
|
+
}
|
|
370
|
+
parts.push('');
|
|
371
|
+
parts.push('**Project Documentation:**');
|
|
372
|
+
parts.push('');
|
|
373
|
+
const mainReadmePath = path.posix.join(relativeToRepo, 'README.md');
|
|
374
|
+
const docsReadmePath = path.posix.join(relativeToRepo, 'docs', 'README.md');
|
|
375
|
+
parts.push(`- [Container Superposition](${mainReadmePath})`);
|
|
376
|
+
parts.push(`- [Documentation](${docsReadmePath})`);
|
|
377
|
+
parts.push('');
|
|
378
|
+
return parts.join('\n');
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Generate consolidated README.md from selected overlays
|
|
382
|
+
*/
|
|
383
|
+
export function generateReadme(answers, overlays, overlayMetadata, outputPath) {
|
|
384
|
+
const parts = [];
|
|
385
|
+
// 1. Header
|
|
386
|
+
parts.push(generateHeader(answers));
|
|
387
|
+
// 2. Quick Start
|
|
388
|
+
parts.push(generateQuickStart(answers));
|
|
389
|
+
// 3. Load overlay documentation
|
|
390
|
+
const overlayDocs = [];
|
|
391
|
+
for (const overlayId of overlays) {
|
|
392
|
+
const metadata = overlayMetadata.get(overlayId);
|
|
393
|
+
if (!metadata) {
|
|
394
|
+
continue;
|
|
395
|
+
}
|
|
396
|
+
const docs = loadOverlayDocs(overlayId, metadata);
|
|
397
|
+
if (docs && docs.sections.size > 0) {
|
|
398
|
+
overlayDocs.push(docs);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
// 4. Services and Tools section
|
|
402
|
+
if (overlayDocs.length > 0) {
|
|
403
|
+
parts.push(generateServices(overlayDocs, overlayMetadata, outputPath));
|
|
404
|
+
}
|
|
405
|
+
// 5. Environment Variables section
|
|
406
|
+
const envSection = generateEnvironmentVariables(outputPath);
|
|
407
|
+
if (envSection) {
|
|
408
|
+
parts.push(envSection);
|
|
409
|
+
}
|
|
410
|
+
// 6. Troubleshooting section (aggregated)
|
|
411
|
+
const troubleshooting = generateTroubleshooting(overlayDocs);
|
|
412
|
+
if (troubleshooting) {
|
|
413
|
+
parts.push(troubleshooting);
|
|
414
|
+
}
|
|
415
|
+
// 7. References
|
|
416
|
+
parts.push(generateReferences(overlays, outputPath));
|
|
417
|
+
// Write README.md
|
|
418
|
+
const readmePath = path.join(outputPath, 'README.md');
|
|
419
|
+
const content = parts.join('\n').trim() + '\n';
|
|
420
|
+
fs.writeFileSync(readmePath, content, 'utf-8');
|
|
421
|
+
}
|
|
422
|
+
//# sourceMappingURL=readme-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readme-generator.js","sourceRoot":"","sources":["../../../tool/readme/readme-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom patches loader - loads user customizations from .devcontainer/custom/
|
|
3
|
+
*/
|
|
4
|
+
import type { CustomizationConfig } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Check if custom directory exists
|
|
7
|
+
*/
|
|
8
|
+
export declare function hasCustomDirectory(outputPath: string): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Load custom patches from .devcontainer/custom/ directory
|
|
11
|
+
*/
|
|
12
|
+
export declare function loadCustomPatches(outputPath: string): CustomizationConfig | null;
|
|
13
|
+
/**
|
|
14
|
+
* Get list of custom scripts that need to be executable
|
|
15
|
+
*/
|
|
16
|
+
export declare function getCustomScriptPaths(outputPath: string): string[];
|
|
17
|
+
//# sourceMappingURL=custom-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"custom-loader.d.ts","sourceRoot":"","sources":["../../../tool/schema/custom-loader.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,mBAAmB,EAAgB,MAAM,YAAY,CAAC;AAEpE;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAG9D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CA4EhF;AAyDD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAqBjE"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom patches loader - loads user customizations from .devcontainer/custom/
|
|
3
|
+
*/
|
|
4
|
+
import * as fs from 'fs';
|
|
5
|
+
import * as path from 'path';
|
|
6
|
+
import * as yaml from 'js-yaml';
|
|
7
|
+
/**
|
|
8
|
+
* Check if custom directory exists
|
|
9
|
+
*/
|
|
10
|
+
export function hasCustomDirectory(outputPath) {
|
|
11
|
+
const customDir = path.join(outputPath, 'custom');
|
|
12
|
+
return fs.existsSync(customDir);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Load custom patches from .devcontainer/custom/ directory
|
|
16
|
+
*/
|
|
17
|
+
export function loadCustomPatches(outputPath) {
|
|
18
|
+
const customDir = path.join(outputPath, 'custom');
|
|
19
|
+
if (!fs.existsSync(customDir)) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
const config = {};
|
|
23
|
+
// Load devcontainer.patch.json
|
|
24
|
+
const devcontainerPatchPath = path.join(customDir, 'devcontainer.patch.json');
|
|
25
|
+
if (fs.existsSync(devcontainerPatchPath)) {
|
|
26
|
+
try {
|
|
27
|
+
const content = fs.readFileSync(devcontainerPatchPath, 'utf-8');
|
|
28
|
+
config.devcontainerPatch = JSON.parse(content);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
console.warn(`⚠️ Failed to parse ${devcontainerPatchPath}:`, error);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// Load docker-compose.patch.yml
|
|
35
|
+
const dockerComposePatchPath = path.join(customDir, 'docker-compose.patch.yml');
|
|
36
|
+
if (fs.existsSync(dockerComposePatchPath)) {
|
|
37
|
+
try {
|
|
38
|
+
const content = fs.readFileSync(dockerComposePatchPath, 'utf-8');
|
|
39
|
+
config.dockerComposePatch = yaml.load(content);
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
console.warn(`⚠️ Failed to parse ${dockerComposePatchPath}:`, error);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// Load environment.env
|
|
46
|
+
const envPath = path.join(customDir, 'environment.env');
|
|
47
|
+
if (fs.existsSync(envPath)) {
|
|
48
|
+
try {
|
|
49
|
+
const content = fs.readFileSync(envPath, 'utf-8');
|
|
50
|
+
config.environmentVars = parseEnvFile(content);
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
console.warn(`⚠️ Failed to parse ${envPath}:`, error);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// Load scripts
|
|
57
|
+
const scriptsDir = path.join(customDir, 'scripts');
|
|
58
|
+
if (fs.existsSync(scriptsDir)) {
|
|
59
|
+
config.scripts = {
|
|
60
|
+
postCreate: [],
|
|
61
|
+
postStart: [],
|
|
62
|
+
};
|
|
63
|
+
// Determine the custom directory path relative to workspace root
|
|
64
|
+
// outputPath is typically .devcontainer, so custom is .devcontainer/custom
|
|
65
|
+
const outputDirName = path.basename(outputPath);
|
|
66
|
+
const customRelPath = path.join(outputDirName, 'custom', 'scripts').replace(/\\/g, '/');
|
|
67
|
+
// Check for post-create.sh
|
|
68
|
+
const postCreatePath = path.join(scriptsDir, 'post-create.sh');
|
|
69
|
+
if (fs.existsSync(postCreatePath)) {
|
|
70
|
+
config.scripts.postCreate.push(`bash ${customRelPath}/post-create.sh`);
|
|
71
|
+
}
|
|
72
|
+
// Check for post-start.sh
|
|
73
|
+
const postStartPath = path.join(scriptsDir, 'post-start.sh');
|
|
74
|
+
if (fs.existsSync(postStartPath)) {
|
|
75
|
+
config.scripts.postStart.push(`bash ${customRelPath}/post-start.sh`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Scan for custom files to copy
|
|
79
|
+
const filesDir = path.join(customDir, 'files');
|
|
80
|
+
if (fs.existsSync(filesDir)) {
|
|
81
|
+
config.files = [];
|
|
82
|
+
scanCustomFiles(filesDir, filesDir, config.files);
|
|
83
|
+
}
|
|
84
|
+
return config;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Parse environment file into key-value pairs
|
|
88
|
+
*/
|
|
89
|
+
function parseEnvFile(content) {
|
|
90
|
+
const env = {};
|
|
91
|
+
const lines = content.split('\n');
|
|
92
|
+
for (const line of lines) {
|
|
93
|
+
const trimmed = line.trim();
|
|
94
|
+
// Skip empty lines and comments
|
|
95
|
+
if (!trimmed || trimmed.startsWith('#')) {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
// Parse KEY=VALUE format
|
|
99
|
+
const match = trimmed.match(/^([^=]+)=(.*)$/);
|
|
100
|
+
if (match) {
|
|
101
|
+
const key = match[1].trim();
|
|
102
|
+
const value = match[2].trim();
|
|
103
|
+
// Preserve the value as-is (including quotes if present)
|
|
104
|
+
env[key] = value;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return env;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Recursively scan custom files directory
|
|
111
|
+
*/
|
|
112
|
+
function scanCustomFiles(baseDir, currentDir, files) {
|
|
113
|
+
const entries = fs.readdirSync(currentDir);
|
|
114
|
+
for (const entry of entries) {
|
|
115
|
+
const fullPath = path.join(currentDir, entry);
|
|
116
|
+
const stat = fs.statSync(fullPath);
|
|
117
|
+
if (stat.isDirectory()) {
|
|
118
|
+
scanCustomFiles(baseDir, fullPath, files);
|
|
119
|
+
}
|
|
120
|
+
else if (stat.isFile()) {
|
|
121
|
+
const relativePath = path.relative(baseDir, fullPath);
|
|
122
|
+
files.push({
|
|
123
|
+
source: fullPath,
|
|
124
|
+
destination: relativePath,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Get list of custom scripts that need to be executable
|
|
131
|
+
*/
|
|
132
|
+
export function getCustomScriptPaths(outputPath) {
|
|
133
|
+
const customDir = path.join(outputPath, 'custom');
|
|
134
|
+
const scriptsDir = path.join(customDir, 'scripts');
|
|
135
|
+
if (!fs.existsSync(scriptsDir)) {
|
|
136
|
+
return [];
|
|
137
|
+
}
|
|
138
|
+
const scripts = [];
|
|
139
|
+
const postCreatePath = path.join(scriptsDir, 'post-create.sh');
|
|
140
|
+
if (fs.existsSync(postCreatePath)) {
|
|
141
|
+
scripts.push(postCreatePath);
|
|
142
|
+
}
|
|
143
|
+
const postStartPath = path.join(scriptsDir, 'post-start.sh');
|
|
144
|
+
if (fs.existsSync(postStartPath)) {
|
|
145
|
+
scripts.push(postStartPath);
|
|
146
|
+
}
|
|
147
|
+
return scripts;
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=custom-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"custom-loader.js","sourceRoot":"","sources":["../../../tool/schema/custom-loader.ts"],"names":[],"mappings":"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"}
|