From 79379faeac81ca78f4d5285fe74b04b3a19e8651 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Thu, 23 Apr 2026 15:04:43 +0100 Subject: [PATCH] rc: add core/disks to enumerate attached disks --- fs/rc/disks.go | 14 +++++++++++ fs/rc/disks_unsupported.go | 8 ++++++ fs/rc/internal.go | 50 ++++++++++++++++++++++++++++++++++++++ fs/rc/internal_test.go | 20 +++++++++++++++ 4 files changed, 92 insertions(+) create mode 100644 fs/rc/disks.go create mode 100644 fs/rc/disks_unsupported.go diff --git a/fs/rc/disks.go b/fs/rc/disks.go new file mode 100644 index 000000000..a964b8f42 --- /dev/null +++ b/fs/rc/disks.go @@ -0,0 +1,14 @@ +//go:build !(netbsd && 386) + +package rc + +import "github.com/shirou/gopsutil/v4/disk" + +// getMounts returns a slice of disk mount points +func getMounts() (mounts []string) { + partitions, _ := disk.Partitions(false) + for _, partition := range partitions { + mounts = append(mounts, partition.Mountpoint) + } + return mounts +} diff --git a/fs/rc/disks_unsupported.go b/fs/rc/disks_unsupported.go new file mode 100644 index 000000000..1b6f9235d --- /dev/null +++ b/fs/rc/disks_unsupported.go @@ -0,0 +1,8 @@ +//go:build netbsd && 386 + +package rc + +// getMounts returns a slice of disk mount points +func getMounts() (mounts []string) { + return []string{"/"} +} diff --git a/fs/rc/internal.go b/fs/rc/internal.go index b32e155d6..e2c72df83 100644 --- a/fs/rc/internal.go +++ b/fs/rc/internal.go @@ -614,3 +614,53 @@ func rcRunCommand(ctx context.Context, in Params) (out Params, err error) { err = cmd.Run() return nil, err } + +func init() { + Add(Call{ + Path: "core/disks", + Fn: rcDisks, + Title: "List the local disks", + Help: `This does not take any parameters + +This call is for rclone GUI programs to enumerate local disks and +important directories for doing transfers to and from. The list +returned will include the root directory and the user's home directory +and any mounted disks. The returned items should be usable directly as +remotes. + +Returns: + +- disks + - This is an array of strings of local disk names +`, + }) +} + +// Disks returns likely local disks and some other useful positions +func rcDisks(ctx context.Context, in Params) (out Params, err error) { + disks := []string{} + home, err := os.UserHomeDir() + tidy := func(s string) string { + if s != "/" { + s, _ = strings.CutSuffix(s, "/") + } + return s + } + if err == nil { + disks = append(disks, tidy(home)) + } + for _, mount := range getMounts() { + mount = tidy(mount) + if runtime.GOOS == "linux" { + if strings.HasPrefix(mount, "/snap/") || strings.HasPrefix(mount, "/var/snap/") || strings.HasPrefix(mount, "/boot/") || mount == "/boot" { + // ignore boring mounts + continue + } + } + disks = append(disks, mount) + } + out = Params{ + "disks": disks, + } + return out, nil +} diff --git a/fs/rc/internal_test.go b/fs/rc/internal_test.go index 2ef26c848..70e3c5868 100644 --- a/fs/rc/internal_test.go +++ b/fs/rc/internal_test.go @@ -199,3 +199,23 @@ func TestCoreCommand(t *testing.T) { test("unknown_command", "STREAM", version+errorString, true) }) } + +// core/disks: Tests local disks +func TestCoreDisks(t *testing.T) { + call := Calls.Get("core/disks") + assert.NotNil(t, call) + in := Params{} + out, err := call.Fn(context.Background(), in) + require.NoError(t, err) + require.NotNil(t, out) + require.NotNil(t, out["disks"]) + disks, ok := out["disks"].([]string) + require.True(t, ok) + assert.True(t, len(disks) >= 2) + for _, disk := range disks { + assert.NotEqual(t, disk, "") + if disk != "/" { + assert.False(t, strings.HasSuffix(disk, "/")) + } + } +}