aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/actions/Action.java
blob: 9f8953b166be21004dea5af0e765fb5a91c4be51 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
// Copyright 2014 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.actions;

import com.google.devtools.build.lib.actions.extra.ExtraActionInfo;
import com.google.devtools.build.lib.concurrent.ThreadSafety.ConditionallyThreadCompatible;
import com.google.devtools.build.lib.profiler.Describable;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;

import java.io.IOException;
import java.util.Collection;

import javax.annotation.Nullable;

/**
 * An Action represents a function from Artifacts to Artifacts executed as an
 * atomic build step.  Examples include compilation of a single C++ source
 * file, or linking a single library.
 */
public interface Action extends ActionMetadata, Describable {

  /**
   * Prepares for executing this action; called by the Builder prior to
   * executing the Action itself. This method should prepare the file system, so
   * that the execution of the Action can write the output files. At a minimum
   * any pre-existing and write protected output files should be removed or the
   * permissions should be changed, so that they can be safely overwritten by
   * the action.
   *
   * @throws IOException if there is an error deleting the outputs.
   */
  void prepare(Path execRoot) throws IOException;

  /**
   * Executes this action; called by the Builder when all of this Action's
   * inputs have been successfully created.  (Behaviour is undefined if the
   * prerequisites are not up to date.)  This method <i>actually does the work
   * of the Action, unconditionally</i>; in other words, it is invoked by the
   * Builder only when dependency analysis has deemed it necessary.</p>
   *
   * <p>The framework guarantees that the output directory for each file in
   * <code>getOutputs()</code> has already been created, and will check to
   * ensure that each of those files is indeed created.</p>
   *
   * <p>Implementations of this method should try to honour the {@link
   * java.lang.Thread#interrupted} contract: if an interrupt is delivered to
   * the thread in which execution occurs, the action should detect this on a
   * best-effort basis and terminate as quickly as possible by throwing an
   * ActionExecutionException.
   *
   * <p>Action execution must be ThreadCompatible in order to be safely used
   * with a concurrent Builder implementation such as ParallelBuilder.
   *
   * @param actionExecutionContext Services in the scope of the action, like the output and error
   *   streams to use for messages arising during action execution.
   * @throws ActionExecutionException if execution fails for any reason.
   * @throws InterruptedException
   */
  @ConditionallyThreadCompatible
  void execute(ActionExecutionContext actionExecutionContext)
      throws ActionExecutionException, InterruptedException;

  /**
   * Returns true iff action must be executed regardless of its current state.
   * Default implementation can be overridden by some actions that might be
   * executed unconditionally under certain circumstances - e.g., if caching of
   * test results is not requested, this method could be used to force test
   * execution even if all dependencies are up-to-date.
   *
   * <p>Note, it is <b>very</b> important not to abuse this method, since it
   * completely overrides dependency checking. Any use of this method must
   * be carefully reviewed and proved to be necessary.
   *
   * <p>Note that the definition of {@link #isVolatile} depends on the
   * definition of this method, so be sure to consider both methods together
   * when making changes.
   */
  boolean executeUnconditionally();

  /**
   * Returns true if it's ever possible that {@link #executeUnconditionally}
   * could evaluate to true during the lifetime of this instance, false
   * otherwise.
   */
  boolean isVolatile();

  /**
   * Method used to find inputs before execution for an action that
   * {@link ActionMetadata#discoversInputs}. Returns null if action's inputs will be discovered
   * during execution proper.
   */
  @Nullable
  Collection<Artifact> discoverInputs(ActionExecutionContext actionExecutionContext)
      throws ActionExecutionException, InterruptedException;

  /**
   * Method used to resolve action inputs based on the information contained in
   * the action cache. It will be called iff inputsKnown() is false for the
   * given action instance and there is a related cache entry in the action
   * cache.
   *
   * Method must be redefined for any action that may return
   * inputsKnown() == false.
   *
   * @param artifactResolver the artifact factory that can be used to manufacture artifacts
   * @param resolver object which helps to resolve some of the artifacts
   * @param inputPaths List of relative (to the execution root) input paths
   * @return List of Artifacts corresponding to inputPaths, or null if some dependencies were
   * missing and we need to try again later.
   * @throws PackageRootResolutionException on failure to determine package roots of inputPaths
   */
  @Nullable
  Iterable<Artifact> resolveInputsFromCache(
      ArtifactResolver artifactResolver, PackageRootResolver resolver,
      Collection<PathFragment> inputPaths) throws PackageRootResolutionException;

  /**
   * Informs the action that its inputs are {@code inputs}, and that its inputs are now known. Can
   * only be called for actions that discover inputs. After this method is called,
   * {@link ActionMetadata#inputsKnown} should return true.
   */
  void updateInputs(Iterable<Artifact> inputs);

  /**
   * Return a best-guess estimate of the operation's resource consumption on the
   * local host itself for use in scheduling.
   *
   * @param executor the application-specific value passed to the
   *   executor parameter of the top-level call to
   *   Builder.buildArtifacts().
   */
  @Nullable ResourceSet estimateResourceConsumption(Executor executor);

  /**
   * @return true iff path prefix conflict (conflict where two actions generate
   *         two output artifacts with one of the artifact's path being the
   *         prefix for another) between this action and another action should
   *         be reported.
   */
  boolean shouldReportPathPrefixConflict(Action action);

  /**
   * Returns true if the output should bypass output filtering. This is used for test actions.
   */
  boolean showsOutputUnconditionally();

  /**
   * Called by {@link com.google.devtools.build.lib.rules.extra.ExtraAction} at execution time to
   * extract information from this action into a protocol buffer to be used by extra_action rules.
   *
   * <p>As this method is called from the ExtraAction, make sure it is ok to call this method from
   * a different thread than the one this action is executed on.
   */
  ExtraActionInfo.Builder getExtraActionInfo();

  /**
   * Returns the action type. Must not be {@code null}.
   */
  MiddlemanType getActionType();

  /**
   * The action type.
   */
  public enum MiddlemanType {

    /** A normal action. */
    NORMAL,

    /** A normal middleman, which just encapsulates a list of artifacts. */
    AGGREGATING_MIDDLEMAN,

    /**
     * A middleman that enforces action ordering, is not validated by the dependency checker, but
     * allows errors to be propagated.
     */
    ERROR_PROPAGATING_MIDDLEMAN,

    /**
     * A runfiles middleman, which is validated by the dependency checker, but is not expanded
     * in blaze. Instead, the runfiles manifest is sent to remote execution client, which
     * performs the expansion.
     */
    RUNFILES_MIDDLEMAN;

    public boolean isMiddleman() {
      return this != NORMAL;
    }
  }
}