Skip to content

feat: support custom placeholder delimiters via workload annotations#501

Open
Abhishek9639 wants to merge 1 commit into
score-spec:mainfrom
Abhishek9639:feat/custom-placeholder-delimiters
Open

feat: support custom placeholder delimiters via workload annotations#501
Abhishek9639 wants to merge 1 commit into
score-spec:mainfrom
Abhishek9639:feat/custom-placeholder-delimiters

Conversation

@Abhishek9639
Copy link
Copy Markdown
Contributor

Description

Adds opt-in support for custom placeholder delimiters in file content expansion, via two workload-level annotations under the existing compose.score.dev/experiment-* namespace. This is the experimental implementation of score-spec/spec#108. score-go is intentionally untouched, so the experiment lives entirely inside internal/compose and is cheap to walk away from if it doesn't pan out. That direction was agreed at the community meeting with @chris-stephenson.

What does this PR do?

Two new annotations:

  • compose.score.dev/experiment-placeholder-start
  • compose.score.dev/experiment-placeholder-end

When both are set on a workload, file content is expanded using the given delimiter pair instead of the default ${...} syntax. Both are required together. Setting only one of them, or leaving either value empty, produces a clear error up front. noExpand: true on a file still takes priority, and binaryContent is never expanded.

The substitution is done by a small unexported helper, substituteWithDelimiters, that builds a regex from regexp.QuoteMeta(start) + "(.*?)" + regexp.QuoteMeta(end) and runs ReplaceAllStringFunc. No escape mechanism in this version. Reasoning is on the parent issue: a doubled-prefix escape doesn't extend cleanly to asymmetric pairs like << / >> or <%{ / }%>, and a backslash escape was set aside until someone hits the problem in practice.

Example use case (Spring Boot properties, where literal ${...} needs to survive so Spring can resolve it at runtime):

apiVersion: score.dev/v1b1
metadata:
  name: spring-app
  annotations:
    compose.score.dev/experiment-placeholder-start: "<%{"
    compose.score.dev/experiment-placeholder-end: "}%>"
containers:
  app:
    image: my-spring-app
    files:
      - target: /app/application.properties
        content: |
          spring.datasource.url=jdbc:postgresql://${DB_HOST}:${DB_PORT}/${DB_NAME}
          app.name=<%{metadata.name}%>

Tests added for: annotation set with %{ }, asymmetric delimiters <%{ }%>, unset/default behaviour, noExpand priority, only-start error, only-end error, empty-value error. examples/03-files/README.md has a new section documenting the annotations.

Refs: score-spec/spec#108

Types of changes

  • New feature (non-breaking change which adds functionality)

Checklist

  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I've signed off with an email address that matches the commit author.

…core-compose

Signed-off-by: Abhishek <abhishekup082@gmail.com>
@Abhishek9639 Abhishek9639 force-pushed the feat/custom-placeholder-delimiters branch from a74e7ae to 3f60ddf Compare June 4, 2026 20:45
@Abhishek9639
Copy link
Copy Markdown
Contributor Author

Hey @chris-stephenson, @mathieu-benoit, opening this for review.

This is the score-compose-only implementation of score-spec/spec#108, following what we agreed at the meeting. score-go is intentionally untouched: the substitution is done by a small unexported helper inside internal/compose so the whole experiment lives in one place.

The behaviour matches what was in the closed score-go PR (score-spec/score-go#188) two annotations (-start / -end), both required together, validation on missing/empty values, noExpand: true still wins, binaryContent untouched. Tests cover the same cases.

If this works out in practice, we can revisit a proper score-go API later.

Could one of you approve the workflows so CI can run? First PR from me on this fork too.
Thanks!

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.

1 participant