Files
opentf/internal/lang/eval/context.go
Martin Atkins 72a32f726d lang/eval: Beginnings of a different way to handle config eval
In "package tofu" today we try to do everything using a generic acyclic
graph model and generic graph walk, which _works_ but tends to make every
other part of the problem very hard to follow because we rely a lot on
sidecar shared mutable data structures to propagate results between the
isolated operations.

This is the beginning of an experimental new way to do it where the "graph"
is implied by a model that more closely represents how the language itself
works, with explicit modelling of the relationships between different
types of objects and letting results flow directly from one object to
another without any big shared mutable state.

There's still a lot to do before this is actually complete enough to
evaluate whether it's a viable new design, but I'm considering this a good
starting checkpoint since there's enough here to run a simple test of
propagating data all the way from input variables to output values via
intermediate local values.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-10-27 10:15:41 -07:00

46 lines
1.8 KiB
Go

// Copyright (c) The OpenTofu Authors
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) 2023 HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package eval
// EvalContext is a collection of contextual information provided by an
// external caller of this package to help it to interact with the surrounding
// environment.
type EvalContext struct {
// This type should only contain broad stuff that'd typically be set up
// only once for a particular OpenTofu CLI command, and NOT
// operation-specific things like the input variables provided for a
// given module, or where state is supposed to be stored, etc.
// Modules gives access to all of the modules available for use in
// this context.
Modules ExternalModules
// Providers gives access to all of the providers available for use
// in this context.
Providers Providers
// Provisioners gives access to all of the provisioners available for
// use in this context.
Provisioners Provisioners
}
// init must be called early on entry to any exported function that accepts
// an [EvalContext] as an argument to prepare it for use, before accessing
// any of its fields or calling any of its other methods.
func (c *EvalContext) init() {
// If any of the external dependency fields were left nil (likely in
// unit tests which aren't intending to use a particular kind of dependency)
// we'll replace it with a non-nil implementation that just returns an
// error immediately on call, so that accidental reliance on these will
// return an error instead of panicking.
//
// "Real" callers (performing operations on behalf of end-users) should
// avoid relying on this because it returns low-quality error messages.
c.Modules = ensureExternalModules(c.Modules)
c.Providers = ensureProviders(c.Providers)
c.Provisioners = ensureProvisioners(c.Provisioners)
}