From fe12d53e777680a4a8c443cdef142bba23366ff8 Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Mon, 15 Feb 2021 11:32:20 +0100 Subject: [PATCH] addr: remove support for defaulting plugin namespace and host --- hcl2template/addrs/plugin.go | 71 +++++++++++++------------------ hcl2template/addrs/plugin_test.go | 32 ++++++++++++++ 2 files changed, 61 insertions(+), 42 deletions(-) create mode 100644 hcl2template/addrs/plugin_test.go diff --git a/hcl2template/addrs/plugin.go b/hcl2template/addrs/plugin.go index 88aa53fc2..f26ee796e 100644 --- a/hcl2template/addrs/plugin.go +++ b/hcl2template/addrs/plugin.go @@ -10,17 +10,13 @@ import ( // Plugin encapsulates a single plugin type. type Plugin struct { - Type string - Namespace string Hostname string + Namespace string + Type string } func (p Plugin) RealRelativePath() string { - ns := DefaultPluginNamespace - if p.Namespace != "" { - ns = p.Namespace - } - return ns + "/packer-plugin-" + p.Type + return p.Namespace + "/packer-plugin-" + p.Type } func (p Plugin) Parts() []string { @@ -34,20 +30,23 @@ func (p Plugin) String() string { // ForDisplay returns a user-friendly FQN string, simplified for readability. If // the plugin is using the default hostname, the hostname is omitted. func (p *Plugin) ForDisplay() string { + const ( + // These will be hidden if they are a prefix + DefaultHashicorpPluginHost = "github.com" + DefaultHashicorpPluginNamespace = "hashicorp" + ) + parts := []string{} - if p.Hostname != DefaultPluginHost { + if p.Hostname != DefaultHashicorpPluginHost { parts = append(parts, p.Hostname) } - if p.Namespace != DefaultPluginNamespace { + if p.Namespace != DefaultHashicorpPluginNamespace { parts = append(parts, p.Namespace) } parts = append(parts, p.Type) return strings.Join(parts, "/") } -const DefaultPluginHost = "github.com" -const DefaultPluginNamespace = "hashicorp" - // ParsePluginPart processes an addrs.Plugin namespace or type string // provided by an end-user, producing a normalized version if possible or // an error if the string contains invalid characters. @@ -120,18 +119,18 @@ func IsPluginPartNormalized(str string) (bool, error) { // hostname/namespace/name func ParsePluginSourceString(str string) (*Plugin, hcl.Diagnostics) { ret := &Plugin{ - Hostname: DefaultPluginHost, - Namespace: DefaultPluginNamespace, + Hostname: "", + Namespace: "", } var diags hcl.Diagnostics // split the source string into individual components parts := strings.Split(str, "/") - if len(parts) == 0 || len(parts) > 3 { + if len(parts) != 3 { diags = diags.Append(&hcl.Diagnostic{ Severity: hcl.DiagError, Summary: "Invalid plugin source string", - Detail: `The "source" attribute must be in the format "[hostname/][namespace/]name"`, + Detail: `The "source" attribute must be in the format "hostname/namespace/name"`, }) return nil, diags } @@ -142,7 +141,7 @@ func ParsePluginSourceString(str string) (*Plugin, hcl.Diagnostics) { diags = diags.Append(&hcl.Diagnostic{ Severity: hcl.DiagError, Summary: "Invalid plugin source string", - Detail: `The "source" attribute must be in the format "[hostname/][namespace/]name"`, + Detail: `The "source" attribute must be in the format "hostname/namespace/name"`, }) return nil, diags } @@ -161,33 +160,21 @@ func ParsePluginSourceString(str string) (*Plugin, hcl.Diagnostics) { } ret.Type = name - if len(parts) == 1 { - return ret, diags - } - - if len(parts) >= 2 { - // the namespace is always the second-to-last part - givenNamespace := parts[len(parts)-2] - namespace, err := ParsePluginPart(givenNamespace) - if err != nil { - diags = diags.Append(&hcl.Diagnostic{ - Severity: hcl.DiagError, - Summary: "Invalid plugin namespace", - Detail: fmt.Sprintf(`Invalid plugin namespace %q in source %q: %s"`, namespace, str, err), - }) - return nil, diags - } - ret.Namespace = namespace + // the namespace is always the second-to-last part + givenNamespace := parts[len(parts)-2] + namespace, err := ParsePluginPart(givenNamespace) + if err != nil { + diags = diags.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid plugin namespace", + Detail: fmt.Sprintf(`Invalid plugin namespace %q in source %q: %s"`, namespace, str, err), + }) + return nil, diags } + ret.Namespace = namespace - // Final Case: 3 parts - if len(parts) == 3 { - // the hostname is always the first part in a three-part source string - hostname := parts[0] - // TODO(azr): validate host ? Can this be something else than a - // github.com host for now? - ret.Hostname = hostname - } + // the hostname is always the first part in a three-part source string + ret.Hostname = parts[0] // Due to how plugin executables are named and plugin git repositories // are conventionally named, it's a reasonable and diff --git a/hcl2template/addrs/plugin_test.go b/hcl2template/addrs/plugin_test.go new file mode 100644 index 000000000..191f103fa --- /dev/null +++ b/hcl2template/addrs/plugin_test.go @@ -0,0 +1,32 @@ +package addrs + +import ( + "reflect" + "testing" +) + +func TestParsePluginSourceString(t *testing.T) { + type args struct { + str string + } + tests := []struct { + args args + want *Plugin + wantDiags bool + }{ + {args{"potato"}, nil, true}, + {args{"hashicorp/azr"}, nil, true}, + {args{"github.com/hashicorp/azr"}, &Plugin{"github.com", "hashicorp", "azr"}, false}, + } + for _, tt := range tests { + t.Run(tt.args.str, func(t *testing.T) { + got, gotDiags := ParsePluginSourceString(tt.args.str) + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("ParsePluginSourceString() got = %v, want %v", got, tt.want) + } + if tt.wantDiags == (len(gotDiags) == 0) { + t.Errorf("Unexpected diags %s", gotDiags) + } + }) + } +}