Преглед изворни кода

wip add layering of disabled extension metadata

Steven Silvester пре 4 година
родитељ
комит
4b00b62377

+ 7 - 0
builder/metadata_schema.json

@@ -77,6 +77,13 @@
       "title": "Discovery metadata",
       "description": "Discovery metadata used to for companion packages",
       "type": "object"
+    },
+    "disabledExtensions": {
+      "title": "List of disabled extension modules and/or regex patterns for extension ids",
+      "type": "array",
+      "items": {
+        "type": "string"
+      }
     }
   },
   "additionalProperties": false,

+ 72 - 11
jupyterlab/commands.py

@@ -28,13 +28,14 @@ import warnings
 from jupyter_core.paths import jupyter_config_path, jupyter_path
 from jupyterlab_server.process import which, Process, WatchHelper, list2cmdline
 from notebook.nbextensions import GREEN_ENABLED, GREEN_OK, RED_DISABLED, RED_X
-from traitlets import HasTraits, Bool, Unicode, Instance, default
+from traitlets import HasTraits, Bool, Dict, Instance, Unicode, default
 
 from jupyterlab.semver import Range, gte, lt, lte, gt, make_semver
 from jupyterlab.jlpmapp import YARN_PATH, HERE
 from jupyterlab.coreconfig import _get_default_core_data, CoreConfig
 
-from .manager import ConfigManager
+from jupyter_server.services.config.manager import ConfigManager
+from jupyter_server._version import version_info as jpserver_version_info
 
 # The regex for expecting the webpack output.
 WEBPACK_EXPECT = re.compile(r'.*/index.out.js')
@@ -295,10 +296,63 @@ def watch_dev(logger=None):
     return package_procs + [wp_proc]
 
 
-def get_page_config():
+def get_page_config(app_options=None):
+    app_options = _ensure_options(app_options)
+
     """Get the page config for the application"""
-    cm = ConfigManager()
-    return cm.get('page_config')
+
+    # Start with the deprecated `share/jupyter/lab/settings/page_config.json` data
+    page_config = dict()
+    old_page_config = pjoin(app_options.app_dir, 'settings', 'page_config.json')
+    if osp.exists(old_page_config):
+        app_options.log.warn('Using deprecated page_config in %s' % old_page_config)
+        app_options.log.warn('This will no longer have an effect in JupyterLab 4.0')
+        with open(old_page_config) as fid:
+            page_config.update(json.load(fid))
+
+    cm = ConfigManager(config_dir_name="labconfig")
+    page_config.update(cm.get('page_config'))
+    
+    # Handle dynamic extensions
+    app_options.page_config = page_config
+
+    # Add a recursion guard and get the app info
+    page_config['_null'] = False
+    info = get_app_info(app_options=app_options)
+    del page_config['_null']
+
+    extensions = page_config['dynamic_extensions'] = []
+    disabled_by_extensions_all = dict()
+
+    for (ext, ext_data) in info.get('dynamic_exts', dict()).items():
+        extbuild = ext_data['jupyterlab']['_build']
+        extension = {
+            'name': ext_data['name'],
+            'load': extbuild['load']
+        }
+        if 'extension' in extbuild:
+            extension['extension'] = extbuild['extension']
+        if 'mimeExtension' in extbuild:
+            extension['mimeExtension'] = extbuild['mimeExtension']
+        if 'style' in extbuild:
+            extension['style'] = extbuild['style']
+        extensions.append(extension)
+
+        # If there is disabledExtensions metadata, consume it.
+        if ext_data['jupyterlab']['disabledExtensions']:
+            disabled_by_extensions_all[ext_data['name']] = ext_data['jupyterlab']['disabledExtensions']
+
+    disabled_by_extensions = dict()
+    for name in sorted(disabled_by_extensions_all):
+        disabled_list = disabled_by_extensions_all[name]
+        for item in disabled_list:
+            disabled_by_extensions[item] = True
+
+    disabledExtensions = disabled_by_extensions
+    disabledExtensions.update(page_config.get('disabled_labextensions', []))
+    page_config['disabled_labextensions'] = disabledExtensions
+    
+    return page_config
 
 
 class AppOptions(HasTraits):
