Source code for medikit.feature.nodejs

"""
NodeJS / Yarn support.

This feature is experimental and as though it may work for you, that's not a guarantee. Please use with care.

"""

import json
import os
import runpy

import medikit
from medikit.events import subscribe
from medikit.feature import LAST_PRIORITY, Feature
from medikit.feature.make import which
from medikit.steps.version import PythonVersion


[docs]class NodeJSConfig(Feature.Config): """ Configuration API for the «nodejs» feature. """ def __init__(self): self._setup = {} self._dependencies = {None: {}, "dev": {}, "peer": {}, "bundled": {}, "optional": {}} self.base_dir = None
[docs] def setup(self, *, base_dir=None): if base_dir: self.base_dir = base_dir return self
[docs] def add_dependencies(self, deps=None, **kwargs): if deps: self.__add_dependencies(deps) for deptype, deps in kwargs.items(): self.__add_dependencies(deps, deptype=deptype) return self
[docs] def get_dependencies(self): return { deptype + "Dependencies" if deptype else "dependencies": deps for deptype, deps in self._dependencies.items() if len(deps) }
def __add_dependencies(self, deps, deptype=None): if len(deps): if deptype not in self._dependencies: raise KeyError("Invalid dependency type " + deptype) self._dependencies[deptype].update(deps)
[docs]class NodeJSFeature(Feature): requires = {"python", "make"} Config = NodeJSConfig
[docs] @subscribe("medikit.feature.make.on_generate") def on_make_generate(self, event): event.makefile["YARN"] = which("yarn") event.makefile["NODE"] = which("node") event.makefile.get_target("install").install += ["$(YARN) install --production"] event.makefile.get_target("install-dev").install += ["$(YARN) install"]
[docs] @subscribe(medikit.on_start) def on_start(self, event): name = event.config["python"].get("name") current_version = PythonVersion.coerce( runpy.run_path(event.config["python"].version_file).get("__version__"), partial=True ) current_version.partial = False package = { "name": name, "version": str(current_version), "description": event.config["python"].get("description"), "author": event.config["python"].get("author"), "license": event.config["python"].get("license"), **event.config["nodejs"].get_dependencies(), } base_dir = event.config["nodejs"].base_dir or "." self.render_file_inline( os.path.join(base_dir, "package.json"), json.dumps(package, sort_keys=True, indent=4), override=True )
[docs] @subscribe(medikit.on_end, priority=LAST_PRIORITY) def on_end(self, event): base_dir = event.config["nodejs"].base_dir or "." os.system("cd {base_dir}; yarn install".format(base_dir=base_dir)) os.system("cd {base_dir}; git add yarn.lock".format(base_dir=base_dir))