main
73 9 years ago committed by Fabien Benureau
parent 0bfe921ad9
commit 2871588703

@ -2,6 +2,7 @@ import os
import platform import platform
import shutil import shutil
import configobj import configobj
import validate import validate
@ -10,6 +11,7 @@ from .spec import configspec
DFT_CONFIG_PATH = os.path.expanduser('~/.pubsrc') DFT_CONFIG_PATH = os.path.expanduser('~/.pubsrc')
def load_default_conf(): def load_default_conf():
"""Load the default configuration""" """Load the default configuration"""
default_conf = configobj.ConfigObj(configspec=configspec) default_conf = configobj.ConfigObj(configspec=configspec)
@ -17,6 +19,7 @@ def load_default_conf():
default_conf.validate(validator, copy=True) default_conf.validate(validator, copy=True)
return default_conf return default_conf
def get_confpath(verify=True): def get_confpath(verify=True):
"""Return the configuration filepath """Return the configuration filepath
If verify is True, verify that the file exists and exit with an error if not. If verify is True, verify that the file exists and exit with an error if not.
@ -32,31 +35,36 @@ def get_confpath(verify=True):
ui.exit(error_code=1) ui.exit(error_code=1)
return confpath return confpath
def check_conf(conf): def check_conf(conf):
"""Type check a configuration""" """Type check a configuration"""
validator = validate.Validator() validator = validate.Validator()
results = conf.validate(validator, copy=True) results = conf.validate(validator, copy=True)
assert results == True, '{}'.format(results) # TODO: precise error dialog when parsing error assert results == True, '{}'.format(results) # TODO: precise error dialog when parsing error
def load_conf(check=True, path=None): def load_conf(check=True, path=None):
"""Load the configuration""" """Load the configuration"""
if path is None: if path is None:
path = get_confpath(verify=True) path = get_confpath(verify=True)
with open(path, 'rb') as f: with open(path, 'rb') as f:
conf = configobj.ConfigObj(f.readlines(), configspec=configspec) conf = configobj.ConfigObj(f.readlines(), configspec=configspec)
if check: if check:
check_conf(conf) check_conf(conf)
conf.filename = path
return conf return conf
def save_conf(conf, path=None): def save_conf(conf, path=None):
"""Save the configuration.""" """Save the configuration."""
if path is None: if path is not None:
path = get_confpath(verify=False) conf.filename = path
with open(path, 'wb') as f: elif conf.filename is None:
conf.filename = get_confpath(verify=False)
with open(conf.filename, 'wb') as f:
conf.write(outfile=f) conf.write(outfile=f)
def default_open_cmd(): def default_open_cmd():
"""Chooses the default command to open documents""" """Chooses the default command to open documents"""
if platform.system() == 'Darwin': if platform.system() == 'Darwin':
@ -68,6 +76,7 @@ def default_open_cmd():
else: else:
return None return None
def which(cmd): def which(cmd):
try: try:
return shutil.which(cmd) # available in python 3.3 return shutil.which(cmd) # available in python 3.3
@ -78,6 +87,7 @@ def which(cmd):
return filepath return filepath
return None return None
def default_edit_cmd(): def default_edit_cmd():
"""Find an available editor""" """Find an available editor"""
if 'EDITOR' in os.environ: if 'EDITOR' in os.environ:

