scripts/check_for_xcodebuild_warnings.py (69 lines of code) (raw):

#!/usr/bin/env fbpython # Copyright (c) Meta Platforms, Inc. and affiliates. # All rights reserved. # # This source code is licensed under the license found in the # LICENSE file in the root directory of this source tree. import os import pathlib import subprocess import sys from xcodebuild_warnings_allowlist import XCODEBUILD_WARNINGS_ALLOWLIST def main(): base_dir = git_base_dir() if is_git_dir() else generic_base_dir() os.chdir(base_dir) xcodebuild_command = " ".join( [ "xcodebuild clean build-for-testing", "-workspace FacebookSDK.xcworkspace", "-scheme BuildAllKits-Dynamic", "-destination 'platform=iOS Simulator,name=iPhone 13'", ] ) completed_process = subprocess.run( xcodebuild_command, shell=True, check=False, capture_output=True ) output_lines = completed_process.stdout.decode().splitlines() warning_lines = { line for line in output_lines if "warning: " in line or "error: " in line } # Make the output prettier by removing the base_dir from the warning file paths warning_lines = [line.replace(f"{base_dir}/", "") for line in warning_lines] non_allowlisted_warnings = [] for warning in warning_lines: can_ignore = any( allowed_warning_text in warning for allowed_warning_text in XCODEBUILD_WARNINGS_ALLOWLIST ) if not can_ignore: non_allowlisted_warnings.append(warning) # If there are warnings print an issue and exit if non_allowlisted_warnings: warning_count = len(non_allowlisted_warnings) warning_word = "WARNINGS" if warning_count > 1 else "WARNING" print_to_stderr( f"\nFAILED DUE TO THE FOLLOWING {warning_count} NON-ALLOWLISTED {warning_word}:" ) for i, warning in enumerate(non_allowlisted_warnings, start=1): print_to_stderr(f"{i}. {warning}") print_to_stderr( "If any of these warnings should be ALLOWLISTED, add them to xcodebuild_warnings_allowlist.py" ) sys.exit(1) if completed_process.returncode != 0: print(f"Failed to run xcodebuild. Return code: {completed_process.returncode}") print(f"STDERR: {completed_process.stderr.decode()}") sys.exit(completed_process.returncode) print("Check complete. No unexpected warnings encountered.") sys.exit(0) def is_git_dir(): return get_output("git rev-parse --is-inside-work-tree") == "true" def git_base_dir() -> str: return get_output("git rev-parse --show-toplevel") def generic_base_dir() -> str: scripts_dir = os.path.dirname(os.path.realpath(__file__)) return pathlib.Path(scripts_dir).parent.absolute() def print_to_stderr(*args, **kwargs): print(*args, file=sys.stderr, **kwargs) def get_output(command): """Returns the output of a shell command""" completed_process = subprocess.run( command, shell=True, check=False, capture_output=True ) if completed_process.returncode == 0: return completed_process.stdout.decode().rstrip() else: return completed_process.stderr.decode().rstrip() if __name__ == "__main__": main()