// Copyright 2015 Pants project contributors (see CONTRIBUTORS.md).
// Licensed under the Apache License, Version 2.0 (see LICENSE).
package com.twitter.intellij.pants.service.python;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.externalSystem.model.DataNode;
import com.intellij.openapi.externalSystem.model.ProjectKeys;
import com.intellij.openapi.externalSystem.model.project.*;
import com.intellij.openapi.vfs.VirtualFile;
import com.twitter.intellij.pants.PantsBundle;
import com.twitter.intellij.pants.service.PantsCompileOptionsExecutor;
import com.twitter.intellij.pants.service.project.model.graph.BuildGraph;
import com.twitter.intellij.pants.service.project.PantsResolverExtension;
import com.twitter.intellij.pants.service.project.model.ProjectInfo;
import com.twitter.intellij.pants.util.PantsConstants;
import com.twitter.intellij.pants.util.PantsUtil;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
import java.util.Optional;
public class PythonPexResolver implements PantsResolverExtension {
private static final Logger LOG = Logger.getInstance(PythonPexResolver.class);
@Override
public void resolve(
@NotNull ProjectInfo projectInfo,
@NotNull PantsCompileOptionsExecutor executor,
@NotNull DataNode<ProjectData> projectDataNode,
@NotNull Map<String, DataNode<ModuleData>> modules,
@NotNull Optional<BuildGraph> buildGraph
) {
final Optional<VirtualFile> buildRoot = PantsUtil.findBuildRoot(projectDataNode.getData().getLinkedExternalProjectPath());
final Optional<VirtualFile> bootstrappedPants = buildRoot.map(file -> file.findChild(PantsConstants.PANTS_PEX));
final Optional<VirtualFile> pexFile = bootstrappedPants.flatMap(file -> findSpecificPexVersionInHomeDirectory(buildRoot));
if (pexFile.isPresent()) {
final LibraryData libraryData = new LibraryData(PantsConstants.SYSTEM_ID, PantsConstants.PANTS_LIBRARY_NAME);
libraryData.addPath(LibraryPathType.BINARY, pexFile.get().getPath());
projectDataNode.createChild(ProjectKeys.LIBRARY, libraryData);
for (DataNode<ModuleData> moduleDataNode : modules.values()) {
final LibraryDependencyData library = new LibraryDependencyData(
moduleDataNode.getData(),
libraryData,
LibraryLevel.PROJECT
);
library.setExported(false);
moduleDataNode.createChild(ProjectKeys.LIBRARY_DEPENDENCY, library);
}
}
}
private Optional<VirtualFile> findSpecificPexVersionInHomeDirectory(Optional<VirtualFile> workingDir) {
final Optional<String> pantsVersion = PantsUtil.findPantsVersion(workingDir);
if (!pantsVersion.isPresent()) {
LOG.warn(PantsBundle.message("pants.library.no.version"));
return Optional.empty();
}
final Optional<VirtualFile> folderWithPex = PantsUtil.findFolderWithPex();
if (!folderWithPex.isPresent()) {
LOG.warn(PantsBundle.message("pants.library.no.pex.folder"));
return null;
}
final Optional<VirtualFile> pexFile = folderWithPex.flatMap(file -> PantsUtil.findPexVersionFile(file, pantsVersion.get()));
if (!pexFile.isPresent()) {
LOG.warn(PantsBundle.message("pants.library.no.pex.file", pantsVersion));
return Optional.empty();
}
return pexFile;
}
}