Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
fcc2184
test workflow
sunmou99 Apr 3, 2023
e2e6a79
Merge branch 'master' into api-changes
sunmou99 Apr 3, 2023
684c947
test workflow
sunmou99 Apr 3, 2023
461a328
test workflow
sunmou99 Apr 3, 2023
f47aebf
test workflow
sunmou99 Apr 3, 2023
d7c48f8
test workflow
sunmou99 Apr 3, 2023
ba50f3b
test workflow
sunmou99 Apr 4, 2023
749f551
test workflow
sunmou99 Apr 4, 2023
bb5e213
test workflow
sunmou99 Apr 4, 2023
7dae765
test workflow
sunmou99 Apr 4, 2023
6261804
test workflow
sunmou99 Apr 4, 2023
fa40cee
test workflow
sunmou99 Apr 4, 2023
846b6ab
test workflow
sunmou99 Apr 4, 2023
7d30347
test workflow
sunmou99 Apr 4, 2023
50e7f4a
test workflow
sunmou99 Apr 4, 2023
bc2f2a1
test workflow
sunmou99 Apr 4, 2023
c3e9c73
test workflow
sunmou99 Apr 4, 2023
65425a4
test workflow
sunmou99 Apr 4, 2023
62bebb2
test workflow
sunmou99 Apr 4, 2023
7748992
test workflow
sunmou99 Apr 4, 2023
da76aa2
test workflow
sunmou99 Apr 4, 2023
6810613
test workflow
sunmou99 Apr 4, 2023
e3ce84d
test workflow
sunmou99 Apr 4, 2023
2cbde2b
test objc
sunmou99 Apr 4, 2023
3bdbe25
test objc
sunmou99 Apr 4, 2023
3e6f4c9
test objc
sunmou99 Apr 4, 2023
49b0076
test objc
sunmou99 Apr 4, 2023
2af340f
test objc
sunmou99 Apr 4, 2023
efbba34
test objc
sunmou99 Apr 4, 2023
de15fd1
test swift diff
sunmou99 Apr 4, 2023
63c3053
test swift diff
sunmou99 Apr 4, 2023
4c2f0c9
test swift diff
sunmou99 Apr 4, 2023
70aaa6d
test swift diff
sunmou99 Apr 4, 2023
d68141e
test objc
sunmou99 Apr 5, 2023
c95123e
test both objc & swift
sunmou99 Apr 5, 2023
22a5f4b
test both objc & swift
sunmou99 Apr 6, 2023
deb85ab
get target
sunmou99 Apr 10, 2023
2eec0c4
get target
sunmou99 Apr 10, 2023
408cd69
get target
sunmou99 Apr 10, 2023
9db8d6a
get target
sunmou99 Apr 11, 2023
954f62c
get target
sunmou99 Apr 11, 2023
0255c5b
get target
sunmou99 Apr 11, 2023
ef5aac6
build target
sunmou99 Apr 11, 2023
5277ac7
build target
sunmou99 Apr 11, 2023
c9fd70d
build target
sunmou99 Apr 11, 2023
60fad46
build target
sunmou99 Apr 11, 2023
8a47513
build target
sunmou99 Apr 11, 2023
f53bf7d
build target
sunmou99 Apr 11, 2023
fb5468b
build target
sunmou99 Apr 11, 2023
655f4d7
build target
sunmou99 Apr 11, 2023
14b0ef1
build target
sunmou99 Apr 11, 2023
28e60c4
build target
sunmou99 Apr 11, 2023
ff137dc
build target
sunmou99 Apr 11, 2023
a421ea0
build target
sunmou99 Apr 11, 2023
6c5bd34
build target
sunmou99 Apr 11, 2023
77cc52d
build target
sunmou99 Apr 11, 2023
1d531be
test more type of APIs
sunmou99 Apr 11, 2023
d9669f6
text diff
sunmou99 Apr 12, 2023
7280d29
text diff for -Swift.h
sunmou99 Apr 12, 2023
b255f31
text diff for -Swift.h
sunmou99 Apr 12, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 31 additions & 4 deletions .github/workflows/api_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,41 @@ jobs:

- name: Checkout PR branch
uses: actions/checkout@v3
with:
fetch-depth: 2

- id: get_changed_files
run: echo "file_list=$(git diff --name-only -r HEAD^1 HEAD | tr '\n' ' ')" >> $GITHUB_OUTPUT

- name: Setup python
uses: actions/setup-python@v4
with:
python-version: 3.7

- name: Make diff directory
run: mkdir ~/diff
- name: Copy script
run: |
cp scripts/api_diff_report/api_info.py ~/api_info.py
cp scripts/api_diff_report/api_diff.py ~/api_diff.py

- name: List changed files
run: git diff --name-only ${{ github.base_ref }})
- name: Generate API files for PR branch
run: python ~/api_info.py -f ${{ steps.get_changed_files.outputs.file_list }} -o "~/merge_branch"

