Skip to content

Commit

Permalink
Merge commit 'refs/pull/4637/head' of https://github.com/dashpay/dash
Browse files Browse the repository at this point in the history
…into pr4637
  • Loading branch information
UdjinM6 committed Dec 23, 2021
2 parents 956fb82 + 9605218 commit 1eca078
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 56 deletions.
134 changes: 78 additions & 56 deletions contrib/devtools/circular-dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,61 +28,83 @@ def module_name(path):
return path[:-4]
return None

files = dict()
deps = dict()

RE = re.compile("^#include <(.*)>")

# Iterate over files, and create list of modules
for arg in sys.argv[1:]:
module = module_name(arg)
if module is None:
print("Ignoring file %s (does not constitute module)\n" % arg)
else:
files[arg] = module
deps[module] = set()

# Iterate again, and build list of direct dependencies for each module
# TODO: implement support for multiple include directories
for arg in sorted(files.keys()):
module = files[arg]
with open(arg, 'r', encoding="utf8") as f:
for line in f:
match = RE.match(line)
if match:
include = match.group(1)
included_module = module_name(include)
if included_module is not None and included_module in deps and included_module != module:
deps[module].add(included_module)

# Loop to find the shortest (remaining) circular dependency
have_cycle = False
while True:
shortest_cycle = None
for module in sorted(deps.keys()):
# Build the transitive closure of dependencies of module
closure = dict()
for dep in deps[module]:
closure[dep] = []
if __name__=="__main__":
files = dict()
deps = dict()

RE = re.compile("^#include <(.*)>")

def handle_module(module):
module = module_name(arg)
if module is None:
print("Ignoring file %s (does not constitute module)\n" % arg)
else:
files[arg] = module
deps[module] = set()


# Iterate over files, and create list of modules
for arg in sys.argv[1:]:
handle_module(arg)

def build_list_direct(arg):
module = files[arg]
with open(arg, 'r', encoding="utf8") as f:
for line in f:
match = RE.match(line)
if match:
include = match.group(1)
included_module = module_name(include)
if included_module is not None and included_module in deps and included_module != module:
deps[module].add(included_module)


# Iterate again, and build list of direct dependencies for each module
# TODO: implement support for multiple include directories
for arg in sorted(files.keys()):
build_list_direct(arg)
# Loop to find the shortest (remaining) circular dependency

def shortest_c_dep():
have_cycle = False

def handle_module(module, shortest_cycle):

# Build the transitive closure of dependencies of module
closure = dict()
for dep in deps[module]:
closure[dep] = []
while True:
old_size = len(closure)
old_closure_keys = sorted(closure.keys())
for src in old_closure_keys:
for dep in deps[src]:
if dep not in closure:
closure[dep] = closure[src] + [src]
if len(closure) == old_size:
break
# If module is in its own transitive closure, it's a circular dependency; check if it is the shortest
if module in closure and (shortest_cycle is None or len(closure[module]) + 1 < len(shortest_cycle)):
shortest_cycle = [module] + closure[module]

return shortest_cycle

while True:
old_size = len(closure)
old_closure_keys = sorted(closure.keys())
for src in old_closure_keys:
for dep in deps[src]:
if dep not in closure:
closure[dep] = closure[src] + [src]
if len(closure) == old_size:

shortest_cycles = None
for module in sorted(deps.keys()):
shortest_cycles = handle_module(module, shortest_cycles)

if shortest_cycles is None:
break
# If module is in its own transitive closure, it's a circular dependency; check if it is the shortest
if module in closure and (shortest_cycle is None or len(closure[module]) + 1 < len(shortest_cycle)):
shortest_cycle = [module] + closure[module]
if shortest_cycle is None:
break
# We have the shortest circular dependency; report it
module = shortest_cycle[0]
print("Circular dependency: %s" % (" -> ".join(shortest_cycle + [module])))
# And then break the dependency to avoid repeating in other cycles
deps[shortest_cycle[-1]] = deps[shortest_cycle[-1]] - set([module])
have_cycle = True

sys.exit(1 if have_cycle else 0)
# We have the shortest circular dependency; report it
module = shortest_cycles[0]
print("Circular dependency: %s" % (" -> ".join(shortest_cycles + [module])))
# And then break the dependency to avoid repeating in other cycles
deps[shortest_cycles[-1]] = deps[shortest_cycles[-1]] - set([module])
have_cycle = True

if have_cycle:
return True

sys.exit(1 if shortest_c_dep() else 0)
14 changes: 14 additions & 0 deletions test/lint/lint-all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ LINTALL=$(basename "${BASH_SOURCE[0]}")

EXIT_CODE=0

SCRIPTS=()

for f in "${SCRIPTDIR}"/lint-*.sh; do
if [ "$(basename "$f")" != "$LINTALL" ]; then
SCRIPTS+=("$f")
fi
done


if ! parallel --help > /dev/null; then
for f in "${SCRIPTDIR}"/lint-*.sh; do
if [ "$(basename "$f")" != "$LINTALL" ]; then
if ! "$f"; then
Expand All @@ -26,5 +36,9 @@ for f in "${SCRIPTDIR}"/lint-*.sh; do
fi
fi
done
elif ! parallel --jobs 100% bash ::: ${SCRIPTS[*]}; then
echo "^---- failure generated"
EXIT_CODE=1
fi

exit ${EXIT_CODE}

0 comments on commit 1eca078

Please sign in to comment.