aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/runtime/CommandNameCacheImpl.java
diff options
context:
space:
mode:
authorGravatar Janak Ramakrishnan <janakr@google.com>2016-04-29 22:46:16 +0000
committerGravatar Damien Martin-Guillerez <dmarting@google.com>2016-05-02 09:10:14 +0000
commite9cd0f315750a4b313768165b0b80ea1e81416d5 (patch)
tree8fa3819b9cff642e2c9e29f6ef71ecca6dc863e9 /src/main/java/com/google/devtools/build/lib/runtime/CommandNameCacheImpl.java
parentdd61520f48cb5fcc28df374e8f7c4c05f68f18a0 (diff)
In InvocationPolicyEnforcer#enforce, instead of just checking the direct command to see if a flag policy applies, check whether the flag applies by seeing if its list of commands matches one of the commands in the hierarchy.
This avoids the tedious and brittle specification of all commands that may use a flag, while providing better filtering out of inapplicable flags. RELNOTES: A FlagPolicy specified via the --invocation_policy flag will now match the current command if any of its commands matches any of the commands the current command inherits from, as opposed to just the current command. -- MOS_MIGRATED_REVID=121159131
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/runtime/CommandNameCacheImpl.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/runtime/CommandNameCacheImpl.java74
1 files changed, 74 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/CommandNameCacheImpl.java b/src/main/java/com/google/devtools/build/lib/runtime/CommandNameCacheImpl.java
new file mode 100644
index 0000000000..dd40207ecb
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/runtime/CommandNameCacheImpl.java
@@ -0,0 +1,74 @@
+// Copyright 2016 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.runtime;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import com.google.devtools.build.lib.flags.CommandNameCache;
+import com.google.devtools.build.lib.util.Preconditions;
+
+import java.util.ArrayDeque;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Set;
+
+class CommandNameCacheImpl implements CommandNameCache {
+ private final Map<String, Command> commandMap;
+ private final Map<String, ImmutableSet<String>> cache = new HashMap<>();
+
+ CommandNameCacheImpl(Map<String, BlazeCommand> commandMap) {
+ // Note: it is important that this map is live, since the commandMap may be altered
+ // post-creation.
+ this.commandMap =
+ Maps.transformValues(
+ commandMap,
+ new Function<BlazeCommand, Command>() {
+ @Override
+ public Command apply(BlazeCommand blazeCommand) {
+ return blazeCommand.getClass().getAnnotation(Command.class);
+ }
+ });
+ }
+
+ @Override
+ public ImmutableSet<String> get(String commandName) {
+ ImmutableSet<String> cachedResult = cache.get(commandName);
+ if (cachedResult != null) {
+ return cachedResult;
+ }
+ ImmutableSet.Builder<String> builder = ImmutableSet.builder();
+
+ Command command = Preconditions.checkNotNull(commandMap.get(commandName), commandName);
+ Set<Command> visited = new HashSet<>();
+ visited.add(command);
+ Queue<Command> queue = new ArrayDeque<>();
+ queue.add(command);
+ while (!queue.isEmpty()) {
+ Command cur = queue.remove();
+ builder.add(cur.name());
+ for (Class<? extends BlazeCommand> clazz : cur.inherits()) {
+ Command parent = clazz.getAnnotation(Command.class);
+ if (visited.add(parent)) {
+ queue.add(parent);
+ }
+ }
+ }
+ cachedResult = builder.build();
+ cache.put(commandName, cachedResult);
+ return cachedResult;
+ }
+}