@@ -380,11 +380,16 @@ def populate_local_dir(path: str) -> list:
380380 return contents
381381
382382
383- def populate_local_repo (path : str ) -> list :
383+ def populate_local_repo (path : str , parent = None ) -> list :
384384 assert Path (os .path .realpath (path )).exists ()
385- basedir = SourceDir ('base' )
385+ if parent is None :
386+ basedir = SourceDir ('base' )
387+ else :
388+ assert isinstance (parent , SourceDir )
389+ basedir = parent
386390
387- def populate_source_path (parent , mypath ):
391+ def populate_source_path (parent : SourceDir , mypath : PosixPath ,
392+ relative : str = None ):
388393 """`git ls-tree` lists all files with their full path.
389394 This populates all intermediate directories and the file."""
390395 parentdir = parent
@@ -405,6 +410,8 @@ def populate_local_repo(path: str) -> list:
405410 else :
406411 if p == revpath [- 1 ]:
407412 relative_path = None
413+ if parentdir .relative :
414+ relative_path = parentdir .relative
408415 elif parentdir .relative :
409416 relative_path = str (Path (parentdir .relative ) /
410417 parentdir .name )
@@ -420,6 +427,16 @@ def populate_local_repo(path: str) -> list:
420427 newfile = SourceFile (mypath .name )
421428 child .contents .append (newfile )
422429
430+ # Submodules contents are populated separately
431+ proc = run (['git' , '-C' , path , 'submodule' , 'status' ],
432+ stdout = PIPE , stderr = PIPE , text = True , timeout = 5 )
433+ if proc .returncode != 0 :
434+ logging .debug (f"'git submodule status' of repo { path } failed" )
435+ return None
436+ submodules = []
437+ for sub in proc .stdout .splitlines ():
438+ submodules .append (sub .split ()[1 ])
439+
423440 # FIXME: Pass in tag or commit hash
424441 ver = 'HEAD'
425442 git_call = ['git' , '-C' , path , 'ls-tree' , '--full-tree' , '-r' ,
@@ -428,8 +445,21 @@ def populate_local_repo(path: str) -> list:
428445 if proc .returncode != 0 :
429446 logging .debug (f'ls-tree of repo { path } failed' )
430447 return None
448+
431449 for filepath in proc .stdout .splitlines ():
432- populate_source_path (basedir , Path (filepath ))
450+ if filepath in submodules :
451+ if parent is None :
452+ relative_path = filepath
453+ elif basedir .relative :
454+ relative_path = str (Path (basedir .relative ) / filepath )
455+ assert relative_path
456+ submodule_dir = SourceDir (filepath , srctype = Source .LOCAL_REPO ,
457+ relative = relative_path )
458+ populate_local_repo (Path (path ) / filepath , parent = submodule_dir )
459+ submodule_dir .prepopulated = True
460+ basedir .contents .append (submodule_dir )
461+ else :
462+ populate_source_path (basedir , Path (filepath ))
433463 return basedir .contents
434464
435465
0 commit comments