From c29776e561604a75605642ba755760938e62341d Mon Sep 17 00:00:00 2001 From: Justin Van Patten Date: Thu, 30 Aug 2018 14:56:13 -0700 Subject: [PATCH] Support project config keys in templates and `-c` (#1841) Previously, we only supported config keys that included a ':' delimiter in config keys specified in the template manifest and in `-c` flags to `new` and `up`. This prevented the use of project keys in the template manifest and made it more difficult to pass such keys with `-c`, effectively preventing the use of `new pulumi.Config()` in project code. This change fixes this by allowing config keys that don't have a delimiter in the template manifest and `-c` flags. In such cases, the project name is automatically prepended behind the scenes, the same as what `pulumi config set` does. --- cmd/new.go | 25 +++++++++++++++++++------ cmd/up.go | 10 ++++++++-- pkg/workspace/project.go | 6 +++--- pkg/workspace/templates.go | 11 +++++------ 4 files changed, 35 insertions(+), 17 deletions(-) diff --git a/cmd/new.go b/cmd/new.go index ec073a4ec..44f8581fb 100644 --- a/cmd/new.go +++ b/cmd/new.go @@ -509,7 +509,7 @@ func parseConfig(configArray []string) (config.Map, error) { for _, c := range configArray { kvp := strings.SplitN(c, "=", 2) - key, err := config.ParseKey(kvp[0]) + key, err := parseConfigKey(kvp[0]) if err != nil { return nil, err } @@ -530,16 +530,27 @@ func parseConfig(configArray []string) (config.Map, error) { // value when prompting instead of the default value specified in templateConfig. func promptForConfig( stack backend.Stack, - templateConfig map[config.Key]workspace.ProjectTemplateConfigValue, + templateConfig map[string]workspace.ProjectTemplateConfigValue, commandLineConfig config.Map, stackConfig config.Map, yes bool, opts backend.DisplayOptions) (config.Map, error) { - c := make(config.Map) + // Convert `string` keys to `config.Key`. If a string key is missing a delimiter, + // the project name will be prepended. + parsedTemplateConfig := make(map[config.Key]workspace.ProjectTemplateConfigValue) + for k, v := range templateConfig { + parsedKey, parseErr := parseConfigKey(k) + if parseErr != nil { + return nil, parseErr + } + parsedTemplateConfig[parsedKey] = v + } + // Sort keys. Note that we use the fully qualified module member here instead of a `prettyKey` so that + // all config values for the current program are prompted one after another. var keys config.KeyArray - for k := range templateConfig { + for k := range parsedTemplateConfig { keys = append(keys, k) } sort.Sort(keys) @@ -547,6 +558,8 @@ func promptForConfig( var err error var crypter config.Crypter + c := make(config.Map) + for _, k := range keys { // If it was passed as a command line flag, use it without prompting. if val, ok := commandLineConfig[k]; ok { @@ -554,7 +567,7 @@ func promptForConfig( continue } - templateConfigValue := templateConfig[k] + templateConfigValue := parsedTemplateConfig[k] // Prepare a default value. var defaultValue string @@ -587,7 +600,7 @@ func promptForConfig( } // Prepare the prompt. - prompt := k.String() + prompt := prettyKey(k) if templateConfigValue.Description != "" { prompt = prompt + ": " + templateConfigValue.Description } diff --git a/cmd/up.go b/cmd/up.go index 46db67365..32556180a 100644 --- a/cmd/up.go +++ b/cmd/up.go @@ -346,7 +346,7 @@ var ( // in the Pulumi Console). func isPreconfiguredEmptyStack( url string, - templateConfig map[config.Key]workspace.ProjectTemplateConfigValue, + templateConfig map[string]workspace.ProjectTemplateConfigValue, stackConfig config.Map, snap *deploy.Snapshot) bool { @@ -378,7 +378,13 @@ func isPreconfiguredEmptyStack( // Can stackConfig satisfy the config requirements of templateConfig? for templateKey, templateVal := range templateConfig { - stackVal, ok := stackConfig[templateKey] + parsedTemplateKey, parseErr := parseConfigKey(templateKey) + if parseErr != nil { + contract.IgnoreError(parseErr) + return false + } + + stackVal, ok := stackConfig[parsedTemplateKey] if !ok { return false } diff --git a/pkg/workspace/project.go b/pkg/workspace/project.go index ead961d4d..1d9279269 100644 --- a/pkg/workspace/project.go +++ b/pkg/workspace/project.go @@ -35,9 +35,9 @@ type Analyzers []tokens.QName // ProjectTemplate is a Pulumi project template manifest. // nolint: lll type ProjectTemplate struct { - Description string `json:"description,omitempty" yaml:"description,omitempty"` // an optional description of the template. - Quickstart string `json:"quickstart,omitempty" yaml:"quickstart,omitempty"` // optional text to be displayed after template creation. - Config map[config.Key]ProjectTemplateConfigValue `json:"config,omitempty" yaml:"config,omitempty"` // optional template config. + Description string `json:"description,omitempty" yaml:"description,omitempty"` // an optional description of the template. + Quickstart string `json:"quickstart,omitempty" yaml:"quickstart,omitempty"` // optional text to be displayed after template creation. + Config map[string]ProjectTemplateConfigValue `json:"config,omitempty" yaml:"config,omitempty"` // optional template config. } // ProjectTemplateConfigValue is a config value included in the project template manifest. diff --git a/pkg/workspace/templates.go b/pkg/workspace/templates.go index 977551854..a051c88e5 100644 --- a/pkg/workspace/templates.go +++ b/pkg/workspace/templates.go @@ -27,7 +27,6 @@ import ( "gopkg.in/src-d/go-git.v4/plumbing" "github.com/pkg/errors" - "github.com/pulumi/pulumi/pkg/resource/config" "github.com/pulumi/pulumi/pkg/tokens" "github.com/pulumi/pulumi/pkg/util/contract" "github.com/pulumi/pulumi/pkg/util/gitutil" @@ -114,11 +113,11 @@ func (repo TemplateRepository) Templates() ([]Template, error) { // Template represents a project template. type Template struct { - Dir string // The directory containing Pulumi.yaml. - Name string // The name of the template. - Description string // Description of the template. - Quickstart string // Optional text to be displayed after template creation. - Config map[config.Key]ProjectTemplateConfigValue // Optional template config. + Dir string // The directory containing Pulumi.yaml. + Name string // The name of the template. + Description string // Description of the template. + Quickstart string // Optional text to be displayed after template creation. + Config map[string]ProjectTemplateConfigValue // Optional template config. ProjectName string // Name of the project. ProjectDescription string // Optional description of the project.