Commit 4d15eee1 authored by Paul McCarthy's avatar Paul McCarthy 🚵
Browse files

ENH: --category option, allowing a sub-set of plugins to be shown as options.

ui.selectPlugins handles case where no plugins or only one plugin is available
parent 5246d815
......@@ -39,7 +39,7 @@ def downloadPluginManifest(url : Union[str, pathlib.Path]) -> Manifest:
prints some messages. If the file cannot be downloaded/loaded, an
empty :class:`.Manifest` is created and returned.
:arg url: URL of manifest file
:arg url: URL of manifest file
:returns: :class:`.Manifest` object
"""
try:
......@@ -65,40 +65,48 @@ def createArchiveDir(archiveDir : Union[str, pathlib.Path]):
f'{archiveDir}!') from e
def selectPlugins(manifest : Manifest) -> List[Plugin]:
"""Prompts the user to select which plugins they would like to download
and install.
:arg manifest: Dict of ``{name : Plugin}`` mappings of all available
plugin files.
def _selectOnePlugin(pluginName : str) -> List[str]:
"""Sub-function of :func:`selectPlugins` called when there is only one
plugin available to install. Asks the user if they would like to install
the plugin.
:returns: A list of :class:`.Plugin` objects representing the plugins
that the user selected.
:arg pluginName: Name of the available plugin
:returns: Either ``[pluginName]``, or ``[]``, depending on whether
the user selected the plugin.
"""
plgnames = list(manifest.keys())
question(f'Do you want to download the [{pluginName}] plugin?', EMPHASIS)
info('Press enter or type Y to confirm the installation. Any other '
'response will cancel the download.', indent=2, wrap=True)
important('Plugins available for download:', EMPHASIS)
for i, name in enumerate(plgnames, 1):
plugin = manifest[name]
name = f'[{name}]'
info(f' {i} {name:25s}', EMPHASIS)
if plugin.description is not None:
info(plugin.description, indent=4)
response = prompt(f'Install [{pluginName}]? (Y/n): ')
if response.lower() in ('', 'y', 'yes'):
return [pluginName]
else:
return []
def _selectMultiplePlugins(pluginNames : List[str]) -> List[str]:
"""Sub-function of :func:`selectPlugins` called when there are multiple
plugins available to install. Prompts the user to select which plugins to
install.
:arg pluginNames: List of available plugins.
:returns: List of plugins selected by the user.
"""
while True:
# TODO handle <2 available plugins
question('Which plugins would you like to download?', EMPHASIS)
info('Type "all" to download all of the plugins that are listed. '
'Alternately, enter the numbers of each plugin you would like '
'to download, separated by spaces. For example, if you would '
f'like to download the [{plgnames[0]}] and [{plgnames[1]}] '
f'like to download the [{pluginNames[0]}] and [{pluginNames[1]}] '
'plugins, enter "1 2".', indent=2, wrap=True)
plugins = prompt('Enter plugin(s) to download: ')
if plugins.lower() == 'all':
plugins = plgnames
plugins = pluginNames
break
try:
......@@ -110,12 +118,57 @@ def selectPlugins(manifest : Manifest) -> List[Plugin]:
warning('No plugins specified! Type "all" to '
'download all plugins.', wrap=True)
continue
if any([p <= 0 or p > len(manifest) for p in plugins]):
if any([p <= 0 or p > len(pluginNames) for p in plugins]):
error(f'One of the requested plugins [{plugins}] does not exist')
continue
plugins = [plgnames[p - 1] for p in plugins]
plugins = [pluginNames[p - 1] for p in plugins]
break
return plugins
def selectPlugins(manifest : Manifest, category : str = None) -> List[Plugin]:
"""Prompts the user to select which plugins they would like to download
and install.
:arg manifest: Dict of ``{name : Plugin}`` mappings of all available
plugin files.
:arg category: If provided, only plugins in the specified category will be
given as options.
:returns: A list of :class:`.Plugin` objects representing the plugins
that the user selected.
"""
plugins = list(manifest.keys())
if category is not None:
plugins = [n for n in plugins if manifest[n].category == category]
if len(plugins) == 0:
error('No plugins are available!')
return []
important('Plugins available for download:', EMPHASIS)
if category is not None:
info(f' (Only showing plugins in the [{category}] category)')
for i, name in enumerate(plugins, 1):
plugin = manifest[name]
name = f'[{name}]'
info(f' {i} {name:25s}', EMPHASIS)
if plugin.description is not None:
info(plugin.description, indent=4)
if len(plugins) > 1:
plugins = _selectMultiplePlugins(plugins)
elif len(plugins) == 1:
plugins = _selectOnePlugin(plugins[0])
if len(plugins) == 0:
important('No plugins selected for installation!', EMPHASIS)
return []
important('Plugins selected for installation:', EMPHASIS)
for p in plugins:
......
......@@ -117,6 +117,9 @@ def parseArgs(argv : List[str]) -> argparse.Namespace:
'plugin' : 'Name or URL of FSL plugin to download.',
'manifest' : 'URL to plugin manifest file.',
'archiveDir' : 'Directory to cache downloaded files in.',
'category' : 'Only display available plugins from the specified '
'category. Ignored if plugins are explicitly '
'specified on the command-line.',
'destination' : 'Destination directory to install plugin files. If '
'used once, applies to all plugins. Otherwise, must '
'be specified for each plugin that is specified on '
......@@ -138,6 +141,8 @@ def parseArgs(argv : List[str]) -> argparse.Namespace:
'plugin', nargs='*', help=helps['plugin'])
parser.add_argument(
'-m', '--manifest', default=MANIFEST_URL, help=helps['manifest'])
parser.add_argument(
'-c', '--category', help=helps['category'])
parser.add_argument(
'-a', '--archiveDir', default=ARCHIVE_DIR, help=helps['archiveDir'])
parser.add_argument(
......@@ -239,7 +244,7 @@ def selectPlugins(args : argparse.Namespace,
# plugins, and ask them which ones they
# want to install
if len(plugins) == 0:
plugins = ui.selectPlugins(manifest)
plugins = ui.selectPlugins(manifest, args.category)
else:
plugins = [manifest[p] for p in plugins]
......@@ -315,9 +320,10 @@ def main(argv=None):
manifest, plugins = loadManifest( args)
plugins = selectPlugins(args, manifest, plugins)
ui.createArchiveDir(args.archiveDir)
download( args, plugins)
install( args, plugins)
if len(plugins) > 0:
ui.createArchiveDir(args.archiveDir)
download( args, plugins)
install( args, plugins)
except Exception as e:
error(str(e))
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment