/*
* Copyright 2014-present Facebook, Inc.
*
* 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.facebook.buck.intellij.ideabuck.environment;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import java.util.Locale;
import java.util.Map;
/** Utility class to filter system environment maps. */
public class EnvironmentFilter {
// Always exclude environment variables with these names.
private static final ImmutableSet<String> ENV_TO_REMOVE =
ImmutableSet.of(
"ATOM_BACKUP_EDITOR", // Added by Nuclide editor
"ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT", // Added by Nuclide editor
"ATOM_HOME", // Added by Nuclide editor
"ARCANIST", // Phabricator / Arcanist cruft.
"Apple_PubSub_Socket_Render", // OS X pubsub control variable.
"BUCK_BUILD_ID", // Build ID passed in from Python.
"BUCK_CLASSPATH", // Main classpath; set in Python
"CHGHG", // Mercurial
"CHGTIMEOUT", // Mercurial
"CLASSPATH", // Bootstrap classpath; set in Python.
"COLORFGBG",
"COLUMNS",
"CMD_DURATION", // Added to environment by 'fish' shell.
"com.apple.java.jvmTask", // Added to environment by Apple JVM.
"COMP_WORDBREAKS", // Set by the programmable completion part of bash.
"DBUS_SESSION_BUS_ADDRESS",
"DIFF_EDITOR", // Changes between terminals and GUIs
"EDITOR", // Changes between terminals and GUIs
"GOOGLE_API_KEY", // Added by Nuclide editor
"GOROOT",
"HG", // Mercurial
"HGNODE", // Mercurial
"HG_NODE", // Mercurial
"HISTSIZE", // Bash history configuration.
"HISTCONTROL", // Bash history configuration.
"HPHP_INTERPRETER", // Added by hhvm.
"ITERM_SESSION_ID", // Added by iTerm on OS X.
"ITERM_ORIG_PS1", // Added by iTerm on OS X.
"ITERM_PREV_PS1", // Added by iTerm on OS X.
"ITERM_PROFILE", // Added by iTerm on OS X.
"JAVA_ARCH", // More OS X cruft.
"KRB5CCNAME", // Kerberos authentication adds this.
"KRB5RCACHETYPE", // More Kerberos cruft.
"LOG_SESSION_ID", // Session ID for certain environments.
"LINES",
"LS_COLORS", // Colour configuration for ls
"MAIL",
"MallocNanoZone", // Added to environment by Xcode
"NODE_ENV", // Added by Nuclide editor
"NODE_PATH", // Added by Nuclide editor
"OLDPWD", // Previous working directory; set by bash's cd builtin.
"PAR_LAUNCH_TIMESTAMP",
"PROMPT_COMMAND", // Prompt control variable, just in case someone exports it.
"PS1", // Same.
"PS2", // Same.
"PS3", // Same.
"PS4", // Same.
"PWD", // Current working directory; set by bash.
"SECURITYSESSIONID", // Session ID for certain environments.
"SHELL",
"SHLVL", // Shell nestedness level; set by bash.
"SSH_AGENT_PID", // SSH session management variable.
"SSH_ASKPASS", // Same.
"SSH_AUTH_SOCK", // Same.
"SSH_CLIENT", // Same.
"SSH_CONNECTION", // Same.
"SSH_TTY", // Same.
"SUDO_COMMAND", // Folks shouldn't run buck under sudo, but..
"TERMCAP",
"TERMINIX_ID", // Added by Terminix on Linux.
"TERM_SESSION_ID", // UUID added to environment by OS X.
"TERM_PROGRAM", // Added to environment by OS X.
"TERM_PROGRAM_VERSION", // Added to environment by OS X.
"TMUX", // tmux session management variable.
"TMUX_PANE", // Current tmux pane.
"WINDOW",
"XDG_SESSION_ID", // Session ID for certain environments.
"XPC_FLAGS", // More OS X cruft.
"XPC_SERVICE_NAME" // Same.
);
// Ignore the environment variables with these names when comparing environments.
private static final ImmutableSet<String> ENV_TO_IGNORE =
ImmutableSet.of(
"ANDROID_SERIAL", // Serial of the target Android device/emulator.
"BUCK_TTY", // Whether buck's stdin is connected to a TTY
"SCRIPT", // Populated by script command: http://www.freebsd.org/cgi/man.cgi?script
"NAILGUN_TTY_0", // Nailgun stdin supports ANSI escape sequences.
"NAILGUN_TTY_1", // Nailgun stdout supports ANSI escape sequences.
"NAILGUN_TTY_2", // Nailgun stderr supports ANSI escape sequences.
"TERM" // The type of terminal we're connected to, used by AnsiEnvironmentChecking
);
// Ignore environment variables whose names start with this string.
private static final ImmutableSet<String> ENV_PREFIXES_TO_IGNORE =
ImmutableSet.of(
"JAVA_MAIN_CLASS_", "SCM_" // Source control, e.g. SCM_WORKER_EXE
);
public static final Predicate<String> NOT_IGNORED_ENV_PREDICATE =
Predicates.not(
Predicates.or(
ENV_TO_IGNORE::contains,
value -> {
for (String prefix : ENV_PREFIXES_TO_IGNORE) {
if (value.startsWith(prefix)) {
return true;
}
}
return false;
}));
// Utility class, do not instantiate.
private EnvironmentFilter() {}
/**
* Given a map (environment variable name: environment variable value) pairs, returns a map
* without the variables which we should not pass to child processes (buck.py, javac, etc.)
*
* <p>Keeping the environment map clean helps us avoid jettisoning the parser cache, as we have to
* rebuild it any time the environment changes.
*/
public static ImmutableMap<String, String> filteredEnvironment(
ImmutableMap<String, String> environment, Platform platform) {
ImmutableMap.Builder<String, String> filteredEnvironmentBuilder = ImmutableMap.builder();
for (Map.Entry<String, String> envEntry : environment.entrySet()) {
String key = envEntry.getKey();
if (!ENV_TO_REMOVE.contains(key)) {
if (platform == Platform.WINDOWS) {
// Windows environment variables are case insensitive. While an ImmutableMap will throw
// if we get duplicate key, we don't have to worry about this for Windows.
filteredEnvironmentBuilder.put(key.toUpperCase(Locale.US), envEntry.getValue());
} else {
filteredEnvironmentBuilder.put(envEntry);
}
}
}
return filteredEnvironmentBuilder.build();
}
}