use of com.google.devtools.build.lib.vfs.ModifiedFileSet in project bazel by bazelbuild.
the class TargetMarkerFunctionTest method testLabelCrossingSubpackageBoundary.
/** Regression test for b/12545745 */
@Test
public void testLabelCrossingSubpackageBoundary() throws Exception {
scratch.file("a/b/c/foo.sh", "echo 'FOO'");
scratch.file("a/BUILD", "sh_library(name = 'foo', srcs = ['b/c/foo.sh'])");
String labelName = "//a:b/c/foo.sh";
scratch.file("a/b/BUILD");
ModifiedFileSet subpackageBuildFile = ModifiedFileSet.builder().modify(new PathFragment("a/b/BUILD")).build();
skyframeExecutor.invalidateFilesUnderPathForTesting(reporter, subpackageBuildFile, rootDirectory);
NoSuchTargetException exn = (NoSuchTargetException) getErrorFromTargetValue(labelName);
// In the presence of b/12545745, the error message is different and comes from the
// PackageFunction.
assertThat(exn.getMessage()).contains("Label '//a:b/c/foo.sh' crosses boundary of subpackage 'a/b'");
}
use of com.google.devtools.build.lib.vfs.ModifiedFileSet in project bazel by bazelbuild.
the class TargetPatternEvaluatorTest method testBrokenSymlinkRepaired.
@Test
public void testBrokenSymlinkRepaired() throws Exception {
reporter.removeHandler(failFastHandler);
Path tuv = scratch.dir("t/u/v");
tuv.getChild("BUILD").createSymbolicLink(new PathFragment("../../BUILD"));
try {
parseList("//t/...");
fail("TargetParsingException expected");
} catch (TargetParsingException e) {
// expected
}
scratch.file("t/BUILD", "sh_library(name='t')");
ModifiedFileSet modifiedFileSet = ModifiedFileSet.builder().modify(new PathFragment("t/BUILD")).build();
invalidate(modifiedFileSet);
reporter.addHandler(failFastHandler);
Set<Label> result = parseList("//t/...");
assertThat(result).containsExactly(Label.parseAbsolute("//t:t"), Label.parseAbsolute("//t/u/v:t"));
}
use of com.google.devtools.build.lib.vfs.ModifiedFileSet in project bazel by bazelbuild.
the class DiffAwarenessManagerTest method testHandlesBrokenDiffs.
@Test
public void testHandlesBrokenDiffs() throws Exception {
Path pathEntry = root.getRelative("pathEntry");
DiffAwarenessFactoryStub factory1 = new DiffAwarenessFactoryStub();
DiffAwarenessStub diffAwareness1 = new DiffAwarenessStub(ImmutableList.<ModifiedFileSet>of(), 1);
factory1.inject(pathEntry, diffAwareness1);
DiffAwarenessFactoryStub factory2 = new DiffAwarenessFactoryStub();
ModifiedFileSet diff2 = ModifiedFileSet.builder().modify(new PathFragment("file2")).build();
DiffAwarenessStub diffAwareness2 = new DiffAwarenessStub(ImmutableList.of(diff2, DiffAwarenessStub.BROKEN_DIFF));
factory2.inject(pathEntry, diffAwareness2);
DiffAwarenessFactoryStub factory3 = new DiffAwarenessFactoryStub();
ModifiedFileSet diff3 = ModifiedFileSet.builder().modify(new PathFragment("file3")).build();
DiffAwarenessStub diffAwareness3 = new DiffAwarenessStub(ImmutableList.of(diff3));
factory3.inject(pathEntry, diffAwareness3);
DiffAwarenessManager manager = new DiffAwarenessManager(ImmutableList.of(factory1, factory2, factory3));
ProcessableModifiedFileSet processableDiff = manager.getDiff(events.reporter(), pathEntry, OptionsClassProvider.EMPTY);
events.assertNoWarningsOrErrors();
assertEquals("Expected EVERYTHING_MODIFIED on first call to getDiff for diffAwareness1", ModifiedFileSet.EVERYTHING_MODIFIED, processableDiff.getModifiedFileSet());
processableDiff.markProcessed();
processableDiff = manager.getDiff(events.reporter(), pathEntry, OptionsClassProvider.EMPTY);
events.assertContainsEventWithFrequency("error in getCurrentView", 1);
assertEquals("Expected EVERYTHING_MODIFIED because of broken getCurrentView", ModifiedFileSet.EVERYTHING_MODIFIED, processableDiff.getModifiedFileSet());
processableDiff.markProcessed();
factory1.remove(pathEntry);
processableDiff = manager.getDiff(events.reporter(), pathEntry, OptionsClassProvider.EMPTY);
assertEquals("Expected EVERYTHING_MODIFIED on first call to getDiff for diffAwareness2", ModifiedFileSet.EVERYTHING_MODIFIED, processableDiff.getModifiedFileSet());
processableDiff.markProcessed();
processableDiff = manager.getDiff(events.reporter(), pathEntry, OptionsClassProvider.EMPTY);
assertEquals(diff2, processableDiff.getModifiedFileSet());
processableDiff.markProcessed();
processableDiff = manager.getDiff(events.reporter(), pathEntry, OptionsClassProvider.EMPTY);
events.assertContainsEventWithFrequency("error in getDiff", 1);
assertEquals("Expected EVERYTHING_MODIFIED because of broken getDiff", ModifiedFileSet.EVERYTHING_MODIFIED, processableDiff.getModifiedFileSet());
processableDiff.markProcessed();
factory2.remove(pathEntry);
processableDiff = manager.getDiff(events.reporter(), pathEntry, OptionsClassProvider.EMPTY);
assertEquals("Expected EVERYTHING_MODIFIED on first call to getDiff for diffAwareness3", ModifiedFileSet.EVERYTHING_MODIFIED, processableDiff.getModifiedFileSet());
processableDiff.markProcessed();
processableDiff = manager.getDiff(events.reporter(), pathEntry, OptionsClassProvider.EMPTY);
assertEquals(diff3, processableDiff.getModifiedFileSet());
processableDiff.markProcessed();
}
use of com.google.devtools.build.lib.vfs.ModifiedFileSet in project bazel by bazelbuild.
the class ExecutionTool method executeBuild.
/**
* Performs the execution phase (phase 3) of the build, in which the Builder
* is applied to the action graph to bring the targets up to date. (This
* function will return prior to execution-proper if --nobuild was specified.)
* @param buildId UUID of the build id
* @param analysisResult the analysis phase output
* @param buildResult the mutable build result
* @param packageRoots package roots collected from loading phase and BuildConfigurationCollection
* creation
*/
void executeBuild(UUID buildId, AnalysisResult analysisResult, BuildResult buildResult, BuildConfigurationCollection configurations, ImmutableMap<PackageIdentifier, Path> packageRoots, TopLevelArtifactContext topLevelArtifactContext) throws BuildFailedException, InterruptedException, TestExecException, AbruptExitException {
Stopwatch timer = Stopwatch.createStarted();
prepare(packageRoots, analysisResult.getWorkspaceName());
ActionGraph actionGraph = analysisResult.getActionGraph();
// Get top-level artifacts.
ImmutableSet<Artifact> additionalArtifacts = analysisResult.getAdditionalArtifactsToBuild();
OutputService outputService = env.getOutputService();
ModifiedFileSet modifiedOutputFiles = ModifiedFileSet.EVERYTHING_MODIFIED;
if (outputService != null) {
modifiedOutputFiles = outputService.startBuild(buildId, request.getBuildOptions().finalizeActions);
} else {
// TODO(bazel-team): this could be just another OutputService
startLocalOutputBuild(analysisResult.getWorkspaceName());
}
List<BuildConfiguration> targetConfigurations = configurations.getTargetConfigurations();
BuildConfiguration targetConfiguration = targetConfigurations.size() == 1 ? targetConfigurations.get(0) : null;
if (targetConfigurations.size() == 1) {
String productName = runtime.getProductName();
String dirName = env.getWorkspaceName();
String workspaceName = analysisResult.getWorkspaceName();
OutputDirectoryLinksUtils.createOutputDirectoryLinks(dirName, env.getWorkspace(), env.getDirectories().getExecRoot(workspaceName), env.getDirectories().getOutputPath(workspaceName), getReporter(), targetConfiguration, request.getBuildOptions().getSymlinkPrefix(productName), productName);
}
ActionCache actionCache = getActionCache();
SkyframeExecutor skyframeExecutor = env.getSkyframeExecutor();
Builder builder = createBuilder(request, actionCache, skyframeExecutor, modifiedOutputFiles);
//
// Execution proper. All statements below are logically nested in
// begin/end pairs. No early returns or exceptions please!
//
Collection<ConfiguredTarget> configuredTargets = buildResult.getActualTargets();
env.getEventBus().post(new ExecutionStartingEvent(configuredTargets));
getReporter().handle(Event.progress("Building..."));
// Conditionally record dependency-checker log:
ExplanationHandler explanationHandler = installExplanationHandler(request.getBuildOptions().explanationPath, request.getOptionsDescription());
Set<ConfiguredTarget> builtTargets = new HashSet<>();
Collection<AspectValue> aspects = analysisResult.getAspects();
Iterable<Artifact> allArtifactsForProviders = Iterables.concat(additionalArtifacts, TopLevelArtifactHelper.getAllArtifactsToBuild(analysisResult.getTargetsToBuild(), analysisResult.getTopLevelContext()).getAllArtifacts(), TopLevelArtifactHelper.getAllArtifactsToBuildFromAspects(aspects, analysisResult.getTopLevelContext()).getAllArtifacts(), //TODO(dslomov): Artifacts to test from aspects?
TopLevelArtifactHelper.getAllArtifactsToTest(analysisResult.getTargetsToTest()));
if (request.isRunningInEmacs()) {
// The syntax of this message is tightly constrained by lisp/progmodes/compile.el in emacs
request.getOutErr().printErrLn("blaze: Entering directory `" + getExecRoot() + "/'");
}
boolean buildCompleted = false;
try {
for (ActionContextProvider actionContextProvider : actionContextProviders) {
actionContextProvider.executionPhaseStarting(actionGraph, allArtifactsForProviders);
}
executor.executionPhaseStarting();
skyframeExecutor.drainChangedFiles();
if (request.getViewOptions().discardAnalysisCache) {
// Free memory by removing cache entries that aren't going to be needed. Note that in
// skyframe full, this destroys the action graph as well, so we can only do it after the
// action graph is no longer needed.
env.getSkyframeBuildView().clearAnalysisCache(analysisResult.getTargetsToBuild());
}
configureResourceManager(request);
Profiler.instance().markPhase(ProfilePhase.EXECUTE);
builder.buildArtifacts(env.getReporter(), additionalArtifacts, analysisResult.getParallelTests(), analysisResult.getExclusiveTests(), analysisResult.getTargetsToBuild(), analysisResult.getAspects(), executor, builtTargets, request.getBuildOptions().explanationPath != null, env.getBlazeWorkspace().getLastExecutionTimeRange(), topLevelArtifactContext);
buildCompleted = true;
} catch (BuildFailedException | TestExecException e) {
buildCompleted = true;
throw e;
} finally {
env.recordLastExecutionTime();
if (request.isRunningInEmacs()) {
request.getOutErr().printErrLn("blaze: Leaving directory `" + getExecRoot() + "/'");
}
if (buildCompleted) {
getReporter().handle(Event.progress("Building complete."));
}
env.getEventBus().post(new ExecutionFinishedEvent(ImmutableMap.<String, Long>of(), 0L, skyframeExecutor.getOutputDirtyFilesAndClear(), skyframeExecutor.getModifiedFilesDuringPreviousBuildAndClear()));
executor.executionPhaseEnding();
for (ActionContextProvider actionContextProvider : actionContextProviders) {
actionContextProvider.executionPhaseEnding();
}
Profiler.instance().markPhase(ProfilePhase.FINISH);
if (buildCompleted) {
saveCaches(actionCache);
}
try (AutoProfiler p = AutoProfiler.profiled("Show results", ProfilerTask.INFO)) {
buildResult.setSuccessfulTargets(determineSuccessfulTargets(configuredTargets, builtTargets, timer));
BuildResultPrinter buildResultPrinter = new BuildResultPrinter(env);
buildResultPrinter.showBuildResult(request, buildResult, configuredTargets, analysisResult.getAspects());
}
try (AutoProfiler p = AutoProfiler.profiled("Show artifacts", ProfilerTask.INFO)) {
if (request.getBuildOptions().showArtifacts) {
BuildResultPrinter buildResultPrinter = new BuildResultPrinter(env);
buildResultPrinter.showArtifacts(request, configuredTargets, analysisResult.getAspects());
}
}
if (explanationHandler != null) {
uninstallExplanationHandler(explanationHandler);
}
// code has already run.
if (env.getOutputService() != null) {
boolean isBuildSuccessful = buildResult.getSuccessfulTargets().size() == configuredTargets.size();
env.getOutputService().finalizeBuild(isBuildSuccessful);
}
}
}
use of com.google.devtools.build.lib.vfs.ModifiedFileSet in project bazel by bazelbuild.
the class DiffAwarenessManager method getDiff.
/**
* Gets the set of changed files since the last call with this path entry, or
* {@code ModifiedFileSet.EVERYTHING_MODIFIED} if this is the first such call.
*/
public ProcessableModifiedFileSet getDiff(EventHandler eventHandler, Path pathEntry, OptionsClassProvider options) {
DiffAwarenessState diffAwarenessState = maybeGetDiffAwarenessState(pathEntry);
if (diffAwarenessState == null) {
return BrokenProcessableModifiedFileSet.INSTANCE;
}
DiffAwareness diffAwareness = diffAwarenessState.diffAwareness;
View newView;
try {
newView = diffAwareness.getCurrentView(options);
} catch (BrokenDiffAwarenessException e) {
handleBrokenDiffAwareness(eventHandler, pathEntry, e);
return BrokenProcessableModifiedFileSet.INSTANCE;
}
View baselineView = diffAwarenessState.baselineView;
if (baselineView == null) {
LOG.info("Initial baseline view for " + pathEntry + " is " + newView);
diffAwarenessState.baselineView = newView;
return BrokenProcessableModifiedFileSet.INSTANCE;
}
ModifiedFileSet diff;
LOG.info("About to compute diff between " + baselineView + " and " + newView + " for " + pathEntry);
try {
diff = diffAwareness.getDiff(baselineView, newView);
} catch (BrokenDiffAwarenessException e) {
handleBrokenDiffAwareness(eventHandler, pathEntry, e);
return BrokenProcessableModifiedFileSet.INSTANCE;
} catch (IncompatibleViewException e) {
throw new IllegalStateException(pathEntry + " " + baselineView + " " + newView, e);
}
ProcessableModifiedFileSet result = new ProcessableModifiedFileSetImpl(diff, pathEntry, newView);
return result;
}
Aggregations