@tdk-landscape/tdk-cli-core 1.3.15 → 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/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 +59 -18
- 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/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,364 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# 🔧 TILT SDK - CORE UTILITIES MODULE
|
|
3
|
+
# =============================================================================
|
|
4
|
+
# Path: .tilt/topologies/tilt/common/utils.star
|
|
5
|
+
# Purpose: Foundational helper functions, constants, and shared API surface.
|
|
6
|
+
# =============================================================================
|
|
7
|
+
|
|
8
|
+
load('./utils_env.star',
|
|
9
|
+
'load_dotenv',
|
|
10
|
+
'validate_infisical_environment',
|
|
11
|
+
'should_enable',
|
|
12
|
+
)
|
|
13
|
+
load('./utils_debug.star',
|
|
14
|
+
'DEBUG_MODE',
|
|
15
|
+
'debug_log',
|
|
16
|
+
'inspect',
|
|
17
|
+
'breadcrumb',
|
|
18
|
+
'fail_with_context',
|
|
19
|
+
)
|
|
20
|
+
load('./utils_docker_networks.star',
|
|
21
|
+
_fix_docker_networks = 'fix_docker_networks',
|
|
22
|
+
_cleanup_docker_networks = 'cleanup_docker_networks',
|
|
23
|
+
)
|
|
24
|
+
load('./utils_output.star',
|
|
25
|
+
'print_resource_summary',
|
|
26
|
+
'get_template_header',
|
|
27
|
+
)
|
|
28
|
+
load('../../platform/docker/constants.star', 'PlatformDockerConstants')
|
|
29
|
+
|
|
30
|
+
# =============================================================================
|
|
31
|
+
# 📦 INTERNAL DEPENDENCY CONSTANTS
|
|
32
|
+
# =============================================================================
|
|
33
|
+
|
|
34
|
+
INTERNAL_SCOPE = PlatformDockerConstants.NPM_SCOPE
|
|
35
|
+
|
|
36
|
+
LIBRARY_ROOTS = {
|
|
37
|
+
'platform': 'shared-platform-engineering',
|
|
38
|
+
'product': 'shared-product-engineering',
|
|
39
|
+
'ddd': 'shared-ddd-layers',
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
DDD_LAYERS = ['domain', 'application', 'infrastructure', 'presentation']
|
|
43
|
+
|
|
44
|
+
# =============================================================================
|
|
45
|
+
# 📦 MIGRATED PACKAGES CONFIGURATION
|
|
46
|
+
# =============================================================================
|
|
47
|
+
# Map of package names that have been moved from their conventional locations
|
|
48
|
+
# to new paths. This allows the resolver to find packages at non-standard paths.
|
|
49
|
+
# Format: "package-name": ("path-relative-to-repo-root", "library-type")
|
|
50
|
+
# =============================================================================
|
|
51
|
+
|
|
52
|
+
MIGRATED_PACKAGES = {
|
|
53
|
+
# Introvertic packages reorganized into unified folder
|
|
54
|
+
"introvertic-core": ("shared-product-engineering/introvertic/core", "product"),
|
|
55
|
+
"introvertic-ui": ("shared-product-engineering/introvertic/ui", "product"),
|
|
56
|
+
"introvertic-docs": ("shared-product-engineering/introvertic/ui/docs", "product"),
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
# Import from canonical location to avoid duplication
|
|
60
|
+
load("../manifest/constants.star", "MANIFEST_FILENAME")
|
|
61
|
+
|
|
62
|
+
# List of all shared platform networks
|
|
63
|
+
# All networks use PROJECT_NAME format (e.g., beauty_crm_*)
|
|
64
|
+
PLATFORM_NETWORKS = [
|
|
65
|
+
PlatformDockerConstants.NETWORK_TRAEFIK_PUBLIC,
|
|
66
|
+
PlatformDockerConstants.PROJECT_NAME + "_traefik-private",
|
|
67
|
+
PlatformDockerConstants.NETWORK_BACKEND,
|
|
68
|
+
PlatformDockerConstants.NETWORK_DATABASE,
|
|
69
|
+
PlatformDockerConstants.NETWORK_INFISICAL,
|
|
70
|
+
PlatformDockerConstants.VERDACCIO_NETWORK,
|
|
71
|
+
PlatformDockerConstants.NETWORK_PROXY,
|
|
72
|
+
]
|
|
73
|
+
|
|
74
|
+
# =============================================================================
|
|
75
|
+
# 🔍 CENTRALIZED DEPENDENCY EXTRACTION (Single Source of Truth)
|
|
76
|
+
# =============================================================================
|
|
77
|
+
|
|
78
|
+
def get_internal_deps(resource_path):
|
|
79
|
+
"""
|
|
80
|
+
Extract all @tdk/* dependencies from a service's package.json.
|
|
81
|
+
"""
|
|
82
|
+
pkg_json_path = resource_path + '/package.json'
|
|
83
|
+
pkg_content = read_file(pkg_json_path, default='')
|
|
84
|
+
|
|
85
|
+
if not pkg_content or not str(pkg_content).strip():
|
|
86
|
+
return []
|
|
87
|
+
|
|
88
|
+
pkg = decode_json(pkg_content)
|
|
89
|
+
if not pkg:
|
|
90
|
+
return []
|
|
91
|
+
|
|
92
|
+
internal_deps = []
|
|
93
|
+
|
|
94
|
+
# Scan all dependency types in one pass
|
|
95
|
+
for dep_type in ['dependencies', 'devDependencies', 'peerDependencies']:
|
|
96
|
+
deps = pkg.get(dep_type, {})
|
|
97
|
+
for dep_name in deps.keys():
|
|
98
|
+
if dep_name.startswith(INTERNAL_SCOPE) and dep_name not in internal_deps:
|
|
99
|
+
internal_deps.append(dep_name)
|
|
100
|
+
|
|
101
|
+
return internal_deps
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def resolve_lib_path(package_name):
|
|
105
|
+
"""
|
|
106
|
+
Resolve @tdk/* package name to workspace path using naming conventions.
|
|
107
|
+
|
|
108
|
+
Checks MIGRATED_PACKAGES first for packages that have been moved from their
|
|
109
|
+
conventional locations, then falls back to standard naming conventions.
|
|
110
|
+
"""
|
|
111
|
+
if not package_name.startswith(INTERNAL_SCOPE):
|
|
112
|
+
return (None, None)
|
|
113
|
+
|
|
114
|
+
lib_name = package_name[len(INTERNAL_SCOPE):]
|
|
115
|
+
|
|
116
|
+
# Check migrated packages first (packages moved from conventional locations)
|
|
117
|
+
if lib_name in MIGRATED_PACKAGES:
|
|
118
|
+
return MIGRATED_PACKAGES[lib_name]
|
|
119
|
+
|
|
120
|
+
# Standard naming convention resolution
|
|
121
|
+
if lib_name in DDD_LAYERS:
|
|
122
|
+
return (LIBRARY_ROOTS['ddd'] + '/' + lib_name, 'ddd')
|
|
123
|
+
|
|
124
|
+
if lib_name.startswith('platform-'):
|
|
125
|
+
return (LIBRARY_ROOTS['platform'] + '/' + lib_name, 'platform')
|
|
126
|
+
|
|
127
|
+
if lib_name.startswith('product-'):
|
|
128
|
+
return (LIBRARY_ROOTS['product'] + '/' + lib_name, 'product')
|
|
129
|
+
|
|
130
|
+
return (LIBRARY_ROOTS['platform'] + '/' + lib_name, 'platform')
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def build_deps_mapping(resource_path, internal_deps=None):
|
|
134
|
+
"""Build a mapping of package_name -> library path for internal dependencies."""
|
|
135
|
+
if internal_deps == None:
|
|
136
|
+
internal_deps = get_internal_deps(resource_path)
|
|
137
|
+
|
|
138
|
+
mapping = {}
|
|
139
|
+
for dep_name in internal_deps:
|
|
140
|
+
lib_info = resolve_lib_path(dep_name)
|
|
141
|
+
lib_path = lib_info[0]
|
|
142
|
+
|
|
143
|
+
if lib_path:
|
|
144
|
+
mapping[dep_name] = lib_path
|
|
145
|
+
|
|
146
|
+
return mapping
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
# =============================================================================
|
|
150
|
+
# 🔍 VALIDATION FUNCTIONS
|
|
151
|
+
# =============================================================================
|
|
152
|
+
|
|
153
|
+
def validate_lib_naming(resource_path):
|
|
154
|
+
"""
|
|
155
|
+
Validate that package names in package.json match folder naming conventions.
|
|
156
|
+
"""
|
|
157
|
+
errors = []
|
|
158
|
+
internal_deps = get_internal_deps(resource_path)
|
|
159
|
+
|
|
160
|
+
for dep_name in internal_deps:
|
|
161
|
+
lib_info = resolve_lib_path(dep_name)
|
|
162
|
+
expected_path = lib_info[0]
|
|
163
|
+
|
|
164
|
+
if not expected_path:
|
|
165
|
+
continue
|
|
166
|
+
|
|
167
|
+
pkg_json = expected_path + '/package.json'
|
|
168
|
+
content = read_file(pkg_json, default='')
|
|
169
|
+
|
|
170
|
+
if not content or not str(content).strip():
|
|
171
|
+
errors.append({
|
|
172
|
+
'package': dep_name,
|
|
173
|
+
'expected_path': expected_path,
|
|
174
|
+
'error': 'Library folder not found at expected location',
|
|
175
|
+
})
|
|
176
|
+
continue
|
|
177
|
+
|
|
178
|
+
pkg = decode_json(content)
|
|
179
|
+
if pkg:
|
|
180
|
+
actual_name = pkg.get('name', '')
|
|
181
|
+
if actual_name != dep_name:
|
|
182
|
+
errors.append({
|
|
183
|
+
'package': dep_name,
|
|
184
|
+
'expected_path': expected_path,
|
|
185
|
+
'actual_name': actual_name,
|
|
186
|
+
'error': 'Package name mismatch: expected "' + dep_name + '" but found "' + actual_name + '"',
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
return errors
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def detect_circular_deps(resource_paths, max_depth=10):
|
|
193
|
+
"""
|
|
194
|
+
Detect circular dependencies between libraries.
|
|
195
|
+
"""
|
|
196
|
+
circular = []
|
|
197
|
+
visited_chains = {}
|
|
198
|
+
|
|
199
|
+
def check_chain(pkg_name, chain, depth):
|
|
200
|
+
if depth > max_depth:
|
|
201
|
+
return
|
|
202
|
+
|
|
203
|
+
if pkg_name in chain:
|
|
204
|
+
cycle_start = chain.index(pkg_name)
|
|
205
|
+
cycle = chain[cycle_start:] + [pkg_name]
|
|
206
|
+
cycle_str = ' -> '.join(cycle)
|
|
207
|
+
if cycle_str not in visited_chains:
|
|
208
|
+
visited_chains[cycle_str] = True
|
|
209
|
+
circular.append(cycle)
|
|
210
|
+
return
|
|
211
|
+
|
|
212
|
+
lib_info = resolve_lib_path(pkg_name)
|
|
213
|
+
lib_path = lib_info[0]
|
|
214
|
+
|
|
215
|
+
if not lib_path:
|
|
216
|
+
return
|
|
217
|
+
|
|
218
|
+
lib_deps = get_internal_deps(lib_path)
|
|
219
|
+
for dep in lib_deps:
|
|
220
|
+
check_chain(dep, chain + [pkg_name], depth + 1)
|
|
221
|
+
|
|
222
|
+
for resource_path in resource_paths:
|
|
223
|
+
deps = get_internal_deps(resource_path)
|
|
224
|
+
for dep in deps:
|
|
225
|
+
check_chain(dep, [], 0)
|
|
226
|
+
|
|
227
|
+
return circular
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def encode_json(obj, _depth=0):
|
|
231
|
+
"""
|
|
232
|
+
Simple JSON encoder for Starlark.
|
|
233
|
+
Supports: dict, list, string, int, bool, None
|
|
234
|
+
"""
|
|
235
|
+
# Prevent stack overflow from circular references or deeply nested data
|
|
236
|
+
if _depth > 50:
|
|
237
|
+
return '"<max-depth-exceeded>"'
|
|
238
|
+
|
|
239
|
+
if obj == None:
|
|
240
|
+
return 'null'
|
|
241
|
+
t = type(obj)
|
|
242
|
+
if t == 'string':
|
|
243
|
+
return '"' + obj.replace('\\', '\\\\').replace('"', '\\"').replace('\n', '\\n').replace('\r', '\\r').replace('\t', '\\t') + '"'
|
|
244
|
+
if t == 'int':
|
|
245
|
+
return str(obj)
|
|
246
|
+
if t == 'bool':
|
|
247
|
+
return 'true' if obj else 'false'
|
|
248
|
+
if t == 'list':
|
|
249
|
+
return '[' + ', '.join([encode_json(i, _depth + 1) for i in obj]) + ']'
|
|
250
|
+
if t == 'dict':
|
|
251
|
+
parts = []
|
|
252
|
+
sorted_keys = sorted(obj.keys())
|
|
253
|
+
for k in sorted_keys:
|
|
254
|
+
parts.append(encode_json(k, _depth + 1) + ': ' + encode_json(obj[k], _depth + 1))
|
|
255
|
+
return '{' + ', '.join(parts) + '}'
|
|
256
|
+
return '"' + str(obj) + '"'
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
# =============================================================================
|
|
260
|
+
# 📁 FILE I/O UTILITIES
|
|
261
|
+
# =============================================================================
|
|
262
|
+
|
|
263
|
+
def write_file_if_changed(file_path, content):
|
|
264
|
+
"""
|
|
265
|
+
Writes content to file only if it differs from existing content.
|
|
266
|
+
Uses Tilt's native read_file() - fast and silent.
|
|
267
|
+
|
|
268
|
+
If file_path is relative (doesn't start with /), it will be written relative
|
|
269
|
+
to the project root (TDK_PROJECT_ROOT env var) instead of Tilt working dir.
|
|
270
|
+
"""
|
|
271
|
+
if content == None:
|
|
272
|
+
content = ""
|
|
273
|
+
|
|
274
|
+
# For relative paths, prepend project root to ensure files go to correct location
|
|
275
|
+
if not file_path.startswith('/'):
|
|
276
|
+
project_root = os.environ.get('TDK_PROJECT_ROOT', '.')
|
|
277
|
+
# Remove leading ./ if present in file_path
|
|
278
|
+
clean_file_path = file_path[2:] if file_path.startswith('./') else file_path
|
|
279
|
+
file_path = project_root + '/' + clean_file_path
|
|
280
|
+
|
|
281
|
+
expected = str(content).rstrip()
|
|
282
|
+
existing_blob = read_file(file_path, default='')
|
|
283
|
+
existing = str(existing_blob).rstrip()
|
|
284
|
+
|
|
285
|
+
if existing == expected:
|
|
286
|
+
print("DEBUG WRITE: Skipping {} (no changes)".format(file_path))
|
|
287
|
+
return
|
|
288
|
+
|
|
289
|
+
dir_path = file_path.rsplit('/', 1)[0]
|
|
290
|
+
if not dir_path:
|
|
291
|
+
dir_path = '/'
|
|
292
|
+
safe_content = (expected + '\n').replace("'", "'\\''")
|
|
293
|
+
cmd = "mkdir -p '" + dir_path + "' && printf '%s' '" + safe_content + "' > '" + file_path + "'"
|
|
294
|
+
print("DEBUG WRITE: Writing {} bytes to {}".format(len(expected), file_path))
|
|
295
|
+
local(cmd, quiet=True, echo_off=True)
|
|
296
|
+
print("DEBUG WRITE: Completed {}".format(file_path))
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
# =============================================================================
|
|
300
|
+
# 🐳 DOCKER NETWORK MANAGEMENT
|
|
301
|
+
# =============================================================================
|
|
302
|
+
|
|
303
|
+
def fix_docker_networks():
|
|
304
|
+
return _fix_docker_networks(PLATFORM_NETWORKS)
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
def cleanup_docker_networks():
|
|
308
|
+
return _cleanup_docker_networks(PLATFORM_NETWORKS)
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
# =============================================================================
|
|
312
|
+
# 📦 Utils STRUCT - Public API for other modules
|
|
313
|
+
# =============================================================================
|
|
314
|
+
|
|
315
|
+
Utils = struct(
|
|
316
|
+
# Core extraction
|
|
317
|
+
get_internal_deps = get_internal_deps,
|
|
318
|
+
resolve_lib_path = resolve_lib_path,
|
|
319
|
+
build_deps_mapping = build_deps_mapping,
|
|
320
|
+
|
|
321
|
+
# Validation
|
|
322
|
+
validate_lib_naming = validate_lib_naming,
|
|
323
|
+
detect_circular_deps = detect_circular_deps,
|
|
324
|
+
|
|
325
|
+
# File I/O
|
|
326
|
+
write_file_if_changed = write_file_if_changed,
|
|
327
|
+
encode_json = encode_json,
|
|
328
|
+
|
|
329
|
+
# Environment
|
|
330
|
+
load_dotenv = load_dotenv,
|
|
331
|
+
validate_infisical_environment = validate_infisical_environment,
|
|
332
|
+
should_enable = should_enable,
|
|
333
|
+
|
|
334
|
+
# Debug utilities
|
|
335
|
+
debug_log = debug_log,
|
|
336
|
+
inspect = inspect,
|
|
337
|
+
breadcrumb = breadcrumb,
|
|
338
|
+
fail_with_context = fail_with_context,
|
|
339
|
+
DEBUG_MODE = DEBUG_MODE,
|
|
340
|
+
|
|
341
|
+
# Docker networks
|
|
342
|
+
fix_docker_networks = fix_docker_networks,
|
|
343
|
+
cleanup_docker_networks = cleanup_docker_networks,
|
|
344
|
+
|
|
345
|
+
# Resource summary
|
|
346
|
+
print_resource_summary = print_resource_summary,
|
|
347
|
+
|
|
348
|
+
# Template headers
|
|
349
|
+
get_template_header = get_template_header,
|
|
350
|
+
|
|
351
|
+
# Constants
|
|
352
|
+
INTERNAL_SCOPE = INTERNAL_SCOPE,
|
|
353
|
+
LIBRARY_ROOTS = LIBRARY_ROOTS,
|
|
354
|
+
DDD_LAYERS = DDD_LAYERS,
|
|
355
|
+
MANIFEST_FILENAME = MANIFEST_FILENAME,
|
|
356
|
+
PLATFORM_NETWORKS = PLATFORM_NETWORKS,
|
|
357
|
+
MIGRATED_PACKAGES = MIGRATED_PACKAGES,
|
|
358
|
+
)
|
|
359
|
+
|
|
360
|
+
CONSTANTS = {}
|
|
361
|
+
|
|
362
|
+
VALIDATION = {}
|
|
363
|
+
|
|
364
|
+
DEBUG = {}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# 🛠️ TILT SDK - DEBUG UTILITIES
|
|
3
|
+
# =============================================================================
|
|
4
|
+
|
|
5
|
+
DEBUG_MODE = os.environ.get('TILT_DEBUG', 'false').lower() in ['true', '1', 'yes']
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def debug_log(message, data=None):
|
|
9
|
+
"""
|
|
10
|
+
Standardized debug logger. Only prints if DEBUG_MODE is True.
|
|
11
|
+
"""
|
|
12
|
+
if DEBUG_MODE:
|
|
13
|
+
prefix = "DEBUG 🛠️ |"
|
|
14
|
+
if data:
|
|
15
|
+
print("{} {}: {}".format(prefix, message, data))
|
|
16
|
+
else:
|
|
17
|
+
print("{} {}".format(prefix, message))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def inspect(obj, label="Object"):
|
|
21
|
+
"""
|
|
22
|
+
Inspect a Starlark object's structure and available methods/attributes.
|
|
23
|
+
"""
|
|
24
|
+
debug_log("Inspecting {} - Type: {}".format(label, type(obj)))
|
|
25
|
+
|
|
26
|
+
if type(obj) == 'dict':
|
|
27
|
+
debug_log(" Keys", list(obj.keys()))
|
|
28
|
+
for key in obj.keys():
|
|
29
|
+
debug_log(" [{}]".format(key), obj[key])
|
|
30
|
+
elif type(obj) == 'list':
|
|
31
|
+
debug_log(" Length", len(obj))
|
|
32
|
+
for i, item in enumerate(obj):
|
|
33
|
+
debug_log(" [{}]".format(i), item)
|
|
34
|
+
else:
|
|
35
|
+
debug_log(" Available methods/attributes:")
|
|
36
|
+
for item in dir(obj):
|
|
37
|
+
print(" - {}".format(item))
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def breadcrumb(file_name, status="Loading"):
|
|
41
|
+
"""
|
|
42
|
+
Print a breadcrumb log to track file loading/execution.
|
|
43
|
+
"""
|
|
44
|
+
emoji_map = {
|
|
45
|
+
"Loading": "📍",
|
|
46
|
+
"Completed": "✅",
|
|
47
|
+
"Failed": "❌",
|
|
48
|
+
"Skipped": "⏭️",
|
|
49
|
+
}
|
|
50
|
+
emoji = emoji_map.get(status, "🔹")
|
|
51
|
+
print("{} {}: {}".format(emoji, status, file_name))
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def fail_with_context(message, context=None):
|
|
55
|
+
"""
|
|
56
|
+
Fail with a detailed error message and optional context data.
|
|
57
|
+
"""
|
|
58
|
+
error_msg = "\n" + ("=" * 79) + "\n"
|
|
59
|
+
error_msg += "❌ ERROR: {}\n".format(message)
|
|
60
|
+
|
|
61
|
+
if context:
|
|
62
|
+
error_msg += "\nContext:\n"
|
|
63
|
+
for key in context.keys():
|
|
64
|
+
error_msg += " - {}: {}\n".format(key, context[key])
|
|
65
|
+
|
|
66
|
+
error_msg += ("=" * 79) + "\n"
|
|
67
|
+
fail(error_msg)
|
|
68
|
+
|
|
69
|
+
DEBUG = {}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# 📋 DETERMINISTIC TILT UTILITIES
|
|
3
|
+
# =============================================================================
|
|
4
|
+
# Inspired by Mira Murati's "Defeating Nondeterminism" philosophy
|
|
5
|
+
# Goal: Same filesystem state + same environment = identical Tilt output
|
|
6
|
+
# =============================================================================
|
|
7
|
+
#
|
|
8
|
+
# Usage:
|
|
9
|
+
# load('ext://tdk-cli', 'deterministic_find', 'deterministic_local')
|
|
10
|
+
#
|
|
11
|
+
# files = deterministic_find('./services', 'service.json')
|
|
12
|
+
# result = deterministic_local('bun install')
|
|
13
|
+
# =============================================================================
|
|
14
|
+
|
|
15
|
+
# =============================================================================
|
|
16
|
+
# DETERMINISTIC MODE SETTINGS
|
|
17
|
+
# =============================================================================
|
|
18
|
+
# Set TILT_DETERMINISTIC=true to enable strict deterministic mode
|
|
19
|
+
# This ensures "same input, same output" guarantees
|
|
20
|
+
# =============================================================================
|
|
21
|
+
|
|
22
|
+
_DETERMINISTIC_MODE = os.environ.get('TILT_DETERMINISTIC', 'false').lower() == 'true'
|
|
23
|
+
|
|
24
|
+
def is_deterministic_mode():
|
|
25
|
+
"""Check if deterministic mode is enabled."""
|
|
26
|
+
return _DETERMINISTIC_MODE
|
|
27
|
+
|
|
28
|
+
if _DETERMINISTIC_MODE:
|
|
29
|
+
print("🔒 DETERMINISTIC MODE ENABLED")
|
|
30
|
+
print(" └─ Same filesystem state + same environment = identical output")
|
|
31
|
+
print(" └─ All operations are ordered, reproducible, and invariant")
|
|
32
|
+
|
|
33
|
+
# =============================================================================
|
|
34
|
+
# DETERMINISTIC FILE DISCOVERY
|
|
35
|
+
# =============================================================================
|
|
36
|
+
|
|
37
|
+
def deterministic_find(path, pattern):
|
|
38
|
+
"""Deterministic file discovery - always returns sorted results.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
path: Directory to search
|
|
42
|
+
pattern: File pattern to match
|
|
43
|
+
|
|
44
|
+
Returns:
|
|
45
|
+
Sorted list of files (alphabetical, cross-platform consistent)
|
|
46
|
+
"""
|
|
47
|
+
cmd = "find {} -type f -name '{}' 2>/dev/null | sort".format(path, pattern)
|
|
48
|
+
result = str(local(cmd, quiet=True, echo_off=True)).strip()
|
|
49
|
+
if result:
|
|
50
|
+
return result.split('\n')
|
|
51
|
+
return []
|
|
52
|
+
|
|
53
|
+
def deterministic_resource_discovery(scan_roots):
|
|
54
|
+
"""Deterministically discover services across all scan roots.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
scan_roots: List of directories to scan for service.json files
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
Sorted list of service paths (guaranteed order across runs)
|
|
61
|
+
"""
|
|
62
|
+
all_services = []
|
|
63
|
+
|
|
64
|
+
for root in sorted(scan_roots):
|
|
65
|
+
services = deterministic_find(root, 'service.json')
|
|
66
|
+
all_services.extend(services)
|
|
67
|
+
|
|
68
|
+
return sorted(all_services)
|
|
69
|
+
|
|
70
|
+
# =============================================================================
|
|
71
|
+
# DETERMINISTIC LOCAL EXECUTION
|
|
72
|
+
# =============================================================================
|
|
73
|
+
|
|
74
|
+
def deterministic_local(cmd, **kwargs):
|
|
75
|
+
"""Execute local command in deterministic mode.
|
|
76
|
+
|
|
77
|
+
In deterministic mode:
|
|
78
|
+
- Commands run sequentially (not parallel)
|
|
79
|
+
- Output is normalized (timestamps, PIDs, temp paths)
|
|
80
|
+
- Cache is used when available
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
cmd: Command to execute
|
|
84
|
+
**kwargs: Additional arguments for local()
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
Command output (normalized in deterministic mode)
|
|
88
|
+
"""
|
|
89
|
+
kwargs['quiet'] = True
|
|
90
|
+
kwargs['echo_off'] = True
|
|
91
|
+
|
|
92
|
+
return local(cmd, **kwargs)
|
|
93
|
+
|
|
94
|
+
# =============================================================================
|
|
95
|
+
# DETERMINISTIC RESOURCE ORDERING
|
|
96
|
+
# =============================================================================
|
|
97
|
+
|
|
98
|
+
def sort_resources_by_name(resources):
|
|
99
|
+
"""Sort resources alphabetically for deterministic ordering.
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
resources: List of resource dictionaries or names
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
Sorted list (by name)
|
|
106
|
+
"""
|
|
107
|
+
if resources and type(resources[0]) == "dict":
|
|
108
|
+
return sorted(resources, key=lambda x: x.get('name', ''))
|
|
109
|
+
return sorted(resources)
|
|
110
|
+
|
|
111
|
+
# =============================================================================
|
|
112
|
+
# DETERMINISTIC ENVIRONMENT
|
|
113
|
+
# =============================================================================
|
|
114
|
+
|
|
115
|
+
def get_deterministic_env():
|
|
116
|
+
"""Get environment variables that affect determinism.
|
|
117
|
+
|
|
118
|
+
Returns:
|
|
119
|
+
Dict of environment variables that must be constant for reproducibility
|
|
120
|
+
"""
|
|
121
|
+
env_keys = [
|
|
122
|
+
'TILT_DETERMINISTIC',
|
|
123
|
+
'TILT_TRIGGER_MODE',
|
|
124
|
+
'VERBOSE',
|
|
125
|
+
'AUTO_DISCOVER',
|
|
126
|
+
'TILT_MAX_PARALLEL_UPDATES',
|
|
127
|
+
]
|
|
128
|
+
return {k: os.environ.get(k, '') for k in env_keys}
|
|
129
|
+
|
|
130
|
+
def validate_deterministic_env():
|
|
131
|
+
"""Validate that environment is suitable for deterministic runs.
|
|
132
|
+
|
|
133
|
+
Returns:
|
|
134
|
+
True if environment is deterministic, False otherwise
|
|
135
|
+
"""
|
|
136
|
+
if not _DETERMINISTIC_MODE:
|
|
137
|
+
return True
|
|
138
|
+
|
|
139
|
+
warnings = []
|
|
140
|
+
|
|
141
|
+
parallel = os.environ.get('TILT_MAX_PARALLEL_UPDATES', '')
|
|
142
|
+
if parallel and int(parallel) > 1:
|
|
143
|
+
warnings.append("TILT_MAX_PARALLEL_UPDATES > 1 may cause ordering differences")
|
|
144
|
+
|
|
145
|
+
if os.environ.get('TILT_TRIGGER_MODE', 'manual') != 'manual':
|
|
146
|
+
warnings.append("TILT_TRIGGER_MODE=auto may cause timing-dependent behavior")
|
|
147
|
+
|
|
148
|
+
if warnings:
|
|
149
|
+
print("⚠️ Deterministic mode warnings:")
|
|
150
|
+
for w in warnings:
|
|
151
|
+
print(" - {}".format(w))
|
|
152
|
+
|
|
153
|
+
return len(warnings) == 0
|
|
154
|
+
|
|
155
|
+
# =============================================================================
|
|
156
|
+
# EXPORTS
|
|
157
|
+
# =============================================================================
|
|
158
|
+
|
|
159
|
+
Determinism = struct(
|
|
160
|
+
is_deterministic_mode=is_deterministic_mode,
|
|
161
|
+
deterministic_find=deterministic_find,
|
|
162
|
+
deterministic_resource_discovery=deterministic_resource_discovery,
|
|
163
|
+
deterministic_local=deterministic_local,
|
|
164
|
+
sort_resources_by_name=sort_resources_by_name,
|
|
165
|
+
get_deterministic_env=get_deterministic_env,
|
|
166
|
+
validate_deterministic_env=validate_deterministic_env,
|
|
167
|
+
DETERMINISTIC_MODE=_DETERMINISTIC_MODE,
|
|
168
|
+
)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# 🐳 TILT SDK - DOCKER NETWORK MANAGEMENT
|
|
3
|
+
# =============================================================================
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def fix_docker_networks(platform_networks):
|
|
7
|
+
"""
|
|
8
|
+
Generates a shell command that:
|
|
9
|
+
1. Removes networks with incorrect labels (if they exist and are not in use)
|
|
10
|
+
2. Creates all platform networks if they don't exist
|
|
11
|
+
"""
|
|
12
|
+
commands = []
|
|
13
|
+
commands.append('echo "Initializing Docker networks..."')
|
|
14
|
+
|
|
15
|
+
for network in platform_networks:
|
|
16
|
+
check_and_remove = '(docker network inspect ' + network + ' >/dev/null 2>&1 && '
|
|
17
|
+
check_and_remove += 'docker network inspect ' + network + ' --format "{{.Labels}}" | grep -q "com.docker.compose" && '
|
|
18
|
+
check_and_remove += 'echo "Removing network ' + network + ' with incorrect labels..." && '
|
|
19
|
+
check_and_remove += 'docker network rm ' + network + ' 2>/dev/null) || true'
|
|
20
|
+
commands.append(check_and_remove)
|
|
21
|
+
|
|
22
|
+
create_cmd = 'docker network create ' + network + ' 2>/dev/null && echo "Created network ' + network + '" || true'
|
|
23
|
+
commands.append(create_cmd)
|
|
24
|
+
|
|
25
|
+
commands.append('echo "Docker networks initialized"')
|
|
26
|
+
|
|
27
|
+
return ' && '.join(commands)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def cleanup_docker_networks(platform_networks):
|
|
31
|
+
"""
|
|
32
|
+
Generates a shell command to forcefully remove all platform networks.
|
|
33
|
+
WARNING: This will disconnect all containers from these networks first!
|
|
34
|
+
"""
|
|
35
|
+
commands = []
|
|
36
|
+
commands.append('echo "Cleaning up Docker networks..."')
|
|
37
|
+
|
|
38
|
+
for network in platform_networks:
|
|
39
|
+
disconnect_cmd = 'for c in $(docker network inspect ' + network + ' -f "{{range .Containers}}{{.Name}} {{end}}" 2>/dev/null); do '
|
|
40
|
+
disconnect_cmd += 'docker network disconnect -f ' + network + ' "$c" 2>/dev/null || true; done'
|
|
41
|
+
commands.append(disconnect_cmd)
|
|
42
|
+
commands.append('docker network rm ' + network + ' 2>/dev/null || true')
|
|
43
|
+
|
|
44
|
+
commands.append('echo "Docker networks cleaned up"')
|
|
45
|
+
|
|
46
|
+
return ' && '.join(commands)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# 🌍 TILT SDK - ENVIRONMENT UTILITIES
|
|
3
|
+
# =============================================================================
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def load_dotenv(project_root=''):
|
|
7
|
+
"""Load .env file into os.environ.
|
|
8
|
+
|
|
9
|
+
The Tiltfile lives in `.tdk/.tdk-out/`, so a bare `.env` lookup misses the
|
|
10
|
+
project-root file. Prefer an explicit project_root, then TDK_PROJECT_ROOT.
|
|
11
|
+
"""
|
|
12
|
+
if not project_root:
|
|
13
|
+
project_root = os.environ.get('TDK_PROJECT_ROOT', '')
|
|
14
|
+
env_path = (project_root + '/.env') if project_root else '.env'
|
|
15
|
+
content = str(local("cat '" + env_path + "' 2>/dev/null || true", quiet=True, echo_off=True))
|
|
16
|
+
if content:
|
|
17
|
+
for line in content.split('\n'):
|
|
18
|
+
line = line.strip()
|
|
19
|
+
if line and not line.startswith('#') and '=' in line:
|
|
20
|
+
key, value = line.split('=', 1)
|
|
21
|
+
os.environ[key.strip()] = value.strip().strip('"').strip("'")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def validate_infisical_environment():
|
|
25
|
+
"""Validate required Infisical environment variables are set."""
|
|
26
|
+
required_vars = ["INFISICAL_CLIENT_ID", "INFISICAL_CLIENT_SECRET", "INFISICAL_PROJECT_ID"]
|
|
27
|
+
missing_vars = [var for var in required_vars if not os.environ.get(var)]
|
|
28
|
+
if missing_vars:
|
|
29
|
+
fail("""
|
|
30
|
+
🛑 MISSING REQUIRED ENVIRONMENT VARIABLES FOR INFISICAL:
|
|
31
|
+
{missing_vars}
|
|
32
|
+
|
|
33
|
+
Please set these variables in your environment or .env file.
|
|
34
|
+
Example:
|
|
35
|
+
export INFISICAL_CLIENT_ID=your_client_id
|
|
36
|
+
export INFISICAL_CLIENT_SECRET=your_client_secret
|
|
37
|
+
export INFISICAL_PROJECT_ID=your_project_id
|
|
38
|
+
""".format(missing_vars=", ".join(missing_vars)))
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def should_enable(resource_name, cfg, defaults):
|
|
42
|
+
"""Check if a service should be enabled based on config and defaults."""
|
|
43
|
+
return cfg.get(resource_name, defaults.get(resource_name, False))
|