1010from libvcs import GitSync , HgSync , SvnSync
1111from libvcs ._internal .run import ProgressCallbackProtocol
1212from libvcs ._internal .types import StrPath , VCSLiteral
13- from libvcs .exc import InvalidVCS
13+ from libvcs .exc import InvalidVCS , LibVCSException
14+ from libvcs .url import registry as url_tools
15+
16+ if t .TYPE_CHECKING :
17+ from typing_extensions import TypeGuard
1418
1519
1620@t .overload
@@ -20,7 +24,7 @@ def create_project(
2024 dir : StrPath ,
2125 vcs : t .Literal ["git" ],
2226 progress_callback : t .Optional [ProgressCallbackProtocol ] = None ,
23- ** kwargs : dict [t .Any , t .Any ]
27+ ** kwargs : dict [t .Any , t .Any ],
2428) -> GitSync :
2529 ...
2630
@@ -32,7 +36,7 @@ def create_project(
3236 dir : StrPath ,
3337 vcs : t .Literal ["svn" ],
3438 progress_callback : t .Optional [ProgressCallbackProtocol ] = None ,
35- ** kwargs : dict [t .Any , t .Any ]
39+ ** kwargs : dict [t .Any , t .Any ],
3640) -> SvnSync :
3741 ...
3842
@@ -44,7 +48,7 @@ def create_project(
4448 dir : StrPath ,
4549 vcs : t .Literal ["hg" ],
4650 progress_callback : t .Optional [ProgressCallbackProtocol ] = ...,
47- ** kwargs : dict [t .Any , t .Any ]
51+ ** kwargs : dict [t .Any , t .Any ],
4852) -> HgSync :
4953 ...
5054
@@ -53,9 +57,9 @@ def create_project(
5357 * ,
5458 url : str ,
5559 dir : StrPath ,
56- vcs : VCSLiteral ,
60+ vcs : t . Optional [ VCSLiteral ] = None ,
5761 progress_callback : t .Optional [ProgressCallbackProtocol ] = None ,
58- ** kwargs : dict [t .Any , t .Any ]
62+ ** kwargs : dict [t .Any , t .Any ],
5963) -> Union [GitSync , HgSync , SvnSync ]:
6064 r"""Return an object representation of a VCS repository.
6165
@@ -71,6 +75,24 @@ def create_project(
7175 >>> isinstance(r, GitSync)
7276 True
7377 """
78+ if vcs is None :
79+ vcs_matches = url_tools .registry .match (url = url , is_explicit = True )
80+
81+ if len (vcs_matches ) == 0 :
82+ raise LibVCSException (f"No vcs found for { url } " )
83+ if len (vcs_matches ) > 1 :
84+ raise LibVCSException (f"No exact matches for { url } " )
85+
86+ assert vcs_matches [0 ].vcs is not None
87+
88+ def is_vcs (val : t .Any ) -> "TypeGuard[VCSLiteral]" :
89+ return isinstance (val , str ) and val in ["git" , "hg" , "svn" ]
90+
91+ if is_vcs (vcs_matches [0 ].vcs ):
92+ vcs = vcs_matches [0 ].vcs
93+ else :
94+ raise InvalidVCS (f"{ url } does not have supported vcs: { vcs } " )
95+
7496 if vcs == "git" :
7597 return GitSync (url = url , dir = dir , progress_callback = progress_callback , ** kwargs )
7698 elif vcs == "hg" :
0 commit comments