- name: Checkout master
uses: actions/checkout@v3
with:
ref: ${{ github.base_ref }}

- name: Generate API files for Base branch
run: python ~/api_info.py -f ${{ steps.get_changed_files.outputs.file_list }} -o "~/base_branch"

- name: Diff
run: python ~/api_diff.py -m "~/merge_branch" -b "~/base_branch"

- uses: actions/upload-artifact@v3
if: ${{ !cancelled() }}
with:
name: api_info
path: |
~/merge_branch
~/base_branch
retention-days: 1
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,13 @@ NS_SWIFT_NAME(AppDistribution)
/**
* Sign-in the App Distribution tester
*/
- (void)signInTesterWithCompletion:(void (^)(NSError *_Nullable error))completion
- (void)signInTesterWithCompletion:(void (^)(NSError * error))completion
NS_SWIFT_NAME(signInTester(completion:));

/**
* Check to see whether a new distribution is available
*/
- (void)checkForUpdateWithCompletion:(void (^)(FIRAppDistributionRelease *_Nullable_result release,
NSError *_Nullable error))completion
- (void)checkForUpdateWithCompletion:(void (^)(FIRAppDistributionRelease *_Nullable_result release))completion
NS_SWIFT_NAME(checkForUpdate(completion:));

/**
Expand Down
5 changes: 4 additions & 1 deletion FirebaseCore/Sources/Public/FirebaseCore/FIRApp.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ NS_ASSUME_NONNULL_BEGIN
typedef void (^FIRAppVoidBoolCallback)(BOOL success)
NS_SWIFT_UNAVAILABLE("Use Swift's closure syntax instead.");

typedef void (^FIRAppVoidBoolCallbackTest)(BOOL success)
NS_SWIFT_UNAVAILABLE("Use Swift's closure syntax instead.");

/**
* The entry point of Firebase SDKs.
*
Expand Down Expand Up @@ -61,7 +64,7 @@ NS_SWIFT_NAME(FirebaseApp)
*
* @param options The Firebase application options used to configure the service.
*/
+ (void)configureWithOptions:(FIROptions *)options NS_SWIFT_NAME(configure(options:));
+ (void)configureWithOptions:(FIROptions *__nullable)options NS_SWIFT_NAME(configure(options:));

