Skip to content

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

Merged
denik merged 20 commits into
mainfrom
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 into
mainfrom
denik/structpath-flexible

Conversation

@denik

@denikdenik commented Sep 22, 2025

Copy link
Copy Markdown
Contributor

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.

@denikdenik changed the title internal: Flexible path input, make PathNode more compatible with dyn.Pathinternal: update structpath to accept both dot and bracket syntax for fields and mapsSep 22, 2025
@eng-dev-ecosystem-bot

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

Copy link
Copy Markdown
Collaborator

Run: 17956956754

Env✅​pass🔄​flaky🙈​skip
✅​aws linux311529
✅​aws windows312528
✅​aws-ucws linux423427
✅​aws-ucws windows424426
✅​azure linux311528
✅​azure windows312527
🔄​azure-ucws linux4158426
🔄​azure-ucws windows4168425
✅​gcp linux310530
✅​gcp windows311529
9 failing tests:
Test Nameazure-ucws linuxazure-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

Comment threadlibs/structs/structpath/path.go Outdated
Comment threadlibs/structs/structpath/path.go
Comment threadlibs/structs/structpath/path.go
Comment threadlibs/structs/structpath/path.go Outdated
Comment threadlibs/structs/structpath/path.go
Comment threadlibs/structs/structpath/path.go
Comment threadlibs/structs/structpath/path.go
Comment threadlibs/structs/structpath/path.go Outdated
Comment threadlibs/structs/structpath/path.go
Comment threadlibs/structs/structpath/path.go
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
denikforce-pushed the denik/structpath-flexible branch from 57285ac to e627b0eCompareSeptember 23, 2025 19:29
@denik
denik added this pull request to the merge queueSep 24, 2025
Merged via the queue into main with commit 13e2dadSep 24, 2025
13 checks passed
@denik
denik deleted the denik/structpath-flexible branch September 24, 2025 09:22
github-merge-queueBot 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.
denik added a commit that referenced this pull request May 20, 2026
… fields and maps (#3640)
## 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 added a commit that referenced this pull request May 20, 2026
…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 freeto 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

@denik@eng-dev-ecosystem-bot@andrewnester@shreyas-goenka