Uninstall files recorded by legacy egg metadata - #251
Conversation
| let entry_points = match fs_err::read_to_string(egg_info.join("entry_points.txt")) { | ||
| Ok(entry_points) => Some(entry_points), | ||
| Err(err) if err.kind() == std::io::ErrorKind::NotFound => None, | ||
| Err(err) => return Err(err.into()), | ||
| }; | ||
| if let Some(entry_points) = entry_points { | ||
| let (console_scripts, gui_scripts) = | ||
| scripts_from_ini(None, layout.python_version.1, entry_points)?; | ||
| for (script, is_gui) in console_scripts | ||
| .into_iter() | ||
| .map(|script| (script, false)) | ||
| .chain(gui_scripts.into_iter().map(|script| (script, true))) | ||
| { | ||
| let validated = ValidatedScript::try_from_script(&script, layout)?; | ||
|
|
There was a problem hiding this comment.
Do we not have a dedicated entry points parser? Can we add a struct that does so?
There was a problem hiding this comment.
Addressed: extracted an EntryPoints reader that owns the INI parsing and missing-file behavior, and reused it for both wheel install and legacy uninstall.
There was a problem hiding this comment.
Also preflighted all entry-point parsing and launcher validation before the first filesystem mutation, with a regression ensuring malformed metadata cannot leave a partial uninstall.
| let installed_files = match fs_err::read_to_string(egg_info.join("installed-files.txt")) { | ||
| Ok(installed_files) => Some(installed_files), | ||
| Err(err) if err.kind() == std::io::ErrorKind::NotFound => None, | ||
| Err(err) => return Err(err.into()), | ||
| }; | ||
| if let Some(installed_files) = installed_files.as_deref() { | ||
| let schemes = [ | ||
| layout.scheme.data.as_path(), | ||
| layout.scheme.purelib.as_path(), | ||
| layout.scheme.platlib.as_path(), | ||
| layout.scheme.scripts.as_path(), | ||
| layout.scheme.include.as_path(), | ||
| ]; |
There was a problem hiding this comment.
Do we not have a dedicated installed-files.txt parser? Should we add one?
There was a problem hiding this comment.
Addressed: added a dedicated InstalledFiles parser for legacy metadata, including whitespace/CRLF and missing-file coverage, so uninstall no longer parses the file inline.
fc8d7c4 to
64235dc
Compare
|
Let's stage refactors separately from the fixes and stack the branches |
64235dc to
b861972
Compare
|
Done — I split the behavior-neutral |
b861972 to
9dc9972
Compare
Legacy egg-info uninstall consults only
top_level.txt, ignoringinstalled-files.txtandentry_points.txt, so executable and data files that pip removes remain installed. Prefer the contained recorded-file list over recursive top-level removal (preserving shared namespaces), remove matching bytecode and console/GUI launchers without validating irrelevant target syntax, and protect core environment files while preflighting deletion. This retains the egg-uninstall safety work in uv#19114 and uv#19340 and follows pip's legacy uninstall.Moved to: astral-sh/uv-dev#223.