@ -1,14 +1,12 @@
import sys import sys
import argparse import argparse
import collections import collections
from . import uis from . import uis
from . import config from . import config
from . import commands from . import commands
from . import update from . import update
from . import plugins from . import plugins
from .__init__ import __version__
CORE_CMDS = collections.OrderedDict([ CORE_CMDS = collections.OrderedDict([
('init', commands.init_cmd), ('init', commands.init_cmd),
@ -33,25 +31,38 @@ CORE_CMDS = collections.OrderedDict([
def execute(raw_args=sys.argv): def execute(raw_args=sys.argv):
conf_parser = argparse.ArgumentParser(add_help=False)
conf_parser.add_argument("-c", "--config", help="path to config file",
type=str, metavar="FILE")
args, remaining_args = conf_parser.parse_known_args(raw_args[1:])
if args.config:
conf_path = args.config
else:
conf_path = config.get_confpath(verify=False) # will be checked on load
# loading config # loading config
if len(raw_args) > 1 and raw_args[1] != 'init': if len(remaining_args) > 0 and remaining_args[0] != 'init':
try: try:
conf = config.load_conf(check=False) conf = config.load_conf(path=conf_path, check=False)
if update.update_check(conf): # an update happened, reload conf. if update.update_check(conf, path=conf.filename): # an update happened, reload conf.
conf = config.load_conf(check=False) conf = config.load_conf(path=conf_path, check=False)
config.check_conf(conf) config.check_conf(conf)
except IOError as e: except IOError as e:
print('error: {}'.format(str(e))) print('error: {}'.format(str(e)))
sys.exit() sys.exit()
else: else:
conf = config.load_default_conf() conf = config.load_default_conf()
conf.filename = conf_path
uis.init_ui(conf) uis.init_ui(conf)
ui = uis.get_ui() ui = uis.get_ui()
parser = argparse.ArgumentParser(description="research papers repository") parser = argparse.ArgumentParser(parents=[conf_parser],
description="research papers repository",
prog="pubs", version=__version__, add_help=True)
subparsers = parser.add_subparsers(title="valid commands", dest="command") subparsers = parser.add_subparsers(title="valid commands", dest="command")
cmd_funcs = collections.OrderedDict() cmd_funcs = collections.OrderedDict()
for cmd_name, cmd_mod in CORE_CMDS.items(): for cmd_name, cmd_mod in CORE_CMDS.items():
cmd_mod.parser(subparsers) cmd_mod.parser(subparsers)
@ -62,7 +73,7 @@ def execute(raw_args=sys.argv):
for p in plugins.get_plugins().values(): for p in plugins.get_plugins().values():
cmd_funcs.update(p.get_commands(subparsers)) cmd_funcs.update(p.get_commands(subparsers))
args = parser.parse_args(raw_args[1:]) args = parser.parse_args(remaining_args)
args.prog = parser.prog # Hack: there might be a better way... args.prog = parser.prog # Hack: there might be a better way...
cmd = args.command cmd = args.command
del args.command del args.command

@ -6,6 +6,7 @@ import codecs
from .content import editor_input from .content import editor_input
from . import color from . import color
from . import config
from .p3 import _get_raw_stdout, _get_raw_stderr, input, ustr from .p3 import _get_raw_stdout, _get_raw_stderr, input, ustr
@ -30,7 +31,7 @@ def _get_encoding(conf):
def get_ui(): def get_ui():
if _ui is None: if _ui is None:
return PrintUI() # no editor support. (#FIXME?) return PrintUI(config.load_default_conf()) # no editor support. (#FIXME?)
return _ui return _ui

@ -59,6 +59,7 @@ class CommandTestCase(unittest.TestCase):
def setUp(self): def setUp(self):
self.fs = fake_env.create_fake_fs([content, filebroker, conf, init_cmd, import_cmd, configobj, update]) self.fs = fake_env.create_fake_fs([content, filebroker, conf, init_cmd, import_cmd, configobj, update])
self.default_pubs_dir = self.fs['os'].path.expanduser('~/.pubs') self.default_pubs_dir = self.fs['os'].path.expanduser('~/.pubs')
self.default_conf_path = self.fs['os'].path.expanduser('~/.pubsrc')
def execute_cmds(self, cmds, capture_output=CAPTURE_OUTPUT): def execute_cmds(self, cmds, capture_output=CAPTURE_OUTPUT):
""" Execute a list of commands, and capture their output """ Execute a list of commands, and capture their output
@ -509,8 +510,21 @@ class TestUsecase(DataCommandTestCase):
'pubs attach --move Page99 data/pagerank.pdf' 'pubs attach --move Page99 data/pagerank.pdf'
] ]
self.execute_cmds(cmds) self.execute_cmds(cmds)
self.assertTrue(self.fs['os'].path.isfile(self.default_conf_path))
self.assertFalse(self.fs['os'].path.exists('/data/pagerank.pdf')) self.assertFalse(self.fs['os'].path.exists('/data/pagerank.pdf'))
def test_alternate_config(self):
alt_conf = self.fs['os'].path.expanduser('~/.alt_conf')
cmds = ['pubs -c ' + alt_conf + ' init',
'pubs --config ' + alt_conf + ' import data/ Page99',
'pubs list -c ' + alt_conf
]
outs = self.execute_cmds(cmds)
# check if pubs works as expected
self.assertEqual(1 + 1, len(outs[-1].split('\n')))
# check whether we actually changed the config file
self.assertFalse(self.fs['os'].path.isfile(self.default_conf_path))
self.assertTrue(self.fs['os'].path.isfile(alt_conf))
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

Loading…
Cancel
Save