From bd153a698af0f8bf54d013b460f5a683cc1366ee Mon Sep 17 00:00:00 2001 From: Terseus Date: Sat, 15 Jun 2024 20:53:16 +0200 Subject: [PATCH 1/2] allow rust hooks to specify crate features Now the rust hooks can use the parameter `additional_dependencies` to receive build-time features for the crate. The features must start with the string "--feature=" following the name of the feature; e.g. "--feature=full". Fixes #3230 --- pre_commit/languages/rust.py | 14 ++++++++++++++ tests/languages/rust_test.py | 17 ++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/pre_commit/languages/rust.py b/pre_commit/languages/rust.py index 5f9db8fb..13eff528 100644 --- a/pre_commit/languages/rust.py +++ b/pre_commit/languages/rust.py @@ -22,6 +22,7 @@ from pre_commit.util import make_executable from pre_commit.util import win_exe ENVIRONMENT_DIR = 'rustenv' +FEATURE_PREFIX = '--feature=' health_check = lang_base.basic_health_check run_hook = lang_base.basic_run_hook @@ -73,6 +74,8 @@ def _add_dependencies( ) -> None: crates = [] for dep in additional_dependencies: + if dep.startswith(FEATURE_PREFIX): + continue name, _, spec = dep.partition(':') crate = f'{name}@{spec or "*"}' crates.append(crate) @@ -130,6 +133,12 @@ def install_environment( cli_deps = { dep for dep in additional_dependencies if dep.startswith('cli:') } + # Features starts with "--feature=" + features = { + dep.replace(FEATURE_PREFIX, '') + for dep in additional_dependencies + if dep.startswith('--') + } lib_deps = set(additional_dependencies) - cli_deps packages_to_install: set[tuple[str, ...]] = {('--path', '.')} @@ -153,8 +162,13 @@ def install_environment( if len(lib_deps) > 0: _add_dependencies(prefix, lib_deps) + features_params = [] + if features: + features_params = ['--features', *features] + for args in packages_to_install: cmd_output_b( 'cargo', 'install', '--bins', '--root', envdir, *args, + *features_params, cwd=prefix.prefix_dir, ) diff --git a/tests/languages/rust_test.py b/tests/languages/rust_test.py index 52e35613..becbf605 100644 --- a/tests/languages/rust_test.py +++ b/tests/languages/rust_test.py @@ -44,13 +44,19 @@ def _make_hello_world(tmp_path): src_dir.joinpath('main.rs').write_text( 'fn main() {\n' ' println!("Hello, world!");\n' + ' if cfg!(feature = "foo") {\n' + ' println!("With feature foo");\n' + ' }\n' '}\n', ) tmp_path.joinpath('Cargo.toml').write_text( '[package]\n' 'name = "hello_world"\n' 'version = "0.1.0"\n' - 'edition = "2021"\n', + 'edition = "2021"\n' + '\n' + '[features]\n' + 'foo = []\n', ) @@ -113,3 +119,12 @@ def test_run_lib_additional_dependencies(tmp_path): assert bin_dir.is_dir() assert not bin_dir.joinpath('shellharden').exists() assert not bin_dir.joinpath('shellharden.exe').exists() + + +def test_run_features_additional_dependencies(tmp_path): + _make_hello_world(tmp_path) + + deps = ('shellharden:4.2.0', 'git-version') + features = ('--feature=foo',) + ret = run_language(tmp_path, rust, 'hello_world', deps=deps + features) + assert ret == (0, b'Hello, world!\nWith feature foo\n') From 558793bbc233f3f5a408fb1161e1941a14b616c3 Mon Sep 17 00:00:00 2001 From: Terseus Date: Thu, 11 Jul 2024 21:12:48 +0200 Subject: [PATCH 2/2] allow rust hooks to specify arbitrary cargo install parameters We've replaced the previous "--feature=" format with a single parameter "--" which marks the start of the "cargo install" arguments, so now we can use "-- --features foo", "-- --locked", etc. Fixes #3162 --- pre_commit/languages/rust.py | 41 ++++++++++++++++++------------------ tests/languages/rust_test.py | 4 ++-- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/pre_commit/languages/rust.py b/pre_commit/languages/rust.py index 13eff528..39623ca5 100644 --- a/pre_commit/languages/rust.py +++ b/pre_commit/languages/rust.py @@ -22,7 +22,6 @@ from pre_commit.util import make_executable from pre_commit.util import win_exe ENVIRONMENT_DIR = 'rustenv' -FEATURE_PREFIX = '--feature=' health_check = lang_base.basic_health_check run_hook = lang_base.basic_run_hook @@ -74,8 +73,6 @@ def _add_dependencies( ) -> None: crates = [] for dep in additional_dependencies: - if dep.startswith(FEATURE_PREFIX): - continue name, _, spec = dep.partition(':') crate = f'{name}@{spec or "*"}' crates.append(crate) @@ -130,19 +127,25 @@ def install_environment( # # Because of this, we allow specifying "cli" dependencies by prefixing # with 'cli:'. - cli_deps = { - dep for dep in additional_dependencies if dep.startswith('cli:') - } - # Features starts with "--feature=" - features = { - dep.replace(FEATURE_PREFIX, '') - for dep in additional_dependencies - if dep.startswith('--') - } - lib_deps = set(additional_dependencies) - cli_deps + # + # We can pass arbitrary arguments to the `cargo install` invocation by + # adding '--' before the arguments. + cli_deps = [] + lib_deps = [] + cargo_params = [] + for index, dep in enumerate(additional_dependencies): + if dep == '--': + cargo_params = list(additional_dependencies[index + 1:]) + break + if dep.startswith('cli:'): + cli_deps.append(dep) + continue + lib_deps.append(dep) + cli_deps_set = set(cli_deps) + lib_deps_set = set(lib_deps) packages_to_install: set[tuple[str, ...]] = {('--path', '.')} - for cli_dep in cli_deps: + for cli_dep in cli_deps_set: cli_dep = cli_dep.removeprefix('cli:') package, _, crate_version = cli_dep.partition(':') if crate_version != '': @@ -159,16 +162,12 @@ def install_environment( tmpdir = ctx.enter_context(tempfile.TemporaryDirectory()) ctx.enter_context(envcontext((('RUSTUP_HOME', tmpdir),))) - if len(lib_deps) > 0: - _add_dependencies(prefix, lib_deps) - - features_params = [] - if features: - features_params = ['--features', *features] + if len(lib_deps_set) > 0: + _add_dependencies(prefix, lib_deps_set) for args in packages_to_install: cmd_output_b( 'cargo', 'install', '--bins', '--root', envdir, *args, - *features_params, + *cargo_params, cwd=prefix.prefix_dir, ) diff --git a/tests/languages/rust_test.py b/tests/languages/rust_test.py index becbf605..9e04f231 100644 --- a/tests/languages/rust_test.py +++ b/tests/languages/rust_test.py @@ -125,6 +125,6 @@ def test_run_features_additional_dependencies(tmp_path): _make_hello_world(tmp_path) deps = ('shellharden:4.2.0', 'git-version') - features = ('--feature=foo',) - ret = run_language(tmp_path, rust, 'hello_world', deps=deps + features) + cargo_params = ('--', '--features', 'foo') + ret = run_language(tmp_path, rust, 'hello_world', deps=deps + cargo_params) assert ret == (0, b'Hello, world!\nWith feature foo\n')