diff --git a/src/archiveClient/handler_findFilesByRules_test.go b/src/archiveClient/handler_findFilesByRules_test.go index 6de1eae7..7416f4dd 100644 --- a/src/archiveClient/handler_findFilesByRules_test.go +++ b/src/archiveClient/handler_findFilesByRules_test.go @@ -8,7 +8,7 @@ import ( "github.com/zeropsio/zcli/src/uxBlock/mocks" ) -var testErrorResponseDataProvider = []struct { +var findByRulesTestCases = []struct { name string workingDir string input []string @@ -33,6 +33,7 @@ var testErrorResponseDataProvider = []struct { "test/var/www/dir/subDir/file3.2.txt", "test/var/www/dir/subDir/file3.3.symlink.txt", "test/var/www/file1.1.txt", + "test/var/www/non–ascii.txt", }, }, { @@ -137,6 +138,7 @@ var testErrorResponseDataProvider = []struct { "dir/subDir/file3.2.txt", "dir/subDir/file3.3.symlink.txt", "file1.1.txt", + "non–ascii.txt", }, }, { @@ -220,25 +222,23 @@ var testErrorResponseDataProvider = []struct { }, } -func TestValidation(t *testing.T) { +func TestFindFilesByRules(t *testing.T) { ctrl := gomock.NewController(t) uxBlocks := mocks.NewMockUxBlocks(ctrl) uxBlocks.EXPECT().PrintInfo(gomock.Any()).AnyTimes() - for _, test := range testErrorResponseDataProvider { + for _, test := range findByRulesTestCases { test := test // scope lint - t.Run(test.name+" in "+test.workingDir, func(t *testing.T) { + t.Run(test.name+"-in-"+test.workingDir, func(t *testing.T) { archiver := New(Config{}) files, err := archiver.FindFilesByRules(uxBlocks, test.workingDir, test.input) require.NoError(t, err) - output := func() (res []string) { - for _, f := range files { - res = append(res, f.ArchivePath) - } - return - }() + output := make([]string, 0, len(files)) + for _, f := range files { + output = append(output, f.ArchivePath) + } require.Equal(t, test.output, output) }) diff --git a/src/archiveClient/handler_findGitFiles.go b/src/archiveClient/handler_findGitFiles.go index f43cdb71..11fcbf3f 100644 --- a/src/archiveClient/handler_findGitFiles.go +++ b/src/archiveClient/handler_findGitFiles.go @@ -37,7 +37,8 @@ func (h *Handler) FindGitFiles(ctx context.Context, workingDir string) (res []Fi // find excluded files excludedFiles := make(map[string]struct{}) if err := h.listFiles( - createCmd("git", "ls-files", "--deleted", "--exclude-standard"), + createCmd("git", "ls-files", "--deleted", "--exclude-standard", "-z"), + replaceNullBytesWithNewLine, func(path string) error { excludedFiles[path] = struct{}{} @@ -48,7 +49,8 @@ func (h *Handler) FindGitFiles(ctx context.Context, workingDir string) (res []Fi } if err := h.listFiles( - createCmd("git", "ls-files", "--others", "--ignored", "--exclude-standard"), + createCmd("git", "ls-files", "--others", "--ignored", "--exclude-standard", "-z"), + replaceNullBytesWithNewLine, func(path string) error { excludedFiles[path] = struct{}{} @@ -60,7 +62,8 @@ func (h *Handler) FindGitFiles(ctx context.Context, workingDir string) (res []Fi // add all non deleted if err := h.listFiles( - createCmd("git", "ls-files", "--exclude-standard", "--recurse-submodules"), + createCmd("git", "ls-files", "--exclude-standard", "--recurse-submodules", "-z"), + replaceNullBytesWithNewLine, func(path string) error { if _, exists := excludedFiles[path]; !exists { res = append(res, createFile(filepath.Join(workingDir, path))) @@ -73,7 +76,8 @@ func (h *Handler) FindGitFiles(ctx context.Context, workingDir string) (res []Fi // add untracked files if err := h.listFiles( - createCmd("git", "ls-files", "--others", "--exclude-standard"), + createCmd("git", "ls-files", "--others", "--exclude-standard", "-z"), + replaceNullBytesWithNewLine, func(path string) error { if _, exists := excludedFiles[path]; !exists { res = append(res, createFile(filepath.Join(workingDir, path))) @@ -90,6 +94,7 @@ func (h *Handler) FindGitFiles(ctx context.Context, workingDir string) (res []Fi if h.config.DeployGitFolder { if err := h.listFiles( createCmd("find", ".git/"), + bytesReader, func(path string) error { res = append(res, createFile(filepath.Join(workingDir, path))) return nil @@ -102,13 +107,24 @@ func (h *Handler) FindGitFiles(ctx context.Context, workingDir string) (res []Fi return res, nil } -func (h *Handler) listFiles(cmd *cmdRunner.ExecCmd, fn func(path string) error) error { +// replaceNullBytesWithNewLine used in combination of '-z' flag with git command +// '-z' flag returns null terminated unquoted strings +func replaceNullBytesWithNewLine(output []byte) io.Reader { + output = bytes.ReplaceAll(output, []byte{0}, []byte{'\n'}) + return bytes.NewReader(output) +} + +func bytesReader(out []byte) io.Reader { + return bytes.NewReader(out) +} + +func (h *Handler) listFiles(cmd *cmdRunner.ExecCmd, reader func(out []byte) io.Reader, fn func(path string) error) error { output, err := cmdRunner.Run(cmd) if err != nil { return err } - rd := bufio.NewReader(bytes.NewReader(output)) + rd := bufio.NewReader(reader(output)) for { lineB, _, err := rd.ReadLine() line := string(lineB) diff --git a/src/archiveClient/handler_findGitFiles_test.go b/src/archiveClient/handler_findGitFiles_test.go new file mode 100644 index 00000000..f52bae63 --- /dev/null +++ b/src/archiveClient/handler_findGitFiles_test.go @@ -0,0 +1,50 @@ +package archiveClient + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" +) + +var findGitFilesTestCases = []struct { + name string + workingDir string + output []string +}{ + { + name: "non-ascii", + workingDir: "test/var/www", + output: []string{ + "dir/", + "dir/file2.1.txt", + "dir/file2.2.txt", + "dir/subDir/", + "dir/subDir/file3.1.txt", + "dir/subDir/file3.2.txt", + "dir/subDir/file3.3.symlink.txt", + "file1.1.txt", + "non–ascii.txt", + }, + }, +} + +func TestFindGitFiles(t *testing.T) { + ctx := context.TODO() + for _, test := range findGitFilesTestCases { + t.Run(test.name+"-in-"+test.workingDir, func(t *testing.T) { + assert := require.New(t) + archiver := New(Config{}) + + files, err := archiver.FindGitFiles(ctx, test.workingDir) + assert.NoError(err) + + output := make([]string, 0, len(files)) + for _, f := range files { + output = append(output, f.ArchivePath) + } + + assert.Equal(test.output, output) + }) + } +} diff --git a/src/archiveClient/handler_utils.go b/src/archiveClient/handler_utils.go index 0c19bcda..5b9241eb 100644 --- a/src/archiveClient/handler_utils.go +++ b/src/archiveClient/handler_utils.go @@ -6,7 +6,7 @@ import ( "strings" ) -// fixes paths/dirs that may be missing between source root and deployed files (all dirs are needed for valid TAR file) +// fixMissingDirPath fixes paths/dirs that may be missing between source root and deployed files (all dirs are needed for valid TAR file) // provided createFile func will receive a valid File.SourcePath and MUST strip workDir to form a valid File.ArchivePath // createdPath is used as a cache to not create paths multiple times for multiple calls of the function func (h *Handler) fixMissingDirPath(files []File, createFile func(filePath string) File, createdPaths map[string]struct{}) []File { diff --git "a/src/archiveClient/test/var/www/non\342\200\223ascii.txt" "b/src/archiveClient/test/var/www/non\342\200\223ascii.txt" new file mode 100644 index 00000000..e69de29b