Skip to content

Commit

Permalink
bazelrc: support --enable_platform_specific_config
Browse files Browse the repository at this point in the history
When the value of this flag is true, a host platform specific config
section will be enabled if it exists. Bazel recognizes your host
platform as linux, osx, windows or freebsd. It's equivalent to add
--config=linux on Linux platforms and --config=windows on Windows, etc.

Fixes bazelbuild#5055

RELNOTES[NEW]: Support --enable_platform_specific_config, you can use
this flag to enable flags in bazelrc according to your host platform.
GOOGLE:
  • Loading branch information
meteorcloudy committed Aug 26, 2019
1 parent 7c91751 commit eb49c62
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,16 @@
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Multiset;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.events.ExtendedEventHandler;
import com.google.devtools.build.lib.runtime.commands.ProjectFileSupport;
import com.google.devtools.build.lib.runtime.proto.InvocationPolicyOuterClass.InvocationPolicy;
import com.google.devtools.build.lib.util.ExitCode;
import com.google.devtools.build.lib.util.OS;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.common.options.InvocationPolicyEnforcer;
Expand Down Expand Up @@ -315,6 +318,28 @@ ExitCode parseOptions(List<String> args, ExtendedEventHandler eventHandler) {
return ExitCode.SUCCESS;
}

/**
* If --enable_platform_specific_config is true and the corresponding config definition exists,
* we should enable the platform specific config.
*/
private boolean shouldEnablePlatformSpecificConfig(
OptionValueDescription enablePlatformSpecificConfigDescription,
ListMultimap<String, RcChunkOfArgs> commandToRcArgs) {
if (enablePlatformSpecificConfigDescription == null ||
!(boolean) enablePlatformSpecificConfigDescription.getValue()) {
return false;
}

Multiset<String> keys = commandToRcArgs.keys();
for (String commandName : getCommandNamesToParse(commandAnnotation)) {
String defaultConfigDef = commandName + ":" + OS.getCurrent().getCanonicalName();
if (keys.contains(defaultConfigDef)) {
return true;
}
}
return false;
}

