@@ -8,13 +8,19 @@ pub(crate) fn command_clone(
88 source : & str ,
99 destination : Option < & str > ,
1010 colocate : bool ,
11+ fork : bool ,
1112) -> anyhow:: Result < ( ) > {
12- let url = build_url (
13+ let ( mut url, mut user , _ ) = build_info (
1314 & config. clone . default_host ,
1415 config. clone . default_user . as_deref ( ) ,
1516 source,
1617 )
1718 . ok_or ( anyhow:: anyhow!( "Invalid URL or fullname" ) ) ?;
19+ if fork && let Some ( forker) = & config. clone . default_user {
20+ cmd ! ( "gh" , "repo" , "fork" , & url) . run ( ) ?;
21+ url = url. replacen ( & ( user. clone ( ) + "/" ) , & ( forker. clone ( ) + "/" ) , 1 ) ;
22+ user = forker. to_string ( ) ; // unused now
23+ }
1824 let mut args = vec ! [ "git" , "clone" , & url] ;
1925 if let Some ( destination) = destination {
2026 args. push ( destination) ;
@@ -26,24 +32,37 @@ pub(crate) fn command_clone(
2632 Ok ( ( ) )
2733}
2834
29- fn build_url (
35+ pub ( crate ) fn build_info (
3036 default_host : & str ,
3137 default_user : Option < & str > ,
3238 url_or_fullname : & str ,
33- ) -> Option < String > {
34- let re_url = Regex :: new ( r"^https://[^\s]*? \.git$" ) . unwrap ( ) ;
35- let re_fullname = Regex :: new ( r"^[^/]+/ [^/]+$" ) . unwrap ( ) ;
39+ ) -> Option < ( String , String , String ) > {
40+ let re_url = Regex :: new ( r"^https://([^/]+)/([^/]+)/([^.]+) \.git$" ) . unwrap ( ) ;
41+ let re_fullname = Regex :: new ( r"^( [^/]+)/( [^/]+) $" ) . unwrap ( ) ;
3642 let re_repo = Regex :: new ( r"^[^/]+$" ) . unwrap ( ) ;
3743
38- if re_url. is_match ( url_or_fullname) {
39- Some ( url_or_fullname. to_string ( ) )
40- } else if re_fullname. is_match ( url_or_fullname) {
44+ if let Some ( caps) = re_url. captures ( url_or_fullname) {
45+ // let _host = caps.get(1).unwrap().as_str();
46+ let user = caps. get ( 2 ) . unwrap ( ) . as_str ( ) ;
47+ let repo = caps. get ( 3 ) . unwrap ( ) . as_str ( ) ;
48+ Some ( (
49+ url_or_fullname. to_string ( ) ,
50+ user. to_string ( ) ,
51+ repo. to_string ( ) ,
52+ ) )
53+ } else if let Some ( caps) = re_fullname. captures ( url_or_fullname) {
4154 // user/repo
42- Some ( format ! ( "https://{}/{}.git" , default_host, url_or_fullname) )
55+ let user = caps. get ( 1 ) . unwrap ( ) . as_str ( ) ;
56+ let repo = caps. get ( 2 ) . unwrap ( ) . as_str ( ) ;
57+ let url = format ! ( "https://{}/{}/{}.git" , default_host, user, repo) ;
58+ Some ( ( url, user. to_string ( ) , repo. to_string ( ) ) )
4359 } else if re_repo. is_match ( url_or_fullname) {
44- // pass repo only, needs `default_user`
45- default_user
46- . map ( |user| format ! ( "https://{}/{}/{}.git" , default_host, user, url_or_fullname) )
60+ // repo only
61+ default_user. map ( |user| {
62+ let repo = url_or_fullname;
63+ let url = format ! ( "https://{}/{}/{}.git" , default_host, user, repo) ;
64+ ( url, user. to_string ( ) , repo. to_string ( ) )
65+ } )
4766 } else {
4867 None
4968 }
0 commit comments