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

Handle anonymous environments when injecting it to the context #250

Merged
merged 8 commits into from
Feb 15, 2024

Conversation

glena
Copy link
Contributor

@glena glena commented Feb 9, 2024

  • Splitting context.environment into rootEnvironment and currentEnvironment (potentially just environment)
  • When evaluating an anonymous environment, the rootEnvironment will evaluate to the rootest non anonymous environment for the imported environments (wont propagate to the root)

Having these 3 envs:

# root
imports:
  - imported
values:
  root:
    currentEnvironment: ${context.currentEnvironment.name}
    rootEnvironment: ${context.rootEnvironment.name}

# imported
imports:
  - child
values:
  imported:
    currentEnvironment: ${context.currentEnvironment.name}
    rootEnvironment: ${context.rootEnvironment.name}

# child
values:
  child:
    currentEnvironment: ${context.currentEnvironment.name}
    rootEnvironment: ${context.rootEnvironment.name}

In the case the root env is anonymous, it resolves:

{
  "child": {
    "currentEnvironment": "child",
    "rootEnvironment": "imported"
  },
  "imported": {
    "currentEnvironment": "imported",
    "rootEnvironment": "imported"
  },
  "root": {
    "currentEnvironment": "<yaml>",
    "rootEnvironment": "<yaml>"
  }
}

In the case the root env is a named environment, it resolves:

{
  "child": {
    "currentEnvironment": "child",
    "rootEnvironment": "root"
  },
  "imported": {
    "currentEnvironment": "imported",
    "rootEnvironment": "root"
  },
  "root": {
    "currentEnvironment": "root",
    "rootEnvironment": "root"
  }
}

@cleverguy25 cleverguy25 changed the title Handle anonimous environments when injecting it to the context Handle anonymous environments when injecting it to the context Feb 9, 2024
}

func newCopier() copier {
return copier{memo: map[*Value]*Value{}}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

I think it's fine to have two implementations for now: using the generic copier feels a bit risky to me given the sensitivity of the *value graph to proper memoized copies.

FWIW, the *Values don't have the same restrictions, so we could also simplify this by removing the memoization.

Copy link
Member

@pgavlin pgavlin left a comment

Choose a reason for hiding this comment

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

one change re: not mutating execcontexts, but generally looks good.

environment.go Outdated
Comment on lines 93 to 108
func (ec *ExecContext) Values(envName string) map[string]Value {
context := ec.values
context["currentEnvironment"] = NewValue(map[string]Value{
"name": NewValue(envName),
})

if ec.rootEvironment == AnonymousEnvironmentName || ec.rootEvironment == "" {
ec.rootEvironment = envName
}

context["rootEnvironment"] = NewValue(map[string]Value{
"name": NewValue(ec.rootEvironment),
})

return context
}
Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer not to mutate the values here. I'd prefer that we instead copy the context for each envName and set the values in Copy.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

environment.go Outdated
return context
}

var ErrForbiddenContextkey = errors.New("forbidden context key")
Copy link
Member

Choose a reason for hiding this comment

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

nit: we generally use "reserved" for keys that the user is not allowed to set

Suggested change
var ErrForbiddenContextkey = errors.New("forbidden context key")
var ErrReservedContextkey = errors.New("reserved context key")

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

}

func newCopier() copier {
return copier{memo: map[*Value]*Value{}}
Copy link
Member

Choose a reason for hiding this comment

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

I think it's fine to have two implementations for now: using the generic copier feels a bit risky to me given the sensitivity of the *value graph to proper memoized copies.

FWIW, the *Values don't have the same restrictions, so we could also simplify this by removing the memoization.

environment.go Outdated
Comment on lines 86 to 108
func (ec *ExecContext) Copy() *ExecContext {
return &ExecContext{
values: ec.values,
rootEvironment: ec.rootEvironment,
}
}

func (ec *ExecContext) Values(envName string) map[string]Value {
context := copyContext(ec.values)
context["currentEnvironment"] = NewValue(map[string]Value{
"name": NewValue(envName),
})

if ec.rootEvironment == AnonymousEnvironmentName || ec.rootEvironment == "" {
ec.rootEvironment = envName
}

context["rootEnvironment"] = NewValue(map[string]Value{
"name": NewValue(ec.rootEvironment),
})

return context
}
Copy link
Member

Choose a reason for hiding this comment

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

sorry, I think I wasn't clear here. this is what I was suggesting:

Suggested change
func (ec *ExecContext) Copy() *ExecContext {
return &ExecContext{
values: ec.values,
rootEvironment: ec.rootEvironment,
}
}
func (ec *ExecContext) Values(envName string) map[string]Value {
context := copyContext(ec.values)
context["currentEnvironment"] = NewValue(map[string]Value{
"name": NewValue(envName),
})
if ec.rootEvironment == AnonymousEnvironmentName || ec.rootEvironment == "" {
ec.rootEvironment = envName
}
context["rootEnvironment"] = NewValue(map[string]Value{
"name": NewValue(ec.rootEvironment),
})
return context
}
func (ec *ExecContext) Copy(envName string) *ExecContext {
values := copyContext(ec.values)
values["currentEnvironment"] = NewValue(map[string]Value{
"name": NewValue(envName),
})
root := ec.rootEnvironment
if ec.rootEvironment == AnonymousEnvironmentName || ec.rootEvironment == "" {
root = envName
}
values["rootEnvironment"] = NewValue(map[string]Value{
"name": NewValue(root),
})
return &ExecContext{
values: values,
rootEvironment: root,
}
}
func (ec *ExecContext) Values() map[string]Value {
return ec.values
}

With this approach the contents of a context are never mutated once the context is created.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ah I misunderstood. I thought the concern was mutating the value we have in memory, not the place were we mutate. Done

environment.go Outdated
Comment on lines 92 to 94
if ec.rootEvironment == AnonymousEnvironmentName || ec.rootEvironment == "" {
ec.rootEvironment = envName
}
Copy link
Member

Choose a reason for hiding this comment

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

this is still mutating ec

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes that is needed to propagate the root environment down the line

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@glena glena merged commit 596237e into pulumi:main Feb 15, 2024
4 checks passed
@glena glena deleted the german/root-current-env-context branch February 15, 2024 18:25
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.

2 participants