Skip to content

fix: Dockerfile template substitution fails with multi-line profile installations#99

Open
b00y0h wants to merge 1 commit into
RchGrav:mainfrom
b00y0h:fix/profile-template-substitution
Open

fix: Dockerfile template substitution fails with multi-line profile installations#99
b00y0h wants to merge 1 commit into
RchGrav:mainfrom
b00y0h:fix/profile-template-substitution

Conversation

@b00y0h
Copy link
Copy Markdown

@b00y0h b00y0h commented Feb 12, 2026

Summary

  • Fix awk -v failing on multi-line $profile_installations values by switching to ENVIRON array, which correctly handles newlines and special characters
  • Fix guard check syntax broken in 634a40d (missing || between grep commands)

Root cause

awk -v pi="$profile_installations" does not support literal newlines in variable assignments. When profile functions return multi-line RUN commands containing &&, the substitution fails with awk: newline in string errors, leaving {{PROFILE_INSTALLATIONS}} placeholders in the generated Dockerfile.

The ENVIRON array reads variables from the process environment, which has no issues with newlines or special characters like &.

Before (broken)

RUN apt-get update {{PROFILE_INSTALLATIONS}}{{PROFILE_INSTALLATIONS}} apt-get install -y nginx {{PROFILE_INSTALLATIONS}}{{PROFILE_INSTALLATIONS}} apt-get clean

After (fixed)

RUN apt-get update && apt-get install -y nginx && apt-get clean

Test

profile_installations="# Python profile
RUN apt-get update && apt-get install -y nginx && apt-get clean"

# Using ENVIRON (this PR)
final=$(PI="$profile_installations" awk '
/\{\{[[:space:]]*PROFILE_INSTALLATIONS[[:space:]]*\}\}/ { print ENVIRON["PI"]; next }
{ print }
' <<<"{{PROFILE_INSTALLATIONS}}")

echo "$final"
# Output: correct multi-line content with && preserved

Fixes #91

Summary by Sourcery

Fix Dockerfile template substitution to correctly handle multi-line profile installation blocks and restore the guard that detects unreplaced placeholders.

Bug Fixes:

  • Resolve failure of Dockerfile template substitution when profile installations contain multi-line commands or special characters by switching awk variable injection to use environment variables.
  • Fix the placeholder guard condition so it properly detects remaining PROFILE_INSTALLATIONS or LABELS placeholders in the generated Dockerfile.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Feb 12, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Refactors the Dockerfile template substitution logic to pass profile installations and labels into awk via environment variables instead of -v (fixing multi-line handling) and corrects the guard that checks for unreplaced placeholders.

Sequence diagram for Dockerfile generation with ENVIRON-based substitution

sequenceDiagram
    participant User
    participant main_sh as main.sh
    participant Awk as awk
    participant Env as ENVIRON

    User->>main_sh: Invoke Dockerfile generation
    main_sh->>main_sh: Prepare base_dockerfile
    main_sh->>Env: Set PI=profile_installations
    main_sh->>Env: Set LBS=labels
    main_sh->>Awk: Execute awk with here-string base_dockerfile
    Awk->>Env: Read PI via ENVIRON[PI]
    Awk->>Env: Read LBS via ENVIRON[LBS]
    Awk->>Awk: For each line
    Awk-->>main_sh: Return final_dockerfile
    main_sh->>main_sh: grep for unreplaced placeholders
    alt Placeholders remain
        main_sh-->>User: error Unreplaced placeholders remain
    else All placeholders replaced
        main_sh->>main_sh: Write final_dockerfile to Dockerfile
        main_sh-->>User: Dockerfile generation successful
    end
Loading

File-Level Changes

Change Details Files
Switch awk variable passing to ENVIRON-based environment variables to properly handle multi-line profile_installations and labels.
  • Stop assigning base_dockerfile to final_dockerfile before substitution and instead capture awk output directly into final_dockerfile.
  • Replace awk -v pi and -v lbs arguments with environment variable exports PI and LBS before invoking awk.
  • Update awk script to read injected blocks from ENVIRON["PI"] and ENVIRON["LBS"] while preserving placeholder-matching regexes and passthrough behavior.
main.sh
Fix guard logic that verifies no unreplaced placeholders remain in the generated Dockerfile.
  • Correct the if condition to use a line continuation and

Assessment against linked issues

Issue Objective Addressed Explanation
#91 Ensure Dockerfile template substitution for {{PROFILE_INSTALLATIONS}} works correctly with multi-line profile installation commands so that container rebuilds succeed after adding profiles.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • The guard that checks for unreplaced placeholders only looks for the exact {{PROFILE_INSTALLATIONS}} and {{LABELS}} strings, but your awk pattern allows optional whitespace inside the braces, so you might want to update the grep patterns (e.g., use grep -E '\{\{[[:space:]]*PROFILE_INSTALLATIONS[[:space:]]*\}\}') to consistently catch all unreplaced forms.
  • Since you’re now relying on ENVIRON, consider briefly noting in a code comment that the PI= and LBS= prefixes are intentional and required for the awk ENVIRON lookup, so future changes don’t inadvertently switch back to -v or remove those environment assignments.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The guard that checks for unreplaced placeholders only looks for the exact `{{PROFILE_INSTALLATIONS}}` and `{{LABELS}}` strings, but your awk pattern allows optional whitespace inside the braces, so you might want to update the grep patterns (e.g., use `grep -E '\{\{[[:space:]]*PROFILE_INSTALLATIONS[[:space:]]*\}\}'`) to consistently catch all unreplaced forms.
- Since you’re now relying on ENVIRON, consider briefly noting in a code comment that the `PI=` and `LBS=` prefixes are intentional and required for the awk ENVIRON lookup, so future changes don’t inadvertently switch back to `-v` or remove those environment assignments.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@b00y0h b00y0h force-pushed the fix/profile-template-substitution branch from 64bbd58 to f0a7be5 Compare February 12, 2026 23:42
awk -v does not support literal newlines in variable assignments,
causing multi-line profile installations to fail with "newline in
string" errors. The && operators in RUN commands were also mangled
because & has special meaning in awk -v value processing.

Switch to ENVIRON array which correctly handles multi-line values
and special characters.

Also fix the guard check which was broken — the || between the two
grep commands was accidentally removed in 634a40d, causing grep to
interpret the second grep command as a filename argument.

Fixes RchGrav#91
@b00y0h b00y0h force-pushed the fix/profile-template-substitution branch from f0a7be5 to 6f2242d Compare February 12, 2026 23:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unable to rebuild container after adding profiles

1 participant