Skip to content

Commit adaef88

Browse files
committed
Error when explicit destination of pkg get already exists
A repeated `kpt pkg get REPO_URI DEST` silently fetched the package into a nested subdirectory (DEST/<pkg-name>) because getDest always defaulted to a repo-named subdirectory when the destination existed, even when the user explicitly named it. Return the existing 'destination directory already exists' error instead when the destination was explicitly provided (keeping the '.' special case and the defaulting behavior for omitted destinations). Fixes #2656 Signed-off-by: Gangadhar Chalapaka <gangadhar@resolve.ai>
1 parent 7928e22 commit adaef88

2 files changed

Lines changed: 86 additions & 0 deletions

File tree

pkg/lib/util/parse/parse.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,14 @@ func getDest(v, repo, subdir string, explicitDest bool) (string, error) {
276276
return v, nil
277277
}
278278

279+
// The user explicitly named a destination that already exists: error out
280+
// instead of silently defaulting to a nested subdirectory inside it, so a
281+
// repeated `kpt pkg get REPO_URI DEST` fails the same way the defaulted
282+
// destination does below.
283+
if explicitDest {
284+
return "", errors.Errorf("destination directory %q already exists", v)
285+
}
286+
279287
// default the location to a new subdirectory matching the pkg URI base
280288
repo = strings.TrimSuffix(repo, "/")
281289
repo = strings.TrimSuffix(repo, ".git")

pkg/lib/util/parse/parse_test.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ package parse
1717
import (
1818
"context"
1919
"fmt"
20+
"os"
21+
"path/filepath"
2022
"testing"
2123

2224
kptfilev1 "github.com/kptdev/kpt/api/kptfile/v1"
@@ -264,3 +266,79 @@ func Test_GitParseArgs(t *testing.T) {
264266
})
265267
}
266268
}
269+
270+
func Test_getDest(t *testing.T) {
271+
repo := "https://github.com/kptdev/kpt"
272+
subdir := "package-examples/nginx"
273+
274+
tests := map[string]struct {
275+
dest func(t *testing.T) string
276+
explicitDest bool
277+
want func(dest string) string
278+
errS string
279+
}{
280+
"explicit destination that does not exist yet": {
281+
dest: func(t *testing.T) string {
282+
return filepath.Join(t.TempDir(), "newDirName")
283+
},
284+
explicitDest: true,
285+
want: func(dest string) string { return dest },
286+
},
287+
"explicit destination that already exists": {
288+
dest: func(t *testing.T) string {
289+
return t.TempDir()
290+
},
291+
explicitDest: true,
292+
errS: "already exists",
293+
},
294+
"explicit current directory": {
295+
dest: func(t *testing.T) string { return "." },
296+
explicitDest: true,
297+
want: func(string) string { return "." },
298+
},
299+
"defaulted destination inside an existing directory": {
300+
dest: func(t *testing.T) string {
301+
return t.TempDir()
302+
},
303+
explicitDest: false,
304+
want: func(dest string) string { return filepath.Join(dest, "nginx") },
305+
},
306+
"defaulted destination whose subdirectory already exists": {
307+
dest: func(t *testing.T) string {
308+
dir := t.TempDir()
309+
require.NoError(t, os.Mkdir(filepath.Join(dir, "nginx"), 0o700))
310+
return dir
311+
},
312+
explicitDest: false,
313+
errS: "already exists",
314+
},
315+
"destination parent does not exist": {
316+
dest: func(t *testing.T) string {
317+
return filepath.Join(t.TempDir(), "missing-parent", "dest")
318+
},
319+
explicitDest: true,
320+
errS: "does not exist",
321+
},
322+
"destination is a file": {
323+
dest: func(t *testing.T) string {
324+
f := filepath.Join(t.TempDir(), "file")
325+
require.NoError(t, os.WriteFile(f, []byte("x"), 0o600))
326+
return f
327+
},
328+
explicitDest: true,
329+
errS: "must be a directory",
330+
},
331+
}
332+
for name, test := range tests {
333+
t.Run(name, func(t *testing.T) {
334+
dest := test.dest(t)
335+
actual, err := getDest(dest, repo, subdir, test.explicitDest)
336+
if test.errS != "" {
337+
require.ErrorContains(t, err, test.errS)
338+
return
339+
}
340+
require.NoError(t, err)
341+
assert.Equal(t, test.want(dest), actual)
342+
})
343+
}
344+
}

0 commit comments

Comments
 (0)