Commit ae5cd9f

Eric Bower  ·  2026-08-01 09:40:30 -0400 EDT
parent 2ce4484
fix: scp <file> pgs.sh:/<project> works
2 files changed,  +92, -0
+5, -0
......@@ -29,6 +29,11 @@ func GetProjectName(entry *utils.FileEntry) string {
2929 } else if len(list) == 1 {
3030 return list[0]
3131 }
32+ // When filepath is like "/bin" (root-level file), dir is "/" and
33+ // split produces ["", ""]. Use the filename as the project name.
34+ if list[1] == "" {
35+ return filepath.Base(entry.Filepath)
36+ }
3237 return list[1]
3338 }
3439
+87, -0
......@@ -0,0 +1,87 @@
1+package shared
2+
3+import (
4+ "io/fs"
5+ "testing"
6+
7+ "github.com/picosh/pico/pkg/send/utils"
8+)
9+
10+func TestGetProjectName(t *testing.T) {
11+ tests := []struct {
12+ name string
13+ filepath string
14+ isDir bool
15+ want string
16+ }{
17+ // Standard cases: /project/file -> project
18+ {
19+ name: "standard project with file",
20+ filepath: "/myproject/index.html",
21+ isDir: false,
22+ want: "myproject",
23+ },
24+ {
25+ name: "nested path",
26+ filepath: "/myproject/subdir/file.txt",
27+ isDir: false,
28+ want: "myproject",
29+ },
30+ // Root-level file (the bug case): /bin -> bin
31+ {
32+ name: "root-level file (scp file pgs.sh:/bin)",
33+ filepath: "/bin",
34+ isDir: false,
35+ want: "bin",
36+ },
37+ {
38+ name: "root-level file with different name",
39+ filepath: "/myproject",
40+ isDir: false,
41+ want: "myproject",
42+ },
43+ // Directory cases
44+ {
45+ name: "directory with no slash",
46+ filepath: "myproject",
47+ isDir: true,
48+ want: "myproject",
49+ },
50+ {
51+ name: "directory at root level",
52+ filepath: "/myproject",
53+ isDir: true,
54+ want: "myproject",
55+ },
56+ // Edge cases (caught by uploader validation, not valid inputs)
57+ {
58+ name: "empty path",
59+ filepath: "",
60+ isDir: false,
61+ want: ".",
62+ },
63+ {
64+ name: "root path",
65+ filepath: "/",
66+ isDir: false,
67+ want: "/",
68+ },
69+ }
70+
71+ for _, tt := range tests {
72+ t.Run(tt.name, func(t *testing.T) {
73+ entry := &utils.FileEntry{
74+ Filepath: tt.filepath,
75+ Mode: fs.FileMode(0644),
76+ }
77+ if tt.isDir {
78+ entry.Mode = fs.ModeDir
79+ }
80+
81+ got := GetProjectName(entry)
82+ if got != tt.want {
83+ t.Errorf("GetProjectName(%q, isDir=%v) = %q, want %q", tt.filepath, tt.isDir, got, tt.want)
84+ }
85+ })
86+ }
87+}