Skip to content

internal: update structpath to accept both dot and bracket syntax for fields and maps#3640

Merged
denik merged 20 commits intomainfrom
denik/structpath-flexible
Sep 24, 2025
Merged

internal: update structpath to accept both dot and bracket syntax for fields and maps#3640
denik merged 20 commits intomainfrom
denik/structpath-flexible

Conversation

@denik
Copy link
Copy Markdown
Contributor

@denik denik commented Sep 22, 2025

Changes

Simplify internal representation of structpath.PathNode: struct fields and map keys are represented the same way internally.

When parsing, users can specify either .field or [‘field’], both will be encoded as tagStringKey in PathNode.

When saving PathNode as string, String() selects appropriate encoding (prefers dot unless it uses reserved characters). DynPath() is removed, String() returns DynPath()-like value for those values that can be represented by dot notation.

At the same time, PathNode now accurately represents foo.* vs foo[*], this structure is preserved and not equivalent. This again improves compatibility with dyn.Path as it represents index and keys wildcard differently.

structaccess is updated to accept PathNode. Since PathNode only gives StringKey() now and does not distinguish between map and struct fields, structaccess.Get essentially supports both syntaxes for both kinds.

structwalk is updated to emit dotStar for map wildcards, making it compatible with code expecting dyn.Pattern (this is used for required fields and enum validation).

structwalk.PathNode.String() is rewritten to be iterative rather than recursive.

PathNode gets new methods: Prefix(N), SkipPrefix(N), AsSlice().

Why

Dot notation is currently used for maps e.g. "resources.jobs.foo". With precise map encoding that would look like "resources.jobs['foo']" which looks unfamiliar and also will not match if someone does string comparison against "resources.jobs.foo".

Adopting this scheme makes it easier to work with PathNode in dyn.Path world and in fact makes it drop-in replacement (the syntax is superset).

Tests

Existing and new unit tests.

@denik denik temporarily deployed to test-trigger-is September 22, 2025 13:07 — with GitHub Actions Inactive
@denik denik temporarily deployed to test-trigger-is September 22, 2025 13:17 — with GitHub Actions Inactive
@denik denik temporarily deployed to test-trigger-is September 22, 2025 13:19 — with GitHub Actions Inactive
@denik denik temporarily deployed to test-trigger-is September 22, 2025 13:24 — with GitHub Actions Inactive
@denik denik temporarily deployed to test-trigger-is September 22, 2025 13:30 — with GitHub Actions Inactive
@denik denik changed the title internal: Flexible path input, make PathNode more compatible with dyn.Path internal: update structpath to accept both dot and bracket syntax for fields and maps Sep 22, 2025
@eng-dev-ecosystem-bot
Copy link
Copy Markdown
Collaborator

eng-dev-ecosystem-bot commented Sep 22, 2025

Run: 17956956754

Env ✅​pass 🔄​flaky 🙈​skip
✅​ aws linux 311 529
✅​ aws windows 312 528
✅​ aws-ucws linux 423 427
✅​ aws-ucws windows 424 426
✅​ azure linux 311 528
✅​ azure windows 312 527
🔄​ azure-ucws linux 415 8 426
🔄​ azure-ucws windows 416 8 425
✅​ gcp linux 310 530
✅​ gcp windows 311 529
9 failing tests:
Test Name azure-ucws linux azure-ucws windows
TestAccept/bundle/deploy/dashboard/detect-change 🔄​flaky 🔄​flaky
TestAccept/bundle/deploy/dashboard/generate_inplace 🔄​flaky 🔄​flaky
TestAccept/bundle/deploy/dashboard/nested-folders 🔄​flaky 🔄​flaky
TestAccept/bundle/deploy/dashboard/simple 🔄​flaky 🔄​flaky
TestAccept/bundle/deploy/dashboard/simple_outside_bundle_root 🔄​flaky 🔄​flaky
TestAccept/bundle/deploy/dashboard/simple_syncroot 🔄​flaky 🔄​flaky
TestAccept/bundle/deployment/bind/dashboard ✅​pass 🔄​flaky
TestAccept/bundle/deployment/bind/dashboard/recreation 🔄​flaky ✅​pass
TestDashboardAssumptions_WorkspaceImport 🔄​flaky 🔄​flaky

@shreyas-goenka shreyas-goenka self-requested a review September 23, 2025 09:36
Previously structpath could represent AnyKey and AnyIndex as struct
but as string they were both represented as field[*].

On the other hand, there was no unambigous representation of x.*.

This commit fixes struct mapping to match string representation 1-1 so
that Parse(x.String()) == x.
@denik denik force-pushed the denik/structpath-flexible branch from 57285ac to e627b0e Compare September 23, 2025 19:29
@denik denik temporarily deployed to test-trigger-is September 23, 2025 19:29 — with GitHub Actions Inactive
@denik denik added this pull request to the merge queue Sep 24, 2025
Merged via the queue into main with commit 13e2dad Sep 24, 2025
13 checks passed
@denik denik deleted the denik/structpath-flexible branch September 24, 2025 09:22
github-merge-queue bot pushed a commit that referenced this pull request Dec 2, 2025
…ys (#4041)

## Changes
- Update structpath to distinguish between fields (.field) and map keys
(["field"]). Note, when it comes to references, we still accept any
syntax. However, structdiff and structwalk accurately represent map keys
now.
- Update server_side_default logic to ignore map keys.

## Why
It was never the intention for map entries to have "server_side_default"
feature. (Similar to slice indices in
#4038).

Issue appeared when we stopped distinguishing between fields and map
keys in struct path #3640

Note, originally the difference between fields and map keys was removed
so that
a) users can use either syntax without worrying about matching the type.
This is still the case, structaccess still treats those two the same
way.
b) "resources.jobs.foo" is printed with dots and not like
'resources.jobs["foo"]'. This is still the case, we don't use
structpath's String() for this.

## Tests
New regression test.
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.

4 participants