addr: remove support for defaulting plugin namespace and host

This commit is contained in:
Adrien Delorme 2021-02-15 11:32:20 +01:00
parent 00fce3c46f
commit fe12d53e77
2 changed files with 61 additions and 42 deletions

View File

@ -10,17 +10,13 @@ import (
// Plugin encapsulates a single plugin type. // Plugin encapsulates a single plugin type.
type Plugin struct { type Plugin struct {
Type string
Namespace string
Hostname string Hostname string
Namespace string
Type string
} }
func (p Plugin) RealRelativePath() string { func (p Plugin) RealRelativePath() string {
ns := DefaultPluginNamespace return p.Namespace + "/packer-plugin-" + p.Type
if p.Namespace != "" {
ns = p.Namespace
}
return ns + "/packer-plugin-" + p.Type
} }
func (p Plugin) Parts() []string { 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 // ForDisplay returns a user-friendly FQN string, simplified for readability. If
// the plugin is using the default hostname, the hostname is omitted. // the plugin is using the default hostname, the hostname is omitted.
func (p *Plugin) ForDisplay() string { func (p *Plugin) ForDisplay() string {
const (
// These will be hidden if they are a prefix
DefaultHashicorpPluginHost = "github.com"
DefaultHashicorpPluginNamespace = "hashicorp"
)
parts := []string{} parts := []string{}
if p.Hostname != DefaultPluginHost { if p.Hostname != DefaultHashicorpPluginHost {
parts = append(parts, p.Hostname) parts = append(parts, p.Hostname)
} }
if p.Namespace != DefaultPluginNamespace { if p.Namespace != DefaultHashicorpPluginNamespace {
parts = append(parts, p.Namespace) parts = append(parts, p.Namespace)
} }
parts = append(parts, p.Type) parts = append(parts, p.Type)
return strings.Join(parts, "/") return strings.Join(parts, "/")
} }
const DefaultPluginHost = "github.com"
const DefaultPluginNamespace = "hashicorp"
// ParsePluginPart processes an addrs.Plugin namespace or type string // ParsePluginPart processes an addrs.Plugin namespace or type string
// provided by an end-user, producing a normalized version if possible or // provided by an end-user, producing a normalized version if possible or
// an error if the string contains invalid characters. // an error if the string contains invalid characters.
@ -120,18 +119,18 @@ func IsPluginPartNormalized(str string) (bool, error) {
// hostname/namespace/name // hostname/namespace/name
func ParsePluginSourceString(str string) (*Plugin, hcl.Diagnostics) { func ParsePluginSourceString(str string) (*Plugin, hcl.Diagnostics) {
ret := &Plugin{ ret := &Plugin{
Hostname: DefaultPluginHost, Hostname: "",
Namespace: DefaultPluginNamespace, Namespace: "",
} }
var diags hcl.Diagnostics var diags hcl.Diagnostics
// split the source string into individual components // split the source string into individual components
parts := strings.Split(str, "/") parts := strings.Split(str, "/")
if len(parts) == 0 || len(parts) > 3 { if len(parts) != 3 {
diags = diags.Append(&hcl.Diagnostic{ diags = diags.Append(&hcl.Diagnostic{
Severity: hcl.DiagError, Severity: hcl.DiagError,
Summary: "Invalid plugin source string", 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 return nil, diags
} }
@ -142,7 +141,7 @@ func ParsePluginSourceString(str string) (*Plugin, hcl.Diagnostics) {
diags = diags.Append(&hcl.Diagnostic{ diags = diags.Append(&hcl.Diagnostic{
Severity: hcl.DiagError, Severity: hcl.DiagError,
Summary: "Invalid plugin source string", 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 return nil, diags
} }
@ -161,33 +160,21 @@ func ParsePluginSourceString(str string) (*Plugin, hcl.Diagnostics) {
} }
ret.Type = name ret.Type = name
if len(parts) == 1 { // the namespace is always the second-to-last part
return ret, diags 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
if len(parts) >= 2 { // the hostname is always the first part in a three-part source string
// the namespace is always the second-to-last part ret.Hostname = parts[0]
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
}
// Due to how plugin executables are named and plugin git repositories // Due to how plugin executables are named and plugin git repositories
// are conventionally named, it's a reasonable and // are conventionally named, it's a reasonable and

View File

@ -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)
}
})
}
}