Skip to content

Commit

Permalink
fix: link type detection for frameworks (#717)
Browse files Browse the repository at this point in the history
- The `find()` result for the file type results was broken. It was not
detecting matches at the front of the string and it was not checking the
dynamic result properly.
- Relaxed the static check to support additional file type results found
in the wild.
- Add unit tests.
  • Loading branch information
cgrindel authored Nov 3, 2023
1 parent 4464d4d commit 994e543
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 8 deletions.
34 changes: 27 additions & 7 deletions swiftpkg/internal/artifact_infos.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -89,18 +89,37 @@ def _new_framework_info_from_files(repository_ctx, path):
)
if len(binary_files) == 0:
fail("No binary files were found for framework at {}".format(path))
file_type = repository_files.file_type(repository_ctx, binary_files[0])
if file_type.find("ar archive random library") > 0:
link_type = link_types.static
elif file_type.find("dynamically linked shared library"):
link_type = link_types.dynamic
else:
link_type = link_types.unknown
link_type = _link_type(repository_ctx, binary_files[0])

return _new_framework_info(
path = path,
link_type = link_type,
)

def _link_type(repository_ctx, path):
"""Determine the link type for the framework binary file.
Args:
repository_ctx: A `repository_ctx` instance.
path: The path to a framework binary file under a `XXX.framework`
directory as a `string`.
Returns:
The link type for the framework as a `string`.
"""
file_type = repository_files.file_type(repository_ctx, path)

# static Examples:
# current ar archive random library
# current ar archive
# dynamic Examples:
# dynamically linked shared library
if file_type.find("ar archive") >= 0:
return link_types.static
elif file_type.find("dynamic") >= 0:
return link_types.dynamic
return link_types.unknown

def _new_xcframework_info_from_files(repository_ctx, path):
"""Return a `struct` descrbing an xcframework from the files at the \
specified path.
Expand Down Expand Up @@ -139,6 +158,7 @@ artifact_infos = struct(
new_framework_info = _new_framework_info,
new_xcframework_info = _new_xcframework_info,
new_xcframework_info_from_files = _new_xcframework_info_from_files,
link_type = _link_type,
)

link_types = struct(
Expand Down
3 changes: 3 additions & 0 deletions swiftpkg/tests/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
load("@cgrindel_bazel_starlib//bzlformat:defs.bzl", "bzlformat_pkg")
load(":artifact_infos_tests.bzl", "artifact_infos_test_suite")
load(":bazel_apple_platforms_tests.bzl", "bazel_apple_platforms_test_suite")
load(":bazel_repo_names_tests.bzl", "bazel_repo_names_test_suite")
load(":build_decls_tests.bzl", "build_decls_test_suite")
Expand All @@ -22,6 +23,8 @@ load(":validations_tests.bzl", "validations_test_suite")

bzlformat_pkg(name = "bzlformat")

artifact_infos_test_suite()

bazel_apple_platforms_test_suite()

bazel_repo_names_test_suite()
Expand Down
56 changes: 56 additions & 0 deletions swiftpkg/tests/artifact_infos_tests.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
"""Tests for `artifact_infos` module."""

load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest")
load("//swiftpkg/internal:artifact_infos.bzl", "artifact_infos", "link_types")
load(":testutils.bzl", "testutils")

def _link_type_test(ctx):
env = unittest.begin(ctx)

tests = [
struct(
msg = "current ar archive",
file_type = """\
path/to/framework/binary/FooBar (for architecture x86_64): current ar archive
path/to/framework/binary/FooBar (for architecture arm64): current ar archive
""",
exp = link_types.static,
),
struct(
msg = "current ar archive random library",
file_type = """\
Mach-O universal binary with 2 architectures: [x86_64:current ar archive random library] [arm64:current ar archive random library]
path/to/framework/binary/FooBar (for architecture x86_64): current ar archive random library
path/to/framework/binary/FooBar (for architecture arm64): current ar archive random library
""",
exp = link_types.static,
),
struct(
msg = "dynamically linked shared library",
file_type = "dynamically linked shared library",
exp = link_types.dynamic,
),
struct(
msg = "unknown",
file_type = "no idea what this is",
exp = link_types.unknown,
),
]
for t in tests:
path = "path/to/framework/binary/FooBar"
stub_repository_ctx = testutils.new_stub_repository_ctx(
repo_name = "chicken",
file_type_results = {path: t.file_type},
)
actual = artifact_infos.link_type(stub_repository_ctx, "path/to/framework/binary/FooBar")
asserts.equals(env, t.exp, actual, t.msg)

return unittest.end(env)

link_type_test = unittest.make(_link_type_test)

def artifact_infos_test_suite(name = "artifact_infos_tests"):
return unittest.suite(
name,
link_type_test,
)
8 changes: 7 additions & 1 deletion swiftpkg/tests/testutils.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ def _new_stub_repository_ctx(
repo_name,
file_contents = {},
find_results = {},
is_directory_results = {}):
is_directory_results = {},
file_type_results = {}):
def read(path):
return file_contents.get(path, "")

Expand All @@ -34,6 +35,11 @@ def _new_stub_repository_ctx(
exec_result = _new_exec_result(
stdout = "\n".join(results),
)
elif args_len == 3 and args[0] == "file" and args[1] == "--brief":
# Expected command: `file --brief path`
path = args[2]
results = file_type_results.get(path, "")
exec_result = _new_exec_result(stdout = results)
else:
exec_result = _new_exec_result()
return exec_result
Expand Down

0 comments on commit 994e543

Please sign in to comment.