diff options
author | dankolesnikov <dankolesnikov@yandex-team.ru> | 2022-02-10 16:51:07 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:51:07 +0300 |
commit | 98174ab8f0e6dbed8894c8226f62cac4bf36171d (patch) | |
tree | 00cab7b3b62da0fe104a2a99c2886064cc0b0d63 /build/plugins/lib/nots/package_manager/base | |
parent | 2e8363373770594fa3e83f1410d513cff82abb30 (diff) | |
download | ydb-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')
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 +) |