diff --git a/config.go b/config.go index 33e88505f..1f47de5a5 100644 --- a/config.go +++ b/config.go @@ -61,10 +61,14 @@ func (c *config) LoadExternalComponentsFromConfig() { var externallyUsed = make([]string, 0, len(pluginPaths)) for _, pluginPath := range pluginPaths { - if name, ok := c.loadExternalComponent(pluginPath); ok { - log.Printf("[DEBUG] Loaded plugin: %s = %s", name, pluginPath) - externallyUsed = append(externallyUsed, name) + name, err := c.loadSingleComponent(pluginPath) + if err != nil { + log.Print(err) + continue } + + log.Printf("loaded plugin: %s = %s", name, pluginPath) + externallyUsed = append(externallyUsed, name) } if len(externallyUsed) > 0 { @@ -73,14 +77,17 @@ func (c *config) LoadExternalComponentsFromConfig() { } } -func (c *config) loadExternalComponent(path string) (string, bool) { +func (c *config) loadSingleComponent(path string) (string, error) { pluginName := filepath.Base(path) // On Windows, ignore any plugins that don't end in .exe. // We could do a full PATHEXT parse, but this is probably good enough. if runtime.GOOS == "windows" && strings.ToLower(filepath.Ext(pluginName)) != ".exe" { - log.Printf("[DEBUG] Ignoring plugin %s, no exe extension", path) - return "", false + return "", fmt.Errorf("error loading plugin %q, no exe extension", path) + } + + if _, err := os.Stat(path); err != nil { + return "", fmt.Errorf("error loading plugin %q: %s", path, err) } // If the filename has a ".", trim up to there @@ -106,7 +113,7 @@ func (c *config) loadExternalComponent(path string) (string, bool) { } } - return pluginName, true + return pluginName, nil } // Discover discovers plugins. diff --git a/config_test.go b/config_test.go index 7a4e10172..cd0785796 100644 --- a/config_test.go +++ b/config_test.go @@ -63,13 +63,14 @@ func TestLoadExternalComponentsFromConfig(t *testing.T) { t.Errorf("failed to load external builders; got %v as the resulting config", cfg.Builders) } + if len(cfg.PostProcessors) != 1 || !cfg.PostProcessors.Has("noop") { + t.Errorf("failed to load external post-processors; got %v as the resulting config", cfg.PostProcessors) + } + if len(cfg.Provisioners) != 1 || !cfg.Provisioners.Has("super-shell") { t.Errorf("failed to load external provisioners; got %v as the resulting config", cfg.Provisioners) } - if len(cfg.PostProcessors) != 1 || !cfg.PostProcessors.Has("noop") { - t.Errorf("failed to load external post-processors; got %v as the resulting config", cfg.PostProcessors) - } } func TestLoadExternalComponentsFromConfig_onlyProvisioner(t *testing.T) { @@ -94,17 +95,53 @@ func TestLoadExternalComponentsFromConfig_onlyProvisioner(t *testing.T) { cfg.LoadExternalComponentsFromConfig() - if len(cfg.Builders) != 0 || cfg.Builders.Has("cloud-xyz") { + if len(cfg.Builders) != 0 { t.Errorf("loaded external builders when it wasn't supposed to; got %v as the resulting config", cfg.Builders) } + if len(cfg.PostProcessors) != 0 { + t.Errorf("loaded external post-processors when it wasn't supposed to; got %v as the resulting config", cfg.PostProcessors) + } + if len(cfg.Provisioners) != 1 || !cfg.Provisioners.Has("super-shell") { t.Errorf("failed to load external provisioners; got %v as the resulting config", cfg.Provisioners) } +} - if len(cfg.PostProcessors) != 0 || cfg.PostProcessors.Has("noop") { - t.Errorf("loaded external post-processors when it wasn't supposed to; got %v as the resulting config", cfg.PostProcessors) +func TestLoadSingleComponent(t *testing.T) { + + tmpFile, err := ioutil.TempFile(".", "packer-builder-") + if err != nil { + t.Fatalf("failed to create test file with error: %s", err) } + defer os.Remove(tmpFile.Name()) + + tt := []struct { + pluginPath string + errorExpected bool + }{ + {pluginPath: tmpFile.Name(), errorExpected: false}, + {pluginPath: "./non-existing-file", errorExpected: true}, + } + + var cfg config + cfg.Builders = packer.MapOfBuilder{} + cfg.PostProcessors = packer.MapOfPostProcessor{} + cfg.Provisioners = packer.MapOfProvisioner{} + + for _, tc := range tt { + tc := tc + _, err := cfg.loadSingleComponent(tc.pluginPath) + if tc.errorExpected && err == nil { + t.Errorf("expected loadSingleComponent(%s) to error but it didn't", tc.pluginPath) + continue + } + + if err != nil && !tc.errorExpected { + t.Errorf("expected loadSingleComponent(%s) to load properly but got an error: %v", tc.pluginPath, err) + } + } + } /* generateFakePackerConfigData creates a collection of mock plugins along with a basic packerconfig.