Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Install rust globally #331

Merged
merged 36 commits into from
Oct 2, 2023
Merged

Install rust globally #331

merged 36 commits into from
Oct 2, 2023

Conversation

popenta
Copy link
Contributor

@popenta popenta commented Sep 13, 2023

In this PR the mxpy deps install rust command has been changed.

From now on mxpy will install rust system-wide. The Rust module now also installs sc-meta, twiggy and wasm-opt.

The clang dependency has also been removed. You can not install it through mxpy anymore. You'll have to install it manually, if needed.

Solves issue #306, #310, #316 and #332.

@popenta popenta self-assigned this Sep 13, 2023
@popenta popenta marked this pull request as draft September 13, 2023 13:19
@popenta popenta marked this pull request as ready for review September 15, 2023 10:31
"RUSTUP_HOME": str(directory),
"CARGO_HOME": str(directory)
}
env: Dict[str, str] = {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think get_env_for_install() isn't used anymore? Also, _get_env_for_is_installed_in_sdk() - can both be removed?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively, we can do the same as for get_env(), and keep the old calls to get_env_for_install(), but simply replace the implementation with return os.environ?

@@ -269,12 +269,12 @@ def _do_install(self, tag: str) -> None:
toolchain = "nightly"

args = [str(installer_path), "--verbose", "--default-toolchain", toolchain, "--profile",
"minimal", "--target", "wasm32-unknown-unknown", "--no-modify-path", "-y"]
output = myprocess.run_process(args, env=self.get_env_for_install())
"minimal", "--target", "wasm32-unknown-unknown", "-y"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀


raise errors.BadDependencyResolution(self.key, resolution)
def get_env(self) -> Dict[str, str]:
return dict(os.environ)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct.

which_sc_meta = shutil.which("sc-meta")

if which_sc_meta is None:
raise errors.KnownError("'sc-meta' is not installed. Run 'cargo install multiversx-sc-meta' then try again.")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

pyproject.toml Outdated
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "multiversx-sdk-cli"
version = "8.2.0b1"
version = "8.1.1"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be 8.2.0.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bumped the version

andreibancioiu
andreibancioiu previously approved these changes Sep 22, 2023
@popenta popenta marked this pull request as draft September 22, 2023 10:20
@popenta popenta marked this pull request as ready for review September 25, 2023 12:36
@@ -5,13 +5,13 @@ name: build

on:
pull_request:
branches: [ main, feat/* ]
branches: [main, feat/*]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some unrelated whitespace changes in this file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll blame it on the formatter.

except Exception:
return False
if not is_rust_installed:
return is_rust_installed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can say return False (more explicit). Then, continue without else (less indentation).

if return_code:
assert False
else:
assert True
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be assert return_code == 0.

Also, maybe do an assert for existence of some files in ~/.cargo/...?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done



def test_deps_check_rust():
return_code = main(["deps", "check", "rust"])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This unit test can be merged into the first one, test_deps_install_rust.

Comment on lines 45 to 50
def test_deps_check_vmtools():
return_code = main(["deps", "check", "vmtools"])
if return_code:
assert False
else:
assert True
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unit test can be merged into the other one, which installs vmtools. Also, assert return_code == 0, here and above.

@@ -1,15 +0,0 @@
#!/usr/bin/env bash

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


return which_rustc is not None and which_cargo is not None

def install(self, tag: str, overwrite: bool) -> None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, here we completely override the function DependencyModule.install().

if not is_rust_installed:
return is_rust_installed
else:
self._recommend_default_rust_version()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, let's move this warning in the if-else that starts on line 269. This way, _is_installed_and_set_to_nightly is a bit more "pure" (does not take any decision, does not produce any effect as a consequence of its own internal checks).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, you can directly inline the implementation of _recommend_default_rust_version inside install - also because the warning message mentions the "overwrite" flag, and the overwrite check is performed there.

Can also stay as it is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved it inside the install() method.

@popenta popenta marked this pull request as draft September 26, 2023 13:41
@popenta popenta changed the base branch from main to feat/next September 27, 2023 09:08
@popenta popenta marked this pull request as ready for review September 28, 2023 09:03
"dependencies.wasm-opt.urlTemplate.linux": "https://github.com/WebAssembly/binaryen/releases/download/{TAG}/binaryen-{TAG}-x86_64-linux.tar.gz",
"dependencies.wasm-opt.urlTemplate.osx": "https://github.com/WebAssembly/binaryen/releases/download/{TAG}/binaryen-{TAG}-x86_64-macos.tar.gz",
"dependencies.wasm-opt.urlTemplate.windows": "https://github.com/WebAssembly/binaryen/releases/download/{TAG}/binaryen-{TAG}-x86_64-windows.tar.gz",
"dependencies.wasm-opt.tag": "0.112.0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


logger = logging.getLogger("install")


def install_module(key: str, tag: str = "", overwrite: bool = False):
def install_module(key: str, overwrite: bool = False):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, we are getting rid of --tag from mxpy deps. Tags are stored within the config file.

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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, shutil.which() returns None when application is missing.

self._do_install(tag)
self._install_sc_meta()
self._install_wasm_opt()
self._install_twiggy()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's rename _do_install() to _install_rust (for consistency). Since we anyway override the install from the base class.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed to _install_rust().


def _install_twiggy(self):
logger.info("Installing twiggy.")
default_tag = config.get_dependency_tag("twiggy")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In _install_wasm_opt, the variable name is tag, while here is default_tag. Rename (either way) to be consistent?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed. Renamed to tag.

@@ -26,6 +29,10 @@ def perform_build(self):
self.file_output = self.unit.with_suffix('.wasm')

try:
is_installed = are_clang_and_cpp_dependencies_installed()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should mention this in the PR description, as well.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's do a raise KnownError instead.

Perhaps we can have a check_clang_and_cpp_dependencies_installed in shared.py. And this would, actually, throw an error if dependencies are missing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed to check_clang_and_cpp_dependencies_installed and now raising a KnownError.

@@ -53,15 +54,16 @@ def prepare_build_wasm_args(self, args: List[str]):
self.get_output_folder()
])

def check_if_sc_meta_is_installed(self):
which_sc_meta = shutil.which("sc-meta")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about checking if the rust dependency is installed (thus, all parts of the rust "module")?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check_if_sc_meta_is_installed can actually be deleted. Before the code reaches this part, the ensure_dependencies_installed() is called. That calls the install() method of the Rust module. If not all the dependencies are installed, it should install them.

@@ -22,3 +28,29 @@ def _directory_contains_file(directory: Path, name_suffix: str) -> bool:
if str(file).lower().endswith(name_suffix.lower()):
return True
return False


def are_clang_and_cpp_dependencies_installed() -> bool:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrt. the other comment, can directly throw error here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Throwing error here.

run: |
python3 -m multiversx_sdk_cli.cli config set dependencies.vmtools.tag v1.4.60
cd ./multiversx_sdk_cli/tests
source ./test_cli_contracts.sh && testAll || return 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How come that we don't need to install clang / llvm, as well? No C smart contracts in our tests?

If so, we should add some tests for C contracts in the next PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we only use rust contracts in our tests

assert True if return_code == 0 else False

which_rustc = shutil.which("rustc")
if which_rustc:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these ifs make the test a bit more weak. We can drop the ifs to make it more restrictive.

@bogdan-rosianu bogdan-rosianu self-requested a review October 2, 2023 08:01
@popenta popenta merged commit 4cfcf50 into feat/next Oct 2, 2023
9 checks passed
@popenta popenta deleted the globally-install-rust branch October 2, 2023 08:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants