22
33import os
44import sys
5- import time
65from contextlib import contextmanager , suppress
76from functools import cached_property
87from os .path import isabs
1413from hatch .utils .fs import Path
1514from hatch .utils .shells import ShellManager
1615from hatch .utils .structures import EnvVars
17-
18- from hatch_uvenv .venv import UVVirtualEnv
16+ from hatch .venv .core import UVVirtualEnv
1917
2018if TYPE_CHECKING :
2119 from collections .abc import Iterable
@@ -86,6 +84,9 @@ def __init__(self, *args, **kwargs):
8684 def explicit_uv_path (self ) -> str :
8785 return self .get_env_var_option ("uv_path" ) or self .config .get ("uv-path" , "" )
8886
87+ def expose_uv (self ):
88+ return EnvVars ({"HATCH_UV" : self .uv_path })
89+
8990 @cached_property
9091 def uv_path (self ) -> str :
9192 if self .explicit_uv_path :
@@ -100,8 +101,8 @@ def uv_path(self) -> str:
100101 # Only if dependencies have been set by the user
101102 or is_default_environment (env_name , self .app .project .config .internal_envs [env_name ])
102103 ):
103- uv_env = self .app .project . get_environment (env_name )
104- self .app .project . prepare_environment (uv_env )
104+ uv_env = self .app .get_environment (env_name )
105+ self .app .prepare_environment (uv_env )
105106 with uv_env :
106107 return self .platform .modules .shutil .which ("uv" )
107108
@@ -125,9 +126,6 @@ def get_option_types() -> dict:
125126 "uv-path" : str ,
126127 }
127128
128- def expose_uv (self ):
129- return EnvVars ({"HATCH_UV" : self .uv_path })
130-
131129 def activate (self ):
132130 self .virtual_env .activate ()
133131
@@ -186,34 +184,57 @@ def install_project_dev_mode(self): ...
186184 def dependencies_in_sync (self ):
187185 return False
188186
189- def dependency_hash (self ):
190- # always return a new value so uv can determine if dependencies are in-sync
191- return time .time ().hex ()
192-
193187 def sync_dependencies (self ):
194- with self .safe_activation ():
195- if self .dev_mode :
196- self .platform .check_command (self .construct_pip_install_command ([]))
197- else :
198- self .platform .check_command (self .construct_pip_install_command (["--no-editable" ]))
188+ self .platform .check_command (self .construct_uv_sync_command ())
189+
190+ @contextmanager
191+ def build_environment (self , dependencies ):
192+ from packaging .requirements import Requirement
193+
194+ from hatchling .dep .core import dependencies_in_sync
195+
196+ if not self .build_environment_exists ():
197+ with self .expose_uv ():
198+ self .build_virtual_env .create (self .parent_python )
199+
200+ with self .get_env_vars (), self .build_virtual_env :
201+ if not dependencies_in_sync (
202+ [Requirement (d ) for d in dependencies ],
203+ sys_path = self .build_virtual_env .sys_path ,
204+ environment = self .build_virtual_env .environment ,
205+ ):
206+ self .platform .check_command (self .construct_pip_install_command (dependencies ))
207+
208+ yield
209+
210+ def build_environment_exists (self ):
211+ return self .build_virtual_env .exists ()
199212
200213 @contextmanager
201214 def command_context (self ):
202215 with self .safe_activation ():
203216 yield
204217
205- def construct_pip_install_command (self , args : list [ str ] ):
218+ def construct_uv_sync_command (self ):
206219 command = ["uv" , "sync" , "--active" ]
207220
208221 # Default to -1 verbosity
209222 add_verbosity_flag (command , self .verbosity , adjustment = - 1 )
210223 self .add_group_flags (command )
211224 self .add_extra_flags (command )
212225 self .add_uv_flags (command )
213- command .extend (args )
214226
215227 return command
216228
229+ def construct_pip_install_command (self , args : list [str ]):
230+ command = [self .uv_path , 'pip' , 'install' ]
231+
232+ # Default to -1 verbosity
233+ add_verbosity_flag (command , self .verbosity , adjustment = - 1 )
234+
235+ command .extend (args )
236+ return command
237+
217238 def enter_shell (self , name : str , path : str , args : Iterable [str ]):
218239 shell_executor = getattr (self .shells , f"enter_{ name } " , None )
219240 if shell_executor is None :
0 commit comments