Skip to content

Commit

Permalink
fix: git ls-files command output quoting on 'unusual' characters
Browse files Browse the repository at this point in the history
  • Loading branch information
l-hellmann committed May 29, 2024
1 parent fdf57e2 commit 65ec888
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 17 deletions.
20 changes: 10 additions & 10 deletions src/archiveClient/handler_findFilesByRules_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"github.com/zeropsio/zcli/src/uxBlock/mocks"
)

var testErrorResponseDataProvider = []struct {
var findByRulesTestCases = []struct {
name string
workingDir string
input []string
Expand All @@ -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",
},
},
{
Expand Down Expand Up @@ -137,6 +138,7 @@ var testErrorResponseDataProvider = []struct {
"dir/subDir/file3.2.txt",
"dir/subDir/file3.3.symlink.txt",
"file1.1.txt",
"non–ascii.txt",
},
},
{
Expand Down Expand Up @@ -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)
})
Expand Down
28 changes: 22 additions & 6 deletions src/archiveClient/handler_findGitFiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{}{}

Expand All @@ -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{}{}

Expand All @@ -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)))
Expand All @@ -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)))
Expand All @@ -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
Expand All @@ -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)
Expand Down
50 changes: 50 additions & 0 deletions src/archiveClient/handler_findGitFiles_test.go
Original file line number Diff line number Diff line change
@@ -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)
})
}
}
2 changes: 1 addition & 1 deletion src/archiveClient/handler_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Empty file.

0 comments on commit 65ec888

Please sign in to comment.