Skip to content

Commit 98bcecf

Browse files
Add tests, clean up, doc string
Signed-off-by: Mikayla Thompson <[email protected]>
1 parent aaca6e5 commit 98bcecf

File tree

5 files changed

+153
-8
lines changed

5 files changed

+153
-8
lines changed

crates/uv-cli/src/lib.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6853,15 +6853,17 @@ pub enum WorkspaceCommand {
68536853
/// Display package metadata.
68546854
#[command(hide = true)]
68556855
Metadata(MetadataArgs),
6856+
/// Display path to workspace root or member packages.
68566857
#[command(hide = true)]
6857-
Dir(DirArgs)
6858+
Dir(WorkspaceDirArgs)
68586859
}
68596860

68606861
#[derive(Args, Debug)]
68616862
pub struct MetadataArgs;
68626863

68636864
#[derive(Args, Debug)]
6864-
pub struct DirArgs {
6865+
pub struct WorkspaceDirArgs {
6866+
#[arg(long)]
68656867
pub package: Option<PackageName>
68666868
}
68676869

crates/uv/src/commands/workspace/dir.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::path::Path;
33

44
use anyhow::{Result, bail};
55

6-
use uv_cli::DirArgs;
6+
use uv_cli::WorkspaceDirArgs;
77
use uv_fs::{PortablePathBuf};
88
use uv_preview::{Preview, PreviewFeatures};
99
use uv_warnings::warn_user;
@@ -14,7 +14,7 @@ use crate::printer::Printer;
1414

1515
/// Print the path to the workspace dir
1616
pub(crate) async fn dir(
17-
args: &DirArgs,
17+
args: &WorkspaceDirArgs,
1818
project_dir: &Path,
1919
preview: Preview,
2020
printer: Printer,
@@ -35,18 +35,17 @@ pub(crate) async fn dir(
3535
PortablePathBuf::from(workspace.install_path().as_path()).to_string()
3636
},
3737
Some(package) => {
38-
if let Some(p) = workspace.packages().get(&package) {
38+
if let Some(p) = workspace.packages().get(package) {
3939
PortablePathBuf::from(p.root().as_path()).to_string()
4040
} else {
41-
bail!("Package {} does not exist.", package)
41+
bail!("Package `{package}` not found in workspace.")
4242
}
4343
}
4444
};
4545

4646
writeln!(
4747
printer.stdout(),
48-
"{}",
49-
dir
48+
"{dir}"
5049
)?;
5150

5251
Ok(ExitStatus::Success)

crates/uv/tests/it/common/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,6 +1072,14 @@ impl TestContext {
10721072
command
10731073
}
10741074

1075+
/// Create a `uv workspace dir` command with options shared across scenarios.
1076+
pub fn workspace_dir(&self) -> Command {
1077+
let mut command = Self::new_command();
1078+
command.arg("workspace").arg("dir");
1079+
self.add_shared_options(&mut command, false);
1080+
command
1081+
}
1082+
10751083
/// Create a `uv export` command with options shared across scenarios.
10761084
pub fn export(&self) -> Command {
10771085
let mut command = Self::new_command();

crates/uv/tests/it/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,4 @@ mod workflow;
142142
mod extract;
143143
mod workspace;
144144
mod workspace_metadata;
145+
mod workspace_dir;
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
use std::env;
2+
use std::path::PathBuf;
3+
4+
use anyhow::Result;
5+
use assert_cmd::assert::OutputAssertExt;
6+
use assert_fs::fixture::PathChild;
7+
8+
use crate::common::{TestContext, copy_dir_ignore, uv_snapshot};
9+
10+
fn workspaces_dir() -> PathBuf {
11+
env::current_dir()
12+
.unwrap()
13+
.parent()
14+
.unwrap()
15+
.parent()
16+
.unwrap()
17+
.join("scripts")
18+
.join("workspaces")
19+
}
20+
21+
/// Test basic output for a simple workspace with one member.
22+
#[test]
23+
fn workspace_dir_simple() {
24+
let context = TestContext::new("3.12");
25+
26+
// Initialize a workspace with one member
27+
context.init().arg("foo").assert().success();
28+
29+
let workspace = context.temp_dir.child("foo");
30+
31+
uv_snapshot!(context.filters(), context.workspace_dir().current_dir(&workspace), @r###"
32+
success: true
33+
exit_code: 0
34+
----- stdout -----
35+
[TEMP_DIR]/foo
36+
37+
----- stderr -----
38+
"###
39+
);
40+
}
41+
42+
// Workspace dir output when run with `--package`
43+
#[test]
44+
fn workspace_dir_specific_package() {
45+
let context = TestContext::new("3.12");
46+
context.init().arg("foo").assert().success();
47+
context.init().arg("foo/bar").assert().success();
48+
let workspace = context.temp_dir.child("foo");
49+
50+
// root workspace
51+
uv_snapshot!(context.filters(), context.workspace_dir().current_dir(&workspace), @r###"
52+
success: true
53+
exit_code: 0
54+
----- stdout -----
55+
[TEMP_DIR]/foo
56+
57+
----- stderr -----
58+
"###
59+
);
60+
61+
// with --package bar
62+
uv_snapshot!(context.filters(), context.workspace_dir().arg("--package").arg("bar").current_dir(&workspace), @r###"
63+
success: true
64+
exit_code: 0
65+
----- stdout -----
66+
[TEMP_DIR]/foo/bar
67+
68+
----- stderr -----
69+
"###
70+
);
71+
}
72+
73+
74+
/// Test output when run from a workspace member directory.
75+
#[test]
76+
fn workspace_metadata_from_member() -> Result<()> {
77+
let context = TestContext::new("3.12");
78+
let workspace = context.temp_dir.child("workspace");
79+
80+
copy_dir_ignore(
81+
workspaces_dir().join("albatross-root-workspace"),
82+
&workspace,
83+
)?;
84+
85+
let member_dir = workspace.join("packages").join("bird-feeder");
86+
87+
uv_snapshot!(context.filters(), context.workspace_dir().current_dir(&member_dir), @r###"
88+
success: true
89+
exit_code: 0
90+
----- stdout -----
91+
[TEMP_DIR]/workspace
92+
93+
----- stderr -----
94+
"###
95+
);
96+
97+
Ok(())
98+
}
99+
100+
/// Test workspace dir error output for a non-existent package.
101+
#[test]
102+
fn workspace_dir_package_doesnt_exist() {
103+
let context = TestContext::new("3.12");
104+
105+
// Initialize a workspace with one member
106+
context.init().arg("foo").assert().success();
107+
108+
let workspace = context.temp_dir.child("foo");
109+
110+
uv_snapshot!(context.filters(), context.workspace_dir().arg("--package").arg("bar").current_dir(&workspace), @r###"
111+
success: false
112+
exit_code: 2
113+
----- stdout -----
114+
115+
----- stderr -----
116+
error: Package `bar` not found in workspace.
117+
"###
118+
);
119+
}
120+
121+
/// Test workspace dir error ouptut when not in a project.
122+
#[test]
123+
fn workspace_metadata_no_project() {
124+
let context = TestContext::new("3.12");
125+
126+
uv_snapshot!(context.filters(), context.workspace_dir(), @r###"
127+
success: false
128+
exit_code: 2
129+
----- stdout -----
130+
131+
----- stderr -----
132+
error: No `pyproject.toml` found in current directory or any parent directory
133+
"###
134+
);
135+
}

0 commit comments

Comments
 (0)