diff --git a/mount.go b/mount.go index 32873f8..9f0d54b 100644 --- a/mount.go +++ b/mount.go @@ -134,10 +134,46 @@ func runGetLocalPathCommand(args []string, cfg config, password string) error { if len(matches) == 0 { return fmt.Errorf("entry %s not found under mounted by-id tree", id) } - fmt.Println(matches[0]) + path := matches[0] + if friendlyPath, err := friendlyLocalPath(mountPoint, path); err == nil && friendlyPath != "" { + path = friendlyPath + } + fmt.Println(path) return nil } +func friendlyLocalPath(mountPoint, byIDPath string) (string, error) { + byIDInfo, err := os.Stat(byIDPath) + if err != nil { + return "", err + } + byIDRoot := filepath.Join(mountPoint, "by-id") + var found string + err = filepath.Walk(mountPoint, func(path string, info os.FileInfo, err error) error { + if err != nil || info == nil { + return nil + } + if path == byIDRoot || strings.HasPrefix(path, byIDRoot+string(os.PathSeparator)) { + if info.IsDir() { + return filepath.SkipDir + } + return nil + } + if info.IsDir() { + return nil + } + if os.SameFile(byIDInfo, info) { + found = path + return filepath.SkipAll + } + return nil + }) + if err != nil { + return "", err + } + return found, nil +} + func runGetURLCommand(args []string, cfg config, password string) error { flags := flag.NewFlagSet("get-url", flag.ExitOnError) if err := flags.Parse(args); err != nil { diff --git a/mount_test.go b/mount_test.go index 5bc0de4..050b5c7 100644 --- a/mount_test.go +++ b/mount_test.go @@ -2,6 +2,7 @@ package main import ( "context" + "os" "path/filepath" "testing" @@ -119,3 +120,51 @@ func TestBuildMountTreeAddsByIDDirectory(t *testing.T) { } } } + +func TestFriendlyLocalPathPrefersNonByIDPath(t *testing.T) { + mountPath := t.TempDir() + friendlyDir := filepath.Join(mountPath, "Bills", "2024", "07") + byIDDir := filepath.Join(mountPath, "by-id", "it") + if err := os.MkdirAll(friendlyDir, 0755); err != nil { + t.Fatal(err) + } + if err := os.MkdirAll(byIDDir, 0755); err != nil { + t.Fatal(err) + } + friendlyPath := filepath.Join(friendlyDir, "Invoice.pdf") + byIDPath := filepath.Join(byIDDir, "item-1.pdf") + if err := os.WriteFile(friendlyPath, []byte("pdf"), 0644); err != nil { + t.Fatal(err) + } + if err := os.Link(friendlyPath, byIDPath); err != nil { + t.Fatal(err) + } + + got, err := friendlyLocalPath(mountPath, byIDPath) + if err != nil { + t.Fatal(err) + } + if got != friendlyPath { + t.Fatalf("expected friendly path %q, got %q", friendlyPath, got) + } +} + +func TestFriendlyLocalPathReturnsEmptyWhenNoFriendlyPathExists(t *testing.T) { + mountPath := t.TempDir() + byIDDir := filepath.Join(mountPath, "by-id", "it") + if err := os.MkdirAll(byIDDir, 0755); err != nil { + t.Fatal(err) + } + byIDPath := filepath.Join(byIDDir, "item-1.pdf") + if err := os.WriteFile(byIDPath, []byte("pdf"), 0644); err != nil { + t.Fatal(err) + } + + got, err := friendlyLocalPath(mountPath, byIDPath) + if err != nil { + t.Fatal(err) + } + if got != "" { + t.Fatalf("expected no friendly path, got %q", got) + } +}