blob: bab90cfcd9b57331deb897e321b37ea1c6b25758 [file] [log] [blame]
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* 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.intellij.execution.configurations;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.EnvironmentUtil;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.FileFilter;
import java.util.Collections;
import java.util.List;
/**
* @author Sergey Simonchik
*/
public class PathEnvironmentVariableUtil {
private static final Logger LOG = Logger.getInstance(PathEnvironmentVariableUtil.class);
private static final String PATH_ENV_VAR_NAME = "PATH";
private PathEnvironmentVariableUtil() { }
/**
* Finds an executable file with the specified base name, that is located in a directory
* listed in PATH environment variable.
*
* @param fileBaseName file base name
* @return {@code File} instance or null if not found
*/
@Nullable
public static File findInPath(@NotNull String fileBaseName) {
return findInPath(fileBaseName, false);
}
/**
* Finds an executable file with the specified base name, that is located in a directory
* listed in PATH environment variable and is accepted by filter.
*
* @param fileBaseName file base name
* @param filter exe file filter
* @return {@code File} instance or null if not found
*/
@Nullable
public static File findInPath(@NotNull String fileBaseName, @Nullable FileFilter filter) {
return findInPath(fileBaseName, false, filter);
}
/**
* Finds an executable file with the specified base name, that is located in a directory
* listed in PATH environment variable.
*
* @param fileBaseName file base name
* @param logDetails true if extra logging is needed
* @return {@code File} instance or null if not found
*/
@Nullable
public static File findInPath(@NotNull String fileBaseName, boolean logDetails) {
return findInPath(fileBaseName, logDetails, null);
}
@Nullable
private static File findInPath(@NotNull String fileBaseName, boolean logDetails, @Nullable FileFilter filter) {
List<File> exeFiles = findExeFilesInPath(fileBaseName, true, logDetails, filter);
return exeFiles.size() > 0 ? exeFiles.get(0) : null;
}
/**
* Finds an executable file with the specified base name, that is located in a directory
* listed in an original PATH environment variable.
* Original PATH environment variable value is a value returned by <code>System.getenv("PATH")</code>.
*
* @param fileBaseName file base name
* @return {@code File} instance or null if not found
*/
private static File findInOriginalPath(@NotNull String fileBaseName) {
String originalPath;
if (SystemInfo.isMac) {
originalPath = System.getenv(PATH_ENV_VAR_NAME);
}
else {
originalPath = EnvironmentUtil.getValue(PATH_ENV_VAR_NAME);
}
List<File> exeFiles = doFindExeFilesInPath(originalPath, fileBaseName, true, false, null);
return exeFiles.size() > 0 ? exeFiles.get(0) : null;
}
/**
* Finds all executable files with the specified base name, that are located in directories
* from PATH environment variable.
*
* @param fileBaseName file base name
* @return file list
*/
@NotNull
public static List<File> findAllExeFilesInPath(@NotNull String fileBaseName) {
return findAllExeFilesInPath(fileBaseName, null);
}
@NotNull
public static List<File> findAllExeFilesInPath(@NotNull String fileBaseName, @Nullable FileFilter filter) {
return findExeFilesInPath(fileBaseName, false, false, filter);
}
@NotNull
private static List<File> findExeFilesInPath(@NotNull String fileBaseName,
boolean stopAfterFirstMatch,
boolean logDetails,
@Nullable FileFilter filter) {
String systemPath = EnvironmentUtil.getValue(PATH_ENV_VAR_NAME);
return doFindExeFilesInPath(systemPath, fileBaseName, stopAfterFirstMatch, logDetails, filter);
}
@NotNull
private static List<File> doFindExeFilesInPath(@Nullable String pathEnvVarValue,
@NotNull String fileBaseName,
boolean stopAfterFirstMatch,
boolean logDetails,
@Nullable FileFilter filter) {
if (logDetails) {
LOG.info("Finding files in PATH (base name=" + fileBaseName + ", PATH=" + StringUtil.notNullize(pathEnvVarValue) + ").");
}
if (pathEnvVarValue == null) {
return Collections.emptyList();
}
List<File> result = new SmartList<File>();
List<String> paths = StringUtil.split(pathEnvVarValue, File.pathSeparator, true, true);
for (String path : paths) {
File dir = new File(path);
if (logDetails) {
File file = new File(dir, fileBaseName);
LOG.info("path:" + path + ", path.isAbsolute:" + dir.isAbsolute() + ", path.isDirectory:" + dir.isDirectory()
+ ", file.isFile:" + file.isFile() + ", file.canExecute:" + file.canExecute());
}
if (dir.isAbsolute() && dir.isDirectory()) {
File exeFile = new File(dir, fileBaseName);
if (exeFile.isFile() && exeFile.canExecute()) {
if (filter == null || filter.accept(exeFile)) {
result.add(exeFile);
if (stopAfterFirstMatch) {
return result;
}
}
}
}
}
return result;
}
/**
* Finds the absolute path of an executable file in PATH by the given relative path.
* This method makes sense for Mac only, because other OSs pass correct environment variables to IDE process
* letting {@link ProcessBuilder#start} sees correct PATH environment variable.
*
* @param exePath String relative path (or just a base name)
* @return the absolute path if the executable file found, and the given {@code exePath} otherwise
*/
@NotNull
public static String findAbsolutePathOnMac(@NotNull String exePath) {
if (SystemInfo.isMac) {
if (!exePath.contains(File.separator)) {
File originalResolvedExeFile = findInOriginalPath(exePath);
// don't modify exePath if the absolute path can be found in the original PATH
if (originalResolvedExeFile == null) {
File resolvedExeFile = findInPath(exePath);
if (resolvedExeFile != null) {
exePath = resolvedExeFile.getAbsolutePath();
}
}
}
}
return exePath;
}
}