Skip to content

Commit

Permalink
Merge pull request #388 from multiversx/fix-deps-all
Browse files Browse the repository at this point in the history
Fix "deps check all" command
  • Loading branch information
popenta authored Jan 18, 2024
2 parents 98102bc + 1ece80a commit 604774c
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 129 deletions.
39 changes: 31 additions & 8 deletions multiversx_sdk_cli/cli_deps.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import logging
from typing import Any
from typing import Any, List, Tuple

from multiversx_sdk_cli import cli_shared, config, dependencies, errors
from multiversx_sdk_cli.dependencies.install import get_deps_dict
from multiversx_sdk_cli.dependencies.modules import DependencyModule

logger = logging.getLogger("cli.deps")

Expand Down Expand Up @@ -34,16 +35,38 @@ def install(args: Any):

def check(args: Any):
name: str = args.name
module = dependencies.get_module_by_key(name)
tag_to_check: str = config.get_dependency_tag(module.key)

if name == "all":
all_dependencies = dependencies.get_all_deps()
missing_dependencies: List[Tuple[str, str]] = []

for dependency in all_dependencies:
tag_to_check: str = config.get_dependency_tag(dependency.key)
is_installed = check_module_is_installed(dependency, tag_to_check)

if not is_installed:
missing_dependencies.append((dependency.key, tag_to_check))

if len(missing_dependencies):
raise errors.DependenciesMissing(missing_dependencies)
return
else:
module = dependencies.get_module_by_key(name)
tag_to_check: str = config.get_dependency_tag(module.key)

is_installed = check_module_is_installed(module, tag_to_check)
if is_installed and name != "rust":
logger.info(f"[{module.key} {tag_to_check}] is installed.")
return
elif not is_installed:
raise errors.DependencyMissing(module.key, tag_to_check)


def check_module_is_installed(module: DependencyModule, tag_to_check: str) -> bool:
resolution: str = config.get_dependency_resolution(module.key)
resolution = resolution if resolution else "HOST"

logger.info(f"Checking dependency: module = {module.key}, tag = {tag_to_check}, resolution = {resolution}")

installed = module.is_installed(tag_to_check)
if installed:
logger.info(f"[{name} {tag_to_check}] is installed.")
return

raise errors.DependencyMissing(name, tag_to_check)
return installed
43 changes: 3 additions & 40 deletions multiversx_sdk_cli/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
from pathlib import Path
from typing import Any, Dict, List

import semver

from multiversx_sdk_cli import errors, utils
from multiversx_sdk_cli.ux import show_warning

