ParsePluginSourceString parses the source attribute and returns a plugin. This is intended primarily to parse the FQN-like strings The following are valid source string formats: namespace/name hostname/namespace/name
(str string)
| 112 | // namespace/name |
| 113 | // hostname/namespace/name |
| 114 | func ParsePluginSourceString(str string) (*Plugin, error) { |
| 115 | var errs []string |
| 116 | |
| 117 | if strings.HasPrefix(str, "/") { |
| 118 | errs = append(errs, "A source URL must not start with a '/' character.") |
| 119 | } |
| 120 | |
| 121 | if strings.HasSuffix(str, "/") { |
| 122 | errs = append(errs, "A source URL must not end with a '/' character.") |
| 123 | } |
| 124 | |
| 125 | if strings.Count(str, "/") < 2 { |
| 126 | errs = append(errs, "A source URL must at least contain a host and a path with 2 components") |
| 127 | } |
| 128 | |
| 129 | url, err := url.Parse(str) |
| 130 | if err != nil { |
| 131 | errs = append(errs, fmt.Sprintf("Failed to parse source URL: %s", err)) |
| 132 | } |
| 133 | |
| 134 | if url != nil && url.Scheme != "" { |
| 135 | errs = append(errs, "A source URL must not contain a scheme (e.g. https://).") |
| 136 | } |
| 137 | |
| 138 | if url != nil && url.RawQuery != "" { |
| 139 | errs = append(errs, "A source URL must not contain a query (e.g. ?var=val)") |
| 140 | } |
| 141 | |
| 142 | if url != nil && url.Fragment != "" { |
| 143 | errs = append(errs, "A source URL must not contain a fragment (e.g. #anchor).") |
| 144 | } |
| 145 | |
| 146 | if errs != nil { |
| 147 | errsMsg := &strings.Builder{} |
| 148 | for _, err := range errs { |
| 149 | fmt.Fprintf(errsMsg, "* %s\n", err) |
| 150 | } |
| 151 | |
| 152 | return nil, fmt.Errorf("The provided source URL is invalid.\nThe following errors have been discovered:\n%s\nA valid source looks like \"github.com/hashicorp/happycloud\"", errsMsg) |
| 153 | } |
| 154 | |
| 155 | // check the 'name' portion, which is always the last part |
| 156 | _, givenName := path.Split(str) |
| 157 | _, err = ParsePluginPart(givenName) |
| 158 | if err != nil { |
| 159 | return nil, fmt.Errorf(`Invalid plugin type %q in source: %s"`, givenName, err) |
| 160 | } |
| 161 | |
| 162 | // Due to how plugin executables are named and plugin git repositories |
| 163 | // are conventionally named, it's a reasonable and |
| 164 | // apparently-somewhat-common user error to incorrectly use the |
| 165 | // "packer-plugin-" prefix in a plugin source address. There is |
| 166 | // no good reason for a plugin to have the prefix "packer-" anyway, |
| 167 | // so we've made that invalid from the start both so we can give feedback |
| 168 | // to plugin developers about the packer- prefix being redundant |
| 169 | // and give specialized feedback to folks who incorrectly use the full |
| 170 | // packer-plugin- prefix to help them self-correct. |
| 171 | const redundantPrefix = "packer-" |
searching dependent graphs…