// Copyright 2016 Pants project contributors (see CONTRIBUTORS.md).
// Licensed under the Apache License, Version 2.0 (see LICENSE).
package com.twitter.intellij.pants.model;
import com.google.common.annotations.VisibleForTesting;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.process.ProcessOutput;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.FileUtil;
import com.twitter.intellij.pants.PantsException;
import com.twitter.intellij.pants.util.PantsConstants;
import com.twitter.intellij.pants.util.PantsUtil;
import com.twitter.intellij.pants.util.TempFile;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
/**
* This represents information from pants export that is not tied with targets,
* obtained by running pants export command with no target arguments. Class
* is in POJO form to facilitate json parsing.
* <p>
* See {@link com.twitter.intellij.pants.service.project.model.ProjectInfo} for
* target level information from pants export.
*/
public class SimpleExportResult {
/**
* Cache of SimpleExportResult mapped from path of Pants executable files.
*/
private static ConcurrentHashMap<File, SimpleExportResult> simpleExportCache = new ConcurrentHashMap<>();
private static final Logger LOG = Logger.getInstance(SimpleExportResult.class);
private String version;
private Map<String, Map<String, String>> preferredJvmDistributions;
private DefaultPlatform jvmPlatforms;
public static void clearCache() {
simpleExportCache.clear();
}
public Map<String, Map<String, String>> getPreferredJvmDistributions() {
return preferredJvmDistributions;
}
public DefaultPlatform getJvmPlatforms() {
return jvmPlatforms;
}
public String getVersion() {
return version;
}
public static class DefaultPlatform {
private String defaultPlatform;
public String getDefaultPlatform() {
return defaultPlatform;
}
}
private static final Gson GSON_PARSER = new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
@NotNull
public static SimpleExportResult getExportResult(@NotNull String pantsExecutable) {
File pantsExecutableFile = new File(pantsExecutable);
SimpleExportResult cache = simpleExportCache.get(pantsExecutableFile);
if (cache != null) {
return cache;
}
final GeneralCommandLine commandline = PantsUtil.defaultCommandLine(pantsExecutable);
commandline.addParameters("export", PantsConstants.PANTS_CLI_OPTION_NO_COLORS);
try (TempFile tempFile = TempFile.create("pants_export_run", ".out")) {
commandline.addParameter(
String.format("%s=%s", PantsConstants.PANTS_CLI_OPTION_EXPORT_OUTPUT_FILE,
tempFile.getFile().getPath()));
final ProcessOutput processOutput = PantsUtil.getProcessOutput(commandline, null);
if (processOutput.checkSuccess(LOG)) {
SimpleExportResult result = parse(FileUtil.loadFile(tempFile.getFile()));
simpleExportCache.put(pantsExecutableFile, result);
return result;
}
}
catch (IOException | ExecutionException e) {
// Fall-through to handle outside the block.
}
throw new PantsException("Failed:" + commandline.getCommandLineString());
}
public Optional<String> getJdkHome(boolean strict) {
Map<String, String> platformMap = getPreferredJvmDistributions()
.get(getJvmPlatforms().getDefaultPlatform());
if (platformMap == null) {
return Optional.empty();
}
return Optional.ofNullable(platformMap.get(strict ? PantsConstants.PANTS_EXPORT_KEY_STRICT : PantsConstants.PANTS_EXPORT_KEY_NON_STRICT));
}
@VisibleForTesting
@NotNull
public static SimpleExportResult parse(@NotNull String output) {
return GSON_PARSER.fromJson(output, SimpleExportResult.class);
}
}