From cc3fb0c926f28067dafd3d52d88d016fc6f8a986 Mon Sep 17 00:00:00 2001 From: Peter Donald Date: Thu, 7 Dec 2000 00:45:22 +0000 Subject: [PATCH] Load environment variables either when a task is explictly executed ( where blah will be prefixed to every variable). Also load it when env elements are specified to exec calls. Submitted By: Jose Alberto Fernandez git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@268325 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/tools/ant/taskdefs/ExecTask.java | 9 ++ .../apache/tools/ant/taskdefs/Execute.java | 114 +++++++++++++++++- .../apache/tools/ant/taskdefs/Property.java | 29 +++++ 3 files changed, 148 insertions(+), 4 deletions(-) diff --git a/src/main/org/apache/tools/ant/taskdefs/ExecTask.java b/src/main/org/apache/tools/ant/taskdefs/ExecTask.java index f91582da3..e8b5e8204 100644 --- a/src/main/org/apache/tools/ant/taskdefs/ExecTask.java +++ b/src/main/org/apache/tools/ant/taskdefs/ExecTask.java @@ -74,6 +74,7 @@ public class ExecTask extends Task { private File out; private File dir; protected boolean failOnError = false; + protected boolean newEnvironment = false; private Integer timeout = null; private Environment env = new Environment(); protected Commandline cmdl = new Commandline(); @@ -131,6 +132,13 @@ public class ExecTask extends Task { failOnError = fail; } + /** + * Use a completely new environment + */ + public void setNewenvironment(boolean newenv) { + newEnvironment = newenv; + } + /** * Add a nested env element - an environment variable. */ @@ -198,6 +206,7 @@ public class ExecTask extends Task { Project.MSG_VERBOSE); } } + exe.setNewenvironment(newEnvironment); exe.setEnvironment(environment); return exe; } diff --git a/src/main/org/apache/tools/ant/taskdefs/Execute.java b/src/main/org/apache/tools/ant/taskdefs/Execute.java index 716fccda4..5698785b6 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Execute.java +++ b/src/main/org/apache/tools/ant/taskdefs/Execute.java @@ -63,9 +63,12 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.io.BufferedReader; +import java.io.StringReader; +import java.io.ByteArrayOutputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; - +import java.util.Vector; /** * Runs an external program. @@ -84,9 +87,11 @@ public class Execute { private ExecuteWatchdog watchdog; private File workingDirectory = null; private Project project = null; + private boolean newEnvironment = false; private static String antWorkingDirectory = System.getProperty("user.dir"); private static CommandLauncher launcher = createCommandLauncher(); + private static Vector procEnvironment = null; /** * Builds a command launcher for the OS and JVM we are running under @@ -138,6 +143,73 @@ public class Execute { } } + /** + * Find the list of environment variables for this process. + */ + public static synchronized Vector getProcEnvironment() { + if (procEnvironment != null) return procEnvironment; + + procEnvironment = new Vector(); + try { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Execute exe = new Execute(new PumpStreamHandler(out)); + exe.setCommandline(getProcEnvCommand()); + // Make sure we do not recurse forever + exe.setNewenvironment(true); + int retval = exe.execute(); + if ( retval != 0 ) { + // Just try to use what we got + } + + BufferedReader in = + new BufferedReader(new StringReader(out.toString())); + String line; + while ((line = in.readLine()) != null) { + procEnvironment.addElement(line); + } + } + catch (java.io.IOException exc) { + exc.printStackTrace(); + // Just try to see how much we got + } + return procEnvironment; + } + + private static String[] getProcEnvCommand() { + String osname = System.getProperty("os.name").toLowerCase(); + if ( osname.indexOf("mac os") >= 0 ) { + // Mac + // TODO: I have no idea how to get it, someone must fix it + String[] cmd = null; + return cmd; + } + else if ( osname.indexOf("os/2") >= 0 ) { + // OS/2 - use same mechanism as Windows 2000 + // Not sure + String[] cmd = {"cmd", "/c", "set" }; + return cmd; + } + else if ( osname.indexOf("indows") >= 0 ) { + // Determine if we're running under 2000/NT or 98/95 + if ( osname.indexOf("nt") >= 0 || osname.indexOf("2000") >= 0 ) { + // Windows 2000/NT + String[] cmd = {"cmd", "/c", "set" }; + return cmd; + } + else { + // Windows 98/95 - need to use an auxiliary script + String[] cmd = {"command.com", "/c", "set" }; + return cmd; + } + } + else { + // Generic UNIX + // Alternatively one could use: /bin/sh -c env + String[] cmd = {"/usr/bin/env"}; + return cmd; + } + } + /** * Creates a new execute object using PumpStreamHandler for * stream handling. @@ -191,12 +263,22 @@ public class Execute { } /** - * Returns the commandline used to create a subprocess. + * Set whether to propagate the default environment or not. * - * @return the commandline used to create a subprocess + * @param newenv whether to propagate the process environment. + */ + public void setNewenvironment(boolean newenv) { + newEnvironment = newenv; + } + + /** + * Returns the environment used to create a subprocess. + * + * @return the environment used to create a subprocess */ public String[] getEnvironment() { - return env; + if (env == null || newEnvironment) return env; + return patchEnvironment(); } @@ -277,6 +359,30 @@ public class Execute { return exitValue; } + /** + * Patch the current environment with the new values from the user. + * @return the patched environment + */ + private String[] patchEnvironment() { + Vector osEnv = (Vector) getProcEnvironment().clone(); + for (int i = 0; i < env.length; i++) { + int pos = env[i].indexOf('='); + // Get key including "=" + String key = env[i].substring(0, pos+1); + int size = osEnv.size(); + for (int j = 0; j < size; j++) { + if (((String)osEnv.elementAt(j)).startsWith(key)) { + osEnv.removeElementAt(j); + break; + } + } + osEnv.addElement(env[i]); + } + String[] result = new String[osEnv.size()]; + osEnv.copyInto(result); + return result; + } + /** * A utility method that runs an external command. Writes the output and * error streams of the command to the project log. diff --git a/src/main/org/apache/tools/ant/taskdefs/Property.java b/src/main/org/apache/tools/ant/taskdefs/Property.java index 65e2a3fd5..f74f5d1dc 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Property.java +++ b/src/main/org/apache/tools/ant/taskdefs/Property.java @@ -73,6 +73,7 @@ public class Property extends Task { protected String value; protected File file; protected String resource; + protected String env; protected Reference ref = null; protected boolean userProperty=false; // set read-only properties @@ -121,6 +122,14 @@ public class Property extends Task { return resource; } + public void setEnvironment(String env) { + this.env = env; + } + + public String getEnvironment() { + return env; + } + public void setUserProperty(boolean userProperty) { this.userProperty = userProperty; } @@ -139,6 +148,8 @@ public class Property extends Task { if (resource != null) loadResource(resource); + if (env != null) loadEnvironment(env); + if ((name != null) && (ref != null)) { Object obj = ref.getReferencedObject(getProject()); if (obj != null) { @@ -193,6 +204,24 @@ public class Property extends Task { } else { log("Unable to find resource " + name, Project.MSG_WARN); } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + protected void loadEnvironment( String prefix ) { + Properties props = new Properties(); + if (!prefix.endsWith(".")) prefix += "."; + log("Loading Environment " + prefix, Project.MSG_VERBOSE); + try { + Vector osEnv = Execute.getProcEnvironment(); + for (Enumeration e = osEnv.elements(); e.hasMoreElements(); ) { + String entry = (String)e.nextElement(); + int pos = entry.indexOf('='); + props.put(prefix + entry.substring(0, pos), + entry.substring(pos + 1)); + } + addProperties(props); } catch (Exception ex) { throw new BuildException(ex, location); }