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

cli: add --config-dir common option #1598

Merged
merged 4 commits into from
Sep 4, 2019
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
37 changes: 21 additions & 16 deletions sopel/cli/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import argparse
import os

from sopel import tools, config
from sopel import tools
from . import utils


Expand All @@ -22,11 +22,13 @@ def build_parser():
# sopel-config list
list_parser = subparsers.add_parser(
'list',
help="List available configurations from Sopel's homedir",
help="List available configurations from Sopel's config directory",
description="""
List available configurations from Sopel's homedir ({homedir})
with the extension "{ext}".
""".format(homedir=config.DEFAULT_HOMEDIR, ext='.cfg'))
List available configurations from Sopel's config directory
with the extension "{ext}". Use option ``--config-dir`` to use a
specific config directory.
""".format(ext='.cfg'))
utils.add_common_arguments(list_parser)
list_parser.add_argument(
'-e', '--ext', '--extension',
dest='extension',
Expand Down Expand Up @@ -60,30 +62,35 @@ def build_parser():


def handle_list(options):
"""Display a list of configuration available from Sopel's homedir
"""Display a list of configurations available in Sopel's config directory.

:param options: parsed arguments
:type options: ``argparse.Namespace``

This command displays an unordered list of config names from Sopel's
default homedir, without their extensions::
config directory, without their extensions::

$ sopel-config list
default
custom

Exirel marked this conversation as resolved.
Show resolved Hide resolved
It is possible to filter by extension using the ``-e/--ext/--extension``
option; default is ``.cfg`` (the ``.`` prefix is not required).
By default, the config directory is ``~/.sopel``. To select a different
config directory, options ``--config-dir`` can be used.

It is possible to filter by extension using the
``-e``/``--ext``/``--extension`` option; default is ``.cfg``
(the ``.`` prefix is not required).
"""
display_path = getattr(options, 'display_path', False)
extension = getattr(options, 'extension', '.cfg')
configdir = options.configdir
display_path = options.display_path
extension = options.extension
if not extension.startswith('.'):
extension = '.' + extension
configs = utils.enumerate_configs(config.DEFAULT_HOMEDIR, extension)
configs = utils.enumerate_configs(configdir, extension)

for config_filename in configs:
if display_path:
print(os.path.join(config.DEFAULT_HOMEDIR, config_filename))
print(os.path.join(configdir, config_filename))
else:
name, _ = os.path.splitext(config_filename)
print(name)
Expand All @@ -101,9 +108,7 @@ def handle_init(options):
extension **must be** ``.cfg``.

"""
config_filename = utils.find_config(
config.DEFAULT_HOMEDIR,
getattr(options, 'config', None) or 'default')
config_filename = utils.find_config(options.configdir, options.config)
config_name, ext = os.path.splitext(config_filename)

if ext and ext != '.cfg':
Expand Down
33 changes: 18 additions & 15 deletions sopel/cli/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,10 @@ def add_legacy_options(parser):
"use `sopel restart` instead)"))
parser.add_argument("-l", '--list', action="store_true",
dest="list_configs",
help="List all config files found")
help=(
"List all config files found"
"(deprecated, and will be removed in Sopel 8; "
"use ``sopel-config list`` instead)"))
parser.add_argument('--quiet', action="store_true", dest="quiet",
help="Suppress all output")
parser.add_argument('-w', '--configure-all', action='store_true',
Expand All @@ -152,13 +155,13 @@ def add_legacy_options(parser):
"Run the configuration wizard, but only for the "
"module configuration options "
"(deprecated, and will be removed in Sopel 8; "
"use `sopel configure --modules` instead)"))
"use ``sopel configure --modules`` instead)"))
parser.add_argument('-v', action="store_true",
dest='version_legacy',
help=(
"Show version number and exit "
"(deprecated, and will be removed in Sopel 8; "
"use -V/--version instead)"))
"use ``-V/--version`` instead)"))
parser.add_argument('-V', '--version', action='store_true',
dest='version',
help='Show version number and exit')
Expand Down Expand Up @@ -291,10 +294,10 @@ def print_version():
print('https://sopel.chat/')


def print_config():
"""Print list of available configurations from default homedir."""
configs = utils.enumerate_configs(config.DEFAULT_HOMEDIR)
print('Config files in %s:' % config.DEFAULT_HOMEDIR)
def print_config(configdir):
"""Print list of available configurations from config directory."""
configs = utils.enumerate_configs(configdir)
print('Config files in %s:' % configdir)
configfile = None
for configfile in configs:
print('\t%s' % configfile)
Expand Down Expand Up @@ -347,7 +350,7 @@ def get_pid_filename(options, pid_dir):
``sopel-{basename}.pid`` instead.
"""
name = 'sopel.pid'
if options.config:
if options.config and options.config != 'default':
basename = os.path.basename(options.config)
if basename.endswith('.cfg'):
basename = basename[:-4]
Expand Down Expand Up @@ -429,9 +432,8 @@ def command_start(opts):

