diff --git a/eval/eval.go b/eval/eval.go index 10d149f8..36ec723f 100644 --- a/eval/eval.go +++ b/eval/eval.go @@ -402,6 +402,10 @@ func (e *evalContext) isReserveTopLevelKey(k string) bool { // evaluate drives the evaluation of the evalContext's environment. func (e *evalContext) evaluate() (*value, syntax.Diagnostics) { + mine := &imported{evaluating: true} + defer func() { mine.evaluating = false }() + e.imports[e.name] = mine + // Evaluate context. We prepare the context values to later evaluate interpolations. e.evaluateContext() // Evaluate imports. We do this prior to declaration so that we can plumb base values as part of declaration. @@ -444,10 +448,6 @@ func (e *evalContext) evaluateContext() { // evaluateImports evaluates an environment's imports. func (e *evalContext) evaluateImports() { - mine := &imported{evaluating: true} - defer func() { mine.evaluating = false }() - e.imports[e.name] = mine - myImports := map[string]*value{} for _, entry := range e.env.Imports.GetElements() { // If the import does not have a name, there's nothing we can do. This can happen for environments diff --git a/eval/testdata/eval/inline-reference-cycle/bad/bad.yaml b/eval/testdata/eval/inline-reference-cycle/bad/bad.yaml new file mode 100644 index 00000000..c5658ec0 --- /dev/null +++ b/eval/testdata/eval/inline-reference-cycle/bad/bad.yaml @@ -0,0 +1,2 @@ +values: + cycle: ${environments.bad.bad.cycle} \ No newline at end of file diff --git a/eval/testdata/eval/inline-reference-cycle/env.yaml b/eval/testdata/eval/inline-reference-cycle/env.yaml new file mode 100644 index 00000000..6dc9114e --- /dev/null +++ b/eval/testdata/eval/inline-reference-cycle/env.yaml @@ -0,0 +1,2 @@ +imports: + - bad/bad diff --git a/eval/testdata/eval/inline-reference-cycle/expected.json b/eval/testdata/eval/inline-reference-cycle/expected.json new file mode 100644 index 00000000..7fd42b7a --- /dev/null +++ b/eval/testdata/eval/inline-reference-cycle/expected.json @@ -0,0 +1,499 @@ +{ + "checkDiags": [ + { + "Severity": 1, + "Summary": "cyclic import of bad/bad", + "Detail": "", + "Subject": { + "Filename": "bad/bad", + "Start": { + "Line": 2, + "Column": 10, + "Byte": 0 + }, + "End": { + "Line": 2, + "Column": 39, + "Byte": 0 + } + }, + "Context": null, + "Expression": null, + "EvalContext": null, + "Extra": null, + "Path": "values.cycle" + } + ], + "check": { + "properties": { + "cycle": { + "unknown": true, + "trace": { + "def": { + "environment": "bad/bad", + "begin": { + "line": 2, + "column": 10, + "byte": 0 + }, + "end": { + "line": 2, + "column": 39, + "byte": 0 + } + } + } + } + }, + "schema": { + "properties": { + "cycle": true + }, + "type": "object", + "required": [ + "cycle" + ] + }, + "executionContext": { + "properties": { + "currentEnvironment": { + "value": { + "name": { + "value": "inline-reference-cycle", + "trace": { + "def": { + "environment": "inline-reference-cycle", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "trace": { + "def": { + "environment": "inline-reference-cycle", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + }, + "pulumi": { + "value": { + "user": { + "value": { + "id": { + "value": "USER_123", + "trace": { + "def": { + "environment": "inline-reference-cycle", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "trace": { + "def": { + "environment": "inline-reference-cycle", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "trace": { + "def": { + "environment": "inline-reference-cycle", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + }, + "rootEnvironment": { + "value": { + "name": { + "value": "inline-reference-cycle", + "trace": { + "def": { + "environment": "inline-reference-cycle", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "trace": { + "def": { + "environment": "inline-reference-cycle", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "schema": { + "properties": { + "currentEnvironment": { + "properties": { + "name": { + "type": "string", + "const": "inline-reference-cycle" + } + }, + "type": "object", + "required": [ + "name" + ] + }, + "pulumi": { + "properties": { + "user": { + "properties": { + "id": { + "type": "string", + "const": "USER_123" + } + }, + "type": "object", + "required": [ + "id" + ] + } + }, + "type": "object", + "required": [ + "user" + ] + }, + "rootEnvironment": { + "properties": { + "name": { + "type": "string", + "const": "inline-reference-cycle" + } + }, + "type": "object", + "required": [ + "name" + ] + } + }, + "type": "object", + "required": [ + "currentEnvironment", + "pulumi", + "rootEnvironment" + ] + } + } + }, + "checkJson": { + "cycle": "[unknown]" + }, + "evalDiags": [ + { + "Severity": 1, + "Summary": "cyclic import of bad/bad", + "Detail": "", + "Subject": { + "Filename": "bad/bad", + "Start": { + "Line": 2, + "Column": 10, + "Byte": 0 + }, + "End": { + "Line": 2, + "Column": 39, + "Byte": 0 + } + }, + "Context": null, + "Expression": null, + "EvalContext": null, + "Extra": null, + "Path": "values.cycle" + } + ], + "eval": { + "properties": { + "cycle": { + "unknown": true, + "trace": { + "def": { + "environment": "bad/bad", + "begin": { + "line": 2, + "column": 10, + "byte": 0 + }, + "end": { + "line": 2, + "column": 39, + "byte": 0 + } + } + } + } + }, + "schema": { + "properties": { + "cycle": true + }, + "type": "object", + "required": [ + "cycle" + ] + }, + "executionContext": { + "properties": { + "currentEnvironment": { + "value": { + "name": { + "value": "inline-reference-cycle", + "trace": { + "def": { + "environment": "inline-reference-cycle", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "trace": { + "def": { + "environment": "inline-reference-cycle", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + }, + "pulumi": { + "value": { + "user": { + "value": { + "id": { + "value": "USER_123", + "trace": { + "def": { + "environment": "inline-reference-cycle", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "trace": { + "def": { + "environment": "inline-reference-cycle", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "trace": { + "def": { + "environment": "inline-reference-cycle", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + }, + "rootEnvironment": { + "value": { + "name": { + "value": "inline-reference-cycle", + "trace": { + "def": { + "environment": "inline-reference-cycle", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "trace": { + "def": { + "environment": "inline-reference-cycle", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "schema": { + "properties": { + "currentEnvironment": { + "properties": { + "name": { + "type": "string", + "const": "inline-reference-cycle" + } + }, + "type": "object", + "required": [ + "name" + ] + }, + "pulumi": { + "properties": { + "user": { + "properties": { + "id": { + "type": "string", + "const": "USER_123" + } + }, + "type": "object", + "required": [ + "id" + ] + } + }, + "type": "object", + "required": [ + "user" + ] + }, + "rootEnvironment": { + "properties": { + "name": { + "type": "string", + "const": "inline-reference-cycle" + } + }, + "type": "object", + "required": [ + "name" + ] + } + }, + "type": "object", + "required": [ + "currentEnvironment", + "pulumi", + "rootEnvironment" + ] + } + } + }, + "evalJsonRedacted": { + "cycle": "[unknown]" + }, + "evalJSONRevealed": { + "cycle": "[unknown]" + } +}