@@ -83,7 +83,7 @@ pub(crate) async fn add(
8383 extras_of_dependency : Vec < ExtraName > ,
8484 package : Option < PackageName > ,
8585 python : Option < String > ,
86- workspace : bool ,
86+ workspace : Option < bool > ,
8787 install_mirrors : PythonInstallMirrors ,
8888 settings : ResolverInstallerSettings ,
8989 network_settings : NetworkSettings ,
@@ -495,16 +495,41 @@ pub(crate) async fn add(
495495 // Track modification status, for reverts.
496496 let mut modified = false ;
497497
498- // If `--workspace` is provided, add any members to the `workspace` section of the
498+ // Determine whether to use workspace mode.
499+ let use_workspace = match workspace {
500+ Some ( workspace) => workspace,
501+ None => {
502+ // Check if we're in a project (not a script), and if any requirements are path
503+ // dependencies within the workspace.
504+ if let AddTarget :: Project ( ref project, _) = target {
505+ let workspace_root = project. workspace ( ) . install_path ( ) ;
506+ requirements. iter ( ) . any ( |req| {
507+ if let RequirementSource :: Directory { install_path, .. } = & req. source {
508+ let absolute_path = if install_path. is_absolute ( ) {
509+ install_path. to_path_buf ( )
510+ } else {
511+ project. root ( ) . join ( install_path)
512+ } ;
513+ absolute_path. starts_with ( workspace_root)
514+ } else {
515+ false
516+ }
517+ } )
518+ } else {
519+ false
520+ }
521+ }
522+ } ;
523+
524+ // If workspace mode is enabled, add any members to the `workspace` section of the
499525 // `pyproject.toml` file.
500- if workspace {
526+ if use_workspace {
501527 let AddTarget :: Project ( project, python_target) = target else {
502528 unreachable ! ( "`--workspace` and `--script` are conflicting options" ) ;
503529 } ;
504530
505- let workspace = project. workspace ( ) ;
506531 let mut toml = PyProjectTomlMut :: from_toml (
507- & workspace. pyproject_toml ( ) . raw ,
532+ & project . workspace ( ) . pyproject_toml ( ) . raw ,
508533 DependencyTarget :: PyProjectToml ,
509534 ) ?;
510535
@@ -517,21 +542,32 @@ pub(crate) async fn add(
517542 project. root ( ) . join ( install_path)
518543 } ;
519544
520- // Check if the path is not already included in the workspace.
521- if ! workspace. includes ( & absolute_path ) ? {
522- let relative_path = absolute_path
523- . strip_prefix ( workspace. install_path ( ) )
524- . unwrap_or ( & absolute_path ) ;
525-
526- toml . add_workspace ( relative_path ) ? ;
527- modified |= true ;
545+ // Either `--workspace` was provided explicitly, or it was omitted but the path is
546+ // within the workspace root.
547+ let use_workspace = workspace . unwrap_or_else ( || {
548+ absolute_path . starts_with ( project . workspace ( ) . install_path ( ) )
549+ } ) ;
550+ if !use_workspace {
551+ continue ;
552+ }
528553
529- writeln ! (
530- printer. stderr( ) ,
531- "Added `{}` to workspace members" ,
532- relative_path. user_display( ) . cyan( )
533- ) ?;
554+ // If the project is already a member of the workspace, skip it.
555+ if project. workspace ( ) . includes ( & absolute_path) ? {
556+ continue ;
534557 }
558+
559+ let relative_path = absolute_path
560+ . strip_prefix ( project. workspace ( ) . install_path ( ) )
561+ . unwrap_or ( & absolute_path) ;
562+
563+ toml. add_workspace ( relative_path) ?;
564+ modified |= true ;
565+
566+ writeln ! (
567+ printer. stderr( ) ,
568+ "Added `{}` to workspace members" ,
569+ relative_path. user_display( ) . cyan( )
570+ ) ?;
535571 }
536572 }
537573
@@ -540,7 +576,7 @@ pub(crate) async fn add(
540576 target = if modified {
541577 let workspace_content = toml. to_string ( ) ;
542578 fs_err:: write (
543- workspace. install_path ( ) . join ( "pyproject.toml" ) ,
579+ project . workspace ( ) . install_path ( ) . join ( "pyproject.toml" ) ,
544580 & workspace_content,
545581 ) ?;
546582
@@ -745,13 +781,13 @@ fn edits(
745781 . and_then ( |tool| tool. uv . as_ref ( ) )
746782 . and_then ( |uv| uv. sources . as_ref ( ) )
747783 . map ( ToolUvSources :: inner) ;
748- let workspace = project
784+ let is_workspace_member = project
749785 . workspace ( )
750786 . packages ( )
751787 . contains_key ( & requirement. name ) ;
752788 resolve_requirement (
753789 requirement,
754- workspace ,
790+ is_workspace_member ,
755791 editable,
756792 index. cloned ( ) ,
757793 rev. map ( ToString :: to_string) ,
0 commit comments