mirror of
https://github.com/beetbox/beets.git
synced 2025-12-15 21:14:19 +01:00
Refactor cli main function
The logic of setting up beets and running a command was scattered across the `_raw_main` and `_configure` functions. This is an attempt to bring more structure to the process and to diminish the dependency on global state.
This commit is contained in:
parent
17549b873e
commit
273874f3a2
2 changed files with 64 additions and 55 deletions
|
|
@ -694,6 +694,16 @@ class SubcommandsOptionParser(optparse.OptionParser):
|
|||
|
||||
# Super constructor.
|
||||
optparse.OptionParser.__init__(self, *args, **kwargs)
|
||||
self.add_option('-l', '--library', dest='library',
|
||||
help='library database file to use')
|
||||
self.add_option('-d', '--directory', dest='directory',
|
||||
help="destination music directory")
|
||||
self.add_option('-v', '--verbose', dest='verbose', action='store_true',
|
||||
help='print debugging information')
|
||||
self.add_option('-c', '--config', dest='config',
|
||||
help='path to configuration file')
|
||||
self.add_option('-h', '--help', dest='help', action='store_true',
|
||||
help='how this help message and exit')
|
||||
|
||||
# Our root parser needs to stop on the first unrecognized argument.
|
||||
self.disable_interspersed_args()
|
||||
|
|
@ -855,11 +865,18 @@ def _load_plugins():
|
|||
plugins.send("pluginload")
|
||||
|
||||
|
||||
def _configure(args):
|
||||
"""Parse the command line, load configuration files (including
|
||||
loading any indicated plugins), and return the invoked subcomand,
|
||||
the subcommand options, and the subcommand arguments.
|
||||
def _setup(options, lib=None):
|
||||
"""Prepare and global state and updates it with command line options.
|
||||
|
||||
Returns a list of subcommands, a list of plugins, and a library instance.
|
||||
"""
|
||||
# Configure the MusicBrainz API.
|
||||
mb.configure()
|
||||
|
||||
_configure(options)
|
||||
|
||||
_load_plugins()
|
||||
|
||||
# Temporary: Migrate from 1.0-style configuration.
|
||||
from beets.ui import migrate
|
||||
migrate.automigrate()
|
||||
|
|
@ -867,21 +884,20 @@ def _configure(args):
|
|||
# Get the default subcommands.
|
||||
from beets.ui.commands import default_commands
|
||||
|
||||
# Construct the root parser.
|
||||
parser = SubcommandsOptionParser()
|
||||
parser.add_option('-l', '--library', dest='library',
|
||||
help='library database file to use')
|
||||
parser.add_option('-d', '--directory', dest='directory',
|
||||
help="destination music directory")
|
||||
parser.add_option('-v', '--verbose', dest='verbose', action='store_true',
|
||||
help='print debugging information')
|
||||
parser.add_option('-c', '--config', dest='config',
|
||||
help='path to configuration file')
|
||||
parser.add_option('-h', '--help', dest='help', action='store_true',
|
||||
help='how this help message and exit')
|
||||
subcommands = list(default_commands)
|
||||
subcommands.append(migrate.migrate_cmd)
|
||||
subcommands.extend(plugins.commands())
|
||||
|
||||
# Parse the command-line!
|
||||
options, subargs = parser.parse_global_options(args)
|
||||
if lib is None:
|
||||
lib = _open_library(config)
|
||||
plugins.send("library_opened", lib=lib)
|
||||
|
||||
return subcommands, plugins, lib
|
||||
|
||||
|
||||
def _configure(options):
|
||||
"""Amend the global configuration object with command line options.
|
||||
"""
|
||||
|
||||
# Add any additional config files specified with --config. This
|
||||
# special handling lets specified plugins get loaded before we
|
||||
|
|
@ -906,54 +922,47 @@ def _configure(args):
|
|||
log.debug('no user configuration found at {0}'.format(
|
||||
util.displayable_path(config_path)))
|
||||
|
||||
# Add builtin subcommands
|
||||
parser.add_subcommand(*default_commands)
|
||||
parser.add_subcommand(migrate.migrate_cmd)
|
||||
log.debug(u'data directory: {0}'
|
||||
.format(util.displayable_path(config.config_dir())))
|
||||
|
||||
# Now add the plugin commands to the parser.
|
||||
_load_plugins()
|
||||
for cmd in plugins.commands():
|
||||
parser.add_subcommand(cmd)
|
||||
|
||||
# Parse the remainder of the command line with loaded plugins.
|
||||
return parser.parse_subcommand(subargs)
|
||||
def _open_library(config):
|
||||
"""Create a new library instance from the configuration.
|
||||
"""
|
||||
dbpath = config['library'].as_filename()
|
||||
try:
|
||||
lib = library.Library(
|
||||
dbpath,
|
||||
config['directory'].as_filename(),
|
||||
get_path_formats(),
|
||||
get_replacements(),
|
||||
)
|
||||
except sqlite3.OperationalError:
|
||||
raise UserError(u"database file {0} could not be opened".format(
|
||||
util.displayable_path(dbpath)
|
||||
))
|
||||
log.debug(u'library database: {0}\n'
|
||||
u'library directory: {1}'
|
||||
.format(
|
||||
util.displayable_path(lib.path),
|
||||
util.displayable_path(lib.directory),
|
||||
))
|
||||
return lib
|
||||
|
||||
|
||||
def _raw_main(args, lib=None):
|
||||
"""A helper function for `main` without top-level exception
|
||||
handling.
|
||||
"""
|
||||
subcommand, suboptions, subargs = _configure(args)
|
||||
|
||||
if lib is None:
|
||||
# Open library file.
|
||||
dbpath = config['library'].as_filename()
|
||||
try:
|
||||
lib = library.Library(
|
||||
dbpath,
|
||||
config['directory'].as_filename(),
|
||||
get_path_formats(),
|
||||
get_replacements(),
|
||||
)
|
||||
except sqlite3.OperationalError:
|
||||
raise UserError(u"database file {0} could not be opened".format(
|
||||
util.displayable_path(dbpath)
|
||||
))
|
||||
plugins.send("library_opened", lib=lib)
|
||||
parser = SubcommandsOptionParser()
|
||||
options, subargs = parser.parse_global_options(args)
|
||||
|
||||
log.debug(u'data directory: {0}\n'
|
||||
u'library database: {1}\n'
|
||||
u'library directory: {2}'
|
||||
.format(
|
||||
util.displayable_path(config.config_dir()),
|
||||
util.displayable_path(lib.path),
|
||||
util.displayable_path(lib.directory),
|
||||
))
|
||||
subcommands, plugins, lib = _setup(options, lib)
|
||||
|
||||
# Configure the MusicBrainz API.
|
||||
mb.configure()
|
||||
parser.add_subcommand(*subcommands)
|
||||
subcommand, suboptions, subargs = parser.parse_subcommand(subargs)
|
||||
|
||||
# Invoke the subcommand.
|
||||
subcommand.func(lib, suboptions, subargs)
|
||||
plugins.send('cli_exit', lib=lib)
|
||||
|
||||
|
|
|
|||
|
|
@ -740,7 +740,7 @@ class ConfigTest(unittest.TestCase, TestHelper):
|
|||
beetsdir = os.path.join(self.temp_dir, 'beetsfile')
|
||||
open(beetsdir, 'a').close()
|
||||
os.environ['BEETSDIR'] = beetsdir
|
||||
self.assertRaises(ConfigError, ui._raw_main, 'test')
|
||||
self.assertRaises(ConfigError, ui._raw_main, ['test'])
|
||||
|
||||
def test_beetsdir_config_does_not_load_default_user_config(self):
|
||||
os.environ['BEETSDIR'] = self.beetsdir
|
||||
|
|
|
|||
Loading…
Reference in a new issue