mirror of
https://github.com/wassname/jupyter_contrib_nbextensions.git
synced 2026-09-12 12:31:30 +08:00
Merge pull request #774 from jcb91/feature/switchable_install
switchable install
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
import copy
|
||||
import sys
|
||||
|
||||
from jupyter_contrib_core.notebook_compat.nbextensions import ArgumentConflict
|
||||
@@ -11,7 +12,9 @@ from tornado.log import LogFormatter
|
||||
from traitlets import Bool, Unicode, default
|
||||
|
||||
import jupyter_contrib_nbextensions
|
||||
from jupyter_contrib_nbextensions.install import install, uninstall
|
||||
from jupyter_contrib_nbextensions.install import (
|
||||
install, toggle_install_config, toggle_install_files, uninstall,
|
||||
)
|
||||
from jupyter_contrib_nbextensions.migrate import migrate
|
||||
|
||||
|
||||
@@ -37,7 +40,7 @@ class BaseContribNbextensionsApp(JupyterApp):
|
||||
|
||||
|
||||
class BaseContribNbextensionsInstallApp(BaseContribNbextensionsApp):
|
||||
"""Base jupyter_contrib_nbextensions (un)installer app."""
|
||||
"""Install/Uninstall jupyter_contrib_nbextensions."""
|
||||
|
||||
aliases = {
|
||||
'prefix': 'BaseContribNbextensionsInstallApp.prefix',
|
||||
@@ -70,6 +73,8 @@ class BaseContribNbextensionsInstallApp(BaseContribNbextensionsApp):
|
||||
),
|
||||
}
|
||||
|
||||
_conflicting_flagsets = [['--user', '--system', '--sys-prefix'], ]
|
||||
|
||||
user = Bool(False, config=True, help='Whether to do a user install')
|
||||
sys_prefix = Bool(False, config=True,
|
||||
help='Use the sys.prefix as the prefix')
|
||||
@@ -93,11 +98,11 @@ class BaseContribNbextensionsInstallApp(BaseContribNbextensionsApp):
|
||||
|
||||
Since notebook version doesn't do it very well
|
||||
"""
|
||||
conflicting_flags = set(['--user', '--system', '--sys-prefix'])
|
||||
|
||||
if len(conflicting_flags.intersection(set(argv))) > 1:
|
||||
raise ArgumentConflict(
|
||||
'cannot specify more than one of user, sys_prefix, or system')
|
||||
for conflicting_flags in map(set, self._conflicting_flagsets):
|
||||
if len(conflicting_flags.intersection(set(argv))) > 1:
|
||||
raise ArgumentConflict(
|
||||
'cannot specify more than one of {}'.format(
|
||||
', '.join(conflicting_flags)))
|
||||
return super(BaseContribNbextensionsInstallApp,
|
||||
self).parse_command_line(argv)
|
||||
|
||||
@@ -106,40 +111,61 @@ BaseContribNbextensionsInstallApp.flags['s'] = (
|
||||
|
||||
|
||||
class InstallContribNbextensionsApp(BaseContribNbextensionsInstallApp):
|
||||
"""Install all jupyter_contrib_nbextensions."""
|
||||
"""Install jupyter_contrib_nbextensions."""
|
||||
|
||||
name = 'jupyter contrib nbextension install'
|
||||
description = (
|
||||
'Install all jupyter_contrib_nbextensions.'
|
||||
)
|
||||
_toggle_value = True # whether to install or uninstall
|
||||
|
||||
flags = copy.deepcopy(BaseContribNbextensionsInstallApp.flags)
|
||||
flags.update({
|
||||
'only-config': (
|
||||
{'BaseContribNbextensionsInstallApp': {'only_config': True}},
|
||||
'Edit config files, but do not install/remove nbextensions files'
|
||||
),
|
||||
'only-files': (
|
||||
{'BaseContribNbextensionsInstallApp': {'only_files': True}},
|
||||
'Install/remove nbextensions files, but do not edit config files'
|
||||
),
|
||||
})
|
||||
|
||||
_conflicting_flagsets = (
|
||||
BaseContribNbextensionsInstallApp._conflicting_flagsets +
|
||||
['--only-config', '--only-files'])
|
||||
|
||||
only_config = Bool(False, config=True, help=(
|
||||
'Edit config files, but do not install/remove nbextensions files'))
|
||||
only_files = Bool(False, config=True, help=(
|
||||
'Install/remove nbextensions files, but do not edit config files'))
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return 'jupyter contrib nbextension {}'.format(
|
||||
'install' if self._toggle_value else 'uninstall')
|
||||
|
||||
@property
|
||||
def description(self):
|
||||
return '{} jupyter_contrib_nbextensions.'.format(
|
||||
'Install' if self._toggle_value else 'Uninstall')
|
||||
|
||||
def start(self):
|
||||
"""Perform the App's actions as configured."""
|
||||
if self.extra_args:
|
||||
sys.exit('{} takes no extra arguments'.format(self.name))
|
||||
self.log.info('{} {}'.format(self.name, ' '.join(self.argv)))
|
||||
return install(
|
||||
user=self.user, sys_prefix=self.sys_prefix, prefix=self.prefix,
|
||||
nbextensions_dir=self.nbextensions_dir, logger=self.log,
|
||||
overwrite=self.overwrite, symlink=self.symlink)
|
||||
kwargs = dict(
|
||||
user=self.user, sys_prefix=self.sys_prefix, logger=self.log)
|
||||
kwargs_files = dict(**kwargs)
|
||||
kwargs_files.update(dict(
|
||||
prefix=self.prefix, nbextensions_dir=self.nbextensions_dir,
|
||||
overwrite=self.overwrite, symlink=self.symlink))
|
||||
if not self.only_config:
|
||||
toggle_install_files(self._toggle_value, **kwargs_files)
|
||||
if not self.only_files:
|
||||
toggle_install_config(self._toggle_value, **kwargs)
|
||||
|
||||
|
||||
class UninstallContribNbextensionsApp(BaseContribNbextensionsInstallApp):
|
||||
"""Uninstall all jupyter_contrib_nbextensions."""
|
||||
|
||||
name = 'jupyter contrib nbextension uninstall'
|
||||
description = (
|
||||
'Uninstall all jupyter_contrib_nbextensions.'
|
||||
)
|
||||
|
||||
def start(self):
|
||||
"""Perform the App's actions as configured."""
|
||||
if self.extra_args:
|
||||
sys.exit('{} takes no extra arguments'.format(self.name))
|
||||
self.log.info('{} {}'.format(self.name, ' '.join(self.argv)))
|
||||
return uninstall(
|
||||
user=self.user, sys_prefix=self.sys_prefix, prefix=self.prefix,
|
||||
nbextensions_dir=self.nbextensions_dir, logger=self.log)
|
||||
class UninstallContribNbextensionsApp(InstallContribNbextensionsApp):
|
||||
"""Uninstall jupyter_contrib_nbextensions."""
|
||||
_toggle_value = False
|
||||
|
||||
|
||||
class MigrateContribNbextensionsApp(BaseContribNbextensionsInstallApp):
|
||||
@@ -169,7 +195,7 @@ class ContribNbextensionsApp(BaseContribNbextensionsApp):
|
||||
examples = '\n'.join(['jupyter contrib nbextension ' + t for t in [
|
||||
'install # {}'.format(install.__doc__),
|
||||
'uninstall # {}'.format(uninstall.__doc__),
|
||||
'migrate # {}'.format(migrate.__doc__),
|
||||
'migrate # {}'.format(migrate.__doc__),
|
||||
]])
|
||||
subcommands = dict(
|
||||
install=(InstallContribNbextensionsApp, install.__doc__),
|
||||
|
||||
@@ -51,41 +51,81 @@ def notebook_is_running():
|
||||
def toggle_install(install, user=False, sys_prefix=False, overwrite=False,
|
||||
symlink=False, prefix=None, nbextensions_dir=None,
|
||||
logger=None):
|
||||
"""Install or remove all jupyter_contrib_nbextensions."""
|
||||
"""Install or remove all jupyter_contrib_nbextensions files & config."""
|
||||
if notebook_is_running():
|
||||
raise NotebookRunningError(
|
||||
'Cannot configure while the Jupyter notebook server is running')
|
||||
_check_conflicting_kwargs(user=user, sys_prefix=sys_prefix, prefix=prefix,
|
||||
nbextensions_dir=nbextensions_dir)
|
||||
config_dir = nbextensions._get_config_dir(user=user, sys_prefix=sys_prefix)
|
||||
toggle_install_files(
|
||||
install, user=user, sys_prefix=sys_prefix, overwrite=overwrite,
|
||||
symlink=symlink, prefix=prefix, nbextensions_dir=nbextensions_dir,
|
||||
logger=logger)
|
||||
toggle_install_config(
|
||||
install, user=user, sys_prefix=sys_prefix, logger=logger)
|
||||
|
||||
verb = 'Installing' if install else 'Uninstalling'
|
||||
|
||||
def toggle_install_files(install, user=False, sys_prefix=False, logger=None,
|
||||
overwrite=False, symlink=False, prefix=None,
|
||||
nbextensions_dir=None):
|
||||
"""Install/remove jupyter_contrib_nbextensions files."""
|
||||
if notebook_is_running():
|
||||
raise NotebookRunningError(
|
||||
'Cannot configure while the Jupyter notebook server is running')
|
||||
kwargs = dict(user=user, sys_prefix=sys_prefix, prefix=prefix,
|
||||
nbextensions_dir=nbextensions_dir)
|
||||
_check_conflicting_kwargs(**kwargs)
|
||||
kwargs['logger'] = logger
|
||||
if logger:
|
||||
logger.info(
|
||||
'{} jupyter_contrib_nbextensions, using config in {}'.format(
|
||||
verb, config_dir))
|
||||
|
||||
# Configure the jupyter_nbextensions_configurator serverextension to load
|
||||
if install:
|
||||
conf_app = EnableJupyterNbextensionsConfiguratorApp(
|
||||
user=user, sys_prefix=sys_prefix, symlink=symlink, logger=logger)
|
||||
conf_app.start()
|
||||
|
||||
# nbextensions:
|
||||
kwargs = dict(user=user, sys_prefix=sys_prefix, prefix=prefix,
|
||||
nbextensions_dir=nbextensions_dir, logger=logger)
|
||||
'{} jupyter_contrib_nbextensions nbextension files {} {}'.format(
|
||||
'Installing' if install else 'Uninstalling',
|
||||
'to' if install else 'from',
|
||||
'jupyter data directory'))
|
||||
if install:
|
||||
nbextensions.install_nbextension_python(
|
||||
jupyter_contrib_nbextensions.__name__,
|
||||
overwrite=overwrite, symlink=symlink, **kwargs)
|
||||
# enable contrib_nbextensions_help_item (item in help menu)
|
||||
nbextensions.enable_nbextension('notebook',
|
||||
'contrib_nbextensions_help_item/main',
|
||||
user=user, sys_prefix=sys_prefix)
|
||||
else:
|
||||
nbextensions.uninstall_nbextension_python(
|
||||
jupyter_contrib_nbextensions.__name__, **kwargs)
|
||||
|
||||
|
||||
def toggle_install_config(install, user=False, sys_prefix=False, logger=None):
|
||||
"""Install/remove contrib nbextensions to/from jupyter_nbconvert_config."""
|
||||
if notebook_is_running():
|
||||
raise NotebookRunningError(
|
||||
'Cannot configure while the Jupyter notebook server is running')
|
||||
_check_conflicting_kwargs(user=user, sys_prefix=sys_prefix)
|
||||
config_dir = nbextensions._get_config_dir(user=user, sys_prefix=sys_prefix)
|
||||
if logger:
|
||||
logger.info(
|
||||
'{} jupyter_contrib_nbextensions items {} config in {}'.format(
|
||||
'Installing' if install else 'Uninstalling',
|
||||
'to' if install else 'from',
|
||||
config_dir))
|
||||
|
||||
# Configure the jupyter_nbextensions_configurator serverextension to load
|
||||
if install:
|
||||
configurator_app = EnableJupyterNbextensionsConfiguratorApp(
|
||||
user=user, sys_prefix=sys_prefix, logger=logger)
|
||||
configurator_app.start()
|
||||
nbextensions.enable_nbextension(
|
||||
'notebook', 'contrib_nbextensions_help_item/main',
|
||||
user=user, sys_prefix=sys_prefix, logger=logger)
|
||||
else:
|
||||
nbconf_cm = BaseJSONConfigManager(
|
||||
config_dir=os.path.join(config_dir, 'nbconfig'))
|
||||
for require, section in {
|
||||
'contrib_nbextensions_help_item/main': 'notebook'}.items():
|
||||
if logger:
|
||||
logger.info('- Disabling {}'.format(require))
|
||||
logger.info(
|
||||
'-- Editing config: {}'.format(
|
||||
nbconf_cm.file_name(section)))
|
||||
# disabled_conf['load_extensions'][require] = None
|
||||
nbconf_cm.update('notebook', {'load_extensions': {require: None}})
|
||||
|
||||
# Set extra template path, pre- and post-processors for nbconvert
|
||||
cm = BaseJSONConfigManager(config_dir=config_dir)
|
||||
config_basename = 'jupyter_nbconvert_config'
|
||||
@@ -120,7 +160,7 @@ def toggle_install(install, user=False, sys_prefix=False, overwrite=False,
|
||||
|
||||
def install(user=False, sys_prefix=False, prefix=None, nbextensions_dir=None,
|
||||
logger=None, overwrite=False, symlink=False):
|
||||
"""Edit jupyter config files to use jupyter_contrib_nbextensions things."""
|
||||
"""Install all jupyter_contrib_nbextensions files & config."""
|
||||
return toggle_install(
|
||||
True, user=user, sys_prefix=sys_prefix, prefix=prefix,
|
||||
nbextensions_dir=nbextensions_dir, logger=logger,
|
||||
@@ -129,7 +169,7 @@ def install(user=False, sys_prefix=False, prefix=None, nbextensions_dir=None,
|
||||
|
||||
def uninstall(user=False, sys_prefix=False, prefix=None, nbextensions_dir=None,
|
||||
logger=None):
|
||||
"""Edit jupyter config files to not use jupyter_contrib_nbextensions."""
|
||||
"""Uninstall all jupyter_contrib_nbextensions files & config."""
|
||||
return toggle_install(
|
||||
False, user=user, sys_prefix=sys_prefix, prefix=prefix,
|
||||
nbextensions_dir=nbextensions_dir, logger=logger)
|
||||
|
||||
@@ -148,20 +148,24 @@ class AppTest(TestCase):
|
||||
retcode = proc.poll()
|
||||
nt.assert_equal(retcode, 0, 'command should exit with code 0')
|
||||
|
||||
def check_app_install(self, argv=None, dirs=None):
|
||||
def check_app_install(self, argv=None, dirs=None, dirs_install=None):
|
||||
"""Check files were installed in the correct place."""
|
||||
argv, dirs = self._get_default_check_kwargs(argv, dirs)
|
||||
if dirs_install is None:
|
||||
dirs_install = dirs
|
||||
self._call_main_app(argv=['install'] + argv)
|
||||
installed_files = self._check_install(dirs)
|
||||
installed_files = self._check_install(dirs_install)
|
||||
self._call_main_app(argv=['uninstall'] + argv)
|
||||
self._check_uninstall(dirs, installed_files)
|
||||
|
||||
def check_cli_install(self, argv=None, dirs=None,
|
||||
def check_cli_install(self, argv=None, dirs=None, dirs_install=None,
|
||||
app_name='jupyter contrib nbextension'):
|
||||
argv, dirs = self._get_default_check_kwargs(argv, dirs)
|
||||
if dirs_install is None:
|
||||
dirs_install = dirs
|
||||
args = app_name.split(' ') + ['install'] + argv
|
||||
self._check_subproc(args)
|
||||
installed_files = self._check_install(dirs)
|
||||
installed_files = self._check_install(dirs_install)
|
||||
args = app_name.split(' ') + ['uninstall'] + argv
|
||||
self._check_subproc(args)
|
||||
self._check_uninstall(dirs, installed_files)
|
||||
@@ -184,6 +188,8 @@ class AppTest(TestCase):
|
||||
# sys.exit should be called if empty argv specified
|
||||
with nt.assert_raises(SystemExit):
|
||||
main_app([])
|
||||
for klass in app_classes:
|
||||
klass.clear_instance()
|
||||
|
||||
def test_02_argument_conflict(self):
|
||||
"""Check that install objects to multiple flags."""
|
||||
@@ -197,6 +203,8 @@ class AppTest(TestCase):
|
||||
self.log.info('testing conflicting flagset {}'.format(flagset))
|
||||
nt.assert_raises(nbextensions.ArgumentConflict,
|
||||
main_app, [subcommand] + list(flagset))
|
||||
for klass in app_classes:
|
||||
klass.clear_instance()
|
||||
|
||||
def test_03_app_install_defaults(self):
|
||||
"""Check that app install works correctly using defaults."""
|
||||
@@ -265,3 +273,17 @@ class AppTest(TestCase):
|
||||
dirs = self._get_default_check_kwargs()[1]
|
||||
dirs['data'] = self.jupyter_dirs['custom']['data']
|
||||
self.check_app_install(dirs=dirs, argv=['--prefix=' + dirs['data']])
|
||||
|
||||
def test_14_app_install_only_files(self):
|
||||
"""Check that install works correctly using --only-files flag."""
|
||||
argv, dirs = self._get_default_check_kwargs()
|
||||
self.check_app_install(
|
||||
argv=argv + ['--only-files'], dirs=dirs,
|
||||
dirs_install={'data': dirs['data']})
|
||||
|
||||
def test_15_app_install_only_config(self):
|
||||
"""Check that install works correctly using --only-config flag."""
|
||||
argv, dirs = self._get_default_check_kwargs()
|
||||
self.check_app_install(
|
||||
argv=argv + ['--only-config'], dirs=dirs,
|
||||
dirs_install={'conf': dirs['conf']})
|
||||
|
||||
Reference in New Issue
Block a user