1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.tradefed.cache;
18 
19 import build.bazel.remote.execution.v2.Action;
20 import build.bazel.remote.execution.v2.Command;
21 import build.bazel.remote.execution.v2.Command.EnvironmentVariable;
22 import build.bazel.remote.execution.v2.Digest;
23 import build.bazel.remote.execution.v2.Platform;
24 import build.bazel.remote.execution.v2.Platform.Property;
25 import com.google.auto.value.AutoValue;
26 import com.google.protobuf.Duration;
27 import java.io.File;
28 import java.io.IOException;
29 import java.util.Map;
30 import java.util.stream.Collectors;
31 
32 /**
33  * A value class representing an action which can be executed.
34  *
35  * <p>Terminology note: "action" is used here in the remote execution protocol sense.
36  */
37 @AutoValue
38 public abstract class ExecutableAction {
39 
40     /** Builds an {@link ExecutableAction}. */
create( File input, Iterable<String> args, Map<String, String> envVariables, long timeout)41     public static ExecutableAction create(
42             File input, Iterable<String> args, Map<String, String> envVariables, long timeout)
43             throws IOException {
44 
45         Command command =
46                 Command.newBuilder()
47                         .addAllArguments(args)
48                         .setPlatform(
49                                 Platform.newBuilder()
50                                         .addProperties(
51                                                 Property.newBuilder()
52                                                         .setName(System.getProperty("os.name"))
53                                                         .build())
54                                         .build())
55                         .addAllEnvironmentVariables(
56                                 envVariables.entrySet().stream()
57                                         .map(
58                                                 entry ->
59                                                         EnvironmentVariable.newBuilder()
60                                                                 .setName(entry.getKey())
61                                                                 .setValue(entry.getValue())
62                                                                 .build())
63                                         .collect(Collectors.toList()))
64                         .build();
65 
66         Action.Builder actionBuilder =
67                 Action.newBuilder()
68                         .setInputRootDigest(MerkleTree.buildFromDir(input).rootDigest())
69                         .setCommandDigest(DigestCalculator.compute(command));
70         if (timeout > 0L) {
71             actionBuilder.setTimeout(Duration.newBuilder().setSeconds(timeout).build());
72         }
73 
74         Action action = actionBuilder.build();
75         return new AutoValue_ExecutableAction(action, DigestCalculator.compute(action), command);
76     }
77 
action()78     public abstract Action action();
79 
actionDigest()80     public abstract Digest actionDigest();
81 
command()82     public abstract Command command();
83 }
84