From f0d8f56c34fc0d7ca8e7ecdded6aa26bba1a70de Mon Sep 17 00:00:00 2001 From: Aliaksei Date: Mon, 12 Sep 2022 18:16:07 +0300 Subject: [PATCH] Fix support for forward slashes in cd_files for Windows (#115) Packer recommends that we use "/" as the path separator. There is a problem with using it on Windows because of the following behaviour: We might pass paths with forward slashes in `StepCreateCD` struct The string `rootFolder, err := tmp.Dir("packer_to_cdrom")` makes rootFolder use system-based slashes, which is "\" for Windows. This rootFolder is passed to `s.AddFile(rootFolder, toAdd)` And a mix of two slashes ruins our replace logic while going through the `visit` function. We end up having different slashes for `allDirs` and `discardPath` in `intermediaryDirs := strings.Replace(allDirs, discardPath, "", 1)` We change our replace login to don't depend on slashes. The tests we had didn't cover such cases as we passed all files with paths constructed with filepath.Join(dir, fname) which returns paths with "\\" on Windows. So we added a test case to specifically check forward slashes. --- multistep/commonsteps/step_create_cdrom.go | 4 ++- .../commonsteps/step_create_cdrom_test.go | 30 +++++++++++-------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/multistep/commonsteps/step_create_cdrom.go b/multistep/commonsteps/step_create_cdrom.go index 8950a60e8..4da3d3906 100644 --- a/multistep/commonsteps/step_create_cdrom.go +++ b/multistep/commonsteps/step_create_cdrom.go @@ -260,7 +260,9 @@ func (s *StepCreateCD) AddFile(dst, src string) error { // Clean up pathing so that we preserve the base directory provided by // the user but not the local pathing to that directory. allDirs, base := filepath.Split(pathname) - intermediaryDirs := strings.Replace(allDirs, discardPath, "", 1) + allDirsSlashSafe := filepath.ToSlash(allDirs) + discardPathSlashSafe := filepath.ToSlash(discardPath) + intermediaryDirs := strings.Replace(allDirsSlashSafe, discardPathSlashSafe, "", 1) dstPath := filepath.Join(dst, base) if intermediaryDirs != "" { diff --git a/multistep/commonsteps/step_create_cdrom_test.go b/multistep/commonsteps/step_create_cdrom_test.go index ccd953ef0..d384a5387 100644 --- a/multistep/commonsteps/step_create_cdrom_test.go +++ b/multistep/commonsteps/step_create_cdrom_test.go @@ -93,16 +93,17 @@ func TestStepCreateCD(t *testing.T) { defer os.RemoveAll(dir) createFiles(t, dir, map[string]string{ - "test folder/b/test1": "1", - "test folder/b/test2": "2", - "test folder 2/x": "3", - "test_cd_roms.tmp": "4", - "test cd files.tmp": "5", - "Test-Test-Test5.tmp": "6", - "subfolder/meta-data": "subfolder/meta-data from files", - "subfolder/user-data": "subfolder/user-data from files", - "user-data": "user-data from files", - "vendor-data": "vendor-data from files", + "test folder/b/test1": "1", + "test folder/b/test2": "2", + "test folder 2/x": "3", + "test_cd_roms.tmp": "4", + "test cd files.tmp": "5", + "Test-Test-Test5.tmp": "6", + "fwdslashes/nested/test": "7", + "subfolder/meta-data": "subfolder/meta-data from files", + "subfolder/user-data": "subfolder/user-data from files", + "user-data": "user-data from files", + "vendor-data": "vendor-data from files", }) step.Content = map[string]string{ "subfolder not created by files/test.tmp": "test", @@ -110,11 +111,15 @@ func TestStepCreateCD(t *testing.T) { "user-data": "user-data from content", } - files := []string{"test folder", "test folder 2/", "test_cd_roms.tmp", "test cd files.tmp", "Test-Test-Test5.tmp", "subfolder", "user-data", "vendor-data"} + files := []string{"test folder", "test folder 2/", "test_cd_roms.tmp", "test cd files.tmp", "Test-Test-Test5.tmp", "fwdslashes", "subfolder", "user-data", "vendor-data"} step.Files = make([]string, len(files)) for i, fname := range files { - step.Files[i] = filepath.Join(dir, fname) + fullPath := filepath.Join(dir, fname) + if fname == "fwdslashes" { + fullPath = filepath.ToSlash(fullPath) + } + step.Files[i] = fullPath } action := step.Run(context.Background(), state) @@ -139,6 +144,7 @@ func TestStepCreateCD(t *testing.T) { "test_cd_roms.tmp": "4", "test cd files.tmp": "5", "Test-Test-Test5.tmp": "6", + "fwdslashes/nested/test": "7", "subfolder not created by files/test.tmp": "test", "subfolder/meta-data": "subfolder/meta-data from content", "subfolder/user-data": "subfolder/user-data from files",