Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F13988072
D15751.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
10 KB
Referenced Files
None
Subscribers
None
D15751.diff
View Options
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -192,6 +192,7 @@
'PhutilExcessiveServiceCallsDaemon' => 'daemon/torture/PhutilExcessiveServiceCallsDaemon.php',
'PhutilExecChannel' => 'channel/PhutilExecChannel.php',
'PhutilExecPassthru' => 'future/exec/PhutilExecPassthru.php',
+ 'PhutilExecutableFuture' => 'future/exec/PhutilExecutableFuture.php',
'PhutilExecutionEnvironment' => 'utils/PhutilExecutionEnvironment.php',
'PhutilExtensionsTestCase' => 'moduleutils/__tests__/PhutilExtensionsTestCase.php',
'PhutilFacebookAuthAdapter' => 'auth/PhutilFacebookAuthAdapter.php',
@@ -576,7 +577,7 @@
'ConduitClientException' => 'Exception',
'ConduitClientTestCase' => 'PhutilTestCase',
'ConduitFuture' => 'FutureProxy',
- 'ExecFuture' => 'Future',
+ 'ExecFuture' => 'PhutilExecutableFuture',
'ExecFutureTestCase' => 'PhutilTestCase',
'ExecPassthruTestCase' => 'PhutilTestCase',
'FileFinder' => 'Phobject',
@@ -736,7 +737,8 @@
'PhutilExampleBufferedIterator' => 'PhutilBufferedIterator',
'PhutilExcessiveServiceCallsDaemon' => 'PhutilTortureTestDaemon',
'PhutilExecChannel' => 'PhutilChannel',
- 'PhutilExecPassthru' => 'Phobject',
+ 'PhutilExecPassthru' => 'PhutilExecutableFuture',
+ 'PhutilExecutableFuture' => 'Future',
'PhutilExecutionEnvironment' => 'Phobject',
'PhutilExtensionsTestCase' => 'PhutilTestCase',
'PhutilFacebookAuthAdapter' => 'PhutilOAuthAuthAdapter',
diff --git a/src/future/exec/ExecFuture.php b/src/future/exec/ExecFuture.php
--- a/src/future/exec/ExecFuture.php
+++ b/src/future/exec/ExecFuture.php
@@ -19,7 +19,7 @@
* @task interact Interacting With Commands
* @task internal Internals
*/
-final class ExecFuture extends Future {
+final class ExecFuture extends PhutilExecutableFuture {
private $pipes = array();
private $proc = null;
@@ -35,8 +35,6 @@
private $stdoutPos = 0;
private $stderrPos = 0;
private $command = null;
- private $env = null;
- private $cwd;
private $readBufferSize;
private $stdoutSizeLimit = PHP_INT_MAX;
@@ -181,59 +179,6 @@
/**
- * Set the current working directory to use when executing the command.
- *
- * @param string Directory to set as CWD before executing the command.
- * @return this
- * @task config
- */
- public function setCWD($cwd) {
- $this->cwd = $cwd;
- return $this;
- }
-
-
- /**
- * Set the environment variables to use when executing the command.
- *
- * @param array Environment variables to use when executing the command.
- * @return this
- * @task config
- */
- public function setEnv($env, $wipe_process_env = false) {
- if ($wipe_process_env) {
- $this->env = $env;
- } else {
- $this->env = $env + $_ENV;
- }
- return $this;
- }
-
-
- /**
- * Set the value of a specific environmental variable for this command.
- *
- * @param string Environmental variable name.
- * @param string|null New value, or null to remove this variable.
- * @return this
- * @task config
- */
- public function updateEnv($key, $value) {
- if (!is_array($this->env)) {
- $this->env = $_ENV;
- }
-
- if ($value === null) {
- unset($this->env[$key]);
- } else {
- $this->env[$key] = $value;
- }
-
- return $this;
- }
-
-
- /**
* Set whether to use non-blocking streams on Windows.
*
* @param bool Whether to use non-blocking streams.
@@ -659,26 +604,14 @@
}
}
-
- // NOTE: Convert all the environmental variables we're going to pass
- // into strings before we install PhutilErrorTrap. If something in here
- // is really an object which is going to throw when we try to turn it
- // into a string, we want the exception to escape here -- not after we
- // start trapping errors.
- $env = $this->env;
- if ($env !== null) {
- foreach ($env as $key => $value) {
- $env[$key] = (string)$value;
- }
- }
-
- // Same for the working directory.
- if ($this->cwd === null) {
- $cwd = null;
+ if ($this->hasEnv()) {
+ $env = $this->getEnv();
} else {
- $cwd = (string)$this->cwd;
+ $env = null;
}
+ $cwd = $this->getCWD();
+
// NOTE: See note above about Phage.
if (class_exists('PhutilErrorTrap')) {
$trap = new PhutilErrorTrap();
diff --git a/src/future/exec/PhutilExecPassthru.php b/src/future/exec/PhutilExecPassthru.php
--- a/src/future/exec/PhutilExecPassthru.php
+++ b/src/future/exec/PhutilExecPassthru.php
@@ -17,13 +17,12 @@
* @{method:setCWD}, and set the environment with @{method:setEnv}.
*
* @task command Executing Passthru Commands
- * @task config Configuring Passthru Commands
*/
-final class PhutilExecPassthru extends Phobject {
+final class PhutilExecPassthru extends PhutilExecutableFuture {
+
private $command;
- private $env;
- private $cwd;
+ private $passthruResult;
/* -( Executing Passthru Commands )---------------------------------------- */
@@ -72,8 +71,13 @@
$unmasked_command = $command;
}
- $env = $this->env;
- $cwd = $this->cwd;
+ if ($this->hasEnv()) {
+ $env = $this->getEnv();
+ } else {
+ $env = null;
+ }
+
+ $cwd = $this->getCWD();
$options = array();
if (phutil_is_windows()) {
@@ -115,50 +119,23 @@
}
-/* -( Configuring Passthru Commands )-------------------------------------- */
+/* -( Future )------------------------------------------------------------- */
- /**
- * Set environmental variables for the subprocess.
- *
- * By default, variables are added to the environment of this process. You
- * can optionally wipe the environment and pass only the specified values.
- *
- * // Env will have "X" and current env ("PATH", etc.)
- * $exec->setEnv(array('X' => 'y'));
- *
- * // Env will have ONLY "X".
- * $exec->setEnv(array('X' => 'y'), $wipe_process_env = true);
- *
- * @param dict Dictionary of environmental variables.
- * @param bool Optionally, pass true to wipe the existing environment clean.
- * @return this
- *
- * @task config
- */
- public function setEnv(array $env, $wipe_process_env = false) {
- if ($wipe_process_env) {
- $this->env = $env;
- } else {
- $this->env = $env + $_ENV;
+ public function isReady() {
+ // This isn't really a future because it executes synchronously and has
+ // full control of the console. We're just implementing the interfaces to
+ // make it easier to share code with ExecFuture.
+
+ if ($this->passthruResult === null) {
+ $this->passthruResult = $this->execute();
}
- return $this->env;
- }
+ return true;
+ }
- /**
- * Set the current working directory for the subprocess (that is, set where
- * the subprocess will execute). If not set, the default value is the parent's
- * current working directory.
- *
- * @param string Directory to execute the subprocess in.
- * @return this
- *
- * @task config
- */
- public function setCWD($cwd) {
- $this->cwd = $cwd;
- return $this;
+ protected function getResult() {
+ return $this->passthruResult;
}
}
diff --git a/src/future/exec/PhutilExecutableFuture.php b/src/future/exec/PhutilExecutableFuture.php
new file mode 100644
--- /dev/null
+++ b/src/future/exec/PhutilExecutableFuture.php
@@ -0,0 +1,122 @@
+<?php
+
+/**
+ * @task config Configuring the Command
+ */
+abstract class PhutilExecutableFuture extends Future {
+
+
+ private $env;
+ private $cwd;
+
+
+ /**
+ * Set environmental variables for the command.
+ *
+ * By default, variables are added to the environment of this process. You
+ * can optionally wipe the environment and pass only the specified values.
+ *
+ * // Env will have "X" and current env ("PATH", etc.)
+ * $exec->setEnv(array('X' => 'y'));
+ *
+ * // Env will have ONLY "X".
+ * $exec->setEnv(array('X' => 'y'), $wipe_process_env = true);
+ *
+ * @param map<string, string> Dictionary of environmental variables.
+ * @param bool Optionally, pass `true` to replace the existing environment.
+ * @return this
+ *
+ * @task config
+ */
+ final public function setEnv(array $env, $wipe_process_env = false) {
+ // Force values to strings here. The underlying PHP commands get upset if
+ // they are handed non-string values as environmental variables.
+ foreach ($env as $key => $value) {
+ $env[$key] = (string)$value;
+ }
+
+ if (!$wipe_process_env) {
+ $env = $env + $this->getEnv();
+ }
+
+ $this->env = $env;
+
+ return $this;
+ }
+
+
+ /**
+ * Set the value of a specific environmental variable for this command.
+ *
+ * @param string Environmental variable name.
+ * @param string|null New value, or null to remove this variable.
+ * @return this
+ * @task config
+ */
+ final public function updateEnv($key, $value) {
+ $env = $this->getEnv();
+
+ if ($value === null) {
+ unset($env[$key]);
+ } else {
+ $env[$key] = (string)$value;
+ }
+
+ $this->env = $env;
+
+ return $this;
+ }
+
+
+ /**
+ * Returns `true` if this command has a configured environment.
+ *
+ * @return bool True if this command has an environment.
+ * @task config
+ */
+ final public function hasEnv() {
+ return ($this->env !== null);
+ }
+
+
+ /**
+ * Get the configured environment.
+ *
+ * @return map<string, string> Effective environment for this command.
+ * @task config
+ */
+ final public function getEnv() {
+ if (!$this->hasEnv()) {
+ $this->setEnv($_ENV, $wipe_process_env = true);
+ }
+
+ return $this->env;
+ }
+
+
+ /**
+ * Set the current working directory for the subprocess (that is, set where
+ * the subprocess will execute). If not set, the default value is the parent's
+ * current working directory.
+ *
+ * @param string Directory to execute the subprocess in.
+ * @return this
+ * @task config
+ */
+ final public function setCWD($cwd) {
+ $this->cwd = (string)$cwd;
+ return $this;
+ }
+
+
+ /**
+ * Get the command's current working directory.
+ *
+ * @return string Working directory.
+ * @task config
+ */
+ final public function getCWD() {
+ return $this->cwd;
+ }
+
+}
diff --git a/src/phage/bootloader/PhagePHPAgentBootloader.php b/src/phage/bootloader/PhagePHPAgentBootloader.php
--- a/src/phage/bootloader/PhagePHPAgentBootloader.php
+++ b/src/phage/bootloader/PhagePHPAgentBootloader.php
@@ -47,6 +47,7 @@
'xsprintf/PhutilCommandString.php',
'future/Future.php',
'future/FutureIterator.php',
+ 'future/exec/PhutilExecutableFuture.php',
'future/exec/ExecFuture.php',
'future/exec/CommandException.php',
'channel/PhutilChannel.php',
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Oct 22, 12:59 PM (1 w, 6 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6718477
Default Alt Text
D15751.diff (10 KB)
Attached To
Mode
D15751: Share Env/CWD methods between Passthru + ExecFuture, expose Env
Attached
Detach File
Event Timeline
Log In to Comment