From 462a13c45ae97ae6251ef147453a660fc9194897 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Mon, 30 Sep 2024 20:52:56 -0400 Subject: [PATCH] Respect `tool.uv.environments` for legacy virtual workspace roots (#7824) ## Summary Closes https://github.com/astral-sh/uv/issues/7821. --- crates/uv-workspace/src/workspace.rs | 32 +----- crates/uv/tests/lock.rs | 164 +++++++++++++++++++++++++++ 2 files changed, 169 insertions(+), 27 deletions(-) diff --git a/crates/uv-workspace/src/workspace.rs b/crates/uv-workspace/src/workspace.rs index b135cbdd0e10..cfee93771027 100644 --- a/crates/uv-workspace/src/workspace.rs +++ b/crates/uv-workspace/src/workspace.rs @@ -343,16 +343,8 @@ impl Workspace { /// Returns the set of overrides for the workspace. pub fn overrides(&self) -> Vec { - let Some(workspace_package) = self - .packages - .values() - .find(|workspace_package| workspace_package.root() == self.install_path()) - else { - return vec![]; - }; - - let Some(overrides) = workspace_package - .pyproject_toml() + let Some(overrides) = self + .pyproject_toml .tool .as_ref() .and_then(|tool| tool.uv.as_ref()) @@ -375,13 +367,7 @@ impl Workspace { /// Returns the set of supported environments for the workspace. pub fn environments(&self) -> Option<&SupportedEnvironments> { - let workspace_package = self - .packages - .values() - .find(|workspace_package| workspace_package.root() == self.install_path())?; - - workspace_package - .pyproject_toml() + self.pyproject_toml .tool .as_ref() .and_then(|tool| tool.uv.as_ref()) @@ -390,16 +376,8 @@ impl Workspace { /// Returns the set of constraints for the workspace. pub fn constraints(&self) -> Vec { - let Some(workspace_package) = self - .packages - .values() - .find(|workspace_package| workspace_package.root() == self.install_path()) - else { - return vec![]; - }; - - let Some(constraints) = workspace_package - .pyproject_toml() + let Some(constraints) = self + .pyproject_toml .tool .as_ref() .and_then(|tool| tool.uv.as_ref()) diff --git a/crates/uv/tests/lock.rs b/crates/uv/tests/lock.rs index bbc35396e7b0..a8686abd641f 100644 --- a/crates/uv/tests/lock.rs +++ b/crates/uv/tests/lock.rs @@ -10927,6 +10927,170 @@ fn lock_constrained_environment() -> Result<()> { Ok(()) } +/// Lock with a user-provided constraint on the space of supported environments, using a legacy +/// virtual workspace root. +#[test] +fn lock_constrained_environment_legacy() -> Result<()> { + let context = TestContext::new("3.12"); + + let pyproject_toml = context.temp_dir.child("pyproject.toml"); + pyproject_toml.write_str( + r#" + [tool.uv.workspace] + members = ["child"] + + [tool.uv] + environments = "platform_system != 'Windows'" + "#, + )?; + + let child = context.temp_dir.child("child"); + child.child("pyproject.toml").write_str( + r#" + [project] + name = "child" + version = "0.1.0" + requires-python = ">=3.12" + dependencies = ["black"] + "#, + )?; + + uv_snapshot!(context.filters(), context.lock(), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 7 packages in [TIME] + "###); + + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + + // Because we're _not_ locking for Windows, `colorama` should not be included. + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" + resolution-markers = [ + "platform_system != 'Windows'", + ] + supported-markers = [ + "platform_system != 'Windows'", + ] + + [options] + exclude-newer = "2024-03-25T00:00:00Z" + + [manifest] + members = [ + "child", + ] + + [[package]] + name = "black" + version = "24.3.0" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "click", marker = "platform_system != 'Windows'" }, + { name = "mypy-extensions", marker = "platform_system != 'Windows'" }, + { name = "packaging", marker = "platform_system != 'Windows'" }, + { name = "pathspec", marker = "platform_system != 'Windows'" }, + { name = "platformdirs", marker = "platform_system != 'Windows'" }, + ] + sdist = { url = "https://files.pythonhosted.org/packages/8f/5f/bac24a952668c7482cfdb4ebf91ba57a796c9da8829363a772040c1a3312/black-24.3.0.tar.gz", hash = "sha256:a0c9c4a0771afc6919578cec71ce82a3e31e054904e7197deacbc9382671c41f", size = 634292 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/b6/c6/1d174efa9ff02b22d0124c73fc5f4d4fb006d0d9a081aadc354d05754a13/black-24.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:2818cf72dfd5d289e48f37ccfa08b460bf469e67fb7c4abb07edc2e9f16fb63f", size = 1600822 }, + { url = "https://files.pythonhosted.org/packages/d9/ed/704731afffe460b8ff0672623b40fce9fe569f2ee617c15857e4d4440a3a/black-24.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4acf672def7eb1725f41f38bf6bf425c8237248bb0804faa3965c036f7672d11", size = 1429987 }, + { url = "https://files.pythonhosted.org/packages/a8/05/8dd038e30caadab7120176d4bc109b7ca2f4457f12eef746b0560a583458/black-24.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7ed6668cbbfcd231fa0dc1b137d3e40c04c7f786e626b405c62bcd5db5857e4", size = 1755319 }, + { url = "https://files.pythonhosted.org/packages/4d/ea/31770a7e49f3eedfd8cd7b35e78b3a3aaad860400f8673994bc988318135/black-24.3.0-py3-none-any.whl", hash = "sha256:41622020d7120e01d377f74249e677039d20e6344ff5851de8a10f11f513bf93", size = 201493 }, + ] + + [[package]] + name = "child" + version = "0.1.0" + source = { virtual = "child" } + dependencies = [ + { name = "black", marker = "platform_system != 'Windows'" }, + ] + + [package.metadata] + requires-dist = [{ name = "black" }] + + [[package]] + name = "click" + version = "8.1.7" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941 }, + ] + + [[package]] + name = "mypy-extensions" + version = "1.0.0" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782", size = 4433 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695 }, + ] + + [[package]] + name = "packaging" + version = "24.0" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/ee/b5/b43a27ac7472e1818c4bafd44430e69605baefe1f34440593e0332ec8b4d/packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9", size = 147882 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/49/df/1fceb2f8900f8639e278b056416d49134fb8d84c5942ffaa01ad34782422/packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", size = 53488 }, + ] + + [[package]] + name = "pathspec" + version = "0.12.1" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191 }, + ] + + [[package]] + name = "platformdirs" + version = "4.2.0" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/96/dc/c1d911bf5bb0fdc58cc05010e9f3efe3b67970cef779ba7fbc3183b987a8/platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768", size = 20055 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/55/72/4898c44ee9ea6f43396fbc23d9bfaf3d06e01b83698bdf2e4c919deceb7c/platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068", size = 17717 }, + ] + "### + ); + }); + + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 7 packages in [TIME] + "###); + + // Re-run with `--offline`. We shouldn't need a network connection to validate an + // already-correct lockfile with immutable metadata. + uv_snapshot!(context.filters(), context.lock().arg("--locked").arg("--offline").arg("--no-cache"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 7 packages in [TIME] + "###); + + Ok(()) +} + /// User-provided constraints must be disjoint. #[test] fn lock_overlapping_environment() -> Result<()> {