From e4749cf0d0e597c38315339fd14562f6b7d94757 Mon Sep 17 00:00:00 2001 From: albertony <12441419+albertony@users.noreply.github.com> Date: Sat, 4 Nov 2023 02:48:42 +0100 Subject: [PATCH] config: make listing of remotes more consistent --- backend/cache/cache_internal_test.go | 4 +- fs/config/config.go | 65 ++++++++++++++++++++++++---- fs/config/rc.go | 4 +- fs/rc/rcserver/rcserver.go | 10 ++--- 4 files changed, 66 insertions(+), 17 deletions(-) diff --git a/backend/cache/cache_internal_test.go b/backend/cache/cache_internal_test.go index 6467e4cd9..0a1a39e46 100644 --- a/backend/cache/cache_internal_test.go +++ b/backend/cache/cache_internal_test.go @@ -850,8 +850,8 @@ func (r *run) encryptRemoteIfNeeded(t *testing.T, remote string) string { func (r *run) newCacheFs(t *testing.T, remote, id string, needRemote, purge bool, flags map[string]string) (fs.Fs, *cache.Persistent) { fstest.Initialise() remoteExists := false - for _, s := range config.FileSections() { - if s == remote { + for _, s := range config.GetRemotes() { + if s.Name == remote { remoteExists = true } } diff --git a/fs/config/config.go b/fs/config/config.go index 0e6349376..ea4b5f2c3 100644 --- a/fs/config/config.go +++ b/fs/config/config.go @@ -415,6 +415,16 @@ func getWithDefault(name, key, defaultValue string) string { return value } +// GetRemoteNames returns the names of remotes defined in environment and config file. +func GetRemoteNames() []string { + remotes := GetRemotes() + var remoteNames []string + for _, remote := range remotes { + remoteNames = append(remoteNames, remote.Name) + } + return remoteNames +} + // UpdateRemoteOpt configures the remote update type UpdateRemoteOpt struct { // Treat all passwords as plain that need obscuring @@ -637,19 +647,58 @@ func FileDeleteKey(section, key string) bool { return LoadedData().DeleteKey(section, key) } -var matchEnv = regexp.MustCompile(`^RCLONE_CONFIG_(.+?)_TYPE=.*$`) - // FileSections returns the sections in the config file -// including any defined by environment variables. func FileSections() []string { - sections := LoadedData().GetSectionList() + return LoadedData().GetSectionList() +} + +// Remote defines a remote with a name, type and source +type Remote struct { + Name string `json:"name"` + Type string `json:"type"` + Source string `json:"source"` +} + +var remoteEnvRe = regexp.MustCompile(`^RCLONE_CONFIG_(.+?)_TYPE=(.+)$`) + +// GetRemotes returns the list of remotes defined in environment and config file. +// +// Emulates the preference documented and normally used by rclone via configmap, +// which means environment variables before config file. +func GetRemotes() []Remote { + var remotes []Remote for _, item := range os.Environ() { - matches := matchEnv.FindStringSubmatch(item) - if len(matches) == 2 { - sections = append(sections, strings.ToLower(matches[1])) + matches := remoteEnvRe.FindStringSubmatch(item) + if len(matches) == 3 { + remotes = append(remotes, Remote{ + Name: strings.ToLower(matches[1]), + Type: strings.ToLower(matches[2]), + Source: "environment", + }) } } - return sections + remoteExists := func(name string) bool { + for _, remote := range remotes { + if name == remote.Name { + return true + } + } + return false + } + sections := LoadedData().GetSectionList() + for _, section := range sections { + if !remoteExists(section) { + typeValue, found := LoadedData().GetValue(section, "type") + if found { + remotes = append(remotes, Remote{ + Name: section, + Type: typeValue, + Source: "file", + }) + } + } + } + return remotes } // DumpRcRemote dumps the config for a single remote diff --git a/fs/config/rc.go b/fs/config/rc.go index ba75b8f7b..2d7a26809 100644 --- a/fs/config/rc.go +++ b/fs/config/rc.go @@ -74,9 +74,9 @@ See the [listremotes](/commands/rclone_listremotes/) command for more informatio // Return the a list of remotes in the config file // including any defined by environment variables. func rcListRemotes(ctx context.Context, in rc.Params) (out rc.Params, err error) { - remotes := FileSections() + remoteNames := GetRemoteNames() out = rc.Params{ - "remotes": remotes, + "remotes": remoteNames, } return out, nil } diff --git a/fs/rc/rcserver/rcserver.go b/fs/rc/rcserver/rcserver.go index 7e20213ab..88f82a484 100644 --- a/fs/rc/rcserver/rcserver.go +++ b/fs/rc/rcserver/rcserver.go @@ -308,14 +308,14 @@ func (s *Server) handleOptions(w http.ResponseWriter, r *http.Request, path stri } func (s *Server) serveRoot(w http.ResponseWriter, r *http.Request) { - remotes := config.FileSections() - sort.Strings(remotes) + remoteNames := config.GetRemoteNames() + sort.Strings(remoteNames) directory := serve.NewDirectory("", s.server.HTMLTemplate()) directory.Name = "List of all rclone remotes." q := url.Values{} - for _, remote := range remotes { - q.Set("fs", remote) - directory.AddHTMLEntry("["+remote+":]", true, -1, time.Time{}) + for _, remoteName := range remoteNames { + q.Set("fs", remoteName) + directory.AddHTMLEntry("["+remoteName+":]", true, -1, time.Time{}) } sortParm := r.URL.Query().Get("sort") orderParm := r.URL.Query().Get("order")