mirror of https://github.com/astral-sh/uv
Add `uv workspace metadata`
This commit is contained in:
parent
a1610c794e
commit
052b89d733
|
|
@ -517,6 +517,12 @@ pub enum Commands {
|
|||
Build(BuildArgs),
|
||||
/// Upload distributions to an index.
|
||||
Publish(PublishArgs),
|
||||
/// Manage workspaces.
|
||||
#[command(
|
||||
after_help = "Use `uv help workspace` for more details.",
|
||||
after_long_help = ""
|
||||
)]
|
||||
Workspace(WorkspaceNamespace),
|
||||
/// The implementation of the build backend.
|
||||
///
|
||||
/// These commands are not directly exposed to the user, instead users invoke their build
|
||||
|
|
@ -6773,6 +6779,21 @@ pub struct PublishArgs {
|
|||
pub dry_run: bool,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct WorkspaceNamespace {
|
||||
#[command(subcommand)]
|
||||
pub command: WorkspaceCommand,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
pub enum WorkspaceCommand {
|
||||
/// Display package metadata.
|
||||
Metadata(MetadataArgs),
|
||||
}
|
||||
|
||||
#[derive(Args, Debug)]
|
||||
pub struct MetadataArgs;
|
||||
|
||||
/// See [PEP 517](https://peps.python.org/pep-0517/) and
|
||||
/// [PEP 660](https://peps.python.org/pep-0660/) for specifications of the parameters.
|
||||
#[derive(Subcommand)]
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ bitflags::bitflags! {
|
|||
const FORMAT = 1 << 8;
|
||||
const NATIVE_AUTH = 1 << 9;
|
||||
const S3_ENDPOINT = 1 << 10;
|
||||
const WORKSPACE_METADATA = 1 << 11;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -40,6 +41,7 @@ impl PreviewFeatures {
|
|||
Self::FORMAT => "format",
|
||||
Self::NATIVE_AUTH => "native-auth",
|
||||
Self::S3_ENDPOINT => "s3-endpoint",
|
||||
Self::WORKSPACE_METADATA => "workspace-metadata",
|
||||
_ => panic!("`flag_as_str` can only be used for exactly one feature flag"),
|
||||
}
|
||||
}
|
||||
|
|
@ -88,6 +90,7 @@ impl FromStr for PreviewFeatures {
|
|||
"format" => Self::FORMAT,
|
||||
"native-auth" => Self::NATIVE_AUTH,
|
||||
"s3-endpoint" => Self::S3_ENDPOINT,
|
||||
"workspace-metadata" => Self::WORKSPACE_METADATA,
|
||||
_ => {
|
||||
warn_user_once!("Unknown preview feature: `{part}`");
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ use uv_normalize::PackageName;
|
|||
use uv_python::PythonEnvironment;
|
||||
use uv_scripts::Pep723Script;
|
||||
pub(crate) use venv::venv;
|
||||
pub(crate) use workspace::metadata::metadata;
|
||||
|
||||
use crate::printer::Printer;
|
||||
|
||||
|
|
@ -86,6 +87,7 @@ pub(crate) mod reporters;
|
|||
mod self_update;
|
||||
mod tool;
|
||||
mod venv;
|
||||
mod workspace;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub(crate) enum ExitStatus {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,91 @@
|
|||
use std::fmt::Write;
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::Result;
|
||||
use serde::Serialize;
|
||||
|
||||
use uv_fs::PortablePathBuf;
|
||||
use uv_normalize::PackageName;
|
||||
use uv_preview::{Preview, PreviewFeatures};
|
||||
use uv_warnings::warn_user;
|
||||
use uv_workspace::{DiscoveryOptions, Workspace, WorkspaceCache};
|
||||
|
||||
use crate::commands::ExitStatus;
|
||||
use crate::printer::Printer;
|
||||
|
||||
/// The schema version for the metadata report.
|
||||
#[derive(Serialize, Debug, Default)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
enum SchemaVersion {
|
||||
/// An unstable, experimental schema.
|
||||
#[default]
|
||||
Preview,
|
||||
}
|
||||
|
||||
/// The schema metadata for the metadata report.
|
||||
#[derive(Serialize, Debug, Default)]
|
||||
struct SchemaReport {
|
||||
/// The version of the schema.
|
||||
version: SchemaVersion,
|
||||
}
|
||||
|
||||
/// Report for a single workspace member.
|
||||
#[derive(Serialize, Debug)]
|
||||
struct WorkspaceMemberReport {
|
||||
/// The name of the workspace member.
|
||||
name: PackageName,
|
||||
/// The path to the workspace member's root directory.
|
||||
path: PortablePathBuf,
|
||||
}
|
||||
|
||||
/// The report for a metadata operation.
|
||||
#[derive(Serialize, Debug)]
|
||||
struct MetadataReport {
|
||||
/// The schema of this report.
|
||||
schema: SchemaReport,
|
||||
/// The workspace root directory.
|
||||
workspace_root: PortablePathBuf,
|
||||
/// The workspace members.
|
||||
members: Vec<WorkspaceMemberReport>,
|
||||
}
|
||||
|
||||
/// Display package metadata.
|
||||
pub(crate) async fn metadata(
|
||||
project_dir: &Path,
|
||||
preview: Preview,
|
||||
printer: Printer,
|
||||
) -> Result<ExitStatus> {
|
||||
if preview.is_enabled(PreviewFeatures::WORKSPACE_METADATA) {
|
||||
warn_user!(
|
||||
"The `uv workspace metadata` command is experimental and may change without warning. Pass `--preview-features {}` to disable this warning.",
|
||||
PreviewFeatures::WORKSPACE_METADATA
|
||||
);
|
||||
}
|
||||
|
||||
let workspace_cache = WorkspaceCache::default();
|
||||
let workspace =
|
||||
Workspace::discover(project_dir, &DiscoveryOptions::default(), &workspace_cache).await?;
|
||||
|
||||
let members = workspace
|
||||
.packages()
|
||||
.values()
|
||||
.map(|package| WorkspaceMemberReport {
|
||||
name: package.project().name.clone(),
|
||||
path: PortablePathBuf::from(package.root().as_path()),
|
||||
})
|
||||
.collect();
|
||||
|
||||
let report = MetadataReport {
|
||||
schema: SchemaReport::default(),
|
||||
workspace_root: PortablePathBuf::from(workspace.install_path().as_path()),
|
||||
members,
|
||||
};
|
||||
|
||||
writeln!(
|
||||
printer.stdout(),
|
||||
"{}",
|
||||
serde_json::to_string_pretty(&report)?
|
||||
)?;
|
||||
|
||||
Ok(ExitStatus::Success)
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
pub(crate) mod metadata;
|
||||
|
|
@ -26,7 +26,8 @@ use uv_cli::SelfUpdateArgs;
|
|||
use uv_cli::{
|
||||
AuthCommand, AuthNamespace, BuildBackendCommand, CacheCommand, CacheNamespace, Cli, Commands,
|
||||
PipCommand, PipNamespace, ProjectCommand, PythonCommand, PythonNamespace, SelfCommand,
|
||||
SelfNamespace, ToolCommand, ToolNamespace, TopLevelArgs, compat::CompatArgs,
|
||||
SelfNamespace, ToolCommand, ToolNamespace, TopLevelArgs, WorkspaceCommand, WorkspaceNamespace,
|
||||
compat::CompatArgs,
|
||||
};
|
||||
use uv_client::BaseClientBuilder;
|
||||
use uv_configuration::min_stack_size;
|
||||
|
|
@ -1709,6 +1710,11 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
|||
)
|
||||
.await
|
||||
}
|
||||
Commands::Workspace(WorkspaceNamespace { command }) => match command {
|
||||
WorkspaceCommand::Metadata(_args) => {
|
||||
commands::metadata(&project_dir, globals.preview, printer).await
|
||||
}
|
||||
},
|
||||
Commands::BuildBackend { command } => spawn_blocking(move || match command {
|
||||
BuildBackendCommand::BuildSdist { sdist_directory } => {
|
||||
commands::build_backend::build_sdist(&sdist_directory)
|
||||
|
|
|
|||
|
|
@ -1050,6 +1050,14 @@ impl TestContext {
|
|||
command
|
||||
}
|
||||
|
||||
/// Create a `uv workspace metadata` command with options shared across scenarios.
|
||||
pub fn workspace_metadata(&self) -> Command {
|
||||
let mut command = Self::new_command();
|
||||
command.arg("workspace").arg("metadata");
|
||||
self.add_shared_options(&mut command, false);
|
||||
command
|
||||
}
|
||||
|
||||
/// Create a `uv export` command with options shared across scenarios.
|
||||
pub fn export(&self) -> Command {
|
||||
let mut command = Self::new_command();
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ fn help() {
|
|||
venv Create a virtual environment
|
||||
build Build Python packages into source distributions and wheels
|
||||
publish Upload distributions to an index
|
||||
workspace Manage workspaces
|
||||
cache Manage uv's cache
|
||||
self Manage the uv executable
|
||||
generate-shell-completion Generate shell completion
|
||||
|
|
@ -98,26 +99,27 @@ fn help_flag() {
|
|||
Usage: uv [OPTIONS] <COMMAND>
|
||||
|
||||
Commands:
|
||||
auth Manage authentication
|
||||
run Run a command or script
|
||||
init Create a new project
|
||||
add Add dependencies to the project
|
||||
remove Remove dependencies from the project
|
||||
version Read or update the project's version
|
||||
sync Update the project's environment
|
||||
lock Update the project's lockfile
|
||||
export Export the project's lockfile to an alternate format
|
||||
tree Display the project's dependency tree
|
||||
format Format Python code in the project
|
||||
tool Run and install commands provided by Python packages
|
||||
python Manage Python versions and installations
|
||||
pip Manage Python packages with a pip-compatible interface
|
||||
venv Create a virtual environment
|
||||
build Build Python packages into source distributions and wheels
|
||||
publish Upload distributions to an index
|
||||
cache Manage uv's cache
|
||||
self Manage the uv executable
|
||||
help Display documentation for a command
|
||||
auth Manage authentication
|
||||
run Run a command or script
|
||||
init Create a new project
|
||||
add Add dependencies to the project
|
||||
remove Remove dependencies from the project
|
||||
version Read or update the project's version
|
||||
sync Update the project's environment
|
||||
lock Update the project's lockfile
|
||||
export Export the project's lockfile to an alternate format
|
||||
tree Display the project's dependency tree
|
||||
format Format Python code in the project
|
||||
tool Run and install commands provided by Python packages
|
||||
python Manage Python versions and installations
|
||||
pip Manage Python packages with a pip-compatible interface
|
||||
venv Create a virtual environment
|
||||
build Build Python packages into source distributions and wheels
|
||||
publish Upload distributions to an index
|
||||
workspace Manage workspaces
|
||||
cache Manage uv's cache
|
||||
self Manage the uv executable
|
||||
help Display documentation for a command
|
||||
|
||||
Cache options:
|
||||
-n, --no-cache Avoid reading from or writing to the cache, instead using a temporary
|
||||
|
|
@ -178,26 +180,27 @@ fn help_short_flag() {
|
|||
Usage: uv [OPTIONS] <COMMAND>
|
||||
|
||||
Commands:
|
||||
auth Manage authentication
|
||||
run Run a command or script
|
||||
init Create a new project
|
||||
add Add dependencies to the project
|
||||
remove Remove dependencies from the project
|
||||
version Read or update the project's version
|
||||
sync Update the project's environment
|
||||
lock Update the project's lockfile
|
||||
export Export the project's lockfile to an alternate format
|
||||
tree Display the project's dependency tree
|
||||
format Format Python code in the project
|
||||
tool Run and install commands provided by Python packages
|
||||
python Manage Python versions and installations
|
||||
pip Manage Python packages with a pip-compatible interface
|
||||
venv Create a virtual environment
|
||||
build Build Python packages into source distributions and wheels
|
||||
publish Upload distributions to an index
|
||||
cache Manage uv's cache
|
||||
self Manage the uv executable
|
||||
help Display documentation for a command
|
||||
auth Manage authentication
|
||||
run Run a command or script
|
||||
init Create a new project
|
||||
add Add dependencies to the project
|
||||
remove Remove dependencies from the project
|
||||
version Read or update the project's version
|
||||
sync Update the project's environment
|
||||
lock Update the project's lockfile
|
||||
export Export the project's lockfile to an alternate format
|
||||
tree Display the project's dependency tree
|
||||
format Format Python code in the project
|
||||
tool Run and install commands provided by Python packages
|
||||
python Manage Python versions and installations
|
||||
pip Manage Python packages with a pip-compatible interface
|
||||
venv Create a virtual environment
|
||||
build Build Python packages into source distributions and wheels
|
||||
publish Upload distributions to an index
|
||||
workspace Manage workspaces
|
||||
cache Manage uv's cache
|
||||
self Manage the uv executable
|
||||
help Display documentation for a command
|
||||
|
||||
Cache options:
|
||||
-n, --no-cache Avoid reading from or writing to the cache, instead using a temporary
|
||||
|
|
@ -892,6 +895,7 @@ fn help_unknown_subcommand() {
|
|||
venv
|
||||
build
|
||||
publish
|
||||
workspace
|
||||
cache
|
||||
self
|
||||
generate-shell-completion
|
||||
|
|
@ -921,6 +925,7 @@ fn help_unknown_subcommand() {
|
|||
venv
|
||||
build
|
||||
publish
|
||||
workspace
|
||||
cache
|
||||
self
|
||||
generate-shell-completion
|
||||
|
|
@ -979,6 +984,7 @@ fn help_with_global_option() {
|
|||
venv Create a virtual environment
|
||||
build Build Python packages into source distributions and wheels
|
||||
publish Upload distributions to an index
|
||||
workspace Manage workspaces
|
||||
cache Manage uv's cache
|
||||
self Manage the uv executable
|
||||
generate-shell-completion Generate shell completion
|
||||
|
|
@ -1102,6 +1108,7 @@ fn help_with_no_pager() {
|
|||
venv Create a virtual environment
|
||||
build Build Python packages into source distributions and wheels
|
||||
publish Upload distributions to an index
|
||||
workspace Manage workspaces
|
||||
cache Manage uv's cache
|
||||
self Manage the uv executable
|
||||
generate-shell-completion Generate shell completion
|
||||
|
|
|
|||
|
|
@ -138,3 +138,4 @@ mod workflow;
|
|||
|
||||
mod extract;
|
||||
mod workspace;
|
||||
mod workspace_metadata;
|
||||
|
|
|
|||
|
|
@ -7760,7 +7760,7 @@ fn preview_features() {
|
|||
show_settings: true,
|
||||
preview: Preview {
|
||||
flags: PreviewFeatures(
|
||||
PYTHON_INSTALL_DEFAULT | PYTHON_UPGRADE | JSON_OUTPUT | PYLOCK | ADD_BOUNDS | PACKAGE_CONFLICTS | EXTRA_BUILD_DEPENDENCIES | DETECT_MODULE_CONFLICTS | FORMAT | NATIVE_AUTH | S3_ENDPOINT,
|
||||
PYTHON_INSTALL_DEFAULT | PYTHON_UPGRADE | JSON_OUTPUT | PYLOCK | ADD_BOUNDS | PACKAGE_CONFLICTS | EXTRA_BUILD_DEPENDENCIES | DETECT_MODULE_CONFLICTS | FORMAT | NATIVE_AUTH | S3_ENDPOINT | WORKSPACE_METADATA,
|
||||
),
|
||||
},
|
||||
python_preference: Managed,
|
||||
|
|
@ -7988,7 +7988,7 @@ fn preview_features() {
|
|||
show_settings: true,
|
||||
preview: Preview {
|
||||
flags: PreviewFeatures(
|
||||
PYTHON_INSTALL_DEFAULT | PYTHON_UPGRADE | JSON_OUTPUT | PYLOCK | ADD_BOUNDS | PACKAGE_CONFLICTS | EXTRA_BUILD_DEPENDENCIES | DETECT_MODULE_CONFLICTS | FORMAT | NATIVE_AUTH | S3_ENDPOINT,
|
||||
PYTHON_INSTALL_DEFAULT | PYTHON_UPGRADE | JSON_OUTPUT | PYLOCK | ADD_BOUNDS | PACKAGE_CONFLICTS | EXTRA_BUILD_DEPENDENCIES | DETECT_MODULE_CONFLICTS | FORMAT | NATIVE_AUTH | S3_ENDPOINT | WORKSPACE_METADATA,
|
||||
),
|
||||
},
|
||||
python_preference: Managed,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,319 @@
|
|||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use anyhow::Result;
|
||||
use assert_cmd::assert::OutputAssertExt;
|
||||
use assert_fs::fixture::PathChild;
|
||||
|
||||
use crate::common::{TestContext, copy_dir_ignore, uv_snapshot};
|
||||
|
||||
fn workspaces_dir() -> PathBuf {
|
||||
env::current_dir()
|
||||
.unwrap()
|
||||
.parent()
|
||||
.unwrap()
|
||||
.parent()
|
||||
.unwrap()
|
||||
.join("scripts")
|
||||
.join("workspaces")
|
||||
}
|
||||
|
||||
/// Test basic metadata output for a simple workspace with one member.
|
||||
#[test]
|
||||
fn workspace_metadata_simple() {
|
||||
let context = TestContext::new("3.12");
|
||||
|
||||
// Initialize a workspace with one member
|
||||
context.init().arg("foo").assert().success();
|
||||
|
||||
let workspace = context.temp_dir.child("foo");
|
||||
|
||||
uv_snapshot!(context.filters(), context.workspace_metadata().current_dir(&workspace), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
{
|
||||
"schema": {
|
||||
"version": "preview"
|
||||
},
|
||||
"workspace_root": "[TEMP_DIR]/foo",
|
||||
"members": [
|
||||
{
|
||||
"name": "foo",
|
||||
"path": "[TEMP_DIR]/foo"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
----- stderr -----
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
||||
/// Test metadata for a root workspace (workspace with a root package).
|
||||
#[test]
|
||||
fn workspace_metadata_root_workspace() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
let workspace = context.temp_dir.child("workspace");
|
||||
|
||||
copy_dir_ignore(
|
||||
workspaces_dir().join("albatross-root-workspace"),
|
||||
&workspace,
|
||||
)?;
|
||||
|
||||
uv_snapshot!(context.filters(), context.workspace_metadata().current_dir(&workspace), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
{
|
||||
"schema": {
|
||||
"version": "preview"
|
||||
},
|
||||
"workspace_root": "[TEMP_DIR]/workspace",
|
||||
"members": [
|
||||
{
|
||||
"name": "albatross",
|
||||
"path": "[TEMP_DIR]/workspace"
|
||||
},
|
||||
{
|
||||
"name": "bird-feeder",
|
||||
"path": "[TEMP_DIR]/workspace/packages/bird-feeder"
|
||||
},
|
||||
{
|
||||
"name": "seeds",
|
||||
"path": "[TEMP_DIR]/workspace/packages/seeds"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
----- stderr -----
|
||||
"###
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Test metadata for a virtual workspace (no root package).
|
||||
#[test]
|
||||
fn workspace_metadata_virtual_workspace() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
let workspace = context.temp_dir.child("workspace");
|
||||
|
||||
copy_dir_ignore(
|
||||
workspaces_dir().join("albatross-virtual-workspace"),
|
||||
&workspace,
|
||||
)?;
|
||||
|
||||
uv_snapshot!(context.filters(), context.workspace_metadata().current_dir(&workspace), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
{
|
||||
"schema": {
|
||||
"version": "preview"
|
||||
},
|
||||
"workspace_root": "[TEMP_DIR]/workspace",
|
||||
"members": [
|
||||
{
|
||||
"name": "albatross",
|
||||
"path": "[TEMP_DIR]/workspace/packages/albatross"
|
||||
},
|
||||
{
|
||||
"name": "bird-feeder",
|
||||
"path": "[TEMP_DIR]/workspace/packages/bird-feeder"
|
||||
},
|
||||
{
|
||||
"name": "seeds",
|
||||
"path": "[TEMP_DIR]/workspace/packages/seeds"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
----- stderr -----
|
||||
"###
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Test metadata when run from a workspace member directory.
|
||||
#[test]
|
||||
fn workspace_metadata_from_member() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
let workspace = context.temp_dir.child("workspace");
|
||||
|
||||
copy_dir_ignore(
|
||||
workspaces_dir().join("albatross-root-workspace"),
|
||||
&workspace,
|
||||
)?;
|
||||
|
||||
let member_dir = workspace.join("packages").join("bird-feeder");
|
||||
|
||||
uv_snapshot!(context.filters(), context.workspace_metadata().current_dir(&member_dir), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
{
|
||||
"schema": {
|
||||
"version": "preview"
|
||||
},
|
||||
"workspace_root": "[TEMP_DIR]/workspace",
|
||||
"members": [
|
||||
{
|
||||
"name": "albatross",
|
||||
"path": "[TEMP_DIR]/workspace"
|
||||
},
|
||||
{
|
||||
"name": "bird-feeder",
|
||||
"path": "[TEMP_DIR]/workspace/packages/bird-feeder"
|
||||
},
|
||||
{
|
||||
"name": "seeds",
|
||||
"path": "[TEMP_DIR]/workspace/packages/seeds"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
----- stderr -----
|
||||
"###
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Test metadata for a workspace with multiple packages.
|
||||
#[test]
|
||||
fn workspace_metadata_multiple_members() {
|
||||
let context = TestContext::new("3.12");
|
||||
|
||||
// Initialize workspace root
|
||||
context.init().arg("pkg-a").assert().success();
|
||||
|
||||
let workspace_root = context.temp_dir.child("pkg-a");
|
||||
|
||||
// Add more members
|
||||
context
|
||||
.init()
|
||||
.arg("pkg-b")
|
||||
.current_dir(&workspace_root)
|
||||
.assert()
|
||||
.success();
|
||||
|
||||
context
|
||||
.init()
|
||||
.arg("pkg-c")
|
||||
.current_dir(&workspace_root)
|
||||
.assert()
|
||||
.success();
|
||||
|
||||
uv_snapshot!(context.filters(), context.workspace_metadata().current_dir(&workspace_root), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
{
|
||||
"schema": {
|
||||
"version": "preview"
|
||||
},
|
||||
"workspace_root": "[TEMP_DIR]/pkg-a",
|
||||
"members": [
|
||||
{
|
||||
"name": "pkg-a",
|
||||
"path": "[TEMP_DIR]/pkg-a"
|
||||
},
|
||||
{
|
||||
"name": "pkg-b",
|
||||
"path": "[TEMP_DIR]/pkg-a/pkg-b"
|
||||
},
|
||||
{
|
||||
"name": "pkg-c",
|
||||
"path": "[TEMP_DIR]/pkg-a/pkg-c"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
----- stderr -----
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
||||
/// Test metadata for a single project (not a workspace).
|
||||
#[test]
|
||||
fn workspace_metadata_single_project() {
|
||||
let context = TestContext::new("3.12");
|
||||
|
||||
context.init().arg("my-project").assert().success();
|
||||
|
||||
let project = context.temp_dir.child("my-project");
|
||||
|
||||
uv_snapshot!(context.filters(), context.workspace_metadata().current_dir(&project), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
{
|
||||
"schema": {
|
||||
"version": "preview"
|
||||
},
|
||||
"workspace_root": "[TEMP_DIR]/my-project",
|
||||
"members": [
|
||||
{
|
||||
"name": "my-project",
|
||||
"path": "[TEMP_DIR]/my-project"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
----- stderr -----
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
||||
/// Test metadata with excluded packages.
|
||||
#[test]
|
||||
fn workspace_metadata_with_excluded() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
let workspace = context.temp_dir.child("workspace");
|
||||
|
||||
copy_dir_ignore(
|
||||
workspaces_dir().join("albatross-project-in-excluded"),
|
||||
&workspace,
|
||||
)?;
|
||||
|
||||
uv_snapshot!(context.filters(), context.workspace_metadata().current_dir(&workspace), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
{
|
||||
"schema": {
|
||||
"version": "preview"
|
||||
},
|
||||
"workspace_root": "[TEMP_DIR]/workspace",
|
||||
"members": [
|
||||
{
|
||||
"name": "albatross",
|
||||
"path": "[TEMP_DIR]/workspace"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
----- stderr -----
|
||||
"###
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Test metadata error when not in a project.
|
||||
#[test]
|
||||
fn workspace_metadata_no_project() {
|
||||
let context = TestContext::new("3.12");
|
||||
|
||||
uv_snapshot!(context.filters(), context.workspace_metadata(), @r###"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: No `pyproject.toml` found in current directory or any parent directory
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
|
@ -29,6 +29,7 @@ uv [OPTIONS] <COMMAND>
|
|||
<dt><a href="#uv-venv"><code>uv venv</code></a></dt><dd><p>Create a virtual environment</p></dd>
|
||||
<dt><a href="#uv-build"><code>uv build</code></a></dt><dd><p>Build Python packages into source distributions and wheels</p></dd>
|
||||
<dt><a href="#uv-publish"><code>uv publish</code></a></dt><dd><p>Upload distributions to an index</p></dd>
|
||||
<dt><a href="#uv-workspace"><code>uv workspace</code></a></dt><dd><p>Manage workspaces</p></dd>
|
||||
<dt><a href="#uv-cache"><code>uv cache</code></a></dt><dd><p>Manage uv's cache</p></dd>
|
||||
<dt><a href="#uv-self"><code>uv self</code></a></dt><dd><p>Manage the uv executable</p></dd>
|
||||
<dt><a href="#uv-help"><code>uv help</code></a></dt><dd><p>Display documentation for a command</p></dd>
|
||||
|
|
@ -5898,6 +5899,79 @@ uv publish --publish-url https://upload.pypi.org/legacy/ --check-url https://pyp
|
|||
<p>You can configure fine-grained logging using the <code>RUST_LOG</code> environment variable. (<a href="https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#directives">https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#directives</a>)</p>
|
||||
</dd></dl>
|
||||
|
||||
## uv workspace
|
||||
|
||||
Manage workspaces
|
||||
|
||||
<h3 class="cli-reference">Usage</h3>
|
||||
|
||||
```
|
||||
uv workspace [OPTIONS] <COMMAND>
|
||||
```
|
||||
|
||||
<h3 class="cli-reference">Commands</h3>
|
||||
|
||||
<dl class="cli-reference"><dt><a href="#uv-workspace-metadata"><code>uv workspace metadata</code></a></dt><dd><p>Display package metadata</p></dd>
|
||||
</dl>
|
||||
|
||||
### uv workspace metadata
|
||||
|
||||
Display package metadata
|
||||
|
||||
<h3 class="cli-reference">Usage</h3>
|
||||
|
||||
```
|
||||
uv workspace metadata [OPTIONS]
|
||||
```
|
||||
|
||||
<h3 class="cli-reference">Options</h3>
|
||||
|
||||
<dl class="cli-reference"><dt id="uv-workspace-metadata--allow-insecure-host"><a href="#uv-workspace-metadata--allow-insecure-host"><code>--allow-insecure-host</code></a>, <code>--trusted-host</code> <i>allow-insecure-host</i></dt><dd><p>Allow insecure connections to a host.</p>
|
||||
<p>Can be provided multiple times.</p>
|
||||
<p>Expects to receive either a hostname (e.g., <code>localhost</code>), a host-port pair (e.g., <code>localhost:8080</code>), or a URL (e.g., <code>https://localhost</code>).</p>
|
||||
<p>WARNING: Hosts included in this list will not be verified against the system's certificate store. Only use <code>--allow-insecure-host</code> in a secure network with verified sources, as it bypasses SSL verification and could expose you to MITM attacks.</p>
|
||||
<p>May also be set with the <code>UV_INSECURE_HOST</code> environment variable.</p></dd><dt id="uv-workspace-metadata--cache-dir"><a href="#uv-workspace-metadata--cache-dir"><code>--cache-dir</code></a> <i>cache-dir</i></dt><dd><p>Path to the cache directory.</p>
|
||||
<p>Defaults to <code>$XDG_CACHE_HOME/uv</code> or <code>$HOME/.cache/uv</code> on macOS and Linux, and <code>%LOCALAPPDATA%\uv\cache</code> on Windows.</p>
|
||||
<p>To view the location of the cache directory, run <code>uv cache dir</code>.</p>
|
||||
<p>May also be set with the <code>UV_CACHE_DIR</code> environment variable.</p></dd><dt id="uv-workspace-metadata--color"><a href="#uv-workspace-metadata--color"><code>--color</code></a> <i>color-choice</i></dt><dd><p>Control the use of color in output.</p>
|
||||
<p>By default, uv will automatically detect support for colors when writing to a terminal.</p>
|
||||
<p>Possible values:</p>
|
||||
<ul>
|
||||
<li><code>auto</code>: Enables colored output only when the output is going to a terminal or TTY with support</li>
|
||||
<li><code>always</code>: Enables colored output regardless of the detected environment</li>
|
||||
<li><code>never</code>: Disables colored output</li>
|
||||
</ul></dd><dt id="uv-workspace-metadata--config-file"><a href="#uv-workspace-metadata--config-file"><code>--config-file</code></a> <i>config-file</i></dt><dd><p>The path to a <code>uv.toml</code> file to use for configuration.</p>
|
||||
<p>While uv configuration can be included in a <code>pyproject.toml</code> file, it is not allowed in this context.</p>
|
||||
<p>May also be set with the <code>UV_CONFIG_FILE</code> environment variable.</p></dd><dt id="uv-workspace-metadata--directory"><a href="#uv-workspace-metadata--directory"><code>--directory</code></a> <i>directory</i></dt><dd><p>Change to the given directory prior to running the command.</p>
|
||||
<p>Relative paths are resolved with the given directory as the base.</p>
|
||||
<p>See <code>--project</code> to only change the project root directory.</p>
|
||||
<p>May also be set with the <code>UV_WORKING_DIRECTORY</code> environment variable.</p></dd><dt id="uv-workspace-metadata--help"><a href="#uv-workspace-metadata--help"><code>--help</code></a>, <code>-h</code></dt><dd><p>Display the concise help for this command</p>
|
||||
</dd><dt id="uv-workspace-metadata--managed-python"><a href="#uv-workspace-metadata--managed-python"><code>--managed-python</code></a></dt><dd><p>Require use of uv-managed Python versions.</p>
|
||||
<p>By default, uv prefers using Python versions it manages. However, it will use system Python versions if a uv-managed Python is not installed. This option disables use of system Python versions.</p>
|
||||
<p>May also be set with the <code>UV_MANAGED_PYTHON</code> environment variable.</p></dd><dt id="uv-workspace-metadata--native-tls"><a href="#uv-workspace-metadata--native-tls"><code>--native-tls</code></a></dt><dd><p>Whether to load TLS certificates from the platform's native certificate store.</p>
|
||||
<p>By default, uv loads certificates from the bundled <code>webpki-roots</code> crate. The <code>webpki-roots</code> are a reliable set of trust roots from Mozilla, and including them in uv improves portability and performance (especially on macOS).</p>
|
||||
<p>However, in some cases, you may want to use the platform's native certificate store, especially if you're relying on a corporate trust root (e.g., for a mandatory proxy) that's included in your system's certificate store.</p>
|
||||
<p>May also be set with the <code>UV_NATIVE_TLS</code> environment variable.</p></dd><dt id="uv-workspace-metadata--no-cache"><a href="#uv-workspace-metadata--no-cache"><code>--no-cache</code></a>, <code>--no-cache-dir</code>, <code>-n</code></dt><dd><p>Avoid reading from or writing to the cache, instead using a temporary directory for the duration of the operation</p>
|
||||
<p>May also be set with the <code>UV_NO_CACHE</code> environment variable.</p></dd><dt id="uv-workspace-metadata--no-config"><a href="#uv-workspace-metadata--no-config"><code>--no-config</code></a></dt><dd><p>Avoid discovering configuration files (<code>pyproject.toml</code>, <code>uv.toml</code>).</p>
|
||||
<p>Normally, configuration files are discovered in the current directory, parent directories, or user configuration directories.</p>
|
||||
<p>May also be set with the <code>UV_NO_CONFIG</code> environment variable.</p></dd><dt id="uv-workspace-metadata--no-managed-python"><a href="#uv-workspace-metadata--no-managed-python"><code>--no-managed-python</code></a></dt><dd><p>Disable use of uv-managed Python versions.</p>
|
||||
<p>Instead, uv will search for a suitable Python version on the system.</p>
|
||||
<p>May also be set with the <code>UV_NO_MANAGED_PYTHON</code> environment variable.</p></dd><dt id="uv-workspace-metadata--no-progress"><a href="#uv-workspace-metadata--no-progress"><code>--no-progress</code></a></dt><dd><p>Hide all progress outputs.</p>
|
||||
<p>For example, spinners or progress bars.</p>
|
||||
<p>May also be set with the <code>UV_NO_PROGRESS</code> environment variable.</p></dd><dt id="uv-workspace-metadata--no-python-downloads"><a href="#uv-workspace-metadata--no-python-downloads"><code>--no-python-downloads</code></a></dt><dd><p>Disable automatic downloads of Python.</p>
|
||||
</dd><dt id="uv-workspace-metadata--offline"><a href="#uv-workspace-metadata--offline"><code>--offline</code></a></dt><dd><p>Disable network access.</p>
|
||||
<p>When disabled, uv will only use locally cached data and locally available files.</p>
|
||||
<p>May also be set with the <code>UV_OFFLINE</code> environment variable.</p></dd><dt id="uv-workspace-metadata--project"><a href="#uv-workspace-metadata--project"><code>--project</code></a> <i>project</i></dt><dd><p>Run the command within the given project directory.</p>
|
||||
<p>All <code>pyproject.toml</code>, <code>uv.toml</code>, and <code>.python-version</code> files will be discovered by walking up the directory tree from the project root, as will the project's virtual environment (<code>.venv</code>).</p>
|
||||
<p>Other command-line arguments (such as relative paths) will be resolved relative to the current working directory.</p>
|
||||
<p>See <code>--directory</code> to change the working directory entirely.</p>
|
||||
<p>This setting has no effect when used in the <code>uv pip</code> interface.</p>
|
||||
<p>May also be set with the <code>UV_PROJECT</code> environment variable.</p></dd><dt id="uv-workspace-metadata--quiet"><a href="#uv-workspace-metadata--quiet"><code>--quiet</code></a>, <code>-q</code></dt><dd><p>Use quiet output.</p>
|
||||
<p>Repeating this option, e.g., <code>-qq</code>, will enable a silent mode in which uv will write no output to stdout.</p>
|
||||
</dd><dt id="uv-workspace-metadata--verbose"><a href="#uv-workspace-metadata--verbose"><code>--verbose</code></a>, <code>-v</code></dt><dd><p>Use verbose output.</p>
|
||||
<p>You can configure fine-grained logging using the <code>RUST_LOG</code> environment variable. (<a href="https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#directives">https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#directives</a>)</p>
|
||||
</dd></dl>
|
||||
|
||||
## uv cache
|
||||
|
||||
Manage uv's cache
|
||||
|
|
|
|||
Loading…
Reference in New Issue