platform_diff.py (3998B)
1 # This Source Code Form is subject to the terms of the Mozilla Public 2 # License, v. 2.0. If a copy of the MPL was not distributed with this 3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 5 import json 6 import logging 7 from typing import Optional 8 9 import requests 10 11 ERROR = "error" 12 USER_AGENT = "mach-runner-diff/1.0" 13 14 15 class PlatformDiff: 16 def __init__( 17 self, 18 command_context, 19 task_id: str, 20 replace: Optional[str], 21 ) -> None: 22 self.command_context = command_context 23 self.component = "platform-diff" 24 self.task_id = task_id 25 try: 26 self.replace: Optional[list[str]] = json.loads(replace) if replace else None 27 except json.JSONDecodeError: 28 self.error( 29 f"Invalid JSON supplied to 'replace': '{replace}'. Ignoring parameter." 30 ) 31 self.replace = None 32 33 def error(self, e): 34 self.command_context.log( 35 logging.ERROR, self.component, {ERROR: str(e)}, "ERROR: {error}" 36 ) 37 38 def info(self, e): 39 self.command_context.log( 40 logging.INFO, self.component, {ERROR: str(e)}, "INFO: {error}" 41 ) 42 43 def run(self): 44 tgdiff = self.get_tgdiff() 45 total_added, total_removed, new_platforms, missing_platforms = ( 46 self.get_diff_lines(tgdiff) 47 ) 48 self.info("") 49 self.info(f"Total new platforms added: \033[34m{len(total_added)}\033[0m") 50 if len(new_platforms) > 0: 51 self.info("") 52 self.info( 53 f"New platforms not replacing old one (\033[34m{len(new_platforms)}\033[0m):" 54 ) 55 self.info("") 56 for platform in new_platforms: 57 self.info(f"\033[93m{platform}\033[0m") 58 59 self.info("") 60 self.info(f"Total old platforms removed: \033[34m{len(total_removed)}\033[0m") 61 if len(missing_platforms) > 0: 62 self.info("") 63 self.info( 64 f"Old platforms missing and their suggested new platform equivalent (\033[34m{len(missing_platforms)}\033[0m):" 65 ) 66 self.info("") 67 for platform in missing_platforms: 68 original, suggestion = next( 69 x for x in total_removed if x[1] == platform 70 ) 71 self.info(f"\033[93m{original}\033[0m -> \033[34m{suggestion}\033[0m") 72 73 def transform_old_platform(self, old_platform: str): 74 new_platform = old_platform 75 if self.replace is not None: 76 for r in self.replace: 77 split = r.split("=", 1) 78 if len(split) == 1: 79 split.append("") 80 new_platform = new_platform.replace(split[0], split[1]) 81 82 return new_platform 83 84 def get_diff_lines( 85 self, tgdiff: str 86 ) -> tuple[set[str], set[tuple[str, str]], set[str], set[str]]: 87 total_added: set[str] = set() 88 total_removed: set[tuple[str, str]] = set() 89 for line in tgdiff.split("\n"): 90 if line.startswith("+++") or line.startswith("---"): 91 continue 92 if line.startswith("+"): 93 total_added.add(line.strip("+")) 94 elif line.startswith("-"): 95 total_removed.add(( 96 line.strip("-"), 97 self.transform_old_platform(line.strip("-")), 98 )) 99 100 total_removed_suggestion = set([r[1] for r in total_removed]) 101 new_platforms = total_added - total_removed_suggestion 102 missing_platforms = total_removed_suggestion - total_added 103 return ((total_added), (total_removed), (new_platforms), (missing_platforms)) 104 105 def get_tgdiff(self) -> str: 106 url = f"https://firefoxci.taskcluster-artifacts.net/{self.task_id}/0/public/taskgraph/diffs/diff_mc-onpush.txt" 107 self.info(f"Fetching diff from {url}") 108 response = requests.get(url, headers={"User-agent": USER_AGENT}) 109 return response.text