Skip to content

Commit

Permalink
Merge pull request #77 from bazel-ios/segiddins/incremental-project-g…
Browse files Browse the repository at this point in the history
…eneration-works

Generated xcodeproj improvements
  • Loading branch information
segiddins authored Jun 17, 2020
2 parents 73f8aa7 + 8eee097 commit 4f96d7b
Show file tree
Hide file tree
Showing 14 changed files with 160 additions and 34 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.xcodeproj/ linguist-generated=true
6 changes: 5 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ jobs:
- name: Select Xcode 11.2
run: sudo xcode-select -s /Applications/Xcode_11.2.app
- name: Generate Xcode projects and compare against existing record
run: (bazelisk query 'kind(xcodeproj, tests/macos/xcodeproj/...)' | xargs -n 1 bazelisk run) && git diff --exit-code tests/macos/xcodeproj
run: |
set -euo pipefail
bazelisk query 'kind(xcodeproj, tests/macos/xcodeproj/...)' | xargs -n 1 bazelisk run
bazel query 'attr(executable, 1, kind(genrule, tests/macos/xcodeproj/...))' | xargs -n 1 bazelisk run
git diff --exit-code tests/macos/xcodeproj
- name: Run Xcode builds
run: ./tests/macos/xcodeproj/build.sh
- name: Run Unit tests
Expand Down
58 changes: 40 additions & 18 deletions rules/repositories.bzl
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
"""Definitions for handling Bazel repositories used by the Apple rules."""

