/*
* Copyright 2016-present Facebook, Inc.
*
* 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.facebook.buck.cxx;
import com.facebook.buck.io.ProjectFilesystem;
import com.facebook.buck.step.ExecutionContext;
import com.facebook.buck.step.Step;
import com.facebook.buck.step.StepExecutionResult;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Optional;
public final class CxxCollectAndLogInferDependenciesStep implements Step {
private Optional<CxxInferAnalyze> analysisRule;
private Optional<CxxInferCaptureTransitive> captureOnlyRule;
private ProjectFilesystem projectFilesystem;
private Path outputFile;
private CxxCollectAndLogInferDependenciesStep(
Optional<CxxInferAnalyze> analysisRule,
Optional<CxxInferCaptureTransitive> captureOnlyRule,
ProjectFilesystem projectFilesystem,
Path outputFile) {
this.analysisRule = analysisRule;
this.captureOnlyRule = captureOnlyRule;
this.projectFilesystem = projectFilesystem;
this.outputFile = outputFile;
}
public static CxxCollectAndLogInferDependenciesStep fromAnalyzeRule(
CxxInferAnalyze analyzeRule, ProjectFilesystem projectFilesystem, Path outputFile) {
return new CxxCollectAndLogInferDependenciesStep(
Optional.of(analyzeRule), Optional.empty(), projectFilesystem, outputFile);
}
public static CxxCollectAndLogInferDependenciesStep fromCaptureOnlyRule(
CxxInferCaptureTransitive captureOnlyRule,
ProjectFilesystem projectFilesystem,
Path outputFile) {
return new CxxCollectAndLogInferDependenciesStep(
Optional.empty(), Optional.of(captureOnlyRule), projectFilesystem, outputFile);
}
private String processCaptureRule(CxxInferCapture captureRule) {
return InferLogLine.fromBuildTarget(
captureRule.getBuildTarget(), captureRule.getAbsolutePathToOutput())
.toString();
}
private ImmutableList<String> processCaptureOnlyRule(CxxInferCaptureTransitive captureOnlyRule) {
ImmutableList.Builder<String> outputBuilder = ImmutableList.builder();
for (CxxInferCapture captureRule : captureOnlyRule.getCaptureRules()) {
outputBuilder.add(processCaptureRule(captureRule));
}
return outputBuilder.build();
}
private void processAnalysisRuleHelper(
CxxInferAnalyze analysisRule, ImmutableList.Builder<String> accumulator) {
accumulator.add(
InferLogLine.fromBuildTarget(
analysisRule.getBuildTarget(), analysisRule.getAbsolutePathToResultsDir())
.toString());
accumulator.addAll(
analysisRule.getCaptureRules().stream().map(this::processCaptureRule).iterator());
}
private ImmutableList<String> processAnalysisRule(CxxInferAnalyze analyzeRule) {
ImmutableList.Builder<String> outputBuilder = ImmutableList.builder();
processAnalysisRuleHelper(analyzeRule, outputBuilder);
for (CxxInferAnalyze analyzeDepRule : analyzeRule.getTransitiveAnalyzeRules()) {
processAnalysisRuleHelper(analyzeDepRule, outputBuilder);
}
return outputBuilder.build();
}
@Override
public StepExecutionResult execute(ExecutionContext context)
throws IOException, InterruptedException {
ImmutableList<String> output;
if (analysisRule.isPresent()) {
output = processAnalysisRule(analysisRule.get());
} else if (captureOnlyRule.isPresent()) {
output = processCaptureOnlyRule(captureOnlyRule.get());
} else {
throw new IllegalStateException("Expected non-empty analysis or capture rules in input");
}
projectFilesystem.writeLinesToPath(output, outputFile);
return StepExecutionResult.SUCCESS;
}
@Override
public String getShortName() {
return "infer-log-deps";
}
@Override
public String getDescription(ExecutionContext context) {
return "Log Infer's dependencies used for the analysis";
}
}