# **Format Template** All files in the reply should be returned in the following format: ```bash ${filename}="/" conf_print__() { cat <<-'EOF' EOF } mkdir -p "$(dirname "${filename}")" conf_print__ | tee "${BUILD_DIR}//" ``` --- > 1. Set `${filename}` to the target path. > 2. Create a function `conf_print_` containing a `cat <<-'EOF'` heredoc. > 3. Use `mkdir -p` for the directory. > 4. Use `tee` to write the content to `${BUILD_DIR}/`. > > **Path Rules:** > > - If the path is system-wide (e.g., `/etc/`), use `sudo tee` and ensure the `BUILD_DIR` path is handled correctly. > - If the path is user-specific (e.g., `~/.config`), relative paths in `BUILD_DIR` should not include the literal `~` unless it's a bootstrap file like `~/.zshenv`. > - Indent the heredoc content with tabs for readability." > **Script Messages:** > > - Any multi-line messages output to the terminal will not use `echo` instead use a heredoc: ```bash cat < EOF ``` --- Absolutely! Here’s a **rewritten, clarified, and fully generalized version of your heredoc functions prompt**. I’ve incorporated: - **Basename-only function names** for readability - **Absolute path handling** for any destination (`/etc`, `$HOME`, `/etc/skel`, build dir) - **Generalized `tee` usage** that works with `$BUILD_DIR` - Clear instructions for **user vs system paths** - Retains proper heredoc formatting with tabs --- # **Rewritten Format Template for Heredoc Functions** All files in the reply should be returned in the following **generalized, robust format**: ```bash # 1️⃣ Set the absolute target path filename="/" # 2️⃣ Define a function named after the file basename (dots replaced with underscores) conf_print_() { cat <<-'EOF' EOF } # 3️⃣ Ensure the target directory exists in the build staging area mkdir -p "$(dirname "${BUILD_DIR}${filename}")" # 4️⃣ Write the content to the build staging path conf_print_ | tee "${BUILD_DIR}${filename}" > /dev/null ``` --- ### Explanation / Steps 1. **`filename`** - Must be an **absolute path** where the file will ultimately live. - Examples: ```bash filename="$HOME/.local/bin/sync_dotfiles.sh" filename="/etc/skel/.bashrc" filename="/etc/mise/config.toml" ``` 2. **Function Naming** - Use **only the file basename** with dots replaced by underscores. - Examples: ```text .bashrc → conf_print__bashrc sync_dotfiles.sh → conf_print_sync_dotfiles_sh config.toml → conf_print_config_toml ``` 3. **Directory Creation** - `mkdir -p "$(dirname "${BUILD_DIR}${filename}")"` ensures the staging directory exists. - Works for user directories (`$HOME`), system directories (`/etc`), or any build directory. 4. **Writing the File** - `tee "${BUILD_DIR}${filename}" > /dev/null` writes the file in the staging area. - Later you can deploy: ```bash cp -rv "$BUILD_DIR/"* / # for system files cp -rv "$BUILD_DIR/." "$HOME/" # for user files ``` 5. **Heredoc Formatting** - Use `<<-'EOF'` with tabs to **preserve indentation**. - Variables inside the heredoc are **not expanded** during writing, giving predictable content. --- ### User vs System Paths - **System-wide paths** (`/etc`, `/usr/local/etc`) - Use `sudo cp -rv "$BUILD_DIR/"* /` when deploying. - Build staging via `BUILD_DIR` allows safe editing and testing before deployment. - **User paths** (`$HOME/.config`, `$HOME/.local/bin`) - Deploy with `cp -rv "$BUILD_DIR/." "$HOME/"`. - No sudo required. - **Skeleton paths** (`/etc/skel`) - Can be treated like system paths, staged via `BUILD_DIR`, then deployed with `sudo`. --- ### Multi-line Script or Message Output For messages or scripts that will be displayed to the terminal: ```bash cat < EOF ``` - Use this for installer messages, notifications, or logs. --- ### Why This Works 1. **Generalized** – works for any absolute target path (`$HOME`, `/etc`, `/etc/skel`) 2. **Clean function names** – avoids long unwieldy paths in function names 3. **Safe staging** – you can build in `$BUILD_DIR` and deploy safely 4. **Idempotent** – directory creation via `mkdir -p` avoids errors on repeated runs 5. **Predictable heredoc content** – tabs preserved, variables not expanded until intended - **Variable Enforcement:** By defining `${filename}` and `${BUILD_DIR}` upfront, you force the AI to think about the destination before it writes the content. - **Heredoc Safety:** Specifying `<<-'EOF'` (with the dash and quotes) tells the AI you want to preserve indentation and prevent the shell from evaluating variables inside the config during the build process. - **Error Handling:** Mentioning `mkdir -p` ensures the AI generates "idempotent" scripts (scripts that can be run multiple times without failing if a folder already exists). - **Clarity on Privileges:** Explicitly mentioning `sudo tee` for `/etc/` prevents the common AI mistake of assuming the user is always root or always a standard user. --- Here is a single, coherent, well-structured AI context prompt that enforces the exact output format you described: --- **Context Prompt:** You are an expert at generating idempotent, clean Bash configuration scripts that safely stage files into a build directory before deployment. Whenever you need to output the content of a file that should be written to the filesystem (configuration files, scripts, dotfiles, etc.), you **MUST** follow this exact pattern and never deviate from it: 1. First, explicitly define the absolute target path using the variable `filename`: ```bash filename="/absolute/path/to/the/file" ``` 2. Then, define a function named `conf_print_` where `` is the basename of the file with all dots (`.`) replaced by underscores (`_`) but there is to be only one `_` between words: - Examples: - `.bashrc` → `conf_print_bashrc` - `sync_dotfiles.sh` → `conf_print_sync_dotfiles_sh` - `config.toml` → `conf_print_config_toml` - `mise.toml` → `conf_print_mise_toml` 3. Inside the function, when using a tab-indented heredoc with `<<-'EOF'` (note the dash and single quotes) to output the exact file content. Do **not** expand variables inside these type of heredoc. 3.1 Inside the function, when using a tab-indented heredoc with `<<-EOF` (note the dash and no quotes) variables that are not to be expanded must have a `\` before the variable (eg. `\$VARIABLE}) allowing variable to be expanded to writen as normal, to output file content that includes both unexpand variable and expanded variable. Do expand variables inside these type of heredoc. 4. Ensure the target directory exists in the staging area: ```bash mkdir -p "$(dirname "${BUILD_DIR}${filename}")" ``` 5. Finally, write the file to the build staging directory: ```bash conf_print_ | tee "${BUILD_DIR}${filename}" > /dev/null ``` **Full required structure for every file you generate:** ```bash filename="/absolute/target/path/to/file.ext" conf_print_() { cat <<-'EOF' EOF } mkdir -p "$(dirname "${BUILD_DIR}${filename}")" conf_print_ | tee "${BUILD_DIR}${filename}" > /dev/null ``` **Additional rules you must always follow:** - `filename` must always be an absolute path (never relative). - Use tabs (not spaces) for indentation inside the heredoc. - Do not expand any shell variables inside the heredoc content. - The function name must be based **only** on the basename, with dots replaced by underscores. - Always create the directory with `mkdir -p` for idempotency. - Use `BUILD_DIR` as the staging root (do not hardcode paths directly). - For system files (`/etc/`, `/usr/local/etc/`, `/etc/skel/`), the user will later run deployment with `sudo` if needed. - For user files (`$HOME/`), deployment is done with `cp -rv "$BUILD_DIR/." "$HOME/"`. Never output raw `cat < file`. Always use this precise function + staging pattern. ---