mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-07 13:25:00 +00:00
Avoid ignore crate finding cache gitignore (#2615)
We put a `.gitignore` with `*` at the top of our cache. When maturin was building a source distribution inside the cache, it would walk up the tree to find a gitignore, see that and ignore all python files. We now add an (empty) `.git` directory one directory below, in the root of built-wheels cache. This prevents ignore walking further up (it marks the top level a git repository). Deptry (from #2490) is a mid sized rust package with additional python packages, so instead of using it in the test i've replaced it with a small (44KB total) reproducer that uses cffi for faster building, the entire test taking <2s on my machine. Fixes #2490
This commit is contained in:
parent
fc32a693c2
commit
fca2883864
10 changed files with 115 additions and 9 deletions
|
@ -251,15 +251,6 @@ impl Cache {
|
|||
Err(err) => return Err(err),
|
||||
}
|
||||
|
||||
// Add a phony .git, if it doesn't exist, to ensure that the cache isn't considered to be
|
||||
// part of a Git repository. (Some packages will include Git metadata (like a hash) in the
|
||||
// built version if they're in a Git repository, but the cache should be viewed as an
|
||||
// isolated store.)
|
||||
fs::OpenOptions::new()
|
||||
.create(true)
|
||||
.write(true)
|
||||
.open(root.join(".git"))?;
|
||||
|
||||
// Add an empty .gitignore to the build bucket, to ensure that the cache's own .gitignore
|
||||
// doesn't interfere with source distribution builds. Build backends (like hatchling) will
|
||||
// traverse upwards to look for .gitignore files.
|
||||
|
@ -273,6 +264,18 @@ impl Cache {
|
|||
Err(err) => return Err(err),
|
||||
}
|
||||
|
||||
// Add a phony .git, if it doesn't exist, to ensure that the cache isn't considered to be
|
||||
// part of a Git repository. (Some packages will include Git metadata (like a hash) in the
|
||||
// built version if they're in a Git repository, but the cache should be viewed as an
|
||||
// isolated store.).
|
||||
// We have to put this below the gitignore. Otherwise, if the build backend uses the rust
|
||||
// ignore crate it will walk up to the top level .gitignore and ignore its python source
|
||||
// files.
|
||||
fs::OpenOptions::new()
|
||||
.create(true)
|
||||
.write(true)
|
||||
.open(root.join(CacheBucket::BuiltWheels.to_str()).join(".git"))?;
|
||||
|
||||
fs::canonicalize(root)
|
||||
}
|
||||
|
||||
|
|
|
@ -6,10 +6,12 @@ use assert_fs::prelude::*;
|
|||
use base64::{prelude::BASE64_STANDARD as base64, Engine};
|
||||
use indoc::indoc;
|
||||
use itertools::Itertools;
|
||||
use std::env::current_dir;
|
||||
use std::process::Command;
|
||||
use url::Url;
|
||||
|
||||
use common::{uv_snapshot, TestContext, EXCLUDE_NEWER, INSTA_FILTERS};
|
||||
use uv_fs::Simplified;
|
||||
|
||||
use crate::common::get_bin;
|
||||
|
||||
|
@ -2952,3 +2954,57 @@ fn install_site_packages_mtime_updated() -> Result<()> {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// We had a bug where maturin would walk up to the top level gitignore of the cache with a `*`
|
||||
/// entry (because we want to ignore the entire cache from outside), ignoring all python source
|
||||
/// files.
|
||||
#[test]
|
||||
fn deptry_gitignore() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
|
||||
let project_root = current_dir()?
|
||||
.parent()
|
||||
.unwrap()
|
||||
.parent()
|
||||
.unwrap()
|
||||
.to_path_buf();
|
||||
let source_dist_dir = project_root
|
||||
.join("scripts")
|
||||
.join("packages")
|
||||
.join("deptry_reproducer");
|
||||
let filter_path = regex::escape(
|
||||
Url::from_directory_path(source_dist_dir.simplified_display().to_string())
|
||||
.unwrap()
|
||||
.to_string()
|
||||
.trim_end_matches('/'),
|
||||
);
|
||||
let filters: Vec<_> = [(filter_path.as_str(), "[SOURCE_DIST_DIR]")]
|
||||
.into_iter()
|
||||
.chain(INSTA_FILTERS.to_vec())
|
||||
.collect();
|
||||
|
||||
uv_snapshot!(filters, command(&context)
|
||||
.arg(format!("deptry_reproducer @ {}/deptry_reproducer-0.1.0.tar.gz", source_dist_dir.simplified_display()))
|
||||
.arg("--strict")
|
||||
.current_dir(source_dist_dir), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 3 packages in [TIME]
|
||||
Downloaded 3 packages in [TIME]
|
||||
Installed 3 packages in [TIME]
|
||||
+ cffi==1.16.0
|
||||
+ deptry-reproducer==0.1.0 (from [SOURCE_DIST_DIR]/deptry_reproducer-0.1.0.tar.gz)
|
||||
+ pycparser==2.21
|
||||
"###
|
||||
);
|
||||
|
||||
// Check that we packed the python source files
|
||||
context
|
||||
.assert_command("import deptry_reproducer.foo")
|
||||
.success();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
1
scripts/packages/deptry_reproducer/.gitignore
vendored
Normal file
1
scripts/packages/deptry_reproducer/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/target
|
7
scripts/packages/deptry_reproducer/Cargo.lock
generated
Normal file
7
scripts/packages/deptry_reproducer/Cargo.lock
generated
Normal file
|
@ -0,0 +1,7 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "deptry_reproducer"
|
||||
version = "0.1.0"
|
11
scripts/packages/deptry_reproducer/Cargo.toml
Normal file
11
scripts/packages/deptry_reproducer/Cargo.toml
Normal file
|
@ -0,0 +1,11 @@
|
|||
[package]
|
||||
name = "deptry_reproducer"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
[lib]
|
||||
name = "deptry_reproducer"
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
Binary file not shown.
21
scripts/packages/deptry_reproducer/pyproject.toml
Normal file
21
scripts/packages/deptry_reproducer/pyproject.toml
Normal file
|
@ -0,0 +1,21 @@
|
|||
[build-system]
|
||||
requires = ["maturin>=1,<2.0"]
|
||||
build-backend = "maturin"
|
||||
|
||||
[project]
|
||||
name = "deptry_reproducer"
|
||||
requires-python = ">=3.8"
|
||||
classifiers = [
|
||||
"Programming Language :: Rust",
|
||||
"Programming Language :: Python :: Implementation :: CPython",
|
||||
"Programming Language :: Python :: Implementation :: PyPy",
|
||||
]
|
||||
dependencies = ["cffi"]
|
||||
dynamic = ["version"]
|
||||
[project.optional-dependencies]
|
||||
tests = [
|
||||
"pytest",
|
||||
]
|
||||
[tool.maturin]
|
||||
bindings = "cffi"
|
||||
python-source = "python"
|
|
@ -0,0 +1,6 @@
|
|||
from .deptry_reproducer import *
|
||||
|
||||
|
||||
__doc__ = deptry_reproducer.__doc__
|
||||
if hasattr(deptry_reproducer, "__all__"):
|
||||
__all__ = deptry_reproducer.__all__
|
1
scripts/packages/deptry_reproducer/src/lib.rs
Normal file
1
scripts/packages/deptry_reproducer/src/lib.rs
Normal file
|
@ -0,0 +1 @@
|
|||
|
Loading…
Add table
Add a link
Reference in a new issue