aboutsummaryrefslogtreecommitdiffstats
path: root/build/plugins/lib/nots/package_manager/base
diff options
context:
space:
mode:
authordankolesnikov <dankolesnikov@yandex-team.ru>2022-02-10 16:51:07 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:51:07 +0300
commit98174ab8f0e6dbed8894c8226f62cac4bf36171d (patch)
tree00cab7b3b62da0fe104a2a99c2886064cc0b0d63 /build/plugins/lib/nots/package_manager/base
parent2e8363373770594fa3e83f1410d513cff82abb30 (diff)
downloadydb-98174ab8f0e6dbed8894c8226f62cac4bf36171d.tar.gz
Restoring authorship annotation for <dankolesnikov@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'build/plugins/lib/nots/package_manager/base')
-rw-r--r--build/plugins/lib/nots/package_manager/base/__init__.py22
-rw-r--r--build/plugins/lib/nots/package_manager/base/constants.py10
-rw-r--r--build/plugins/lib/nots/package_manager/base/lockfile.py136
-rw-r--r--build/plugins/lib/nots/package_manager/base/package_json.py226
-rw-r--r--build/plugins/lib/nots/package_manager/base/package_manager.py216
-rw-r--r--build/plugins/lib/nots/package_manager/base/tests/package_json.py228
-rw-r--r--build/plugins/lib/nots/package_manager/base/tests/ya.make26
-rw-r--r--build/plugins/lib/nots/package_manager/base/ya.make42
8 files changed, 453 insertions, 453 deletions
diff --git a/build/plugins/lib/nots/package_manager/base/__init__.py b/build/plugins/lib/nots/package_manager/base/__init__.py
index 1b55fe3f56..b7f6729eec 100644
--- a/build/plugins/lib/nots/package_manager/base/__init__.py
+++ b/build/plugins/lib/nots/package_manager/base/__init__.py
@@ -1,11 +1,11 @@
-from . import constants
-from .lockfile import BaseLockfile, LockfilePackageMeta, LockfilePackageMetaInvalidError
-from .package_json import PackageJson
-from .package_manager import BasePackageManager, PackageManagerError, PackageManagerCommandError
-
-__all__ = [
- "constants",
- "BaseLockfile", "LockfilePackageMeta", "LockfilePackageMetaInvalidError",
- "BasePackageManager", "PackageManagerError", "PackageManagerCommandError",
- "PackageJson",
-]
+from . import constants
+from .lockfile import BaseLockfile, LockfilePackageMeta, LockfilePackageMetaInvalidError
+from .package_json import PackageJson
+from .package_manager import BasePackageManager, PackageManagerError, PackageManagerCommandError
+
+__all__ = [
+ "constants",
+ "BaseLockfile", "LockfilePackageMeta", "LockfilePackageMetaInvalidError",
+ "BasePackageManager", "PackageManagerError", "PackageManagerCommandError",
+ "PackageJson",
+]
diff --git a/build/plugins/lib/nots/package_manager/base/constants.py b/build/plugins/lib/nots/package_manager/base/constants.py
index 0b9fcb76af..89bfe8a42e 100644
--- a/build/plugins/lib/nots/package_manager/base/constants.py
+++ b/build/plugins/lib/nots/package_manager/base/constants.py
@@ -1,5 +1,5 @@
-PACKAGE_JSON_FILENAME = "package.json"
-NODE_MODULES_BUNDLE_FILENAME = "node_modules.tar"
-NPM_REGISTRY_URL = "http://npm.yandex-team.ru"
-PNPM_WS_FILENAME = "pnpm-workspace.yaml"
-PNPM_LOCKFILE_FILENAME = "pnpm-lock.yaml"
+PACKAGE_JSON_FILENAME = "package.json"
+NODE_MODULES_BUNDLE_FILENAME = "node_modules.tar"
+NPM_REGISTRY_URL = "http://npm.yandex-team.ru"
+PNPM_WS_FILENAME = "pnpm-workspace.yaml"
+PNPM_LOCKFILE_FILENAME = "pnpm-lock.yaml"
diff --git a/build/plugins/lib/nots/package_manager/base/lockfile.py b/build/plugins/lib/nots/package_manager/base/lockfile.py
index 9b9c0be954..8a377045ed 100644
--- a/build/plugins/lib/nots/package_manager/base/lockfile.py
+++ b/build/plugins/lib/nots/package_manager/base/lockfile.py
@@ -1,68 +1,68 @@
-import os
-
-from abc import ABCMeta, abstractmethod
-from six import add_metaclass
-
-
-class LockfilePackageMeta(object):
- """
- Basic struct representing package meta from lockfile.
- """
- __slots__ = ("name", "version", "sky_id", "integrity", "integrity_algorithm", "tarball_path")
-
- @staticmethod
- def from_str(s):
- return LockfilePackageMeta(*s.strip().split(" "))
-
- def __init__(self, name, version, sky_id, integrity, integrity_algorithm):
- self.name = name
- self.version = version
- self.sky_id = sky_id
- self.integrity = integrity
- self.integrity_algorithm = integrity_algorithm
- self.tarball_path = "{}-{}.tgz".format(name, version)
-
- def to_str(self):
- return " ".join([self.name, self.version, self.sky_id, self.integrity, self.integrity_algorithm])
-
-
-class LockfilePackageMetaInvalidError(RuntimeError):
- pass
-
-
-@add_metaclass(ABCMeta)
-class BaseLockfile(object):
- @classmethod
- def load(cls, path):
- """
- :param path: lockfile path
- :type path: str
- :rtype: BaseLockfile
- """
- pj = cls(path)
- pj.read()
-
- return pj
-
- def __init__(self, path):
- if not os.path.isabs(path):
- raise TypeError("Absolute path required, given: {}".format(path))
-
- self.path = path
- self.data = None
-
- @abstractmethod
- def read(self):
- pass
-
- @abstractmethod
- def write(self, path=None):
- pass
-
- @abstractmethod
- def get_packages_meta(self):
- pass
-
- @abstractmethod
- def update_tarball_resolutions(self, fn):
- pass
+import os
+
+from abc import ABCMeta, abstractmethod
+from six import add_metaclass
+
+
+class LockfilePackageMeta(object):
+ """
+ Basic struct representing package meta from lockfile.
+ """
+ __slots__ = ("name", "version", "sky_id", "integrity", "integrity_algorithm", "tarball_path")
+
+ @staticmethod
+ def from_str(s):
+ return LockfilePackageMeta(*s.strip().split(" "))
+
+ def __init__(self, name, version, sky_id, integrity, integrity_algorithm):
+ self.name = name
+ self.version = version
+ self.sky_id = sky_id
+ self.integrity = integrity
+ self.integrity_algorithm = integrity_algorithm
+ self.tarball_path = "{}-{}.tgz".format(name, version)
+
+ def to_str(self):
+ return " ".join([self.name, self.version, self.sky_id, self.integrity, self.integrity_algorithm])
+
+
+class LockfilePackageMetaInvalidError(RuntimeError):
+ pass
+
+
+@add_metaclass(ABCMeta)
+class BaseLockfile(object):
+ @classmethod
+ def load(cls, path):
+ """
+ :param path: lockfile path
+ :type path: str
+ :rtype: BaseLockfile
+ """
+ pj = cls(path)
+ pj.read()
+
+ return pj
+
+ def __init__(self, path):
+ if not os.path.isabs(path):
+ raise TypeError("Absolute path required, given: {}".format(path))
+
+ self.path = path
+ self.data = None
+
+ @abstractmethod
+ def read(self):
+ pass
+
+ @abstractmethod
+ def write(self, path=None):
+ pass
+
+ @abstractmethod
+ def get_packages_meta(self):
+ pass
+
+ @abstractmethod
+ def update_tarball_resolutions(self, fn):
+ pass
diff --git a/build/plugins/lib/nots/package_manager/base/package_json.py b/build/plugins/lib/nots/package_manager/base/package_json.py
index 3d0bf3238e..f9c1caf368 100644
--- a/build/plugins/lib/nots/package_manager/base/package_json.py
+++ b/build/plugins/lib/nots/package_manager/base/package_json.py
@@ -1,113 +1,113 @@
-import os
-import json
-
-from six import iteritems
-
-from . import constants
-
-
-class PackageJsonWorkspaceError(RuntimeError):
- pass
-
-
-class PackageJson(object):
- DEP_KEY = "dependencies"
- DEV_DEP_KEY = "devDependencies"
- PEER_DEP_KEY = "peerDependencies"
- OPT_DEP_KEY = "optionalDependencies"
- DEP_KEYS = (DEP_KEY, DEV_DEP_KEY, PEER_DEP_KEY, OPT_DEP_KEY)
-
- WORKSPACE_SCHEMA = "workspace:"
-
- @classmethod
- def load(cls, path):
- """
- :param path: package.json path
- :type path: str
- :rtype: PackageJson
- """
- pj = cls(path)
- pj.read()
-
- return pj
-
- def __init__(self, path):
- if not os.path.isabs(path):
- raise TypeError("Absolute path required, given: {}".format(path))
-
- self.path = path
- self.data = None
-
- def read(self):
- with open(self.path) as f:
- self.data = json.load(f)
-
- def get_name(self):
- return self.data.get("name")
-
- def get_workspace_dep_paths(self):
- """
- :return: Workspace dependencies.
- :rtype: list of (str, str)
- """
- dep_paths = []
- schema = self.WORKSPACE_SCHEMA
- schema_len = len(schema)
-
- for deps in map(lambda x: self.data.get(x), self.DEP_KEYS):
- if not deps:
- continue
-
- for name, spec in iteritems(deps):
- if not spec.startswith(schema):
- continue
-
- spec_path = spec[schema_len:]
- if not (spec_path.startswith(".") or spec_path.startswith("..")):
- raise PackageJsonWorkspaceError(
- "Expected relative path specifier for workspace dependency, but got '{}' for {} in {}".format(spec, name, self.path))
-
- dep_paths.append((name, spec_path))
-
- return dep_paths
-
- def get_workspace_deps(self):
- """
- :rtype: list of PackageJson
- """
- ws_deps = []
- pj_dir = os.path.dirname(self.path)
-
- for (name, rel_path) in self.get_workspace_dep_paths():
- dep_path = os.path.normpath(os.path.join(pj_dir, rel_path))
- dep_pj = PackageJson.load(os.path.join(dep_path, constants.PACKAGE_JSON_FILENAME))
-
- if name != dep_pj.get_name():
- raise PackageJsonWorkspaceError(
- "Workspace dependency name mismatch, found '{}' instead of '{}' in {}".format(name, dep_pj.get_name(), self.path))
-
- ws_deps.append(dep_pj)
-
- return ws_deps
-
- def get_workspace_map(self):
- """
- :return: Absolute paths of workspace dependencies (including transitive) mapped to package.json and depth.
- :rtype: dict of (PackageJson, int)
- """
- ws_deps = {}
- # list of (pj, depth)
- pj_queue = [(self, 0)]
-
- while len(pj_queue):
- (pj, depth) = pj_queue.pop()
- pj_dir = os.path.dirname(pj.path)
- if pj_dir in ws_deps:
- continue
-
- ws_deps[pj_dir] = (pj, depth)
-
- for dep_pj in pj.get_workspace_deps():
- pj_queue.append((dep_pj, depth + 1))
-
- return ws_deps
+import os
+import json
+
+from six import iteritems
+
+from . import constants
+
+
+class PackageJsonWorkspaceError(RuntimeError):
+ pass
+
+
+class PackageJson(object):
+ DEP_KEY = "dependencies"
+ DEV_DEP_KEY = "devDependencies"
+ PEER_DEP_KEY = "peerDependencies"
+ OPT_DEP_KEY = "optionalDependencies"
+ DEP_KEYS = (DEP_KEY, DEV_DEP_KEY, PEER_DEP_KEY, OPT_DEP_KEY)
+
+ WORKSPACE_SCHEMA = "workspace:"
+
+ @classmethod
+ def load(cls, path):
+ """
+ :param path: package.json path
+ :type path: str
+ :rtype: PackageJson
+ """
+ pj = cls(path)
+ pj.read()
+
+ return pj
+
+ def __init__(self, path):
+ if not os.path.isabs(path):
+ raise TypeError("Absolute path required, given: {}".format(path))
+
+ self.path = path
+ self.data = None
+
+ def read(self):
+ with open(self.path) as f:
+ self.data = json.load(f)
+
+ def get_name(self):
+ return self.data.get("name")
+
+ def get_workspace_dep_paths(self):
+ """
+ :return: Workspace dependencies.
+ :rtype: list of (str, str)
+ """
+ dep_paths = []
+ schema = self.WORKSPACE_SCHEMA
+ schema_len = len(schema)
+
+ for deps in map(lambda x: self.data.get(x), self.DEP_KEYS):
+ if not deps:
+ continue
+
+ for name, spec in iteritems(deps):
+ if not spec.startswith(schema):
+ continue
+
+ spec_path = spec[schema_len:]
+ if not (spec_path.startswith(".") or spec_path.startswith("..")):
+ raise PackageJsonWorkspaceError(
+ "Expected relative path specifier for workspace dependency, but got '{}' for {} in {}".format(spec, name, self.path))
+
+ dep_paths.append((name, spec_path))
+
+ return dep_paths
+
+ def get_workspace_deps(self):
+ """
+ :rtype: list of PackageJson
+ """
+ ws_deps = []
+ pj_dir = os.path.dirname(self.path)
+
+ for (name, rel_path) in self.get_workspace_dep_paths():
+ dep_path = os.path.normpath(os.path.join(pj_dir, rel_path))
+ dep_pj = PackageJson.load(os.path.join(dep_path, constants.PACKAGE_JSON_FILENAME))
+
+ if name != dep_pj.get_name():
+ raise PackageJsonWorkspaceError(
+ "Workspace dependency name mismatch, found '{}' instead of '{}' in {}".format(name, dep_pj.get_name(), self.path))
+
+ ws_deps.append(dep_pj)
+
+ return ws_deps
+
+ def get_workspace_map(self):
+ """
+ :return: Absolute paths of workspace dependencies (including transitive) mapped to package.json and depth.
+ :rtype: dict of (PackageJson, int)
+ """
+ ws_deps = {}
+ # list of (pj, depth)
+ pj_queue = [(self, 0)]
+
+ while len(pj_queue):
+ (pj, depth) = pj_queue.pop()
+ pj_dir = os.path.dirname(pj.path)
+ if pj_dir in ws_deps:
+ continue
+
+ ws_deps[pj_dir] = (pj, depth)
+
+ for dep_pj in pj.get_workspace_deps():
+ pj_queue.append((dep_pj, depth + 1))
+
+ return ws_deps
diff --git a/build/plugins/lib/nots/package_manager/base/package_manager.py b/build/plugins/lib/nots/package_manager/base/package_manager.py
index 0de9d8acc3..9c0fcb8c34 100644
--- a/build/plugins/lib/nots/package_manager/base/package_manager.py
+++ b/build/plugins/lib/nots/package_manager/base/package_manager.py
@@ -1,108 +1,108 @@
-import os
-import sys
-import subprocess
-import tarfile
-
-from abc import ABCMeta, abstractmethod
-from six import add_metaclass
-
-from . import constants
-
-
-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, contribs_path):
- self.module_path = build_path[len(build_root) + 1:]
- 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]
- self.nodejs_bin_path = nodejs_bin_path
- self.script_path = script_path
- self.contribs_path = contribs_path
-
- @abstractmethod
- def install(self):
- pass
-
- @abstractmethod
- def get_peer_paths_from_package_json(self):
- pass
-
- @abstractmethod
- def calc_node_modules_inouts(self):
- pass
-
- @abstractmethod
- def extract_packages_meta_from_lockfiles(self, lf_paths):
- pass
-
- def create_node_modules_bundle(self, path):
- """
- Creates tarball from the node_modules directory contents.
- :param path: tarball path
- :type path: str
- """
- with tarfile.open(path, "w") as tf:
- tf.add(self._nm_path(), arcname=".")
-
- def _exec_command(self, args, include_defaults=True):
- if not self.nodejs_bin_path:
- raise PackageManagerError("Unable to execute command: nodejs_bin_path is not configured")
-
- cmd = [self.nodejs_bin_path, self.script_path] + args + (self._get_default_options() if include_defaults else [])
- p = subprocess.Popen(
- cmd,
- cwd=self.build_path,
- stdin=None,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- )
- 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(self.build_path, "node_modules", *parts)
-
- def _contrib_tarball_path(self, pkg):
- return os.path.join(self.contribs_path, pkg.tarball_path)
-
- def _contrib_tarball_url(self, pkg):
- return "file:" + self._contrib_tarball_path(pkg)
-
- def _get_default_options(self):
- return ["--registry", constants.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:
- sys.stderr.write("Failed to dump package manager log {}.\n".format(log_path))
+import os
+import sys
+import subprocess
+import tarfile
+
+from abc import ABCMeta, abstractmethod
+from six import add_metaclass
+
+from . import constants
+
+
+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, contribs_path):
+ self.module_path = build_path[len(build_root) + 1:]
+ 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]
+ self.nodejs_bin_path = nodejs_bin_path
+ self.script_path = script_path
+ self.contribs_path = contribs_path
+
+ @abstractmethod
+ def install(self):
+ pass
+
+ @abstractmethod
+ def get_peer_paths_from_package_json(self):
+ pass
+
+ @abstractmethod
+ def calc_node_modules_inouts(self):
+ pass
+
+ @abstractmethod
+ def extract_packages_meta_from_lockfiles(self, lf_paths):
+ pass
+
+ def create_node_modules_bundle(self, path):
+ """
+ Creates tarball from the node_modules directory contents.
+ :param path: tarball path
+ :type path: str
+ """
+ with tarfile.open(path, "w") as tf:
+ tf.add(self._nm_path(), arcname=".")
+
+ def _exec_command(self, args, include_defaults=True):
+ if not self.nodejs_bin_path:
+ raise PackageManagerError("Unable to execute command: nodejs_bin_path is not configured")
+
+ cmd = [self.nodejs_bin_path, self.script_path] + args + (self._get_default_options() if include_defaults else [])
+ p = subprocess.Popen(
+ cmd,
+ cwd=self.build_path,
+ stdin=None,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ )
+ 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(self.build_path, "node_modules", *parts)
+
+ def _contrib_tarball_path(self, pkg):
+ return os.path.join(self.contribs_path, pkg.tarball_path)
+
+ def _contrib_tarball_url(self, pkg):
+ return "file:" + self._contrib_tarball_path(pkg)
+
+ def _get_default_options(self):
+ return ["--registry", constants.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:
+ sys.stderr.write("Failed to dump package manager log {}.\n".format(log_path))
diff --git a/build/plugins/lib/nots/package_manager/base/tests/package_json.py b/build/plugins/lib/nots/package_manager/base/tests/package_json.py
index 3657e581bc..64a7841e50 100644
--- a/build/plugins/lib/nots/package_manager/base/tests/package_json.py
+++ b/build/plugins/lib/nots/package_manager/base/tests/package_json.py
@@ -1,114 +1,114 @@
-import os
-import pytest
-
-from build.plugins.lib.nots.package_manager.base.package_json import PackageJson, PackageJsonWorkspaceError
-
-
-def test_get_workspace_dep_paths_ok():
- pj = PackageJson("/packages/foo/package.json")
- pj.data = {
- "dependencies": {
- "@yandex-int/bar": "workspace:../bar",
- },
- "devDependencies": {
- "@yandex-int/baz": "workspace:../baz",
- },
- }
-
- ws_dep_paths = pj.get_workspace_dep_paths()
-
- assert ws_dep_paths == [
- ("@yandex-int/bar", "../bar"),
- ("@yandex-int/baz", "../baz"),
- ]
-
-
-def test_get_workspace_dep_paths_invalid_path():
- pj = PackageJson("/packages/foo/package.json")
- pj.data = {
- "dependencies": {
- "@yandex-int/bar": "workspace:*",
- },
- }
-
- with pytest.raises(PackageJsonWorkspaceError) as e:
- pj.get_workspace_dep_paths()
-
- assert str(e.value) == "Expected relative path specifier for workspace dependency, but got 'workspace:*' for @yandex-int/bar in /packages/foo/package.json"
-
-
-def test_get_workspace_deps_ok():
- pj = PackageJson("/packages/foo/package.json")
- pj.data = {
- "dependencies": {
- "@yandex-int/bar": "workspace:../bar",
- },
- "devDependencies": {
- "@yandex-int/baz": "workspace:../baz",
- },
- }
-
- def load_mock(cls, path):
- p = PackageJson(path)
- p.data = {
- "name": "@yandex-int/{}".format(os.path.basename(os.path.dirname(path))),
- }
- return p
- PackageJson.load = classmethod(load_mock)
-
- ws_deps = pj.get_workspace_deps()
-
- assert len(ws_deps) == 2
- assert ws_deps[0].path == "/packages/bar/package.json"
- assert ws_deps[1].path == "/packages/baz/package.json"
-
-
-def test_get_workspace_deps_with_wrong_name():
- pj = PackageJson("/packages/foo/package.json")
- pj.data = {
- "dependencies": {
- "@yandex-int/bar": "workspace:../bar",
- },
- }
-
- def load_mock(cls, path):
- p = PackageJson(path)
- p.data = {
- "name": "@shouldbe/{}".format(os.path.basename(os.path.dirname(path))),
- }
- return p
- PackageJson.load = classmethod(load_mock)
-
- with pytest.raises(PackageJsonWorkspaceError) as e:
- pj.get_workspace_deps()
-
- assert str(e.value) == "Workspace dependency name mismatch, found '@yandex-int/bar' instead of '@shouldbe/bar' in /packages/foo/package.json"
-
-
-def test_get_workspace_map_ok():
- pj = PackageJson("/packages/foo/package.json")
- pj.data = {
- "dependencies": {
- "@yandex-int/bar": "workspace:../bar",
- },
- }
-
- def load_mock(cls, path):
- name = os.path.basename(os.path.dirname(path))
- p = PackageJson(path)
- p.data = {
- "name": "@yandex-int/{}".format(name),
- "dependencies": ({"@yandex-int/qux": "workspace:../qux"} if name == "bar" else {}),
- }
- return p
- PackageJson.load = classmethod(load_mock)
-
- ws_map = pj.get_workspace_map()
-
- assert len(ws_map) == 3
- assert ws_map["/packages/foo"][0].path == "/packages/foo/package.json"
- assert ws_map["/packages/foo"][1] == 0
- assert ws_map["/packages/bar"][0].path == "/packages/bar/package.json"
- assert ws_map["/packages/bar"][1] == 1
- assert ws_map["/packages/qux"][0].path == "/packages/qux/package.json"
- assert ws_map["/packages/qux"][1] == 2
+import os
+import pytest
+
+from build.plugins.lib.nots.package_manager.base.package_json import PackageJson, PackageJsonWorkspaceError
+
+
+def test_get_workspace_dep_paths_ok():
+ pj = PackageJson("/packages/foo/package.json")
+ pj.data = {
+ "dependencies": {
+ "@yandex-int/bar": "workspace:../bar",
+ },
+ "devDependencies": {
+ "@yandex-int/baz": "workspace:../baz",
+ },
+ }
+
+ ws_dep_paths = pj.get_workspace_dep_paths()
+
+ assert ws_dep_paths == [
+ ("@yandex-int/bar", "../bar"),
+ ("@yandex-int/baz", "../baz"),
+ ]
+
+
+def test_get_workspace_dep_paths_invalid_path():
+ pj = PackageJson("/packages/foo/package.json")
+ pj.data = {
+ "dependencies": {
+ "@yandex-int/bar": "workspace:*",
+ },
+ }
+
+ with pytest.raises(PackageJsonWorkspaceError) as e:
+ pj.get_workspace_dep_paths()
+
+ assert str(e.value) == "Expected relative path specifier for workspace dependency, but got 'workspace:*' for @yandex-int/bar in /packages/foo/package.json"
+
+
+def test_get_workspace_deps_ok():
+ pj = PackageJson("/packages/foo/package.json")
+ pj.data = {
+ "dependencies": {
+ "@yandex-int/bar": "workspace:../bar",
+ },
+ "devDependencies": {
+ "@yandex-int/baz": "workspace:../baz",
+ },
+ }
+
+ def load_mock(cls, path):
+ p = PackageJson(path)
+ p.data = {
+ "name": "@yandex-int/{}".format(os.path.basename(os.path.dirname(path))),
+ }
+ return p
+ PackageJson.load = classmethod(load_mock)
+
+ ws_deps = pj.get_workspace_deps()
+
+ assert len(ws_deps) == 2
+ assert ws_deps[0].path == "/packages/bar/package.json"
+ assert ws_deps[1].path == "/packages/baz/package.json"
+
+
+def test_get_workspace_deps_with_wrong_name():
+ pj = PackageJson("/packages/foo/package.json")
+ pj.data = {
+ "dependencies": {
+ "@yandex-int/bar": "workspace:../bar",
+ },
+ }
+
+ def load_mock(cls, path):
+ p = PackageJson(path)
+ p.data = {
+ "name": "@shouldbe/{}".format(os.path.basename(os.path.dirname(path))),
+ }
+ return p
+ PackageJson.load = classmethod(load_mock)
+
+ with pytest.raises(PackageJsonWorkspaceError) as e:
+ pj.get_workspace_deps()
+
+ assert str(e.value) == "Workspace dependency name mismatch, found '@yandex-int/bar' instead of '@shouldbe/bar' in /packages/foo/package.json"
+
+
+def test_get_workspace_map_ok():
+ pj = PackageJson("/packages/foo/package.json")
+ pj.data = {
+ "dependencies": {
+ "@yandex-int/bar": "workspace:../bar",
+ },
+ }
+
+ def load_mock(cls, path):
+ name = os.path.basename(os.path.dirname(path))
+ p = PackageJson(path)
+ p.data = {
+ "name": "@yandex-int/{}".format(name),
+ "dependencies": ({"@yandex-int/qux": "workspace:../qux"} if name == "bar" else {}),
+ }
+ return p
+ PackageJson.load = classmethod(load_mock)
+
+ ws_map = pj.get_workspace_map()
+
+ assert len(ws_map) == 3
+ assert ws_map["/packages/foo"][0].path == "/packages/foo/package.json"
+ assert ws_map["/packages/foo"][1] == 0
+ assert ws_map["/packages/bar"][0].path == "/packages/bar/package.json"
+ assert ws_map["/packages/bar"][1] == 1
+ assert ws_map["/packages/qux"][0].path == "/packages/qux/package.json"
+ assert ws_map["/packages/qux"][1] == 2
diff --git a/build/plugins/lib/nots/package_manager/base/tests/ya.make b/build/plugins/lib/nots/package_manager/base/tests/ya.make
index 1968fac42e..d1d9042d21 100644
--- a/build/plugins/lib/nots/package_manager/base/tests/ya.make
+++ b/build/plugins/lib/nots/package_manager/base/tests/ya.make
@@ -1,13 +1,13 @@
-PY23_TEST()
-
-OWNER(dankolesnikov)
-
-TEST_SRCS(
- package_json.py
-)
-
-PEERDIR(
- build/plugins/lib/nots/package_manager/base
-)
-
-END()
+PY23_TEST()
+
+OWNER(dankolesnikov)
+
+TEST_SRCS(
+ package_json.py
+)
+
+PEERDIR(
+ build/plugins/lib/nots/package_manager/base
+)
+
+END()
diff --git a/build/plugins/lib/nots/package_manager/base/ya.make b/build/plugins/lib/nots/package_manager/base/ya.make
index aa73cfbe25..4b00ef4d85 100644
--- a/build/plugins/lib/nots/package_manager/base/ya.make
+++ b/build/plugins/lib/nots/package_manager/base/ya.make
@@ -1,21 +1,21 @@
-PY23_LIBRARY()
-
-OWNER(dankolesnikov)
-
-PY_SRCS(
- __init__.py
- constants.py
- lockfile.py
- package_json.py
- package_manager.py
-)
-
-PEERDIR(
- contrib/python/six
-)
-
-END()
-
-RECURSE_FOR_TESTS(
- tests
-)
+PY23_LIBRARY()
+
+OWNER(dankolesnikov)
+
+PY_SRCS(
+ __init__.py
+ constants.py
+ lockfile.py
+ package_json.py
+ package_manager.py
+)
+
+PEERDIR(
+ contrib/python/six
+)
+
+END()
+
+RECURSE_FOR_TESTS(
+ tests
+)