/**
* Expand the values of --config according to the definitions provided in the rc files and the
* applicable command.
Expand All @@ -325,23 +350,30 @@ void expandConfigOptions(

OptionValueDescription configValueDescription =
optionsParser.getOptionValueDescription("config");
if (configValueDescription == null || configValueDescription.getCanonicalInstances() == null) {
// No --config values were set, we can avoid this whole thing.
return;
if (configValueDescription != null && configValueDescription.getCanonicalInstances() != null) {
// Find the base set of configs. This does not include the config options that might be
// recursively included.
ImmutableList<ParsedOptionDescription> configInstances =
ImmutableList.copyOf(configValueDescription.getCanonicalInstances());

// Expand the configs that are mentioned in the input. Flatten these expansions before parsing
// them, to preserve order.
for (ParsedOptionDescription configInstance : configInstances) {
String configValueToExpand = (String) configInstance.getConvertedValue();
List<String> expansion = getExpansion(eventHandler, commandToRcArgs, configValueToExpand);
optionsParser.parseArgsAsExpansionOfOption(
configInstance, String.format("expanded from --%s", configValueToExpand), expansion);
}
}

// Find the base set of configs. This does not include the config options that might be
// recursively incuded.
ImmutableList<ParsedOptionDescription> configInstances =
ImmutableList.copyOf(configValueDescription.getCanonicalInstances());

// Expand the configs that are mentioned in the input. Flatten these expansions before parsing
// them, to preserve order.
for (ParsedOptionDescription configInstance : configInstances) {
String configValueToExpand = (String) configInstance.getConvertedValue();
List<String> expansion = getExpansion(eventHandler, commandToRcArgs, configValueToExpand);
OptionValueDescription enablePlatformSpecificConfigDescription =
optionsParser.getOptionValueDescription("enable_platform_specific_config");
if (shouldEnablePlatformSpecificConfig(enablePlatformSpecificConfigDescription, commandToRcArgs)) {
List<String> expansion = getExpansion(eventHandler, commandToRcArgs, OS.getCurrent().getCanonicalName());
optionsParser.parseArgsAsExpansionOfOption(
configInstance, String.format("expanded from --%s", configValueToExpand), expansion);
Iterables.getOnlyElement(enablePlatformSpecificConfigDescription.getCanonicalInstances()),
String.format("enabled by --enable_platform_specific_config"),
expansion);
}

// At this point, we've expanded everything, identify duplicates, if any, to warn about
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,19 @@ public class CommonCommandOptions extends OptionsBase {
+ "your build may break in the future due to deprecations or other changes.")
public Void allIncompatibleChanges;

@Option(
name = "enable_platform_specific_config",
defaultValue = "false",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.UNKNOWN},
help =
"When the value of this flag is true, a host platform specific config section will be "
+ "enabled if it exists. Bazel recognizes your host platform as linux, osx, windows "
+ "or freebsd. It's equivalent to add --config=linux on Linux platforms and "
+ "--config=windows on Windows, etc."
)
public boolean enablePlatformSpecificConfig;

@Option(
name = "config",
defaultValue = "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.google.devtools.build.lib.runtime.proto.InvocationPolicyOuterClass.InvocationPolicy;
import com.google.devtools.build.lib.testutil.Scratch;
import com.google.devtools.build.lib.testutil.TestConstants;
import com.google.devtools.build.lib.util.OS;
import com.google.devtools.common.options.OptionsParser;
import com.google.devtools.common.options.OptionsParsingException;
import com.google.devtools.common.options.OptionsParsingResult;
Expand Down Expand Up @@ -155,6 +156,16 @@ private ListMultimap<String, RcChunkOfArgs> structuredArgsFromImportedRcsWithOnl
return structuredArgs;
}

private ListMultimap<String, RcChunkOfArgs> structuredArgsForDifferentPlatforms() {
ListMultimap<String, RcChunkOfArgs> structuredArgs = ArrayListMultimap.create();
structuredArgs.put("c0:linux", new RcChunkOfArgs("rc1", ImmutableList.of("command_linux")));
structuredArgs.put("c0:windows", new RcChunkOfArgs("rc1", ImmutableList.of("command_windows")));
structuredArgs.put("c0:osx", new RcChunkOfArgs("rc1", ImmutableList.of("command_osx")));
structuredArgs.put("c0:freebsd", new RcChunkOfArgs("rc1", ImmutableList.of("command_freebsd")));
structuredArgs.put("c0:platform_config", new RcChunkOfArgs("rc1", ImmutableList.of("--enable_platform_specific_config")));
return structuredArgs;
}

@Test
public void testStructureRcOptionsAndConfigs_argumentless() throws Exception {
ListMultimap<String, RcChunkOfArgs> structuredRc =
Expand Down Expand Up @@ -297,6 +308,59 @@ public void testExpandConfigOptions_withConfig() throws Exception {
.containsExactly("Found applicable config definition c0:config in file rc1: b");
}

@Test
public void testExpandConfigOptions_withPlatformSpecificConfigEnabled() throws Exception {
parser.parse("--enable_platform_specific_config");
optionHandler.expandConfigOptions(eventHandler, structuredArgsForDifferentPlatforms());
switch (OS.getCurrent()) {
case LINUX:
assertThat(parser.getResidue()).containsExactly("command_linux");
break;
case DARWIN:
assertThat(parser.getResidue()).containsExactly("command_osx");
break;
case WINDOWS:
assertThat(parser.getResidue()).containsExactly("command_windows");
break;
case FREEBSD:
assertThat(parser.getResidue()).containsExactly("command_freebsd");
break;
default:
assertThat(parser.getResidue()).isEmpty();
}
}

@Test
public void testExpandConfigOptions_withPlatformSpecificConfigEnabledInConfig() throws Exception {
parser.parse("--config=platform_config");
optionHandler.expandConfigOptions(eventHandler, structuredArgsForDifferentPlatforms());
switch (OS.getCurrent()) {
case LINUX:
assertThat(parser.getResidue()).containsExactly("command_linux");
break;
case DARWIN:
assertThat(parser.getResidue()).containsExactly("command_osx");
break;
case WINDOWS:
assertThat(parser.getResidue()).containsExactly("command_windows");
break;
case FREEBSD:
assertThat(parser.getResidue()).containsExactly("command_freebsd");
break;
default:
assertThat(parser.getResidue()).isEmpty();
}
}

@Test
public void testExpandConfigOptions_withPlatformSpecificConfigEnabledWhenNothingSpecified()
throws Exception {
parser.parse("--enable_platform_specific_config");
optionHandler.parseRcOptions(eventHandler, ArrayListMultimap.create());
assertThat(eventHandler.getEvents()).isEmpty();
assertThat(parser.getResidue()).isEmpty();
}

@Test
public void testExpandConfigOptions_withConfigForUnapplicableCommand() throws Exception {
parser.parse("--config=other");
Expand Down

0 comments on commit eb49c62

Please sign in to comment.