Make transitive_deps as a topologically sorted list

pull/21515/head
Esun Kim 5 years ago
parent a27b2c2015
commit 4a68e396a2
  1. 2
      templates/gRPC-C++.podspec.template
  2. 2
      templates/gRPC-Core.podspec.template
  3. 53
      tools/buildgen/plugins/transitive_dependencies.py

@ -35,7 +35,7 @@
return "abseil/" + label[5:].replace(":", "/")
def lib_and_transitive_deps(lib):
return list(sorted(set({lib} | lib_maps[lib].transitive_deps)))
return list(sorted(set({lib} | set(lib_maps[lib].transitive_deps))))
def non_abseil_lib_and_transitive_deps(lib):
return [l for l in lib_and_transitive_deps(lib) if not is_absl_lib(l)]

@ -34,7 +34,7 @@
return "abseil/" + label[5:].replace(":", "/")
def lib_and_transitive_deps(lib):
return list(sorted(set({lib} | lib_maps[lib].transitive_deps)))
return list(sorted(set({lib} | set(lib_maps[lib].transitive_deps))))
def non_abseil_lib_and_transitive_deps(lib):
return [l for l in lib_and_transitive_deps(lib) if not is_absl_lib(l)]

@ -16,43 +16,48 @@
This takes the list of libs, node_modules, and targets from our
yaml dictionary, and adds to each the transitive closure
of the list of dependencies.
"""
def get_lib(libs, name):
try:
return next(lib for lib in libs if lib['name'] == name)
except StopIteration:
return None
def transitive_deps(lib_map, node):
"""Returns a list of transitive dependencies from node.
Recursively iterate all dependent node in a depth-first fashion and
list a result using a topological sorting.
"""
result = []
seen = set()
start = node
def recursive_helper(node):
if node is None:
return
for dep in node.get("deps", []):
if dep not in seen:
seen.add(dep)
next_node = lib_map.get(dep)
recursive_helper(next_node)
if node is not start:
result.insert(0, node["name"])
def transitive_deps(lib, libs):
if lib is not None and 'deps' in lib:
# Recursively call transitive_deps on each dependency, and take the union
return set.union(
set(lib['deps']), *[
set(transitive_deps(get_lib(libs, dep), libs))
for dep in lib['deps']
])
else:
return set()
recursive_helper(node)
return result
def mako_plugin(dictionary):
"""The exported plugin code for transitive_dependencies.
Iterate over each list and check each item for a deps list. We add a
transitive_deps property to each with the transitive closure of those
dependency lists.
"""
libs = dictionary.get('libs')
Iterate over each list and check each item for a deps list. We add a
transitive_deps property to each with the transitive closure of those
dependency lists. The result list is sorted in a topological ordering.
"""
lib_map = {lib['name']: lib for lib in dictionary.get('libs')}
for target_name, target_list in dictionary.items():
for target in target_list:
if isinstance(target, dict) and 'deps' in target:
target['transitive_deps'] = transitive_deps(target, libs)
target['transitive_deps'] = transitive_deps(lib_map, target)
python_dependencies = dictionary.get('python_dependencies')
python_dependencies['transitive_deps'] = (transitive_deps(
python_dependencies, libs))
python_dependencies['transitive_deps'] = transitive_deps(
lib_map, python_dependencies)

Loading…
Cancel
Save