89b4c118d1
src/gas/core/, src/gas_adapter_parts/의 모듈 소스를 clasp push 대상인 루트 .gs 번들(gas_lib.gs, gas_data_collect.gs, gas_data_feed.gs)로 해시 검증과 함께 생성한다. 번들 파일에는 "GENERATED — DO NOT EDIT MANUALLY" 헤더와 소스 해시를 새겨 수동 편집 드리프트를 방지한다. - build_gas_bundle_v1.py: 소스→번들 생성, 해시 헤더 삽입 - validate_gas_bundle_sync_v1.py: 번들이 현재 소스 해시와 일치하는지 검증 - audit_tools_thin_wrapper_v1.py: tools/ CLI가 핵심 로직 없이 thin wrapper로만 동작하는지 감사 - deploy_gas.py: 번들 빌드 파이프라인과 연동
79 lines
2.7 KiB
Python
79 lines
2.7 KiB
Python
#!/usr/bin/env python3
|
|
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import sys
|
|
from datetime import datetime, timezone, timedelta
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parent.parent
|
|
|
|
# Define source-to-bundle mapping
|
|
BUNDLES = {
|
|
"gas_lib.gs": [
|
|
"src/gas/core/gas_lib.gs"
|
|
],
|
|
"gas_data_collect.gs": [
|
|
"src/gas_adapter_parts/gdc_01_fetch_fundamentals.gs",
|
|
"src/gas_adapter_parts/gdc_02_account_satellite.gs"
|
|
],
|
|
"gas_data_feed.gs": [
|
|
"src/gas_adapter_parts/gdf_01_price_metrics.gs",
|
|
"src/gas_adapter_parts/gdf_02_harness_assembly.gs",
|
|
"src/gas_adapter_parts/gdf_03_portfolio_gates.gs",
|
|
"src/gas_adapter_parts/gdf_04_execution_quality.gs",
|
|
"src/gas_adapter_parts/gdf_05_alpha_engines.gs",
|
|
"src/gas_adapter_parts/gdf_06_rebalance.gs"
|
|
]
|
|
}
|
|
|
|
def get_now_kst() -> str:
|
|
kst = timezone(timedelta(hours=9))
|
|
return datetime.now(kst).strftime("%Y-%m-%d %H:%M:%S KST")
|
|
|
|
def compute_hash(contents: str) -> str:
|
|
return hashlib.sha256(contents.encode("utf-8")).hexdigest()
|
|
|
|
def build_bundles() -> int:
|
|
now_str = get_now_kst()
|
|
print(f"[build_gas_bundle] Started bundling at {now_str}")
|
|
|
|
for bundle_name, src_relative_paths in BUNDLES.items():
|
|
dst_path = ROOT / bundle_name
|
|
|
|
# Concatenate source file contents
|
|
concatenated_lines = []
|
|
for src_rel in src_relative_paths:
|
|
src_path = ROOT / src_rel
|
|
if not src_path.exists():
|
|
print(f"ERROR: Source file not found: {src_rel}")
|
|
return 1
|
|
|
|
content = src_path.read_text(encoding="utf-8")
|
|
concatenated_lines.append(f"// --- Source: {src_rel} ---")
|
|
concatenated_lines.append(content)
|
|
concatenated_lines.append("")
|
|
|
|
full_source_content = "\n".join(concatenated_lines)
|
|
source_hash = compute_hash(full_source_content)
|
|
|
|
# Build the bundled file content with the generated header
|
|
bundle_content = f"""// =========================================================================
|
|
// GENERATED BUNDLE - DO NOT EDIT THIS FILE MANUALLY
|
|
// Generated At: {now_str}
|
|
// Source Files: {", ".join(src_relative_paths)}
|
|
// Source Hash: {source_hash}
|
|
// =========================================================================
|
|
|
|
{full_source_content}"""
|
|
|
|
# Write to destination
|
|
dst_path.write_text(bundle_content, encoding="utf-8")
|
|
print(f" [build_gas_bundle] Generated bundle: {bundle_name} (Hash: {source_hash[:8]})")
|
|
|
|
print("[build_gas_bundle] All bundles generated successfully.")
|
|
return 0
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(build_bundles())
|