[red-knot] Use POSIX representations of paths when creating the typeshed zip file (#11982)

This commit is contained in:
Alex Waygood 2024-06-22 17:54:19 +01:00 committed by GitHub
parent 79d72e6479
commit 91d091bb81
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 14 additions and 13 deletions

1
Cargo.lock generated
View File

@ -1997,6 +1997,7 @@ version = "0.0.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"insta", "insta",
"path-slash",
"ruff_db", "ruff_db",
"ruff_python_stdlib", "ruff_python_stdlib",
"rustc-hash", "rustc-hash",

View File

@ -21,6 +21,7 @@ tracing = { workspace = true }
zip = { workspace = true } zip = { workspace = true }
[build-dependencies] [build-dependencies]
path-slash = { workspace = true }
walkdir = { workspace = true } walkdir = { workspace = true }
zip = { workspace = true } zip = { workspace = true }

View File

@ -8,6 +8,7 @@
use std::fs::File; use std::fs::File;
use std::path::Path; use std::path::Path;
use path_slash::PathExt;
use zip::result::ZipResult; use zip::result::ZipResult;
use zip::write::{FileOptions, ZipWriter}; use zip::write::{FileOptions, ZipWriter};
use zip::CompressionMethod; use zip::CompressionMethod;
@ -28,25 +29,25 @@ fn zip_dir(directory_path: &str, writer: File) -> ZipResult<File> {
for entry in walkdir::WalkDir::new(directory_path) { for entry in walkdir::WalkDir::new(directory_path) {
let dir_entry = entry.unwrap(); let dir_entry = entry.unwrap();
let relative_path = dir_entry.path(); let absolute_path = dir_entry.path();
let name = relative_path let normalized_relative_path = absolute_path
.strip_prefix(Path::new(directory_path)) .strip_prefix(Path::new(directory_path))
.unwrap() .unwrap()
.to_str() .to_slash()
.expect("Unexpected non-utf8 typeshed path!"); .expect("Unexpected non-utf8 typeshed path!");
// Write file or directory explicitly // Write file or directory explicitly
// Some unzip tools unzip files with directory paths correctly, some do not! // Some unzip tools unzip files with directory paths correctly, some do not!
if relative_path.is_file() { if absolute_path.is_file() {
println!("adding file {relative_path:?} as {name:?} ..."); println!("adding file {absolute_path:?} as {normalized_relative_path:?} ...");
zip.start_file(name, options)?; zip.start_file(normalized_relative_path, options)?;
let mut f = File::open(relative_path)?; let mut f = File::open(absolute_path)?;
std::io::copy(&mut f, &mut zip).unwrap(); std::io::copy(&mut f, &mut zip).unwrap();
} else if !name.is_empty() { } else if !normalized_relative_path.is_empty() {
// Only if not root! Avoids path spec / warning // Only if not root! Avoids path spec / warning
// and mapname conversion failed error on unzip // and mapname conversion failed error on unzip
println!("adding dir {relative_path:?} as {name:?} ..."); println!("adding dir {absolute_path:?} as {normalized_relative_path:?} ...");
zip.add_directory(name, options)?; zip.add_directory(normalized_relative_path, options)?;
} }
} }
zip.finish() zip.finish()

View File

@ -3,7 +3,6 @@ pub(crate) mod versions;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::io::{self, Read}; use std::io::{self, Read};
use std::path::Path;
#[test] #[test]
fn typeshed_zip_created_at_build_time() -> anyhow::Result<()> { fn typeshed_zip_created_at_build_time() -> anyhow::Result<()> {
@ -14,9 +13,8 @@ mod tests {
let mut typeshed_zip_archive = zip::ZipArchive::new(io::Cursor::new(TYPESHED_ZIP_BYTES))?; let mut typeshed_zip_archive = zip::ZipArchive::new(io::Cursor::new(TYPESHED_ZIP_BYTES))?;
let path_to_functools = Path::new("stdlib").join("functools.pyi");
let mut functools_module_stub = typeshed_zip_archive let mut functools_module_stub = typeshed_zip_archive
.by_name(path_to_functools.to_str().unwrap()) .by_name("stdlib/functools.pyi")
.unwrap(); .unwrap();
assert!(functools_module_stub.is_file()); assert!(functools_module_stub.is_file());