Expand Down Expand Up @@ -146,7 +144,6 @@ def _guard_valid_config_deletion(name: str):
def get_defaults() -> Dict[str, Any]:
return {
"dependencies.vmtools.tag": "v1.4.60",
"dependencies.mx_sdk_rs.tag": "latest",
"dependencies.vmtools.urlTemplate.linux": "https://github.com/multiversx/mx-chain-vm-go/archive/{TAG}.tar.gz",
"dependencies.vmtools.urlTemplate.osx": "https://github.com/multiversx/mx-chain-vm-go/archive/{TAG}.tar.gz",
"dependencies.vmtools.urlTemplate.windows": "https://github.com/multiversx/mx-chain-vm-go/archive/{TAG}.tar.gz",
Expand All @@ -156,9 +153,9 @@ def get_defaults() -> Dict[str, Any]:
"dependencies.golang.urlTemplate.linux": "https://golang.org/dl/{TAG}.linux-amd64.tar.gz",
"dependencies.golang.urlTemplate.osx": "https://golang.org/dl/{TAG}.darwin-amd64.tar.gz",
"dependencies.golang.urlTemplate.windows": "https://golang.org/dl/{TAG}.windows-amd64.zip",
"dependencies.twiggy.tag": "latest",
"dependencies.sc-meta.tag": "latest",
"dependencies.testwallets.tag": "latest",
"dependencies.twiggy.tag": "",
"dependencies.sc-meta.tag": "",
"dependencies.testwallets.tag": "v1.0.0",
"dependencies.testwallets.urlTemplate.linux": "https://github.com/multiversx/mx-sdk-testwallets/archive/{TAG}.tar.gz",
"dependencies.testwallets.urlTemplate.osx": "https://github.com/multiversx/mx-sdk-testwallets/archive/{TAG}.tar.gz",
"dependencies.testwallets.urlTemplate.windows": "https://github.com/multiversx/mx-sdk-testwallets/archive/{TAG}.tar.gz",
Expand Down Expand Up @@ -254,42 +251,8 @@ def determine_final_args(argv: List[str], config_args: Dict[str, Any]) -> List[s

def get_dependency_directory(key: str, tag: str) -> Path:
parent_directory = get_dependency_parent_directory(key)
if tag == 'latest':
if not parent_directory.is_dir():
return parent_directory / tag
tag = get_latest_semver_from_directory(parent_directory)

return parent_directory / tag


def get_dependency_parent_directory(key: str) -> Path:
return SDK_PATH / key


def get_latest_semver_from_directory(directory: Path) -> str:
subdirs = [subdir.name for subdir in directory.iterdir()]
try:
return get_latest_semver(subdirs)
except IndexError:
raise Exception(f'no versions found in {directory}')


def get_latest_semver(versions: List[str]) -> str:
semantic_versions = parse_strings_to_semver(versions)
latest_version = sorted(semantic_versions).pop()
return 'v' + str(latest_version)


def parse_strings_to_semver(version_strings: List[str]) -> List[semver.VersionInfo]:
versions = []
for version_string in version_strings:
try:
# Omit the 'v' prefix of the version string
version_string = version_string[1:]
version = semver.VersionInfo.parse(version_string)
except ValueError:
continue

versions.append(version)

return versions
7 changes: 5 additions & 2 deletions multiversx_sdk_cli/dependencies/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
from multiversx_sdk_cli.dependencies.install import install_module, get_module_directory, get_module_by_key, get_golang
from multiversx_sdk_cli.dependencies.install import (get_all_deps, get_golang,
get_module_by_key,
get_module_directory,
install_module)

__all__ = ["install_module", "get_module_directory", "get_module_by_key", "get_golang"]
__all__ = ["install_module", "get_module_directory", "get_module_by_key", "get_golang", "get_all_deps"]
8 changes: 4 additions & 4 deletions multiversx_sdk_cli/dependencies/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

def install_module(key: str, overwrite: bool = False):
if key == 'all':
modules = _get_all_deps()
modules = get_all_deps()
else:
modules = [get_module_by_key(key)]

Expand All @@ -29,7 +29,7 @@ def get_module_directory(key: str) -> Path:


def get_module_by_key(key: str) -> DependencyModule:
matches = [module for module in _get_all_deps() if module.key == key or key in module.aliases]
matches = [module for module in get_all_deps() if module.key == key or key in module.aliases]
if len(matches) != 1:
raise errors.UnknownDependency(key)

Expand All @@ -39,15 +39,15 @@ def get_module_by_key(key: str) -> DependencyModule:
def get_deps_dict() -> Dict[str, DependencyModule]:
deps: Dict[str, DependencyModule] = dict()

for module in _get_all_deps():
for module in get_all_deps():
deps[module.key] = module
for alias in module.aliases:
deps[alias] = module

return deps


def _get_all_deps() -> List[DependencyModule]:
def get_all_deps() -> List[DependencyModule]:
return [
Rust(key="rust"),
GolangModule(key="golang"),
Expand Down
54 changes: 29 additions & 25 deletions multiversx_sdk_cli/dependencies/modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ def install(self, overwrite: bool) -> None:
# We install the default tag
tag = config.get_dependency_tag(self.key)

if tag == 'latest':
tag = self.get_latest_release()

logger.info(f"install: key={self.key}, tag={tag}, overwrite={overwrite}")

if self._should_skip(tag, overwrite):
Expand Down Expand Up @@ -60,9 +57,6 @@ def is_installed(self, tag: str) -> bool:
def get_env(self) -> Dict[str, str]:
raise NotImplementedError()

def get_latest_release(self) -> str:
raise NotImplementedError()

def get_resolution(self) -> DependencyResolution:
return get_dependency_resolution(self.key)

Expand Down Expand Up @@ -135,14 +129,6 @@ def _get_download_url(self, tag: str) -> str:
url = url.replace("{TAG}", tag)
return url

def get_latest_release(self) -> str:
if self.repo_name is None or self.organisation is None:
raise ValueError(f'{self.key}: repo_name or organisation not specified')

org_repo = f'{self.organisation}/{self.repo_name}'
tag = utils.query_latest_release_tag(org_repo)
return tag

def _get_archive_path(self, tag: str) -> Path:
tools_folder = Path(workstation.get_tools_folder())
archive = tools_folder / f"{self.key}.{tag}.{self.archive_type}"
Expand Down Expand Up @@ -252,9 +238,6 @@ def get_env(self) -> Dict[str, str]:
def get_gopath(self) -> Path:
return self.get_parent_directory() / "GOPATH"

def get_latest_release(self) -> str:
raise errors.UnsupportedConfigurationValue("Golang tag must always be explicit, not latest")


class Rust(DependencyModule):
def is_installed(self, tag: str) -> bool:
Expand All @@ -270,7 +253,24 @@ def is_installed(self, tag: str) -> bool:
logger.info(f"which twiggy: {which_twiggy}")

dependencies = [which_rustc, which_cargo, which_sc_meta, which_wasm_opt, which_twiggy]
return all(dependency is not None for dependency in dependencies)
installed = all(dependency is not None for dependency in dependencies)

if installed:
actual_version_installed = self._get_actual_installed_version()

if tag in actual_version_installed:
logger.info(f"[{self.key} {tag}] is installed.")
elif "not found" in actual_version_installed:
show_warning("You have installed Rust without using `rustup`.")
else:
show_warning(f"The Rust version you have installed does not match the recommended version.\nInstalled [{actual_version_installed}], expected [{tag}].")

return installed

def _get_actual_installed_version(self) -> str:
args = ["rustup", "default"]
output = myprocess.run_process(args, dump_to_stdout=False)
return output.strip()

def install(self, overwrite: bool) -> None:
self._check_install_env(apply_correction=overwrite)
Expand Down Expand Up @@ -338,26 +338,26 @@ def _install_sc_meta(self):
tag = config.get_dependency_tag("sc-meta")
args = ["cargo", "install", "multiversx-sc-meta", "--locked"]

if tag != "latest":
if tag:
args.extend(["--version", tag])

myprocess.run_process(args)
myprocess.run_process(args, env=self.get_cargo_env())

def _install_wasm_opt(self):
logger.info("Installing wasm-opt. This may take a while.")
tag = config.get_dependency_tag("wasm-opt")
args = ["cargo", "install", "wasm-opt", "--version", tag]
myprocess.run_process(args)
myprocess.run_process(args, env=self.get_cargo_env())

def _install_twiggy(self):
logger.info("Installing twiggy.")
tag = config.get_dependency_tag("twiggy")
args = ["cargo", "install", "twiggy"]

if tag != "latest":
if tag:
args.extend(["--version", tag])

myprocess.run_process(args)
myprocess.run_process(args, env=self.get_cargo_env())

def _get_installer_url(self) -> str:
if workstation.is_windows():
Expand All @@ -383,8 +383,12 @@ def get_directory(self, tag: str) -> Path:
def get_env(self) -> Dict[str, str]:
return dict(os.environ)

def get_latest_release(self) -> str:
raise errors.UnsupportedConfigurationValue("Rust tag must either be explicit, empty or 'nightly'")
def get_cargo_env(self) -> Dict[str, str]:
env = self.get_env()
cargo = Path("~/.cargo/bin").expanduser()
path = env["PATH"]
env["PATH"] = f"{str(cargo)}:{path}"
return env


class TestWalletsModule(StandaloneModule):
Expand Down
16 changes: 13 additions & 3 deletions multiversx_sdk_cli/errors.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

from pathlib import Path
from typing import Any, Union
from typing import Any, List, Tuple, Union


class KnownError(Exception):
Expand Down Expand Up @@ -49,6 +49,16 @@ def __init__(self, name: str, tag: str):
super().__init__(f"Dependency missing: {name} {tag}")


class DependenciesMissing(KnownError):
def __init__(self, dependencies: List[Tuple[str, str]]):
message = "Dependencies missing: \n"

for dependency in dependencies:
message += f"{dependency[0]} {dependency[1]}\n"

super().__init__(message.rstrip("\n"))


class UnknownDependency(KnownError):
def __init__(self, name: str):
super().__init__(f"Unknown dependency: {name}")
Expand Down Expand Up @@ -80,8 +90,8 @@ def __init__(self, action_or_item: str, platform: str):


class BuildError(KnownError):
def __init__(self, message, inner=None):
super().__init__(f"Build error: {message}.", inner)
def __init__(self, message: str):
super().__init__(f"Build error: {message}.")


class UnknownArgumentFormat(KnownError):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging
from pathlib import Path

from multiversx_sdk_cli import config, dependencies, myprocess, utils
from multiversx_sdk_cli import dependencies, myprocess, utils
from multiversx_sdk_cli.errors import BadFile
from multiversx_sdk_cli.projects.report.features.report_option import \
ReportFeature
Expand Down
12 changes: 12 additions & 0 deletions multiversx_sdk_cli/tests/test_cli_deps.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,15 @@ def test_deps_install_testwallets():
def test_deps_check_testwallets():
return_code = main(["deps", "check", "testwallets"])
assert return_code == 0


@pytest.mark.skip_on_windows
def test_deps_install_all():
return_code = main(["deps", "install", "all"])
assert return_code == 0


@pytest.mark.skip_on_windows
def test_deps_check_all():
return_code = main(["deps", "check", "all"])
assert return_code == 0
25 changes: 0 additions & 25 deletions multiversx_sdk_cli/tests/test_modules.py

This file was deleted.

Loading

0 comments on commit 604774c

Please sign in to comment.