Repository: spyder-ide/spyder

Issue:
Feature Request: Specify a config directory on the command line
I think it would be handy for the user to be able to specify a spyder configuration directory as a command line option so that, for example, if you install  a new version of spyder in an environment you can also isolate any changes in the config from the new version. I personally would use this also for when I'm working off an external monitor compare to travelling and working on my laptop due to differences in screen size and scaling etc.

Looking at the code, I think one could implement this by having spyder's config manager look for an environment variable e.g. SPYDER_CONFDIR and use that in preference to the calculated directory, and then in the Spyder app's main() have it set that environment variable between the point the options get read and the configuration manager instance is imported.

But perhaps there is a reason for not doing this (or even more likely, my proposed solution sucks!)


Discussion:
I did a quick play to implement this if you were interested in seeing a pull-request...
Hi @gb119,

Thanks for this feature request! In fact we've discussed this multiple times and we would like to implement not only a spyder configuration directory, but also isolate configurations per project and global spyder configurations. In this way people will be able to load/save their configuration.

Right now we've added this to our roadmap that we are planning to put it public in the next month. If you are interested in helping us implement this it will be great! We can give you all the guidance you need :) 
I can imagine that involves a much more comprehensive refactoring of  the config management code. At the moment there are certain preference changes that require a Spyder restart and I guess those forced restarts need to be eliminated as you don't want the user to be told that opening a new project requires them to restart Spyder just because they have some different preferences set in the new project that are different from their current project...

If you want the user to manage a set of global and per project settings then the config manager is going to have to track the sets of preferences separately and then present some sort of merged view. There'd need to be some UI to let the user know whether they were changing global rather than project settings too.

I think I'd need to find a lot more time to study the code quite a bit more to understand how one might implement your plan - probably best not to wait for that to happen :-) !

Resolving patch:
diff --git a/spyder/app/cli_options.py b/spyder/app/cli_options.py
--- a/spyder/app/cli_options.py
+++ b/spyder/app/cli_options.py
@@ -142,6 +142,13 @@ def get_options(argv=None):
         default=False,
         help="Report segmentation fault to Github."
     )
+    parser.add_argument(
+        '--conf-dir',
+        type=str,
+        dest="conf_dir",
+        default=None,
+        help="Choose a configuration directory to use for Spyder."
+    )
 
     parser.add_argument('files', nargs='*')
     options = parser.parse_args(argv)
diff --git a/spyder/app/start.py b/spyder/app/start.py
--- a/spyder/app/start.py
+++ b/spyder/app/start.py
@@ -59,6 +59,9 @@
 if CLI_OPTIONS.safe_mode:
     os.environ['SPYDER_SAFE_MODE'] = 'True'
 
+if CLI_OPTIONS.conf_dir:
+    os.environ['SPYDER_CONFDIR'] = CLI_OPTIONS.conf_dir
+
 
 def send_args_to_spyder(args):
     """
diff --git a/spyder/config/base.py b/spyder/config/base.py
--- a/spyder/config/base.py
+++ b/spyder/config/base.py
@@ -204,12 +204,31 @@ def get_clean_conf_dir():
     return conf_dir
 
 
+def get_custom_conf_dir():
+    """
+    Use a custom configuration directory, passed through our command
+    line options or by setting the env var below.
+    """
+    custom_dir = os.environ.get('SPYDER_CONFDIR')
+    if custom_dir:
+        custom_dir = osp.abspath(custom_dir)
+
+        # Set env var to not lose its value in future calls when the cwd
+        # is changed by Spyder.
+        os.environ['SPYDER_CONFDIR'] = custom_dir
+        return custom_dir
+
+
 def get_conf_path(filename=None):
     """Return absolute path to the config file with the specified filename."""
     # Define conf_dir
     if running_under_pytest() or get_safe_mode():
         # Use clean config dir if running tests or the user requests it.
         conf_dir = get_clean_conf_dir()
+    elif get_custom_conf_dir():
+        # Use a custom directory if the user decided to do it through
+        # our command line options.
+        conf_dir = get_custom_conf_dir()
     elif sys.platform.startswith('linux'):
         # This makes us follow the XDG standard to save our settings
         # on Linux, as it was requested on spyder-ide/spyder#2629.
@@ -226,7 +245,7 @@ def get_conf_path(filename=None):
 
     # Create conf_dir
     if not osp.isdir(conf_dir):
-        if running_under_pytest() or get_safe_mode():
+        if running_under_pytest() or get_safe_mode() or get_custom_conf_dir():
             os.makedirs(conf_dir)
         else:
             os.mkdir(conf_dir)


Test patch: