mirror of
https://github.com/opentofu/opentofu.git
synced 2026-05-28 04:15:54 -04:00
81 lines
3.5 KiB
Go
81 lines
3.5 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 jsonconfig
|
||
|
|
|
||
|
|
import (
|
||
|
|
"github.com/opentofu/opentofu/internal/configs"
|
||
|
|
"github.com/opentofu/opentofu/internal/configs/configschema"
|
||
|
|
"github.com/opentofu/opentofu/internal/tofu"
|
||
|
|
)
|
||
|
|
|
||
|
|
// MarshalSingleModule is a variant of [Marshal] that describes only a single
|
||
|
|
// module, without any references to its child modules or associated provider
|
||
|
|
// schemas.
|
||
|
|
//
|
||
|
|
// This uses only a subset of the typical configuration representation, due to
|
||
|
|
// schema and child module information being unavailable:
|
||
|
|
// - Module calls omit the "module" property that would normally describe the
|
||
|
|
// content of the child module.
|
||
|
|
// - Resource descriptions omit the "schema_version" property because no
|
||
|
|
// schema-based information is included.
|
||
|
|
// - Expression-related properties are omitted in all cases. Technically only
|
||
|
|
// expressions passed to providers _need_ to be omitted, but for now we
|
||
|
|
// just consistently omit all of them because that's an easier rule to
|
||
|
|
// explain and avoids exposing what is and is not provider-based so that
|
||
|
|
// we could potentially change those details in future.
|
||
|
|
func MarshalSingleModule(m *configs.Module) ([]byte, error) {
|
||
|
|
// Our shared codepaths are built to work with a full config tree rather
|
||
|
|
// than a single module, so we'll construct a synthetic [configs.Config]
|
||
|
|
// that only has a root module and then downstream shared functions will
|
||
|
|
// use the nil-ness of the schemas argument to handle the special
|
||
|
|
// treatments required in single-module mode.
|
||
|
|
cfg := &configs.Config{
|
||
|
|
Module: m,
|
||
|
|
// Everything else intentionally not populated because single module
|
||
|
|
// mode should not attempt to access anything else.
|
||
|
|
}
|
||
|
|
return marshal(cfg, nil)
|
||
|
|
}
|
||
|
|
|
||
|
|
// inSingleModuleMode returns true if the given schema value indicates that
|
||
|
|
// we should be rendering in "single module" mode, meaning that we're producing
|
||
|
|
// a result for [MarshalSingleModule] rather than [Marshal].
|
||
|
|
//
|
||
|
|
// Currently the rule is only that a nil schemas represents single-module mode;
|
||
|
|
// this simple rule is factored out into this helper function only so we can
|
||
|
|
// centralize it underneath this doc comment explaining the special convention.
|
||
|
|
//
|
||
|
|
// (This rather odd design is a consequence of how this code evolved; we
|
||
|
|
// retrofitted the single-module mode later while using this strange treatment
|
||
|
|
// to minimize the risk to the existing working codepaths. Maybe we'll change
|
||
|
|
// the appoach to this in future; this is only an implementation detail
|
||
|
|
// within this package so we'll be able to those changes without affecting
|
||
|
|
// callers.)
|
||
|
|
func inSingleModuleMode[S schemaObject](schema S) bool {
|
||
|
|
return schema == nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// mapSchema is a helper that uses the given function to transform the given
|
||
|
|
// schema object only if it isn't nil, or immediately returns nil otherwise.
|
||
|
|
//
|
||
|
|
// This is part of our strategy to retrofit the single-module mode without
|
||
|
|
// a risky refactor of the already-working code, intended to be used in
|
||
|
|
// conjunction with [inSingleModuleMode] to smuggle the flag for whether we're
|
||
|
|
// in that mode through the nil-ness of the schema objects.
|
||
|
|
func mapSchema[In, Out schemaObject](schema In, f func(In) Out) Out {
|
||
|
|
if schema == nil {
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
return f(schema)
|
||
|
|
}
|
||
|
|
|
||
|
|
// schemaObject is a helper interface to allow [inSingleModuleMode] to be
|
||
|
|
// generic over the different nilable schema types used by different parts
|
||
|
|
// of the implementation in this package.
|
||
|
|
type schemaObject interface {
|
||
|
|
*tofu.Schemas | *configschema.Block
|
||
|
|
}
|