Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use XDG_CONFIG_HOME to save our settings on Linux #3352

Merged
merged 3 commits into from
Aug 12, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions spyderlib/app/spyder.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@
from spyderlib import __version__, __project_url__, __forum_url__, get_versions
from spyderlib.config.base import (get_conf_path, get_module_data_path,
get_module_source_path, STDERR, DEBUG,
debug_print, TEST, SUBFOLDER, MAC_APP_NAME,
debug_print, MAC_APP_NAME,
running_in_mac_app, get_module_path)
from spyderlib.config.main import CONF, OPEN_FILES_PORT
from spyderlib.config.utils import IMPORT_EXT, is_gtk_desktop
Expand Down Expand Up @@ -1213,12 +1213,6 @@ def post_visible_setup(self):
# Remove our temporary dir
atexit.register(self.remove_tmpdir)

# Remove settings test directory
if TEST is not None:
import tempfile
conf_dir = osp.join(tempfile.gettempdir(), SUBFOLDER)
atexit.register(shutil.rmtree, conf_dir, ignore_errors=True)

# [Workaround for Issue 880]
# QDockWidget objects are not painted if restored as floating
# windows, so we must dock them before showing the mainwindow,
Expand Down
4 changes: 1 addition & 3 deletions spyderlib/app/start.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

# Local imports
from spyderlib.app.cli_options import get_options
from spyderlib.config.base import get_conf_path, running_in_mac_app, DEV, TEST
from spyderlib.config.base import DEV, get_conf_path, running_in_mac_app
from spyderlib.config.main import CONF
from spyderlib.utils.external import lockfile
from spyderlib.py3compat import is_unicode
Expand Down Expand Up @@ -113,8 +113,6 @@ def main():

if lock_created:
# Start a new instance
if TEST is None:
atexit.register(lock.unlock)
from spyderlib.app import spyder
spyder.main()
else:
Expand Down
20 changes: 13 additions & 7 deletions spyderlib/config/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,10 @@ def debug_print(*message):
# since 3.0+ we've reverted back to use .spyder to simplify major
# updates in version (required when we change APIs by Linux
# packagers)
if TEST is None:
SUBFOLDER = '.spyder'
if sys.platform.startswith('linux'):
SUBFOLDER = 'spyder'
else:
SUBFOLDER = 'spyder_test'
SUBFOLDER = '.spyder'


# We can't have PY2 and PY3 settings in the same dir because:
Expand Down Expand Up @@ -111,11 +111,17 @@ def get_home_dir():

def get_conf_path(filename=None):
"""Return absolute path for configuration file with specified filename"""
if TEST is None:
conf_dir = osp.join(get_home_dir(), SUBFOLDER)
# This makes us follow the XDG standard to save our settings
# on Linux, as it was requested on Issue 2629
if sys.platform.startswith('linux'):
xdg_config_home = os.environ.get('XDG_CONFIG_HOME', '')
if not xdg_config_home:
xdg_config_home = osp.join(get_home_dir(), '.config')
if not osp.isdir(xdg_config_home):
os.makedirs(xdg_config_home)
conf_dir = osp.join(xdg_config_home, SUBFOLDER)
else:
import tempfile
conf_dir = osp.join(tempfile.gettempdir(), SUBFOLDER)
conf_dir = osp.join(get_home_dir(), SUBFOLDER)
if not osp.isdir(conf_dir):
os.mkdir(conf_dir)
if filename is None:
Expand Down
13 changes: 6 additions & 7 deletions spyderlib/config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
import os.path as osp

# Local import
from spyderlib.config.base import (CHECK_ALL, EXCLUDED_NAMES, SUBFOLDER,
get_home_dir)
from spyderlib.config.base import (CHECK_ALL, EXCLUDED_NAMES, get_home_dir,
SUBFOLDER, TEST)
from spyderlib.config.fonts import BIG, MEDIUM, MONOSPACE, SANS_SERIF
from spyderlib.config.user import UserConfig
from spyderlib.config.utils import IMPORT_EXT
Expand Down Expand Up @@ -587,11 +587,10 @@
# 3. You don't need to touch this value if you're just adding a new option
CONF_VERSION = '27.2.0'


# XXX: Previously we had load=(not DEV) here but DEV was set to *False*.
# Check if it *really* needs to be updated or not
CONF = UserConfig('spyder', defaults=DEFAULTS, load=True, version=CONF_VERSION,
subfolder=SUBFOLDER, backup=True, raw_mode=True)
# Main configuration instance
CONF = UserConfig('spyder', defaults=DEFAULTS, load=(not TEST),
version=CONF_VERSION, subfolder=SUBFOLDER, backup=True,
raw_mode=True)


# Removing old .spyder.ini location:
Expand Down
57 changes: 15 additions & 42 deletions spyderlib/config/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,8 @@
import time

# Local imports
from spyderlib import __version__
from spyderlib.config.base import (DEV, TEST, get_module_source_path,
get_home_dir)
from spyderlib.config.base import (get_conf_path, get_home_dir,
get_module_source_path, TEST)
from spyderlib.utils.programs import check_version
from spyderlib.py3compat import configparser as cp
from spyderlib.py3compat import PY2, is_text_string, to_text_string
Expand All @@ -32,6 +31,7 @@
if PY2:
import codecs


#==============================================================================
# Auxiliary classes
#==============================================================================
Expand Down Expand Up @@ -89,6 +89,10 @@ def _save(self):
"""
Save config into the associated .ini file
"""
# Don't save settings if we are on testing mode
if TEST:
return

# See Issue 1086 and 1242 for background on why this
# method contains all the exception handling.
fname = self.filename()
Expand Down Expand Up @@ -118,51 +122,20 @@ def _write_file(fname):

def filename(self):
"""
Create a .ini filename located in user home directory
Return the name of a .ini filename to save config settings
"""
if TEST is None:
folder = get_home_dir()
else:
import tempfile
folder = tempfile.gettempdir()
w_dot = osp.join(folder, '.%s.ini' % self.name)
if self.subfolder is None:
return w_dot
config_file = osp.join(get_home_dir(), '.%s.ini' % self.name)
return config_file
else:
folder = osp.join(folder, self.subfolder)
w_dot = osp.join(folder, '.%s.ini' % self.name)
folder = get_conf_path()
# Save defaults in a "defaults" dir of .spyder2 to not pollute it
if 'defaults' in self.name:
folder = osp.join(folder, 'defaults')
try:
# Copying old config dir for Spyder 3.0. The new config
# dir for 3.0+ is going to be simply ~/.spyder{-py3}
if __version__.split('.')[0] == '3':
if PY2:
old_confdir = '.spyder2'
else:
old_confdir = '.spyder2-py3'
old_confdir = osp.join(get_home_dir(), old_confdir)
new_confdir = osp.join(get_home_dir(), self.subfolder)
if osp.isdir(old_confdir) and not osp.isdir(new_confdir):
shutil.copytree(old_confdir, new_confdir)
else:
os.makedirs(folder)
else:
os.makedirs(folder)
except os.error:
# Folder (or one of its parents) already exists
pass
old, new = w_dot, osp.join(folder, '%s.ini' % self.name)
if osp.isfile(old) and DEV is None:
try:
if osp.isfile(new):
os.remove(old)
else:
os.rename(old, new)
except OSError:
pass
return new
if not osp.isdir(folder):
os.mkdir(folder)
config_file = osp.join(folder, '%s.ini' % self.name)
return config_file

def set_defaults(self, defaults):
for section, options in defaults:
Expand Down