diff --git a/rye/src/lock.rs b/rye/src/lock.rs index 5348ebf524..1f3bd64113 100644 --- a/rye/src/lock.rs +++ b/rye/src/lock.rs @@ -479,29 +479,34 @@ fn finalize_lockfile( .lines() { // we deal with this explicitly. - if line.trim().is_empty() + let line = line.trim(); + if line.is_empty() || line.starts_with("--index-url ") || line.starts_with("--extra-index-url ") || line.starts_with("--find-links ") + || line.starts_with("--hash=") { continue; } + // Strip trailing backslashes. + let line = line.strip_suffix('\\').unwrap_or(line); + if let Some(m) = FILE_EDITABLE_RE.captures(line) { let url = Url::parse(&m[1]).context("invalid editable URL generated")?; if url.scheme() == "file" { let rel_url = make_relative_url(Path::new(url.path()), workspace_root)?; - writeln!(rv, "-e {}", rel_url)?; + writeln!(rv, "-e {rel_url}")?; continue; } - } else if let Ok(ref req) = line.trim().parse::() { + } else if let Ok(ref req) = line.parse::() { // TODO: this does not evaluate markers if exclusions.iter().any(|x| { normalize_package_name(&x.name) == normalize_package_name(&req.name) && (x.version_or_url.is_none() || x.version_or_url == req.version_or_url) }) { // skip exclusions - writeln!(rv, "# {} (excluded)", line)?; + writeln!(rv, "# {line} (excluded)")?; continue; } } else if let Some(m) = DEP_COMMENT_RE.captures(line) { @@ -510,14 +515,14 @@ fn finalize_lockfile( // we cannot tell today based on the output where this comes from. This // can show up because it's a root dependency, because it's a dev dependency // or in some cases just because we declared it as a duplicate. - writeln!(rv, " # via {}", dep)?; + writeln!(rv, " # via {dep}")?; } }; continue; } else if line.starts_with('#') { continue; } - writeln!(rv, "{}", line)?; + writeln!(rv, "{line}")?; } Ok(()) } diff --git a/rye/tests/test_sync.rs b/rye/tests/test_sync.rs index 74c8fdcc13..f4989e136e 100644 --- a/rye/tests/test_sync.rs +++ b/rye/tests/test_sync.rs @@ -261,3 +261,55 @@ fn test_autosync_remember() { werkzeug==3.0.1 "###); } + +#[test] +fn test_exclude_hashes() { + let space = Space::new(); + space.init("my-project"); + + fs::write( + space.project_path().join("pyproject.toml"), + r###" + [project] + name = "exclude-rye-test" + version = "0.1.0" + dependencies = ["jinja2"] + readme = "README.md" + requires-python = ">= 3.8" + + [build-system] + requires = ["hatchling"] + build-backend = "hatchling.build" + + [tool.rye] + generate-hashes = true + excluded-dependencies = ["markupsafe"] + + [tool.hatch.metadata] + allow-direct-references = true + + [tool.hatch.build.targets.wheel] + packages = ["src/exclude_rye_test"] + "###, + ) + .unwrap(); + + rye_cmd_snapshot!(space.rye_cmd().arg("sync"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + Initializing new virtualenv in [TEMP_PATH]/project/.venv + Python version: cpython@3.12.3 + Generating production lockfile: [TEMP_PATH]/project/requirements.lock + Generating dev lockfile: [TEMP_PATH]/project/requirements-dev.lock + Installing dependencies + Done! + + ----- stderr ----- + Resolved 2 packages in [EXECUTION_TIME] + Prepared 2 packages in [EXECUTION_TIME] + Installed 2 packages in [EXECUTION_TIME] + + exclude-rye-test==0.1.0 (from file:[TEMP_PATH]/project) + + jinja2==3.1.2 + "###); +}