zenops 0.2.2

Declarative system configuration management for shell config and dotfiles.
Documentation
use std::fmt::Write as _;
use zenops_safe_relative_path::srpath;

use super::common::{
    StoredShellConfig, write_aliases, write_brew_llvm_flags, write_environment,
    write_path_variable, write_pkg_inits,
};
use crate::{
    config::{Config, pkg::Shell},
    config_files::{ConfigFilePath, ConfigFileSource, ConfigFiles},
    error::Error,
};

pub(in super::super) type StoredZshConfig = StoredShellConfig;

pub(super) fn make_config_files(
    shell_config: &StoredShellConfig,
    config: &Config,
    config_files: &mut ConfigFiles,
) -> Result<(), Error> {
    let StoredShellConfig { environment, alias } = shell_config;

    // ~/.zshenv — sourced for every shell invocation
    let mut zshenv = String::new();
    _ = writeln!(
        zshenv,
        "#\n# Zsh environment config generated by zenops\n#\n"
    );

    write_pkg_inits(&mut zshenv, &config.env_pkg_inits(Shell::Zsh));

    write_environment(&mut zshenv, environment);

    if let Some(path) = config.path_variable() {
        write_path_variable(&mut zshenv, &path);
    }

    if let Some(prefix) = config.brew_prefix()
        && config.has_brew_llvm()
    {
        write_brew_llvm_flags(&mut zshenv, prefix);
    }

    config_files.add(
        ConfigFilePath::in_home(srpath!(".zshenv")),
        ConfigFileSource::Generated(zshenv),
    );

    // ~/.zprofile — sourced for login shells (only when brew is installed)
    if let Some(prefix) = config.brew_prefix() {
        let mut zprofile = String::new();
        _ = writeln!(zprofile, "#\n# Zsh login profile generated by zenops\n#\n");
        _ = writeln!(
            zprofile,
            "# Homebrew environment (PATH, MANPATH, INFOPATH, fpath)"
        );
        _ = writeln!(
            zprofile,
            "eval \"$({}/bin/brew shellenv zsh)\"",
            prefix.display()
        );

        config_files.add(
            ConfigFilePath::in_home(srpath!(".zprofile")),
            ConfigFileSource::Generated(zprofile),
        );
    }

    // ~/.zshrc — sourced for interactive shells
    let mut zshrc = String::new();
    _ = writeln!(
        zshrc,
        "#\n# Zsh interactive config generated by zenops\n#\n"
    );

    _ = writeln!(zshrc, "# Initialize Zsh completions");
    _ = writeln!(zshrc, "autoload -Uz compinit && compinit");
    zshrc.push('\n');

    write_pkg_inits(&mut zshrc, &config.interactive_pkg_inits(Shell::Zsh));

    write_aliases(&mut zshrc, alias);

    config_files.add(
        ConfigFilePath::in_home(srpath!(".zshrc")),
        ConfigFileSource::Generated(zshrc),
    );

    Ok(())
}