123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- import os
- import subprocess
- import sys
- from abc import ABCMeta, abstractmethod
- from six import add_metaclass
- from .constants import NPM_REGISTRY_URL
- from .package_json import PackageJson
- from .utils import build_nm_path, build_pj_path
- from .timeit import timeit
- class PackageManagerError(RuntimeError):
- pass
- class PackageManagerCommandError(PackageManagerError):
- def __init__(self, cmd, code, stdout, stderr):
- self.cmd = cmd
- self.code = code
- self.stdout = stdout
- self.stderr = stderr
- msg = "package manager exited with code {} while running {}:\n{}\n{}".format(code, cmd, stdout, stderr)
- super(PackageManagerCommandError, self).__init__(msg)
- @add_metaclass(ABCMeta)
- class BasePackageManager(object):
- def __init__(
- self,
- build_root,
- build_path,
- sources_path,
- nodejs_bin_path,
- script_path,
- module_path=None,
- sources_root=None,
- ):
- self.module_path = build_path[len(build_root) + 1 :] if module_path is None else module_path
- self.build_path = build_path
- self.sources_path = sources_path
- self.build_root = build_root
- self.sources_root = sources_path[: -len(self.module_path) - 1] if sources_root is None else sources_root
- self.nodejs_bin_path = nodejs_bin_path
- self.script_path = script_path
- @classmethod
- def load_package_json(cls, path):
- """
- :param path: path to package.json
- :type path: str
- :rtype: PackageJson
- """
- return PackageJson.load(path)
- @classmethod
- def load_package_json_from_dir(cls, dir_path):
- """
- :param dir_path: path to directory with package.json
- :type dir_path: str
- :rtype: PackageJson
- """
- return cls.load_package_json(build_pj_path(dir_path))
- def _build_package_json(self):
- """
- :rtype: PackageJson
- """
- pj = self.load_package_json_from_dir(self.sources_path)
- if not os.path.exists(self.build_path):
- os.makedirs(self.build_path, exist_ok=True)
- pj.path = build_pj_path(self.build_path)
- pj.write()
- return pj
- @classmethod
- @abstractmethod
- def load_lockfile(cls, path):
- pass
- @classmethod
- @abstractmethod
- def load_lockfile_from_dir(cls, dir_path):
- pass
- @abstractmethod
- def create_node_modules(self, yatool_prebuilder_path=None, local_cli=False, bundle=True):
- pass
- @abstractmethod
- def extract_packages_meta_from_lockfiles(self, lf_paths):
- pass
- @abstractmethod
- def calc_prepare_deps_inouts_and_resources(
- self, store_path: str, has_deps: bool
- ) -> tuple[list[str], list[str], list[str]]:
- pass
- @abstractmethod
- def calc_node_modules_inouts(self, local_cli: bool, has_deps: bool) -> tuple[list[str], list[str]]:
- pass
- @abstractmethod
- def build_workspace(self, tarballs_store: str):
- pass
- def get_local_peers_from_package_json(self):
- """
- Returns paths of direct workspace dependencies (source root related).
- :rtype: list of str
- """
- return self.load_package_json_from_dir(self.sources_path).get_workspace_dep_paths(base_path=self.module_path)
- def get_peers_from_package_json(self):
- """
- Returns paths of workspace dependencies (source root related).
- :rtype: list of str
- """
- pj = self.load_package_json_from_dir(self.sources_path)
- prefix_len = len(self.sources_root) + 1
- return [p[prefix_len:] for p in pj.get_workspace_map(ignore_self=True).keys()]
- @timeit
- def _exec_command(self, args, cwd: str, include_defaults=True, script_path=None, env=None):
- if not self.nodejs_bin_path:
- raise PackageManagerError("Unable to execute command: nodejs_bin_path is not configured")
- cmd = (
- [self.nodejs_bin_path, script_path or self.script_path]
- + args
- + (self._get_default_options() if include_defaults else [])
- )
- p = subprocess.Popen(cmd, cwd=cwd, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
- stdout, stderr = p.communicate()
- if p.returncode != 0:
- self._dump_debug_log()
- raise PackageManagerCommandError(cmd, p.returncode, stdout.decode("utf-8"), stderr.decode("utf-8"))
- def _nm_path(self, *parts):
- return os.path.join(build_nm_path(self.build_path), *parts)
- def _tarballs_store_path(self, pkg, store_path):
- return os.path.join(self.module_path, store_path, pkg.tarball_path)
- def _get_default_options(self):
- return ["--registry", NPM_REGISTRY_URL]
- def _get_debug_log_path(self):
- return None
- def _dump_debug_log(self):
- log_path = self._get_debug_log_path()
- if not log_path:
- return
- try:
- with open(log_path) as f:
- sys.stderr.write("Package manager log {}:\n{}\n".format(log_path, f.read()))
- except Exception:
- sys.stderr.write("Failed to dump package manager log {}.\n".format(log_path))
|