blob: 46f7875e7e661d888531f02095e6b6d2bfb322d8 [file] [log] [blame]
// Copyright 2017 The Bazel Authors. All rights reserved.
//
// 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.
package com.google.devtools.build.lib.rules.objc;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ObjectArrays;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.Depset;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.packages.Provider;
import com.google.devtools.build.lib.packages.StarlarkInfo;
import com.google.devtools.build.lib.packages.StarlarkProvider;
import com.google.devtools.build.lib.packages.StructImpl;
import com.google.devtools.build.lib.rules.apple.DottedVersion;
import com.google.devtools.build.lib.rules.cpp.CcInfo;
import com.google.devtools.build.lib.rules.cpp.CcLinkingContext;
import java.util.List;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Tests for Starlark interaction with the objc_* rules. */
@RunWith(JUnit4.class)
public class ObjcStarlarkTest extends ObjcRuleTestCase {
private static final Provider.Key APPLE_EXECUTABLE_BINARY_PROVIDER_KEY =
new StarlarkProvider.Key(
Label.parseCanonicalUnchecked("@_builtins//:common/objc/linking_support.bzl"),
"AppleExecutableBinaryInfo");
@Before
public void setupMyInfo() throws Exception {
scratch.file("myinfo/myinfo.bzl", "MyInfo = provider()");
scratch.file("myinfo/BUILD");
}
private StructImpl getMyInfoFromTarget(ConfiguredTarget configuredTarget) throws Exception {
Provider.Key key =
new StarlarkProvider.Key(Label.parseCanonical("//myinfo:myinfo.bzl"), "MyInfo");
return (StructImpl) configuredTarget.get(key);
}
@Test
@SuppressWarnings("unchecked")
public void testStarlarkRuleCanDependOnNativeAppleRule() throws Exception {
scratch.file("examples/rule/BUILD");
scratch.file(
"examples/rule/apple_rules.bzl",
"""
load('//myinfo:myinfo.bzl', 'MyInfo')
def my_rule_impl(ctx):
dep = ctx.attr.deps[0]
library_to_link = dep[CcInfo].linking_context.linker_inputs.to_list()[0].libraries[0]
return MyInfo(
found_hdrs = dep[CcInfo].compilation_context.headers.to_list(),
found_libs = [library_to_link.static_library],
)
my_rule = rule(implementation = my_rule_impl,
attrs = {
'deps': attr.label_list(allow_files = False, mandatory = False,
providers = [[CcInfo]]),
})
""");
scratch.file("examples/apple_starlark/a.m");
scratch.file(
"examples/apple_starlark/BUILD",
"""
package(default_visibility = ['//visibility:public'])
load('//examples/rule:apple_rules.bzl', 'my_rule')
my_rule(
name = 'my_target',
deps = [':lib'],
)
objc_library(
name = 'lib',
srcs = ['a.m'],
hdrs = ['b.h']
)
""");
ConfiguredTarget starlarkTarget = getConfiguredTarget("//examples/apple_starlark:my_target");
StructImpl myInfo = getMyInfoFromTarget(starlarkTarget);
List<Artifact> starlarkHdrs = (List<Artifact>) myInfo.getValue("found_hdrs");
List<Artifact> starlarkLibraries = (List<Artifact>) myInfo.getValue("found_libs");
assertThat(ActionsTestUtil.baseArtifactNames(starlarkHdrs)).contains("b.h");
assertThat(ActionsTestUtil.baseArtifactNames(starlarkLibraries)).contains("liblib.a");
}
@Test
public void testStarlarkProviderRetrievalNoneIfNoProvider() throws Exception {
scratch.file("examples/rule/BUILD");
scratch.file(
"examples/rule/apple_rules.bzl",
"""
def my_rule_impl(ctx):
dep = ctx.attr.deps[0]
objc_provider = dep[apple_common.Objc] # this is line 3
return []
my_rule = rule(implementation = my_rule_impl,
attrs = {
'deps': attr.label_list(allow_files = False, mandatory = False),
})
""");
scratch.file("examples/apple_starlark/a.cc");
scratch.file(
"examples/apple_starlark/BUILD",
"""
package(default_visibility = ['//visibility:public'])
load('//examples/rule:apple_rules.bzl', 'my_rule')
my_rule(
name = 'my_target',
deps = [':lib'],
)
cc_library(
name = 'lib',
srcs = ['a.cc'],
hdrs = ['b.h']
)
""");
AssertionError e =
assertThrows(
AssertionError.class, () -> getConfiguredTarget("//examples/apple_starlark:my_target"));
assertThat(e)
.hasMessageThat()
.contains("apple_starlark/BUILD:3:8: in my_rule rule //examples/apple_starlark:my_target:");
assertThat(e)
.hasMessageThat()
.contains(
"File \"/workspace/examples/rule/apple_rules.bzl\", line 3, column 23, in"
+ " my_rule_impl");
assertThat(e)
.hasMessageThat()
.contains(
"<target //examples/apple_starlark:lib> (rule 'cc_library') "
+ "doesn't contain declared provider 'ObjcInfo'");
}
@Test
public void testStarlarkProviderCanCheckForExistenceOfObjcProvider() throws Exception {
scratch.file("examples/rule/BUILD");
scratch.file(
"examples/rule/apple_rules.bzl",
"""
load('//myinfo:myinfo.bzl', 'MyInfo')
def my_rule_impl(ctx):
cc_has_provider = apple_common.Objc in ctx.attr.deps[0]
objc_has_provider = apple_common.Objc in ctx.attr.deps[1]
return MyInfo(cc_has_provider=cc_has_provider, objc_has_provider=objc_has_provider)
my_rule = rule(implementation = my_rule_impl,
attrs = {
'deps': attr.label_list(allow_files = False, mandatory = False),
})
""");
scratch.file("examples/apple_starlark/a.cc");
scratch.file("examples/apple_starlark/a.m");
scratch.file(
"examples/apple_starlark/BUILD",
"""
package(default_visibility = ['//visibility:public'])
load('//examples/rule:apple_rules.bzl', 'my_rule')
my_rule(
name = 'my_target',
deps = [':cc_lib', ':objc_lib'],
)
objc_library(
name = 'objc_lib',
srcs = ['a.m'],
)
cc_library(
name = 'cc_lib',
srcs = ['a.cc'],
)
""");
ConfiguredTarget starlarkTarget = getConfiguredTarget("//examples/apple_starlark:my_target");
StructImpl myInfo = getMyInfoFromTarget(starlarkTarget);
boolean ccResult = (boolean) myInfo.getValue("cc_has_provider");
boolean objcResult = (boolean) myInfo.getValue("objc_has_provider");
assertThat(ccResult).isFalse();
assertThat(objcResult).isTrue();
}
@Test
public void testStarlarkExportsObjcProviderToNativeRule() throws Exception {
scratch.file("examples/rule/BUILD");
scratch.file(
"examples/rule/apple_rules.bzl",
"""
def my_rule_impl(ctx):
dep = ctx.attr.deps[0]
return [dep[apple_common.Objc], dep[CcInfo]]
swift_library = rule(
implementation = my_rule_impl,
attrs = {
'deps': attr.label_list(
allow_files = False,
mandatory = False,
providers = [[apple_common.Objc, CcInfo]],
)
}
)
""");
scratch.file("examples/apple_starlark/a.m");
addAppleBinaryStarlarkRule(scratch);
scratch.file(
"examples/apple_starlark/BUILD",
"""
load('//test_starlark:apple_binary_starlark.bzl', 'apple_binary_starlark')
load('//examples/rule:apple_rules.bzl', 'swift_library')
package(default_visibility = ['//visibility:public'])
objc_library(
name = 'lib',
srcs = ['a.m'],
)
swift_library(
name='my_target',
deps=[':lib'],
)
apple_binary_starlark(
name = 'bin',
platform_type = 'ios',
deps = [':my_target']
)
""");
ConfiguredTarget binaryTarget = getConfiguredTarget("//examples/apple_starlark:bin");
StructImpl executableProvider =
(StructImpl) binaryTarget.get(APPLE_EXECUTABLE_BINARY_PROVIDER_KEY);
CcLinkingContext ccLinkingContext =
executableProvider.getValue("cc_info", CcInfo.class).getCcLinkingContext();
assertThat(
Artifact.toRootRelativePaths(
ccLinkingContext.getStaticModeParamsForDynamicLibraryLibraries()))
.contains("examples/apple_starlark/liblib.a");
}
@Test
public void testObjcRuleCanDependOnArbitraryStarlarkRuleThatProvidesCcInfo() throws Exception {
scratch.file("examples/rule/BUILD");
scratch.file(
"examples/rule/apple_rules.bzl",
"""
def my_rule_impl(ctx):
return [CcInfo()]
my_rule = rule(implementation = my_rule_impl,
attrs = {})
""");
scratch.file("examples/apple_starlark/a.m");
addAppleBinaryStarlarkRule(scratch);
scratch.file(
"examples/apple_starlark/BUILD",
"""
load('//test_starlark:apple_binary_starlark.bzl', 'apple_binary_starlark')
load('//examples/rule:apple_rules.bzl', 'my_rule')
package(default_visibility = ['//visibility:public'])
my_rule(
name='my_target'
)
objc_library(
name = 'lib',
srcs = ['a.m'],
deps = [':my_target']
)
apple_binary_starlark(
name = 'bin',
platform_type = 'ios',
deps = [':lib']
)
""");
ConfiguredTarget libTarget = getConfiguredTarget("//examples/apple_starlark:lib");
assertThat(libTarget.get(CcInfo.PROVIDER)).isNotNull();
}
@Test
public void testStarlarkCanAccessAppleConfiguration() throws Exception {
scratch.file("examples/rule/BUILD");
scratch.file(
"examples/rule/apple_rules.bzl",
"""
load('//myinfo:myinfo.bzl', 'MyInfo')
def swift_binary_impl(ctx):
xcode_config = ctx.attr._xcode_config[apple_common.XcodeVersionConfig]
cpu = ctx.fragments.apple.single_arch_cpu
platform = ctx.fragments.apple.single_arch_platform
xcode_config = ctx.attr._xcode_config[apple_common.XcodeVersionConfig]
dead_code_report = ctx.attr._dead_code_report
env = apple_common.target_apple_env(xcode_config, platform)
xcode_version = xcode_config.xcode_version()
sdk_version = xcode_config.sdk_version_for_platform(platform)
single_arch_platform = ctx.fragments.apple.single_arch_platform
single_arch_cpu = ctx.fragments.apple.single_arch_cpu
platform_type = single_arch_platform.platform_type
return MyInfo(
cpu=cpu,
env=env,
xcode_version=str(xcode_version),
sdk_version=str(sdk_version),
single_arch_platform=str(single_arch_platform),
single_arch_cpu=str(single_arch_cpu),
platform_type=str(platform_type),
dead_code_report=str(dead_code_report),
)
swift_binary = rule(
implementation = swift_binary_impl,
fragments = ['apple'],
attrs = {
'_xcode_config': attr.label(
default = configuration_field(
fragment = 'apple', name = 'xcode_config_label')),
'_dead_code_report': attr.label(
default = configuration_field(
fragment = 'j2objc', name = 'dead_code_report')),
},
)
""");
scratch.file("examples/apple_starlark/a.m");
scratch.file(
"examples/apple_starlark/BUILD",
"""
package(default_visibility = ['//visibility:public'])
load('//examples/rule:apple_rules.bzl', 'swift_binary')
swift_binary(
name='my_target',
)
""");
useConfiguration("--apple_platform_type=ios", "--cpu=ios_i386", "--xcode_version=7.3");
ConfiguredTarget starlarkTarget = getConfiguredTarget("//examples/apple_starlark:my_target");
StructImpl myInfo = getMyInfoFromTarget(starlarkTarget);
Object iosCpu = myInfo.getValue("cpu");
@SuppressWarnings("unchecked")
Map<String, String> env = (Map<String, String>) myInfo.getValue("env");
Object sdkVersion = myInfo.getValue("sdk_version");
assertThat(iosCpu).isEqualTo("i386");
assertThat(env).containsEntry("APPLE_SDK_PLATFORM", "iPhoneSimulator");
assertThat(env).containsEntry("APPLE_SDK_VERSION_OVERRIDE", "8.4");
assertThat(sdkVersion).isEqualTo("8.4");
assertThat(myInfo.getValue("xcode_version")).isEqualTo("7.3");
assertThat(myInfo.getValue("single_arch_platform")).isEqualTo("IOS_SIMULATOR");
assertThat(myInfo.getValue("single_arch_cpu")).isEqualTo("i386");
assertThat(myInfo.getValue("platform_type")).isEqualTo("ios");
assertThat(myInfo.getValue("dead_code_report")).isEqualTo("None");
}
@Test
public void testDefaultJ2objcDeadCodeReport() throws Exception {
scratch.file("examples/rule/BUILD");
scratch.file(
"examples/rule/apple_rules.bzl",
"""
load('//myinfo:myinfo.bzl', 'MyInfo')
def swift_binary_impl(ctx):
dead_code_report = ctx.attr._dead_code_report
return MyInfo(
dead_code_report=str(dead_code_report),
)
swift_binary = rule(
implementation = swift_binary_impl,
fragments = ['j2objc'],
attrs = {
'_dead_code_report': attr.label(
default = configuration_field(
fragment = 'j2objc', name = 'dead_code_report')),
},
)
""");
scratch.file("examples/apple_starlark/a.m");
scratch.file(
"examples/apple_starlark/BUILD",
"""
package(default_visibility = ['//visibility:public'])
load('//examples/rule:apple_rules.bzl', 'swift_binary')
swift_binary(
name='my_target',
)
""");
useConfiguration();
ConfiguredTarget starlarkTarget = getConfiguredTarget("//examples/apple_starlark:my_target");
assertThat(getMyInfoFromTarget(starlarkTarget).getValue("dead_code_report")).isEqualTo("None");
}
@Test
public void testCustomJ2objcDeadCodeReport() throws Exception {
scratch.file("examples/rule/BUILD");
scratch.file(
"examples/rule/apple_rules.bzl",
"""
load('//myinfo:myinfo.bzl', 'MyInfo')
def dead_code_report_impl(ctx):
return MyInfo(foo='bar')
def swift_binary_impl(ctx):
dead_code_report = ctx.attr._dead_code_report[MyInfo].foo
return MyInfo(
dead_code_report=dead_code_report,
)
dead_code_report = rule(
implementation = dead_code_report_impl,
)
swift_binary = rule(
implementation = swift_binary_impl,
fragments = ['j2objc'],
attrs = {
'_dead_code_report': attr.label(
default = configuration_field(
fragment = 'j2objc', name = 'dead_code_report')),
},
)
""");
scratch.file("examples/apple_starlark/a.m");
scratch.file(
"examples/apple_starlark/BUILD",
"""
package(default_visibility = ['//visibility:public'])
load('//examples/rule:apple_rules.bzl', 'dead_code_report', 'swift_binary')
swift_binary(
name='my_target',
)
dead_code_report(name='dead_code_report')
""");
useConfiguration("--j2objc_dead_code_report=//examples/apple_starlark:dead_code_report");
ConfiguredTarget starlarkTarget = getConfiguredTarget("//examples/apple_starlark:my_target");
assertThat(getMyInfoFromTarget(starlarkTarget).getValue("dead_code_report")).isEqualTo("bar");
}
@Test
public void testStarlarkCanAccessJ2objcTranslationFlags() throws Exception {
scratch.file("examples/rule/BUILD");
scratch.file(
"examples/rule/apple_rules.bzl",
"""
load('//myinfo:myinfo.bzl', 'MyInfo')
def swift_binary_impl(ctx):
j2objc_flags = ctx.fragments.j2objc.translation_flags
return MyInfo(
j2objc_flags=j2objc_flags,
)
swift_binary = rule(
implementation = swift_binary_impl,
fragments = ['j2objc'],
)
""");
scratch.file("examples/apple_starlark/a.m");
scratch.file(
"examples/apple_starlark/BUILD",
"""
package(default_visibility = ['//visibility:public'])
load('//examples/rule:apple_rules.bzl', 'swift_binary')
swift_binary(
name='my_target',
)
""");
useConfiguration("--j2objc_translation_flags=-DTestJ2ObjcFlag");
ConfiguredTarget starlarkTarget = getConfiguredTarget("//examples/apple_starlark:my_target");
@SuppressWarnings("unchecked")
List<String> flags =
(List<String>) getMyInfoFromTarget(starlarkTarget).getValue("j2objc_flags");
assertThat(flags).contains("-DTestJ2ObjcFlag");
assertThat(flags).doesNotContain("-unspecifiedFlag");
}
@Test
public void testStarlarkCanAccessApplePlatformNames() throws Exception {
scratch.file("examples/rule/BUILD");
scratch.file(
"examples/rule/apple_rules.bzl",
"""
load('//myinfo:myinfo.bzl', 'MyInfo')
def _test_rule_impl(ctx):
platform = ctx.fragments.apple.single_arch_platform
return MyInfo(
name=platform.name_in_plist,
)
test_rule = rule(
implementation = _test_rule_impl,
fragments = ['apple']
)
""");
scratch.file(
"examples/apple_starlark/BUILD",
"""
package(default_visibility = ['//visibility:public'])
load('//examples/rule:apple_rules.bzl', 'test_rule')
test_rule(
name='my_target',
)
""");
useConfiguration("--cpu=ios_i386", "--apple_platform_type=ios");
ConfiguredTarget starlarkTarget = getConfiguredTarget("//examples/apple_starlark:my_target");
Object name = getMyInfoFromTarget(starlarkTarget).getValue("name");
assertThat(name).isEqualTo("iPhoneSimulator");
}
@Test
public void testStarlarkCanAccessAppleToolchain() throws Exception {
scratch.file("examples/rule/BUILD");
scratch.file(
"examples/rule/apple_rules.bzl",
"""
load('//myinfo:myinfo.bzl', 'MyInfo')
def swift_binary_impl(ctx):
apple_toolchain = apple_common.apple_toolchain()
sdk_dir = apple_toolchain.sdk_dir()
platform_developer_framework_dir = \\
apple_toolchain.platform_developer_framework_dir(ctx.fragments.apple)
return MyInfo(
platform_developer_framework_dir=platform_developer_framework_dir,
sdk_dir=sdk_dir,
)
swift_binary = rule(
implementation = swift_binary_impl,
fragments = ['apple']
)
""");
scratch.file("examples/apple_starlark/a.m");
scratch.file(
"examples/apple_starlark/BUILD",
"""
package(default_visibility = ['//visibility:public'])
load('//examples/rule:apple_rules.bzl', 'swift_binary')
swift_binary(
name='my_target',
)
""");
useConfiguration("--apple_platform_type=ios", "--cpu=ios_i386");
ConfiguredTarget starlarkTarget = getConfiguredTarget("//examples/apple_starlark:my_target");
StructImpl myInfo = getMyInfoFromTarget(starlarkTarget);
String platformDevFrameworksDir = (String) myInfo.getValue("platform_developer_framework_dir");
String sdkDir = (String) myInfo.getValue("sdk_dir");
assertThat(platformDevFrameworksDir)
.isEqualTo(
"__BAZEL_XCODE_DEVELOPER_DIR__"
+ "/Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks");
assertThat(sdkDir).isEqualTo("__BAZEL_XCODE_SDKROOT__");
}
@Test
public void testStarlarkCanAccessSdkAndMinimumOs() throws Exception {
scratch.file("examples/rule/BUILD");
scratch.file(
"examples/rule/apple_rules.bzl",
"""
load('//myinfo:myinfo.bzl', 'MyInfo')
def swift_binary_impl(ctx):
xcode_config = ctx.attr._xcode_config[apple_common.XcodeVersionConfig]
ios_sdk_version = xcode_config.sdk_version_for_platform\\
(apple_common.platform.ios_device)
watchos_sdk_version = xcode_config.sdk_version_for_platform\\
(apple_common.platform.watchos_device)
tvos_sdk_version = xcode_config.sdk_version_for_platform\\
(apple_common.platform.tvos_device)
macos_sdk_version = xcode_config.sdk_version_for_platform\\
(apple_common.platform.macos)
ios_minimum_os = xcode_config.minimum_os_for_platform_type\\
(apple_common.platform_type.ios)
watchos_minimum_os = xcode_config.minimum_os_for_platform_type\\
(apple_common.platform_type.watchos)
tvos_minimum_os = xcode_config.minimum_os_for_platform_type\\
(apple_common.platform_type.tvos)
visionos_minimum_os = xcode_config.minimum_os_for_platform_type\\
(apple_common.platform_type.visionos)
return MyInfo(
ios_sdk_version=str(ios_sdk_version),
watchos_sdk_version=str(watchos_sdk_version),
tvos_sdk_version=str(tvos_sdk_version),
macos_sdk_version=str(macos_sdk_version),
ios_minimum_os=str(ios_minimum_os),
watchos_minimum_os=str(watchos_minimum_os),
tvos_minimum_os=str(tvos_minimum_os),
visionos_minimum_os=str(visionos_minimum_os)
)
swift_binary = rule(
implementation = swift_binary_impl,
fragments = ['apple'],
attrs = { '_xcode_config':
attr.label(default=configuration_field(
fragment='apple', name='xcode_config_label')) },
)
""");
scratch.file("examples/apple_starlark/a.m");
scratch.file(
"examples/apple_starlark/BUILD",
"""
package(default_visibility = ['//visibility:public'])
load('//examples/rule:apple_rules.bzl', 'swift_binary')
swift_binary(
name='my_target',
)
""");
useConfiguration(
"--ios_sdk_version=1.1",
"--ios_minimum_os=1.0",
"--watchos_sdk_version=2.1",
"--watchos_minimum_os=2.0",
"--tvos_sdk_version=3.1",
"--tvos_minimum_os=3.0",
"--macos_sdk_version=4.1",
"--minimum_os_version=5.1");
ConfiguredTarget starlarkTarget = getConfiguredTarget("//examples/apple_starlark:my_target");
StructImpl myInfo = getMyInfoFromTarget(starlarkTarget);
assertThat(myInfo.getValue("ios_sdk_version")).isEqualTo("1.1");
assertThat(myInfo.getValue("ios_minimum_os")).isEqualTo("1.0");
assertThat(myInfo.getValue("watchos_sdk_version")).isEqualTo("2.1");
assertThat(myInfo.getValue("watchos_minimum_os")).isEqualTo("2.0");
assertThat(myInfo.getValue("tvos_sdk_version")).isEqualTo("3.1");
assertThat(myInfo.getValue("tvos_minimum_os")).isEqualTo("3.0");
assertThat(myInfo.getValue("macos_sdk_version")).isEqualTo("4.1");
assertThat(myInfo.getValue("visionos_minimum_os")).isEqualTo("5.1");
useConfiguration(
"--ios_sdk_version=1.1",
"--watchos_sdk_version=2.1",
"--tvos_sdk_version=3.1",
"--macos_sdk_version=4.1");
starlarkTarget = getConfiguredTarget("//examples/apple_starlark:my_target");
myInfo = getMyInfoFromTarget(starlarkTarget);
assertThat(myInfo.getValue("ios_sdk_version")).isEqualTo("1.1");
assertThat(myInfo.getValue("ios_minimum_os")).isEqualTo("1.1");
assertThat(myInfo.getValue("watchos_sdk_version")).isEqualTo("2.1");
assertThat(myInfo.getValue("watchos_minimum_os")).isEqualTo("2.1");
assertThat(myInfo.getValue("tvos_sdk_version")).isEqualTo("3.1");
assertThat(myInfo.getValue("tvos_minimum_os")).isEqualTo("3.1");
assertThat(myInfo.getValue("macos_sdk_version")).isEqualTo("4.1");
}
@Test
public void testStarlarkCanAccessObjcConfiguration() throws Exception {
scratch.file("examples/rule/BUILD");
scratch.file(
"examples/rule/objc_rules.bzl",
"""
load('//myinfo:myinfo.bzl', 'MyInfo')
def swift_binary_impl(ctx):
compilation_mode_copts = ctx.fragments.objc.copts_for_current_compilation_mode
ios_simulator_device = ctx.fragments.objc.ios_simulator_device
ios_simulator_version = ctx.fragments.objc.ios_simulator_version
signing_certificate_name = ctx.fragments.objc.signing_certificate_name
return MyInfo(
compilation_mode_copts=compilation_mode_copts,
ios_simulator_device=ios_simulator_device,
ios_simulator_version=str(ios_simulator_version),
signing_certificate_name=signing_certificate_name,
)
swift_binary = rule(
implementation = swift_binary_impl,
fragments = ['objc']
)
""");
scratch.file("examples/objc_starlark/a.m");
scratch.file(
"examples/objc_starlark/BUILD",
"""
package(default_visibility = ['//visibility:public'])
load('//examples/rule:objc_rules.bzl', 'swift_binary')
swift_binary(
name='my_target',
)
""");
useConfiguration(
"--compilation_mode=opt",
"--ios_simulator_device='iPhone 6'",
"--ios_simulator_version=8.4",
"--ios_signing_cert_name='Apple Developer'");
ConfiguredTarget starlarkTarget = getConfiguredTarget("//examples/objc_starlark:my_target");
StructImpl myInfo = getMyInfoFromTarget(starlarkTarget);
@SuppressWarnings("unchecked")
List<String> compilationModeCopts = (List<String>) myInfo.getValue("compilation_mode_copts");
Object iosSimulatorDevice = myInfo.getValue("ios_simulator_device");
Object iosSimulatorVersion = myInfo.getValue("ios_simulator_version");
Object signingCertificateName = myInfo.getValue("signing_certificate_name");
assertThat(compilationModeCopts).containsExactlyElementsIn(ObjcConfiguration.OPT_COPTS);
assertThat(iosSimulatorDevice).isEqualTo("'iPhone 6'");
assertThat(iosSimulatorVersion).isEqualTo("8.4");
assertThat(signingCertificateName).isEqualTo("'Apple Developer'");
}
@Test
public void testSigningCertificateNameCanReturnNone() throws Exception {
scratch.file("examples/rule/BUILD");
scratch.file(
"examples/rule/objc_rules.bzl",
"""
load('//myinfo:myinfo.bzl', 'MyInfo')
def my_rule_impl(ctx):
signing_certificate_name = ctx.fragments.objc.signing_certificate_name
return MyInfo(
signing_certificate_name=str(signing_certificate_name),
)
my_rule = rule(
implementation = my_rule_impl,
fragments = ['objc']
)
""");
scratch.file("examples/objc_starlark/a.m");
scratch.file(
"examples/objc_starlark/BUILD",
"""
package(default_visibility = ['//visibility:public'])
load('//examples/rule:objc_rules.bzl', 'my_rule')
my_rule(
name='my_target',
)
""");
ConfiguredTarget starlarkTarget = getConfiguredTarget("//examples/objc_starlark:my_target");
Object signingCertificateName =
getMyInfoFromTarget(starlarkTarget).getValue("signing_certificate_name");
assertThat(signingCertificateName).isEqualTo("None");
}
@Test
public void testUsesDebugEntitlementsIsTrueIfCompilationModeIsNotOpt() throws Exception {
scratch.file("examples/rule/BUILD");
scratch.file(
"examples/rule/objc_rules.bzl",
"""
load('//myinfo:myinfo.bzl', 'MyInfo')
def test_rule_impl(ctx):
uses_device_debug_entitlements = ctx.fragments.objc.uses_device_debug_entitlements
return MyInfo(
uses_device_debug_entitlements=uses_device_debug_entitlements,
)
test_rule = rule(
implementation = test_rule_impl,
fragments = ['objc']
)
""");
scratch.file("examples/objc_starlark/a.m");
scratch.file(
"examples/objc_starlark/BUILD",
"""
package(default_visibility = ['//visibility:public'])
load('//examples/rule:objc_rules.bzl', 'test_rule')
test_rule(
name='my_target',
)
""");
useConfiguration("--compilation_mode=dbg");
ConfiguredTarget starlarkTarget = getConfiguredTarget("//examples/objc_starlark:my_target");
boolean usesDeviceDebugEntitlements =
(boolean) getMyInfoFromTarget(starlarkTarget).getValue("uses_device_debug_entitlements");
assertThat(usesDeviceDebugEntitlements).isTrue();
}
@Test
public void testUsesDebugEntitlementsIsFalseIfFlagIsExplicitlyFalse() throws Exception {
scratch.file("examples/rule/BUILD");
scratch.file(
"examples/rule/objc_rules.bzl",
"""
load('//myinfo:myinfo.bzl', 'MyInfo')
def test_rule_impl(ctx):
uses_device_debug_entitlements = ctx.fragments.objc.uses_device_debug_entitlements
return MyInfo(
uses_device_debug_entitlements=uses_device_debug_entitlements,
)
test_rule = rule(
implementation = test_rule_impl,
fragments = ['objc']
)
""");
scratch.file("examples/objc_starlark/a.m");
scratch.file(
"examples/objc_starlark/BUILD",
"""
package(default_visibility = ['//visibility:public'])
load('//examples/rule:objc_rules.bzl', 'test_rule')
test_rule(
name='my_target',
)
""");
useConfiguration("--compilation_mode=dbg", "--nodevice_debug_entitlements");
ConfiguredTarget starlarkTarget = getConfiguredTarget("//examples/objc_starlark:my_target");
boolean usesDeviceDebugEntitlements =
(boolean) getMyInfoFromTarget(starlarkTarget).getValue("uses_device_debug_entitlements");
assertThat(usesDeviceDebugEntitlements).isFalse();
}
@Test
public void testUsesDebugEntitlementsIsFalseIfCompilationModeIsOpt() throws Exception {
scratch.file("examples/rule/BUILD");
scratch.file(
"examples/rule/objc_rules.bzl",
"""
load('//myinfo:myinfo.bzl', 'MyInfo')
def test_rule_impl(ctx):
uses_device_debug_entitlements = ctx.fragments.objc.uses_device_debug_entitlements
return MyInfo(
uses_device_debug_entitlements=uses_device_debug_entitlements,
)
test_rule = rule(
implementation = test_rule_impl,
fragments = ['objc']
)
""");
scratch.file("examples/objc_starlark/a.m");
scratch.file(
"examples/objc_starlark/BUILD",
"""
package(default_visibility = ['//visibility:public'])
load('//examples/rule:objc_rules.bzl', 'test_rule')
test_rule(
name='my_target',
)
""");
useConfiguration("--compilation_mode=opt");
ConfiguredTarget starlarkTarget = getConfiguredTarget("//examples/objc_starlark:my_target");
boolean usesDeviceDebugEntitlements =
(boolean) getMyInfoFromTarget(starlarkTarget).getValue("uses_device_debug_entitlements");
assertThat(usesDeviceDebugEntitlements).isFalse();
}
private ConfiguredTarget createObjcProviderStarlarkTarget(String... implLines) throws Exception {
String[] impl =
ObjectArrays.concat(
ObjectArrays.concat("def swift_binary_impl(ctx):", implLines),
new String[] {
"swift_binary = rule(",
"implementation = swift_binary_impl,",
"attrs = {",
" 'deps': attr.label_list(",
"allow_files = False, mandatory = False, providers = [[apple_common.Objc]])",
"})"
},
String.class);
scratch.file("examples/rule/BUILD");
scratch.file("examples/rule/objc_rules.bzl", impl);
scratch.file(
"examples/objc_starlark/BUILD",
"""
package(default_visibility = ['//visibility:public'])
load('//examples/rule:objc_rules.bzl', 'swift_binary')
swift_binary(
name='my_target',
deps=[':lib'],
)
objc_library(
name = 'lib',
srcs = ['a.m'],
)
""");
return getConfiguredTarget("//examples/objc_starlark:my_target");
}
@Test
public void testStarlarkCanCreateObjcProviderFromScratch() throws Exception {
ConfiguredTarget starlarkTarget =
createObjcProviderStarlarkTarget(
" file = ctx.actions.declare_file('foo.m')",
" ctx.actions.run_shell(outputs=[file], command='echo')",
" created_provider = apple_common.new_objc_provider(source=depset([file]))",
" return [created_provider]");
StarlarkInfo dependerProvider = getObjcInfo(starlarkTarget);
ImmutableList<Artifact> sources = getSource(dependerProvider);
assertThat(ActionsTestUtil.baseArtifactNames(sources)).containsExactly("foo.m");
}
@Test
public void testStarlarkCanCreateObjcProviderWithStrictDeps() throws Exception {
ConfiguredTarget starlarkTarget =
createObjcProviderStarlarkTarget(
" strict_includes = depset(['path'])",
" created_provider = apple_common.new_objc_provider(strict_include=strict_includes)",
" return [created_provider, CcInfo()]");
StarlarkInfo starlarkProvider = getObjcInfo(starlarkTarget);
assertThat(getStrictInclude(starlarkProvider)).containsExactly("path");
scratch.file(
"examples/objc_starlark2/BUILD",
"""
objc_library(
name = 'direct_dep',
deps = ['//examples/objc_starlark:my_target']
)
""");
StarlarkInfo starlarkProviderDirectDepender =
getObjcInfo(getConfiguredTarget("//examples/objc_starlark2:direct_dep"));
assertThat(getStrictInclude(starlarkProviderDirectDepender)).isEmpty();
}
@Test
public void testStarlarkCanCreateObjcProviderFromObjcProvider() throws Exception {
scratch.file("examples/rule/BUILD");
scratch.file(
"examples/rule/objc_rules.bzl",
"""
def library_impl(ctx):
lib = ctx.label.name + '.a'
file = ctx.actions.declare_file(lib)
ctx.actions.run_shell(outputs=[file], command='echo')
return [apple_common.new_objc_provider(j2objc_library=depset([file]))]
library = rule(implementation = library_impl)
def binary_impl(ctx):
dep = ctx.attr.deps[0]
lib = ctx.label.name + '.a'
file = ctx.actions.declare_file(lib)
ctx.actions.run_shell(outputs=[file], command='echo')
created_provider = apple_common.new_objc_provider(
providers=[dep[apple_common.Objc]],
j2objc_library=depset([file]),
)
return [created_provider]
binary = rule(
implementation = binary_impl,
attrs = {
'deps': attr.label_list(
allow_files = False,
mandatory = False,
providers = [[apple_common.Objc]],
)
})
""");
scratch.file(
"examples/objc_starlark/BUILD",
"""
package(default_visibility = ['//visibility:public'])
load('//examples/rule:objc_rules.bzl', 'library', 'binary')
binary(
name='bin',
deps=[':lib'],
)
library(
name = 'lib',
)
""");
ConfiguredTarget starlarkTarget = getConfiguredTarget("//examples/objc_starlark:bin");
StarlarkInfo dependerProvider = getObjcInfo(starlarkTarget);
ImmutableList<Artifact> libraries =
Depset.cast(
dependerProvider.getValue("j2objc_library"),
Artifact.class,
"dependerProvider value j2objc_library")
.toList();
assertThat(ActionsTestUtil.baseArtifactNames(libraries)).containsExactly("lib.a", "bin.a");
}
@Test
public void testStarlarkErrorOnBadObjcProviderInputKey() throws Exception {
AssertionError e =
assertThrows(
AssertionError.class,
() ->
createObjcProviderStarlarkTarget(
" created_provider = apple_common.new_objc_provider(foo=depset(['bar']))",
" return created_provider"));
assertThat(e).hasMessageThat().contains("got unexpected keyword argument: foo");
}
@Test
public void testEmptyObjcProviderKeysArePresent() throws Exception {
scratch.file("examples/rule/BUILD");
scratch.file(
"examples/rule/apple_rules.bzl",
"""
load('//myinfo:myinfo.bzl', 'MyInfo')
def swift_binary_impl(ctx):
objc_provider = ctx.attr.deps[0][apple_common.Objc]
return MyInfo(
empty_value=objc_provider.j2objc_library,
)
swift_binary = rule(
implementation = swift_binary_impl,
fragments = ['apple'],
attrs = {
'deps': attr.label_list(
allow_files = False,
mandatory = False,
providers = [[apple_common.Objc]],
)
},
)
""");
scratch.file("examples/apple_starlark/a.m");
scratch.file(
"examples/apple_starlark/BUILD",
"""
package(default_visibility = ['//visibility:public'])
load('//examples/rule:apple_rules.bzl', 'swift_binary')
swift_binary(
name='my_target',
deps=[':lib'],
)
objc_library(
name = 'lib',
srcs = ['a.m'],
)
""");
ConfiguredTarget starlarkTarget = getConfiguredTarget("//examples/apple_starlark:my_target");
NestedSet<Artifact> emptyValue =
Depset.cast(
getMyInfoFromTarget(starlarkTarget).getValue("empty_value"),
Artifact.class,
"provider \"empty_value\"'s j2objc_library");
assertThat(emptyValue.toList()).isEmpty();
}
@Test
public void testStarlarkCanAccessAndUseApplePlatformTypes() throws Exception {
scratch.file("examples/rule/BUILD");
scratch.file(
"examples/rule/apple_rules.bzl",
"""
load('//myinfo:myinfo.bzl', 'MyInfo')
def _test_rule_impl(ctx):
apple = ctx.fragments.apple
ios_platform = apple.multi_arch_platform(apple_common.platform_type.ios)
watchos_platform = apple.multi_arch_platform(apple_common.platform_type.watchos)
tvos_platform = apple.multi_arch_platform(apple_common.platform_type.tvos)
return MyInfo(
ios_platform=str(ios_platform),
watchos_platform=str(watchos_platform),
tvos_platform=str(tvos_platform),
)
test_rule = rule(implementation = _test_rule_impl,
fragments = ['apple'])
""");
scratch.file(
"examples/apple_starlark/BUILD",
"""
package(default_visibility = ['//visibility:public'])
load('//examples/rule:apple_rules.bzl', 'test_rule')
test_rule(
name = 'my_target',
)
""");
useConfiguration("--ios_multi_cpus=arm64,armv7", "--watchos_cpus=armv7k", "--tvos_cpus=arm64");
ConfiguredTarget starlarkTarget = getConfiguredTarget("//examples/apple_starlark:my_target");
StructImpl myInfo = getMyInfoFromTarget(starlarkTarget);
Object iosPlatform = myInfo.getValue("ios_platform");
Object watchosPlatform = myInfo.getValue("watchos_platform");
Object tvosPlatform = myInfo.getValue("tvos_platform");
assertThat(iosPlatform).isEqualTo("IOS_DEVICE");
assertThat(watchosPlatform).isEqualTo("WATCHOS_DEVICE");
assertThat(tvosPlatform).isEqualTo("TVOS_DEVICE");
}
@Test
public void testPlatformIsDeviceReturnsTrueForDevicePlatforms() throws Exception {
scratch.file("examples/rule/BUILD");
scratch.file(
"examples/rule/apple_rules.bzl",
"""
load('//myinfo:myinfo.bzl', 'MyInfo')
def _test_rule_impl(ctx):
apple = ctx.fragments.apple
platform = apple.multi_arch_platform(apple_common.platform_type.ios)
return MyInfo(
is_device=platform.is_device,
)
test_rule = rule(implementation = _test_rule_impl,
fragments = ['apple'])
""");
scratch.file(
"examples/apple_starlark/BUILD",
"""
package(default_visibility = ['//visibility:public'])
load('//examples/rule:apple_rules.bzl', 'test_rule')
test_rule(
name = 'my_target',
)
""");
useConfiguration("--ios_multi_cpus=arm64,armv7");
ConfiguredTarget starlarkTarget = getConfiguredTarget("//examples/apple_starlark:my_target");
Boolean isDevice = (Boolean) getMyInfoFromTarget(starlarkTarget).getValue("is_device");
assertThat(isDevice).isTrue();
}
@Test
public void testPlatformIsDeviceReturnsFalseForSimulatorPlatforms() throws Exception {
scratch.file("examples/rule/BUILD");
scratch.file(
"examples/rule/apple_rules.bzl",
"""
load('//myinfo:myinfo.bzl', 'MyInfo')
def _test_rule_impl(ctx):
apple = ctx.fragments.apple
platform = apple.multi_arch_platform(apple_common.platform_type.ios)
return MyInfo(
is_device=platform.is_device,
)
test_rule = rule(implementation = _test_rule_impl,
fragments = ['apple'])
""");
scratch.file(
"examples/apple_starlark/BUILD",
"""
package(default_visibility = ['//visibility:public'])
load('//examples/rule:apple_rules.bzl', 'test_rule')
test_rule(
name = 'my_target',
)
""");
ConfiguredTarget starlarkTarget = getConfiguredTarget("//examples/apple_starlark:my_target");
Boolean isDevice = (Boolean) getMyInfoFromTarget(starlarkTarget).getValue("is_device");
assertThat(isDevice).isFalse();
}
@Test
public void testStarlarkWithRunMemleaksEnabled() throws Exception {
useConfiguration("--ios_memleaks");
checkStarlarkRunMemleaksWithExpectedValue(true);
}
@Test
public void testStarlarkWithRunMemleaksDisabled() throws Exception {
checkStarlarkRunMemleaksWithExpectedValue(false);
}
@Test
public void testDottedVersion() throws Exception {
scratch.file("examples/rule/BUILD", "exports_files(['test_artifact'])");
scratch.file(
"examples/rule/apple_rules.bzl",
"""
load('//myinfo:myinfo.bzl', 'MyInfo')
def _test_rule_impl(ctx):
version = apple_common.dotted_version('5.4')
return MyInfo(
version=version
)
test_rule = rule(implementation = _test_rule_impl)
""");
scratch.file(
"examples/apple_starlark/BUILD",
"""
package(default_visibility = ['//visibility:public'])
load('//examples/rule:apple_rules.bzl', 'test_rule')
test_rule(
name = 'my_target',
)
""");
ConfiguredTarget starlarkTarget = getConfiguredTarget("//examples/apple_starlark:my_target");
DottedVersion version = (DottedVersion) getMyInfoFromTarget(starlarkTarget).getValue("version");
assertThat(version).isEqualTo(DottedVersion.fromString("5.4"));
}
@Test
public void testDottedVersion_invalid() throws Exception {
scratch.file("examples/rule/BUILD", "exports_files(['test_artifact'])");
scratch.file(
"examples/rule/apple_rules.bzl",
"""
load('//myinfo:myinfo.bzl', 'MyInfo')
def _test_rule_impl(ctx):
version = apple_common.dotted_version('hello')
return MyInfo(
version=version
)
test_rule = rule(implementation = _test_rule_impl)
""");
scratch.file(
"examples/apple_starlark/BUILD",
"""
package(default_visibility = ['//visibility:public'])
load('//examples/rule:apple_rules.bzl', 'test_rule')
test_rule(
name = 'my_target',
)
""");
AssertionError e =
assertThrows(
AssertionError.class, () -> getConfiguredTarget("//examples/apple_starlark:my_target"));
assertThat(e)
.hasMessageThat()
.contains("Dotted version components must all start with the form");
}
/**
* This test verifies that its possible to use the Starlark constructor of ObjcProvider as a
* provider key to obtain the provider. This test only needs to exist as long as there are two
* methods of retrieving ObjcProvider (which is true for legacy reasons). This is the 'new' method
* of retrieving ObjcProvider.
*/
@Test
public void testObjcProviderStarlarkConstructor() throws Exception {
scratch.file("examples/rule/BUILD");
scratch.file(
"examples/rule/apple_rules.bzl",
"""
def my_rule_impl(ctx):
dep = ctx.attr.deps[0]
objc_provider = dep[apple_common.Objc]
return objc_provider
my_rule = rule(implementation = my_rule_impl,
attrs = {
'deps': attr.label_list(allow_files = False, mandatory = False),
})
""");
scratch.file("examples/apple_starlark/a.cc");
scratch.file(
"examples/apple_starlark/BUILD",
"""
package(default_visibility = ['//visibility:public'])
load('//examples/rule:apple_rules.bzl', 'my_rule')
my_rule(
name = 'my_target',
deps = [':lib'],
)
objc_library(
name = 'lib',
srcs = ['a.m'],
hdrs = ['a.h']
)
""");
ConfiguredTarget starlarkTarget = getConfiguredTarget("//examples/apple_starlark:my_target");
StarlarkInfo dependerProvider = getObjcInfo(starlarkTarget);
assertThat(dependerProvider).isNotNull();
}
private void checkStarlarkRunMemleaksWithExpectedValue(boolean expectedValue) throws Exception {
scratch.file("examples/rule/BUILD");
scratch.file(
"examples/rule/apple_rules.bzl",
"""
load('//myinfo:myinfo.bzl', 'MyInfo')
def _test_rule_impl(ctx):
return MyInfo(run_memleaks = ctx.fragments.objc.run_memleaks)
test_rule = rule(implementation = _test_rule_impl,
fragments = ['objc'],
attrs = {},
)
""");
scratch.file(
"examples/apple_starlark/BUILD",
"""
package(default_visibility = ['//visibility:public'])
load('//examples/rule:apple_rules.bzl', 'test_rule')
test_rule(
name = 'my_target',
)
""");
ConfiguredTarget starlarkTarget = getConfiguredTarget("//examples/apple_starlark:my_target");
boolean runMemleaks = (boolean) getMyInfoFromTarget(starlarkTarget).getValue("run_memleaks");
assertThat(runMemleaks).isEqualTo(expectedValue);
}
@Test
public void testDisallowSDKFrameworkAttribute() throws Exception {
useConfiguration("--incompatible_disallow_sdk_frameworks_attributes");
scratch.file(
"examples/apple_starlark/BUILD",
"""
objc_library(
name = 'lib',
srcs = ['a.m'],
sdk_frameworks = ['Accelerate', 'GLKit'],
)
""");
AssertionError e =
assertThrows(
AssertionError.class, () -> getConfiguredTarget("//examples/apple_starlark:lib"));
assertThat(e)
.hasMessageThat()
.contains(
"ERROR /workspace/examples/apple_starlark/BUILD:1:13: in sdk_frameworks attribute of"
+ " objc_library rule //examples/apple_starlark:lib: sdk_frameworks attribute is"
+ " disallowed. Use explicit dependencies instead.");
}
@Test
public void testDisallowWeakSDKFrameworksAttribute() throws Exception {
useConfiguration("--incompatible_disallow_sdk_frameworks_attributes");
scratch.file(
"examples/apple_starlark/BUILD",
"""
objc_library(
name = 'lib',
srcs = ['a.m'],
weak_sdk_frameworks = ['XCTest'],
)
""");
AssertionError e =
assertThrows(
AssertionError.class, () -> getConfiguredTarget("//examples/apple_starlark:lib"));
assertThat(e)
.hasMessageThat()
.contains(
"ERROR /workspace/examples/apple_starlark/BUILD:1:13: in weak_sdk_frameworks attribute"
+ " of objc_library rule //examples/apple_starlark:lib: weak_sdk_frameworks"
+ " attribute is disallowed. Use explicit dependencies instead.");
}
@Test
public void testGetExperimentalShorterHeaderPathForStarlarkIsPrivateApi() throws Exception {
scratch.file(
"foo/rule.bzl",
"""
def _impl(ctx):
ctx.fragments.j2objc.experimental_shorter_header_path()
return []
myrule = rule(
implementation=_impl,
fragments = ['j2objc']
)
""");
scratch.file(
"foo/BUILD",
"""
load(':rule.bzl', 'myrule')
myrule(name='myrule')
""");
reporter.removeHandler(failFastHandler);
getConfiguredTarget("//foo:myrule");
assertContainsEvent("file '//foo:rule.bzl' cannot use private @_builtins API");
}
@Test
public void testGetExperimentalJ2ObjcHeaderMapForStarlarkIsPrivateApi() throws Exception {
scratch.file(
"foo/rule.bzl",
"""
def _impl(ctx):
ctx.fragments.j2objc.experimental_j2objc_header_map()
return []
myrule = rule(
implementation=_impl,
fragments = ['j2objc']
)
""");
scratch.file(
"foo/BUILD",
"""
load(':rule.bzl', 'myrule')
myrule(name='myrule')
""");
reporter.removeHandler(failFastHandler);
getConfiguredTarget("//foo:myrule");
assertContainsEvent("file '//foo:rule.bzl' cannot use private @_builtins API");
}
@Test
public void testGetRemoveDeadCodeFromJ2ObjcConfigurationForStarlarkIsPrivateApi()
throws Exception {
scratch.file(
"foo/rule.bzl",
"""
def _impl(ctx):
ctx.fragments.j2objc.remove_dead_code()
return []
myrule = rule(
implementation=_impl,
fragments = ['j2objc']
)
""");
scratch.file(
"foo/BUILD",
"""
load(':rule.bzl', 'myrule')
myrule(name='myrule')
""");
reporter.removeHandler(failFastHandler);
getConfiguredTarget("//foo:myrule");
assertContainsEvent("file '//foo:rule.bzl' cannot use private @_builtins API");
}
@Test
public void testJ2objcLibraryMigrationForStarlarkIsPrivateApi() throws Exception {
scratch.file(
"foo/rule.bzl",
"""
def _impl(ctx):
ctx.fragments.j2objc.j2objc_library_migration()
return []
myrule = rule(
implementation=_impl,
fragments = ['j2objc']
)
""");
scratch.file(
"foo/BUILD",
"""
load(':rule.bzl', 'myrule')
myrule(name='myrule')
""");
reporter.removeHandler(failFastHandler);
getConfiguredTarget("//foo:myrule");
assertContainsEvent("file \'//foo:rule.bzl\' cannot use private API");
}
}