@@ -2,7 +2,7 @@ use std::collections::HashMap;
22use std:: ffi:: OsStr ;
33use std:: fmt:: Debug ;
44use std:: fs;
5- use std:: path:: Path ;
5+ use std:: path:: { Path , PathBuf } ;
66use std:: process:: { Command , ExitStatus , Output } ;
77
88fn get_command_inner (
@@ -254,20 +254,12 @@ pub struct CloneResult {
254254 pub repo_dir : String ,
255255}
256256
257- pub fn git_clone (
257+ fn git_clone_inner (
258258 to_clone : & str ,
259- dest : Option < & Path > ,
259+ dest : & Path ,
260260 shallow_clone : bool ,
261+ repo_name : String ,
261262) -> Result < CloneResult , String > {
262- let repo_name = to_clone. split ( '/' ) . last ( ) . unwrap ( ) ;
263- let repo_name = match repo_name. strip_suffix ( ".git" ) {
264- Some ( n) => n. to_string ( ) ,
265- None => repo_name. to_string ( ) ,
266- } ;
267-
268- let dest = dest
269- . map ( |dest| dest. join ( & repo_name) )
270- . unwrap_or_else ( || Path :: new ( & repo_name) . into ( ) ) ;
271263 if dest. is_dir ( ) {
272264 return Ok ( CloneResult {
273265 ran_clone : false ,
@@ -289,6 +281,51 @@ pub fn git_clone(
289281 } )
290282}
291283
284+ fn get_repo_name ( url : & str ) -> String {
285+ let repo_name = url. split ( '/' ) . last ( ) . unwrap ( ) ;
286+ match repo_name. strip_suffix ( ".git" ) {
287+ Some ( n) => n. to_string ( ) ,
288+ None => repo_name. to_string ( ) ,
289+ }
290+ }
291+
292+ pub fn git_clone (
293+ to_clone : & str ,
294+ dest : Option < & Path > ,
295+ shallow_clone : bool ,
296+ ) -> Result < CloneResult , String > {
297+ let repo_name = get_repo_name ( to_clone) ;
298+ let tmp: PathBuf ;
299+
300+ let dest = match dest {
301+ Some ( dest) => dest,
302+ None => {
303+ tmp = repo_name. clone ( ) . into ( ) ;
304+ & tmp
305+ }
306+ } ;
307+ git_clone_inner ( to_clone, dest, shallow_clone, repo_name)
308+ }
309+
310+ /// This function differs from `git_clone` in how it handles *where* the repository will be cloned.
311+ /// In `git_clone`, it is cloned in the provided path. In this function, the path you provide is
312+ /// the parent folder. So if you pass "a" as folder and try to clone "b.git", it will be cloned into
313+ /// `a/b`.
314+ pub fn git_clone_root_dir (
315+ to_clone : & str ,
316+ dest_parent_dir : & Path ,
317+ shallow_clone : bool ,
318+ ) -> Result < CloneResult , String > {
319+ let repo_name = get_repo_name ( to_clone) ;
320+
321+ git_clone_inner (
322+ to_clone,
323+ & dest_parent_dir. join ( & repo_name) ,
324+ shallow_clone,
325+ repo_name,
326+ )
327+ }
328+
292329pub fn walk_dir < P , D , F > ( dir : P , mut dir_cb : D , mut file_cb : F ) -> Result < ( ) , String >
293330where
294331 P : AsRef < Path > ,
0 commit comments