blob: bd54a391377de8382782ae913914cbddf80c483e [file] [log] [blame]
/*
* 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.idea.blaze.base.sync.workspace;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.idea.blaze.base.command.info.BlazeInfo;
import com.google.idea.blaze.base.io.FileAttributeProvider;
import com.google.idea.blaze.base.model.primitives.ExecutionRootPath;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.settings.Blaze;
import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import java.io.File;
import java.io.Serializable;
import java.util.List;
import javax.annotation.Nullable;
/** The data output by BlazeInfo. */
public class BlazeRoots implements Serializable {
public static final long serialVersionUID = 3L;
private static final Logger LOG = Logger.getInstance(BlazeRoots.class);
public static ListenableFuture<BlazeRoots> compute(
Project project, WorkspaceRoot workspaceRoot, BlazeContext context) {
BuildSystem buildSystem = Blaze.getBuildSystem(project);
ListenableFuture<ImmutableMap<String, String>> blazeInfoDataFuture =
BlazeInfo.getInstance()
.runBlazeInfo(context, buildSystem, workspaceRoot, ImmutableList.of());
return Futures.transform(
blazeInfoDataFuture,
new Function<ImmutableMap<String, String>, BlazeRoots>() {
@Nullable
@Override
public BlazeRoots apply(@Nullable ImmutableMap<String, String> blazeInfoData) {
// This method is supposed to throw if the input is null
// but the input is not allowed to be null.
if (blazeInfoData == null) {
throw new NullPointerException("blazeInfoData is not allowed to be null");
}
return build(
workspaceRoot,
getOrThrow(buildSystem, blazeInfoData, BlazeInfo.EXECUTION_ROOT_KEY),
getOrThrow(buildSystem, blazeInfoData, BlazeInfo.PACKAGE_PATH_KEY),
getOrThrow(buildSystem, blazeInfoData, BlazeInfo.blazeBinKey(buildSystem)),
getOrThrow(buildSystem, blazeInfoData, BlazeInfo.blazeGenfilesKey(buildSystem)));
}
});
}
private static String getOrThrow(
BuildSystem buildSystem, ImmutableMap<String, String> map, String key) {
String value = map.get(key);
if (value == null) {
throw new RuntimeException(
String.format("Could not locate %s in %s info", key, buildSystem.getLowerCaseName()));
}
return value;
}
private static BlazeRoots build(
WorkspaceRoot workspaceRoot,
String execRootString,
String packagePathString,
String blazeBinRoot,
String blazeGenfilesRoot) {
List<File> packagePaths = parsePackagePaths(workspaceRoot.toString(), packagePathString.trim());
File executionRoot = new File(execRootString.trim());
ExecutionRootPath blazeBinExecutionRootPath =
ExecutionRootPath.createAncestorRelativePath(executionRoot, new File(blazeBinRoot));
ExecutionRootPath blazeGenfilesExecutionRootPath =
ExecutionRootPath.createAncestorRelativePath(executionRoot, new File(blazeGenfilesRoot));
LOG.assertTrue(blazeBinExecutionRootPath != null);
LOG.assertTrue(blazeGenfilesExecutionRootPath != null);
return new BlazeRoots(
executionRoot, packagePaths, blazeBinExecutionRootPath, blazeGenfilesExecutionRootPath);
}
private static List<File> parsePackagePaths(String workspaceRoot, String packagePathString) {
String[] paths = packagePathString.split(":");
List<File> packagePaths = Lists.newArrayListWithCapacity(paths.length);
FileAttributeProvider fileAttributeProvider = FileAttributeProvider.getInstance();
for (String path : paths) {
File packagePath = new File(path.replace("%workspace%", workspaceRoot));
if (fileAttributeProvider.exists(packagePath)) {
packagePaths.add(packagePath);
}
}
return packagePaths;
}
public final File executionRoot;
public final List<File> packagePaths;
public final ExecutionRootPath blazeBinExecutionRootPath;
public final ExecutionRootPath blazeGenfilesExecutionRootPath;
@VisibleForTesting
public BlazeRoots(
File executionRoot,
List<File> packagePaths,
ExecutionRootPath blazeBinExecutionRootPath,
ExecutionRootPath blazeGenfilesExecutionRootPath) {
this.executionRoot = executionRoot;
this.packagePaths = packagePaths;
this.blazeBinExecutionRootPath = blazeBinExecutionRootPath;
this.blazeGenfilesExecutionRootPath = blazeGenfilesExecutionRootPath;
}
public File getGenfilesDirectory() {
return blazeGenfilesExecutionRootPath.getFileRootedAt(executionRoot);
}
}