Skip to content

Commit

Permalink
add glob support for Local
Browse files Browse the repository at this point in the history
  • Loading branch information
umputun committed May 4, 2023
1 parent 04a6e5a commit dbff054
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 12 deletions.
22 changes: 20 additions & 2 deletions app/executor/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,31 @@ func (l *Local) Run(ctx context.Context, cmd string, verbose bool) (out []string

// Upload just copy file from one place to another
func (l *Local) Upload(_ context.Context, src, dst string, mkdir bool) (err error) {

// check if the local parameter contains a glob pattern
matches, err := filepath.Glob(src)
if err != nil {
return fmt.Errorf("failed to expand glob pattern %s: %w", src, err)
}

if len(matches) == 0 { // no match
return fmt.Errorf("source file %q not found", src)
}

if mkdir {
if err = os.MkdirAll(filepath.Dir(dst), 0o750); err != nil {
return fmt.Errorf("can't create local dir %s: %w", filepath.Dir(dst), err)
}
}
if err = l.copyFile(src, dst); err != nil {
return fmt.Errorf("can't copy local file from %s to %s: %w", src, dst, err)

for _, match := range matches {
destination := dst
if len(matches) > 1 {
destination = filepath.Join(dst, filepath.Base(match))
}
if err = l.copyFile(match, destination); err != nil {
return fmt.Errorf("can't copy local file from %s to %s: %w", match, dst, err)
}
}
return nil
}
Expand Down
96 changes: 96 additions & 0 deletions app/executor/local_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package executor

import (
"context"
"fmt"
"os"
"path/filepath"
"testing"
Expand Down Expand Up @@ -131,6 +132,101 @@ func TestUploadAndDownload(t *testing.T) {
}
}

func TestUploadDownloadWithGlob(t *testing.T) {
// create some temporary test files with content
tmpDir, err := os.MkdirTemp("", "test")
require.NoError(t, err)
defer os.RemoveAll(tmpDir)

data1File := filepath.Join(tmpDir, "data1.txt")
err = os.WriteFile(data1File, []byte("data1 content"), 0644)
require.NoError(t, err)

data2File := filepath.Join(tmpDir, "data2.txt")
err = os.WriteFile(data2File, []byte("data2 content"), 0644)
require.NoError(t, err)

// create a temporary destination directory
dstDir, err := os.MkdirTemp("", "dst")
require.NoError(t, err)
defer os.RemoveAll(dstDir)

type fn func(ctx context.Context, src, dst string, mkdir bool) (err error)

l := &Local{}
fns := []struct {
name string
fn fn
}{{"upload", l.Upload}}

for _, tc := range []struct {
name string
src string
dst string
mkdir bool
expectError bool
}{
{
name: "successful upload with mkdir=true",
src: filepath.Join(tmpDir, "*.txt"),
dst: dstDir,
mkdir: true,
},
{
name: "successful upload with mkdir=false",
src: filepath.Join(tmpDir, "*.txt"),
dst: dstDir,
},
{
name: "failed upload with non-existent source file",
src: filepath.Join(tmpDir, "nonexistent.txt"),
dst: dstDir,
mkdir: false,
expectError: true,
},
{
name: "failed upload with non-existent directory and mkdir=false",
src: filepath.Join(tmpDir, "*.txt"),
dst: filepath.Join(tmpDir, "nonexistent", "dst"),
mkdir: false,
expectError: true,
},
{
name: "failed upload with invalid glob pattern",
src: filepath.Join(tmpDir, "*.txt["),
dst: dstDir,
mkdir: false,
expectError: true,
},
} {
for _, fn := range fns {
t.Run(fmt.Sprintf("%s#%s", tc.name, fn.name), func(t *testing.T) {
err := fn.fn(context.Background(), tc.src, tc.dst, tc.mkdir)

if tc.expectError {
assert.Error(t, err, "expected an error")
return
}

assert.NoError(t, err, "unexpected error")

// assert that all files were uploaded
files, err := os.ReadDir(dstDir)
require.NoError(t, err)
assert.Len(t, files, 2, "unexpected number of uploaded files")

// assert that the contents of the uploaded files match the contents of the source files
for _, f := range files {
dstContent, err := os.ReadFile(filepath.Join(dstDir, f.Name()))
require.NoError(t, err)
assert.Equal(t, fmt.Sprintf("data%d content", f.Name()[4]-'0'), string(dstContent),
"uploaded content should match source content")
}
})
}
}
}

func TestLocal_Sync(t *testing.T) {

testCases := []struct {
Expand Down
5 changes: 0 additions & 5 deletions app/executor/testdata/data.txt

This file was deleted.

1 change: 1 addition & 0 deletions app/executor/testdata/data1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
data1 content
6 changes: 1 addition & 5 deletions app/executor/testdata/data2.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1 @@
--start of data file2--
some data file
blah
blah
--end of data file2--
data2 content

0 comments on commit dbff054

Please sign in to comment.