hyf

Context-aware query service for Radroots
git clone https://radroots.dev/git/hyf.git
Log | Files | Refs | README | LICENSE

commit bf5114b28674e28c465e5c3e43c1f78d660d765e
parent 22253d833097dd81edbcea1121097906f6d580f5
Author: triesap <tyson@radroots.org>
Date:   Thu,  9 Apr 2026 16:58:27 +0000

runtime: resolve hyf startup paths

Diffstat:
Asrc/hyf_runtime/env.mojo | 30++++++++++++++++++++++++++++++
Asrc/hyf_runtime/startup.mojo | 136+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/main.mojo | 3+++
Mtests/test_runtime_paths.mojo | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 263 insertions(+), 0 deletions(-)

diff --git a/src/hyf_runtime/env.mojo b/src/hyf_runtime/env.mojo @@ -0,0 +1,30 @@ +from std.os import getenv + +from hyf_runtime.profile import interactive_user_profile + + +comptime _HYF_PATHS_PROFILE_ENV = "HYF_PATHS_PROFILE" +comptime _HYF_PATHS_REPO_LOCAL_ROOT_ENV = "HYF_PATHS_REPO_LOCAL_ROOT" + + +def hyf_paths_profile_env_name() -> String: + return _HYF_PATHS_PROFILE_ENV + + +def hyf_paths_repo_local_root_env_name() -> String: + return _HYF_PATHS_REPO_LOCAL_ROOT_ENV + + +def configured_paths_profile_from_env() -> String: + var value = getenv(_HYF_PATHS_PROFILE_ENV, "") + if value != "": + return value + return interactive_user_profile() + + +def configured_repo_local_root_from_env() -> String: + return getenv(_HYF_PATHS_REPO_LOCAL_ROOT_ENV, "") + + +def configured_user_home_from_env() -> String: + return getenv("HOME", "") diff --git a/src/hyf_runtime/startup.mojo b/src/hyf_runtime/startup.mojo @@ -0,0 +1,136 @@ +from std.collections import List +from std.sys import argv + +from hyf_runtime.env import ( + configured_paths_profile_from_env, + configured_repo_local_root_from_env, + configured_user_home_from_env, +) +from hyf_runtime.errors import raise_runtime_contract_error +from hyf_runtime.paths import RuntimePaths, hyf_runtime_paths_for_unix_profile + + +@fieldwise_init +struct RuntimeStartupContext(Copyable, Movable): + var paths_profile: String + var repo_local_base_root: String + var user_home: String + var paths: RuntimePaths + + +@fieldwise_init +struct RuntimeStartupInput(Copyable, Movable): + var env_paths_profile: String + var env_repo_local_base_root: String + var user_home: String + var argv: List[String] + + +@fieldwise_init +struct _StartupOverrides(Copyable, Movable): + var paths_profile: String + var repo_local_base_root: String + + +def _require_flag_value( + args: List[String], value_index: Int, flag_name: String +) raises -> String: + if value_index >= len(args): + raise_runtime_contract_error(flag_name + " requires a value") + var value = String(String(args[value_index]).strip()) + if value == "": + raise_runtime_contract_error(flag_name + " requires a non-empty value") + if value.startswith("-"): + raise_runtime_contract_error( + flag_name + " value must not be another flag" + ) + return value^ + + +def _parse_startup_overrides(args: List[String]) raises -> _StartupOverrides: + var overrides = _StartupOverrides(paths_profile="", repo_local_base_root="") + var index = 0 + while index < len(args): + var arg = String(args[index]) + + if arg == "--paths-profile": + overrides.paths_profile = _require_flag_value( + args, index + 1, "--paths-profile" + ) + index += 2 + continue + + if arg.startswith("--paths-profile="): + overrides.paths_profile = String( + arg[byte = len("--paths-profile=") :] + ) + if overrides.paths_profile == "": + raise_runtime_contract_error("--paths-profile requires a value") + index += 1 + continue + + if arg == "--repo-local-root": + overrides.repo_local_base_root = _require_flag_value( + args, index + 1, "--repo-local-root" + ) + index += 2 + continue + + if arg.startswith("--repo-local-root="): + overrides.repo_local_base_root = String( + arg[byte = len("--repo-local-root=") :] + ) + if overrides.repo_local_base_root == "": + raise_runtime_contract_error( + "--repo-local-root requires a value" + ) + index += 1 + continue + + raise_runtime_contract_error("unknown startup argument '" + arg + "'") + + return overrides^ + + +def resolve_startup_context( + input: RuntimeStartupInput, +) raises -> RuntimeStartupContext: + var profile = String(input.env_paths_profile) + if profile == "": + raise_runtime_contract_error("env paths profile must not be empty") + + var repo_local_base_root = String(input.env_repo_local_base_root) + var overrides = _parse_startup_overrides(input.argv) + if overrides.paths_profile != "": + profile = String(overrides.paths_profile) + if overrides.repo_local_base_root != "": + repo_local_base_root = String(overrides.repo_local_base_root) + + var paths = hyf_runtime_paths_for_unix_profile( + profile, input.user_home, repo_local_base_root + ) + return RuntimeStartupContext( + paths_profile=profile, + repo_local_base_root=repo_local_base_root, + user_home=String(input.user_home), + paths=paths^, + ) + + +def process_startup_args() -> List[String]: + var raw_args = argv() + var args = List[String]() + for index in range(1, len(raw_args)): + args.append(String(raw_args[index])) + return args^ + + +def resolve_startup_context_from_process() raises -> RuntimeStartupContext: + return resolve_startup_context( + RuntimeStartupInput( + env_paths_profile=configured_paths_profile_from_env(), + env_repo_local_base_root=configured_repo_local_root_from_env(), + user_home=configured_user_home_from_env(), + argv=process_startup_args(), + ) + ) diff --git a/src/main.mojo b/src/main.mojo @@ -1,5 +1,8 @@ +from hyf_runtime.startup import resolve_startup_context_from_process from hyf_stdio.server import run_stdio_server def main() raises: + var startup_context = resolve_startup_context_from_process() + _ = startup_context.paths.config_path run_stdio_server() diff --git a/tests/test_runtime_paths.mojo b/tests/test_runtime_paths.mojo @@ -1,10 +1,16 @@ +from std.collections import List from std.testing import TestSuite, assert_equal, assert_raises +from hyf_runtime.env import ( + hyf_paths_profile_env_name, + hyf_paths_repo_local_root_env_name, +) from hyf_runtime.paths import ( hyf_runtime_paths_for_unix_profile, runtime_paths_for_namespace, ) from hyf_runtime.roots import runtime_roots_from_base_root +from hyf_runtime.startup import RuntimeStartupInput, resolve_startup_context def test_runtime_paths_repo_local_contract_vector() raises: @@ -80,5 +86,93 @@ def test_runtime_paths_reject_invalid_profile_namespace_and_base_root() raises: ) +def _startup_argv() -> List[String]: + return List[String]() + + +def _startup_argv2(first: String, second: String) -> List[String]: + var args = List[String]() + args.append(first) + args.append(second) + return args^ + + +def test_runtime_env_contract_names_are_frozen() raises: + assert_equal(hyf_paths_profile_env_name(), "HYF_PATHS_PROFILE") + assert_equal( + hyf_paths_repo_local_root_env_name(), "HYF_PATHS_REPO_LOCAL_ROOT" + ) + + +def test_startup_context_defaults_from_env_and_home() raises: + var context = resolve_startup_context( + RuntimeStartupInput( + env_paths_profile="interactive_user", + env_repo_local_base_root="", + user_home="/home/hyf-test", + argv=_startup_argv(), + ) + ) + + assert_equal(context.paths_profile, "interactive_user") + assert_equal( + context.paths.config_path, + "/home/hyf-test/.radroots/config/services/hyf/config.toml", + ) + + +def test_startup_context_cli_flags_override_env() raises: + var context = resolve_startup_context( + RuntimeStartupInput( + env_paths_profile="service_host", + env_repo_local_base_root="", + user_home="/home/ignored", + argv=_startup_argv2( + "--paths-profile=repo_local", + "--repo-local-root=/tmp/hyf-runtime", + ), + ) + ) + + assert_equal(context.paths_profile, "repo_local") + assert_equal(context.repo_local_base_root, "/tmp/hyf-runtime") + assert_equal( + context.paths.config_path, + "/tmp/hyf-runtime/config/services/hyf/config.toml", + ) + + +def test_startup_context_rejects_missing_root_unknown_flag_and_flag_as_value() raises: + with assert_raises(): + _ = resolve_startup_context( + RuntimeStartupInput( + env_paths_profile="repo_local", + env_repo_local_base_root="", + user_home="/home/ignored", + argv=_startup_argv(), + ) + ) + + with assert_raises(): + _ = resolve_startup_context( + RuntimeStartupInput( + env_paths_profile="interactive_user", + env_repo_local_base_root="", + user_home="/home/ignored", + argv=_startup_argv2("--profile", "repo_local"), + ) + ) + + with assert_raises(): + _ = resolve_startup_context( + RuntimeStartupInput( + env_paths_profile="interactive_user", + env_repo_local_base_root="", + user_home="/home/ignored", + argv=_startup_argv2("--paths-profile", "--repo-local-root"), + ) + ) + + def main() raises: TestSuite.discover_tests[__functions_in_module()]().run()