From ed10ca130d45d853d217def35737954dcd862c13 Mon Sep 17 00:00:00 2001 From: Aliaksei Savanchuk Date: Wed, 6 Jul 2022 22:32:30 +0300 Subject: [PATCH] Fix possibility to use forward slashes in cd_files for Windows 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",