mirror of
https://github.com/boostorg/boostdep.git
synced 2026-07-21 13:13:31 +00:00
depinst option to reject dependency cycles
This commit is contained in:
@@ -391,7 +391,7 @@ jobs:
|
||||
- throw_exception
|
||||
- uuid
|
||||
|
||||
args: [ '' ]
|
||||
args: [ '', '-C' ]
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
|
||||
+67
-20
@@ -70,7 +70,7 @@ def module_for_header( h, x, gm ):
|
||||
return None
|
||||
|
||||
|
||||
def scan_header_dependencies( f, x, gm, deps ):
|
||||
def scan_header_dependencies( f, x, gm, deps, dep_path ):
|
||||
|
||||
for line in f:
|
||||
|
||||
@@ -89,8 +89,13 @@ def scan_header_dependencies( f, x, gm, deps ):
|
||||
vprint( 1, 'Adding dependency', mod )
|
||||
deps[ mod ] = 0
|
||||
|
||||
elif len(dep_path) > 1 and mod == dep_path[0]:
|
||||
|
||||
def scan_directory( d, x, gm, deps ):
|
||||
dep_path = dep_path + [ mod ]
|
||||
raise DependencyCycle( 'Dependency cycle detected: ' + ' -> '.join(dep_path) )
|
||||
|
||||
|
||||
def scan_directory( d, x, gm, deps, dep_path ):
|
||||
|
||||
vprint( 1, 'Scanning directory', d )
|
||||
|
||||
@@ -108,20 +113,20 @@ def scan_directory( d, x, gm, deps ):
|
||||
if sys.version_info[0] < 3:
|
||||
|
||||
with open( fn, 'r' ) as f:
|
||||
scan_header_dependencies( f, x, gm, deps )
|
||||
scan_header_dependencies( f, x, gm, deps, dep_path )
|
||||
|
||||
else:
|
||||
|
||||
with open( fn, 'r', encoding='latin-1' ) as f:
|
||||
scan_header_dependencies( f, x, gm, deps )
|
||||
scan_header_dependencies( f, x, gm, deps, dep_path )
|
||||
|
||||
|
||||
def scan_module_dependencies( m, x, gm, deps, dirs ):
|
||||
def scan_module_dependencies( m, x, gm, deps, dirs, dep_path ):
|
||||
|
||||
vprint( 1, 'Scanning module', m )
|
||||
|
||||
for dir in dirs:
|
||||
scan_directory( os.path.join( 'libs', m, dir ), x, gm, deps )
|
||||
scan_directory( os.path.join( 'libs', m, dir ), x, gm, deps, dep_path )
|
||||
|
||||
|
||||
def read_exceptions():
|
||||
@@ -197,7 +202,7 @@ def install_modules( modules, git_args ):
|
||||
raise Exception( "The command '%s' failed with exit code %d" % (command, r) )
|
||||
|
||||
|
||||
def install_module_dependencies( deps, x, gm, git_args ):
|
||||
def install_module_dependencies( deps, x, gm, git_args, dep_path ):
|
||||
|
||||
modules = []
|
||||
|
||||
@@ -214,11 +219,20 @@ def install_module_dependencies( deps, x, gm, git_args ):
|
||||
install_modules( modules, git_args )
|
||||
|
||||
for m in modules:
|
||||
scan_module_dependencies( m, x, gm, deps, [ 'include', 'src' ] )
|
||||
next_dep_path = dep_path
|
||||
|
||||
if dep_path:
|
||||
next_dep_path = dep_path + [m]
|
||||
|
||||
scan_module_dependencies( m, x, gm, deps, [ 'include', 'src' ], next_dep_path )
|
||||
|
||||
return len( modules )
|
||||
|
||||
|
||||
class DependencyCycle(Exception):
|
||||
pass
|
||||
|
||||
|
||||
if( __name__ == "__main__" ):
|
||||
|
||||
parser = argparse.ArgumentParser( description='Installs the dependencies needed to test a Boost library.' )
|
||||
@@ -230,6 +244,7 @@ if( __name__ == "__main__" ):
|
||||
parser.add_argument( '-I', '--include', help="additional subdirectory to scan; can be repeated", metavar='DIR', action='append', default=[] )
|
||||
parser.add_argument( '-g', '--git_args', help="additional arguments to `git submodule update`", default='', action='store' )
|
||||
parser.add_argument( '-u', '--update', help='update <library> before scanning', action='store_true' )
|
||||
parser.add_argument( '-C', '--reject-cycles', help='abort if <library> has cyclical dependencies', action='store_true' )
|
||||
parser.add_argument( 'library', help="name of library to scan ('libs/' will be prepended)" )
|
||||
|
||||
args = parser.parse_args()
|
||||
@@ -239,6 +254,7 @@ if( __name__ == "__main__" ):
|
||||
vprint( 2, '-X:', args.exclude )
|
||||
vprint( 2, '-I:', args.include )
|
||||
vprint( 2, '-N:', args.ignore )
|
||||
vprint( 2, '-C:', args.reject_cycles )
|
||||
|
||||
x = read_exceptions()
|
||||
vprint( 2, 'Exceptions:', x )
|
||||
@@ -257,26 +273,57 @@ if( __name__ == "__main__" ):
|
||||
|
||||
m = args.library
|
||||
|
||||
deps = { m : 1 }
|
||||
|
||||
dirs = [ 'include', 'src', 'test' ]
|
||||
main_dirs = [ 'include', 'src' ]
|
||||
extra_dirs = [ 'test' ]
|
||||
|
||||
for dir in args.exclude:
|
||||
dirs.remove( dir )
|
||||
if dir in main_dirs:
|
||||
main_dirs.remove( dir )
|
||||
|
||||
if dir in extra_dirs:
|
||||
extra_dirs.remove( dir )
|
||||
|
||||
for dir in args.include:
|
||||
dirs.append( dir )
|
||||
extra_dirs.append( dir )
|
||||
|
||||
vprint( 1, 'Directories to scan:', *dirs )
|
||||
vprint( 1, 'Directories to scan:', *(main_dirs + extra_dirs) )
|
||||
|
||||
scan_module_dependencies( m, x, gm, deps, dirs )
|
||||
dep_path = []
|
||||
if args.reject_cycles:
|
||||
dep_path.append( m )
|
||||
|
||||
main_deps = { m : 1 }
|
||||
scan_module_dependencies( m, x, gm, main_deps, main_dirs, dep_path )
|
||||
|
||||
extra_deps = { m : 1 }
|
||||
scan_module_dependencies( m, x, gm, extra_deps, extra_dirs, [] )
|
||||
|
||||
for dep in args.ignore:
|
||||
if dep in deps:
|
||||
reported = False
|
||||
|
||||
if dep in main_deps:
|
||||
vprint( 1, 'Ignoring dependency', dep )
|
||||
del deps[dep]
|
||||
reported = True
|
||||
del main_deps[dep]
|
||||
|
||||
vprint( 2, 'Dependencies:', deps )
|
||||
if dep in extra_deps:
|
||||
if not reported:
|
||||
vprint( 1, 'Ignoring dependency', dep )
|
||||
reported = True
|
||||
del extra_deps[dep]
|
||||
|
||||
while install_module_dependencies( deps, x, gm, args.git_args ):
|
||||
pass
|
||||
all_deps = dict( **main_deps )
|
||||
all_deps.update( extra_deps )
|
||||
vprint( 2, 'Dependencies:', all_deps )
|
||||
|
||||
try:
|
||||
|
||||
while install_module_dependencies( main_deps, x, gm, args.git_args, dep_path ):
|
||||
pass
|
||||
|
||||
while install_module_dependencies( extra_deps, x, gm, args.git_args, [] ):
|
||||
pass
|
||||
|
||||
except DependencyCycle as e:
|
||||
print( e, file=sys.stderr )
|
||||
sys.exit(1)
|
||||
|
||||
Reference in New Issue
Block a user