// 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.intellij.execution.ExecutionException; import com.intellij.execution.configurations.GeneralCommandLine; import com.intellij.execution.process.ProcessOutput; import com.intellij.openapi.project.Project; import com.twitter.intellij.pants.PantsException; import com.twitter.intellij.pants.util.PantsConstants; import com.twitter.intellij.pants.util.PantsUtil; import org.jetbrains.annotations.NotNull; import java.io.File; import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; public class PantsOptions { /** * Cache of PantsOptions mapped from Pants executable files. */ private static ConcurrentHashMap<File, PantsOptions> optionsCache = new ConcurrentHashMap<>(); private Map<String, String> options; public static void clearCache() { optionsCache.clear(); } public PantsOptions(final String rawOutput) { options = parseOptions(rawOutput); } public boolean has(String optionName) { return options.containsKey(optionName); } public Optional<String> get(String optionName) { return Optional.ofNullable(options.get(optionName)); } public static Optional<PantsOptions> getPantsOptions(final Project myProject) { return PantsUtil.findPantsExecutable(myProject).map(file -> getPantsOptions(file.getPath())); } public boolean supportsManifestJar() { return has(PantsConstants.PANTS_OPTION_EXPORT_CLASSPATH_MANIFEST_JAR); } public boolean supportsAsyncCleanAll() { return has(PantsConstants.PANTS_OPTION_ASYNC_CLEAN_ALL); } public static PantsOptions getPantsOptions(@NotNull final String pantsExecutable) { File pantsExecutableFile = new File(pantsExecutable); PantsOptions cache = optionsCache.get(pantsExecutableFile); if (cache != null) { return cache; } GeneralCommandLine exportCommandline = PantsUtil.defaultCommandLine(pantsExecutable); exportCommandline.addParameters("options", PantsConstants.PANTS_CLI_OPTION_NO_COLORS); try { final ProcessOutput processOutput = PantsUtil.getProcessOutput(exportCommandline, null); PantsOptions result = new PantsOptions(processOutput.getStdout()); optionsCache.put(pantsExecutableFile, result); return result; } catch (ExecutionException e) { throw new PantsException("Failed:" + exportCommandline.getCommandLineString()); } } // TODO https://github.com/pantsbuild/pants/issues/3161 to output options in json, // parsing will be simplified. private static Map<String, String> parseOptions(final String rawData) { String lines[] = rawData.split("\\r?\\n"); Map<String, String> options = new HashMap<String, String>(); for (String line : lines) { String fields[] = line.split(" = ", 2); if (fields.length != 2) { continue; } String optionValue = fields[1].replaceAll("\\s*\\(from (NONE|HARDCODED|CONFIG|ENVIRONMENT|FLAG).*", ""); options.put(fields[0], optionValue); } return options; } }