def command_configure(opts):
"""Sopel Configuration Wizard"""
configpath = utils.find_config(
config.DEFAULT_HOMEDIR, opts.config or 'default')
if getattr(opts, 'modules', False):
configpath = utils.find_config(opts.configdir, opts.config)
if opts.modules:
utils.plugins_wizard(configpath)
else:
utils.wizard(configpath)
Expand Down Expand Up @@ -543,9 +545,7 @@ def command_legacy(opts):
print_version()
return

# TODO: allow to use a different homedir
configpath = utils.find_config(
config.DEFAULT_HOMEDIR, opts.config or 'default')
configpath = utils.find_config(opts.configdir, opts.config)

if opts.wizard:
tools.stderr(
Expand All @@ -562,7 +562,10 @@ def command_legacy(opts):
return

if opts.list_configs:
print_config()
tools.stderr(
'WARNING: option --list is deprecated; '
'use `sopel-config list` instead')
print_config(opts.configdir)
return

# Step Two: Get the configuration file and prepare to run
Expand Down
39 changes: 25 additions & 14 deletions sopel/cli/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,24 +78,24 @@ def wizard(filename):
This wizard function helps the creation of a Sopel configuration file,
with its core section and its plugins' sections.
"""
homedir, basename = os.path.split(filename)
configdir, basename = os.path.split(filename)
if not basename:
raise config.ConfigurationError(
'Sopel requires a filename for its configuration, not a directory')

try:
if not os.path.isdir(homedir):
print('Creating config directory at {}'.format(homedir))
os.makedirs(homedir)
if not os.path.isdir(configdir):
print('Creating config directory at {}'.format(configdir))
os.makedirs(configdir)
print('Config directory created')
except Exception:
tools.stderr('There was a problem creating {}'.format(homedir))
tools.stderr('There was a problem creating {}'.format(configdir))
raise

name, ext = os.path.splitext(basename)
if not ext:
# Always add .cfg if filename does not have an extension
filename = os.path.join(homedir, name + '.cfg')
filename = os.path.join(configdir, name + '.cfg')
elif ext != '.cfg':
# It is possible to use a non-cfg file for Sopel
# but the wizard does not allow it at the moment
Expand Down Expand Up @@ -250,17 +250,21 @@ def add_common_arguments(parser):
:type parser: argparse.ArgumentParser

This functions adds the common arguments for Sopel's command line tools.
At the moment, this functions adds only one argument to the parser: the
argument used as the standard way to define a configuration filename.
It adds the following arguments:

* ``-c``/``--config``: the name of the Sopel config, or its absolute path
* ``--config-dir``: the directory to scan for config files

This can be used on an argument parser, or an argument subparser, to handle
these cases::

[sopel-command] -c [filename]
[sopel-command] [action] -c [filename]
[sopel-command] --config-dir [directory] -c [name]

Then, when the parser parses the command line arguments, it will expose
a ``config`` option to be used to find and load Sopel's settings.
``config`` and ``configdir`` options that can be used to find and load
Sopel's settings.

.. seealso::

Expand All @@ -270,7 +274,7 @@ def add_common_arguments(parser):
"""
parser.add_argument(
'-c', '--config',
default=None,
default='default',
metavar='filename',
dest='config',
help=inspect.cleandoc("""
Expand All @@ -280,6 +284,11 @@ def add_common_arguments(parser):
An absolute pathname can be provided instead to use an
arbitrary location.
"""))
parser.add_argument(
'--config-dir',
default=config.DEFAULT_HOMEDIR,
dest='configdir',
help='Look for configuration files in this directory.')


def load_settings(options):
Expand Down Expand Up @@ -307,9 +316,11 @@ def load_settings(options):

.. note::

To use this function effectively, the
:func:`sopel.cli.utils.add_common_arguments` function should be used to
add the proper option to the argument parser.
This function expects that ``options`` exposes two attributes:
``config`` and ``configdir``.

The :func:`sopel.cli.utils.add_common_arguments` function should be
used to add these options to the argument parser.

"""
# Default if no options.config or no env var or if they are empty
Expand All @@ -319,7 +330,7 @@ def load_settings(options):
elif 'SOPEL_CONFIG' in os.environ:
name = os.environ['SOPEL_CONFIG'] or name # use default if empty

filename = find_config(config.DEFAULT_HOMEDIR, name)
filename = find_config(options.configdir, name)

if not os.path.isfile(filename):
raise config.ConfigurationNotFound(filename=filename)
Expand Down
Loading