From 28f8c55b31d3b0055dc6fd68ef8349f578bba25d Mon Sep 17 00:00:00 2001 From: Wolf Vollprecht Date: Tue, 28 Oct 2025 12:56:18 +0100 Subject: [PATCH 1/9] fix diffy patch application for pure renames --- Cargo.lock | 2 +- rust-toolchain | 2 +- src/source/patch.rs | 81 +++++++++++++++++-- .../patches/test_create_delete.patch | 16 ++++ .../patches/test_pure_rename.patch | 15 ++++ 5 files changed, 108 insertions(+), 8 deletions(-) create mode 100644 test-data/patch_application/patches/test_create_delete.patch create mode 100644 test-data/patch_application/patches/test_pure_rename.patch diff --git a/Cargo.lock b/Cargo.lock index ab2e48590..645ef3e99 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1651,7 +1651,7 @@ checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" [[package]] name = "diffy" version = "0.4.2" -source = "git+https://github.com/prefix-dev/diffy.git?branch=master#f916e25c31a8d9e7483116c9e8aa6a36e20f947a" +source = "git+https://github.com/prefix-dev/diffy.git?branch=master#0ee342981a9af49ec24821e0259c06746854f480" dependencies = [ "nu-ansi-term", "strsim", diff --git a/rust-toolchain b/rust-toolchain index b7844a6ff..636ea711a 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -1.86.0 +1.89.0 diff --git a/src/source/patch.rs b/src/source/patch.rs index fd521ed16..51d3750ef 100644 --- a/src/source/patch.rs +++ b/src/source/patch.rs @@ -446,18 +446,16 @@ mod tests { let patch = patch_from_bytes(&patch_file_content).expect("Failed to parse patch file"); let patched_paths = parse_patch(&patch); - assert_eq!(patched_paths.len(), 2); - assert!(patched_paths.contains(&PathBuf::from("a/text.md"))); - assert!(patched_paths.contains(&PathBuf::from("b/text.md"))); + assert_eq!(patched_paths.len(), 1); + assert!(patched_paths.contains(&PathBuf::from("text.md"))); let patch_file_content = fs_err::read(patches_dir.join("0001-increase-minimum-cmake-version.patch")) .expect("Could not read file contents"); let patch = patch_from_bytes(&patch_file_content).expect("Failed to parse patch file"); let patched_paths = parse_patch(&patch); - assert_eq!(patched_paths.len(), 2); - assert!(patched_paths.contains(&PathBuf::from("a/CMakeLists.txt"))); - assert!(patched_paths.contains(&PathBuf::from("b/CMakeLists.txt"))); + assert_eq!(patched_paths.len(), 1); + assert!(patched_paths.contains(&PathBuf::from("CMakeLists.txt"))); } fn setup_patch_test_dir() -> (TempDir, PathBuf) { @@ -677,6 +675,77 @@ mod tests { assert!(text_md.contains("Oh, wow, I was patched! Thank you soooo much!")); } + #[test] + fn test_apply_pure_rename_patch() { + let (tempdir, _) = setup_patch_test_dir(); + + // Apply patch with pure renames (100% similarity, no content changes) + apply_patches( + &[PathBuf::from("test_pure_rename.patch")], + &tempdir.path().join("workdir"), + &tempdir.path().join("patches"), + apply_patch_custom, + ) + .expect("Pure rename patch should apply successfully"); + + // Check that the __init__.py file was deleted + let init_file = tempdir.path().join("workdir/tinygrad/frontend/__init__.py"); + assert!( + !init_file.exists(), + "frontend/__init__.py should be deleted" + ); + + // Check that onnx.py was renamed from frontend to nn + let old_onnx = tempdir.path().join("workdir/tinygrad/frontend/onnx.py"); + let new_onnx = tempdir.path().join("workdir/tinygrad/nn/onnx.py"); + assert!(!old_onnx.exists(), "frontend/onnx.py should not exist"); + assert!(new_onnx.exists(), "nn/onnx.py should exist"); + let onnx_content = fs_err::read_to_string(&new_onnx).unwrap(); + assert_eq!( + onnx_content, "# onnx code\n", + "onnx.py content should be preserved" + ); + + // Check that torch.py was renamed from frontend to nn + let old_torch = tempdir.path().join("workdir/tinygrad/frontend/torch.py"); + let new_torch = tempdir.path().join("workdir/tinygrad/nn/torch.py"); + assert!(!old_torch.exists(), "frontend/torch.py should not exist"); + assert!(new_torch.exists(), "nn/torch.py should exist"); + let torch_content = fs_err::read_to_string(&new_torch).unwrap(); + assert_eq!( + torch_content, "# torch code\n", + "torch.py content should be preserved" + ); + } + + #[test] + fn test_apply_create_delete_patch() { + let (tempdir, _) = setup_patch_test_dir(); + + // Create the file that will be deleted + let to_delete = tempdir.path().join("workdir/to_be_deleted.txt"); + fs_err::write(&to_delete, "This file will be deleted\nby the patch\n").unwrap(); + + // Apply patch with creation and deletion + apply_patches( + &[PathBuf::from("test_create_delete.patch")], + &tempdir.path().join("workdir"), + &tempdir.path().join("patches"), + apply_patch_custom, + ) + .expect("Create/delete patch should apply successfully"); + + // Check that the file was deleted + assert!(!to_delete.exists(), "to_be_deleted.txt should be deleted"); + + // Check that the new file was created with correct content + let created_file = tempdir.path().join("workdir/newly_created.txt"); + assert!(created_file.exists(), "newly_created.txt should exist"); + let content = fs_err::read_to_string(&created_file).unwrap(); + assert!(content.contains("This is a newly created file")); + assert!(content.contains("via patch application")); + } + #[test] fn test_apply_0001_increase_minimum_cmake_version_patch() { let (tempdir, _) = setup_patch_test_dir(); diff --git a/test-data/patch_application/patches/test_create_delete.patch b/test-data/patch_application/patches/test_create_delete.patch new file mode 100644 index 000000000..8b8ae7a06 --- /dev/null +++ b/test-data/patch_application/patches/test_create_delete.patch @@ -0,0 +1,16 @@ +diff --git a/to_be_deleted.txt b/to_be_deleted.txt +deleted file mode 100644 +index 1234567..0000000 +--- a/to_be_deleted.txt ++++ /dev/null +@@ -1,2 +0,0 @@ +-This file will be deleted +-by the patch +diff --git a/newly_created.txt b/newly_created.txt +new file mode 100644 +index 0000000..abcdefg +--- /dev/null ++++ b/newly_created.txt +@@ -0,0 +1,2 @@ ++This is a newly created file ++via patch application diff --git a/test-data/patch_application/patches/test_pure_rename.patch b/test-data/patch_application/patches/test_pure_rename.patch new file mode 100644 index 000000000..9075bc35e --- /dev/null +++ b/test-data/patch_application/patches/test_pure_rename.patch @@ -0,0 +1,15 @@ +diff --git a/tinygrad/frontend/__init__.py b/tinygrad/frontend/__init__.py +deleted file mode 100644 +index 9d2492e..0000000 +--- a/tinygrad/frontend/__init__.py ++++ /dev/null +@@ -1 +0,0 @@ +-# frontend init +diff --git a/tinygrad/frontend/onnx.py b/tinygrad/nn/onnx.py +similarity index 100% +rename from tinygrad/frontend/onnx.py +rename to tinygrad/nn/onnx.py +diff --git a/tinygrad/frontend/torch.py b/tinygrad/nn/torch.py +similarity index 100% +rename from tinygrad/frontend/torch.py +rename to tinygrad/nn/torch.py From 1d5b766f76aa3eebcf70425d1de9551f49d82eca Mon Sep 17 00:00:00 2001 From: Wolf Vollprecht Date: Tue, 28 Oct 2025 13:37:12 +0100 Subject: [PATCH 2/9] fix new clippy lints --- .github/workflows/rust.yml | 4 +- Cargo.toml | 7 +- .../src/cpan.rs | 32 ++-- .../src/cran.rs | 8 +- .../src/luarocks/mod.rs | 8 +- .../src/pypi.rs | 33 ++-- deny.toml | 28 +-- pixi.lock | 170 +++++++++--------- pixi.toml | 4 +- py-rattler-build/pixi.toml | 2 +- src/build.rs | 16 +- src/cache.rs | 12 +- src/env_vars.rs | 11 +- src/lib.rs | 42 ++--- src/macos/link.rs | 10 +- src/main.rs | 8 +- src/package_test/run_test.rs | 32 ++-- src/packaging.rs | 14 +- src/packaging/file_finder.rs | 6 +- src/packaging/file_mapper.rs | 99 +++++----- src/packaging/metadata.rs | 14 +- src/post_process/checks.rs | 32 ++-- src/post_process/menuinst.rs | 13 +- src/post_process/python.rs | 14 +- src/rebuild.rs | 16 +- src/recipe/custom_yaml.rs | 17 +- src/recipe/custom_yaml/rendered.rs | 11 +- src/recipe/error.rs | 96 +++++----- src/recipe/jinja.rs | 12 +- src/recipe/parser/output.rs | 2 + src/recipe/parser/script.rs | 8 +- src/recipe/parser/skip.rs | 2 +- src/render/resolved_dependencies.rs | 97 +++++----- src/script/interpreter/bash.rs | 3 +- src/script/interpreter/cmd_exe.rs | 11 +- src/script/interpreter/nushell.rs | 3 +- src/script/mod.rs | 16 +- src/source/create_patch.rs | 8 +- src/source/mod.rs | 8 +- src/source/patch.rs | 46 ++--- src/source/url_source.rs | 42 ++--- src/tool_configuration.rs | 8 +- src/types/mod.rs | 2 +- src/unix/permission_guard.rs | 8 +- src/used_variables.rs | 1 + src/variant_config.rs | 32 ++-- src/variant_render.rs | 25 ++- src/windows/link.rs | 10 +- 48 files changed, 553 insertions(+), 550 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 1bfae921b..04692915a 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -35,7 +35,7 @@ jobs: submodules: recursive - uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master with: - toolchain: "1.86.0" + toolchain: "1.89.0" components: clippy,rustfmt - uses: Swatinem/rust-cache@f13886b937689c021905a6b90929199931d60db1 # v2 # https://github.com/actions/runner-images/issues/5459#issuecomment-1532856844 @@ -142,7 +142,7 @@ jobs: - name: Install Rust toolchain uses: actions-rust-lang/setup-rust-toolchain@1780873c7b576612439a134613cc4cc74ce5538c # v1 with: - toolchain: "1.86.0" + toolchain: "1.89.0" target: ${{ matrix.target }} - name: Install musl-gcc diff --git a/Cargo.toml b/Cargo.toml index 8b3b8c76c..3af37eae4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,7 +48,7 @@ readme = "README.md" description = "A fast CLI tool to build conda packages on Windows, macOS and Linux" documentation = "https://prefix-dev.github.io/rattler-build" default-run = "rattler-build" -rust-version = "1.86.0" +rust-version = "1.89.0" [features] default = ['rustls-tls', 'recipe-generation', 's3'] @@ -75,10 +75,7 @@ tui = [ 'throbber-widgets-tui', 'tui-input', ] -s3 = [ - 'rattler_networking/s3', - 'rattler_upload/s3', -] +s3 = ['rattler_networking/s3', 'rattler_upload/s3'] recipe-generation = ["rattler_build_recipe_generator"] # This feature needs to add a dependency on # clap-markdown = { git = "https://github.com/ruben-arts/clap-markdown", branch = "main" } diff --git a/crates/rattler_build_recipe_generator/src/cpan.rs b/crates/rattler_build_recipe_generator/src/cpan.rs index 076bbed3f..502132b19 100644 --- a/crates/rattler_build_recipe_generator/src/cpan.rs +++ b/crates/rattler_build_recipe_generator/src/cpan.rs @@ -145,13 +145,10 @@ fn get_core_modules_from_perl() -> Result, std::io::Error> { .output()?; if !output.status.success() { - return Err(std::io::Error::new( - std::io::ErrorKind::Other, - format!( - "Perl command failed: {}", - String::from_utf8_lossy(&output.stderr) - ), - )); + return Err(std::io::Error::other(format!( + "Perl command failed: {}", + String::from_utf8_lossy(&output.stderr) + ))); } let modules_text = String::from_utf8_lossy(&output.stdout); @@ -562,21 +559,20 @@ make install"# } // Add bugtracker URL if available - if let Some(bugtracker) = &resources.bugtracker { - if recipe.about.repository.is_none() { - recipe.about.repository = bugtracker.web.clone(); - } + if let Some(bugtracker) = &resources.bugtracker + && recipe.about.repository.is_none() + { + recipe.about.repository = bugtracker.web.clone(); } } // Add author information - if let Some(metadata) = &metadata.release.metadata { - if let Some(authors) = &metadata.author { - if !authors.is_empty() { - let authors_str = authors.join(", "); - recipe.about.description = Some(format!("By {}", authors_str)); - } - } + if let Some(metadata) = &metadata.release.metadata + && let Some(authors) = &metadata.author + && !authors.is_empty() + { + let authors_str = authors.join(", "); + recipe.about.description = Some(format!("By {}", authors_str)); } // Add additional metadata from modules if not already set diff --git a/crates/rattler_build_recipe_generator/src/cran.rs b/crates/rattler_build_recipe_generator/src/cran.rs index 11539dbf0..eaded7fe9 100644 --- a/crates/rattler_build_recipe_generator/src/cran.rs +++ b/crates/rattler_build_recipe_generator/src/cran.rs @@ -337,10 +337,10 @@ async fn build_cran_recipe_and_deps( recipe.about.description = Some(package_info.Description.clone()); (recipe.about.license, recipe.about.license_file) = map_license(&package_info.License); recipe.about.repository = Some(package_info._upstream.clone()); - if let Some(pkgdocs) = &package_info._pkgdocs { - if url::Url::parse(pkgdocs).is_ok() { - recipe.about.documentation = Some(pkgdocs.clone()); - } + if let Some(pkgdocs) = &package_info._pkgdocs + && url::Url::parse(pkgdocs).is_ok() + { + recipe.about.documentation = Some(pkgdocs.clone()); } recipe.tests.push(Test::Script(ScriptTest { diff --git a/crates/rattler_build_recipe_generator/src/luarocks/mod.rs b/crates/rattler_build_recipe_generator/src/luarocks/mod.rs index 835a69044..145b352b6 100644 --- a/crates/rattler_build_recipe_generator/src/luarocks/mod.rs +++ b/crates/rattler_build_recipe_generator/src/luarocks/mod.rs @@ -445,10 +445,10 @@ fn rockspec_to_recipe(rockspec: &LuarocksRockspec) -> miette::Result { fn generate_require_test(spec: &LuarocksRockspec) -> Test { // Try to get module names from the build.modules field if present let mut modules = Vec::new(); - if let Some(build) = &spec.build { - if let Some(mods) = &build.modules { - modules.extend(mods.keys().cloned()); - } + if let Some(build) = &spec.build + && let Some(mods) = &build.modules + { + modules.extend(mods.keys().cloned()); } // If no modules found, fall back to the package name if modules.is_empty() { diff --git a/crates/rattler_build_recipe_generator/src/pypi.rs b/crates/rattler_build_recipe_generator/src/pypi.rs index aecff31bb..0b09dc54f 100644 --- a/crates/rattler_build_recipe_generator/src/pypi.rs +++ b/crates/rattler_build_recipe_generator/src/pypi.rs @@ -163,19 +163,16 @@ async fn extract_build_requirements( // Try different build system specs return Ok(match toml.get("build-system") { - Some(build) => { - let reqs = build - .get("requires") - .and_then(|r| r.as_array()) - .map(|arr| { - arr.iter() - .filter_map(|v| v.as_str()) - .map(|s| s.to_string()) - .collect() - }) - .unwrap_or_default(); - reqs - } + Some(build) => build + .get("requires") + .and_then(|r| r.as_array()) + .map(|arr| { + arr.iter() + .filter_map(|v| v.as_str()) + .map(|s| s.to_string()) + .collect() + }) + .unwrap_or_default(), None => Vec::new(), }); } @@ -317,11 +314,11 @@ async fn map_requirement( return req.to_string(); } // Get base package name without markers/version - if let Some(base_name) = req.split([' ', ';']).next() { - if let Some(mapped_name) = mapping.get(base_name) { - // Replace the package name but keep version and markers - return req.replacen(base_name, mapped_name, 1).to_string(); - } + if let Some(base_name) = req.split([' ', ';']).next() + && let Some(mapped_name) = mapping.get(base_name) + { + // Replace the package name but keep version and markers + return req.replacen(base_name, mapped_name, 1).to_string(); } req.to_string() } diff --git a/deny.toml b/deny.toml index b3ef3b00e..93b2729f3 100644 --- a/deny.toml +++ b/deny.toml @@ -1,19 +1,19 @@ [licenses] allow = [ - "0BSD", - "Apache-2.0 WITH LLVM-exception", - "Apache-2.0", - "BSD-2-Clause", - "BSD-3-Clause", - "BSL-1.0", - "bzip2-1.0.6", - "CC0-1.0", - "CDLA-Permissive-2.0", - "ISC", - "MIT", - "MPL-2.0", - "Unicode-3.0", - "Zlib", + "0BSD", + "Apache-2.0 WITH LLVM-exception", + "Apache-2.0", + "BSD-2-Clause", + "BSD-3-Clause", + "BSL-1.0", + "bzip2-1.0.6", + "CC0-1.0", + "CDLA-Permissive-2.0", + "ISC", + "MIT", + "MPL-2.0", + "Unicode-3.0", + "Zlib", ] confidence-threshold = 0.8 private = { ignore = true } diff --git a/pixi.lock b/pixi.lock index 15fe36df3..13a531d81 100644 --- a/pixi.lock +++ b/pixi.lock @@ -103,9 +103,9 @@ environments: - conda: https://prefix.dev/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda - conda: https://prefix.dev/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/linux-64/rhash-1.4.6-hb9d3cd8_1.conda - - conda: https://prefix.dev/conda-forge/linux-64/rust-1.86.0-h1a8d7c4_0.conda - - conda: https://prefix.dev/conda-forge/noarch/rust-src-1.86.0-unix_0.conda - - conda: https://prefix.dev/conda-forge/noarch/rust-std-x86_64-unknown-linux-gnu-1.86.0-h2c6d0dc_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/rust-1.89.0-h53717f1_0.conda + - conda: https://prefix.dev/conda-forge/noarch/rust-src-1.89.0-unix_0.conda + - conda: https://prefix.dev/conda-forge/noarch/rust-std-x86_64-unknown-linux-gnu-1.89.0-h2c6d0dc_0.conda - conda: https://prefix.dev/conda-forge/noarch/s3transfer-0.13.1-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/schema-0.7.7-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda @@ -219,9 +219,9 @@ environments: - conda: https://prefix.dev/conda-forge/osx-64/readline-8.2-h7cca4af_2.conda - conda: https://prefix.dev/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/osx-64/rhash-1.4.6-h6e16a3a_1.conda - - conda: https://prefix.dev/conda-forge/osx-64/rust-1.86.0-h34a2095_0.conda - - conda: https://prefix.dev/conda-forge/noarch/rust-src-1.86.0-unix_0.conda - - conda: https://prefix.dev/conda-forge/noarch/rust-std-x86_64-apple-darwin-1.86.0-h38e4360_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/rust-1.89.0-h34a2095_0.conda + - conda: https://prefix.dev/conda-forge/noarch/rust-src-1.89.0-unix_0.conda + - conda: https://prefix.dev/conda-forge/noarch/rust-std-x86_64-apple-darwin-1.89.0-h38e4360_0.conda - conda: https://prefix.dev/conda-forge/noarch/s3transfer-0.13.1-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/schema-0.7.7-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/osx-64/sigtool-0.1.3-h88f4db0_0.tar.bz2 @@ -339,9 +339,9 @@ environments: - conda: https://prefix.dev/conda-forge/osx-arm64/readline-8.2-h1d1bf99_2.conda - conda: https://prefix.dev/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/rhash-1.4.6-h5505292_1.conda - - conda: https://prefix.dev/conda-forge/osx-arm64/rust-1.86.0-h4ff7c5d_0.conda - - conda: https://prefix.dev/conda-forge/noarch/rust-src-1.86.0-unix_0.conda - - conda: https://prefix.dev/conda-forge/noarch/rust-std-aarch64-apple-darwin-1.86.0-hf6ec828_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/rust-1.89.0-h4ff7c5d_0.conda + - conda: https://prefix.dev/conda-forge/noarch/rust-src-1.89.0-unix_0.conda + - conda: https://prefix.dev/conda-forge/noarch/rust-std-aarch64-apple-darwin-1.89.0-hf6ec828_0.conda - conda: https://prefix.dev/conda-forge/noarch/s3transfer-0.13.1-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/schema-0.7.7-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/sigtool-0.1.3-h44b9a77_0.tar.bz2 @@ -433,9 +433,9 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/python_abi-3.12-8_cp312.conda - conda: https://prefix.dev/conda-forge/win-64/pyyaml-6.0.2-py312h31fea79_2.conda - conda: https://prefix.dev/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda - - conda: https://prefix.dev/conda-forge/win-64/rust-1.86.0-hf8d6059_0.conda - - conda: https://prefix.dev/conda-forge/noarch/rust-src-1.86.0-win_0.conda - - conda: https://prefix.dev/conda-forge/noarch/rust-std-x86_64-pc-windows-msvc-1.86.0-h17fc481_0.conda + - conda: https://prefix.dev/conda-forge/win-64/rust-1.89.0-hf8d6059_0.conda + - conda: https://prefix.dev/conda-forge/noarch/rust-src-1.89.0-win_0.conda + - conda: https://prefix.dev/conda-forge/noarch/rust-std-x86_64-pc-windows-msvc-1.89.0-h17fc481_0.conda - conda: https://prefix.dev/conda-forge/noarch/s3transfer-0.13.1-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/schema-0.7.7-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda @@ -1021,9 +1021,9 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/linux-64/rhash-1.4.6-hb9d3cd8_1.conda - conda: https://prefix.dev/conda-forge/linux-64/ruff-0.4.10-py312h5715c7c_0.conda - - conda: https://prefix.dev/conda-forge/linux-64/rust-1.86.0-h1a8d7c4_0.conda - - conda: https://prefix.dev/conda-forge/noarch/rust-src-1.86.0-unix_0.conda - - conda: https://prefix.dev/conda-forge/noarch/rust-std-x86_64-unknown-linux-gnu-1.86.0-h2c6d0dc_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/rust-1.89.0-h53717f1_0.conda + - conda: https://prefix.dev/conda-forge/noarch/rust-src-1.89.0-unix_0.conda + - conda: https://prefix.dev/conda-forge/noarch/rust-std-x86_64-unknown-linux-gnu-1.89.0-h2c6d0dc_0.conda - conda: https://prefix.dev/conda-forge/noarch/s3transfer-0.13.1-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/linux-64/shellcheck-0.10.0-ha770c72_0.conda - conda: https://prefix.dev/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda @@ -1137,9 +1137,9 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/osx-64/rhash-1.4.6-h6e16a3a_1.conda - conda: https://prefix.dev/conda-forge/osx-64/ruff-0.4.10-py312h8b25c6c_0.conda - - conda: https://prefix.dev/conda-forge/osx-64/rust-1.86.0-h34a2095_0.conda - - conda: https://prefix.dev/conda-forge/noarch/rust-src-1.86.0-unix_0.conda - - conda: https://prefix.dev/conda-forge/noarch/rust-std-x86_64-apple-darwin-1.86.0-h38e4360_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/rust-1.89.0-h34a2095_0.conda + - conda: https://prefix.dev/conda-forge/noarch/rust-src-1.89.0-unix_0.conda + - conda: https://prefix.dev/conda-forge/noarch/rust-std-x86_64-apple-darwin-1.89.0-h38e4360_0.conda - conda: https://prefix.dev/conda-forge/noarch/s3transfer-0.13.1-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/osx-64/shellcheck-0.10.0-h7dd6a17_0.conda - conda: https://prefix.dev/conda-forge/osx-64/sigtool-0.1.3-h88f4db0_0.tar.bz2 @@ -1257,9 +1257,9 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/rhash-1.4.6-h5505292_1.conda - conda: https://prefix.dev/conda-forge/osx-arm64/ruff-0.4.10-py312h3402d49_0.conda - - conda: https://prefix.dev/conda-forge/osx-arm64/rust-1.86.0-h4ff7c5d_0.conda - - conda: https://prefix.dev/conda-forge/noarch/rust-src-1.86.0-unix_0.conda - - conda: https://prefix.dev/conda-forge/noarch/rust-std-aarch64-apple-darwin-1.86.0-hf6ec828_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/rust-1.89.0-h4ff7c5d_0.conda + - conda: https://prefix.dev/conda-forge/noarch/rust-src-1.89.0-unix_0.conda + - conda: https://prefix.dev/conda-forge/noarch/rust-std-aarch64-apple-darwin-1.89.0-hf6ec828_0.conda - conda: https://prefix.dev/conda-forge/noarch/s3transfer-0.13.1-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/shellcheck-0.10.0-hecfb573_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/sigtool-0.1.3-h44b9a77_0.tar.bz2 @@ -1351,9 +1351,9 @@ environments: - conda: https://prefix.dev/conda-forge/win-64/pyyaml-6.0.2-py312h31fea79_2.conda - conda: https://prefix.dev/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/win-64/ruff-0.4.10-py312h7a6832a_0.conda - - conda: https://prefix.dev/conda-forge/win-64/rust-1.86.0-hf8d6059_0.conda - - conda: https://prefix.dev/conda-forge/noarch/rust-src-1.86.0-win_0.conda - - conda: https://prefix.dev/conda-forge/noarch/rust-std-x86_64-pc-windows-msvc-1.86.0-h17fc481_0.conda + - conda: https://prefix.dev/conda-forge/win-64/rust-1.89.0-hf8d6059_0.conda + - conda: https://prefix.dev/conda-forge/noarch/rust-src-1.89.0-win_0.conda + - conda: https://prefix.dev/conda-forge/noarch/rust-std-x86_64-pc-windows-msvc-1.89.0-h17fc481_0.conda - conda: https://prefix.dev/conda-forge/noarch/s3transfer-0.13.1-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/win-64/shellcheck-0.10.0-h57928b3_0.conda - conda: https://prefix.dev/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda @@ -6455,113 +6455,113 @@ packages: license_family: MIT size: 6273796 timestamp: 1718951278593 -- conda: https://prefix.dev/conda-forge/linux-64/rust-1.86.0-h1a8d7c4_0.conda - sha256: fa3b6757df927a24c3006bc5bffbac5b0c9a54b9755c08847f8a832ec1b79300 - md5: 98eab8148e1447e79f9e03492d04e291 +- conda: https://prefix.dev/conda-forge/linux-64/rust-1.89.0-h53717f1_0.conda + sha256: bc68b5225d80de6da78350213655c8d7cd43519803c2f6dc7c6e9ab9fe810f36 + md5: 719a6e2a172b21c2c61446221e9192c1 depends: - __glibc >=2.17,<3.0.a0 - gcc_impl_linux-64 - - libgcc >=13 + - libgcc >=14 - libzlib >=1.3.1,<2.0a0 - - rust-std-x86_64-unknown-linux-gnu 1.86.0 h2c6d0dc_0 + - rust-std-x86_64-unknown-linux-gnu 1.89.0 h2c6d0dc_0 - sysroot_linux-64 >=2.17 license: MIT license_family: MIT - size: 218638108 - timestamp: 1743697775334 -- conda: https://prefix.dev/conda-forge/osx-64/rust-1.86.0-h34a2095_0.conda - sha256: 69b7d7eb9f6b3aaf84a09f5e07f16aa9bcbf52aec8364f572d96668d2a1c6bf1 - md5: a9991a60df5a93e7c87ff17e5c306499 + size: 225780210 + timestamp: 1754660161071 +- conda: https://prefix.dev/conda-forge/osx-64/rust-1.89.0-h34a2095_0.conda + sha256: 6e5c0632859a94701fadaf22e7b9589baf008afb8022b199726286a6465fa2bf + md5: 79d89d8541a705cf58bf8399dd83d1d1 depends: - - rust-std-x86_64-apple-darwin 1.86.0 h38e4360_0 + - rust-std-x86_64-apple-darwin 1.89.0 h38e4360_0 license: MIT license_family: MIT - size: 232864569 - timestamp: 1743697077267 -- conda: https://prefix.dev/conda-forge/osx-arm64/rust-1.86.0-h4ff7c5d_0.conda - sha256: 84eed612b108a2ac5db2eb76c5f2cd596fec8e21a3cb1eb478080d74a39fab13 - md5: 05c1a701cdb550b46e0526c2453b7337 + size: 240526373 + timestamp: 1754659861134 +- conda: https://prefix.dev/conda-forge/osx-arm64/rust-1.89.0-h4ff7c5d_0.conda + sha256: cea00732dc2a51defda5ce5a0fcb334da2613930f5f2f9079ee5fcc22eae7486 + md5: 796e88939e7360dfb9e26ed78b9fa6ee depends: - - rust-std-aarch64-apple-darwin 1.86.0 hf6ec828_0 + - rust-std-aarch64-apple-darwin 1.89.0 hf6ec828_0 license: MIT license_family: MIT - size: 224722205 - timestamp: 1743697077568 -- conda: https://prefix.dev/conda-forge/win-64/rust-1.86.0-hf8d6059_0.conda - sha256: acb32e2aebf79a07b7ccd0d4c8eed49ea0c45e62489b3cd8c609314ee12a5a7d - md5: 6b65d15fe703b59d2f1c7e2693db5bbf + size: 230462759 + timestamp: 1754659707516 +- conda: https://prefix.dev/conda-forge/win-64/rust-1.89.0-hf8d6059_0.conda + sha256: 248b294e5c5193b23441b9c6c25d240d0b218e1e2f6187ade522dceeb7063c42 + md5: dac15b5704c5d93f1ffc38e20f08dea4 depends: - - rust-std-x86_64-pc-windows-msvc 1.86.0 h17fc481_0 + - rust-std-x86_64-pc-windows-msvc 1.89.0 h17fc481_0 license: MIT license_family: MIT - size: 228028589 - timestamp: 1743699306537 -- conda: https://prefix.dev/conda-forge/noarch/rust-src-1.86.0-unix_0.conda - sha256: 73cc7c49ef8088fc5186f6aee48166ca71c7dc527997a592f5b76a815f4bda88 - md5: 9c2af1ca0493191466b300691edc2145 + size: 250040157 + timestamp: 1754662524987 +- conda: https://prefix.dev/conda-forge/noarch/rust-src-1.89.0-unix_0.conda + sha256: 4299a72c9430fe6b8d73d52fb97bbcf241336966531b6281b0d1190c0bcdd7c1 + md5: 7581f796c775dca1f095e421c5d2565f depends: - __unix constrains: - - rust >=1.86.0,<1.86.1.0a0 + - rust >=1.89.0,<1.89.1.0a0 license: MIT license_family: MIT - size: 3568928 - timestamp: 1743696829470 -- conda: https://prefix.dev/conda-forge/noarch/rust-src-1.86.0-win_0.conda - sha256: be0ecdbfb3970ef94c080ce055b7424b343f46269f30e18007a830e040ced28d - md5: 749e6db8ccde79a44b60894e8b89ff46 + size: 4073060 + timestamp: 1754659534828 +- conda: https://prefix.dev/conda-forge/noarch/rust-src-1.89.0-win_0.conda + sha256: 1732c4ca3358f8885b6ab73fdd0d2cd210089189b99638840c3950a765823c62 + md5: 0fab763526316f056bf7adae8e1d2c5e depends: - __win constrains: - - rust >=1.86.0,<1.86.1.0a0 + - rust >=1.89.0,<1.89.1.0a0 license: MIT license_family: MIT - size: 3527152 - timestamp: 1743697981200 -- conda: https://prefix.dev/conda-forge/noarch/rust-std-aarch64-apple-darwin-1.86.0-hf6ec828_0.conda - sha256: 13ece700416fd30628019ee589b8de01a66991c2ff583e876057309cd4a0b59a - md5: e1a76ff63763cf04e06eca94978b9dd0 + size: 4042027 + timestamp: 1754660987136 +- conda: https://prefix.dev/conda-forge/noarch/rust-std-aarch64-apple-darwin-1.89.0-hf6ec828_0.conda + sha256: 38afa19e77e682c9802ccbb2dd822362918c968b04d7331716aae33c3f601719 + md5: 4a76b5b647ec0ad20092798774cca2fb depends: - __unix constrains: - - rust >=1.86.0,<1.86.1.0a0 + - rust >=1.89.0,<1.89.1.0a0 license: MIT license_family: MIT - size: 32999893 - timestamp: 1743696811586 -- conda: https://prefix.dev/conda-forge/noarch/rust-std-x86_64-apple-darwin-1.86.0-h38e4360_0.conda - sha256: 21f363d82ff18cf4532edd793258890f16c78bcb62d09720ec8077c80b5b3e21 - md5: bf9600640e706037e6b095f910f797fb + size: 34368223 + timestamp: 1754659525934 +- conda: https://prefix.dev/conda-forge/noarch/rust-std-x86_64-apple-darwin-1.89.0-h38e4360_0.conda + sha256: b41a2e4afe1c2ad25ff75e6fdcc7bf4b88694df1d6f2d6bb2b774c53d9e253bc + md5: ff95f484b7302f016b2af68272a24df4 depends: - __unix constrains: - - rust >=1.86.0,<1.86.1.0a0 + - rust >=1.89.0,<1.89.1.0a0 license: MIT license_family: MIT - size: 34776293 - timestamp: 1743696857590 -- conda: https://prefix.dev/conda-forge/noarch/rust-std-x86_64-pc-windows-msvc-1.86.0-h17fc481_0.conda - sha256: e5f9d2507e78d2508613480ffff586e70fc181351b46999c67387fe4c31df53f - md5: 7c621ff4a342c29e465c92bd6d464cb3 + size: 35698822 + timestamp: 1754659553183 +- conda: https://prefix.dev/conda-forge/noarch/rust-std-x86_64-pc-windows-msvc-1.89.0-h17fc481_0.conda + sha256: 0102785df1ea410dde59c7f658f625f61ce8df7380d9687e46588f6a8b555e8a + md5: 4f670fbc603c73ecb0a79f37ec2ec03c depends: - __win constrains: - - rust >=1.86.0,<1.86.1.0a0 + - rust >=1.89.0,<1.89.1.0a0 license: MIT license_family: MIT - size: 28054537 - timestamp: 1743699089031 -- conda: https://prefix.dev/conda-forge/noarch/rust-std-x86_64-unknown-linux-gnu-1.86.0-h2c6d0dc_0.conda - sha256: 8c1c68b7a8ce9657fea7d266607c21c9a00a382c346348a232e539c8a3266e84 - md5: 2fcc4c775a50bd2ce3ccb8dc56e4fb47 + size: 28323427 + timestamp: 1754662269621 +- conda: https://prefix.dev/conda-forge/noarch/rust-std-x86_64-unknown-linux-gnu-1.89.0-h2c6d0dc_0.conda + sha256: 533e3144feeb5d20008436149c4c90ac8a3b4e91e0f28b9ccb9d99d2ddfec2aa + md5: b604abab3384fc21314b6d0c60413de4 depends: - __unix constrains: - - rust >=1.86.0,<1.86.1.0a0 + - rust >=1.89.0,<1.89.1.0a0 license: MIT license_family: MIT - size: 37636509 - timestamp: 1743697574868 + size: 38055572 + timestamp: 1754660019384 - conda: https://prefix.dev/conda-forge/noarch/s3transfer-0.13.1-pyhd8ed1ab_0.conda sha256: a9cc762b0a472ed3bb69784ebe71e99a72661cdf38001c5e717cb4c2a2505d6f md5: d66713a183295206013e8f93db001e99 diff --git a/pixi.toml b/pixi.toml index a78899101..b8b124abd 100644 --- a/pixi.toml +++ b/pixi.toml @@ -28,7 +28,8 @@ deploy-dev = "mike deploy --push dev devel" [dependencies] openssl = "3.*" -rust = ">=1.86.0,<1.87" +rust = ">=1.89.0,<1.90" +rust-src = ">=1.89.0,<1.90" compilers = "1.6.0.*" libssh2 = "1.11.0.*" pkg-config = "0.29.2.*" @@ -41,7 +42,6 @@ pyyaml = ">=6.0.1,<6.1" conda-package-handling = "2.2.0.*" requests = ">=2.32.2,<2.33" syrupy = "4.6.*" -rust-src = ">=1.86.0,<1.87" boto3 = "*" [feature.lint.dependencies] diff --git a/py-rattler-build/pixi.toml b/py-rattler-build/pixi.toml index d964c08b3..13449dd6d 100644 --- a/py-rattler-build/pixi.toml +++ b/py-rattler-build/pixi.toml @@ -24,7 +24,7 @@ patchelf = "~=0.17.2" [feature.lint.dependencies] # we need rust for cargo-fmt and clippy -rust = ">=1.86.0,<1.87" +rust = ">=1.89.0,<1.90" ruff = ">=0.3.3,<0.4" [feature.lint.tasks] diff --git a/src/build.rs b/src/build.rs index 3b368613d..8184258c9 100644 --- a/src/build.rs +++ b/src/build.rs @@ -209,16 +209,16 @@ fn check_for_binary_prefix(output: &Output, paths_json: &PathsJson) -> Result<() use rattler_conda_types::package::FileMode; for paths_entry in &paths_json.paths { - if let Some(prefix_placeholder) = &paths_entry.prefix_placeholder { - if prefix_placeholder.file_mode == FileMode::Binary { - return Err(miette::miette!( - "Package {} contains Binary file {} which contains host prefix placeholder, which may cause issues when the package is installed to a different location. \ + if let Some(prefix_placeholder) = &paths_entry.prefix_placeholder + && prefix_placeholder.file_mode == FileMode::Binary + { + return Err(miette::miette!( + "Package {} contains Binary file {} which contains host prefix placeholder, which may cause issues when the package is installed to a different location. \ Consider fixing the build process to avoid embedding the host prefix in binaries. \ To allow this, remove the --error-prefix-in-binary flag.", - output.name().as_normalized(), - paths_entry.relative_path.display() - )); - } + output.name().as_normalized(), + paths_entry.relative_path.display() + )); } } diff --git a/src/cache.rs b/src/cache.rs index 22f1b093e..d645bab07 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -75,12 +75,12 @@ impl Output { .requirements .build_time() .filter_map(|x| { - if let Dependency::Spec(spec) = x { - if spec.version.is_none() && spec.build.is_none() { - if let Some(name) = spec.name.as_ref() { - return Some(name.as_normalized().to_string()); - } - } + if let Dependency::Spec(spec) = x + && spec.version.is_none() + && spec.build.is_none() + && let Some(name) = spec.name.as_ref() + { + return Some(name.as_normalized().to_string()); } None }) diff --git a/src/env_vars.rs b/src/env_vars.rs index 72ae0cc25..d942a8f4c 100644 --- a/src/env_vars.rs +++ b/src/env_vars.rs @@ -54,12 +54,11 @@ pub fn python_vars(output: &Output) -> HashMap> { .variant() .get(&"python".into()) .map(|s| s.to_string()); - if python_version.is_none() { - if let Some((record, requested)) = output.find_resolved_package("python") { - if requested { - python_version = Some(record.package_record.version.to_string()); - } - } + if python_version.is_none() + && let Some((record, requested)) = output.find_resolved_package("python") + && requested + { + python_version = Some(record.package_record.version.to_string()); } if let Some(py_ver) = python_version { diff --git a/src/lib.rs b/src/lib.rs index b19a0f66e..d1a9bf4b9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -223,20 +223,20 @@ pub async fn get_build_output( consts::VARIANTS_CONFIG_FILE, consts::CONDA_BUILD_CONFIG_FILE, ] { - if let Some(variant_path) = recipe_path.parent().map(|parent| parent.join(file)) { - if variant_path.is_file() { - if !build_data.ignore_recipe_variants { - let mut configs = build_data.variant_config.clone(); - configs.push(variant_path); - detected_variant_config = Some(configs); - } else { - tracing::debug!( - "Ignoring variants from {} because \"--ignore-recipe-variants\" was specified", - variant_path.display() - ); - } - break; + if let Some(variant_path) = recipe_path.parent().map(|parent| parent.join(file)) + && variant_path.is_file() + { + if !build_data.ignore_recipe_variants { + let mut configs = build_data.variant_config.clone(); + configs.push(variant_path); + detected_variant_config = Some(configs); + } else { + tracing::debug!( + "Ignoring variants from {} because \"--ignore-recipe-variants\" was specified", + variant_path.display() + ); } + break; }; } @@ -423,15 +423,15 @@ fn can_test(output: &Output, all_output_names: &[&PackageName], done_outputs: &[ if spec.name.as_ref() != Some(output.name()) { return false; } - if let Some(version_spec) = &spec.version { - if !version_spec.matches(output.recipe.package().version()) { - return false; - } + if let Some(version_spec) = &spec.version + && !version_spec.matches(output.recipe.package().version()) + { + return false; } - if let Some(build_string_spec) = &spec.build { - if !build_string_spec.matches(&output.build_string()) { - return false; - } + if let Some(build_string_spec) = &spec.build + && !build_string_spec.matches(&output.build_string()) + { + return false; } true }; diff --git a/src/macos/link.rs b/src/macos/link.rs index 95d8adb6e..e2a9b47bc 100644 --- a/src/macos/link.rs +++ b/src/macos/link.rs @@ -296,11 +296,11 @@ impl Relinker for Dylib { } }; - if let Some(id) = &self.id { - if let Some(new_dylib) = exchange_dylib(id) { - changes.change_id = Some(new_dylib); - modified = true; - } + if let Some(id) = &self.id + && let Some(new_dylib) = exchange_dylib(id) + { + changes.change_id = Some(new_dylib); + modified = true; } for lib in &self.libraries { diff --git a/src/main.rs b/src/main.rs index 3785dcaf2..7a5f647ae 100644 --- a/src/main.rs +++ b/src/main.rs @@ -210,10 +210,10 @@ fn recipe_paths( if let Some(recipe_dir) = &recipe_dir { for entry in ignore::Walk::new(recipe_dir) { let entry = entry.into_diagnostic()?; - if entry.path().is_dir() { - if let Ok(recipe_path) = get_recipe_path(entry.path()) { - recipe_paths.push(recipe_path); - } + if entry.path().is_dir() + && let Ok(recipe_path) = get_recipe_path(entry.path()) + { + recipe_paths.push(recipe_path); } } } diff --git a/src/package_test/run_test.rs b/src/package_test/run_test.rs index bff74ea0e..1fb67b2b8 100644 --- a/src/package_test/run_test.rs +++ b/src/package_test/run_test.rs @@ -128,10 +128,10 @@ impl Tests { // copy all test files to a temporary directory and set it as the working // directory CopyDir::new(path, tmp_dir.path()).run().map_err(|e| { - TestError::IoError(std::io::Error::new( - std::io::ErrorKind::Other, - format!("Failed to copy test files: {}", e), - )) + TestError::IoError(std::io::Error::other(format!( + "Failed to copy test files: {}", + e + ))) })?; script @@ -458,14 +458,14 @@ pub async fn run_test( let tests = fs::read_to_string(package_folder.join("info/tests/tests.yaml"))?; let tests: Vec = serde_yaml::from_str(&tests)?; - if let Some(test_index) = config.test_index { - if test_index >= tests.len() { - return Err(TestError::TestFailed(format!( - "Test index {} out of range (0..{})", - test_index, - tests.len() - ))); - } + if let Some(test_index) = config.test_index + && test_index >= tests.len() + { + return Err(TestError::TestFailed(format!( + "Test index {} out of range (0..{})", + test_index, + tests.len() + ))); } let tests = if let Some(test_index) = config.test_index { @@ -845,10 +845,10 @@ impl CommandsTest { // directory let test_dir = test_directory.join("test"); CopyDir::new(path, &test_dir).run().map_err(|e| { - TestError::IoError(std::io::Error::new( - std::io::ErrorKind::Other, - format!("Failed to copy test files: {}", e), - )) + TestError::IoError(std::io::Error::other(format!( + "Failed to copy test files: {}", + e + ))) })?; tracing::info!("Testing commands:"); diff --git a/src/packaging.rs b/src/packaging.rs index 834f7a97b..81514efeb 100644 --- a/src/packaging.rs +++ b/src/packaging.rs @@ -211,13 +211,13 @@ fn write_recipe_folder( let mut files = Vec::from(copy_result.copied_paths()); // Make sure that the recipe file is "recipe.yaml" in `info/recipe/` - if recipe_path.file_name() != Some("recipe.yaml".as_ref()) { - if let Some(name) = recipe_path.file_name() { - fs::rename(recipe_folder.join(name), recipe_folder.join("recipe.yaml"))?; - // Update the existing entry with the new recipe file. - if let Some(pos) = files.iter().position(|x| x == &recipe_folder.join(name)) { - files[pos] = recipe_folder.join("recipe.yaml"); - } + if recipe_path.file_name() != Some("recipe.yaml".as_ref()) + && let Some(name) = recipe_path.file_name() + { + fs::rename(recipe_folder.join(name), recipe_folder.join("recipe.yaml"))?; + // Update the existing entry with the new recipe file. + if let Some(pos) = files.iter().position(|x| x == &recipe_folder.join(name)) { + files[pos] = recipe_folder.join("recipe.yaml"); } } diff --git a/src/packaging/file_finder.rs b/src/packaging/file_finder.rs index 0d68c9e78..56a38ee98 100644 --- a/src/packaging/file_finder.rs +++ b/src/packaging/file_finder.rs @@ -126,7 +126,7 @@ fn find_new_files( }) .collect(); - let current_files = current_files + current_files .clone() .into_iter() .filter(|p| { @@ -135,9 +135,7 @@ fn find_new_files( p.strip_prefix(prefix).expect("File should be in prefix"), )) }) - .collect::>(); - - current_files + .collect::>() } } diff --git a/src/packaging/file_mapper.rs b/src/packaging/file_mapper.rs index e8377c344..3239c1059 100644 --- a/src/packaging/file_mapper.rs +++ b/src/packaging/file_mapper.rs @@ -13,32 +13,32 @@ use super::PackagingError; /// This is a temporary measure to avoid packaging `pyc` files that are not /// generated by the build process. pub fn filter_pyc(path: &Path, old_files: &HashSet) -> bool { - if let (Some(ext), Some(parent)) = (path.extension(), path.parent()) { - if ext == "pyc" { - let has_pycache = parent.ends_with("__pycache__"); - let pyfile = if has_pycache { - // a pyc file with a pycache parent should be removed - // replace two last dots with .py - // these paths look like .../__pycache__/file_dependency.cpython-311.pyc - // where the `file_dependency.py` path would be found in the parent directory from __pycache__ - let stem = path - .file_name() - .expect("unreachable as extension doesn't exist without filename") - .to_string_lossy() - .to_string(); - let py_stem = stem.rsplitn(3, '.').last().unwrap_or_default(); - if let Some(pp) = parent.parent() { - pp.join(format!("{}.py", py_stem)) - } else { - return false; - } + if let (Some(ext), Some(parent)) = (path.extension(), path.parent()) + && ext == "pyc" + { + let has_pycache = parent.ends_with("__pycache__"); + let pyfile = if has_pycache { + // a pyc file with a pycache parent should be removed + // replace two last dots with .py + // these paths look like .../__pycache__/file_dependency.cpython-311.pyc + // where the `file_dependency.py` path would be found in the parent directory from __pycache__ + let stem = path + .file_name() + .expect("unreachable as extension doesn't exist without filename") + .to_string_lossy() + .to_string(); + let py_stem = stem.rsplitn(3, '.').last().unwrap_or_default(); + if let Some(pp) = parent.parent() { + pp.join(format!("{}.py", py_stem)) } else { - path.with_extension("py") - }; - - if old_files.contains(&pyfile) { - return true; + return false; } + } else { + path.with_extension("py") + }; + + if old_files.contains(&pyfile) { + return true; } } false @@ -120,25 +120,23 @@ impl Output { if self.recipe.build().is_python_version_independent() { // we need to remove files in bin/ that are registered as entry points if path_rel.starts_with("bin") { - if let Some(name) = path_rel.file_name() { - if entry_points + if let Some(name) = path_rel.file_name() + && entry_points .iter() .any(|ep| ep.command == name.to_string_lossy()) - { - return Ok(None); - } + { + return Ok(None); } } // Windows - else if path_rel.starts_with("Scripts") { - if let Some(name) = path_rel.file_name() { - if entry_points.iter().any(|ep| { - format!("{}.exe", ep.command) == name.to_string_lossy() - || format!("{}-script.py", ep.command) == name.to_string_lossy() - }) { - return Ok(None); - } - } + else if path_rel.starts_with("Scripts") + && let Some(name) = path_rel.file_name() + && entry_points.iter().any(|ep| { + format!("{}.exe", ep.command) == name.to_string_lossy() + || format!("{}-script.py", ep.command) == name.to_string_lossy() + }) + { + return Ok(None); } // skip .pyc or .pyo or .egg-info files @@ -185,14 +183,12 @@ impl Output { new_parts[0] = Component::Normal("python-scripts".as_ref()); // on Windows, if the file ends with -script.py, remove the -script.py suffix - if let Some(Component::Normal(name)) = new_parts.last_mut() { - if let Some(name_str) = name.to_str() { - if target_platform.is_windows() { - if let Some(stripped_suffix) = name_str.strip_suffix("-script.py") { - *name = stripped_suffix.as_ref(); - } - } - } + if let Some(Component::Normal(name)) = new_parts.last_mut() + && let Some(name_str) = name.to_str() + && target_platform.is_windows() + && let Some(stripped_suffix) = name_str.strip_suffix("-script.py") + { + *name = stripped_suffix.as_ref(); } dest_path = dest_folder.join(PathBuf::from_iter(new_parts)); @@ -209,8 +205,7 @@ impl Output { } } None => { - return Err(PackagingError::IoError(std::io::Error::new( - std::io::ErrorKind::Other, + return Err(PackagingError::IoError(std::io::Error::other( "Could not get parent directory", ))); } @@ -228,10 +223,10 @@ impl Output { Ok(mut target) => { // If absolute and within the build prefix, make it relative if target.is_absolute() && target.starts_with(prefix) { - if let Some(parent) = path.parent() { - if let Some(rel) = pathdiff::diff_paths(&target, parent) { - target = rel; - } + if let Some(parent) = path.parent() + && let Some(rel) = pathdiff::diff_paths(&target, parent) + { + target = rel; } } else if target.is_absolute() { tracing::warn!( diff --git a/src/packaging/metadata.rs b/src/packaging/metadata.rs index 156820b8c..22c65ea55 100644 --- a/src/packaging/metadata.rs +++ b/src/packaging/metadata.rs @@ -130,10 +130,10 @@ pub fn create_prefix_placeholder( prefix_detection: &PrefixDetection, ) -> Result, PackagingError> { // exclude pyc and pyo files from prefix replacement - if let Some(ext) = file_path.extension() { - if ext == "pyc" || ext == "pyo" { - return Ok(None); - } + if let Some(ext) = file_path.extension() + && (ext == "pyc" || ext == "pyo") + { + return Ok(None); } let relative_path = file_path.strip_prefix(prefix)?; @@ -254,7 +254,7 @@ impl Output { pub fn about_json(&self) -> AboutJson { let recipe = &self.recipe; - let about_json = AboutJson { + AboutJson { home: recipe .about() .homepage @@ -286,9 +286,7 @@ impl Output { .map(clean_url) .collect(), extra: self.extra_meta.clone().unwrap_or_default(), - }; - - about_json + } } /// Create the contents of the index.json file for the given output. diff --git a/src/post_process/checks.rs b/src/post_process/checks.rs index 23c1b0203..bf332761c 100644 --- a/src/post_process/checks.rs +++ b/src/post_process/checks.rs @@ -131,10 +131,10 @@ fn resolved_run_dependencies( }) .flat_map(|dep| { if let Some(package_name) = &dep.spec().name { - if let Some(nature) = package_to_nature_map.get(package_name) { - if nature != &PackageNature::DSOLibrary { - return None; - } + if let Some(nature) = package_to_nature_map.get(package_name) + && nature != &PackageNature::DSOLibrary + { + return None; } dep.spec().name.to_owned().map(|v| v.as_source().to_owned()) } else { @@ -208,10 +208,10 @@ fn find_system_libs(output: &Output) -> Result { let record = PrefixRecord::from_path(sysroot_path).unwrap(); let so_glob = Glob::new("*.so*")?.compile_matcher(); for file in record.files { - if let Some(file_name) = file.file_name() { - if so_glob.is_match(file_name) { - system_libs.add(Glob::new(&file_name.to_string_lossy())?); - } + if let Some(file_name) = file.file_name() + && so_glob.is_match(file_name) + { + system_libs.add(Glob::new(&file_name.to_string_lossy())?); } } } @@ -253,17 +253,15 @@ pub fn perform_linking_checks( } let lib = resolved.as_ref().unwrap_or(lib); - if let Ok(libpath) = lib.strip_prefix(host_prefix) { - if let Some(package) = prefix_info + if let Ok(libpath) = lib.strip_prefix(host_prefix) + && let Some(package) = prefix_info .path_to_package .get(&libpath.to_path_buf().into()) - { - if let Some(nature) = prefix_info.package_to_nature.get(package) { - // Only take shared libraries into account. - if nature == &PackageNature::DSOLibrary { - file_dsos.push((libpath.to_path_buf(), package.clone())); - } - } + && let Some(nature) = prefix_info.package_to_nature.get(package) + { + // Only take shared libraries into account. + if nature == &PackageNature::DSOLibrary { + file_dsos.push((libpath.to_path_buf(), package.clone())); } } } diff --git a/src/post_process/menuinst.rs b/src/post_process/menuinst.rs index f1248b676..f9bf98820 100644 --- a/src/post_process/menuinst.rs +++ b/src/post_process/menuinst.rs @@ -10,12 +10,13 @@ pub fn menuinst(temp_files: &TempFiles) -> Result<(), PackagingError> { // find all new files `Menu/*.json` for p in temp_files.files.iter() { let prefix_path = p.strip_prefix(temp_files.temp_dir.path()).unwrap(); - if let Some(first) = prefix_path.components().next() { - if first.as_os_str() == "Menu" && prefix_path.extension() == Some(OsStr::new("json")) { - let content = fs_err::read_to_string(p)?; - let _menu: MenuInstSchema = serde_json::from_str(&content) - .map_err(|e| PackagingError::InvalidMenuInstSchema(p.to_path_buf(), e))?; - } + if let Some(first) = prefix_path.components().next() + && first.as_os_str() == "Menu" + && prefix_path.extension() == Some(OsStr::new("json")) + { + let content = fs_err::read_to_string(p)?; + let _menu: MenuInstSchema = serde_json::from_str(&content) + .map_err(|e| PackagingError::InvalidMenuInstSchema(p.to_path_buf(), e))?; } } diff --git a/src/post_process/python.rs b/src/post_process/python.rs index fbb318b99..f5d0f3676 100644 --- a/src/post_process/python.rs +++ b/src/post_process/python.rs @@ -127,10 +127,16 @@ pub fn compile_pyc( .arg(f) .output(); - if command.is_err() { - let stderr = String::from_utf8_lossy(&command.as_ref().unwrap().stderr); - tracing::error!("Error compiling .py files to .pyc: {}", stderr); - return Err(PackagingError::PythonCompileError(stderr.to_string())); + if let Err(err) = command { + tracing::error!( + "Error compiling .py files to .pyc! Command could not spawn ({:?})", + err + ); + return Err(PackagingError::PythonCompileError(format!( + "Could not spawn python compiler for file {}: {:?}", + f.display(), + err + ))); } let command = command.unwrap(); diff --git a/src/rebuild.rs b/src/rebuild.rs index 5ba863f6f..a9b0ea4c2 100644 --- a/src/rebuild.rs +++ b/src/rebuild.rs @@ -19,10 +19,10 @@ fn folder_from_tar_bz2( let path = entry.path()?; if let Ok(stripped_path) = path.strip_prefix(find_path) { let dest_file = dest_folder.join(stripped_path); - if let Some(parent_folder) = dest_file.parent() { - if !parent_folder.exists() { - fs::create_dir_all(parent_folder)?; - } + if let Some(parent_folder) = dest_file.parent() + && !parent_folder.exists() + { + fs::create_dir_all(parent_folder)?; } entry.unpack(dest_file)?; } @@ -52,10 +52,10 @@ fn folder_from_conda( let path = entry.path()?; if let Ok(stripped_path) = path.strip_prefix(find_path) { let dest_file = dest_folder.join(stripped_path); - if let Some(parent_folder) = dest_file.parent() { - if !parent_folder.exists() { - fs::create_dir_all(parent_folder)?; - } + if let Some(parent_folder) = dest_file.parent() + && !parent_folder.exists() + { + fs::create_dir_all(parent_folder)?; } entry.unpack(dest_file)?; } diff --git a/src/recipe/custom_yaml.rs b/src/recipe/custom_yaml.rs index 2d50d190c..8b03cb2bc 100644 --- a/src/recipe/custom_yaml.rs +++ b/src/recipe/custom_yaml.rs @@ -67,6 +67,7 @@ pub enum Node { } /// Parse YAML from a string and return a Node representing the content. +#[allow(clippy::result_large_err)] pub fn parse_yaml( init_span_index: usize, src: S, @@ -93,6 +94,7 @@ impl Node { /// type here is the generic Node enumeration to make it potentially easier /// for callers to use. Regardless, it's always possible to treat the /// returned node as a mapping node without risk of panic. + #[allow(clippy::result_large_err)] pub fn parse_yaml( init_span_index: usize, src: S, @@ -155,10 +157,11 @@ impl Render for Node { impl Render for ScalarNode { fn render(&self, jinja: &Jinja, _name: &str) -> Result> { let rendered = jinja.render_str(self.as_str()).map_err(|err| { + let label = jinja_error_to_label(&err); vec![_partialerror!( *self.span(), - ErrorKind::JinjaRendering(err), - label = jinja_error_to_label(&err) + ErrorKind::JinjaRendering(Box::new(err)), + label = label )] })?; @@ -177,10 +180,11 @@ impl Render> for ScalarNode { _name: &str, ) -> Result, Vec> { let rendered = jinja.render_str(self.as_str()).map_err(|err| { + let label = jinja_error_to_label(&err); vec![_partialerror!( *self.span(), - ErrorKind::JinjaRendering(err), - label = jinja_error_to_label(&err) + ErrorKind::JinjaRendering(Box::new(err)), + label = label )] })?; @@ -893,10 +897,11 @@ impl IfSelector { /// chosen node. pub fn process(&self, jinja: &Jinja) -> Result, Vec> { let cond = jinja.eval(self.cond.as_str()).map_err(|err| { + let label = err.to_string(); vec![_partialerror!( *self.cond.span(), - ErrorKind::JinjaRendering(err), - label = err.to_string(), + ErrorKind::JinjaRendering(Box::new(err)), + label = label, help = "error evaluating if-selector condition" )] })?; diff --git a/src/recipe/custom_yaml/rendered.rs b/src/recipe/custom_yaml/rendered.rs index 22eb2fc0b..7614081b5 100644 --- a/src/recipe/custom_yaml/rendered.rs +++ b/src/recipe/custom_yaml/rendered.rs @@ -86,6 +86,7 @@ impl RenderedNode { /// type here is the generic Node enumeration to make it potentially easier /// for callers to use. Regardless, it's always possible to treat the /// returned node as a mapping node without risk of panic. + #[allow(clippy::result_large_err)] pub fn parse_yaml( init_span_index: usize, src: S, @@ -663,10 +664,11 @@ impl Render for Node { impl Render for ScalarNode { fn render(&self, jinja: &Jinja, _name: &str) -> Result> { let rendered = jinja.render_str(self.as_str()).map_err(|err| { + let label = jinja_error_to_label(&err); vec![_partialerror!( *self.span(), - ErrorKind::JinjaRendering(err), - label = jinja_error_to_label(&err), + ErrorKind::JinjaRendering(Box::new(err)), + label = label, )] })?; // unsure whether this should be allowed to coerce // check if it's quoted? @@ -692,10 +694,11 @@ impl Render> for ScalarNode { _name: &str, ) -> Result, Vec> { let rendered = jinja.render_str(self.as_str()).map_err(|err| { + let label = format!("Rendering error: {}", err.kind()); vec![_partialerror!( *self.span(), - ErrorKind::JinjaRendering(err), - label = format!("Rendering error: {}", err.kind()) + ErrorKind::JinjaRendering(Box::new(err)), + label = label )] })?; diff --git a/src/recipe/error.rs b/src/recipe/error.rs index 53200be4c..e4fcaaca4 100644 --- a/src/recipe/error.rs +++ b/src/recipe/error.rs @@ -78,7 +78,7 @@ impl ParsingError { pub enum ErrorKind { /// Error while parsing YAML. #[diagnostic(code(error::yaml_parsing))] - YamlParsing(#[from] marked_yaml::LoadError), + YamlParsing(Box), /// Error when expected mapping but got something else. #[diagnostic(code(error::expected_mapping))] @@ -126,7 +126,7 @@ pub enum ErrorKind { /// Error rendering a Jinja expression. #[diagnostic(code(error::jinja_rendering))] - JinjaRendering(#[from] minijinja::Error), + JinjaRendering(Box), /// Error processing the condition of a if-selector. #[diagnostic(code(error::if_selector_condition_not_bool))] @@ -220,30 +220,32 @@ impl fmt::Display for ErrorKind { use std::error::Error; match self { - ErrorKind::YamlParsing(LoadError::TopLevelMustBeMapping(_)) => { - write!(f, "failed to parse YAML: top level must be a mapping.") - } - ErrorKind::YamlParsing(LoadError::UnexpectedAnchor(_)) => { - write!(f, "failed to parse YAML: unexpected definition of anchor.") - } - ErrorKind::YamlParsing(LoadError::MappingKeyMustBeScalar(_)) => { - write!(f, "failed to parse YAML: keys in mappings must be scalar.") - } - ErrorKind::YamlParsing(LoadError::UnexpectedTag(_)) => { - write!(f, "failed to parse YAML: unexpected use of YAML tag.") - } - ErrorKind::YamlParsing(LoadError::ScanError(_, e)) => { - // e.description() is deprecated but it's the only way to get - // the exact info we want out of yaml-rust + ErrorKind::YamlParsing(e) => match e.as_ref() { + LoadError::TopLevelMustBeMapping(_) => { + write!(f, "failed to parse YAML: top level must be a mapping.") + } + LoadError::UnexpectedAnchor(_) => { + write!(f, "failed to parse YAML: unexpected definition of anchor.") + } + LoadError::MappingKeyMustBeScalar(_) => { + write!(f, "failed to parse YAML: keys in mappings must be scalar.") + } + LoadError::UnexpectedTag(_) => { + write!(f, "failed to parse YAML: unexpected use of YAML tag.") + } + LoadError::ScanError(_, e) => { + // e.description() is deprecated but it's the only way to get + // the exact info we want out of yaml-rust - write!(f, "failed to parse YAML: {}", e.description()) - } - ErrorKind::YamlParsing(LoadError::DuplicateKey(_)) => { - write!(f, "failed to parse YAML: duplicate key.") - } - ErrorKind::YamlParsing(_) => { - write!(f, "failed to parse YAML.") - } + write!(f, "failed to parse YAML: {}", e.description()) + } + LoadError::DuplicateKey(_) => { + write!(f, "failed to parse YAML: duplicate key.") + } + _ => { + write!(f, "failed to parse YAML.") + } + }, ErrorKind::ExpectedMapping => write!(f, "expected a mapping."), ErrorKind::ExpectedScalar => write!(f, "expected a scalar value."), ErrorKind::ExpectedSequence => write!(f, "expected a sequence."), @@ -260,7 +262,7 @@ impl fmt::Display for ErrorKind { ErrorKind::InvalidValue((key, s)) => write!(f, "invalid value for `{key}`: `{s}`."), ErrorKind::MissingField(s) => write!(f, "missing field `{s}`"), ErrorKind::JinjaRendering(err) => { - write!(f, "failed to render Jinja expression: {}", err) + write!(f, "failed to render Jinja expression: {}", err.as_ref()) } ErrorKind::IfSelectorConditionNotBool(err) => { write!(f, "condition in `if` selector must be a boolean: {}", err) @@ -313,6 +315,18 @@ impl From for ErrorKind { } } +impl From for ErrorKind { + fn from(e: marked_yaml::LoadError) -> Self { + Self::YamlParsing(Box::new(e)) + } +} + +impl From for ErrorKind { + fn from(e: minijinja::Error) -> Self { + Self::JinjaRendering(Box::new(e)) + } +} + /// Macro to facilitate the creation of [`Error`]s. #[macro_export] #[doc(hidden)] @@ -403,17 +417,18 @@ pub(super) fn load_error_handler( err: marked_yaml::LoadError, ) -> ParsingError { let span = marker_to_span(src.as_ref(), marker(&err)); + let label = Cow::Borrowed(match &err { + marked_yaml::LoadError::TopLevelMustBeMapping(_) => "expected a mapping here", + marked_yaml::LoadError::UnexpectedAnchor(_) => "unexpected anchor here", + marked_yaml::LoadError::UnexpectedTag(_) => "unexpected tag here", + marked_yaml::LoadError::DuplicateKey(_) => "duplicate key here", + _ => "here", + }); _error!( src, span, - ErrorKind::YamlParsing(err), - label = Cow::Borrowed(match err { - marked_yaml::LoadError::TopLevelMustBeMapping(_) => "expected a mapping here", - marked_yaml::LoadError::UnexpectedAnchor(_) => "unexpected anchor here", - marked_yaml::LoadError::UnexpectedTag(_) => "unexpected tag here", - marked_yaml::LoadError::DuplicateKey(_) => "duplicate key here", - _ => "here", - }) + ErrorKind::YamlParsing(Box::new(err)), + label = label ) } @@ -492,13 +507,12 @@ pub(super) fn find_length(src: &str, start: SourceOffset) -> usize { // FIXME: Implement `"`, `'` and `[` open and close detection. while let Some((i, c)) = iter.next() { - if c == ':' { - if let Some((_, c)) = iter.next() { - if c == '\n' || c == '\r' || c == '\t' || c == ' ' { - end += i; - break; - } - } + if c == ':' + && let Some((_, c)) = iter.next() + && (c == '\n' || c == '\r' || c == '\t' || c == ' ') + { + end += i; + break; } if c == '\n' || c == '\r' || c == '\t' { diff --git a/src/recipe/jinja.rs b/src/recipe/jinja.rs index facef7a8a..68c9dfacf 100644 --- a/src/recipe/jinja.rs +++ b/src/recipe/jinja.rs @@ -608,12 +608,12 @@ fn set_jinja(config: &SelectorConfig) -> minijinja::Environment<'static> { env.add_function("load_from_file", move |path: String| { check_experimental(experimental)?; - if let Some(recipe_path) = recipe_path.as_ref() { - if let Some(parent) = recipe_path.parent() { - let relative_path = parent.join(&path); - if let Ok(value) = read_and_parse_file(&relative_path) { - return Ok(value); - } + if let Some(recipe_path) = recipe_path.as_ref() + && let Some(parent) = recipe_path.parent() + { + let relative_path = parent.join(&path); + if let Ok(value) = read_and_parse_file(&relative_path) { + return Ok(value); } } diff --git a/src/recipe/parser/output.rs b/src/recipe/parser/output.rs index 61165f6f3..f2c73b312 100644 --- a/src/recipe/parser/output.rs +++ b/src/recipe/parser/output.rs @@ -32,6 +32,7 @@ static ALLOWED_KEYS_MULTI_OUTPUTS: [&str; 9] = [ // Check if the `cache` top-level key is present. If it does not contain a // source, but there is a top-level `source` key, then we should warn the user // because this key was moved to the `cache` +#[allow(clippy::result_large_err)] fn check_src_cache(root: &MarkedMappingNode) -> Result<(), PartialParsingError> { if let Some(cache) = root.get("cache") { let has_top_level_source = root.contains_key("source"); @@ -54,6 +55,7 @@ fn check_src_cache(root: &MarkedMappingNode) -> Result<(), PartialParsingError> } /// Retrieve all outputs from the recipe source (YAML) +#[allow(clippy::result_large_err)] pub fn find_outputs_from_src(src: S) -> Result, ParsingError> { let root_node = parse_yaml(0, src.clone())?; let root_map = root_node.as_mapping().ok_or_else(|| { diff --git a/src/recipe/parser/script.rs b/src/recipe/parser/script.rs index 32903e98e..2e5f4ff21 100644 --- a/src/recipe/parser/script.rs +++ b/src/recipe/parser/script.rs @@ -381,10 +381,10 @@ impl TryConvertNode