@tdk-landscape/tdk-cli-core 1.3.14 → 1.3.22
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 +3 -3
- package/Tiltfile +144 -0
- package/discovery/AGENTS.md +362 -0
- package/discovery/TILT_DISCOVERY.star +424 -0
- package/discovery/Tiltfile +58 -0
- package/discovery/config.star +258 -0
- package/discovery/constants.star +127 -0
- package/discovery/deterministic.star +211 -0
- package/discovery/discovery_daemon.star +191 -0
- package/discovery/discovery_orchestrator.star +460 -0
- package/discovery/filtering.star +5 -0
- package/discovery/identity-management-backend/service.yaml +26 -0
- package/discovery/identity-management-frontend/service.yaml +29 -0
- package/discovery/identity-sdk/service.yaml +9 -0
- package/discovery/incremental_discovery.star +213 -0
- package/discovery/indexing.star +7 -0
- package/discovery/json_manifest_scanner.star +51 -0
- package/discovery/libraries.star +46 -0
- package/discovery/loading.star +23 -0
- package/discovery/manifest/constants.star +104 -0
- package/discovery/manifest/loading.star +386 -0
- package/discovery/manifest/normalize.star +281 -0
- package/discovery/manifest/validation.star +108 -0
- package/discovery/normalization.star +11 -0
- package/discovery/registry.star +544 -0
- package/discovery/resource_snapshot.py +382 -0
- package/discovery/resource_snapshot.star +143 -0
- package/discovery/schemas.star +1 -0
- package/discovery/services/platform/cdc/debezium/nats-connector/service.yaml +9 -0
- package/discovery/services/platform/cdc/nats-http-bridge/service.yaml +9 -0
- package/discovery/services/platform/orchestrator/orchestrator-glue-backend/service.yaml +26 -0
- package/discovery/services/platform/synthetic-monitor/service.yaml +9 -0
- package/discovery/test_resource_snapshot.py +251 -0
- package/discovery/validation.star +78 -0
- package/discovery/versioning.star +1 -0
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +11 -0
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +1 -2
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/project.d.ts.map +1 -1
- package/dist/commands/project.js +36 -41
- package/dist/commands/project.js.map +1 -1
- package/dist/commands/resource.d.ts.map +1 -1
- package/dist/commands/resource.js +51 -55
- package/dist/commands/resource.js.map +1 -1
- package/dist/commands/stack.d.ts.map +1 -1
- package/dist/commands/stack.js +22 -24
- package/dist/commands/stack.js.map +1 -1
- package/dist/commands/ui.d.ts.map +1 -1
- package/dist/commands/ui.js +1 -2
- package/dist/commands/ui.js.map +1 -1
- package/dist/commands/up.d.ts.map +1 -1
- package/dist/commands/up.js +1 -2
- package/dist/commands/up.js.map +1 -1
- package/dist/commands/upgrade.d.ts +8 -0
- package/dist/commands/upgrade.d.ts.map +1 -1
- package/dist/commands/upgrade.js +62 -21
- package/dist/commands/upgrade.js.map +1 -1
- package/dist/generator/extension-fetch.d.ts +19 -0
- package/dist/generator/extension-fetch.d.ts.map +1 -1
- package/dist/generator/extension-fetch.js +71 -5
- package/dist/generator/extension-fetch.js.map +1 -1
- package/dist/generator/template-engine.d.ts +1 -0
- package/dist/generator/template-engine.d.ts.map +1 -1
- package/dist/generator/template-engine.js +50 -6
- package/dist/generator/template-engine.js.map +1 -1
- package/dist/utils/command-helpers.d.ts.map +1 -1
- package/dist/utils/command-helpers.js +7 -9
- package/dist/utils/command-helpers.js.map +1 -1
- package/dist/utils/constants.d.ts +1 -0
- package/dist/utils/constants.d.ts.map +1 -1
- package/dist/utils/constants.js +1 -0
- package/dist/utils/constants.js.map +1 -1
- package/dist/utils/errors.d.ts +2 -0
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +6 -1
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/paths.js +1 -1
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/project-features.d.ts.map +1 -1
- package/dist/utils/project-features.js +1 -1
- package/dist/utils/project-features.js.map +1 -1
- package/dist/utils/resource-features.d.ts.map +1 -1
- package/dist/utils/resource-features.js +2 -2
- package/dist/utils/resource-features.js.map +1 -1
- package/dist/utils/tar.js +4 -4
- package/dist/utils/tar.js.map +1 -1
- package/dist/utils/validation.d.ts +7 -0
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +9 -0
- package/dist/utils/validation.js.map +1 -1
- package/engine/AGENTS.md +705 -0
- package/engine/README.md +29 -0
- package/engine/REFACTORING_MANIFEST_SYSTEM.md +974 -0
- package/engine/Tiltfile +80 -0
- package/engine/assets/docker/golden-layers.Dockerfile +221 -0
- package/engine/assets/scripts/cleanup-completed-migrator-images.sh +37 -0
- package/engine/assets/scripts/cleanup-tilt-images.sh +120 -0
- package/engine/assets/scripts/mac-m1-resource-monitor.sh +121 -0
- package/engine/config.star +3 -0
- package/engine/docs/AUTODISCOVERY_TEST.md +182 -0
- package/engine/docs/C4-ARCHITECTURE-operations.md +396 -0
- package/engine/docs/C4-ARCHITECTURE-overview.md +284 -0
- package/engine/docs/C4-ARCHITECTURE.md +17 -0
- package/engine/docs/GOLDEN_IMAGE_INTEGRATION.md +349 -0
- package/engine/docs/MANIFEST_DRIVEN_ARCHITECTURE.md +357 -0
- package/engine/docs/README.md +284 -0
- package/engine/entrypoint.star +97 -0
- package/engine/lifecycle/orchestrator.star +260 -0
- package/engine/paths.star +717 -0
- package/engine/schemas/manifest-schema.json +301 -0
- package/engine/schemas/service-schema.json +301 -0
- package/engine/scripts/README.md +89 -0
- package/engine/scripts/build-and-publish-lib.sh +205 -0
- package/engine/scripts/check-lib-publish.sh +85 -0
- package/engine/scripts/debug-container.sh +258 -0
- package/engine/scripts/generate-manifest.sh +197 -0
- package/engine/spec.master +702 -0
- package/engine/spec.master.example +341 -0
- package/engine/topologies/README.md +34 -0
- package/engine/topologies/platform/docker/AGENTS.md +59 -0
- package/engine/topologies/platform/docker/auth/auth.star +167 -0
- package/engine/topologies/platform/docker/build/golden_image.star +37 -0
- package/engine/topologies/platform/docker/build/golden_image_build.star +82 -0
- package/engine/topologies/platform/docker/build/golden_image_constants.star +93 -0
- package/engine/topologies/platform/docker/build/golden_image_dockerfile.star +291 -0
- package/engine/topologies/platform/docker/compose/compose.star +636 -0
- package/engine/topologies/platform/docker/compose/compose_helpers.star +52 -0
- package/engine/topologies/platform/docker/compose/traefik_standalone.star +53 -0
- package/engine/topologies/platform/docker/config/bunignore.star +142 -0
- package/engine/topologies/platform/docker/config/dockerignore.star +150 -0
- package/engine/topologies/platform/docker/constants.star +170 -0
- package/engine/topologies/platform/docker/dockerfile/dockerfile.star +54 -0
- package/engine/topologies/platform/docker/generators/golden_docker_generator_v2.star +73 -0
- package/engine/topologies/platform/docker/index.star +27 -0
- package/engine/topologies/platform/docker/layers/bun_helpers.star +23 -0
- package/engine/topologies/platform/docker/layers/infisical/index.star +40 -0
- package/engine/topologies/platform/docker/layers/infisical/infisical_docker.star +262 -0
- package/engine/topologies/platform/docker/layers/l1_base_layers.star +87 -0
- package/engine/topologies/platform/docker/layers/l2_dependency_layers.star +125 -0
- package/engine/topologies/platform/docker/layers/l3_builder_layers.star +209 -0
- package/engine/topologies/platform/docker/layers/l4_runtime_layers.star +214 -0
- package/engine/topologies/platform/docker/layers/prisma/constants.star +135 -0
- package/engine/topologies/platform/docker/layers/prisma/db_readiness.star +96 -0
- package/engine/topologies/platform/docker/layers/prisma/filesystem_setup.star +109 -0
- package/engine/topologies/platform/docker/layers/prisma/migrate_script.star +98 -0
- package/engine/topologies/platform/docker/layers/prisma/prisma_build.star +126 -0
- package/engine/topologies/platform/docker/layers/prisma/prisma_runtime.star +161 -0
- package/engine/topologies/platform/docker/layers/prisma/secret_resolution.star +119 -0
- package/engine/topologies/platform/docker/networking/api_path_constants.star +230 -0
- package/engine/topologies/platform/docker/networking/sablier_container_cycle.star +27 -0
- package/engine/topologies/platform/docker/networking/traefik.star +232 -0
- package/engine/topologies/platform/docker/networking/traefik_constants.star +146 -0
- package/engine/topologies/platform/docker/networking/traefik_helpers.star +160 -0
- package/engine/topologies/platform/docker/secrets/infisical.star +135 -0
- package/engine/topologies/platform/net/proxy.star +4 -0
- package/engine/topologies/platform/registries/local.star +4 -0
- package/engine/topologies/platform/security/secrets.star +239 -0
- package/engine/topologies/platform/state/relational.star +4 -0
- package/engine/topologies/tilt/common/AGENTS.md +59 -0
- package/engine/topologies/tilt/common/utils.star +364 -0
- package/engine/topologies/tilt/common/utils_debug.star +69 -0
- package/engine/topologies/tilt/common/utils_deterministic.star +168 -0
- package/engine/topologies/tilt/common/utils_docker_networks.star +46 -0
- package/engine/topologies/tilt/common/utils_env.star +43 -0
- package/engine/topologies/tilt/common/utils_output.star +97 -0
- package/engine/topologies/tilt/config/AGENTS.md +68 -0
- package/engine/topologies/tilt/config/defaults.star +3 -0
- package/engine/topologies/tilt/config/feature_flags.star +10 -0
- package/engine/topologies/tilt/config/global.star +55 -0
- package/engine/topologies/tilt/config/profiles.star +382 -0
- package/engine/topologies/tilt/generators/agents_md.star +62 -0
- package/engine/topologies/tilt/generators/api_gateway.star +145 -0
- package/engine/topologies/tilt/generators/index.star +124 -0
- package/engine/topologies/tilt/generators/infisical/README.md +424 -0
- package/engine/topologies/tilt/generators/infisical/examples.star +312 -0
- package/engine/topologies/tilt/generators/infisical/index.star +57 -0
- package/engine/topologies/tilt/generators/infisical/machine_identity.star +420 -0
- package/engine/topologies/tilt/generators/infisical/organization.star +534 -0
- package/engine/topologies/tilt/generators/infisical/path_manager.star +476 -0
- package/engine/topologies/tilt/generators/infisical/secrets_generator.star +420 -0
- package/engine/topologies/tilt/generators/nginx_conf.star +143 -0
- package/engine/topologies/tilt/generators/npmrc.star +111 -0
- package/engine/topologies/tilt/generators/tsconfig.star +23 -0
- package/engine/topologies/tilt/generators/typescript/backend_library_tsconfig.star +71 -0
- package/engine/topologies/tilt/generators/typescript/backend_tsconfig.star +124 -0
- package/engine/topologies/tilt/generators/typescript/common.star +7 -0
- package/engine/topologies/tilt/generators/typescript/frontend_library_tsconfig.star +76 -0
- package/engine/topologies/tilt/generators/typescript/frontend_tsconfig.star +110 -0
- package/engine/topologies/tilt/generators/typescript/include.star +23 -0
- package/engine/topologies/tilt/generators/typescript/playwright_config.star +40 -0
- package/engine/topologies/tilt/generators/typescript/prisma_config.star +49 -0
- package/engine/topologies/tilt/generators/validators.star +853 -0
- package/engine/topologies/tilt/generators/vite/backend.star +78 -0
- package/engine/topologies/tilt/generators/vite/frontend.star +98 -0
- package/engine/topologies/tilt/generators/vite/generators.star +43 -0
- package/engine/topologies/tilt/generators/vite/helpers.star +244 -0
- package/engine/topologies/tilt/generators/vite/library.star +65 -0
- package/engine/topologies/tilt/generators/vite/sdk.star +73 -0
- package/engine/topologies/tilt/generators/vite/templates.star +737 -0
- package/engine/topologies/tilt/generators/vite_config.star +22 -0
- package/engine/topologies/tilt/manifest/AGENTS.md +61 -0
- package/engine/topologies/tilt/manifest/README.md +693 -0
- package/engine/topologies/tilt/manifest/__init__.star +218 -0
- package/engine/topologies/tilt/manifest/constants.star +252 -0
- package/engine/topologies/tilt/manifest/errors.star +266 -0
- package/engine/topologies/tilt/manifest/integration.star +339 -0
- package/engine/topologies/tilt/manifest/json_to_yaml.py +54 -0
- package/engine/topologies/tilt/manifest/loader.star +214 -0
- package/engine/topologies/tilt/manifest/mapper.star +227 -0
- package/engine/topologies/tilt/manifest/parser.star +400 -0
- package/engine/topologies/tilt/manifest/schema.star +462 -0
- package/engine/topologies/tilt/manifest/tests/test_integration.star +276 -0
- package/engine/topologies/tilt/manifest/tests/test_loader_parser.star +397 -0
- package/engine/topologies/tilt/manifest/tests/test_manifest.star +316 -0
- package/engine/topologies/tilt/manifest/tests/test_validator.star +470 -0
- package/engine/topologies/tilt/manifest/validator.star +717 -0
- package/engine/topologies/tilt/manifest/yaml_to_json.py +18 -0
- package/engine/topologies/tilt/resources/AGENTS.md +71 -0
- package/engine/topologies/tilt/resources/conditions.star +3 -0
- package/engine/topologies/tilt/resources/databases.star +244 -0
- package/engine/topologies/tilt/resources/declaration.star +3 -0
- package/engine/topologies/tilt/resources/deps.star +3 -0
- package/engine/topologies/tilt/resources/infra-loader.star +437 -0
- package/engine/topologies/tilt/resources/libs.star +30 -0
- package/engine/topologies/tilt/resources/libs_discovery.star +102 -0
- package/engine/topologies/tilt/resources/libs_paths.star +79 -0
- package/engine/topologies/tilt/resources/libs_resource_definition.star +151 -0
- package/engine/topologies/tilt/resources/libs_setup.star +164 -0
- package/engine/topologies/tilt/resources/libs_tsconfig.star +37 -0
- package/engine/topologies/tilt/resources/orchestrator/apply.star +77 -0
- package/engine/topologies/tilt/resources/orchestrator/apply_compose_resource_registration.star +431 -0
- package/engine/topologies/tilt/resources/orchestrator/apply_manifest_orchestration.star +81 -0
- package/engine/topologies/tilt/resources/orchestrator/apply_migrator_orchestration.star +148 -0
- package/engine/topologies/tilt/resources/orchestrator/apply_resource_validation.star +36 -0
- package/engine/topologies/tilt/resources/orchestrator/apply_runtime_flags.star +44 -0
- package/engine/topologies/tilt/resources/orchestrator/builders/typescript.star +164 -0
- package/engine/topologies/tilt/resources/orchestrator/generators/dependencies/AGENTS.md +75 -0
- package/engine/topologies/tilt/resources/orchestrator/generators/dependencies/index.star +21 -0
- package/engine/topologies/tilt/resources/orchestrator/generators/dependencies/resolver.star +134 -0
- package/engine/topologies/tilt/resources/orchestrator/generators/env.star +258 -0
- package/engine/topologies/tilt/resources/orchestrator/generators/frontend.star +169 -0
- package/engine/topologies/tilt/resources/orchestrator/generators/manifest_resource.star +524 -0
- package/engine/topologies/tilt/resources/orchestrator/helpers.star +33 -0
- package/engine/topologies/tilt/resources/orchestrator.star +54 -0
- package/engine/topologies/tilt/resources/ordering.star +3 -0
- package/engine/topologies/tilt/resources/triggers.star +3 -0
- package/engine/topologies/tilt/resources/watchers.star +299 -0
- package/engine/where-things-live.star +717 -0
- package/ext/Tiltfile +66 -0
- package/ext/ide-components/README.md +219 -0
- package/ext/ide-components/code_executor/server.py +268 -0
- package/ext/ide-components/code_viewer/server.py +206 -0
- package/ext/ide-components/config_inspector/server.py +1050 -0
- package/ext/ide-components/file_browser/server.py +285 -0
- package/ext/ide-components/shared/config_service.py +469 -0
- package/ext/ide-components/shared/file_utils.py +298 -0
- package/ext/ide-components/shared/http_utils.py +232 -0
- package/ext/ide-components/shared/static/styles.css +1334 -0
- package/ext/ide-components/shared/syntax_highlighter.py +140 -0
- package/ext/ide-components/shared/template_engine.py +123 -0
- package/ext/ide-components/shared/templates/base.html +121 -0
- package/ext/ide-components/shared/test_config_service.py +326 -0
- package/ext/ide-components/shared/tilt_integration.py +158 -0
- package/ext/ui-enhancements/cron-status-server.sh +49 -0
- package/ext/ui-enhancements/cron-status-tracker.sh +146 -0
- package/ext/ui-enhancements/extension.yaml +36 -0
- package/ext/ui-enhancements/tiltfile.py +99 -0
- package/ext/ui-enhancements/ui/cron-jobs-tab.css +396 -0
- package/ext/ui-enhancements/ui/help-panel.css +279 -0
- package/ext/ui-enhancements/ui/icons.css +125 -0
- package/ext/ui-enhancements/ui/tooltips.css +114 -0
- package/package.json +13 -9
- package/specs/specs/TILT_SERVICE_DEFAULTS.star +205 -0
- package/specs/specs/TILT_TECH_STACK.star +159 -0
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
#!/usr/bin/env starlark
|
|
2
|
+
# =============================================================================
|
|
3
|
+
# 🗺️ TOPOLOGIES - DISCOVERY CONFIG
|
|
4
|
+
# =============================================================================
|
|
5
|
+
|
|
6
|
+
load("./constants.star", "RESOURCES_ROOT")
|
|
7
|
+
load("../engine/topologies/platform/docker/constants.star", "PlatformDockerConstants")
|
|
8
|
+
|
|
9
|
+
# NOTE: DEFAULTS and focus lists are now loaded dynamically in resource_registry.star
|
|
10
|
+
# from the project's spec.master (using TDK_PROJECT_ROOT environment variable).
|
|
11
|
+
# This allows per-project resource configuration.
|
|
12
|
+
|
|
13
|
+
# Default empty values - will be populated by _load_project_defaults() in resource_registry.star
|
|
14
|
+
DEFAULTS = {}
|
|
15
|
+
FOCUS_PRE_ALPHA = []
|
|
16
|
+
FOCUS_ALPHA = []
|
|
17
|
+
FOCUS_BETA = []
|
|
18
|
+
|
|
19
|
+
# Export a function to load project-specific defaults
|
|
20
|
+
def load_project_defaults(project_root):
|
|
21
|
+
"""
|
|
22
|
+
Load DEFAULTS and focus lists from project spec.master.
|
|
23
|
+
Called by resource_registry.star during initialization.
|
|
24
|
+
|
|
25
|
+
Returns struct with loaded values or None if spec.master not found.
|
|
26
|
+
"""
|
|
27
|
+
if not project_root:
|
|
28
|
+
return None
|
|
29
|
+
|
|
30
|
+
# Check multiple locations for spec.master (in order of preference)
|
|
31
|
+
spec_paths = [
|
|
32
|
+
project_root + "/.tdk/.tdk-out/generated/spec.master", # New unified output folder
|
|
33
|
+
project_root + "/spec.master", # Original location (legacy)
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
spec_path = None
|
|
37
|
+
for path in spec_paths:
|
|
38
|
+
check_cmd = "test -f '{}' && echo 'yes' || echo 'no'".format(path)
|
|
39
|
+
exists = str(local(check_cmd, quiet=True, echo_off=True)).strip() == 'yes'
|
|
40
|
+
if exists:
|
|
41
|
+
spec_path = path
|
|
42
|
+
break
|
|
43
|
+
|
|
44
|
+
if not spec_path:
|
|
45
|
+
return None
|
|
46
|
+
|
|
47
|
+
# Read and parse the spec.master file
|
|
48
|
+
# Since we can't dynamically load, we parse it manually
|
|
49
|
+
spec_content_raw = read_file(spec_path, default="")
|
|
50
|
+
if not spec_content_raw:
|
|
51
|
+
return None
|
|
52
|
+
|
|
53
|
+
# Ensure content is a string (read_file may return bytes)
|
|
54
|
+
spec_content = str(spec_content_raw)
|
|
55
|
+
|
|
56
|
+
# Extract PRE_ALPHA_RESOURCES from the file
|
|
57
|
+
# This is a simple parser for the expected format
|
|
58
|
+
defaults = {}
|
|
59
|
+
pre_alpha = []
|
|
60
|
+
alpha = []
|
|
61
|
+
beta = []
|
|
62
|
+
|
|
63
|
+
# Parse PRE_ALPHA_RESOURCES
|
|
64
|
+
if "PRE_ALPHA_RESOURCES" in spec_content:
|
|
65
|
+
# Extract the dict content between { and }
|
|
66
|
+
start = spec_content.find("PRE_ALPHA_RESOURCES = {")
|
|
67
|
+
if start != -1:
|
|
68
|
+
start = spec_content.find("{", start)
|
|
69
|
+
end = spec_content.find("}", start)
|
|
70
|
+
if start != -1 and end != -1:
|
|
71
|
+
dict_content = spec_content[start+1:end]
|
|
72
|
+
# Parse "key": True/False entries
|
|
73
|
+
for line in dict_content.split("\n"):
|
|
74
|
+
line = line.strip()
|
|
75
|
+
if line and not line.startswith("#"):
|
|
76
|
+
# Extract key before colon
|
|
77
|
+
if '"' in line or "'" in line:
|
|
78
|
+
# Find quoted key
|
|
79
|
+
quote_char = '"' if '"' in line else "'"
|
|
80
|
+
key_start = line.find(quote_char)
|
|
81
|
+
key_end = line.find(quote_char, key_start + 1)
|
|
82
|
+
if key_start != -1 and key_end != -1:
|
|
83
|
+
key = line[key_start+1:key_end]
|
|
84
|
+
# Check if value is True
|
|
85
|
+
if "True" in line:
|
|
86
|
+
defaults[key] = True
|
|
87
|
+
pre_alpha.append(key)
|
|
88
|
+
|
|
89
|
+
# Parse ALPHA_RESOURCES
|
|
90
|
+
if "ALPHA_RESOURCES" in spec_content:
|
|
91
|
+
start = spec_content.find("ALPHA_RESOURCES = {")
|
|
92
|
+
if start != -1:
|
|
93
|
+
start = spec_content.find("{", start)
|
|
94
|
+
end = spec_content.find("}", start)
|
|
95
|
+
if start != -1 and end != -1:
|
|
96
|
+
dict_content = spec_content[start+1:end]
|
|
97
|
+
for line in dict_content.split("\n"):
|
|
98
|
+
line = line.strip()
|
|
99
|
+
if line and not line.startswith("#"):
|
|
100
|
+
if '"' in line or "'" in line:
|
|
101
|
+
quote_char = '"' if '"' in line else "'"
|
|
102
|
+
key_start = line.find(quote_char)
|
|
103
|
+
key_end = line.find(quote_char, key_start + 1)
|
|
104
|
+
if key_start != -1 and key_end != -1:
|
|
105
|
+
key = line[key_start+1:key_end]
|
|
106
|
+
if "True" in line:
|
|
107
|
+
defaults[key] = True
|
|
108
|
+
alpha.append(key)
|
|
109
|
+
|
|
110
|
+
# Parse BETA_RESOURCES
|
|
111
|
+
if "BETA_RESOURCES" in spec_content:
|
|
112
|
+
start = spec_content.find("BETA_RESOURCES = {")
|
|
113
|
+
if start != -1:
|
|
114
|
+
start = spec_content.find("{", start)
|
|
115
|
+
end = spec_content.find("}", start)
|
|
116
|
+
if start != -1 and end != -1:
|
|
117
|
+
dict_content = spec_content[start+1:end]
|
|
118
|
+
for line in dict_content.split("\n"):
|
|
119
|
+
line = line.strip()
|
|
120
|
+
if line and not line.startswith("#"):
|
|
121
|
+
if '"' in line or "'" in line:
|
|
122
|
+
quote_char = '"' if '"' in line else "'"
|
|
123
|
+
key_start = line.find(quote_char)
|
|
124
|
+
key_end = line.find(quote_char, key_start + 1)
|
|
125
|
+
if key_start != -1 and key_end != -1:
|
|
126
|
+
key = line[key_start+1:key_end]
|
|
127
|
+
if "True" in line:
|
|
128
|
+
defaults[key] = True
|
|
129
|
+
beta.append(key)
|
|
130
|
+
|
|
131
|
+
return struct(
|
|
132
|
+
DEFAULTS = defaults,
|
|
133
|
+
FOCUS_PRE_ALPHA = pre_alpha,
|
|
134
|
+
FOCUS_ALPHA = pre_alpha + alpha,
|
|
135
|
+
FOCUS_BETA = pre_alpha + alpha + beta,
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
# -----------------------------------------------------------------------------
|
|
139
|
+
# 🎛️ RESOURCE DEFAULTS
|
|
140
|
+
# -----------------------------------------------------------------------------
|
|
141
|
+
# LOADED FROM: spec.master (searched in order):
|
|
142
|
+
# 1. .tdk/.tdk-out/generated/spec.master (new unified output folder)
|
|
143
|
+
# 2. spec.master (legacy location in project root)
|
|
144
|
+
# PURPOSE: Single source of truth for resource enable/disable configuration
|
|
145
|
+
#
|
|
146
|
+
# 📖 To modify which resources run, edit: spec.master
|
|
147
|
+
# -----------------------------------------------------------------------------
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def get_global_config():
|
|
151
|
+
verdaccio_url_docker = os.environ.get(
|
|
152
|
+
"VERDACCIO_URL_DOCKER",
|
|
153
|
+
PlatformDockerConstants.VERDACCIO_URL_DOCKER,
|
|
154
|
+
)
|
|
155
|
+
return {
|
|
156
|
+
"verdaccio_url_local": PlatformDockerConstants.VERDACCIO_URL_LOCAL,
|
|
157
|
+
"verdaccio_url_docker": verdaccio_url_docker,
|
|
158
|
+
"npm_registry": PlatformDockerConstants.VERDACCIO_NPM_REGISTRY,
|
|
159
|
+
"internal_scope": "@" + PlatformDockerConstants.PROJECT_NAME + "/",
|
|
160
|
+
"library_roots": {
|
|
161
|
+
"platform": "shared-platform-engineering",
|
|
162
|
+
"product": "shared-product-engineering",
|
|
163
|
+
"ddd": "shared-ddd-layers",
|
|
164
|
+
},
|
|
165
|
+
# Relative to .tilt/topologies/tilt/discovery/
|
|
166
|
+
"resources_root": RESOURCES_ROOT,
|
|
167
|
+
"database": PlatformDockerConstants.DB_CONFIG,
|
|
168
|
+
"docker": {
|
|
169
|
+
"base_image": PlatformDockerConstants.BUN_IMAGE,
|
|
170
|
+
"nginx_image": "nginx:alpine",
|
|
171
|
+
"golden_l1_image": PlatformDockerConstants.PROJECT_NAME_HYPHEN + "-l1:latest",
|
|
172
|
+
"golden_l2_image": PlatformDockerConstants.PROJECT_NAME_HYPHEN + "-l2:latest",
|
|
173
|
+
"golden_l3_backend_image": PlatformDockerConstants.PROJECT_NAME_HYPHEN + "-l3-backend:latest",
|
|
174
|
+
"golden_l3_frontend_image": PlatformDockerConstants.PROJECT_NAME_HYPHEN + "-l3-frontend:latest",
|
|
175
|
+
"golden_l3_migrator_image": PlatformDockerConstants.PROJECT_NAME_HYPHEN + "-l3-migrator:latest",
|
|
176
|
+
"golden_l4_backend_image": PlatformDockerConstants.PROJECT_NAME_HYPHEN + "-l4-backend:latest",
|
|
177
|
+
"golden_l4_frontend_image": PlatformDockerConstants.PROJECT_NAME_HYPHEN + "-l4-frontend:latest",
|
|
178
|
+
"golden_l4_migrator_image": PlatformDockerConstants.PROJECT_NAME_HYPHEN + "-l4-migrator:latest",
|
|
179
|
+
"network_prefix": PlatformDockerConstants.PROJECT_NAME + "_",
|
|
180
|
+
},
|
|
181
|
+
"ports": {
|
|
182
|
+
"backend": 3000,
|
|
183
|
+
"frontend": 80,
|
|
184
|
+
"postgres": 5432,
|
|
185
|
+
"nats": 4222,
|
|
186
|
+
"verdaccio": PlatformDockerConstants.VERDACCIO_PORT,
|
|
187
|
+
},
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
GLOBAL_CONFIG = get_global_config()
|
|
192
|
+
|
|
193
|
+
INFRA_RESOURCES = [
|
|
194
|
+
{"name": "database-management", "memory": 1152},
|
|
195
|
+
{"name": "proxy", "memory": 384},
|
|
196
|
+
{"name": "api-gateway", "memory": 512},
|
|
197
|
+
{"name": "verdaccio", "memory": 128},
|
|
198
|
+
{"name": "infisical", "memory": 192},
|
|
199
|
+
{"name": "monitoring", "memory": 1536},
|
|
200
|
+
{"name": "elk", "memory": 1024},
|
|
201
|
+
{"name": "debezium", "memory": 448},
|
|
202
|
+
]
|
|
203
|
+
|
|
204
|
+
CORE_INFRA = [
|
|
205
|
+
"init-networks",
|
|
206
|
+
"golden-layers-build",
|
|
207
|
+
"postgres",
|
|
208
|
+
"nats",
|
|
209
|
+
"traefik",
|
|
210
|
+
]
|
|
211
|
+
|
|
212
|
+
INFRA_STACK_MAP = {
|
|
213
|
+
"golden-layers-build": "golden-image",
|
|
214
|
+
"postgres": "database-management",
|
|
215
|
+
"nats": "database-management",
|
|
216
|
+
"redis": "database-management",
|
|
217
|
+
"traefik": "proxy",
|
|
218
|
+
"verdaccio": "verdaccio",
|
|
219
|
+
"infisical": "infisical",
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
OPTIONAL_INFRA = {
|
|
223
|
+
"monitoring": ["signoz-frontend", "signoz-otel-collector", "signoz-query-service", "clickhouse", "elasticsearch", "skywalking-oap", "skywalking-ui"],
|
|
224
|
+
"infisical": ["infisical", "infisical-db", "infisical-redis"],
|
|
225
|
+
"elk": ["elasticsearch", "logstash", "kibana"],
|
|
226
|
+
"debezium": ["kafka", "zookeeper", "nats-http-bridge", "debezium-connect", "enhanced-connector-setup"],
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
# -----------------------------------------------------------------------------
|
|
230
|
+
# 📚 LIBRARY DEFINITIONS
|
|
231
|
+
# -----------------------------------------------------------------------------
|
|
232
|
+
# Libraries are auto-discovered from the filesystem in libraries.star.
|
|
233
|
+
# Only non-auto-discoverable definitions (e.g. DDD layer paths) live here.
|
|
234
|
+
# -----------------------------------------------------------------------------
|
|
235
|
+
|
|
236
|
+
DDD_LIBS = [
|
|
237
|
+
{"name": "domain", "path": "shared-ddd-layers/domain"},
|
|
238
|
+
{"name": "infrastructure", "path": "shared-ddd-layers/infrastructure"},
|
|
239
|
+
{"name": "application", "path": "shared-ddd-layers/application"},
|
|
240
|
+
{"name": "presentation", "path": "shared-ddd-layers/presentation"},
|
|
241
|
+
]
|
|
242
|
+
|
|
243
|
+
# Export DEFAULTS and focus filters for use by other modules via Config struct
|
|
244
|
+
# Note: These will be populated by load_project_defaults() in resource_registry.star
|
|
245
|
+
Config = struct(
|
|
246
|
+
load_project_defaults = load_project_defaults,
|
|
247
|
+
DEFAULTS = DEFAULTS,
|
|
248
|
+
FOCUS_PRE_ALPHA = FOCUS_PRE_ALPHA,
|
|
249
|
+
FOCUS_ALPHA = FOCUS_ALPHA,
|
|
250
|
+
FOCUS_BETA = FOCUS_BETA,
|
|
251
|
+
GLOBAL = GLOBAL_CONFIG,
|
|
252
|
+
INFRA_RESOURCES = INFRA_RESOURCES,
|
|
253
|
+
CORE_INFRA = CORE_INFRA,
|
|
254
|
+
INFRA_STACK_MAP = INFRA_STACK_MAP,
|
|
255
|
+
OPTIONAL_INFRA = OPTIONAL_INFRA,
|
|
256
|
+
DDD_LIBS = DDD_LIBS,
|
|
257
|
+
|
|
258
|
+
)
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# 📍 TOPOLOGIES - DISCOVERY CONSTANTS
|
|
3
|
+
# =============================================================================
|
|
4
|
+
|
|
5
|
+
# Import manifest filename from local manifest folder (self-contained)
|
|
6
|
+
load("./manifest/constants.star",
|
|
7
|
+
_manifest_file="MANIFEST_FILENAME",
|
|
8
|
+
_manifest_file_yaml="MANIFEST_FILENAME_YAML"
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
# Re-export for consumers of this module
|
|
12
|
+
MANIFEST_FILENAME = _manifest_file
|
|
13
|
+
MANIFEST_FILENAME_YAML = _manifest_file_yaml
|
|
14
|
+
|
|
15
|
+
# NOTE: These paths are resolved relative to the TILTFILE directory (project root)
|
|
16
|
+
# NOT relative to this module's location
|
|
17
|
+
RESOURCES_ROOT = "services/product"
|
|
18
|
+
RESOURCES_ROOT_PREFIX = ""
|
|
19
|
+
|
|
20
|
+
# Check for project-specific discovery patterns
|
|
21
|
+
def _get_project_discovery_roots():
|
|
22
|
+
"""Get discovery roots from project spec.master if available."""
|
|
23
|
+
project_root = os.environ.get('TDK_PROJECT_ROOT', '')
|
|
24
|
+
if not project_root:
|
|
25
|
+
return []
|
|
26
|
+
|
|
27
|
+
# Try to read spec.master for custom discovery patterns
|
|
28
|
+
spec_paths = [
|
|
29
|
+
project_root + "/.tdk/.tdk-out/spec.master",
|
|
30
|
+
project_root + "/spec.master",
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
for spec_path in spec_paths:
|
|
34
|
+
check_cmd = "test -f '{}' && echo 'yes' || echo 'no'".format(spec_path)
|
|
35
|
+
exists = str(local(check_cmd, quiet=True, echo_off=True)).strip() == 'yes'
|
|
36
|
+
if exists:
|
|
37
|
+
# Read and parse spec.master for RESOURCE_PATTERNS
|
|
38
|
+
spec_content = str(read_file(spec_path, default=""))
|
|
39
|
+
if "RESOURCE_PATTERNS" in spec_content:
|
|
40
|
+
# Extract patterns from the array
|
|
41
|
+
start = spec_content.find("RESOURCE_PATTERNS = [")
|
|
42
|
+
if start != -1:
|
|
43
|
+
start = spec_content.find("[", start)
|
|
44
|
+
end = spec_content.find("]", start)
|
|
45
|
+
if start != -1 and end != -1:
|
|
46
|
+
array_content = spec_content[start+1:end]
|
|
47
|
+
patterns = []
|
|
48
|
+
for part in array_content.split(","):
|
|
49
|
+
part = part.strip().strip("'").strip('"').strip()
|
|
50
|
+
if part and not part.startswith("#"):
|
|
51
|
+
patterns.append(part)
|
|
52
|
+
if patterns:
|
|
53
|
+
|
|
54
|
+
return patterns
|
|
55
|
+
return []
|
|
56
|
+
|
|
57
|
+
# Get project-specific roots or fall back to defaults
|
|
58
|
+
_PROJECT_DISCOVERY_ROOTS = _get_project_discovery_roots()
|
|
59
|
+
|
|
60
|
+
# Phase 2: Universal Discovery - Scan roots configuration
|
|
61
|
+
# Each root is scanned for service.json files
|
|
62
|
+
# Paths are relative to PROJECT_ROOT (where Tiltfile is located)
|
|
63
|
+
_DISCOVERY_ROOTS_RAW = _PROJECT_DISCOVERY_ROOTS if _PROJECT_DISCOVERY_ROOTS else [
|
|
64
|
+
RESOURCES_ROOT, # services/product/*/*/
|
|
65
|
+
"services/platform", # services/platform/*/*/
|
|
66
|
+
"shared-product-engineering", # shared-product-engineering/*/
|
|
67
|
+
"cli-platform-engineering", # cli-platform-engineering/*/
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
# SAFETY: Filter out tdk-cli's own directories to prevent self-modification
|
|
71
|
+
# The CLI should never scan or write to its own installation directory
|
|
72
|
+
def _filter_cli_dirs(roots):
|
|
73
|
+
"""Remove tdk-cli internal directories from scan roots."""
|
|
74
|
+
filtered = []
|
|
75
|
+
for root in roots:
|
|
76
|
+
# Skip if path contains tdk-cli internal paths
|
|
77
|
+
if "tdk-cli" in root and "discovery" in root:
|
|
78
|
+
print("⚠️ Skipping tdk-cli internal directory: {}".format(root))
|
|
79
|
+
continue
|
|
80
|
+
if root.startswith("discovery/") or root == "discovery":
|
|
81
|
+
print("⚠️ Skipping discovery directory: {}".format(root))
|
|
82
|
+
continue
|
|
83
|
+
filtered.append(root)
|
|
84
|
+
return filtered
|
|
85
|
+
|
|
86
|
+
DISCOVERY_SCAN_ROOTS = _filter_cli_dirs(_DISCOVERY_ROOTS_RAW)
|
|
87
|
+
|
|
88
|
+
# Phase 2: Explicit stack extraction patterns for each root type
|
|
89
|
+
# Documents HOW to extract stack from different directory structures
|
|
90
|
+
SCAN_ROOT_PATTERNS = {
|
|
91
|
+
RESOURCES_ROOT: {
|
|
92
|
+
"stack_depth": -3, # services/product/{STACK}/{service}/
|
|
93
|
+
"description": "Stack-grouped services (product)"
|
|
94
|
+
},
|
|
95
|
+
"services/platform": {
|
|
96
|
+
"stack_depth": -2, # services/platform/{SERVICE}/ (flat)
|
|
97
|
+
"description": "Flat platform services"
|
|
98
|
+
},
|
|
99
|
+
"shared-product-engineering": {
|
|
100
|
+
"stack_depth": -2, # shared-product-engineering/{SERVICE}/ (flat)
|
|
101
|
+
"description": "Shared libraries (flat)"
|
|
102
|
+
},
|
|
103
|
+
"cli-platform-engineering": {
|
|
104
|
+
"stack_depth": -2, # cli-platform-engineering/{SERVICE}/ (flat)
|
|
105
|
+
"description": "CLI tools (flat)"
|
|
106
|
+
},
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
# Phase 2: Performance guardrails (Phase 3 optimization baseline)
|
|
110
|
+
MAX_SCAN_TIMEOUT_MS = 5000 # 5 seconds per root (warn if exceeded)
|
|
111
|
+
MAX_MANIFESTS_PER_ROOT = 50 # Warn if root has more manifests
|
|
112
|
+
|
|
113
|
+
# Autogenerated files directory (relative to this file's location)
|
|
114
|
+
PRODUCT_SNAPSHOT_DIR = "../../product_autogenerated_resource_manifests"
|
|
115
|
+
|
|
116
|
+
PRODUCT_SNAPSHOT_FILES = {
|
|
117
|
+
"services": "services.autogenerated.star",
|
|
118
|
+
"dependencies": "resource_dependencies.autogenerated.star",
|
|
119
|
+
"aliases": "resource_aliases.autogenerated.star",
|
|
120
|
+
"paths": "resource_paths.autogenerated.star",
|
|
121
|
+
"index": "index.autogenerated.star",
|
|
122
|
+
"readme": "README.autogenerated.md",
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
PRODUCT_TOPOLOGY_DIR = "../../product_autogenerated_services_list"
|
|
126
|
+
PRODUCT_STACKS_INDEX_FILE = "stacks.autogenerated.star"
|
|
127
|
+
PRODUCT_STACK_RESOURCES_FILE = "resources.autogenerated.star"
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# Deterministic Tilt Configuration for TDK Landscape
|
|
2
|
+
# Inspired by Mira Murati's "Defeating Nondeterminism" philosophy
|
|
3
|
+
# Goal: Same filesystem state + same environment = identical Tilt output
|
|
4
|
+
|
|
5
|
+
# =============================================================================
|
|
6
|
+
# DETERMINISTIC MODE SETTINGS
|
|
7
|
+
# =============================================================================
|
|
8
|
+
# Set TILT_DETERMINISTIC=true to enable strict deterministic mode
|
|
9
|
+
# This ensures "same input, same output" guarantees
|
|
10
|
+
# =============================================================================
|
|
11
|
+
|
|
12
|
+
# Read deterministic mode flag
|
|
13
|
+
_DETERMINISTIC_MODE = os.environ.get('TILT_DETERMINISTIC', 'false').lower() == 'true'
|
|
14
|
+
|
|
15
|
+
if _DETERMINISTIC_MODE:
|
|
16
|
+
print("🔒 DETERMINISTIC MODE ENABLED")
|
|
17
|
+
print(" └─ Same filesystem state + same environment = identical output")
|
|
18
|
+
print(" └─ All operations are ordered, reproducible, and invariant")
|
|
19
|
+
|
|
20
|
+
# =============================================================================
|
|
21
|
+
# DETERMINISTIC FILE DISCOVERY
|
|
22
|
+
# =============================================================================
|
|
23
|
+
|
|
24
|
+
def deterministic_find(path, pattern):
|
|
25
|
+
"""Deterministic file discovery - always returns sorted results.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
path: Directory to search
|
|
29
|
+
pattern: File pattern to match
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
Sorted list of files (alphabetical, cross-platform consistent)
|
|
33
|
+
"""
|
|
34
|
+
# Always use | sort to ensure alphabetical ordering
|
|
35
|
+
# This makes output invariant to filesystem ordering (ext4 vs APFS vs NTFS)
|
|
36
|
+
cmd = "find {} -type f -name '{}' 2>/dev/null | sort".format(path, pattern)
|
|
37
|
+
result = str(local(cmd, quiet=True, echo_off=True)).strip()
|
|
38
|
+
if result:
|
|
39
|
+
return result.split('\n')
|
|
40
|
+
return []
|
|
41
|
+
|
|
42
|
+
def deterministic_resource_discovery(scan_roots):
|
|
43
|
+
"""Deterministically discover resources across all scan roots.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
scan_roots: List of directories to scan for service.json files
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
Sorted list of resource paths (guaranteed order across runs)
|
|
50
|
+
"""
|
|
51
|
+
all_resources = []
|
|
52
|
+
|
|
53
|
+
# Process scan roots in fixed order (not parallel)
|
|
54
|
+
for root in sorted(scan_roots):
|
|
55
|
+
resources = deterministic_find(root, 'service.json')
|
|
56
|
+
all_resources.extend(resources)
|
|
57
|
+
|
|
58
|
+
# Final sort to ensure absolute ordering
|
|
59
|
+
return sorted(all_resources)
|
|
60
|
+
|
|
61
|
+
# =============================================================================
|
|
62
|
+
# DETERMINISTIC LOCAL EXECUTION
|
|
63
|
+
# =============================================================================
|
|
64
|
+
|
|
65
|
+
def deterministic_local(cmd, **kwargs):
|
|
66
|
+
"""Execute local command in deterministic mode.
|
|
67
|
+
|
|
68
|
+
In deterministic mode:
|
|
69
|
+
- Commands run sequentially (not parallel)
|
|
70
|
+
- Output is normalized (timestamps, PIDs, temp paths)
|
|
71
|
+
- Cache is used when available
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
cmd: Command to execute
|
|
75
|
+
**kwargs: Additional arguments for local()
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
Command output (normalized in deterministic mode)
|
|
79
|
+
"""
|
|
80
|
+
# Force quiet mode and no echo for determinism
|
|
81
|
+
kwargs['quiet'] = True
|
|
82
|
+
kwargs['echo_off'] = True
|
|
83
|
+
|
|
84
|
+
if _DETERMINISTIC_MODE:
|
|
85
|
+
# In deterministic mode, we could add:
|
|
86
|
+
# - Output normalization
|
|
87
|
+
# - Result caching
|
|
88
|
+
# - Strict ordering
|
|
89
|
+
pass
|
|
90
|
+
|
|
91
|
+
return local(cmd, **kwargs)
|
|
92
|
+
|
|
93
|
+
# =============================================================================
|
|
94
|
+
# DETERMINISTIC RESOURCE ORDERING
|
|
95
|
+
# =============================================================================
|
|
96
|
+
|
|
97
|
+
def sort_resources_by_name(resources):
|
|
98
|
+
"""Sort resources alphabetically for deterministic ordering.
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
resources: List of resource dictionaries or names
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
Sorted list (by name)
|
|
105
|
+
"""
|
|
106
|
+
if resources and isinstance(resources[0], dict):
|
|
107
|
+
return sorted(resources, key=lambda x: x.get('name', ''))
|
|
108
|
+
return sorted(resources)
|
|
109
|
+
|
|
110
|
+
# =============================================================================
|
|
111
|
+
# DETERMINISTIC ENVIRONMENT
|
|
112
|
+
# =============================================================================
|
|
113
|
+
|
|
114
|
+
def get_deterministic_env():
|
|
115
|
+
"""Get environment variables that affect determinism.
|
|
116
|
+
|
|
117
|
+
Returns:
|
|
118
|
+
Dict of environment variables that must be constant for reproducibility
|
|
119
|
+
"""
|
|
120
|
+
env_keys = [
|
|
121
|
+
'TILT_DETERMINISTIC',
|
|
122
|
+
'TILT_TRIGGER_MODE',
|
|
123
|
+
'MOCK_TIKKIE',
|
|
124
|
+
'INFISICAL_ENABLED',
|
|
125
|
+
'VERBOSE',
|
|
126
|
+
'AUTO_DISCOVER',
|
|
127
|
+
'TILT_MAX_PARALLEL_UPDATES',
|
|
128
|
+
]
|
|
129
|
+
return {k: os.environ.get(k, '') for k in env_keys}
|
|
130
|
+
|
|
131
|
+
def validate_deterministic_env():
|
|
132
|
+
"""Validate that environment is suitable for deterministic runs.
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
True if environment is deterministic, False otherwise
|
|
136
|
+
"""
|
|
137
|
+
if not _DETERMINISTIC_MODE:
|
|
138
|
+
return True
|
|
139
|
+
|
|
140
|
+
# Check for sources of nondeterminism
|
|
141
|
+
warnings = []
|
|
142
|
+
|
|
143
|
+
# Parallel updates can cause ordering differences
|
|
144
|
+
parallel = os.environ.get('TILT_MAX_PARALLEL_UPDATES', '')
|
|
145
|
+
if parallel and int(parallel) > 1:
|
|
146
|
+
warnings.append("TILT_MAX_PARALLEL_UPDATES > 1 may cause ordering differences")
|
|
147
|
+
|
|
148
|
+
# Auto trigger mode can cause timing-dependent behavior
|
|
149
|
+
if os.environ.get('TILT_TRIGGER_MODE', 'manual') != 'manual':
|
|
150
|
+
warnings.append("TILT_TRIGGER_MODE=auto may cause timing-dependent behavior")
|
|
151
|
+
|
|
152
|
+
if warnings:
|
|
153
|
+
print("⚠️ Deterministic mode warnings:")
|
|
154
|
+
for w in warnings:
|
|
155
|
+
print(" - {}".format(w))
|
|
156
|
+
|
|
157
|
+
return len(warnings) == 0
|
|
158
|
+
|
|
159
|
+
# =============================================================================
|
|
160
|
+
# DETERMINISTIC MANIFEST GENERATION
|
|
161
|
+
# =============================================================================
|
|
162
|
+
|
|
163
|
+
def deterministic_yaml_generation(resource_paths):
|
|
164
|
+
"""Generate YAML manifests deterministically from JSON manifests.
|
|
165
|
+
|
|
166
|
+
Args:
|
|
167
|
+
resource_paths: List of service.json paths
|
|
168
|
+
|
|
169
|
+
Returns:
|
|
170
|
+
List of generated/verified YAML paths
|
|
171
|
+
"""
|
|
172
|
+
yaml_paths = []
|
|
173
|
+
|
|
174
|
+
# Process in sorted order for determinism
|
|
175
|
+
for resource_json in sorted(resource_paths):
|
|
176
|
+
resource_dir = os.path.dirname(resource_json)
|
|
177
|
+
resource_yaml = os.path.join(resource_dir, 'service.yaml')
|
|
178
|
+
|
|
179
|
+
# Check if regeneration needed
|
|
180
|
+
needs_regen = False
|
|
181
|
+
if not os.path.exists(resource_yaml):
|
|
182
|
+
needs_regen = True
|
|
183
|
+
else:
|
|
184
|
+
# Compare modification times
|
|
185
|
+
json_stat = os.stat(resource_json)
|
|
186
|
+
yaml_stat = os.path.exists(resource_yaml) and os.stat(resource_yaml)
|
|
187
|
+
if yaml_stat and json_stat.st_mtime > yaml_stat.st_mtime:
|
|
188
|
+
needs_regen = True
|
|
189
|
+
|
|
190
|
+
yaml_paths.append(resource_yaml)
|
|
191
|
+
|
|
192
|
+
return sorted(yaml_paths)
|
|
193
|
+
|
|
194
|
+
# =============================================================================
|
|
195
|
+
# EXPORTS
|
|
196
|
+
# =============================================================================
|
|
197
|
+
|
|
198
|
+
DETERMINISTIC_EXPORTS = {
|
|
199
|
+
'deterministic_find': deterministic_find,
|
|
200
|
+
'deterministic_resource_discovery': deterministic_resource_discovery,
|
|
201
|
+
'deterministic_local': deterministic_local,
|
|
202
|
+
'sort_resources_by_name': sort_resources_by_name,
|
|
203
|
+
'get_deterministic_env': get_deterministic_env,
|
|
204
|
+
'validate_deterministic_env': validate_deterministic_env,
|
|
205
|
+
'deterministic_yaml_generation': deterministic_yaml_generation,
|
|
206
|
+
'DETERMINISTIC_MODE': _DETERMINISTIC_MODE,
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
print("📋 Deterministic Tilt utilities loaded")
|
|
210
|
+
if _DETERMINISTIC_MODE:
|
|
211
|
+
print(" └─ All operations will be ordered and reproducible")
|