summaryrefslogtreecommitdiff
path: root/site_scons
diff options
context:
space:
mode:
authorAndrew Morrow <andrew.morrow@10gen.com>2020-01-03 17:53:50 +0000
committerevergreen <evergreen@mongodb.com>2020-01-03 17:53:50 +0000
commit00a41363a70bd0c8ab61d037ac1ec78a6b2d2c8b (patch)
treed044cc337791ee8f29744d0dd2e4e2a0546e58d3 /site_scons
parent02ce213b40c56096c9c57e093778b0889c335bb9 (diff)
downloadmongo-00a41363a70bd0c8ab61d037ac1ec78a6b2d2c8b.tar.gz
SERVER-45171 Improve handling of transitive dependencies in hygienic
Diffstat (limited to 'site_scons')
-rw-r--r--site_scons/site_tools/auto_install_binaries.py74
1 files changed, 54 insertions, 20 deletions
diff --git a/site_scons/site_tools/auto_install_binaries.py b/site_scons/site_tools/auto_install_binaries.py
index bf133852051..6328f0ec0a4 100644
--- a/site_scons/site_tools/auto_install_binaries.py
+++ b/site_scons/site_tools/auto_install_binaries.py
@@ -362,18 +362,35 @@ def scan_for_transitive_install(node, env, cb=None):
return results
-def collect_transitive_files(env, source):
- """Collect all transitive files for source where source is a list of either Alias or File nodes."""
+def collect_transitive_files(env, source, installed, cache=None):
+ """Collect all installed transitive files for source where source is a list of either Alias or File nodes."""
+
+ if not cache:
+ cache = set()
+
files = []
for s in source:
+
+ cache.add(s)
+
if isinstance(s, SCons.Node.FS.File):
+ if s not in installed:
+ continue
files.append(s)
- else:
- files.extend(collect_transitive_files(env, s.children()))
- return files
+ children_to_collect = []
+ for child in s.children():
+ if child in cache:
+ continue
+ if isinstance(child, SCons.Node.FS.File) and child not in installed:
+ continue
+ children_to_collect.append(child)
+ if children_to_collect:
+ files.extend(collect_transitive_files(env, children_to_collect, installed, cache))
+
+ return files
def archive_builder(source, target, env, for_signature):
"""Build archives of the AutoInstall'd sources."""
@@ -381,11 +398,14 @@ def archive_builder(source, target, env, for_signature):
return
source = env.Flatten([source])
- common_ancestor = None
+ make_archive_script = source[0].get_abspath()
+ # We expect this to be a list of aliases, but really they could be
+ # any sort of node.
+ aliases = source[1:]
+
+ common_ancestor = None
archive_type = env["__AIB_ARCHIVE_TYPE"]
- make_archive_script = source[0].get_abspath()
- source = source[1:]
# Get the path elements that make up both DESTDIR and PREFIX. Then
# iterate the dest_dir_elems with the prefix path elements
@@ -403,8 +423,28 @@ def archive_builder(source, target, env, for_signature):
else:
common_ancestor = dest_dir_elems
- # Pre-process what should be in the archive
- transitive_files = collect_transitive_files(env, source)
+ archive_name = env.File(target[0]).get_abspath()
+
+ command_prefix = "{python} {make_archive_script} {archive_type} {archive_name} {common_ancestor}".format(
+ python=sys.executable,
+ archive_type=archive_type,
+ archive_name=archive_name,
+ make_archive_script=make_archive_script,
+ common_ancestor=common_ancestor,
+ )
+
+ # If we are just being invoked for our signature, we can omit the indirect dependencies
+ # found by expanding the transitive dependencies, since we really only have a hard dependency
+ # on our direct depenedencies.
+ if for_signature:
+ return command_prefix
+
+ # Pre-process what should be in the archive. We need to pass the
+ # set of known installed files along to the transitive dependency
+ # walk so we can filter out files that aren't in the install
+ # directory.
+ installed = env.get('__AIB_INSTALLED_SET', set())
+ transitive_files = collect_transitive_files(env, aliases, installed)
paths = {file.get_abspath() for file in transitive_files}
# The env["ESCAPE"] function is used by scons to make arguments
@@ -419,17 +459,8 @@ def archive_builder(source, target, env, for_signature):
escape_func(os.path.relpath(path, common_ancestor))
for path in paths
])
- archive_name = env.File(target[0]).get_abspath()
-
- return "{python} {make_archive_script} {archive_type} {archive_name} {common_ancestor} {relative_files}".format(
- python=sys.executable,
- archive_type=archive_type,
- archive_name=archive_name,
- make_archive_script=make_archive_script,
- common_ancestor=common_ancestor,
- relative_files=relative_files,
- )
+ return " ".join([command_prefix, relative_files])
def auto_install(env, target, source, **kwargs):
@@ -517,6 +548,8 @@ def auto_install(env, target, source, **kwargs):
def finalize_install_dependencies(env):
"""Generates package aliases and wires install dependencies."""
+ installed = set(env.FindInstalledFiles())
+
for component, rolemap in env[ALIAS_MAP].items():
for role, info in rolemap.items():
info.alias.extend(env.Alias(info.alias_name, info.actions))
@@ -563,6 +596,7 @@ def finalize_install_dependencies(env):
target="#{}.{}".format(pkg_name, pkg_suffix),
source=[make_archive_script] + info.alias,
__AIB_ARCHIVE_TYPE=fmt,
+ __AIB_INSTALLED_SET=installed,
AIB_COMPONENT=component,
AIB_ROLE=role,
)