File tree Expand file tree Collapse file tree 6 files changed +96
-0
lines changed Expand file tree Collapse file tree 6 files changed +96
-0
lines changed Original file line number Diff line number Diff line change @@ -163,10 +163,12 @@ impl DevGroupsSpecification {
163163 ( self . dev . is_none ( ) || self . dev . as_ref ( ) . is_some_and ( DevMode :: prod) ) && self . groups . prod ( )
164164 }
165165
166+ /// Returns the flag that was used to request development dependencies.
166167 pub fn dev_mode ( & self ) -> Option < & DevMode > {
167168 self . dev . as_ref ( )
168169 }
169170
171+ /// Returns the list of groups to include.
170172 pub fn groups ( & self ) -> & GroupsSpecification {
171173 & self . groups
172174 }
Original file line number Diff line number Diff line change @@ -540,6 +540,11 @@ impl DependencyGroups {
540540 self . 0 . get ( group)
541541 }
542542
543+ /// Returns `true` if the dependency group is in the list.
544+ pub fn contains_key ( & self , group : & GroupName ) -> bool {
545+ self . 0 . contains_key ( group)
546+ }
547+
543548 /// Returns an iterator over the dependency groups.
544549 pub fn iter ( & self ) -> impl Iterator < Item = ( & GroupName , & Vec < DependencyGroupSpecifier > ) > {
545550 self . 0 . iter ( )
Original file line number Diff line number Diff line change @@ -70,6 +70,20 @@ pub(crate) async fn export(
7070 VirtualProject :: discover ( project_dir, & DiscoveryOptions :: default ( ) ) . await ?
7171 } ;
7272
73+ // Validate the requested dependency groups.
74+ for group in dev. groups ( ) . iter ( ) {
75+ if !project
76+ . pyproject_toml ( )
77+ . dependency_groups
78+ . as_ref ( )
79+ . is_some_and ( |groups| groups. contains_key ( group) )
80+ {
81+ return Err ( anyhow:: anyhow!(
82+ "Group `{group}` is not defined in the project's `dependency-group` table"
83+ ) ) ;
84+ }
85+ }
86+
7387 let VirtualProject :: Project ( project) = project else {
7488 return Err ( anyhow:: anyhow!( "Legacy non-project roots are not supported in `uv export`; add a `[project]` table to your `pyproject.toml` to enable exports" ) ) ;
7589 } ;
Original file line number Diff line number Diff line change @@ -469,6 +469,20 @@ pub(crate) async fn run(
469469 ) ;
470470 }
471471
472+ // Validate the requested dependency groups.
473+ for group in dev. groups ( ) . iter ( ) {
474+ if !project
475+ . pyproject_toml ( )
476+ . dependency_groups
477+ . as_ref ( )
478+ . is_some_and ( |groups| groups. contains_key ( group) )
479+ {
480+ return Err ( anyhow:: anyhow!(
481+ "Group `{group}` is not defined in the project's `dependency-group` table"
482+ ) ) ;
483+ }
484+ }
485+
472486 let venv = if isolated {
473487 debug ! ( "Creating isolated virtual environment" ) ;
474488
Original file line number Diff line number Diff line change @@ -93,6 +93,20 @@ pub(crate) async fn sync(
9393 warn_user ! ( "Skipping installation of entry points (`project.scripts`) because this project is not packaged; to install entry points, set `tool.uv.package = true` or define a `build-system`" ) ;
9494 }
9595
96+ // Validate the requested dependency groups.
97+ for group in dev. groups ( ) . iter ( ) {
98+ if !project
99+ . pyproject_toml ( )
100+ . dependency_groups
101+ . as_ref ( )
102+ . is_some_and ( |groups| groups. contains_key ( group) )
103+ {
104+ return Err ( anyhow:: anyhow!(
105+ "Group `{group}` is not defined in the project's `dependency-group` table"
106+ ) ) ;
107+ }
108+ }
109+
96110 // Discover or create the virtual environment.
97111 let venv = project:: get_or_init_environment (
98112 target. workspace ( ) ,
Original file line number Diff line number Diff line change @@ -1226,6 +1226,53 @@ fn sync_dev_group() -> Result<()> {
12261226 Ok ( ( ) )
12271227}
12281228
1229+ #[ test]
1230+ fn sync_non_existent_group ( ) -> Result < ( ) > {
1231+ let context = TestContext :: new ( "3.12" ) ;
1232+
1233+ let pyproject_toml = context. temp_dir . child ( "pyproject.toml" ) ;
1234+ pyproject_toml. write_str (
1235+ r#"
1236+ [project]
1237+ name = "project"
1238+ version = "0.1.0"
1239+ requires-python = ">=3.12"
1240+ dependencies = ["typing-extensions"]
1241+
1242+ [dependency-groups]
1243+ foo = []
1244+ bar = ["requests"]
1245+ "# ,
1246+ ) ?;
1247+
1248+ context. lock ( ) . assert ( ) . success ( ) ;
1249+
1250+ // Requesting a non-existent group should fail.
1251+ uv_snapshot ! ( context. filters( ) , context. sync( ) . arg( "--group" ) . arg( "baz" ) , @r###"
1252+ success: false
1253+ exit_code: 2
1254+ ----- stdout -----
1255+
1256+ ----- stderr -----
1257+ error: Group `baz` is not defined in the project's `dependency-group` table
1258+ "### ) ;
1259+
1260+ // Requesting an empty group should succeed.
1261+ uv_snapshot ! ( context. filters( ) , context. sync( ) . arg( "--group" ) . arg( "foo" ) , @r###"
1262+ success: true
1263+ exit_code: 0
1264+ ----- stdout -----
1265+
1266+ ----- stderr -----
1267+ Resolved 7 packages in [TIME]
1268+ Prepared 1 package in [TIME]
1269+ Installed 1 package in [TIME]
1270+ + typing-extensions==4.10.0
1271+ "### ) ;
1272+
1273+ Ok ( ( ) )
1274+ }
1275+
12291276/// Regression test for <https://github.com/astral-sh/uv/issues/6316>.
12301277///
12311278/// Previously, we would read metadata statically from pyproject.toml and write that to `uv.lock`. In
You can’t perform that action at this time.
0 commit comments