Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch '1.5'

Conflicts:
	docs/changelog.rst
  • Loading branch information...
commit b5dadddd519de77d35edf0fe9466e02518f41e70 2 parents ee1efc7 + 221731e
@bitprophet bitprophet authored
View
4 docs/changelog.rst
@@ -25,6 +25,10 @@ would have also been included in the 1.2 line.
Changelog
=========
+* :bug:`775` Shell escaping was incorrectly applied to the value of ``$PATH``
+ updates in our shell environment handling, causing (at the very least)
+ `~fabric.operations.local` binary paths to become inoperable in certain
+ situations. This has been fixed.
* :feature:`787` Utilize new Paramiko feature allowing us to skip the use of
temporary local files when using file-like objects in
`~fabric.operations.get`/`~fabric.operations.put`.
View
2  fabric/context_managers.py
@@ -143,7 +143,7 @@ def _setenv(variables):
# If the current env value for this key still matches the
# value we set it to beforehand, we are OK to revert it to the
# pre-block value.
- if value == state.env[key]:
+ if key in state.env and value == state.env[key]:
if key in previous:
state.env[key] = previous[key]
else:
View
6 fabric/operations.py
@@ -672,8 +672,10 @@ def _prefix_env_vars(command):
env_vars.update(env.shell_env)
if env_vars:
- exports = ' '.join('%s="%s"' % (k, _shell_escape(v))
- for k, v in env_vars.iteritems())
+ exports = ' '.join(
+ '%s="%s"' % (k, v if k == 'PATH' else _shell_escape(v))
+ for k, v in env_vars.iteritems()
+ )
shell_env_str = 'export %s && ' % exports
else:
shell_env_str = ''
View
6 fabric/tasks.py
@@ -233,8 +233,10 @@ def execute(task, *args, **kwargs):
taskname:host=hostname``.
Any other arguments or keyword arguments will be passed verbatim into
- ``task`` when it is called, so ``execute(mytask, 'arg1', kwarg1='value')``
- will (once per host) invoke ``mytask('arg1', kwarg1='value')``.
+ ``task`` (the function itself -- not the ``@task`` decorator wrapping your
+ function!) when it is called, so ``execute(mytask, 'arg1',
+ kwarg1='value')`` will (once per host) invoke ``mytask('arg1',
+ kwarg1='value')``.
This function returns a dictionary mapping host strings to the given task's
return value for that host's execution run. For example, ``execute(foo,
View
30 tests/test_context_managers.py
@@ -1,13 +1,14 @@
from __future__ import with_statement
+import os
import sys
from nose.tools import eq_, ok_
from fabric.state import env, output
from fabric.context_managers import (cd, settings, lcd, hide, shell_env, quiet,
- warn_only, prefix)
-from fabric.operations import run
+ warn_only, prefix, path)
+from fabric.operations import run, local
from utils import mock_streams, FabricTest
from server import server
@@ -212,3 +213,28 @@ def test_warn_only_does_not_imply_hide_everything(self):
with warn_only():
run("ls /simple")
assert sys.stdout.getvalue().strip() != ""
+
+
+# path() (distinct from shell_env)
+
+class TestPathManager(FabricTest):
+ def setup(self):
+ super(TestPathManager, self).setup()
+ self.real = os.environ.get('PATH')
+
+ def via_local(self):
+ with hide('everything'):
+ return local("echo $PATH", capture=True)
+
+ def test_lack_of_path_has_default_local_path(self):
+ """
+ No use of 'with path' == default local $PATH
+ """
+ eq_(self.real, self.via_local())
+
+ def test_use_of_path_appends_by_default(self):
+ """
+ 'with path' appends by default
+ """
+ with path('foo'):
+ eq_(self.via_local(), self.real + ":foo")
Please sign in to comment.
Something went wrong with that request. Please try again.