# HG changeset patch # User Goffi # Date 1588174751 -7200 # Node ID 780dbc2f4853d881b198eb9bc73800f9ff8d6275 # Parent 6d49fae517ba2464e79c99445b2ba6add742cf2c server (tasks): new `js_modules` implicit task: /!\ either `yarn` (preferred) or `npm` (fallback) is a new dependency This task will install JS modules specified in `browser_meta.js` using either `yarn` or `npm`. A mapping for Brython can also be specified in browser metadata, in this case Python modules will be created and put in the `js_modules` python package. diff -r 6d49fae517ba -r 780dbc2f4853 libervia/server/tasks/implicit/task_js_modules.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libervia/server/tasks/implicit/task_js_modules.py Wed Apr 29 17:39:11 2020 +0200 @@ -0,0 +1,71 @@ +#!/ur/bin/env python3 + +import json +from pathlib import Path +from sat.core.i18n import _ +from sat.core.log import getLogger +from sat.core import exceptions +from libervia.server.constants import Const as C +from libervia.server.tasks import task + + +log = getLogger(__name__) + + +class Task(task.Task): + + async def prepare(self): + if "js" not in self.resource.browser_modules: + raise exceptions.CancelError(f"No JS module needed") + + async def start(self): + js_data = self.resource.browser_modules['js'] + package = js_data.get('package', {}) + package_path = self.build_path / 'package.json' + with package_path.open('w') as f: + json.dump(package, f) + + try: + cmd = self.findCommand('yarn') + except exceptions.NotFound: + cmd = self.findCommand('npm') + await self.runCommand(cmd, 'install', path=str(self.build_path)) + + try: + brython_map = js_data['brython_map'] + except KeyError: + pass + else: + log.info(_("creating JS modules mapping for Brython")) + js_modules_path = self.build_path / 'js_modules' + js_modules_path.mkdir(exist_ok=True) + init_path = js_modules_path / '__init__.py' + init_path.touch() + + for module_name, module_data in brython_map.items(): + log.debug(f"generating mapping for {module_name}") + if ' ' in module_name: + raise ValueError( + f"module {module_name!r} has space(s), it must not!") + module_path = js_modules_path / f"{module_name}.py" + if isinstance(module_data, str): + module_data = {'path': module_data} + try: + js_path = module_data.pop('path') + except KeyError: + raise ValueError( + f'module data for {module_name} must have a "path" key') + module_data['path'] = Path('node_modules') / js_path.strip(' /') + export = module_data.get('export') or [module_name] + export_objects = '\n'.join(f'{e} = window.{e}' for e in export) + + with module_path.open('w') as f: + f.write(f"""\ +#!/usr/bin/env python3 +from browser import window, load +{module_data.get('extra_import', '')} + +load("{Path('/').joinpath(C.BUILD_DIR, module_data['path'])}") +{export_objects} +{module_data.get('extra_init', '')} +""")