diff --git a/.github/workflows/go-test.yml b/.github/workflows/go-test.yml
index 44e7fefa8a421dd3e3b41b0955c45e86ae40b480..8e1b790e232ece52e991276a9b9eb7acade96da7 100644
--- a/.github/workflows/go-test.yml
+++ b/.github/workflows/go-test.yml
@@ -1,12 +1,15 @@
 #
-# This GitHub action runs Packer go tests across 
-# Windows, Linux, and MacOS runners. 
+# This GitHub action runs Packer go tests across
+# Windows, Linux, and MacOS runners.
 #
 
 name: "Go Test"
 
 on: [ workflow_dispatch, push ]
 
+env:
+  PACKER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
 jobs:
   linux-go-tests:
     runs-on: ubuntu-latest
@@ -19,8 +22,6 @@ jobs:
   darwin-go-tests:
     runs-on: macos-latest
     name: Darwin go tests
-    env:
-      PACKER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
     steps:
       - uses: actions/checkout@v2
       - uses: actions/setup-go@v2
@@ -35,4 +36,4 @@ jobs:
       - uses: actions/setup-go@v2
         with:
           go-version: '1.17'
-      - run: go test ./... -coverprofile=coverage.txt  -covermode=atomic
\ No newline at end of file
+      - run: go test ./... -coverprofile=coverage.txt  -covermode=atomic
diff --git a/command/plugins_install.go b/command/plugins_install.go
index f9fd0244724ad1d29209c2e5128e95693248aa60..a744b7d9ece96cb5f6021293e0bd70b29a3dd46c 100644
--- a/command/plugins_install.go
+++ b/command/plugins_install.go
@@ -29,7 +29,7 @@ func (c *PluginsInstallCommand) Help() string {
 	helpText := `
 Usage: packer plugins install <plugin> [<version constraint>]
 
-  This command will install the most recent compatible Packer plugin matching 
+  This command will install the most recent compatible Packer plugin matching
   version constraint.
   When the version constraint is omitted, the most recent version will be
   installed.
diff --git a/command/plugins_install_test.go b/command/plugins_install_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..e2b5dac9c3e36c4778aa1314e87aee644ad84018
--- /dev/null
+++ b/command/plugins_install_test.go
@@ -0,0 +1,176 @@
+package command
+
+import (
+	"log"
+	"os"
+	"runtime"
+	"sort"
+	"testing"
+
+	"github.com/google/go-cmp/cmp"
+	"github.com/mitchellh/cli"
+	"golang.org/x/mod/sumdb/dirhash"
+)
+
+type testCasePluginsInstall struct {
+	name                                     string
+	Meta                                     Meta
+	inPluginFolder                           map[string]string
+	expectedPackerConfigDirHashBeforeInstall string
+	packerConfigDir                          string
+	pluginSourceArgs                         []string
+	want                                     int
+	dirFiles                                 []string
+	expectedPackerConfigDirHashAfterInstall  string
+}
+
+func TestPluginsInstallCommand_Run(t *testing.T) {
+
+	cfg := &configDirSingleton{map[string]string{}}
+
+	tests := []testCasePluginsInstall{
+		{
+			name: "already-installed-no-op",
+			Meta: TestMetaFile(t),
+			inPluginFolder: map[string]string{
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_darwin_amd64":                "1",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_darwin_amd64_SHA256SUM":      "6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_windows_amd64.exe":           "1.exe",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_windows_amd64.exe_SHA256SUM": "07d8453027192ee0c4120242e6e84e2ca2328b8e0f506e2f818a1a5b82790a0b",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_linux_amd64":                 "1.out",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_linux_amd64_SHA256SUM":       "59031c50e0dfeedfde2b4e9445754804dce3f29e4efa737eead0ca9b4f5b85a5",
+			},
+			expectedPackerConfigDirHashBeforeInstall: "h1:Q5qyAOdD43hL3CquQdVfaHpOYGf0UsZ/+wVA9Ry6cbA=",
+			packerConfigDir:                          cfg.dir("1_pkr_plugins_config"),
+			pluginSourceArgs:                         []string{"github.com/sylviamoss/comment", "v0.2.18"},
+			want:                                     0,
+			dirFiles:                                 nil,
+			expectedPackerConfigDirHashAfterInstall:  "h1:Q5qyAOdD43hL3CquQdVfaHpOYGf0UsZ/+wVA9Ry6cbA=",
+		},
+		{
+			name: "install-newer-version",
+			Meta: TestMetaFile(t),
+			inPluginFolder: map[string]string{
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_darwin_amd64":                "1",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_darwin_amd64_SHA256SUM":      "6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_windows_amd64.exe":           "1.exe",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_windows_amd64.exe_SHA256SUM": "07d8453027192ee0c4120242e6e84e2ca2328b8e0f506e2f818a1a5b82790a0b",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_linux_amd64":                 "1.out",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_linux_amd64_SHA256SUM":       "59031c50e0dfeedfde2b4e9445754804dce3f29e4efa737eead0ca9b4f5b85a5",
+			},
+			expectedPackerConfigDirHashBeforeInstall: "h1:Q5qyAOdD43hL3CquQdVfaHpOYGf0UsZ/+wVA9Ry6cbA=",
+			packerConfigDir:                          cfg.dir("2_pkr_plugins_config"),
+			pluginSourceArgs:                         []string{"github.com/sylviamoss/comment", "v0.2.19"},
+			want:                                     0,
+			dirFiles: []string{
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_darwin_amd64",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_darwin_amd64_SHA256SUM",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_linux_amd64",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_linux_amd64_SHA256SUM",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_windows_amd64.exe",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_windows_amd64.exe_SHA256SUM",
+				map[string]string{
+					"darwin":  "github.com/sylviamoss/comment/packer-plugin-comment_v0.2.19_x5.0_darwin_amd64_SHA256SUM",
+					"linux":   "github.com/sylviamoss/comment/packer-plugin-comment_v0.2.19_x5.0_linux_amd64_SHA256SUM",
+					"windows": "github.com/sylviamoss/comment/packer-plugin-comment_v0.2.19_x5.0_windows_amd64.exe_SHA256SUM",
+				}[runtime.GOOS],
+				map[string]string{
+					"darwin":  "github.com/sylviamoss/comment/packer-plugin-comment_v0.2.19_x5.0_darwin_amd64",
+					"linux":   "github.com/sylviamoss/comment/packer-plugin-comment_v0.2.19_x5.0_linux_amd64",
+					"windows": "github.com/sylviamoss/comment/packer-plugin-comment_v0.2.19_x5.0_windows_amd64.exe",
+				}[runtime.GOOS],
+			},
+			expectedPackerConfigDirHashAfterInstall: map[string]string{
+				"darwin":  "h1:ORwcCYUx8z/5n/QvuTJo2vrgKpfJA4AxlNg1G9/BCDI=",
+				"linux":   "h1:CGym0+Nd0LEANgzqL0wx/LDjRL8bYwlpZ0HajPJo/hs=",
+				"windows": "h1:ag0/C1YjP7KoEDYOiJHE0K+lhFgs0tVgjriWCXVT1fg=",
+			}[runtime.GOOS],
+		},
+		{
+			name:                                     "unsupported-non-github-source-address",
+			Meta:                                     TestMetaFile(t),
+			inPluginFolder:                           nil,
+			expectedPackerConfigDirHashBeforeInstall: "h1:47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
+			packerConfigDir:                          cfg.dir("3_pkr_plugins_config"),
+			pluginSourceArgs:                         []string{"example.com/sylviamoss/comment", "v0.2.19"},
+			want:                                     1,
+			dirFiles:                                 nil,
+			expectedPackerConfigDirHashAfterInstall:  "h1:47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
+		},
+		{
+			name:                                     "multiple-source-addresses-provided",
+			Meta:                                     TestMetaFile(t),
+			inPluginFolder:                           nil,
+			expectedPackerConfigDirHashBeforeInstall: "h1:47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
+			packerConfigDir:                          cfg.dir("4_pkr_plugins_config"),
+			pluginSourceArgs:                         []string{"github.com/sylviamoss/comment", "v0.2.18", "github.com/sylviamoss/comment", "v0.2.19"},
+			want:                                     cli.RunResultHelp,
+			dirFiles:                                 nil,
+			expectedPackerConfigDirHashAfterInstall:  "h1:47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
+		},
+		{
+			name:                                     "no-source-address-provided",
+			Meta:                                     TestMetaFile(t),
+			inPluginFolder:                           nil,
+			expectedPackerConfigDirHashBeforeInstall: "h1:47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
+			packerConfigDir:                          cfg.dir("5_pkr_plugins_config"),
+			pluginSourceArgs:                         []string{},
+			want:                                     cli.RunResultHelp,
+			dirFiles:                                 nil,
+			expectedPackerConfigDirHashAfterInstall:  "h1:47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			log.Printf("starting %s", tt.name)
+			log.Printf("%#v", tt)
+			t.Cleanup(func() {
+				_ = os.RemoveAll(tt.packerConfigDir)
+			})
+			os.Setenv("PACKER_CONFIG_DIR", tt.packerConfigDir)
+			createFiles(tt.packerConfigDir, tt.inPluginFolder)
+
+			hash, err := dirhash.HashDir(tt.packerConfigDir, "", dirhash.DefaultHash)
+			if err != nil {
+				t.Fatalf("HashDir: %v", err)
+			}
+			if diff := cmp.Diff(tt.expectedPackerConfigDirHashBeforeInstall, hash); diff != "" {
+				t.Errorf("unexpected dir hash before plugins install: +found -expected %s", diff)
+			}
+
+			c := &PluginsInstallCommand{
+				Meta: tt.Meta,
+			}
+
+			if err := c.CoreConfig.Components.PluginConfig.Discover(); err != nil {
+				t.Fatalf("Failed to discover plugins: %s", err)
+			}
+
+			c.CoreConfig.Components.PluginConfig.KnownPluginFolders = []string{tt.packerConfigDir}
+			if got := c.Run(tt.pluginSourceArgs); got != tt.want {
+				t.Errorf("PluginsInstallCommand.Run() = %v, want %v", got, tt.want)
+			}
+
+			if tt.dirFiles != nil {
+				dirFiles, err := dirhash.DirFiles(tt.packerConfigDir, "")
+				if err != nil {
+					t.Fatalf("DirFiles: %v", err)
+				}
+				sort.Strings(tt.dirFiles)
+				sort.Strings(dirFiles)
+				if diff := cmp.Diff(tt.dirFiles, dirFiles); diff != "" {
+					t.Errorf("found files differ: %v", diff)
+				}
+			}
+
+			hash, err = dirhash.HashDir(tt.packerConfigDir, "", dirhash.DefaultHash)
+			if err != nil {
+				t.Fatalf("HashDir: %v", err)
+			}
+			if diff := cmp.Diff(tt.expectedPackerConfigDirHashAfterInstall, hash); diff != "" {
+				t.Errorf("unexpected dir hash after plugins install: %s", diff)
+			}
+		})
+	}
+}
diff --git a/command/plugins_remove_test.go b/command/plugins_remove_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..e33a0c229e9508578b3983abb61e377dd13b3a6f
--- /dev/null
+++ b/command/plugins_remove_test.go
@@ -0,0 +1,219 @@
+package command
+
+import (
+	"log"
+	"os"
+	"runtime"
+	"sort"
+	"testing"
+
+	"github.com/google/go-cmp/cmp"
+	"golang.org/x/mod/sumdb/dirhash"
+)
+
+type testCasePluginsRemove struct {
+	name                                    string
+	Meta                                    Meta
+	inPluginFolder                          map[string]string
+	expectedPackerConfigDirHashBeforeRemove string
+	packerConfigDir                         string
+	pluginSourceArgs                        []string
+	want                                    int
+	dirFiles                                []string
+	expectedPackerConfigDirHashAfterRemove  string
+}
+
+func TestPluginsRemoveCommand_Run(t *testing.T) {
+
+	cfg := &configDirSingleton{map[string]string{}}
+
+	tests := []testCasePluginsRemove{
+		{
+			name: "version-not-installed-no-op",
+			Meta: TestMetaFile(t),
+			inPluginFolder: map[string]string{
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_darwin_amd64":                "1",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_darwin_amd64_SHA256SUM":      "6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_windows_amd64.exe":           "1.exe",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_windows_amd64.exe_SHA256SUM": "07d8453027192ee0c4120242e6e84e2ca2328b8e0f506e2f818a1a5b82790a0b",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_linux_amd64":                 "1.out",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_linux_amd64_SHA256SUM":       "59031c50e0dfeedfde2b4e9445754804dce3f29e4efa737eead0ca9b4f5b85a5",
+			},
+			expectedPackerConfigDirHashBeforeRemove: "h1:Q5qyAOdD43hL3CquQdVfaHpOYGf0UsZ/+wVA9Ry6cbA=",
+			packerConfigDir:                         cfg.dir("1_pkr_plugins_config"),
+			pluginSourceArgs:                        []string{"github.com/sylviamoss/comment", "v0.2.19"},
+			want:                                    0,
+			dirFiles:                                nil,
+			expectedPackerConfigDirHashAfterRemove:  "h1:Q5qyAOdD43hL3CquQdVfaHpOYGf0UsZ/+wVA9Ry6cbA=",
+		},
+		{
+			name: "remove-specific-version",
+			Meta: TestMetaFile(t),
+			inPluginFolder: map[string]string{
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_darwin_amd64":                "1",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_darwin_amd64_SHA256SUM":      "6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_windows_amd64.exe":           "1.exe",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_windows_amd64.exe_SHA256SUM": "07d8453027192ee0c4120242e6e84e2ca2328b8e0f506e2f818a1a5b82790a0b",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_linux_amd64":                 "1.out",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_linux_amd64_SHA256SUM":       "59031c50e0dfeedfde2b4e9445754804dce3f29e4efa737eead0ca9b4f5b85a5",
+			},
+			expectedPackerConfigDirHashBeforeRemove: "h1:Q5qyAOdD43hL3CquQdVfaHpOYGf0UsZ/+wVA9Ry6cbA=",
+			packerConfigDir:                         cfg.dir("2_pkr_plugins_config"),
+			pluginSourceArgs:                        []string{"github.com/sylviamoss/comment", "v0.2.18"},
+			want:                                    0,
+			dirFiles: map[string][]string{
+				"darwin": {
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_darwin_amd64_SHA256SUM",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_linux_amd64",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_linux_amd64_SHA256SUM",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_windows_amd64.exe",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_windows_amd64.exe_SHA256SUM",
+				},
+				"linux": {
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_darwin_amd64",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_darwin_amd64_SHA256SUM",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_linux_amd64_SHA256SUM",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_windows_amd64.exe",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_windows_amd64.exe_SHA256SUM",
+				},
+				"windows": {
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_darwin_amd64",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_darwin_amd64_SHA256SUM",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_linux_amd64",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_linux_amd64_SHA256SUM",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_windows_amd64.exe_SHA256SUM",
+				},
+			}[runtime.GOOS],
+			expectedPackerConfigDirHashAfterRemove: map[string]string{
+				"darwin":  "h1:IMsWPgJZzRhn80t78zE45003gFKN6EXq562/wjaCrKE=",
+				"linux":   "h1:Ez7SU1GZLvNGJmoTm9PeFIwHv9fvEgzZAZTMl6874iM=",
+				"windows": "h1:RrXlhy9tG9Bi3c2aOzjx/FLLyVNQolcY+MAr4V1etRI=",
+			}[runtime.GOOS],
+		},
+		{
+			name: "remove-all-installed-versions",
+			Meta: TestMetaFile(t),
+			inPluginFolder: map[string]string{
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_darwin_amd64":                "1",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_darwin_amd64_SHA256SUM":      "6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.19_x5.0_darwin_amd64":                "1",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.19_x5.0_darwin_amd64_SHA256SUM":      "6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_windows_amd64.exe":           "1.exe",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_windows_amd64.exe_SHA256SUM": "07d8453027192ee0c4120242e6e84e2ca2328b8e0f506e2f818a1a5b82790a0b",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.19_x5.0_windows_amd64.exe":           "1.exe",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.19_x5.0_windows_amd64.exe_SHA256SUM": "07d8453027192ee0c4120242e6e84e2ca2328b8e0f506e2f818a1a5b82790a0b",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_linux_amd64":                 "1.out",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_linux_amd64_SHA256SUM":       "59031c50e0dfeedfde2b4e9445754804dce3f29e4efa737eead0ca9b4f5b85a5",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.19_x5.0_linux_amd64":                 "1.out",
+				"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.19_x5.0_linux_amd64_SHA256SUM":       "59031c50e0dfeedfde2b4e9445754804dce3f29e4efa737eead0ca9b4f5b85a5",
+			},
+			expectedPackerConfigDirHashBeforeRemove: "h1:IEvr6c46+Uk776Hnzy04PuXqnyHGKnnEvIJ713cv0iU=",
+			packerConfigDir:                         cfg.dir("2_pkr_plugins_config"),
+			pluginSourceArgs:                        []string{"github.com/sylviamoss/comment"},
+			want:                                    0,
+			dirFiles: map[string][]string{
+				"darwin": {
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_darwin_amd64_SHA256SUM",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.19_x5.0_darwin_amd64_SHA256SUM",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_linux_amd64",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_linux_amd64_SHA256SUM",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.19_x5.0_linux_amd64",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.19_x5.0_linux_amd64_SHA256SUM",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_windows_amd64.exe",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_windows_amd64.exe_SHA256SUM",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.19_x5.0_windows_amd64.exe",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.19_x5.0_windows_amd64.exe_SHA256SUM",
+				},
+				"linux": {
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_darwin_amd64",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_darwin_amd64_SHA256SUM",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.19_x5.0_darwin_amd64",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.19_x5.0_darwin_amd64_SHA256SUM",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_linux_amd64_SHA256SUM",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.19_x5.0_linux_amd64_SHA256SUM",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_windows_amd64.exe",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_windows_amd64.exe_SHA256SUM",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.19_x5.0_windows_amd64.exe",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.19_x5.0_windows_amd64.exe_SHA256SUM",
+				},
+				"windows": {
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_darwin_amd64",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_darwin_amd64_SHA256SUM",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.19_x5.0_darwin_amd64",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.19_x5.0_darwin_amd64_SHA256SUM",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_linux_amd64",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_linux_amd64_SHA256SUM",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.19_x5.0_linux_amd64",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.19_x5.0_linux_amd64_SHA256SUM",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_windows_amd64.exe_SHA256SUM",
+					"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.19_x5.0_windows_amd64.exe_SHA256SUM",
+				},
+			}[runtime.GOOS],
+			expectedPackerConfigDirHashAfterRemove: map[string]string{
+				"darwin":  "h1:FBBGQ1SKngN9PvF98awv8TZcKaS+CKzJmQoS7vuSXqY=",
+				"linux":   "h1:F8lN4Q3sv45ig8r1BLOS/wFuQQy6tSfmuIJf3fnbD5k=",
+				"windows": "h1:DOfH6WR1eJNLJcaL8ar8j1xu2WB7Jcn6oG7LGEvNBZI=",
+			}[runtime.GOOS],
+		},
+		{
+			name:                                    "no-installed-binaries",
+			Meta:                                    TestMetaFile(t),
+			inPluginFolder:                          nil,
+			expectedPackerConfigDirHashBeforeRemove: "h1:47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
+			packerConfigDir:                         cfg.dir("3_pkr_plugins_config"),
+			pluginSourceArgs:                        []string{"example.com/sylviamoss/comment", "v0.2.19"},
+			want:                                    0,
+			dirFiles:                                nil,
+			expectedPackerConfigDirHashAfterRemove:  "h1:47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			log.Printf("starting %s", tt.name)
+			log.Printf("%#v", tt)
+			t.Cleanup(func() {
+				_ = os.RemoveAll(tt.packerConfigDir)
+			})
+			os.Setenv("PACKER_CONFIG_DIR", tt.packerConfigDir)
+			createFiles(tt.packerConfigDir, tt.inPluginFolder)
+
+			hash, err := dirhash.HashDir(tt.packerConfigDir, "", dirhash.DefaultHash)
+			if err != nil {
+				t.Fatalf("HashDir: %v", err)
+			}
+			if diff := cmp.Diff(tt.expectedPackerConfigDirHashBeforeRemove, hash); diff != "" {
+				t.Errorf("unexpected dir hash before plugins remove: +found -expected %s", diff)
+			}
+
+			c := &PluginsRemoveCommand{
+				Meta: tt.Meta,
+			}
+
+			c.CoreConfig.Components.PluginConfig.KnownPluginFolders = []string{tt.packerConfigDir}
+			if got := c.Run(tt.pluginSourceArgs); got != tt.want {
+				t.Errorf("PluginsRemoveCommand.Run() = %v, want %v", got, tt.want)
+			}
+
+			if tt.dirFiles != nil {
+				dirFiles, err := dirhash.DirFiles(tt.packerConfigDir, "")
+				if err != nil {
+					t.Fatalf("DirFiles: %v", err)
+				}
+				sort.Strings(tt.dirFiles)
+				sort.Strings(dirFiles)
+				if diff := cmp.Diff(tt.dirFiles, dirFiles); diff != "" {
+					t.Errorf("found files differ: %v", diff)
+				}
+			}
+
+			hash, err = dirhash.HashDir(tt.packerConfigDir, "", dirhash.DefaultHash)
+			if err != nil {
+				t.Fatalf("HashDir: %v", err)
+			}
+			if diff := cmp.Diff(tt.expectedPackerConfigDirHashAfterRemove, hash); diff != "" {
+				t.Errorf("unexpected dir hash after plugins remove: %s", diff)
+			}
+		})
+	}
+}