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))