mirror of
https://github.com/firebase/firebase-ios-sdk
synced 2026-11-10 22:45:59 +05:45
This reverts commit 8056cdacc0.
This commit is contained in:
1 parent
a00925f7eb
commit
e7c5c9713b
11 files changed
-962
No files matched your search
@@ -1,261 +0,0 @@
|
||||
# Copyright 2023 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import json
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import api_info
|
||||
import datetime
|
||||
import pytz
|
||||
|
||||
STATUS_ADD = 'ADDED'
|
||||
STATUS_REMOVED = 'REMOVED'
|
||||
STATUS_MODIFIED = 'MODIFIED'
|
||||
STATUS_ERROR = 'BUILD ERROR'
|
||||
|
||||
|
||||
def main():
|
||||
logging.getLogger().setLevel(logging.INFO)
|
||||
|
||||
args = parse_cmdline_args()
|
||||
|
||||
pr_branch = os.path.expanduser(args.pr_branch)
|
||||
base_branch = os.path.expanduser(args.base_branch)
|
||||
new_api_json = json.load(
|
||||
open(os.path.join(pr_branch, api_info.API_INFO_FILE_NAME)))
|
||||
old_api_json = json.load(
|
||||
open(os.path.join(base_branch, api_info.API_INFO_FILE_NAME)))
|
||||
|
||||
diff = generate_diff_json(new_api_json, old_api_json)
|
||||
if diff:
|
||||
logging.info(f'json diff: \n{json.dumps(diff, indent=2)}')
|
||||
logging.info(f'plain text diff report: \n{generate_text_report(diff)}')
|
||||
logging.info(
|
||||
f'markdown diff report title: \n{generate_markdown_title(args.commit, args.run_id)}'
|
||||
)
|
||||
logging.info(
|
||||
f'markdown diff report: \n{generate_markdown_report(diff)}')
|
||||
else:
|
||||
logging.info('No API Diff Detected.')
|
||||
|
||||
|
||||
def generate_diff_json(new_api, old_api, level='module'):
|
||||
"""diff_json only contains module & api that has a change.
|
||||
|
||||
format:
|
||||
{
|
||||
$(module_name_1): {
|
||||
"api_types": {
|
||||
$(api_type_1): {
|
||||
"apis": {
|
||||
$(api_1): {
|
||||
"declaration": [
|
||||
$(api_1_declaration)
|
||||
],
|
||||
"sub_apis": {
|
||||
$(sub_api_1): {
|
||||
"declaration": [
|
||||
$(sub_api_1_declaration)
|
||||
]
|
||||
},
|
||||
},
|
||||
"status": $(diff_status)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
NEXT_LEVEL = {
|
||||
'module': 'api_types',
|
||||
'api_types': 'apis',
|
||||
'apis': 'sub_apis'
|
||||
}
|
||||
next_level = NEXT_LEVEL.get(level)
|
||||
|
||||
diff = {}
|
||||
for key in set(new_api.keys()).union(old_api.keys()):
|
||||
# Added API
|
||||
if key not in old_api:
|
||||
diff[key] = new_api[key]
|
||||
diff[key]['status'] = STATUS_ADD
|
||||
if diff[key].get('declaration'):
|
||||
diff[key]['declaration'] = [STATUS_ADD
|
||||
] + diff[key]['declaration']
|
||||
# Removed API
|
||||
elif key not in new_api:
|
||||
diff[key] = old_api[key]
|
||||
diff[key]['status'] = STATUS_REMOVED
|
||||
if diff[key].get('declaration'):
|
||||
diff[key]['declaration'] = [STATUS_REMOVED
|
||||
] + diff[key]['declaration']
|
||||
# Moudle Build Error. If a "module" exist but have no
|
||||
# content (e.g. doc_path), it must have a build error.
|
||||
elif level == 'module' and (not new_api[key]['path']
|
||||
or not old_api[key]['path']):
|
||||
diff[key] = {'status': STATUS_ERROR}
|
||||
# Check diff in clild level and diff in declaration
|
||||
else:
|
||||
child_diff = generate_diff_json(
|
||||
new_api[key][next_level],
|
||||
old_api[key][next_level],
|
||||
level=next_level) if next_level else {}
|
||||
declaration_diff = new_api[key].get(
|
||||
'declaration') != old_api[key].get('declaration') if level in [
|
||||
'apis', 'sub_apis'
|
||||
] else False
|
||||
|
||||
# No diff
|
||||
if not child_diff and not declaration_diff:
|
||||
continue
|
||||
|
||||
diff[key] = new_api[key]
|
||||
# Changes at child level
|
||||
if child_diff:
|
||||
diff[key][next_level] = child_diff
|
||||
|
||||
# Modified API (changes in API declaration)
|
||||
if declaration_diff:
|
||||
diff[key]['status'] = STATUS_MODIFIED
|
||||
diff[key]['declaration'] = [STATUS_ADD] + new_api[key]['declaration'] + \
|
||||
[STATUS_REMOVED] + old_api[key]['declaration']
|
||||
|
||||
return diff
|
||||
|
||||
|
||||
def generate_text_report(diff, level=0, print_key=True):
|
||||
report = ''
|
||||
indent_str = ' ' * level
|
||||
for key, value in diff.items():
|
||||
# filter out ["path", "api_type_link", "api_link", "declaration", "status"]
|
||||
if isinstance(value, dict):
|
||||
if key in ['api_types', 'apis', 'sub_apis']:
|
||||
report += generate_text_report(value, level=level)
|
||||
else:
|
||||
status_text = f"{value.get('status', '')}: " if 'status' in value else ''
|
||||
if status_text:
|
||||
if print_key:
|
||||
report += f'{indent_str}{status_text}{key}\n'
|
||||
else:
|
||||
report += f'{indent_str}{status_text}\n'
|
||||
if value.get('declaration'):
|
||||
for d in value.get('declaration'):
|
||||
report += f'{indent_str}{d}\n'
|
||||
else:
|
||||
report += f'{indent_str}{key}\n'
|
||||
report += generate_text_report(value, level=level + 1)
|
||||
|
||||
return report
|
||||
|
||||
|
||||
def generate_markdown_title(commit, run_id):
|
||||
pst_now = datetime.datetime.utcnow().astimezone(
|
||||
pytz.timezone('America/Los_Angeles'))
|
||||
return (
|
||||
'## Apple API Diff Report\n' + 'Commit: %s\n' % commit +
|
||||
'Last updated: %s \n' % pst_now.strftime('%a %b %e %H:%M %Z %G') +
|
||||
'**[View workflow logs & download artifacts](https://github.com/firebase/firebase-cpp-sdk/actions/runs/%s)**\n\n'
|
||||
% run_id + '-----\n')
|
||||
|
||||
|
||||
def generate_markdown_report(diff, level=0):
|
||||
report = ''
|
||||
header_str = '#' * (level + 3)
|
||||
for key, value in diff.items():
|
||||
if isinstance(value, dict):
|
||||
if key in ['api_types', 'apis', 'sub_apis']:
|
||||
report += generate_markdown_report(value, level=level)
|
||||
else:
|
||||
current_status = value.get('status')
|
||||
if current_status:
|
||||
if level == 0: # Module level: Always print out module name as title
|
||||
report += f'{header_str} {key} [{current_status}]\n'
|
||||
if current_status != STATUS_ERROR: # ADDED,REMOVED,MODIFIED
|
||||
report += f'<details>\n<summary>\n[{current_status}] {key}\n</summary>\n\n'
|
||||
declarations = value.get('declaration', [])
|
||||
sub_report = generate_text_report(value,
|
||||
level=1,
|
||||
print_key=False)
|
||||
detail = process_declarations(current_status,
|
||||
declarations, sub_report)
|
||||
report += f'```diff\n{detail}\n```\n\n</details>\n\n'
|
||||
else: # no diff at current level
|
||||
report += f'{header_str} {key}\n'
|
||||
report += generate_markdown_report(value, level=level + 1)
|
||||
|
||||
if level == 0: # Module level: Always print out divider in the end
|
||||
report += '-----\n'
|
||||
|
||||
return report
|
||||
|
||||
|
||||
def process_declarations(current_status, declarations, sub_report):
|
||||
"""Diff syntax highlighting in Github Markdown."""
|
||||
detail = ''
|
||||
if current_status == STATUS_MODIFIED:
|
||||
for line in (declarations + sub_report.split('\n')):
|
||||
if STATUS_ADD in line:
|
||||
prefix = '+ '
|
||||
continue
|
||||
elif STATUS_REMOVED in line:
|
||||
prefix = '- '
|
||||
continue
|
||||
if line:
|
||||
detail += f'{prefix}{line}\n'
|
||||
else:
|
||||
prefix = '+ ' if current_status == STATUS_ADD else '- '
|
||||
for line in (declarations + sub_report.split('\n')):
|
||||
if line:
|
||||
detail += f'{prefix}{line}\n'
|
||||
|
||||
return categorize_declarations(detail)
|
||||
|
||||
|
||||
def categorize_declarations(detail):
|
||||
"""Categorize API info by Swift and Objective-C."""
|
||||
lines = detail.split('\n')
|
||||
|
||||
swift_lines = [
|
||||
line.replace('Swift', '') for line in lines if 'Swift' in line
|
||||
]
|
||||
objc_lines = [
|
||||
line.replace('Objective-C', '') for line in lines
|
||||
if 'Objective-C' in line
|
||||
]
|
||||
|
||||
swift_detail = 'Swift:\n' + '\n'.join(swift_lines) if swift_lines else ''
|
||||
objc_detail = 'Objective-C:\n' + '\n'.join(
|
||||
objc_lines) if objc_lines else ''
|
||||
|
||||
if not swift_detail and not objc_detail:
|
||||
return detail
|
||||
else:
|
||||
return f'{swift_detail}\n{objc_detail}'.strip()
|
||||
|
||||
|
||||
def parse_cmdline_args():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('-p', '--pr_branch')
|
||||
parser.add_argument('-b', '--base_branch')
|
||||
parser.add_argument('-c', '--commit')
|
||||
parser.add_argument('-i', '--run_id')
|
||||
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in new issue
Block a user