///|
/// ~/.config/bit/bitconfig.toml のパスを解決
fn config_path() -> String? {
match @env.get_env_var("HOME") {
Some(home) => Some(home + "/.config/bit/bitconfig.toml")
None => None
}
}
///|
/// TOML テーブルから文字列値を取得
fn get_string(table : Map[String, @toml.TomlValue], key : String) -> String? {
guard table.get(key) is Some(@toml.TomlValue::TomlString(v)) else {
return None
}
Some(v)
}
///|
/// TOML テーブルから bool 値を取得し文字列に変換
fn get_bool_string(
table : Map[String, @toml.TomlValue],
key : String,
) -> String? {
guard table.get(key) is Some(@toml.TomlValue::TomlBoolean(v)) else {
return None
}
Some(if v { "true" } else { "false" })
}
///|
/// TOML テーブルからサブテーブルを取得
fn get_table(
table : Map[String, @toml.TomlValue],
key : String,
) -> Map[String, @toml.TomlValue]? {
guard table.get(key) is Some(@toml.TomlValue::TomlTable(t)) else {
return None
}
Some(t)
}
///|
/// 環境変数が未設定の場合のみ値を注入
fn inject_if_unset(env_key : String, value : String) -> Unit {
match @env.get_env_var(env_key) {
Some(existing) if existing.length() > 0 => () // 既存値を優先
_ => @env.set_env_var(env_key, value)
}
}
///|
/// ~ をホームディレクトリに展開
fn expand_home(path : String, home : String) -> String {
if path.has_prefix("~/") {
let rest = String::unsafe_substring(path, start=1, end=path.length())
home + rest
} else {
path
}
}
///|
/// [bit] セクション配下の設定を環境変数に注入
fn inject_from_bit_table(
bit : Map[String, @toml.TomlValue],
home : String,
) -> Unit {
// [bit.user]
if get_table(bit, "user") is Some(user) {
if get_string(user, "sender") is Some(v) {
inject_if_unset("BIT_RELAY_SENDER", v)
}
if get_string(user, "github_username") is Some(v) {
inject_if_unset("BIT_GITHUB_USERNAME", v)
}
}
// [bit.relay]
if get_table(bit, "relay") is Some(relay) {
if get_string(relay, "url") is Some(v) {
inject_if_unset("BIT_RELAY_URL", v)
}
if get_string(relay, "auth_token") is Some(v) {
inject_if_unset("BIT_RELAY_AUTH_TOKEN", v)
}
}
// [bit.key]
if get_table(bit, "key") is Some(key) {
if get_string(key, "private_key_file") is Some(v) {
inject_if_unset("BIT_RELAY_SIGN_PRIVATE_KEY_FILE", expand_home(v, home))
}
if get_string(key, "public_key") is Some(v) {
inject_if_unset("BIT_RELAY_SIGN_PUBLIC_KEY", v)
}
}
// [bit.serve]
if get_table(bit, "serve") is Some(serve) {
if get_bool_string(serve, "allow_push") is Some(v) {
inject_if_unset("BIT_SERVE_ALLOW_PUSH", v)
}
if get_bool_string(serve, "broadcast") is Some(v) {
inject_if_unset("BIT_SERVE_BROADCAST", v)
}
if get_bool_string(serve, "auto_fetch") is Some(v) {
inject_if_unset("BIT_SERVE_AUTO_FETCH", v)
}
if get_string(serve, "room") is Some(v) {
inject_if_unset("BIT_SERVE_ROOM", v)
}
}
// [bit.hub]
if get_table(bit, "hub") is Some(hub) {
if get_string(hub, "conflict_policy") is Some(v) {
inject_if_unset("BIT_HUB_CONFLICT_POLICY", v)
}
if get_string(hub, "collab_sign_key") is Some(v) {
inject_if_unset("BIT_COLLAB_SIGN_KEY", v)
}
if get_bool_string(hub, "require_signed") is Some(v) {
inject_if_unset("BIT_COLLAB_REQUIRE_SIGNED", v)
}
}
}
///| TOML 設定を読み込み、未設定の環境変数に注入する。
///|
/// エラーは静かに無視する(設定ファイルはオプション)。
pub fn load_and_inject() -> Unit {
let path = match config_path() {
Some(p) => p
None => return
}
if !@fs.path_exists(path) {
return
}
let content = @fs.read_file_to_string(path) catch { _ => return }
let root = @toml.parse(content) catch { _ => return }
guard root is @toml.TomlValue::TomlTable(top) else { return }
let home = @env.get_env_var("HOME").unwrap_or("")
// [bit.*] セクションから bit 固有の設定を注入
if get_table(top, "bit") is Some(bit) {
inject_from_bit_table(bit, home)
}
}