Skip to content

feat: use GetFiles for --patch-templates to support local directories#469

Merged
mathieu-benoit merged 2 commits into
score-spec:mainfrom
Venkatesh1505:feat/patch-templates-folder-support
Apr 16, 2026
Merged

feat: use GetFiles for --patch-templates to support local directories#469
mathieu-benoit merged 2 commits into
score-spec:mainfrom
Venkatesh1505:feat/patch-templates-folder-support

Conversation

@Venkatesh1505
Copy link
Copy Markdown
Contributor

@Venkatesh1505 Venkatesh1505 commented Apr 16, 2026

Description

The --patch-templates flag in score-compose init used uriget.GetFile which only supports single file URIs. This change replaces it with uriget.GetFiles, which additionally supports passing a local directory path to load all patch template files from it at once.

This mirrors the same change already done for the --provisioners flag in PR #465

Related issue: score-spec/score-go#177

What does this PR do?

Enables --patch-templates to accept a local directory path, loading all files within it as patch templates. Previously, only individual file paths and remote URIs were supported.

All existing behavior (single file, remote URI, stdin) remains unchanged.

Testing evidence

Single file:

./score-compose init --no-sample --patch-templates ../community-patchers/score-compose/unprivileged.tpl
INFO: Fetching patch template from ../community-patchers/score-compose/unprivileged.tpl
INFO: Read 330 bytes from ../community-patchers/score-compose/unprivileged.tpl
INFO: Writing new state directory '.score-compose'
INFO: Writing new state directory '.score-compose' with project name 'score-compose'
INFO: Writing default provisioners file
INFO: Found existing Score file './score.yaml'
INFO: Read more about the Score specification at https://docs.score.dev/docs/

state.yaml

yq '.patching_templates' .score-compose/state.yaml
- |
  {{ range $name, $spec := .Workloads }}
  {{ range $cname, $_ := $spec.containers }}
  - op: set
    path: services.{{ $name }}-{{ $cname }}.read_only
    value: true
  - op: set
    path: services.{{ $name }}-{{ $cname }}.user
    value: "65532"
  - op: set
    path: services.{{ $name }}-{{ $cname }}.cap_drop
    value: ["ALL"]
  {{ end }}
  {{ end }}

Directory:

./score-compose init --no-sample --patch-templates ../community-patchers/score-compose
INFO: Fetching patch template from ../community-patchers/score-compose
INFO: Read 1313 bytes from ../community-patchers/score-compose/dapr.tpl
INFO: Read 300 bytes from ../community-patchers/score-compose/microcks.tpl
INFO: Read 307 bytes from ../community-patchers/score-compose/ollama.tpl
INFO: Read 330 bytes from ../community-patchers/score-compose/unprivileged.tpl
INFO: Writing new state directory '.score-compose'
INFO: Writing new state directory '.score-compose' with project name 'score-compose'
INFO: Writing default provisioners file
INFO: Found existing Score file './score.yaml'
INFO: Read more about the Score specification at https://docs.score.dev/docs/

state.yaml

yq '.patching_templates' .score-compose/state.yaml
- |
  - op: set
    path: services.placement
    value:
      image: ghcr.io/dapr/placement:latest
      command: ["./placement", "--port", "50006"]
      ports:
      - target: 50006
        published: "50006"
  - op: set
    path: services.scheduler
    value:
      image: ghcr.io/dapr/scheduler:latest
      command: ["./scheduler", "--port", "50007", "--etcd-data-dir", "/data"]
      ports:
      - target: 50007
        published: "50007"
      user: root
      volumes:
      - type: bind
        source: ./dapr-etcd-data/
        target: /data
  {{ range $name, $cfg := .Compose.services }}
  {{ if dig "annotations" "dapr.io/enabled" false $cfg }}
  - op: set
    path: services.{{ $name }}-sidecar
    value:
      image: ghcr.io/dapr/daprd:latest
      command: ["./daprd", "--app-id={{ dig "annotations" "dapr.io/app-id" "" $cfg }}", "--app-port={{ dig "annotations" "dapr.io/app-port" "" $cfg }}", "--enable-api-logging={{ dig "annotations" "dapr.io/enable-api-logging" false $cfg }}", "--placement-host-address=placement:50006", "--scheduler-host-address=scheduler:50007", "--resources-path=/components"]
      network_mode: service:{{ $name }}
      volumes:
      - type: bind
        source: .score-compose/mounts/components/
        target: /components
      depends_on:
        placement:
          condition: service_started
          required: true
  {{ end }}
  {{ end }}
- |
  - op: set
    path: services.microcks
    value:
      image: quay.io/microcks/microcks-uber:nightly-native
      read_only: true
      user: "65532"
      cap_drop: ["ALL"]
      ports:
      - target: 8080
        published: "9090"
      volumes:
      - type: tmpfs
        target: /tmp
        tmpfs:
          size: 655360
- |-
  - op: set
    path: services.ollama
    value:
      image: ollama/ollama:latest
      ports:
      - target: 11434
        published: "11434"
      volumes:
      - type: volume
        source: ollama_data
        target: /root/.ollama
  - op: set
    path: volumes.ollama_data
    value:
        name: ollama_data
        driver: local
- |
  {{ range $name, $spec := .Workloads }}
  {{ range $cname, $_ := $spec.containers }}
  - op: set
    path: services.{{ $name }}-{{ $cname }}.read_only
    value: true
  - op: set
    path: services.{{ $name }}-{{ $cname }}.user
    value: "65532"
  - op: set
    path: services.{{ $name }}-{{ $cname }}.cap_drop
    value: ["ALL"]
  {{ end }}
  {{ end }}

Stdin:

cat ../community-patchers/score-compose/unprivileged.tpl | ./score-compose init --no-sample --patch-templates -
INFO: Fetching patch template from -
INFO: Writing new state directory '.score-compose'
INFO: Writing new state directory '.score-compose' with project name 'score-compose'
INFO: Writing default provisioners file
INFO: Found existing Score file './score.yaml'
INFO: Read more about the Score specification at https://docs.score.dev/docs/

state.yaml

yq '.patching_templates' .score-compose/state.yaml
- |
  {{ range $name, $spec := .Workloads }}
  {{ range $cname, $_ := $spec.containers }}
  - op: set
    path: services.{{ $name }}-{{ $cname }}.read_only
    value: true
  - op: set
    path: services.{{ $name }}-{{ $cname }}.user
    value: "65532"
  - op: set
    path: services.{{ $name }}-{{ $cname }}.cap_drop
    value: ["ALL"]
  {{ end }}
  {{ end }}

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • New chore (expected functionality to be implemented)

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.

Signed-off-by: Venkatesh R <venkyravi97@gmail.com>
Copy link
Copy Markdown
Contributor

@mathieu-benoit mathieu-benoit left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

@mathieu-benoit mathieu-benoit merged commit a8b5fd5 into score-spec:main Apr 16, 2026
8 checks passed
@mathieu-benoit
Copy link
Copy Markdown
Contributor

FYI: associated docs updated accordingly: score-spec/docs#278

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.

2 participants