Skip to content

Commit

Permalink
Respect exclusions in uv init (#5318)
Browse files Browse the repository at this point in the history
## Summary

Avoid adding to the workspace.

Closes #5254.
  • Loading branch information
charliermarsh authored Jul 23, 2024
1 parent 13dd885 commit 2f768b8
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 16 deletions.
15 changes: 15 additions & 0 deletions crates/uv-workspace/src/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,21 @@ impl Workspace {
&self.pyproject_toml
}

/// Returns `true` if the path is excluded by the workspace.
pub fn excludes(&self, project_path: &Path) -> Result<bool, WorkspaceError> {
if let Some(workspace) = self
.pyproject_toml
.tool
.as_ref()
.and_then(|tool| tool.uv.as_ref())
.and_then(|uv| uv.workspace.as_ref())
{
is_excluded_from_workspace(project_path, &self.install_path, workspace)
} else {
Ok(false)
}
}

/// Collect the workspace member projects from the `members` and `excludes` entries.
async fn collect_members(
workspace_root: PathBuf,
Expand Down
40 changes: 25 additions & 15 deletions crates/uv/src/commands/project/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,22 +115,32 @@ pub(crate) async fn init(
}

if let Some(workspace) = workspace {
// Add the package to the workspace.
let mut pyproject = PyProjectTomlMut::from_toml(workspace.pyproject_toml())?;
pyproject.add_workspace(path.strip_prefix(workspace.install_path())?)?;

// Save the modified `pyproject.toml`.
fs_err::write(
workspace.install_path().join("pyproject.toml"),
pyproject.to_string(),
)?;
if workspace.excludes(&path)? {
// If the member is excluded by the workspace, ignore it.
writeln!(
printer.stderr(),
"Project `{}` is excluded by workspace `{}`",
name.cyan(),
workspace.install_path().simplified_display().cyan()
)?;
} else {
// Add the package to the workspace.
let mut pyproject = PyProjectTomlMut::from_toml(workspace.pyproject_toml())?;
pyproject.add_workspace(path.strip_prefix(workspace.install_path())?)?;

// Save the modified `pyproject.toml`.
fs_err::write(
workspace.install_path().join("pyproject.toml"),
pyproject.to_string(),
)?;

writeln!(
printer.stderr(),
"Adding `{}` as member of workspace `{}`",
name.cyan(),
workspace.install_path().simplified_display().cyan()
)?;
writeln!(
printer.stderr(),
"Adding `{}` as member of workspace `{}`",
name.cyan(),
workspace.install_path().simplified_display().cyan()
)?;
}
}

match explicit_path {
Expand Down
46 changes: 45 additions & 1 deletion crates/uv/tests/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,7 @@ fn init_virtual_workspace() -> Result<()> {

/// Run `uv init` from within a workspace. The path is already included via `members`.
#[test]
fn init_matches_member() -> Result<()> {
fn init_matches_members() -> Result<()> {
let context = TestContext::new("3.12");

let pyproject_toml = context.temp_dir.child("pyproject.toml");
Expand Down Expand Up @@ -766,3 +766,47 @@ fn init_matches_member() -> Result<()> {

Ok(())
}

/// Run `uv init` from within a workspace. The path is already included via `members`.
#[test]
fn init_matches_exclude() -> Result<()> {
let context = TestContext::new("3.12");

let pyproject_toml = context.temp_dir.child("pyproject.toml");
pyproject_toml.write_str(indoc! {
r"
[tool.uv.workspace]
exclude = ['packages/foo']
members = ['packages/*']
",
})?;

let packages = context.temp_dir.join("packages");
fs_err::create_dir_all(packages)?;

uv_snapshot!(context.filters(), context.init().current_dir(context.temp_dir.join("packages")).arg("foo"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
warning: `uv init` is experimental and may change without warning
Project `foo` is excluded by workspace `[TEMP_DIR]/`
Initialized project `foo` at `[TEMP_DIR]/packages/foo`
"###);

let workspace = fs_err::read_to_string(context.temp_dir.join("pyproject.toml"))?;
insta::with_settings!({
filters => context.filters(),
}, {
assert_snapshot!(
workspace, @r###"
[tool.uv.workspace]
exclude = ['packages/foo']
members = ['packages/*']
"###
);
});

Ok(())
}

0 comments on commit 2f768b8

Please sign in to comment.