| // 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.apple; |
| |
| 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.ImmutableMap; |
| import com.google.common.eventbus.Subscribe; |
| import com.google.devtools.build.lib.actions.ExecutionRequirements; |
| import com.google.devtools.build.lib.analysis.ConfiguredTarget; |
| import com.google.devtools.build.lib.analysis.XcodeConfigEvent; |
| import com.google.devtools.build.lib.analysis.util.BuildViewTestCase; |
| import com.google.devtools.build.lib.cmdline.Label; |
| import com.google.devtools.build.lib.packages.ConfiguredAttributeMapper; |
| import com.google.devtools.build.lib.packages.Provider; |
| import com.google.devtools.build.lib.packages.StarlarkProvider; |
| import com.google.devtools.build.lib.packages.StructImpl; |
| import com.google.devtools.build.lib.packages.Type; |
| import com.google.devtools.build.lib.skyframe.ConfiguredTargetAndData; |
| import com.google.devtools.build.lib.xcode.proto.XcodeConfig.XcodeConfigRuleInfo; |
| import com.google.devtools.build.lib.xcode.proto.XcodeConfig.XcodeConfigRuleInfo.Availability; |
| import com.google.devtools.build.lib.xcode.proto.XcodeConfig.XcodeVersionInfo; |
| 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; |
| |
| /** |
| * Unit tests for the {@code xcode_config} rule. |
| */ |
| @RunWith(JUnit4.class) |
| public class XcodeConfigTest extends BuildViewTestCase { |
| private static class EventRecorder { |
| public XcodeConfigEvent xcodeConfigEvent; |
| |
| @Subscribe |
| public synchronized void setXcodeConfigInfo(XcodeConfigEvent xcodeConfigEvent) { |
| // We only care about the top level xcode_config, so drop earlier events. |
| this.xcodeConfigEvent = xcodeConfigEvent; |
| } |
| } |
| |
| private final EventRecorder eventRecorder = new EventRecorder(); |
| |
| @Before |
| public void setUp() { |
| eventBus.register(eventRecorder); |
| } |
| |
| @Test |
| public void testEmptyConfig_noVersionFlag() throws Exception { |
| scratch.file("xcode/BUILD", |
| "xcode_config(name = 'foo',)"); |
| useConfiguration("--xcode_version_config=//xcode:foo"); |
| |
| assertIosSdkVersion(AppleCommandLineOptions.DEFAULT_IOS_SDK_VERSION); |
| } |
| |
| @Test |
| public void testDefaultVersion() throws Exception { |
| BuildFileBuilder fileBuilder = new BuildFileBuilder(); |
| fileBuilder |
| .addExplicitVersion("version512", "5.1.2", true) |
| .addExplicitVersion("version84", "8.4", false) |
| .write(scratch, "xcode/BUILD"); |
| |
| useConfiguration("--xcode_version_config=//xcode:foo"); |
| |
| assertXcodeVersion("5.1.2"); |
| assertAvailability(XcodeConfigInfo.Availability.UNKNOWN); |
| assertHasRequirements( |
| ImmutableList.of( |
| ExecutionRequirements.REQUIRES_DARWIN, ExecutionRequirements.REQUIREMENTS_SET)); |
| } |
| |
| @Test |
| public void testMutualAndExplicitXcodesThrows() throws Exception { |
| scratch.file( |
| "xcode/BUILD", |
| "xcode_config(", |
| " name = 'foo',", |
| " versions = [':version512', ':version84'],", |
| " default = ':version512',", |
| " remote_versions = ':remote',", |
| " local_versions = ':local',", |
| ")", |
| "", |
| "xcode_version(", |
| " name = 'version512',", |
| " version = '5.1.2',", |
| " aliases = ['5', '5.1'],", |
| ")", |
| "xcode_version(", |
| " name = 'version84',", |
| " version = '8.4',", |
| ")", |
| "available_xcodes(", |
| " name = 'remote',", |
| " versions = [':version512',],", |
| " default = ':version512',", |
| ")", |
| "available_xcodes(", |
| " name = 'local',", |
| " versions = [':version84',],", |
| " default = ':version84',", |
| ")"); |
| reporter.removeHandler(failFastHandler); |
| getConfiguredTarget("//xcode:foo"); |
| assertContainsEvent("'versions' may not be set if '[local,remote]_versions' is set"); |
| } |
| |
| @Test |
| public void testMutualAndDefaultThrows() throws Exception { |
| scratch.file( |
| "xcode/BUILD", |
| "xcode_config(", |
| " name = 'foo',", |
| " default = ':version512',", |
| " remote_versions = ':remote',", |
| " local_versions = ':local',", |
| ")", |
| "", |
| "xcode_version(", |
| " name = 'version512',", |
| " version = '5.1.2',", |
| " aliases = ['5', '5.1'],", |
| ")", |
| "xcode_version(", |
| " name = 'version84',", |
| " version = '8.4',", |
| ")", |
| "available_xcodes(", |
| " name = 'remote',", |
| " versions = [':version512',],", |
| " default = ':version512',", |
| ")", |
| "available_xcodes(", |
| " name = 'local',", |
| " versions = [':version84',],", |
| " default = ':version84',", |
| ")"); |
| reporter.removeHandler(failFastHandler); |
| getConfiguredTarget("//xcode:foo"); |
| assertContainsEvent("'default' may not be set if '[local,remote]_versions' is set."); |
| } |
| |
| @Test |
| public void testNoLocalXcodesThrows() throws Exception { |
| scratch.file( |
| "xcode/BUILD", |
| "xcode_config(", |
| " name = 'foo',", |
| " remote_versions = ':remote',", |
| ")", |
| "", |
| "xcode_version(", |
| " name = 'version512',", |
| " version = '5.1.2',", |
| " aliases = ['5', '5.1'],", |
| ")", |
| "available_xcodes(", |
| " name = 'remote',", |
| " versions = [':version512',],", |
| " default = ':version512',", |
| ")"); |
| reporter.removeHandler(failFastHandler); |
| getConfiguredTarget("//xcode:foo"); |
| assertContainsEvent("if 'remote_versions' are set, you must also set 'local_versions'"); |
| } |
| |
| @Test |
| public void testAcceptFlagForMutuallyAvailable() throws Exception { |
| new BuildFileBuilder() |
| .addRemoteVersion("version512", "5.1.2", true) |
| .addRemoteVersion("version84", "8.4", false) |
| .addLocalVersion("version84", "8.4", true) |
| .write(scratch, "xcode/BUILD"); |
| |
| useConfiguration("--xcode_version=8.4", "--xcode_version_config=//xcode:foo"); |
| assertXcodeVersion("8.4"); |
| assertAvailability(XcodeConfigInfo.Availability.BOTH); |
| assertHasRequirements( |
| ImmutableList.of( |
| ExecutionRequirements.REQUIRES_DARWIN, ExecutionRequirements.REQUIREMENTS_SET)); |
| |
| assertNoEvents(); |
| } |
| |
| @Test |
| public void testPreferFlagOverMutuallyAvailable() throws Exception { |
| new BuildFileBuilder() |
| .addRemoteVersion("version512", "5.1.2", true) |
| .addRemoteVersion("version84", "8.4", false) |
| .addLocalVersion("version84", "8.4", true) |
| .write(scratch, "xcode/BUILD"); |
| |
| useConfiguration("--xcode_version=5.1.2", "--xcode_version_config=//xcode:foo"); |
| assertXcodeVersion("5.1.2"); |
| assertAvailability(XcodeConfigInfo.Availability.REMOTE); |
| assertHasRequirements( |
| ImmutableList.of( |
| ExecutionRequirements.REQUIRES_DARWIN, |
| ExecutionRequirements.NO_LOCAL, |
| ExecutionRequirements.REQUIREMENTS_SET)); |
| |
| assertContainsEvent( |
| "--xcode_version=5.1.2 specified, but it is not available locally. Your build" |
| + " will fail if any actions require a local Xcode."); |
| } |
| |
| @Test |
| public void testWarnWithExplicitLocalOnlyVersion() throws Exception { |
| new BuildFileBuilder() |
| .addRemoteVersion("version512", "5.1.2", true) |
| .addLocalVersion("version84", "8.4", true) |
| .write(scratch, "xcode/BUILD"); |
| |
| useConfiguration("--xcode_version=8.4", "--xcode_version_config=//xcode:foo"); |
| assertXcodeVersion("8.4"); |
| assertAvailability(XcodeConfigInfo.Availability.LOCAL); |
| assertHasRequirements( |
| ImmutableList.of( |
| ExecutionRequirements.REQUIRES_DARWIN, |
| ExecutionRequirements.NO_REMOTE, |
| ExecutionRequirements.REQUIREMENTS_SET)); |
| |
| assertContainsEvent( |
| "--xcode_version=8.4 specified, but it is not available remotely. Actions" |
| + " requiring Xcode will be run locally, which could make your build" |
| + " slower."); |
| } |
| |
| @Test |
| public void testPreferLocalDefaultIfNoMutualNoFlag() throws Exception { |
| new BuildFileBuilder() |
| .addRemoteVersion("version512", "5.1.2", true) |
| .addLocalVersion("version84", "8.4", true) |
| .write(scratch, "xcode/BUILD"); |
| |
| useConfiguration("--xcode_version_config=//xcode:foo"); |
| assertXcodeVersion("8.4"); |
| assertAvailability(XcodeConfigInfo.Availability.LOCAL); |
| assertHasRequirements( |
| ImmutableList.of( |
| ExecutionRequirements.REQUIRES_DARWIN, |
| ExecutionRequirements.NO_REMOTE, |
| ExecutionRequirements.REQUIREMENTS_SET)); |
| |
| assertContainsEvent( |
| "Using a local Xcode version, '8.4', since there are no" |
| + " remotely available Xcodes on this machine. Consider downloading one of the" |
| + " remotely available Xcode versions (5.1.2)"); |
| } |
| |
| @Test |
| public void testChooseNewestMutualXcode() throws Exception { |
| new BuildFileBuilder() |
| .addRemoteVersion("version92", "9.2", true) |
| .addRemoteVersion("version10", "10", false, "10.0.0.10C504") |
| .addRemoteVersion("version84", "8.4", false) |
| .addLocalVersion("version84", "8.4", true) |
| .addLocalVersion("version10.0.0.10C504", "10.0.0.10C504", false, "10.0") |
| .write(scratch, "xcode/BUILD"); |
| |
| useConfiguration("--xcode_version_config=//xcode:foo"); |
| assertXcodeVersion("10"); |
| assertAvailability(XcodeConfigInfo.Availability.BOTH); |
| assertHasRequirements( |
| ImmutableList.of( |
| ExecutionRequirements.REQUIRES_DARWIN, ExecutionRequirements.REQUIREMENTS_SET)); |
| |
| assertNoEvents(); |
| } |
| |
| @Test |
| public void testPreferMutualXcodeFalseOverridesMutual() throws Exception { |
| new BuildFileBuilder() |
| .addRemoteVersion("version10", "10", true, "10.0.0.10C504") |
| .addLocalVersion("version84", "8.4", true) |
| .addLocalVersion("version10.0.0.10C504", "10.0.0.10C504", false, "10.0") |
| .write(scratch, "xcode/BUILD"); |
| |
| useConfiguration( |
| "--xcode_version_config=//xcode:foo", "--experimental_prefer_mutual_xcode=false"); |
| assertXcodeVersion("8.4"); |
| assertAvailability(XcodeConfigInfo.Availability.LOCAL); |
| assertHasRequirements( |
| ImmutableList.of( |
| ExecutionRequirements.REQUIRES_DARWIN, ExecutionRequirements.REQUIREMENTS_SET)); |
| |
| assertContainsEvent("You passed --experimental_prefer_mutual_xcode=false"); |
| assertContainsEvent("consider using --experimental_prefer_mutual_xcode=true"); |
| } |
| |
| @Test |
| public void testLocalDefaultCanBeMutuallyAvailable() throws Exception { |
| // Passing "--experimental_prefer_mutual_xcode=false" allows toggling between Xcode versions |
| // using xcode-select. This test ensures that if the version from xcode-select is available |
| // remotely, both local and remote execution are enabled. |
| new BuildFileBuilder() |
| .addRemoteVersion("version10", "10", true, "10.0.0.10C504") |
| .addLocalVersion("version10.0.0.10C504", "10.0.0.10C504", true, "10.0") |
| .write(scratch, "xcode/BUILD"); |
| |
| useConfiguration( |
| "--xcode_version_config=//xcode:foo", "--experimental_prefer_mutual_xcode=false"); |
| assertXcodeVersion("10"); |
| assertAvailability(XcodeConfigInfo.Availability.BOTH); |
| assertHasRequirements( |
| ImmutableList.of( |
| ExecutionRequirements.REQUIRES_DARWIN, ExecutionRequirements.REQUIREMENTS_SET)); |
| |
| assertNoEvents(); |
| } |
| |
| @Test |
| public void testInvalidXcodeFromMutualThrows() throws Exception { |
| new BuildFileBuilder() |
| .addRemoteVersion("version512", "5.1.2", true) |
| .addRemoteVersion("version84", "8.4", false) |
| .addLocalVersion("version84", "8.4", true) |
| .write(scratch, "xcode/BUILD"); |
| |
| useConfiguration("--xcode_version=6"); |
| reporter.removeHandler(failFastHandler); |
| getConfiguredTarget("//xcode:foo"); |
| assertContainsEvent( |
| "--xcode_version=6 specified, but '6' is not an available Xcode version." |
| + " localy available versions: [8.4]. remotely available versions:" |
| + " [5.1.2, 8.4]."); |
| } |
| |
| @Test |
| public void xcodeVersionConfig_isFunction() throws Exception { |
| scratch.file( |
| "foo/extension.bzl", |
| "result = provider()", |
| "def _impl(ctx):", |
| " return [result(xcode_version =" |
| + " apple_common.XcodeVersionConfig(" |
| + " iosSdkVersion='1.1'," |
| + " iosMinimumOsVersion='1.2'," |
| + " watchosSdkVersion='1.3'," |
| + " watchosMinimumOsVersion='1.4'," |
| + " tvosSdkVersion='1.5'," |
| + " tvosMinimumOsVersion='1.6'," |
| + " macosSdkVersion='1.7'," |
| + " macosMinimumOsVersion='1.8'," |
| + " xcodeVersion='1.9'))]", |
| "my_rule = rule(_impl, attrs = { 'dep' : attr.label() })"); |
| scratch.file("foo/BUILD", "load(':extension.bzl', 'my_rule')", "my_rule(name='test')"); |
| assertNoEvents(); |
| ConfiguredTarget myRuleTarget = getConfiguredTarget("//foo:test"); |
| StructImpl info = |
| (StructImpl) |
| myRuleTarget.get( |
| new StarlarkProvider.Key( |
| Label.parseAbsolute("//foo:extension.bzl", ImmutableMap.of()), "result")); |
| assertThat(info.getValue("xcode_version")) |
| .isEqualTo( |
| new XcodeConfigInfo( |
| DottedVersion.fromStringUnchecked("1.1"), |
| DottedVersion.fromStringUnchecked("1.2"), |
| DottedVersion.fromStringUnchecked("1.3"), |
| DottedVersion.fromStringUnchecked("1.4"), |
| DottedVersion.fromStringUnchecked("1.5"), |
| DottedVersion.fromStringUnchecked("1.6"), |
| DottedVersion.fromStringUnchecked("1.7"), |
| DottedVersion.fromStringUnchecked("1.8"), |
| DottedVersion.fromStringUnchecked("1.9"), |
| XcodeConfigInfo.Availability.UNKNOWN)); |
| } |
| |
| @Test |
| public void xcodeVersionConfig_throwsOnBadInput() throws Exception { |
| scratch.file( |
| "foo/extension.bzl", |
| "result = provider()", |
| "def _impl(ctx):", |
| " return [result(xcode_version =" |
| + " apple_common.XcodeVersionConfig(" |
| + " iosSdkVersion='not a valid dotted version'," |
| + " iosMinimumOsVersion='1.2'," |
| + " watchosSdkVersion='1.3'," |
| + " watchosMinimumOsVersion='1.4'," |
| + " tvosSdkVersion='1.5'," |
| + " tvosMinimumOsVersion='1.6'," |
| + " macosSdkVersion='1.7'," |
| + " macosMinimumOsVersion='1.8'," |
| + " xcodeVersion='1.9'))]", |
| "my_rule = rule(_impl, attrs = { 'dep' : attr.label() })"); |
| scratch.file("foo/BUILD", "load(':extension.bzl', 'my_rule')", "my_rule(name='test')"); |
| assertNoEvents(); |
| assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:test")); |
| assertContainsEvent("Dotted version components must all be of the form"); |
| assertContainsEvent("got 'not a valid dotted version'"); |
| } |
| |
| @Test |
| public void xcodeVersionConfig_exposesExpectedAttributes() throws Exception { |
| scratch.file( |
| "foo/extension.bzl", |
| "result = provider()", |
| "def _impl(ctx):", |
| " xcode_version =" |
| + " apple_common.XcodeVersionConfig(" |
| + " iosSdkVersion='1.1'," |
| + " iosMinimumOsVersion='1.2'," |
| + " watchosSdkVersion='1.3'," |
| + " watchosMinimumOsVersion='1.4'," |
| + " tvosSdkVersion='1.5'," |
| + " tvosMinimumOsVersion='1.6'," |
| + " macosSdkVersion='1.7'," |
| + " macosMinimumOsVersion='1.8'," |
| + " xcodeVersion='1.9')", |
| " return [result(xcode_version=xcode_version.xcode_version()," |
| + "min_os=xcode_version.minimum_os_for_platform_type(ctx.fragments.apple.single_arch_platform.platform_type)),]", |
| "my_rule = rule(_impl, attrs = { 'dep' : attr.label() }, fragments = ['apple'])"); |
| scratch.file("foo/BUILD", "load(':extension.bzl', 'my_rule')", "my_rule(name='test')"); |
| assertNoEvents(); |
| ConfiguredTarget myRuleTarget = getConfiguredTarget("//foo:test"); |
| StructImpl info = |
| (StructImpl) |
| myRuleTarget.get( |
| new StarlarkProvider.Key( |
| Label.parseAbsolute("//foo:extension.bzl", ImmutableMap.of()), "result")); |
| assertThat(info.getValue("xcode_version").toString()).isEqualTo("1.9"); |
| assertThat(info.getValue("min_os").toString()).isEqualTo("1.8"); |
| } |
| |
| @Test |
| public void testConfigAlias_configSetting() throws Exception { |
| scratch.file("starlark/BUILD"); |
| scratch.file( |
| "starlark/version_retriever.bzl", |
| "def _version_retriever_impl(ctx):", |
| " xcode_properties = ctx.attr.dep[apple_common.XcodeProperties]", |
| " version = xcode_properties.xcode_version", |
| " return [config_common.FeatureFlagInfo(value=version)]", |
| "", |
| "version_retriever = rule(", |
| " implementation = _version_retriever_impl,", |
| " attrs = {'dep': attr.label()},", |
| ")"); |
| |
| scratch.file( |
| "xcode/BUILD", |
| "load('//starlark:version_retriever.bzl', 'version_retriever')", |
| "version_retriever(", |
| " name = 'flag_propagator',", |
| " dep = ':alias',", |
| ")", |
| "", |
| "xcode_config(", |
| " name = 'config',", |
| " default = ':version512',", |
| " versions = [':version512', ':version64', ':version12'],", |
| ")", |
| "", |
| "xcode_config_alias(", |
| " name = 'alias'", |
| ")", |
| "", |
| "xcode_version(", |
| " name = 'version512',", |
| " version = '5.1.2',", |
| " aliases = ['5', '5.1'],", |
| ")", |
| "", |
| "xcode_version(", |
| " name = 'version64',", |
| " version = '6.4',", |
| " aliases = ['6.0', 'six', '6'],", |
| ")", |
| "", |
| "xcode_version(", |
| " name = 'version12',", |
| " version = '12',", |
| ")", |
| "config_setting(name = 'xcode_5_1_2',", |
| " flag_values = {':flag_propagator': '5.1.2'})", |
| "config_setting(name = 'xcode_6_4',", |
| " flag_values = {':flag_propagator': '6.4'})", |
| "genrule(", |
| " name = 'gen',", |
| " srcs = [],", |
| " outs = ['out'],", |
| " cmd = select({", |
| " ':xcode_5_1_2': '5.1.2',", |
| " ':xcode_6_4': '6.4',", |
| " '//conditions:default': 'none'", |
| " }))"); |
| |
| useConfiguration("--xcode_version_config=//xcode:config"); |
| assertThat(getMapper("//xcode:gen").get("cmd", Type.STRING)).isEqualTo("5.1.2"); |
| |
| useConfiguration("--xcode_version_config=//xcode:config", "--xcode_version=6.4"); |
| assertThat(getMapper("//xcode:gen").get("cmd", Type.STRING)).isEqualTo("6.4"); |
| |
| useConfiguration("--xcode_version_config=//xcode:config", "--xcode_version=6"); |
| assertThat(getMapper("//xcode:gen").get("cmd", Type.STRING)).isEqualTo("6.4"); |
| |
| useConfiguration("--xcode_version_config=//xcode:config", "--xcode_version=12"); |
| assertThat(getMapper("//xcode:gen").get("cmd", Type.STRING)).isEqualTo("none"); |
| } |
| |
| @Test |
| public void testDefaultVersion_configSetting() throws Exception { |
| scratch.file("starlark/BUILD"); |
| scratch.file( |
| "starlark/version_retriever.bzl", |
| "def _version_retriever_impl(ctx):", |
| " xcode_properties = ctx.attr.dep[apple_common.XcodeProperties]", |
| " version = xcode_properties.xcode_version", |
| " return [config_common.FeatureFlagInfo(value=version)]", |
| "", |
| "version_retriever = rule(", |
| " implementation = _version_retriever_impl,", |
| " attrs = {'dep': attr.label()},", |
| ")"); |
| |
| scratch.file( |
| "xcode/BUILD", |
| "load('//starlark:version_retriever.bzl', 'version_retriever')", |
| "version_retriever(", |
| " name = 'flag_propagator',", |
| " dep = ':alias',", |
| ")", |
| "xcode_config_alias(", |
| " name = 'alias'", |
| ")", |
| "xcode_config(", |
| " name = 'foo',", |
| " default = ':version512',", |
| " versions = [':version512', ':version64'],", |
| ")", |
| "", |
| "xcode_version(", |
| " name = 'version512',", |
| " version = '5.1.2',", |
| " aliases = ['5', '5.1'],", |
| ")", |
| "", |
| "xcode_version(", |
| " name = 'version64',", |
| " version = '6.4',", |
| " aliases = ['6.0', 'foo', '6'],", |
| ")", |
| "config_setting(name = 'xcode_5_1_2',", |
| " flag_values = {':flag_propagator': '5.1.2'})", |
| "config_setting(name = 'xcode_6_4',", |
| " flag_values = {':flag_propagator': '6.4'})", |
| "genrule(", |
| " name = 'gen',", |
| " srcs = [],", |
| " outs = ['out'],", |
| " cmd = select({", |
| " ':xcode_5_1_2': '5.1.2',", |
| " ':xcode_6_4': '6.4',", |
| " '//conditions:default': 'none'", |
| " }))"); |
| |
| useConfiguration("--xcode_version_config=//xcode:foo"); |
| assertThat(getMapper("//xcode:gen").get("cmd", Type.STRING)).isEqualTo("5.1.2"); |
| |
| useConfiguration("--xcode_version_config=//xcode:foo", "--xcode_version=6.4"); |
| assertThat(getMapper("//xcode:gen").get("cmd", Type.STRING)).isEqualTo("6.4"); |
| } |
| |
| @Test |
| public void testValidVersion() throws Exception { |
| new BuildFileBuilder() |
| .addExplicitVersion("version512", "5.1.2", true) |
| .write(scratch, "xcode/BUILD"); |
| |
| useConfiguration("--xcode_version=5.1.2", "--xcode_version_config=//xcode:foo"); |
| |
| assertXcodeVersion("5.1.2"); |
| assertAvailability(XcodeConfigInfo.Availability.UNKNOWN); |
| assertHasRequirements( |
| ImmutableList.of( |
| ExecutionRequirements.REQUIRES_DARWIN, ExecutionRequirements.REQUIREMENTS_SET)); |
| } |
| |
| @Test |
| public void testValidAlias_dottedVersion() throws Exception { |
| new BuildFileBuilder() |
| .addExplicitVersion("version512", "5.1.2", true, "5") |
| .write(scratch, "xcode/BUILD"); |
| |
| useConfiguration("--xcode_version=5", "--xcode_version_config=//xcode:foo"); |
| |
| assertXcodeVersion("5.1.2"); |
| assertAvailability(XcodeConfigInfo.Availability.UNKNOWN); |
| assertHasRequirements( |
| ImmutableList.of( |
| ExecutionRequirements.REQUIRES_DARWIN, ExecutionRequirements.REQUIREMENTS_SET)); |
| } |
| |
| @Test |
| public void testValidAlias_nonNumerical() throws Exception { |
| new BuildFileBuilder() |
| .addExplicitVersion("version512", "5.1.2", true, "valid_version") |
| .write(scratch, "xcode/BUILD"); |
| |
| useConfiguration("--xcode_version=valid_version", "--xcode_version_config=//xcode:foo"); |
| |
| assertXcodeVersion("5.1.2"); |
| assertAvailability(XcodeConfigInfo.Availability.UNKNOWN); |
| assertHasRequirements( |
| ImmutableList.of( |
| ExecutionRequirements.REQUIRES_DARWIN, ExecutionRequirements.REQUIREMENTS_SET)); |
| } |
| |
| @Test |
| public void testInvalidXcodeSpecified() throws Exception { |
| new BuildFileBuilder() |
| .addExplicitVersion("version512", "5.1.2", true) |
| .addExplicitVersion("version84", "8.4", false) |
| .write(scratch, "xcode/BUILD"); |
| |
| useConfiguration("--xcode_version=6"); |
| reporter.removeHandler(failFastHandler); |
| getConfiguredTarget("//xcode:foo"); |
| assertContainsEvent( |
| "--xcode_version=6 specified, but '6' is not an available Xcode version. " |
| + "available versions: [5.1.2, 8.4]. If you believe you have '6' installed"); |
| } |
| |
| @Test |
| public void testRequiresDefault() throws Exception { |
| scratch.file( |
| "xcode/BUILD", |
| "xcode_config(", |
| " name = 'foo',", |
| " versions = [':version512'],", |
| ")", |
| "", |
| "xcode_version(", |
| " name = 'version512',", |
| " version = '5.1.2',", |
| " aliases = ['5', '5.1'],", |
| ")"); |
| reporter.removeHandler(failFastHandler); |
| getConfiguredTarget("//xcode:foo"); |
| assertContainsEvent("default version must be specified"); |
| } |
| |
| @Test |
| public void testDuplicateAliases_definedVersion() throws Exception { |
| new BuildFileBuilder() |
| .addExplicitVersion("version512", "5.1.2", true, "5") |
| .addExplicitVersion("version5", "5.0", false, "5") |
| .write(scratch, "xcode/BUILD"); |
| |
| reporter.removeHandler(failFastHandler); |
| getConfiguredTarget("//xcode:foo"); |
| assertContainsEvent( |
| "'5' is registered to multiple labels (//xcode:version512, //xcode:version5)"); |
| } |
| |
| @Test |
| public void testDuplicateAliases_withinAvailableXcodes() throws Exception { |
| new BuildFileBuilder() |
| .addRemoteVersion("version512", "5.1.2", true, "5") |
| .addRemoteVersion("version5", "5.0", false, "5") |
| .addLocalVersion("version5", "5.0", true, "5") |
| .write(scratch, "xcode/BUILD"); |
| |
| reporter.removeHandler(failFastHandler); |
| getConfiguredTarget("//xcode:foo"); |
| assertContainsEvent( |
| "'5' is registered to multiple labels (//xcode:version512, //xcode:version5)"); |
| } |
| |
| @Test |
| public void testVersionAliasedToItself() throws Exception { |
| new BuildFileBuilder() |
| .addExplicitVersion("version512", "5.1.2", true, "5.1.2") |
| .write(scratch, "xcode/BUILD"); |
| |
| useConfiguration("--xcode_version_config=//xcode:foo"); |
| |
| assertXcodeVersion("5.1.2"); |
| assertAvailability(XcodeConfigInfo.Availability.UNKNOWN); |
| assertHasRequirements( |
| ImmutableList.of( |
| ExecutionRequirements.REQUIRES_DARWIN, ExecutionRequirements.REQUIREMENTS_SET)); |
| } |
| |
| @Test |
| public void testDuplicateVersionNumbers() throws Exception { |
| new BuildFileBuilder() |
| .addExplicitVersion("version512", "5.1.2", true) |
| .addExplicitVersion("version5", "5.1.2", false, "5") |
| .write(scratch, "xcode/BUILD"); |
| |
| useConfiguration("--xcode_version=5"); |
| reporter.removeHandler(failFastHandler); |
| getConfiguredTarget("//xcode:foo"); |
| assertContainsEvent( |
| "'5.1.2' is registered to multiple labels (//xcode:version512, //xcode:version5)"); |
| } |
| |
| @Test |
| public void testVersionConflictsWithAlias() throws Exception { |
| new BuildFileBuilder() |
| .addExplicitVersion("version512", "5.1.2", true) |
| .addExplicitVersion("version5", "5.0", false, "5.1.2") |
| .write(scratch, "xcode/BUILD"); |
| |
| reporter.removeHandler(failFastHandler); |
| getConfiguredTarget("//xcode:foo"); |
| assertContainsEvent( |
| "'5.1.2' is registered to multiple labels (//xcode:version512, //xcode:version5)"); |
| } |
| |
| @Test |
| public void testDefaultIosSdkVersion() throws Exception { |
| scratch.file( |
| "xcode/BUILD", |
| "xcode_config(", |
| " name = 'foo',", |
| " default = ':version512',", |
| " versions = [':version512', ':version64'],", |
| ")", |
| "", |
| "xcode_version(", |
| " name = 'version512',", |
| " version = '5.1.2',", |
| " aliases = ['5', '5.1'],", |
| " default_ios_sdk_version = '7.1'", |
| ")", |
| "", |
| "xcode_version(", |
| " name = 'version64',", |
| " version = '6.4',", |
| " aliases = ['6.0', 'foo', '6'],", |
| " default_ios_sdk_version = '43.0'", |
| ")"); |
| useConfiguration("--xcode_version_config=//xcode:foo"); |
| |
| assertXcodeVersion("5.1.2"); |
| assertIosSdkVersion("7.1"); |
| assertAvailability(XcodeConfigInfo.Availability.UNKNOWN); |
| assertHasRequirements( |
| ImmutableList.of( |
| ExecutionRequirements.REQUIRES_DARWIN, ExecutionRequirements.REQUIREMENTS_SET)); |
| } |
| |
| @Test |
| public void testDefaultSdkVersions() throws Exception { |
| scratch.file("xcode/BUILD", |
| "xcode_config(", |
| " name = 'foo',", |
| " default = ':version512',", |
| " versions = [':version512', ':version64'],", |
| ")", |
| "", |
| "xcode_version(", |
| " name = 'version512',", |
| " version = '5.1.2',", |
| " aliases = ['5', '5.1'],", |
| " default_ios_sdk_version = '101',", |
| " default_watchos_sdk_version = '102',", |
| " default_tvos_sdk_version = '103',", |
| " default_macos_sdk_version = '104',", |
| ")", |
| "", |
| "xcode_version(", |
| " name = 'version64',", |
| " version = '6.4',", |
| " aliases = ['6.0', 'foo', '6'],", |
| " default_ios_sdk_version = '43.0'", |
| ")"); |
| useConfiguration("--xcode_version_config=//xcode:foo"); |
| |
| assertXcodeVersion("5.1.2"); |
| assertAvailability(XcodeConfigInfo.Availability.UNKNOWN); |
| assertHasRequirements( |
| ImmutableList.of( |
| ExecutionRequirements.REQUIRES_DARWIN, ExecutionRequirements.REQUIREMENTS_SET)); |
| |
| ImmutableMap<ApplePlatform, String> platformToVersion = |
| ImmutableMap.<ApplePlatform, String>builder() |
| .put(ApplePlatform.IOS_SIMULATOR, "101") |
| .put(ApplePlatform.WATCHOS_SIMULATOR, "102") |
| .put(ApplePlatform.TVOS_SIMULATOR, "103") |
| .put(ApplePlatform.MACOS, "104") |
| .build(); |
| for (ApplePlatform platform : platformToVersion.keySet()) { |
| DottedVersion version = DottedVersion.fromString(platformToVersion.get(platform)); |
| assertThat(getSdkVersionForPlatform(platform)).isEqualTo(version); |
| assertThat(getMinimumOsVersionForPlatform(platform)).isEqualTo(version); |
| } |
| } |
| |
| @Test |
| public void testDefaultSdkVersions_selectedXcode() throws Exception { |
| scratch.file("xcode/BUILD", |
| "xcode_config(", |
| " name = 'foo',", |
| " default = ':version512',", |
| " versions = [':version512', ':version64'],", |
| ")", |
| "", |
| "xcode_version(", |
| " name = 'version512',", |
| " version = '5.1.2',", |
| " aliases = ['5', '5.1'],", |
| " default_ios_sdk_version = '7.1'", |
| ")", |
| "", |
| "xcode_version(", |
| " name = 'version64',", |
| " version = '6.4',", |
| " aliases = ['6.0', 'foo', '6'],", |
| " default_ios_sdk_version = '43',", |
| " default_watchos_sdk_version = '44',", |
| " default_tvos_sdk_version = '45',", |
| " default_macos_sdk_version = '46',", |
| ")"); |
| useConfiguration("--xcode_version=6", "--xcode_version_config=//xcode:foo"); |
| |
| assertXcodeVersion("6.4"); |
| assertAvailability(XcodeConfigInfo.Availability.UNKNOWN); |
| assertHasRequirements( |
| ImmutableList.of( |
| ExecutionRequirements.REQUIRES_DARWIN, ExecutionRequirements.REQUIREMENTS_SET)); |
| |
| ImmutableMap<ApplePlatform, String> platformToVersion = |
| ImmutableMap.<ApplePlatform, String>builder() |
| .put(ApplePlatform.IOS_SIMULATOR, "43") |
| .put(ApplePlatform.WATCHOS_SIMULATOR, "44") |
| .put(ApplePlatform.TVOS_SIMULATOR, "45") |
| .put(ApplePlatform.MACOS, "46") |
| .build(); |
| for (ApplePlatform platform : platformToVersion.keySet()) { |
| DottedVersion version = DottedVersion.fromString(platformToVersion.get(platform)); |
| assertThat(getSdkVersionForPlatform(platform)).isEqualTo(version); |
| assertThat(getMinimumOsVersionForPlatform(platform)).isEqualTo(version); |
| } |
| } |
| |
| @Test |
| public void testOverrideDefaultSdkVersions() throws Exception { |
| scratch.file("xcode/BUILD", |
| "xcode_config(", |
| " name = 'foo',", |
| " default = ':version512',", |
| " versions = [':version512', ':version64'],", |
| ")", |
| "", |
| "xcode_version(", |
| " name = 'version512',", |
| " version = '5.1.2',", |
| " aliases = ['5', '5.1'],", |
| " default_ios_sdk_version = '7.1'", |
| ")", |
| "", |
| "xcode_version(", |
| " name = 'version64',", |
| " version = '6.4',", |
| " aliases = ['6.0', 'foo', '6'],", |
| " default_ios_sdk_version = '101',", |
| " default_watchos_sdk_version = '102',", |
| " default_tvos_sdk_version = '103',", |
| " default_macos_sdk_version = '104',", |
| ")"); |
| useConfiguration("--xcode_version=6", "--xcode_version_config=//xcode:foo", |
| "--ios_sdk_version=15.3", "--watchos_sdk_version=15.4", |
| "--tvos_sdk_version=15.5", "--macos_sdk_version=15.6"); |
| |
| assertXcodeVersion("6.4"); |
| assertAvailability(XcodeConfigInfo.Availability.UNKNOWN); |
| ImmutableMap<ApplePlatform, String> platformToVersion = |
| ImmutableMap.<ApplePlatform, String>builder() |
| .put(ApplePlatform.IOS_SIMULATOR, "15.3") |
| .put(ApplePlatform.WATCHOS_SIMULATOR, "15.4") |
| .put(ApplePlatform.TVOS_SIMULATOR, "15.5") |
| .put(ApplePlatform.MACOS, "15.6") |
| .build(); |
| for (ApplePlatform platform : platformToVersion.keySet()) { |
| DottedVersion version = DottedVersion.fromString(platformToVersion.get(platform)); |
| assertThat(getSdkVersionForPlatform(platform)).isEqualTo(version); |
| assertThat(getMinimumOsVersionForPlatform(platform)).isEqualTo(version); |
| } |
| } |
| |
| @Test |
| public void testXcodeVersionFromStarlarkByAlias() throws Exception { |
| scratch.file("x/BUILD", |
| "load('//x:r.bzl', 'r')", |
| "xcode_config_alias(name='a')", |
| "xcode_config(name='c', default=':v', versions=[':v'])", |
| "xcode_version(", |
| " name = 'v',", |
| " version = '0.0',", |
| " default_ios_sdk_version = '1.0',", |
| " default_tvos_sdk_version = '2.0',", |
| " default_macos_sdk_version = '3.0',", |
| " default_watchos_sdk_version = '4.0',", |
| ")", |
| "r(name='r')"); |
| scratch.file( |
| "x/r.bzl", |
| "MyInfo = provider()", |
| "def _impl(ctx):", |
| " conf = ctx.attr._xcode[apple_common.XcodeVersionConfig]", |
| " ios = ctx.fragments.apple.multi_arch_platform(apple_common.platform_type.ios)", |
| " tvos = ctx.fragments.apple.multi_arch_platform(apple_common.platform_type.tvos)", |
| " return MyInfo(", |
| " xcode = conf.xcode_version(),", |
| " ios_sdk = conf.sdk_version_for_platform(ios),", |
| " tvos_sdk = conf.sdk_version_for_platform(tvos),", |
| " macos_min = conf.minimum_os_for_platform_type(apple_common.platform_type.macos),", |
| " watchos_min = conf.minimum_os_for_platform_type(apple_common.platform_type.watchos),", |
| " availability = conf.availability(),", |
| " execution_info = conf.execution_info(),", |
| " )", |
| "r = rule(implementation = _impl,", |
| " attrs = { '_xcode': attr.label(default = Label('//x:a'))},", |
| " fragments = ['apple'],", |
| ")"); |
| |
| useConfiguration( |
| "--xcode_version_config=//x:c", |
| "--tvos_sdk_version=2.5", |
| "--watchos_minimum_os=4.5"); |
| ConfiguredTarget r = getConfiguredTarget("//x:r"); |
| Provider.Key key = |
| new StarlarkProvider.Key(Label.parseAbsolute("//x:r.bzl", ImmutableMap.of()), "MyInfo"); |
| StructImpl info = (StructImpl) r.get(key); |
| |
| assertThat(info.getValue("xcode").toString()).isEqualTo("0.0"); |
| assertThat(info.getValue("ios_sdk").toString()).isEqualTo("1.0"); |
| assertThat(info.getValue("tvos_sdk").toString()).isEqualTo("2.5"); |
| assertThat(info.getValue("macos_min").toString()).isEqualTo("3.0"); |
| assertThat(info.getValue("watchos_min").toString()).isEqualTo("4.5"); |
| assertThat(info.getValue("availability").toString()).isEqualTo("unknown"); |
| assertThat((Map<?, ?>) info.getValue("execution_info")) |
| .containsKey(ExecutionRequirements.REQUIRES_DARWIN); |
| assertThat((Map<?, ?>) info.getValue("execution_info")) |
| .containsKey(ExecutionRequirements.REQUIREMENTS_SET); |
| } |
| |
| @Test |
| public void testMutualXcodeFromStarlarkByAlias() throws Exception { |
| scratch.file( |
| "x/BUILD", |
| "load('//x:r.bzl', 'r')", |
| "xcode_config_alias(name='a')", |
| "xcode_config(name='c',", |
| " remote_versions = ':remote',", |
| " local_versions = ':local',", |
| ")", |
| "", |
| "xcode_version(", |
| " name = 'version512',", |
| " version = '5.1.2',", |
| " aliases = ['5', '5.1'],", |
| ")", |
| "xcode_version(", |
| " name = 'version84',", |
| " version = '8.4',", |
| ")", |
| "available_xcodes(", |
| " name = 'remote',", |
| " versions = [':version512', ':version84'],", |
| " default = ':version512',", |
| ")", |
| "available_xcodes(", |
| " name = 'local',", |
| " versions = [':version84',],", |
| " default = ':version84',", |
| ")", |
| "r(name='r')"); |
| scratch.file( |
| "x/r.bzl", |
| "MyInfo = provider()", |
| "def _impl(ctx):", |
| " conf = ctx.attr._xcode[apple_common.XcodeVersionConfig]", |
| " ios = ctx.fragments.apple.multi_arch_platform(apple_common.platform_type.ios)", |
| " tvos = ctx.fragments.apple.multi_arch_platform(apple_common.platform_type.tvos)", |
| " return MyInfo(", |
| " xcode = conf.xcode_version(),", |
| " ios_sdk = conf.sdk_version_for_platform(ios),", |
| " tvos_sdk = conf.sdk_version_for_platform(tvos),", |
| " macos_min = conf.minimum_os_for_platform_type(apple_common.platform_type.macos),", |
| " watchos_min = conf.minimum_os_for_platform_type(apple_common.platform_type.watchos),", |
| " availability = conf.availability(),", |
| " execution_info = conf.execution_info(),", |
| " )", |
| "r = rule(implementation = _impl,", |
| " attrs = { '_xcode': attr.label(default = Label('//x:a'))},", |
| " fragments = ['apple'],", |
| ")"); |
| |
| useConfiguration("--xcode_version_config=//x:c"); |
| ConfiguredTarget r = getConfiguredTarget("//x:r"); |
| Provider.Key key = |
| new StarlarkProvider.Key(Label.parseAbsolute("//x:r.bzl", ImmutableMap.of()), "MyInfo"); |
| StructImpl info = (StructImpl) r.get(key); |
| assertThat((Map<?, ?>) info.getValue("execution_info")) |
| .containsKey(ExecutionRequirements.REQUIRES_DARWIN); |
| assertThat((Map<?, ?>) info.getValue("execution_info")) |
| .containsKey(ExecutionRequirements.REQUIREMENTS_SET); |
| } |
| |
| @Test |
| public void testLocalXcodeFromStarlarkByAlias() throws Exception { |
| scratch.file( |
| "x/BUILD", |
| "load('//x:r.bzl', 'r')", |
| "xcode_config_alias(name='a')", |
| "xcode_config(name='c',", |
| " remote_versions = ':remote',", |
| " local_versions = ':local',", |
| ")", |
| "", |
| "xcode_version(", |
| " name = 'version512',", |
| " version = '5.1.2',", |
| " aliases = ['5', '5.1'],", |
| ")", |
| "xcode_version(", |
| " name = 'version84',", |
| " version = '8.4',", |
| ")", |
| "available_xcodes(", |
| " name = 'remote',", |
| " versions = [':version512'],", |
| " default = ':version512',", |
| ")", |
| "available_xcodes(", |
| " name = 'local',", |
| " versions = [':version84',],", |
| " default = ':version84',", |
| ")", |
| "r(name='r')"); |
| scratch.file( |
| "x/r.bzl", |
| "MyInfo = provider()", |
| "def _impl(ctx):", |
| " conf = ctx.attr._xcode[apple_common.XcodeVersionConfig]", |
| " ios = ctx.fragments.apple.multi_arch_platform(apple_common.platform_type.ios)", |
| " tvos = ctx.fragments.apple.multi_arch_platform(apple_common.platform_type.tvos)", |
| " return MyInfo(", |
| " xcode = conf.xcode_version(),", |
| " ios_sdk = conf.sdk_version_for_platform(ios),", |
| " tvos_sdk = conf.sdk_version_for_platform(tvos),", |
| " macos_min = conf.minimum_os_for_platform_type(apple_common.platform_type.macos),", |
| " watchos_min = conf.minimum_os_for_platform_type(apple_common.platform_type.watchos),", |
| " availability = conf.availability(),", |
| " )", |
| "r = rule(implementation = _impl,", |
| " attrs = { '_xcode': attr.label(default = Label('//x:a'))},", |
| " fragments = ['apple'],", |
| ")"); |
| |
| useConfiguration("--xcode_version_config=//x:c"); |
| ConfiguredTarget r = getConfiguredTarget("//x:r"); |
| Provider.Key key = |
| new StarlarkProvider.Key(Label.parseAbsolute("//x:r.bzl", ImmutableMap.of()), "MyInfo"); |
| StructImpl info = (StructImpl) r.get(key); |
| |
| assertThat(info.getValue("xcode").toString()).isEqualTo("8.4"); |
| assertThat(info.getValue("availability").toString()).isEqualTo("local"); |
| } |
| |
| @Test |
| public void testDefaultWithoutVersion() throws Exception { |
| scratch.file("xcode/BUILD", |
| "xcode_config(", |
| " name = 'foo',", |
| " default = ':version512',", |
| ")", |
| "", |
| "xcode_version(", |
| " name = 'version512',", |
| " version = '5.1.2',", |
| " aliases = ['5', '5.1', '5.1.2'],", |
| ")"); |
| |
| reporter.removeHandler(failFastHandler); |
| getConfiguredTarget("//xcode:foo"); |
| assertContainsEvent( |
| "default label '//xcode:version512' must be contained in versions attribute"); |
| } |
| |
| @Test |
| public void testVersionDoesNotContainDefault() throws Exception { |
| scratch.file( |
| "xcode/BUILD", |
| "xcode_config(", |
| " name = 'foo',", |
| " default = ':version512',", |
| " versions = [':version6'],", |
| ")", |
| "", |
| "xcode_version(", |
| " name = 'version512',", |
| " version = '5.1.2',", |
| " aliases = ['5', '5.1', '5.1.2'],", |
| ")", |
| "", |
| "xcode_version(", |
| " name = 'version6',", |
| " version = '6.0',", |
| ")"); |
| reporter.removeHandler(failFastHandler); |
| getConfiguredTarget("//xcode:foo"); |
| assertContainsEvent("must be contained in versions attribute"); |
| } |
| |
| @Test |
| public void testInvalidBitcodeVersion() throws Exception { |
| new BuildFileBuilder() |
| .addExplicitVersion("version512", "5.1.2", true) |
| .write(scratch, "xcode/BUILD"); |
| |
| useConfiguration( |
| "--apple_platform_type=ios", "--apple_bitcode=embedded", "--apple_split_cpu=arm64"); |
| |
| reporter.removeHandler(failFastHandler); |
| getConfiguredTarget("//xcode:foo"); |
| assertContainsEvent("apple_bitcode mode 'embedded' is unsupported"); |
| } |
| |
| // Verifies that the --xcode_version_config configuration value can be accessed via the |
| // configuration_field() Starlark method and used in a Starlark rule. |
| @Test |
| public void testConfigurationFieldForRule() throws Exception { |
| scratch.file( |
| "x/provider_grabber.bzl", |
| "def _impl(ctx):", |
| " conf = ctx.attr._xcode_dep[apple_common.XcodeVersionConfig]", |
| " return [conf]", |
| "provider_grabber = rule(implementation = _impl,", |
| " attrs = { '_xcode_dep': attr.label(", |
| " default = configuration_field(", |
| " fragment = 'apple', name = 'xcode_config_label')),", |
| " },", |
| " fragments = ['apple'],", |
| ")"); |
| |
| scratch.file("x/BUILD", |
| "load('//x:provider_grabber.bzl', 'provider_grabber')", |
| "xcode_config(name='config1', default=':version1', versions=[':version1'])", |
| "xcode_config(name='config2', default=':version2', versions=[':version2'])", |
| "xcode_version(name = 'version1', version = '1.0')", |
| "xcode_version(name = 'version2', version = '2.0')", |
| "provider_grabber(name='provider_grabber')"); |
| |
| useConfiguration("--xcode_version_config=//x:config1"); |
| assertXcodeVersion("1.0", "//x:provider_grabber"); |
| |
| useConfiguration("--xcode_version_config=//x:config2"); |
| assertXcodeVersion("2.0", "//x:provider_grabber"); |
| } |
| |
| // Verifies that the --xcode_version_config configuration value can be accessed via the |
| // configuration_field() Starlark method and used in a Starlark aspect. |
| @Test |
| public void testConfigurationFieldForAspect() throws Exception { |
| scratch.file( |
| "x/provider_grabber.bzl", |
| "def _aspect_impl(target, ctx):", |
| " conf = ctx.attr._xcode_dep[apple_common.XcodeVersionConfig]", |
| " return [conf]", |
| "", |
| "MyAspect = aspect(implementation = _aspect_impl,", |
| " attrs = { '_xcode_dep': attr.label(", |
| " default = configuration_field(", |
| " fragment = 'apple', name = 'xcode_config_label')),", |
| " },", |
| " fragments = ['apple'],", |
| ")", |
| "", |
| "def _rule_impl(ctx):", |
| " conf = ctx.attr.dep[0][apple_common.XcodeVersionConfig]", |
| " return [conf]", |
| "", |
| "provider_grabber = rule(implementation = _rule_impl,", |
| " attrs = { 'dep' : ", |
| " attr.label_list(mandatory=True, allow_files=True, aspects = [MyAspect]) },", |
| ")"); |
| |
| scratch.file("x/BUILD", |
| "load('//x:provider_grabber.bzl', 'provider_grabber')", |
| "xcode_config(name='config1', default=':version1', versions=[':version1'])", |
| "xcode_config(name='config2', default=':version2', versions=[':version2'])", |
| "xcode_version(name = 'version1', version = '1.0')", |
| "xcode_version(name = 'version2', version = '2.0')", |
| "java_library(", |
| " name = 'fake_lib',", |
| ")", |
| "provider_grabber(", |
| " name = 'provider_grabber',", |
| " dep = [':fake_lib'],", |
| ")"); |
| |
| useConfiguration("--xcode_version_config=//x:config1"); |
| assertXcodeVersion("1.0", "//x:provider_grabber"); |
| |
| useConfiguration("--xcode_version_config=//x:config2"); |
| assertXcodeVersion("2.0", "//x:provider_grabber"); |
| } |
| |
| @Test |
| public void testExplicitXcodesModeNoFlag() throws Exception { |
| new BuildFileBuilder() |
| .addExplicitVersion("version512", "5.1.2", true, "5", "5.1") |
| .addExplicitVersion("version64", "6.4", false, "6.0", "foo", "6") |
| .write(scratch, "xcode/BUILD"); |
| getConfiguredTarget("//xcode:foo"); |
| XcodeConfigRuleInfo expected = |
| XcodeConfigRuleInfo.newBuilder() |
| .setSelectedVersion("5.1.2") |
| .setDefaultVersion("5.1.2") |
| .setSelectedVersionAvailability(Availability.UNKNOWN) |
| .addExplicitVersions( |
| XcodeVersionInfo.newBuilder() |
| .setVersion("5.1.2") |
| .addAllAliases(ImmutableList.of("5", "5.1"))) |
| .addExplicitVersions( |
| XcodeVersionInfo.newBuilder() |
| .setVersion("6.4") |
| .addAllAliases(ImmutableList.of("6.0", "foo", "6"))) |
| .build(); |
| assertThat(eventRecorder.xcodeConfigEvent.xcodeConfigInfo).isEqualTo(expected); |
| } |
| |
| @Test |
| public void testExplicitXcodesModeWithFlag() throws Exception { |
| new BuildFileBuilder() |
| .addExplicitVersion("version512", "5.1.2", true, "5", "5.1") |
| .addExplicitVersion("version64", "6.4", false, "6.0", "foo", "6") |
| .write(scratch, "xcode/BUILD"); |
| useConfiguration("--xcode_version=6.4"); |
| getConfiguredTarget("//xcode:foo"); |
| XcodeConfigRuleInfo expected = |
| XcodeConfigRuleInfo.newBuilder() |
| .setSelectedVersion("6.4") |
| .setDefaultVersion("5.1.2") |
| .setSelectedVersionAvailability(Availability.UNKNOWN) |
| .addExplicitVersions( |
| XcodeVersionInfo.newBuilder() |
| .setVersion("5.1.2") |
| .addAllAliases(ImmutableList.of("5", "5.1"))) |
| .addExplicitVersions( |
| XcodeVersionInfo.newBuilder() |
| .setVersion("6.4") |
| .addAllAliases(ImmutableList.of("6.0", "foo", "6"))) |
| .setXcodeVersionFlag("6.4") |
| .build(); |
| assertThat(eventRecorder.xcodeConfigEvent.xcodeConfigInfo).isEqualTo(expected); |
| } |
| |
| @Test |
| public void testAvailableXcodesModeNoFlag() throws Exception { |
| new BuildFileBuilder() |
| .addRemoteVersion("version512", "5.1.2", true, "5", "5.1") |
| .addRemoteVersion("version84", "8.4", false) |
| .addLocalVersion("version84", "8.4", true) |
| .write(scratch, "xcode/BUILD"); |
| |
| useConfiguration("--xcode_version_config=//xcode:foo"); |
| getConfiguredTarget("//xcode:foo"); |
| XcodeConfigRuleInfo expected = |
| XcodeConfigRuleInfo.newBuilder() |
| .setSelectedVersion("8.4") |
| .setDefaultVersion("8.4") |
| .setSelectedVersionAvailability(Availability.BOTH) |
| .addRemoteVersions( |
| XcodeVersionInfo.newBuilder() |
| .setVersion("5.1.2") |
| .addAllAliases(ImmutableList.of("5", "5.1"))) |
| .addRemoteVersions(XcodeVersionInfo.newBuilder().setVersion("8.4")) |
| .addLocalVersions(XcodeVersionInfo.newBuilder().setVersion("8.4")) |
| .addMutualVersions(XcodeVersionInfo.newBuilder().setVersion("8.4")) |
| .build(); |
| assertThat(eventRecorder.xcodeConfigEvent.xcodeConfigInfo).isEqualTo(expected); |
| } |
| |
| @Test |
| public void testAvailableXcodesModeWithFlag() throws Exception { |
| new BuildFileBuilder() |
| .addRemoteVersion("version512", "5.1.2", true, "5", "5.1") |
| .addRemoteVersion("version84", "8.4", false) |
| .addLocalVersion("version84", "8.4", true) |
| .write(scratch, "xcode/BUILD"); |
| useConfiguration("--xcode_version=5.1.2"); |
| getConfiguredTarget("//xcode:foo"); |
| XcodeConfigRuleInfo expected = |
| XcodeConfigRuleInfo.newBuilder() |
| .setSelectedVersion("5.1.2") |
| .setDefaultVersion("8.4") |
| .setSelectedVersionAvailability(Availability.REMOTE) |
| .addRemoteVersions( |
| XcodeVersionInfo.newBuilder() |
| .setVersion("5.1.2") |
| .addAllAliases(ImmutableList.of("5", "5.1"))) |
| .addRemoteVersions(XcodeVersionInfo.newBuilder().setVersion("8.4")) |
| .addLocalVersions(XcodeVersionInfo.newBuilder().setVersion("8.4")) |
| .addMutualVersions(XcodeVersionInfo.newBuilder().setVersion("8.4")) |
| .setXcodeVersionFlag("5.1.2") |
| .build(); |
| assertThat(this.eventRecorder.xcodeConfigEvent.xcodeConfigInfo).isEqualTo(expected); |
| } |
| |
| private DottedVersion getSdkVersionForPlatform(ApplePlatform platform) throws Exception { |
| ConfiguredTarget xcodeConfig = getConfiguredTarget("//xcode:foo"); |
| XcodeConfigInfo provider = xcodeConfig.get(XcodeConfigInfo.PROVIDER); |
| return provider.getSdkVersionForPlatform(platform); |
| } |
| |
| private DottedVersion getMinimumOsVersionForPlatform(ApplePlatform platform) throws Exception { |
| ConfiguredTarget xcodeConfig = getConfiguredTarget("//xcode:foo"); |
| XcodeConfigInfo provider = xcodeConfig.get(XcodeConfigInfo.PROVIDER); |
| return provider.getMinimumOsForPlatformType(platform.getType()); |
| } |
| |
| private void assertXcodeVersion(String version) throws Exception { |
| assertXcodeVersion(version, "//xcode:foo"); |
| } |
| |
| private void assertXcodeVersion(String version, String providerTargetLabel) throws Exception { |
| ConfiguredTarget xcodeConfig = getConfiguredTarget(providerTargetLabel); |
| XcodeConfigInfo provider = xcodeConfig.get(XcodeConfigInfo.PROVIDER); |
| assertThat(provider.getXcodeVersion()).isEqualTo(DottedVersion.fromString(version)); |
| } |
| |
| private void assertAvailability(XcodeConfigInfo.Availability availabilty) throws Exception { |
| assertAvailability(availabilty, "//xcode:foo"); |
| } |
| |
| private void assertAvailability( |
| XcodeConfigInfo.Availability availabilty, String providerTargetLabel) throws Exception { |
| ConfiguredTarget xcodeConfig = getConfiguredTarget(providerTargetLabel); |
| XcodeConfigInfo provider = xcodeConfig.get(XcodeConfigInfo.PROVIDER); |
| assertThat(provider.getAvailability()).isEqualTo(availabilty); |
| } |
| |
| private void assertHasRequirements(List<String> executionRequirements) throws Exception { |
| assertHasRequirements(executionRequirements, "//xcode:foo"); |
| } |
| |
| private void assertHasRequirements(List<String> executionRequirements, String providerTargetLabel) |
| throws Exception { |
| ConfiguredTarget xcodeConfig = getConfiguredTarget(providerTargetLabel); |
| XcodeConfigInfo provider = xcodeConfig.get(XcodeConfigInfo.PROVIDER); |
| for (String requirement : executionRequirements) { |
| assertThat(requirement).isIn(provider.getExecutionRequirements().keySet()); |
| } |
| } |
| |
| private void assertIosSdkVersion(String version) throws Exception { |
| assertThat(getSdkVersionForPlatform(ApplePlatform.IOS_SIMULATOR)) |
| .isEqualTo(DottedVersion.fromString(version)); |
| } |
| |
| /** |
| * Returns a ConfiguredAttributeMapper bound to the given rule with the target configuration. |
| */ |
| private ConfiguredAttributeMapper getMapper(String label) throws Exception { |
| ConfiguredTargetAndData ctad = getConfiguredTargetAndData(label); |
| return getMapperFromConfiguredTargetAndTarget(ctad); |
| } |
| } |