@@ -70,7 +70,7 @@ def module_for_header( h, x, gm ):
7070 return None
7171
7272
73- def scan_header_dependencies ( f , x , gm , deps ):
73+ def scan_header_dependencies ( f , x , gm , deps , dep_path ):
7474
7575 for line in f :
7676
@@ -89,8 +89,11 @@ def scan_header_dependencies( f, x, gm, deps ):
8989 vprint ( 1 , 'Adding dependency' , mod )
9090 deps [ mod ] = 0
9191
92+ elif len (dep_path ) > 1 and mod == dep_path [0 ]:
93+ raise DependencyCycle ('Dependency cycle detected: ' + '->' .join (dep_path ) + '->' + mod )
9294
93- def scan_directory ( d , x , gm , deps ):
95+
96+ def scan_directory ( d , x , gm , deps , dep_path ):
9497
9598 vprint ( 1 , 'Scanning directory' , d )
9699
@@ -108,20 +111,20 @@ def scan_directory( d, x, gm, deps ):
108111 if sys .version_info [0 ] < 3 :
109112
110113 with open ( fn , 'r' ) as f :
111- scan_header_dependencies ( f , x , gm , deps )
114+ scan_header_dependencies ( f , x , gm , deps , dep_path )
112115
113116 else :
114117
115118 with open ( fn , 'r' , encoding = 'latin-1' ) as f :
116- scan_header_dependencies ( f , x , gm , deps )
119+ scan_header_dependencies ( f , x , gm , deps , dep_path )
117120
118121
119- def scan_module_dependencies ( m , x , gm , deps , dirs ):
122+ def scan_module_dependencies ( m , x , gm , deps , dirs , dep_path ):
120123
121124 vprint ( 1 , 'Scanning module' , m )
122125
123126 for dir in dirs :
124- scan_directory ( os .path .join ( 'libs' , m , dir ), x , gm , deps )
127+ scan_directory ( os .path .join ( 'libs' , m , dir ), x , gm , deps , dep_path )
125128
126129
127130def read_exceptions ():
@@ -197,7 +200,7 @@ def install_modules( modules, git_args ):
197200 raise Exception ( "The command '%s' failed with exit code %d" % (command , r ) )
198201
199202
200- def install_module_dependencies ( deps , x , gm , git_args ):
203+ def install_module_dependencies ( deps , x , gm , git_args , dep_path ):
201204
202205 modules = []
203206
@@ -214,11 +217,15 @@ def install_module_dependencies( deps, x, gm, git_args ):
214217 install_modules ( modules , git_args )
215218
216219 for m in modules :
217- scan_module_dependencies ( m , x , gm , deps , [ 'include' , 'src' ] )
220+ scan_module_dependencies ( m , x , gm , deps , [ 'include' , 'src' ], dep_path + [ m ] )
218221
219222 return len ( modules )
220223
221224
225+ class DependencyCycle (Exception ):
226+ pass
227+
228+
222229if ( __name__ == "__main__" ):
223230
224231 parser = argparse .ArgumentParser ( description = 'Installs the dependencies needed to test a Boost library.' )
@@ -230,6 +237,7 @@ def install_module_dependencies( deps, x, gm, git_args ):
230237 parser .add_argument ( '-I' , '--include' , help = "additional subdirectory to scan; can be repeated" , metavar = 'DIR' , action = 'append' , default = [] )
231238 parser .add_argument ( '-g' , '--git_args' , help = "additional arguments to `git submodule update`" , default = '' , action = 'store' )
232239 parser .add_argument ( '-u' , '--update' , help = 'update <library> before scanning' , action = 'store_true' )
240+ parser .add_argument ( '-C' , '--detect-cylces' , help = 'detect if <library> has cyclical dependencies' , action = 'store_true' )
233241 parser .add_argument ( 'library' , help = "name of library to scan ('libs/' will be prepended)" )
234242
235243 args = parser .parse_args ()
@@ -269,7 +277,11 @@ def install_module_dependencies( deps, x, gm, git_args ):
269277
270278 vprint ( 1 , 'Directories to scan:' , * dirs )
271279
272- scan_module_dependencies ( m , x , gm , deps , dirs )
280+ dep_path = []
281+ if args .detect_cylces :
282+ dep_path .append (m )
283+
284+ scan_module_dependencies ( m , x , gm , deps , dirs , dep_path )
273285
274286 for dep in args .ignore :
275287 if dep in deps :
@@ -278,5 +290,5 @@ def install_module_dependencies( deps, x, gm, git_args ):
278290
279291 vprint ( 2 , 'Dependencies:' , deps )
280292
281- while install_module_dependencies ( deps , x , gm , args .git_args ):
293+ while install_module_dependencies ( deps , x , gm , args .git_args , dep_path ):
282294 pass
0 commit comments