load(
"@bazel_tools//tools/build_defs/repo:git.bzl",
"git_repository",
)
load(
"@bazel_tools//tools/build_defs/repo:http.bzl",
"http_archive",
Expand All @@ -22,32 +18,58 @@ def _maybe(repo_rule, name, **kwargs):
if not native.existing_rule(name):
repo_rule(name = name, **kwargs)

def github_repo(name, project, repo, ref, sha256 = None):
"""Downloads a repository from GitHub as a tarball.
Args:
name: The name of the repository.
project: The project (user or organization) on GitHub that hosts the repository.
repo: The name of the repository on GitHub.
ref: The reference to be downloaded. Can be any named ref, e.g. a commit, branch, or tag.
sha256: The sha256 of the downloaded tarball.
"""

github_url = "https://github.com/{project}/{repo}/archive/{ref}.zip".format(
project = project,
repo = repo,
ref = ref,
)
http_archive(
name = name,
strip_prefix = "%s-%s" % (repo, ref.replace("/", "-")),
url = github_url,
sha256 = sha256,
canonical_id = github_url,
)

def rules_ios_dependencies():
"""Fetches repositories that are dependencies of the `rules_apple` workspace.
"""
_maybe(
git_repository,
github_repo,
name = "build_bazel_rules_apple",
commit = "74eca5857a136b9f1e2020886be76b791eb08231",
# TODO: Investigate why enabling this causes an analysis failure
# shallow_since = "1590530217 -0700",
remote = "https://github.com/bazelbuild/rules_apple.git",
ref = "eadfa72e26dd8b459038dc83fc440759daff65c6",
project = "bazelbuild",
repo = "rules_apple",
sha256 = "be2e2e26d85dff61d4f9ae11e74be656a231389629474b39db887baa407a6f7d",
)

_maybe(
git_repository,
github_repo,
name = "build_bazel_rules_swift",
commit = "6408d85da799ec2af053c4e2883dce3ce6d30f08",
shallow_since = "1589833120 -0700",
remote = "https://github.com/bazelbuild/rules_swift.git",
ref = "15d2b18ac7a71796984c4064fc0b570260969ac3",
project = "bazelbuild",
repo = "rules_swift",
sha256 = "566bfce66201c9264bfc4bc5a84260c8039858158432eda012ec9907feceff41",
)

_maybe(
git_repository,
github_repo,
name = "build_bazel_apple_support",
commit = "501b4afb27745c4813a88ffa28acd901408014e4",
shallow_since = "1577729628 -0800",
remote = "https://github.com/bazelbuild/apple_support.git",
ref = "501b4afb27745c4813a88ffa28acd901408014e4",
project = "bazelbuild",
repo = "apple_support",
sha256 = "8aa07a6388e121763c0164624feac9b20841afa2dd87bac0ba0c3ed1d56feb70",
)

_maybe(
Expand Down Expand Up @@ -92,7 +114,7 @@ native_binary(
visibility = ["//visibility:public"],
)
""",
canonical_id = "xcodegen-2.15.2",
canonical_id = "xcodegen-2.15.1",
sha256 = "0a53aef09e1b93c5307fc1c411c52a034305ccfd87255c01de7f9ff5141e0d86",
strip_prefix = "xcodegen",
urls = ["https://github.com/yonaskolb/XcodeGen/releases/download/2.15.1/xcodegen.zip"],
Expand Down
43 changes: 37 additions & 6 deletions rules/xcodeproj.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,19 @@ def _dir(o):
if x not in ("to_json", "to_proto")
]

def _is_current_project_file(f):
return f.is_source and _is_current_project_path(f.path)

def _is_current_project_path(path):
return not path.startswith("external/")

def _srcs_info_build_files(ctx):
path = ctx.build_file_path
if not _is_current_project_path(path):
return []

return [path]

def _xcodeproj_aspect_impl(target, ctx):
providers = []

Expand Down Expand Up @@ -77,7 +90,7 @@ def _xcodeproj_aspect_impl(target, ctx):
bazel_bin_subdir = bazel_bin_subdir,
srcs = depset([], transitive = _get_attr_values_for_name(deps, _SrcsInfo, "srcs")),
asset_srcs = depset([], transitive = _get_attr_values_for_name(deps, _SrcsInfo, "asset_srcs")),
build_files = depset([ctx.build_file_path], transitive = _get_attr_values_for_name(deps, _SrcsInfo, "build_files")),
build_files = depset(_srcs_info_build_files(ctx), transitive = _get_attr_values_for_name(deps, _SrcsInfo, "build_files")),
product_type = bundle_info.product_type[_PRODUCT_SPECIFIER_LENGTH:],
platform_type = bundle_info.platform_type,
minimum_os_version = bundle_info.minimum_os_version,
Expand All @@ -90,7 +103,7 @@ def _xcodeproj_aspect_impl(target, ctx):
_SrcsInfo(
srcs = info.srcs,
asset_srcs = info.asset_srcs,
build_files = depset([ctx.build_file_path]),
build_files = depset(_srcs_info_build_files(ctx)),
direct_srcs = [],
),
)
Expand All @@ -107,14 +120,14 @@ def _xcodeproj_aspect_impl(target, ctx):
srcs += getattr(ctx.rule.files, attr, [])
else:
asset_srcs += getattr(ctx.rule.files, attr, [])
srcs = [f for f in srcs if not f.path.startswith("external/") and f.is_source]
asset_srcs = [f for f in asset_srcs if not f.path.startswith("external/") and f.is_source]
srcs = [f for f in srcs if _is_current_project_file(f)]
asset_srcs = [f for f in asset_srcs if _is_current_project_file(f)]

providers.append(
_SrcsInfo(
srcs = depset(srcs, transitive = _get_attr_values_for_name(deps, _SrcsInfo, "srcs")),
asset_srcs = depset(asset_srcs, transitive = _get_attr_values_for_name(deps, _SrcsInfo, "asset_srcs")),
build_files = depset([ctx.build_file_path], transitive = _get_attr_values_for_name(deps, _SrcsInfo, "build_files")),
build_files = depset(_srcs_info_build_files(ctx), transitive = _get_attr_values_for_name(deps, _SrcsInfo, "build_files")),
direct_srcs = srcs,
),
)
Expand Down Expand Up @@ -163,6 +176,7 @@ def _xcodeproj_impl(ctx):
"createIntermediateGroups": True,
"defaultConfig": "Debug",
"groupSortPosition": "none",
"settingPresets": "none",
}
proj_settings = {
"BAZEL_BUILD_EXEC": "$BAZEL_STUBS_DIR/build-wrapper",
Expand Down Expand Up @@ -209,6 +223,13 @@ def _xcodeproj_impl(ctx):
"optional": True,
"buildPhase": "none",
} for s in target_info.asset_srcs.to_list()]
asset_sources += [{
"path": paths.join(src_dot_dots, p),
"group": paths.dirname(p),
"optional": True,
"buildPhase": "none",
# TODO: add source language type once https://github.com/yonaskolb/XcodeGen/issues/850 is resolved
} for p in target_info.build_files.to_list()]
target_settings = {
"PRODUCT_NAME": target_info.name,
"BAZEL_BIN_SUBDIR": target_info.bazel_bin_subdir,
Expand Down Expand Up @@ -282,16 +303,22 @@ $BAZEL_INSTALLER
scheme_action_name: scheme_action_details,
}

project_file_groups = [
{"path": paths.join(src_dot_dots, f.short_path), "optional": True}
for f in ctx.files.additional_files
if _is_current_project_file(f)
]

xcodeproj_info = struct(
name = paths.split_extension(project_name)[0],
options = proj_options,
settings = proj_settings,
targets = xcodeproj_targets_by_name,
schemes = xcodeproj_schemes_by_name,
fileGroups = project_file_groups,
)

ctx.actions.write(xcodegen_jsonfile, xcodeproj_info.to_json())

ctx.actions.run(
executable = ctx.executable._xcodegen,
arguments = ["--quiet", "--no-env", "--spec", xcodegen_jsonfile.path, "--project", project.dirname],
Expand Down Expand Up @@ -319,6 +346,7 @@ $BAZEL_INSTALLER
"$(infoplist_stub)": ctx.file._infoplist_stub.short_path,
"$(output_processor_path)": ctx.file.output_processor.short_path,
"$(workspacesettings_xcsettings_short_path)": ctx.file._workspace_xcsettings.short_path,
"$(ideworkspacechecks_plist_short_path)": ctx.file._workspace_checks.short_path,
},
is_executable = True,
)
Expand All @@ -337,6 +365,7 @@ $BAZEL_INSTALLER
ctx.files._infoplist_stub +
ctx.files.print_json_leaf_nodes +
ctx.files._workspace_xcsettings +
ctx.files._workspace_checks +
ctx.files.output_processor,
transitive = [ctx.attr.installer[DefaultInfo].default_runfiles.files],
)),
Expand All @@ -354,6 +383,7 @@ xcodeproj = rule(
"_xcodeproj_installer_template": attr.label(executable = False, default = Label("//tools/xcodeproj_shims:xcodeproj-installer.sh"), allow_single_file = ["sh"]),
"_infoplist_stub": attr.label(executable = False, default = Label("//rules/test_host_app:Info.plist"), allow_single_file = ["plist"]),
"_workspace_xcsettings": attr.label(executable = False, default = Label("//tools/xcodeproj_shims:WorkspaceSettings.xcsettings"), allow_single_file = ["xcsettings"]),
"_workspace_checks": attr.label(executable = False, default = Label("//tools/xcodeproj_shims:IDEWorkspaceChecks.plist"), allow_single_file = ["plist"]),
"output_processor": attr.label(executable = True, default = Label("//tools/xcodeproj_shims:output-processor.rb"), cfg = "host", allow_single_file = True),
"_xcodegen": attr.label(executable = True, default = Label("@com_github_yonaskolb_xcodegen//:xcodegen"), cfg = "host"),
"index_import": attr.label(executable = True, default = Label("@com_github_lyft_index_import//:index_import"), cfg = "host"),
Expand All @@ -363,6 +393,7 @@ xcodeproj = rule(
"print_json_leaf_nodes": attr.label(executable = True, default = Label("//tools/xcodeproj_shims:print_json_leaf_nodes"), cfg = "host"),
"installer": attr.label(executable = True, default = Label("//tools/xcodeproj_shims:installer"), cfg = "host"),
"build_wrapper": attr.label(executable = True, default = Label("//tools/xcodeproj_shims:build-wrapper"), cfg = "host"),
"additional_files": attr.label_list(allow_files = True, allow_empty = True, default = [], mandatory = False),
},
executable = True,
)
20 changes: 20 additions & 0 deletions tests/macos/xcodeproj/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,23 @@ xcodeproj(
"//tests/ios/unit-test/test-imports-app:TestImports-Unit-Tests",
],
)

genrule(
name = "Test-Project-Regeneration",
testonly = True,
outs = ["Test-Project-Regeneration.sh"],
cmd = """
cat <<'EOS' > $@
#!/bin/sh
set -euxo pipefail
rm -fr {package_name}/{target_name}.xcodeproj
bazel run {package_name}:{target_name}
bazel run {package_name}:{target_name}
EOS
""".format(
package_name = package_name(),
target_name = "Single-Application-Project-DirectTargetsOnly",
),
executable = True,
tools = [":Single-Application-Project-DirectTargetsOnly"],
)
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
78FAC8B505DC9C839473A482 /* iOS-12.0-AppHost.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = "iOS-12.0-AppHost.app"; sourceTree = BUILT_PRODUCTS_DIR; };
7ABD95023B71172929B010EE /* common.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = common.pch; path = ../../../rules/library/common.pch; sourceTree = "<group>"; };
908EFE5EAE901D6B372D68F7 /* ios.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = ios.entitlements; path = ../../../rules/test_host_app/ios.entitlements; sourceTree = "<group>"; };
A05E016687115D20E64A5C60 /* BUILD.bazel */ = {isa = PBXFileReference; name = BUILD.bazel; path = BUILD.bazel; sourceTree = "<group>"; };
BA5C2481E04D8592323A7AD9 /* BUILD.bazel */ = {isa = PBXFileReference; name = BUILD.bazel; path = ../../../rules/test_host_app/BUILD.bazel; sourceTree = "<group>"; };
BFC300E7CF04688067094BFF /* Contents.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; name = Contents.json; path = ../../../rules/test_host_app/AssetCatalogFixture.xcassets/Contents.json; sourceTree = "<group>"; };
EEB1C98DB4C8E24414A69917 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = main.m; path = ../../../rules/test_host_app/main.m; sourceTree = "<group>"; };
EFADB1CE81C3F97F647C9255 /* Single-Application-UnitTests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = "Single-Application-UnitTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
Expand All @@ -38,6 +40,7 @@
isa = PBXGroup;
children = (
7CCE59C7822E18EBC1CD9D6D /* AssetCatalogFixture.xcassets */,
BA5C2481E04D8592323A7AD9 /* BUILD.bazel */,
908EFE5EAE901D6B372D68F7 /* ios.entitlements */,
EEB1C98DB4C8E24414A69917 /* main.m */,
);
Expand Down Expand Up @@ -99,6 +102,7 @@
F237C982F1E8CD4A105006B4 /* xcodeproj */ = {
isa = PBXGroup;
children = (
A05E016687115D20E64A5C60 /* BUILD.bazel */,
F1162A80978C527830EDADEE /* test.swift */,
);
name = xcodeproj;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@
0BD63CC255956E60D898C7B7 /* test.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = test.swift; path = test.swift; sourceTree = "<group>"; };
2B41830721183AA100B23D64 /* ios.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = ios.entitlements; path = ../../../rules/test_host_app/ios.entitlements; sourceTree = "<group>"; };
2DA260AA799ED8A57078C331 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = main.m; path = ../../../rules/test_host_app/main.m; sourceTree = "<group>"; };
4936F4D0B63B32AD09E63C43 /* BUILD.bazel */ = {isa = PBXFileReference; name = BUILD.bazel; path = BUILD.bazel; sourceTree = "<group>"; };
58D47D35D8B8E34549EE944E /* Contents.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; name = Contents.json; path = ../../../rules/test_host_app/AssetCatalogFixture.xcassets/Contents.json; sourceTree = "<group>"; };
712BB7D3F966AAE042C40E4E /* iOS-12.0-AppHost.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = "iOS-12.0-AppHost.app"; sourceTree = BUILT_PRODUCTS_DIR; };
9735D50F44B3B4D188BA18BF /* Single-Application-RunnableTestSuite.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = "Single-Application-RunnableTestSuite.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
CF248CD4BA2D7D91429E9BCB /* common.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = common.pch; path = ../../../rules/library/common.pch; sourceTree = "<group>"; };
E94B0DB5FD5082DE73F52008 /* Single-Application-UnitTests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = "Single-Application-UnitTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
EAEB79BE70BFB649A6FBC92C /* BUILD.bazel */ = {isa = PBXFileReference; name = BUILD.bazel; path = ../../../rules/test_host_app/BUILD.bazel; sourceTree = "<group>"; };
F689E871A09EA979611C589A /* resource_bundle.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; name = resource_bundle.plist; path = ../../../rules/library/resource_bundle.plist; sourceTree = "<group>"; };
/* End PBXFileReference section */

Expand Down Expand Up @@ -56,6 +58,7 @@
isa = PBXGroup;
children = (
D46477D0666FC1C236EDC486 /* AssetCatalogFixture.xcassets */,
EAEB79BE70BFB649A6FBC92C /* BUILD.bazel */,
2B41830721183AA100B23D64 /* ios.entitlements */,
2DA260AA799ED8A57078C331 /* main.m */,
);
Expand Down Expand Up @@ -99,6 +102,7 @@
F4FF0CBD8A1F7A37DB68252E /* xcodeproj */ = {
isa = PBXGroup;
children = (
4936F4D0B63B32AD09E63C43 /* BUILD.bazel */,
0BD63CC255956E60D898C7B7 /* test.swift */,
);
name = xcodeproj;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
Loading

0 comments on commit 4f96d7b

Please sign in to comment.