@@ -318,6 +372,8 @@ class AppOptions(HasTraits):
 
     app_dir = Unicode(help='The application directory')
 
+    page_config = Dict(help='The page config options')
+
     use_sys_dir = Bool(
         True,
         help=('Whether to shadow the default app_dir if that is set to a '
@@ -572,6 +628,7 @@ class _AppHandler(object):
         """Create a new _AppHandler object
         """
         options = _ensure_options(options)
+        self._options = options
         self.app_dir = options.app_dir
         self.sys_dir = get_app_dir() if options.use_sys_dir else self.app_dir
         self.logger = options.logger
@@ -726,10 +783,10 @@ class _AppHandler(object):
             logger.info('\nUninstalled core extensions:')
             [logger.info('    %s' % item) for item in sorted(uninstalled_core)]
 
-        disabled_core = info['disabled_core']
-        if disabled_core:
-            logger.info('\nDisabled core extensions:')
-            [logger.info('    %s' % item) for item in sorted(disabled_core)]
+        disabled = info['disabled']
+        if disabled:
+            logger.info('\nDisabled extensions:')
+            [logger.info('    %s' % item) for item in sorted(disabled)]
 
         messages = self.build_check(fast=True)
         if messages:
@@ -1000,7 +1057,7 @@ class _AppHandler(object):
             did_something = True
         if did_something:
             page_config['disabled_labextensions'] = disabled
-            cm = ConfigManager()
+            cm = ConfigManager(config_dir_name='labconfig')
             cm.set('page_config', page_config)
         return did_something
 
@@ -1067,7 +1124,11 @@ class _AppHandler(object):
         info['core_data'] = core_data = self.core_data
         info['extensions'] = extensions = self._get_extensions(core_data)
 
-        info['disabled'] = list(get_page_config().get('disabled_labextensions', {}))
+        page_config = self._options.page_config 
+        if not page_config:
+            page_config = get_page_config(app_options=self._options)
+
+        info['disabled'] = list(page_config.get('disabled_labextensions', {}))
         info['local_extensions'] = self._get_local_extensions()
         info['linked_packages'] = self._get_linked_packages()
         info['app_extensions'] = app = []

+ 2 - 19
jupyterlab/labapp.py

@@ -15,7 +15,7 @@ from jupyter_core.application import JupyterApp, base_aliases, base_flags
 from jupyter_core.application import NoStart
 from jupyterlab_server import slugify, WORKSPACE_EXTENSION
 from jupyter_server.serverapp import flags
-from jupyter_server.utils import url_path_join as ujoin
+from jupyter_server.utils import url_path_join as ujoin, url_escape
 from jupyter_server._version import version_info as jpserver_version_info
 from traitlets import Bool, Instance, Unicode, default
 
@@ -700,28 +700,11 @@ class LabApp(NBClassicConfigShimMixin, LabServerApp):
             page_config['hubUser'] = self.user
             page_config['shareUrl'] = ujoin(self.hub_prefix, 'user-redirect')
             # Assume the server_name property indicates running JupyterHub 1.0.
-            if hasattr(labapp, 'server_name'):
+            if hasattr(self, 'server_name'):
                 page_config['hubServerName'] = self.server_name
             api_token = os.getenv('JUPYTERHUB_API_TOKEN', '')
             page_config['token'] = api_token
 
-        # Handle dynamic extensions
-        info = get_app_info()
-        extensions = page_config['dynamic_extensions'] = []
-        for (ext, ext_data) in info.get('dynamic_exts', dict()).items():
-            extbuild = ext_data['jupyterlab']['_build']
-            extension = {
-                'name': ext_data['name'],
-                'load': extbuild['load']
-            }
-            if 'extension' in extbuild:
-                extension['extension'] = extbuild['extension']
-            if 'mimeExtension' in extbuild:
-                extension['mimeExtension'] = extbuild['mimeExtension']
-            if 'style' in extbuild:
-                extension['style'] = extbuild['style']
-            extensions.append(extension)
-
         # Update Jupyter Server's webapp settings with jupyterlab settings.
         self.serverapp.web_app.settings['page_config_data'] = page_config
 

+ 0 - 58
jupyterlab/manager.py

@@ -1,58 +0,0 @@
-"""Manager to read and modify frontend config data in JSON files.
-"""
-# Copyright (c) Jupyter Development Team.
-# Distributed under the terms of the Modified BSD License.
-
-import os.path
-
-from jupyter_server.config_manager import BaseJSONConfigManager, recursive_update
-from jupyter_core.paths import jupyter_config_dir, jupyter_config_path
-from traitlets import Unicode, Instance, List, observe, default
-from traitlets.config import LoggingConfigurable
-
-
-class ConfigManager(LoggingConfigurable):
-    """Config Manager used for storing notebook frontend config"""
-
-    # Public API
-
-    def get(self, section_name):
-        """Get the config from all config sections."""
-        config = {}
-        # step through back to front, to ensure front of the list is top priority
-        for p in self.read_config_path[::-1]:
-            cm = BaseJSONConfigManager(config_dir=p)
-            recursive_update(config, cm.get(section_name))
-        return config
-
-    def set(self, section_name, data):
-        """Set the config only to the user's config."""
-        return self.write_config_manager.set(section_name, data)
-
-    def update(self, section_name, new_data):
-        """Update the config only to the user's config."""
-        return self.write_config_manager.update(section_name, new_data)
-
-    # Private API
-
-    read_config_path = List(Unicode())
-
-    @default('read_config_path')
-    def _default_read_config_path(self):
-        return [os.path.join(p, 'labconfig') for p in jupyter_config_path()]
-
-    write_config_dir = Unicode()
-
-    @default('write_config_dir')
-    def _default_write_config_dir(self):
-        return os.path.join(jupyter_config_dir(), 'labconfig')
-
-    write_config_manager = Instance(BaseJSONConfigManager)
-
-    @default('write_config_manager')
-    def _default_write_config_manager(self):
-        return BaseJSONConfigManager(config_dir=self.write_config_dir)
-
-    @observe('write_config_dir')
-    def _update_write_config_dir(self, change):
-        self.write_config_manager = BaseJSONConfigManager(config_dir=self.write_config_dir)

+ 2 - 1
jupyterlab/tests/mock_packages/extension/package.json

@@ -9,6 +9,7 @@
     "@jupyterlab/builder": "^3.0.0-beta.1"
   },
   "jupyterlab": {
-    "extension": true
+    "extension": true,
+    "disabledExtensions": ["@jupyterlab/filebrowser-extension:share-file"]
   }
 }

+ 1 - 2
scripts/ci_script.sh

@@ -183,8 +183,7 @@ if [[ $GROUP == usage ]]; then
     jupyter labextension develop extension --debug
     jupyter labextension build extension
 
-    # TODO: reinstate after beta release
-    # python -m jupyterlab.browser_check
+    python -m jupyterlab.browser_check
     jupyter labextension list 1>labextensions 2>&1
     cat labextensions | grep "@jupyterlab/mock-extension.*enabled.*OK"
     jupyter labextension build extension --static-url /foo/

+ 1 - 0
setup.py

@@ -152,6 +152,7 @@ setup_args['install_requires'] = [
     'ipython',
     'tornado!=6.0.0, !=6.0.1, !=6.0.2',
     'jupyterlab_server~=2.0.0b5',
+    'jupyter_server~=1.0.0rc13',
     'nbclassic~=0.2.0rc4',
     'jinja2>=2.10'
 ]