Skip to content

Commit d09ec89

Browse files
committed
feat: add CreateUploadDirectories to mkdir inside UploadFile
Fixes: #22
1 parent 7ea67a1 commit d09ec89

File tree

3 files changed

+68
-4
lines changed

3 files changed

+68
-4
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,6 @@ go.work
2323
/bin/
2424
coverage.txt
2525
gitleaks.tar.gz
26-
/lint-project.sh
26+
/lint-project.sh
27+
28+
/testdata/ftp-server/newdir/

client.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ type ClientConfig struct {
3232
CAFile string
3333

3434
TLSConfig *tls.Config
35+
36+
CreateUploadDirectories bool
3537
}
3638

3739
type Client interface {
@@ -317,7 +319,7 @@ func (cc *client) UploadFile(path string, contents io.ReadCloser) (err error) {
317319

318320
dir, filename := filepath.Split(path)
319321
if dir != "" {
320-
// Jump to previous directory after command is done
322+
// Record the current directory we will jump back to after
321323
wd, err := conn.CurrentDir()
322324
if err != nil {
323325
return err
@@ -329,6 +331,14 @@ func (cc *client) UploadFile(path string, contents io.ReadCloser) (err error) {
329331
}
330332
}(wd)
331333

334+
// Create any directories if needed
335+
if cc.cfg.CreateUploadDirectories {
336+
err := conn.MakeDir(dir)
337+
if err != nil {
338+
return fmt.Errorf("FTP: mkdir %s (from %s) failed: %w", dir, wd, err)
339+
}
340+
}
341+
332342
// Move into directory to run the command
333343
if err := conn.ChangeDir(dir); err != nil {
334344
return err

client_test.go

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,12 @@ import (
2424
)
2525

2626
func TestClient(t *testing.T) {
27-
client, err := go_ftp.NewClient(go_ftp.ClientConfig{
27+
config := go_ftp.ClientConfig{
2828
Hostname: "127.0.0.1:2121",
2929
Username: "admin",
3030
Password: "123456",
31-
})
31+
}
32+
client, err := go_ftp.NewClient(config)
3233
require.NotNil(t, client)
3334
require.NoError(t, err)
3435

@@ -127,6 +128,55 @@ func TestClient(t *testing.T) {
127128
require.ErrorContains(t, err, "retrieving new.txt failed: 551 File not available")
128129
})
129130

131+
t.Run("mkdir and upload", func(t *testing.T) {
132+
client, err := go_ftp.NewClient(go_ftp.ClientConfig{
133+
Hostname: config.Hostname,
134+
Username: config.Username,
135+
Password: config.Password,
136+
137+
CreateUploadDirectories: true,
138+
})
139+
require.NotNil(t, client)
140+
require.NoError(t, err)
141+
142+
// Make sure we've delted newdir from any previous test runs
143+
require.NoError(t, os.RemoveAll(filepath.Join("testdata", "ftp-server", "newdir")))
144+
145+
// Upload files into new directories
146+
err = client.UploadFile("newdir/first.txt", io.NopCloser(strings.NewReader("first newdir data")))
147+
require.NoError(t, err)
148+
149+
err = client.UploadFile("newdir/a/second.txt", io.NopCloser(strings.NewReader("second newdir data")))
150+
require.NoError(t, err)
151+
152+
err = client.UploadFile("newdir/a/b/third.txt", io.NopCloser(strings.NewReader("third newdir data")))
153+
require.NoError(t, err)
154+
155+
// read all files
156+
file, err := client.Open("newdir/first.txt")
157+
require.NoError(t, err)
158+
159+
bs, err := io.ReadAll(file)
160+
require.NoError(t, err)
161+
require.Equal(t, "first newdir data", string(bs))
162+
163+
// second file
164+
file, err = client.Open("newdir/a/second.txt")
165+
require.NoError(t, err)
166+
167+
bs, err = io.ReadAll(file)
168+
require.NoError(t, err)
169+
require.Equal(t, "second newdir data", string(bs))
170+
171+
// third file
172+
file, err = client.Open("newdir/a/b/third.txt")
173+
require.NoError(t, err)
174+
175+
bs, err = io.ReadAll(file)
176+
require.NoError(t, err)
177+
require.Equal(t, "third newdir data", string(bs))
178+
})
179+
130180
t.Run("delete", func(t *testing.T) {
131181
err := client.Delete("/missing.txt")
132182
require.NoError(t, err)
@@ -217,6 +267,7 @@ func TestClient(t *testing.T) {
217267
"archive", "archive/old.txt", "archive/empty2.txt",
218268
"with-empty", "with-empty/EMPTY1.txt", "with-empty/empty_file2.txt",
219269
"with-empty/data.txt", "with-empty/data2.txt",
270+
"newdir", "newdir/first.txt", "newdir/a", "newdir/a/second.txt", "newdir/a/b", "newdir/a/b/third.txt",
220271
})
221272
})
222273

@@ -248,6 +299,7 @@ func TestClient(t *testing.T) {
248299
"bigdata", "bigdata/large.txt",
249300
"archive", "archive/old.txt", "archive/empty2.txt",
250301
"Upper", "Upper/names.txt",
302+
"newdir", "newdir/first.txt", "newdir/a", "newdir/a/second.txt", "newdir/a/b", "newdir/a/b/third.txt",
251303
})
252304
})
253305

0 commit comments

Comments
 (0)