From c4a73d9a5bcb45f2fcc06737194865b7930693bb Mon Sep 17 00:00:00 2001 From: "Reid D. McKenzie" Date: Wed, 4 Jun 2025 11:31:27 -0600 Subject: [PATCH 1/2] fix(py_venv): Implement collision handling Fixes #575 --- Cargo.Bazel.lock | 84 ++++++++++++++++++- Cargo.lock | 14 ++++ py/tests/py_venv_conflict/BUILD.bazel | 41 +++++++++ py/tests/py_venv_conflict/a/BUILD.bazel | 13 +++ .../a/site-packages/conflict.py | 4 + .../a/site-packages/noconflict.py | 4 + py/tests/py_venv_conflict/b/BUILD.bazel | 13 +++ .../b/site-packages/conflict.py | 4 + .../b/site-packages/noconflict.py | 4 + py/tools/py/BUILD.bazel | 1 + py/tools/py/Cargo.toml | 1 + py/tools/py/src/lib.rs | 2 +- py/tools/py/src/pth.rs | 14 ++-- py/tools/py/src/venv.rs | 84 ++++++++++++++----- py/tools/venv_bin/BUILD.bazel | 11 --- py/tools/venv_bin/src/main.rs | 18 ++-- py/tools/venv_shim/BUILD.bazel | 21 ----- 17 files changed, 260 insertions(+), 73 deletions(-) create mode 100644 py/tests/py_venv_conflict/BUILD.bazel create mode 100644 py/tests/py_venv_conflict/a/BUILD.bazel create mode 100644 py/tests/py_venv_conflict/a/site-packages/conflict.py create mode 100644 py/tests/py_venv_conflict/a/site-packages/noconflict.py create mode 100644 py/tests/py_venv_conflict/b/BUILD.bazel create mode 100644 py/tests/py_venv_conflict/b/site-packages/conflict.py create mode 100644 py/tests/py_venv_conflict/b/site-packages/noconflict.py diff --git a/Cargo.Bazel.lock b/Cargo.Bazel.lock index 70a2d07c..fd5f005d 100644 --- a/Cargo.Bazel.lock +++ b/Cargo.Bazel.lock @@ -1,5 +1,5 @@ { - "checksum": "eb371dc49c5639c18e7f0415686de673ae7f83a972b6fd8823550485f5f63bea", + "checksum": "81528401c6d6fde79ca22def4e50d7ebc47f7f182a83a106d38e9e1279da39a5", "crates": { "addr2line 0.24.2": { "name": "addr2line", @@ -10864,6 +10864,10 @@ "id": "relative-path 1.9.3", "target": "relative_path" }, + { + "id": "sha256 1.6.0", + "target": "sha256" + }, { "id": "tempfile 3.13.0", "target": "tempfile" @@ -16836,6 +16840,83 @@ ], "license_file": "LICENSE-APACHE" }, + "sha256 1.6.0": { + "name": "sha256", + "version": "1.6.0", + "package_url": "https://github.com/baoyachi/sha256-rs", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/sha256/1.6.0/download", + "sha256": "f880fc8562bdeb709793f00eb42a2ad0e672c4f883bbe59122b926eca935c8f6" + } + }, + "targets": [ + { + "Library": { + "crate_name": "sha256", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "sha256", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "async", + "default", + "tokio" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "bytes 1.8.0", + "target": "bytes" + }, + { + "id": "hex 0.4.3", + "target": "hex" + }, + { + "id": "sha2 0.10.8", + "target": "sha2" + }, + { + "id": "tokio 1.41.0", + "target": "tokio" + } + ], + "selects": {} + }, + "edition": "2018", + "proc_macro_deps": { + "common": [ + { + "id": "async-trait 0.1.83", + "target": "async_trait" + } + ], + "selects": {} + }, + "version": "1.6.0" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, "shell-escape 0.1.5": { "name": "shell-escape", "version": "0.1.5", @@ -27627,6 +27708,7 @@ "miette 7.2.0", "pathdiff 0.2.3", "relative-path 1.9.3", + "sha256 1.6.0", "tempfile 3.13.0", "thiserror 1.0.65", "uv-cache 0.0.1", diff --git a/Cargo.lock b/Cargo.lock index 9804dbe5..d6b7e183 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1622,6 +1622,7 @@ dependencies = [ "miette", "pathdiff", "relative-path", + "sha256", "tempfile", "thiserror", "uv-cache", @@ -2286,6 +2287,19 @@ dependencies = [ "digest", ] +[[package]] +name = "sha256" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f880fc8562bdeb709793f00eb42a2ad0e672c4f883bbe59122b926eca935c8f6" +dependencies = [ + "async-trait", + "bytes", + "hex", + "sha2", + "tokio", +] + [[package]] name = "shell-escape" version = "0.1.5" diff --git a/py/tests/py_venv_conflict/BUILD.bazel b/py/tests/py_venv_conflict/BUILD.bazel new file mode 100644 index 00000000..d7d5d037 --- /dev/null +++ b/py/tests/py_venv_conflict/BUILD.bazel @@ -0,0 +1,41 @@ +load("@bazel_skylib//rules:build_test.bzl", "build_test") +load("//py/unstable:defs.bzl", "py_venv") + +py_venv( + name = "test_venv_error", + deps = [ + "//py/tests/py_venv_conflict/a", + "//py/tests/py_venv_conflict/b", + ], + package_collisions="error", + tags = [ + "manual", + "known-to-fail", + ] +) + +py_venv( + name = "test_venv_warning", + deps = [ + "//py/tests/py_venv_conflict/a", + "//py/tests/py_venv_conflict/b", + ], + package_collisions="warning", +) + +py_venv( + name = "test_venv_ignore", + deps = [ + "//py/tests/py_venv_conflict/a", + "//py/tests/py_venv_conflict/b", + ], + package_collisions="ignore", +) + +build_test( + name = "py_venv_conflict", + targets = [ + ":test_venv_warning", + ":test_venv_ignore", + ] +) diff --git a/py/tests/py_venv_conflict/a/BUILD.bazel b/py/tests/py_venv_conflict/a/BUILD.bazel new file mode 100644 index 00000000..292b5ba7 --- /dev/null +++ b/py/tests/py_venv_conflict/a/BUILD.bazel @@ -0,0 +1,13 @@ +load("//py:defs.bzl", "py_library") + +py_library( + name = "a", + srcs = [ + "site-packages/conflict.py", + "site-packages/noconflict.py", + ], + imports = [ + "site-packages", + ], + visibility = ["//py/tests/py_venv_conflict:__pkg__"], +) diff --git a/py/tests/py_venv_conflict/a/site-packages/conflict.py b/py/tests/py_venv_conflict/a/site-packages/conflict.py new file mode 100644 index 00000000..9becc6ae --- /dev/null +++ b/py/tests/py_venv_conflict/a/site-packages/conflict.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python3 + +def conflict(): + return "a" diff --git a/py/tests/py_venv_conflict/a/site-packages/noconflict.py b/py/tests/py_venv_conflict/a/site-packages/noconflict.py new file mode 100644 index 00000000..1255c28e --- /dev/null +++ b/py/tests/py_venv_conflict/a/site-packages/noconflict.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python3 + +def noconflict(): + return 1 diff --git a/py/tests/py_venv_conflict/b/BUILD.bazel b/py/tests/py_venv_conflict/b/BUILD.bazel new file mode 100644 index 00000000..72984e01 --- /dev/null +++ b/py/tests/py_venv_conflict/b/BUILD.bazel @@ -0,0 +1,13 @@ +load("//py:defs.bzl", "py_library") + +py_library( + name = "b", + srcs = [ + "site-packages/conflict.py", + "site-packages/noconflict.py", + ], + imports = [ + "site-packages", + ], + visibility = ["//py/tests/py_venv_conflict:__pkg__"], +) diff --git a/py/tests/py_venv_conflict/b/site-packages/conflict.py b/py/tests/py_venv_conflict/b/site-packages/conflict.py new file mode 100644 index 00000000..f81ec052 --- /dev/null +++ b/py/tests/py_venv_conflict/b/site-packages/conflict.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python3 + +def conflict(): + return "b" diff --git a/py/tests/py_venv_conflict/b/site-packages/noconflict.py b/py/tests/py_venv_conflict/b/site-packages/noconflict.py new file mode 100644 index 00000000..1255c28e --- /dev/null +++ b/py/tests/py_venv_conflict/b/site-packages/noconflict.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python3 + +def noconflict(): + return 1 diff --git a/py/tools/py/BUILD.bazel b/py/tools/py/BUILD.bazel index adaefd99..597e692f 100644 --- a/py/tools/py/BUILD.bazel +++ b/py/tools/py/BUILD.bazel @@ -32,5 +32,6 @@ rust_library( "@crate_index//:uv-python", "@crate_index//:uv-virtualenv", "@crate_index//:walkdir", + "@crate_index//:sha256", ], ) diff --git a/py/tools/py/Cargo.toml b/py/tools/py/Cargo.toml index 3a2857cf..7a7b3135 100644 --- a/py/tools/py/Cargo.toml +++ b/py/tools/py/Cargo.toml @@ -19,6 +19,7 @@ itertools = { workspace = true } miette = { workspace = true } pathdiff = "0.2.3" relative-path = "1.9.3" +sha256 = "1.6.0" tempfile = { workspace = true } thiserror = { workspace = true } uv-cache = { workspace = true } diff --git a/py/tools/py/src/lib.rs b/py/tools/py/src/lib.rs index 7f05945f..c6466018 100644 --- a/py/tools/py/src/lib.rs +++ b/py/tools/py/src/lib.rs @@ -5,4 +5,4 @@ pub mod venv; pub use unpack::unpack_wheel; pub use venv::create_venv; -pub use pth::{PthFile, SymlinkCollisionResolutionStrategy}; +pub use pth::{CollisionResolutionStrategy, PthFile}; diff --git a/py/tools/py/src/pth.rs b/py/tools/py/src/pth.rs index 6a313e27..ba00a3fd 100644 --- a/py/tools/py/src/pth.rs +++ b/py/tools/py/src/pth.rs @@ -31,8 +31,8 @@ from .runfiles import * /// Strategy that will be used when creating the virtual env symlink and /// a collision is found. -#[derive(Default, Debug)] -pub enum SymlinkCollisionResolutionStrategy { +#[derive(Default, Debug, PartialEq)] +pub enum CollisionResolutionStrategy { /// Collisions cause a hard error. #[default] Error, @@ -49,7 +49,7 @@ pub struct SitePackageOptions { pub dest: PathBuf, /// Collision strategy determining the action taken when sylinks in the venv collide. - pub collision_strategy: SymlinkCollisionResolutionStrategy, + pub collision_strategy: CollisionResolutionStrategy, } pub struct PthFile { @@ -121,7 +121,7 @@ pub fn create_symlinks( dir: &Path, root_dir: &Path, dst_dir: &Path, - collision_strategy: &SymlinkCollisionResolutionStrategy, + collision_strategy: &CollisionResolutionStrategy, ) -> miette::Result<()> { // Create this directory at the destination. let tgt_dir = dst_dir.join(dir.strip_prefix(root_dir).unwrap()); @@ -176,7 +176,7 @@ fn create_symlink( e: &DirEntry, root_dir: &Path, dst_dir: &Path, - collision_strategy: &SymlinkCollisionResolutionStrategy, + collision_strategy: &CollisionResolutionStrategy, ) -> miette::Result<()> { let tgt = e.path(); let link = dst_dir.join(tgt.strip_prefix(root_dir).unwrap()); @@ -232,7 +232,7 @@ fn create_symlink( } match collision_strategy { - SymlinkCollisionResolutionStrategy::LastWins(warn) => { + CollisionResolutionStrategy::LastWins(warn) => { fs::remove_file(&link) .into_diagnostic() .wrap_err( @@ -248,7 +248,7 @@ fn create_symlink( eprintln!("{:?}", conflicts); } } - SymlinkCollisionResolutionStrategy::Error => { + CollisionResolutionStrategy::Error => { // If the link already exists, then there is going to be a conflict. let conflicts = conflict_report(&link, &tgt, Severity::Error); return Err(conflicts); diff --git a/py/tools/py/src/venv.rs b/py/tools/py/src/venv.rs index d34e1df0..4368e9e7 100644 --- a/py/tools/py/src/venv.rs +++ b/py/tools/py/src/venv.rs @@ -1,14 +1,15 @@ use crate::{ - pth::{SitePackageOptions, SymlinkCollisionResolutionStrategy}, + pth::{CollisionResolutionStrategy, SitePackageOptions}, PthFile, }; use miette::{miette, Context, IntoDiagnostic}; use pathdiff::diff_paths; +use sha256::try_digest; use std::{ env::current_dir, fs::{self, File}, io::{BufRead, BufReader, BufWriter, Write}, - os::unix::fs::PermissionsExt, + os::unix::fs::{MetadataExt, PermissionsExt}, path::{Path, PathBuf}, }; use std::{ffi::OsStr, os::unix::fs as unix_fs}; @@ -18,7 +19,7 @@ pub fn create_venv( python: &Path, location: &Path, pth_file: Option, - collision_strategy: SymlinkCollisionResolutionStrategy, + collision_strategy: CollisionResolutionStrategy, venv_name: &str, ) -> miette::Result<()> { if location.exists() { @@ -133,7 +134,7 @@ fn link(original: &PathBuf, link: &PathBuf) -> miette::Result<()> { .wrap_err("Unable to create link target dir")?; #[cfg(feature = "debug")] - println!( + eprintln!( "L {} -> {}", link_abs.to_str().unwrap(), original_relative.to_str().unwrap(), @@ -152,7 +153,7 @@ fn _copy(original: &PathBuf, link: &PathBuf) -> miette::Result<()> { .wrap_err("Unable to create copy target dir")?; #[cfg(feature = "debug")] - println!( + eprintln!( "C {} -> {}", link_abs.to_str().unwrap(), original_abs.to_str().unwrap(), @@ -429,15 +430,22 @@ pub fn populate_venv_with_copies( venv: Virtualenv, pth_file: PthFile, bin_dir: PathBuf, - collision_strategy: SymlinkCollisionResolutionStrategy, + collision_strategy: CollisionResolutionStrategy, ) -> miette::Result<()> { // Assumes that `create_empty_venv` has already been called to build out the virtualenv. let dest = &venv.site_dir; // Get $PWD, which is the build working directory. let action_src_dir = current_dir().into_diagnostic()?; + let main_module = action_src_dir.file_name().unwrap(); let action_bin_dir = action_src_dir.join(bin_dir); + #[cfg(feature = "debug")] + eprintln!("action_src_dir: {}", &action_src_dir.to_str().unwrap()); + + #[cfg(feature = "debug")] + eprintln!("action_bin_dir: {}", &action_bin_dir.to_str().unwrap()); + let source_pth = File::open(pth_file.src.as_path()) .into_diagnostic() .wrap_err("Unable to open source .pth file")?; @@ -457,6 +465,9 @@ pub fn populate_venv_with_copies( .into_diagnostic()?; for line in BufReader::new(source_pth).lines().map_while(Result::ok) { + #[cfg(feature = "debug")] + eprintln!("Got pth line {}", &line); + let line = line.trim().to_string(); // Entries should be of the form `/`, but may not have // a trailing `/` in the case of the default workspace root import that @@ -472,14 +483,18 @@ pub fn populate_venv_with_copies( }; #[cfg(feature = "debug")] - println!("Got pth entry @{}//{}", workspace, entry_path); + eprintln!("Got pth entry @{}//{}", workspace, entry_path); let mut entry = PathBuf::from(entry_path); // FIXME: Handle other wheel install dirs like bin? if entry.file_name() == Some(OsStr::new("site-packages")) { + #[cfg(feature = "debug")] + eprintln!("Entry is site-packages..."); + // If the entry is external then we have to adjust the path - if workspace != "_main" { + // FIXME: This isn't quite right outside of bzlmod + if workspace != main_module { entry = PathBuf::from("external") .join(PathBuf::from(workspace)) .join(entry) @@ -490,6 +505,9 @@ pub fn populate_venv_with_copies( let src_dir = prefix.join(&entry); if src_dir.exists() { create_tree(&src_dir, &venv.site_dir, &collision_strategy)?; + } else { + #[cfg(feature = "debug")] + eprintln!("Unable to find srcs under {}", src_dir.to_str().unwrap()); } } @@ -536,23 +554,28 @@ pub fn populate_venv_with_copies( /// to the configured import roots. At runtime this will cause the booting /// interpreter to traverse up out of the venv and insert other workspaces' /// site-packages trees (and potentially other import roots) onto the path. -/// -/// + pub fn populate_venv_with_pth( venv: Virtualenv, pth_file: PthFile, bin_dir: PathBuf, - collision_strategy: SymlinkCollisionResolutionStrategy, + collision_strategy: CollisionResolutionStrategy, ) -> miette::Result<()> { // Assumes that `create_empty_venv` has already been called to build out the virtualenv. Ok(()) } +/// TODO (arrdem 2025-06-04): +/// This needs to be refactored into a multi-pass solution for error handling +/// Pass 1: Collect sources, group by destination key +/// Pass 2: Report collision error(s) all at once +/// Pass 3: Create links + pub fn create_tree( original: &Path, link_dir: &Path, - collision_strategy: &SymlinkCollisionResolutionStrategy, + collision_strategy: &CollisionResolutionStrategy, ) -> miette::Result<()> { for entry in WalkDir::new(original) { if let Ok(entry) = entry { @@ -564,24 +587,43 @@ pub fn create_tree( if original_entry.canonicalize().unwrap().is_dir() { continue; } - // Handle collisions, probably conflicting empty __init__.py files from Bazel - else if link_entry.exists() { - return Err(miette!( - "Collision resolution not yet implemented! Saw {} twice", - relative_entry.to_str().unwrap() - )); - } // Specifically avoid linking in a /__init__.py file else if relative_entry == PathBuf::from("__init__.py") { continue; } + // Handle collisions, probably conflicting empty __init__.py files from Bazel + else if link_entry.exists() { + // If the _content_ of the files is the same then we have a + // false collision, otherwise we have to do collision handling. + + let new_hash = try_digest(&original_entry).into_diagnostic()?; + let existing_hash = try_digest(&link_entry).into_diagnostic()?; + + if new_hash != existing_hash { + match *collision_strategy { + CollisionResolutionStrategy::Error => { + return Err(miette!( + "Collision detected on venv element {}!", + relative_entry.to_str().unwrap() + )) + } + CollisionResolutionStrategy::LastWins(true) => { + eprintln!("Warning: Collision detected on venv element {}!\n Last one wins is configured, continuing", + relative_entry.to_str().unwrap() + ) + } + _ => {} + } + } + } + // In the case of copying bin entries, we need to patch them. Yay. - else if link_dir.file_name() == Some(OsStr::new("bin")) { + if link_dir.file_name() == Some(OsStr::new("bin")) { let mut content = fs::read_to_string(original_entry).into_diagnostic()?; if content.starts_with("#!/dev/null") { content.replace_range(..0, &RELOCATABLE_SHEBANG); } - fs::write(link_entry, content).into_diagnostic()?; + fs::write(&link_entry, content).into_diagnostic()?; } // Normal case of needing to link a file :smile: else { diff --git a/py/tools/venv_bin/BUILD.bazel b/py/tools/venv_bin/BUILD.bazel index 7f3ee20a..7ff4b2dd 100644 --- a/py/tools/venv_bin/BUILD.bazel +++ b/py/tools/venv_bin/BUILD.bazel @@ -21,14 +21,3 @@ alias( "//visibility:public", ], ) - -platform_transition_filegroup( - name = "local_venv_bin", - srcs = [ - ":venv", - ], - target_platform = "@bazel_tools//tools:host_platform", - visibility = [ - "//visibility:public", - ], -) diff --git a/py/tools/venv_bin/src/main.rs b/py/tools/venv_bin/src/main.rs index cd170fe5..6de28137 100644 --- a/py/tools/venv_bin/src/main.rs +++ b/py/tools/venv_bin/src/main.rs @@ -6,23 +6,19 @@ use miette::Context; use py; #[derive(clap::ValueEnum, Clone, Debug, Default)] -enum SymlinkCollisionStrategy { +enum CollisionStrategy { #[default] Error, Warning, Ignore, } -impl Into for SymlinkCollisionStrategy { - fn into(self) -> py::SymlinkCollisionResolutionStrategy { +impl Into for CollisionStrategy { + fn into(self) -> py::CollisionResolutionStrategy { match self { - SymlinkCollisionStrategy::Error => py::SymlinkCollisionResolutionStrategy::Error, - SymlinkCollisionStrategy::Warning => { - py::SymlinkCollisionResolutionStrategy::LastWins(true) - } - SymlinkCollisionStrategy::Ignore => { - py::SymlinkCollisionResolutionStrategy::LastWins(false) - } + CollisionStrategy::Error => py::CollisionResolutionStrategy::Error, + CollisionStrategy::Warning => py::CollisionResolutionStrategy::LastWins(true), + CollisionStrategy::Ignore => py::CollisionResolutionStrategy::LastWins(false), } } } @@ -68,7 +64,7 @@ struct VenvArgs { /// encountered when creating the venv. /// If none is given, an error will be thrown. #[arg(long)] - collision_strategy: Option, + collision_strategy: Option, /// Name to apply to the venv in the terminal when using /// activate scripts. diff --git a/py/tools/venv_shim/BUILD.bazel b/py/tools/venv_shim/BUILD.bazel index f092baea..f9ff1835 100644 --- a/py/tools/venv_shim/BUILD.bazel +++ b/py/tools/venv_shim/BUILD.bazel @@ -1,31 +1,10 @@ load("//tools/release:defs.bzl", "rust_binary") -config_setting( - name = "debug_build", - values = { - "compilation_mode": "dbg", - }, -) - rust_binary( name = "shim", srcs = [ "src/main.rs", ], - crate_features = select({ - ":debug_build": [ - "debug", - ], - "//conditions:default": [], - }), - rustc_flags = select({ - ":debug_build": [], - "//conditions:default": [ - "-Copt-level=3", - "-Clto", - "-Cstrip=symbols", - ], - }), deps = [ "@crate_index//:miette", ], From 222f9f5bd69a63b96811193d5e0c95b809475f0b Mon Sep 17 00:00:00 2001 From: "Reid D. McKenzie" Date: Wed, 4 Jun 2025 11:35:46 -0600 Subject: [PATCH 2/2] Lint. --- py/tests/py_venv_conflict/BUILD.bazel | 16 ++++++++-------- py/tools/py/BUILD.bazel | 2 +- py/tools/venv_bin/BUILD.bazel | 1 - tools/release/BUILD.bazel | 7 +++++++ tools/release/defs.bzl | 14 ++++++++++++++ 5 files changed, 30 insertions(+), 10 deletions(-) diff --git a/py/tests/py_venv_conflict/BUILD.bazel b/py/tests/py_venv_conflict/BUILD.bazel index d7d5d037..3d40242d 100644 --- a/py/tests/py_venv_conflict/BUILD.bazel +++ b/py/tests/py_venv_conflict/BUILD.bazel @@ -3,33 +3,33 @@ load("//py/unstable:defs.bzl", "py_venv") py_venv( name = "test_venv_error", + package_collisions = "error", + tags = [ + "known-to-fail", + "manual", + ], deps = [ "//py/tests/py_venv_conflict/a", "//py/tests/py_venv_conflict/b", ], - package_collisions="error", - tags = [ - "manual", - "known-to-fail", - ] ) py_venv( name = "test_venv_warning", + package_collisions = "warning", deps = [ "//py/tests/py_venv_conflict/a", "//py/tests/py_venv_conflict/b", ], - package_collisions="warning", ) py_venv( name = "test_venv_ignore", + package_collisions = "ignore", deps = [ "//py/tests/py_venv_conflict/a", "//py/tests/py_venv_conflict/b", ], - package_collisions="ignore", ) build_test( @@ -37,5 +37,5 @@ build_test( targets = [ ":test_venv_warning", ":test_venv_ignore", - ] + ], ) diff --git a/py/tools/py/BUILD.bazel b/py/tools/py/BUILD.bazel index 597e692f..c9049f96 100644 --- a/py/tools/py/BUILD.bazel +++ b/py/tools/py/BUILD.bazel @@ -22,6 +22,7 @@ rust_library( "@crate_index//:itertools", "@crate_index//:miette", "@crate_index//:pathdiff", + "@crate_index//:sha256", "@crate_index//:tempfile", "@crate_index//:thiserror", "@crate_index//:uv-cache", @@ -32,6 +33,5 @@ rust_library( "@crate_index//:uv-python", "@crate_index//:uv-virtualenv", "@crate_index//:walkdir", - "@crate_index//:sha256", ], ) diff --git a/py/tools/venv_bin/BUILD.bazel b/py/tools/venv_bin/BUILD.bazel index 7ff4b2dd..2ac8a8ef 100644 --- a/py/tools/venv_bin/BUILD.bazel +++ b/py/tools/venv_bin/BUILD.bazel @@ -1,4 +1,3 @@ -load("@aspect_bazel_lib//lib:transitions.bzl", "platform_transition_filegroup") load("//tools/release:defs.bzl", "rust_binary") # TODO(#497): transition to --nocollect_code_coverage to avoid rules_rust trying to instrument this binary diff --git a/tools/release/BUILD.bazel b/tools/release/BUILD.bazel index 5a444999..5f041dd3 100644 --- a/tools/release/BUILD.bazel +++ b/tools/release/BUILD.bazel @@ -2,6 +2,13 @@ # Since this is a load from private despite it being our private... sigh load("//py/private/toolchain:tools.bzl", "TOOL_CFGS") +config_setting( + name = "debug_build", + values = { + "compilation_mode": "dbg", + }, +) + [ platform( name = "{}_{}".format(os, cpu), diff --git a/tools/release/defs.bzl b/tools/release/defs.bzl index bf011019..7ab69ba2 100644 --- a/tools/release/defs.bzl +++ b/tools/release/defs.bzl @@ -41,6 +41,20 @@ def rust_binary(name, visibility = [], **kwargs): platform = release_platform, target_compatible_with = target_compatible_with, tags = ["manual"], + crate_features = select({ + str(Label(":debug_build")): [ + "debug", + ], + "//conditions:default": [], + }), + rustc_flags = select({ + str(Label(":debug_build")): [], + "//conditions:default": [ + "-Copt-level=3", + "-Clto", + "-Cstrip=symbols", + ], + }), **kwargs )