GAS 번들 빌드/동기화 파이프라인 추가
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: 번들 빌드 파이프라인과 연동
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
#!/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())
|
||||
Reference in New Issue
Block a user