fman-users / fman

Issue tracker for fman, a cross-platform file manager
https://fman.io
240 stars 3 forks source link

Make it possible to configure the settings location #371

Open mherrmann opened 6 years ago

mherrmann commented 6 years ago

Users' custom configuration of fman is stored in the data directory. In #368, @kwonoj wished to be able to customize its location, so he can share his config across machines. He did not want to use symlinks because they are flaky for him on Windows. The goal of this issue is thus to make it possible to configure the location of the data directory, or at least of the Settings plugin.

vovcacik commented 6 years ago

Great idea! Temporary workaround:

@echo off
setlocal

set FMAN_DIR=C:\fman
set APPDATA=%FMAN_DIR%\home

"%FMAN_DIR%\bin\fman.exe" %*

This will keep fman binaries in C:\fman\bin and your configuration files in C:\fman\home.

mherrmann commented 6 years ago

That's a nice solution @vovcacik. Perhaps fman's implementation of this feature could also be to simply check for the existence of an environment variable, say FMAN_DATA_DIR. If set, fman uses it as the location of the data directory. Otherwise, the default locations are used.

That leaves the question of whether the entire data directory should be stored at an arbitrary location, or just the Settings plugin. My data directory contains:

So, most likely you only want to sync the Plugins/User directory across machines. Perhaps there could be two environment variables:

What do you think? Do you have better ideas for the name of FMAN_USER_DIR? I'm not sure I'm too happy with it yet.

vovcacik commented 6 years ago

Before you dive in I wanted to point out two use cases that apply to this issue:

a) configuration synchronization

b) portable installation

These two are in conflict. You can't keep local data local while you keep all fman's data encapsulated in single dir unless you design for it.

While I don't know if you considered the above conflict between the two use cases, funny thing is that your proposed solution env. var. FMAN_DATA_DIR and FMAN_USER_DIR would be great for this. To satisfy both above use cases I would probably do something simple&easy as this:

@echo off
setlocal

set FMAN_DIR=C:\fman
set FMAN_DATA_DIR=%FMAN_DIR%\local\%COMPUTERNAME%
set FMAN_USER_DIR=%FMAN_DIR%\home

"%FMAN_DIR%\bin\fman.exe" %*

Other viable approach is to keep FMAN_USER_DIR as is (i.e. place for global/syncable config) and make paths to local config files configurable. Then you can get rid of FMAN_DATA_DIR as path to that data will be configurable. For example path to Local/ could have default value %TEMP%\fman\Local but user could change it to .\local\%COMPUTERNAME%\Local. Everything by voidtools does that.

I currently have tens of tools that I have to hack to some degree to make them portable as they don't support it out of the box. It ranges from small hacks like changing %APPDATA%, %TEMP% or %USERPROFILE% env. var. to rather nasty directory junctions, soft or hard links (which creates clutter). I usually resign on making registry keys portable.

With the above in mind, this is how others do it and ordered as I prefer it:

  1. program detects his configuration file on relative path to the executable
    • if missing it creates it locally
    • if missing it creates it in %APPDATA%
  2. program has argument to define configuration path, e.g. --config-dir
    • ideally it also adds env. var. with same meaning, e.g. %PROGRAM_CONFIG_DIR%, but the cli arg has precedence
  3. program's config dir can't be configured, but it creates one in %APPDATA% and it reads the appdata path from env. var. (that I can easily change)
  4. program's config dir can't be configured, but it creates one in %APPDATA% but unfortunately it reads appdata path from Windows API or registry (which I can't change, so I need to make dir junction or soft link)
  5. program's config dir is hard coded to some location (again junction or link)
mherrmann commented 6 years ago

(I edited your comment @vovcacik to number your preferred approaches at the end.)

I can see why you prefer 1. in light of a portable version of fman (#82). The thing is, a portable version is an edge case in my opinion. I can see why it's useful. But I think most users will run fman from a non-portable version. In those cases, the first part of 1. ("try to create locally") does not make much sense.

My preferred approach is thus 3. And it would let you do all that's required right?

vovcacik commented 6 years ago

Yeah, point 1, 2 or 3 would work just fine for me. But 3 is where we are now and my point to engage in this issue was:

But the above would be the easy part. I suppose the hard part will be to decide how to split the config dir into two parts, local-only and synchronizable one. As long as paths to both parts are configurable, I am happy 😃

tmssngr commented 6 years ago

I like the idea of first checking a certain settings path relative to the executable. If existing, it uses that, if not, it uses the default system location at %APPDATA%. That way it is very easy to get a portable bundle by simply creating a new directory somewhere "near" the executable. Of course, it then would be perfect, if fman would be shipped as a zipped directory structure instead of a net installer that uses multiple executables (%APPDATA%\local\fman.exe and %APPDATA%\local\Versions\\fman.exe)

vovcacik commented 6 years ago

Of course, it then would be perfect, if fman would be shipped as a zipped directory structure instead of a net installer

Agreed, also the installer writes system registry. #338 may be worth reopening.

mherrmann commented 6 years ago

338 is a duplicate of #82. I updated both issue descriptions to reflect this.

SteveBenner commented 5 years ago

If it were me, I would start with the XDG standard, especially seeing as fman is cross-platform.