Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New YAML loader to support configuration location #828

Merged
merged 6 commits into from
Oct 20, 2023
Merged

New YAML loader to support configuration location #828

merged 6 commits into from
Oct 20, 2023

Conversation

pietern
Copy link
Contributor

@pietern pietern commented Oct 2, 2023

Changes

In order to support variable interpolation on fields that aren't a string in the resource types, we need a separate representation of the bundle configuration tree with the type equivalent of Go's any. But instead of using any directly, we can do better and use a custom type equivalent to any that captures additional metadata. In this PR, the additional metadata is limited to the origin of the configuration value (file, line number, and column).

The YAML in this commit uses the upstream YAML parser's yaml.Node type to get access to location information. It reimplements the loader that takes the yaml.Node structure and turns it into the configuration tree we need.

Next steps after this PR:

  • Implement configuration tree type checking (against a Go type)
  • Implement configuration tree merging (to replace the current merge functionality)
  • Implement conversion to and from the bundle configuration struct
  • Perform variable interpolation against this configuration tree (to support variable interpolation for ints)
  • (later) Implement a jsonloader that produces the same tree and includes location information

Tests

The tests in yamlloader perform an equality check on the untyped output of loading a YAML file between the upstream YAML loader and this loader. The YAML examples were generated by prompting ChatGPT for examples that showcase anchors, primitive values, edge cases, etc.

libs/config/node.go Outdated Show resolved Hide resolved
libs/config/node.go Outdated Show resolved Hide resolved
@andrewnester andrewnester self-requested a review October 3, 2023 12:40
Copy link
Contributor

@shreyas-goenka shreyas-goenka left a comment

Choose a reason for hiding this comment

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

lgtm, pretty cool!

Copy link
Contributor

@kartikgupta-db kartikgupta-db left a comment

Choose a reason for hiding this comment

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

Looks really nice. I can already see a lot of possibilities with language servers here.

The only concern I have is with speed. How does this scale with project size and when we collect more data (eg. comments)? We need to call this multiple times from vscode.

Can we maybe add a "load test" once we have the entire command (to generate a consolidated JSON view of the bundle) wired up?

Maybe this is a non issue because we never see too big or too recursive bundles. But would be nice to be sure.

libs/config/value.go Outdated Show resolved Hide resolved
Copy link
Contributor

@mgyucht mgyucht left a comment

Choose a reason for hiding this comment

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

Nice, couple of nits but the core logic seems fine to me. Great tests!

Comment on lines 109 to 111
case "!!merge":
merge = val
continue
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess there is only one merge node in each mapping? Any sense in panicking if merge is non-nil and we hit this codepath?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That is correct. It is not allowed to use the same key multiple times, which means that specifying << twice is not valid. To merge multiple anchors, the value for << can be an array. I checked and the parser returns an error if you specify the same key twice.

I'll still add the panic, though, that is cheap.

libs/config/yamlloader/loader.go Show resolved Hide resolved
}
m, ok := v.AsMap()
if !ok {
return config.NilValue, merr
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we indicate to the user which anchor is incorrect and what its true type is? Would help with debugging.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The error comes from merr and includes the location information where it is defined.

For example:

yaml (testdata/error_02.yml:5:7): map merge requires map or sequence of maps as the value

Where 5:7 maps to the opening bracket in the merge key:

# Use string anchor inside sequence to extend a mapping.
str: &str "Hello world!"

map:
  <<: [*str]
  key: value

libs/config/yamlloader/loader.go Show resolved Hide resolved
seq = append(seq, m)
}
case yaml.AliasNode:
v, err := d.load(merge)
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we ever intend this pathway and that inside the loop in the SequenceNode branch to diverge? If not, it may make sense to abstract this logic into a standalone function to ensure consistency over time.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We do not. I rewrote this to first get a slice of *yaml.Node and then do the processing to abstract it.

@pietern pietern marked this pull request as ready for review October 20, 2023 12:20
@pietern pietern added this pull request to the merge queue Oct 20, 2023
Merged via the queue into main with commit ab05f8e Oct 20, 2023
4 checks passed
@pietern pietern deleted the unmarshal branch October 20, 2023 13:02
pietern added a commit that referenced this pull request Oct 23, 2023
CLI:
 * Never load authentication configuration from bundle for sync command ([#889](#889)).
 * Fixed requiring positional arguments for API URL parameters ([#878](#878)).

Bundles:
 * Add support for validating CLI version when loading a jsonschema object ([#883](#883)).
 * Do not emit wheel wrapper error when python_wheel_wrapper setting is true ([#894](#894)).
 * Resolve configuration before performing verification ([#890](#890)).
 * Fix wheel task not working with with 13.x clusters ([#898](#898)).

Internal:
 * Skip prompt on completion hook ([#888](#888)).
 * New YAML loader to support configuration location ([#828](#828)).

Dependency updates:
 * Bump github.com/mattn/go-isatty from 0.0.19 to 0.0.20 ([#896](#896)).
@pietern pietern mentioned this pull request Oct 23, 2023
github-merge-queue bot pushed a commit that referenced this pull request Oct 23, 2023
CLI:
* Never load authentication configuration from bundle for sync command
([#889](#889)).
* Fixed requiring positional arguments for API URL parameters
([#878](#878)).

Bundles:
* Add support for validating CLI version when loading a jsonschema
object ([#883](#883)).
* Do not emit wheel wrapper error when python_wheel_wrapper setting is
true ([#894](#894)).
* Resolve configuration before performing verification
([#890](#890)).
* Fix wheel task not working with with 13.x clusters
([#898](#898)).

Internal:
* Skip prompt on completion hook
([#888](#888)).
* New YAML loader to support configuration location
([#828](#828)).

Dependency updates:
* Bump github.com/mattn/go-isatty from 0.0.19 to 0.0.20
([#896](#896)).
github-merge-queue bot pushed a commit that referenced this pull request Oct 24, 2023
## Changes

Now that we have a new YAML loader (see #828), we need code to turn this
into our Go structs.

## Tests

New unit tests pass.

Confirmed that we can replace our existing loader/converter with this
one and that existing unit tests for bundle loading still pass.
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.

None yet

5 participants