/**
* Configures a Firebase app with the given name and options. Raises an exception if any
Expand Down
1 change: 1 addition & 0 deletions FirebaseCore/Sources/Public/FirebaseCore/FIRLoggerLevel.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
* The log levels used by internal logging.
*/
typedef NS_ENUM(NSInteger, FIRLoggerLevel) {
FIRLoggerLevelTest = 999,
/** Error level, matches ASL_LEVEL_ERR. */
FIRLoggerLevelError = 3,
/** Warning level, matches ASL_LEVEL_WARNING. */
Expand Down
2 changes: 1 addition & 1 deletion FirebaseCore/Sources/Public/FirebaseCore/FIRVersion.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ NS_ASSUME_NONNULL_BEGIN

/** Returns the current version of Firebase. */
NS_SWIFT_NAME(FirebaseVersion())
NSString* FIRFirebaseVersion(void);
NSString* FIRFirebaseVersion(NSString *);

NS_ASSUME_NONNULL_END
2 changes: 1 addition & 1 deletion FirebaseMLModelDownloader/Sources/ModelDownloadTask.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import Foundation

/// Task to download model file to device.
class ModelDownloadTask {
public final class ModelDownloadTask {
/// Name of the app associated with this instance of ModelDownloadTask.
private let appName: String

Expand Down
10 changes: 9 additions & 1 deletion FirebaseMLModelDownloader/Sources/ModelDownloader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,21 @@ public class ModelDownloader {
}

/// Model downloader with default app.
public static func modelDownloader() -> ModelDownloader {
public static func modelDownloader() -> ModelDownloader? {
guard let defaultApp = FirebaseApp.app() else {
fatalError(ModelDownloader.ErrorDescription.defaultAppNotConfigured)
}
return modelDownloader(app: defaultApp)
}

/// Model downloader with default app.
public static func modelDownloaderNullable() -> ModelDownloader? {
guard let defaultApp = FirebaseApp.app() else {
fatalError(ModelDownloader.ErrorDescription.defaultAppNotConfigured)
}
return nil
}

/// Model Downloader with custom app.
public static func modelDownloader(app: FirebaseApp) -> ModelDownloader {
if let downloader = modelDownloaderDictionary[app.name] {
Expand Down
167 changes: 167 additions & 0 deletions scripts/api_diff_report/api_diff.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# 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 subprocess

OBJC_EXTENSION = "h"
SWIFT_EXTENSION = "swift"

KEY_KIND = {
"source.lang.swift.decl.function.method.instance": "",
"source.lang.swift.decl.function.method.static": "static"
}

def main():
logging.getLogger().setLevel(logging.INFO)

args = parse_cmdline_args()
logging.info(args)

merged_branch = os.path.expanduser(args.merged_branch)
base_branch = os.path.expanduser(args.base_branch)

for file_name in os.listdir(merged_branch):
logging.info(f"\n\nDetect API changes in {file_name}")
merged_file = os.path.join(merged_branch, file_name)
base_file = os.path.join(base_branch, file_name)
api_diff(merged_file, base_file)
text_diff(merged_file, base_file)


def text_diff(merged_file, base_file):
result = subprocess.Popen(f"git diff --no-index --word-diff {merged_file} {base_file}",
universal_newlines=True,
shell=True,
stdout=subprocess.PIPE)
logging.info("------------")
api_info = result.stdout.read()
logging.info(api_info)


def api_diff(merged_file, base_file):
file_extension = merged_file.split(".")[1]
if file_extension == OBJC_EXTENSION:
pr_apis = get_objc_public_apis(json.load(open(merged_file)))
base_apis = get_objc_public_apis(json.load(open(base_file)))

pr_only_apis = get_objc_diff(pr_apis, base_apis)
base_only_apis = get_objc_diff(base_apis, pr_apis)
logging.info("Added APIs")
print_objc_diff(pr_only_apis)
logging.info("\nRemoved APIS")
print_objc_diff(base_only_apis)
elif file_extension == SWIFT_EXTENSION:
pr_apis = get_swift_public_apis(json.load(open(merged_file)))
base_apis = get_swift_public_apis(json.load(open(base_file)))

pr_only_apis = get_swift_diff(pr_apis, base_apis)
base_only_apis = get_swift_diff(base_apis, pr_apis)
logging.info("Added APIs")
print_swift_diff(pr_only_apis)
logging.info("\nRemoved APIS")
print_swift_diff(base_only_apis)


def get_swift_public_apis(api_json):
# key: file name
# value: all classes and functions
# only one key, value pair
for key, value in api_json.items():
# filter out non-public classes
public_apis = [sc for sc in value["key.substructure"] if "key.accessibility" in sc and sc["key.accessibility"] == "source.lang.swift.accessibility.public"]
for sc in public_apis:
# filter out non-public functions
sc["key.substructure"] = [f for f in sc["key.substructure"] if "key.accessibility" in f and f["key.accessibility"] == "source.lang.swift.accessibility.public"]
return public_apis


def get_swift_diff(target, base):
diff = {"class":[], "function":[]}

for tc in target:
for bc in base:
# check for same public classes
if tc["key.kind"] == bc["key.kind"] and tc["key.name"] == bc["key.name"]:
# check for same public functions
for tf in tc["key.substructure"]:
if "key.typename" in tf:
for bf in bc["key.substructure"]:
if tf["key.kind"] == bf["key.kind"] and tf["key.name"] == bf["key.name"] and tf["key.typename"] == bf["key.typename"]:
break
else:
diff["function"].append(tf)
break
else:
diff["class"].append(tc)
return diff


def print_swift_diff(diff):
for c in diff["class"]:
logging.info(f'{c["key.name"]}')
for f in diff["function"]:
logging.info(f'Function: public {KEY_KIND[f["key.kind"]]} func {f["key.name"]} -> {f["key.typename"]}')


def get_objc_public_apis(api_json):
for key, value in api_json[0].items():
return value["key.substructure"]


def get_objc_diff(target, base):
diff = {"class":[], "function":[]}

for tc in target:
for bc in base:
# check for same public classes
if tc["key.kind"] == bc["key.kind"] and tc["key.name"] == bc["key.name"] and tc["key.parsed_declaration"] == bc["key.parsed_declaration"]:
# check for same public functions
if "key.substructure" in tc:
for tf in tc["key.substructure"]:
for bf in bc["key.substructure"]:
if tf["key.kind"] == bf["key.kind"] and tf["key.name"] == bf["key.name"] and tf["key.parsed_declaration"] == bf["key.parsed_declaration"]:
break
else:
diff["function"].append(tf)
break
else:
diff["class"].append(tc)
return diff


def print_objc_diff(diff):
for c in diff["class"]:
logging.info(f'Class: {c["key.kind"]} {c["key.name"]}')
for f in diff["function"]:
logging.info(f'OBJC Function: {f["key.parsed_declaration"]}')
for f in diff["function"]:
if "key.swift_declaration" in f:
logging.info(f'SWIFT Function: {f["key.swift_declaration"]}')


def parse_cmdline_args():
parser = argparse.ArgumentParser()
parser.add_argument('-m', '--merged_branch')
parser.add_argument('-b', '--base_branch')

args = parser.parse_args()
return args


if __name__ == '__main__':
main()
Loading