Avoid post-install when nothing is installed (#736)

This avoids re-running the post-install scripts when commands such as
`./emsdk install latest` a re-run.  This re-running of npm ci can be
significant slowdown especially during testing and developerment.

Becuase of the refactoring this change change also means we exit ealier
when a given tool fails to install.  In general we want to error out as
early as possible on the first failure so as not to bury it.
This commit is contained in:
Sam Clegg
2021-03-01 09:32:07 -08:00
committed by GitHub
parent f788ca9208
commit 0a841562df
2 changed files with 52 additions and 44 deletions

View File

@@ -1828,9 +1828,11 @@ class Tool(object):
return None return None
def install(self): def install(self):
"""Returns True if the Tool was installed of False if was skipped due to
already being installed.
"""
if self.can_be_installed() is not True: if self.can_be_installed() is not True:
print("The tool '" + str(self) + "' is not available due to the reason: " + self.can_be_installed()) exit_with_error("The tool '" + str(self) + "' is not available due to the reason: " + self.can_be_installed())
return False
if self.id == 'sdk': if self.id == 'sdk':
return self.install_sdk() return self.install_sdk()
@@ -1838,33 +1840,42 @@ class Tool(object):
return self.install_tool() return self.install_tool()
def install_sdk(self): def install_sdk(self):
"""Returns True if any SDK component was installed of False all componented
were already installed.
"""
print("Installing SDK '" + str(self) + "'..") print("Installing SDK '" + str(self) + "'..")
installed = False
for tool_name in self.uses: for tool_name in self.uses:
tool = find_tool(tool_name) tool = find_tool(tool_name)
if tool is None: if tool is None:
print("Manifest error: No tool by name '" + tool_name + "' found! This may indicate an internal SDK error!") exit_with_error("Manifest error: No tool by name '" + tool_name + "' found! This may indicate an internal SDK error!")
success = tool.install() installed |= tool.install()
if not success:
if not installed:
print("All SDK components already installed: '" + str(self) + "'.")
return False return False
if getattr(self, 'custom_install_script', None) == 'emscripten_npm_install': if getattr(self, 'custom_install_script', None) == 'emscripten_npm_install':
# upstream tools have hardcoded paths that are not stored in emsdk_manifest.json registry # upstream tools have hardcoded paths that are not stored in emsdk_manifest.json registry
install_path = 'upstream' if 'releases-upstream' in self.version else 'fastcomp' install_path = 'upstream' if 'releases-upstream' in self.version else 'fastcomp'
success = emscripten_npm_install(self, os.path.join(emsdk_path(), install_path, 'emscripten')) if not emscripten_npm_install(self, os.path.join(emsdk_path(), install_path, 'emscripten')):
if not success: exit_with_error('post-install step failed: emscripten_npm_install')
return False
print("Done installing SDK '" + str(self) + "'.") print("Done installing SDK '" + str(self) + "'.")
return True return True
def install_tool(self): def install_tool(self):
"""Returns True if the SDK was installed of False if was skipped due to
already being installed.
"""
# Avoid doing a redundant reinstall of the tool, if it has already been installed. # Avoid doing a redundant reinstall of the tool, if it has already been installed.
# However all tools that are sourced directly from git branches do need to be # However all tools that are sourced directly from git branches do need to be
# installed every time when requested, since the install step is then used to git # installed every time when requested, since the install step is then used to git
# pull the tool to a newer version. # pull the tool to a newer version.
if self.is_installed() and not hasattr(self, 'git_branch'): if self.is_installed() and not hasattr(self, 'git_branch'):
print("Skipped installing " + self.name + ", already installed.") print("Skipped installing " + self.name + ", already installed.")
return True return False
print("Installing tool '" + str(self) + "'..") print("Installing tool '" + str(self) + "'..")
url = self.download_url() url = self.download_url()
@@ -1892,7 +1903,9 @@ class Tool(object):
else: else:
success = False success = False
if success: if not success:
exit_with_error("Installation failed!")
if hasattr(self, 'custom_install_script'): if hasattr(self, 'custom_install_script'):
if self.custom_install_script == 'emscripten_post_install': if self.custom_install_script == 'emscripten_post_install':
success = emscripten_post_install(self) success = emscripten_post_install(self)
@@ -1907,6 +1920,9 @@ class Tool(object):
else: else:
raise Exception('Unknown custom_install_script command "' + self.custom_install_script + '"!') raise Exception('Unknown custom_install_script command "' + self.custom_install_script + '"!')
if not success:
exit_with_error("Installation failed!")
# Install an emscripten-version.txt file if told to, and if there is one. # Install an emscripten-version.txt file if told to, and if there is one.
# (If this is not an actual release, but some other build, then we do not # (If this is not an actual release, but some other build, then we do not
# write anything.) # write anything.)
@@ -1916,21 +1932,15 @@ class Tool(object):
if version: if version:
open(emscripten_version_file_path, 'w').write('"%s"' % version) open(emscripten_version_file_path, 'w').write('"%s"' % version)
if not success:
print("Installation failed!")
return False
print("Done installing tool '" + str(self) + "'.") print("Done installing tool '" + str(self) + "'.")
# Sanity check that the installation succeeded, and if so, remove unneeded # Sanity check that the installation succeeded, and if so, remove unneeded
# leftover installation files. # leftover installation files.
if self.is_installed(skip_version_check=True): if not self.is_installed(skip_version_check=True):
exit_with_error("Installation of '" + str(self) + "' failed, but no error was detected. Either something went wrong with the installation, or this may indicate an internal emsdk error.")
self.cleanup_temp_install_files() self.cleanup_temp_install_files()
self.update_installed_version() self.update_installed_version()
else:
print("Installation of '" + str(self) + "' failed, but no error was detected. Either something went wrong with the installation, or this may indicate an internal emsdk error.")
return False
return True return True
def cleanup_temp_install_files(self): def cleanup_temp_install_files(self):
@@ -3030,9 +3040,7 @@ def main(args):
tool = find_sdk(t) tool = find_sdk(t)
if tool is None: if tool is None:
return error_on_missing_tool(t) return error_on_missing_tool(t)
success = tool.install() tool.install()
if not success:
return 1
return 0 return 0
elif cmd == 'uninstall': elif cmd == 'uninstall':
if not args: if not args: