Hello community,

here is the log from the commit of package python-Fabric for openSUSE:Factory 
checked in at 2012-02-14 13:10:41
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-Fabric (Old)
 and      /work/SRC/openSUSE:Factory/.python-Fabric.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-Fabric", Maintainer is ""

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-Fabric/python-Fabric.changes      
2011-11-14 13:35:23.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.python-Fabric.new/python-Fabric.changes 
2012-02-14 13:10:45.000000000 +0100
@@ -1,0 +2,49 @@
+Fri Jan 13 04:01:33 UTC 2012 - [email protected]
+
+- Update to 1.3.4:
+  - [Bug] #492: @parallel did not automatically trigger linewise
+    output, as was intended. This has been fixed. Thanks to Brandon
+    Huey for the catch.
+  - [Bug] #510: Parallel mode is incompatible with user input, such
+    as password/hostname prompts, and was causing cryptic Operation
+    not supported by device errors when such prompts needed to be
+    displayed. This behavior has been updated to cleanly and obviously
+    abort instead.
+  - [Bug] #494: Fixed regression bug affecting some env values such
+    as env.port under parallel mode. Symptoms included rsync_project
+    bailing out due to a None port value when run under @parallel.
+    Thanks to Rob Terhaar for the report.
+  - [Bug] #339: Don’t show imported colors members in --list output.
+    Thanks to Nick Trew for the report.
+
+-------------------------------------------------------------------
+Thu Nov 24 00:51:06 UTC 2011 - [email protected]
+
+- Update to 1.3.3:
+  - [Bug] #441: Specifying a task module as a task on the command
+    line no longer blows up but presents the usual “no task by that
+    name” error message instead. Thanks to Mitchell Hashimoto for
+    the catch.
+  - [Bug] #475: Allow escaping of equals signs in per-task args/kwargs.
+  - [Bug] #450: Improve traceback display when handling
+    ``ImportError``s for dependencies. Thanks to David Wolever for the patches.
+  - [Bug] #446: Add QNX to list of secondary-case sed targets.
+    Thanks to Rodrigo Madruga for the tip.
+  - [Bug] #443: exists didn’t expand tildes; now it does. Thanks to
+    Riccardo Magliocchetti for the patch.
+  - [Bug] #437: with_settings now correctly preserves the wrapped
+    function’s docstring and other attributes. Thanks to Eric Buckley for the 
catch and Luke Plant for the patch.
+  - [Bug] #400: Handle corner case of systems where pwd.getpwuid
+    raises KeyError for the user’s UID instead of returning a valid string. 
Thanks to Dougal Matthews for the catch.
+  - [Bug] #397: Some poorly behaved objects in third party modules
+    triggered exceptions during Fabric’s “classic or new-style task?” test. A 
fix has been added which tries to work around these.
+  - [Bug] #341: append incorrectly failed to detect that the line(s) given 
already existed in files hidden to the remote user, and continued appending 
every time it ran. This has been fixed. Thanks to Dominique Peretti for the 
catch and Martin Vilcans for the patch.
+  - [Bug] #342: Combining cd with put and its use_sudo keyword
+    caused an unrecoverable error. This has been fixed. Thanks to
+    Egor M for the report.
+  - [Bug] #482: Parallel mode should imply linewise output;
+    omission of this behavior was an oversight.
+  - [Bug] #230: Fix regression re: combo of no fabfile & arbitrary
+    command use. Thanks to Ali Saifee for the catch. 
+
+-------------------------------------------------------------------

Old:
----
  Fabric-1.3.2.tar.gz

New:
----
  Fabric-1.3.4.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-Fabric.spec ++++++
--- /var/tmp/diff_new_pack.0kvFIx/_old  2012-02-14 13:10:47.000000000 +0100
+++ /var/tmp/diff_new_pack.0kvFIx/_new  2012-02-14 13:10:47.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-Fabric
 #
-# Copyright (c) 2011 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -15,16 +15,14 @@
 # Please submit bugfixes or comments via http://bugs.opensuse.org/
 #
 
-
-
 Name:           python-Fabric
-Version:        1.3.2
+Version:        1.3.4
 Release:        0
 Url:            http://fabfile.org
 Summary:        Fabric is a simple, Pythonic tool for remote execution and 
deployment
 License:        BSD-2-Clause
 Group:          Development/Languages/Python
-Source:         Fabric-%{version}.tar.gz
+Source:         Fabric-%{version}.tar.bz2
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 BuildRequires:  python-devel
 BuildRequires:  python-distribute

++++++ Fabric-1.3.2.tar.gz -> Fabric-1.3.4.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Fabric-1.3.2/AUTHORS new/Fabric-1.3.4/AUTHORS
--- old/Fabric-1.3.2/AUTHORS    2011-10-24 00:34:53.000000000 +0200
+++ new/Fabric-1.3.4/AUTHORS    2012-01-13 00:35:20.000000000 +0100
@@ -46,3 +46,4 @@
 Mark Merritt
 Max Arnold
 Szymon Reichmann
+David Wolever
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Fabric-1.3.2/Fabric.egg-info/PKG-INFO 
new/Fabric-1.3.4/Fabric.egg-info/PKG-INFO
--- old/Fabric-1.3.2/Fabric.egg-info/PKG-INFO   2011-11-08 02:26:19.000000000 
+0100
+++ new/Fabric-1.3.4/Fabric.egg-info/PKG-INFO   2012-01-13 01:42:37.000000000 
+0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.0
 Name: Fabric
-Version: 1.3.2
+Version: 1.3.4
 Summary: Fabric is a simple, Pythonic tool for remote execution and deployment.
 Home-page: http://fabfile.org
 Author: Jeff Forcier
@@ -8,7 +8,7 @@
 License: UNKNOWN
 Description: 
         To find out what's new in this version of Fabric, please see `the 
changelog
-        <http://docs.fabfile.org/en/1.3.2/changelog.html>`_.
+        <http://docs.fabfile.org/en/1.3.4/changelog.html>`_.
         
         You can also install the `in-development version
         <https://github.com/fabric/fabric/tarball/master#egg=fabric-dev>`_ 
using
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Fabric-1.3.2/Fabric.egg-info/SOURCES.txt 
new/Fabric-1.3.4/Fabric.egg-info/SOURCES.txt
--- old/Fabric-1.3.2/Fabric.egg-info/SOURCES.txt        2011-11-08 
02:26:19.000000000 +0100
+++ new/Fabric-1.3.4/Fabric.egg-info/SOURCES.txt        2012-01-13 
01:42:37.000000000 +0100
@@ -41,6 +41,8 @@
 docs/usage/tasks.rst
 fabfile/__init__.py
 fabfile/docs.py
+fabfile/tag.py
+fabfile/utils.py
 fabric/__init__.py
 fabric/api.py
 fabric/auth.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Fabric-1.3.2/PKG-INFO new/Fabric-1.3.4/PKG-INFO
--- old/Fabric-1.3.2/PKG-INFO   2011-11-08 02:26:19.000000000 +0100
+++ new/Fabric-1.3.4/PKG-INFO   2012-01-13 01:42:37.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.0
 Name: Fabric
-Version: 1.3.2
+Version: 1.3.4
 Summary: Fabric is a simple, Pythonic tool for remote execution and deployment.
 Home-page: http://fabfile.org
 Author: Jeff Forcier
@@ -8,7 +8,7 @@
 License: UNKNOWN
 Description: 
         To find out what's new in this version of Fabric, please see `the 
changelog
-        <http://docs.fabfile.org/en/1.3.2/changelog.html>`_.
+        <http://docs.fabfile.org/en/1.3.4/changelog.html>`_.
         
         You can also install the `in-development version
         <https://github.com/fabric/fabric/tarball/master#egg=fabric-dev>`_ 
using
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Fabric-1.3.2/docs/changelog.rst 
new/Fabric-1.3.4/docs/changelog.rst
--- old/Fabric-1.3.2/docs/changelog.rst 2011-11-08 02:26:17.000000000 +0100
+++ new/Fabric-1.3.4/docs/changelog.rst 2012-01-13 01:42:34.000000000 +0100
@@ -25,6 +25,53 @@
 Changelog
 =========
 
+* :release:`1.3.4 <2012-01-12>`
+* :bug:`492` `@parallel <fabric.decorators.parallel>` did not automatically
+  trigger :ref:`linewise output <linewise-output>`, as was intended. This has
+  been fixed. Thanks to Brandon Huey for the catch.
+* :bug:`510` Parallel mode is incompatible with user input, such as
+  password/hostname prompts, and was causing cryptic `Operation not supported
+  by device` errors when such prompts needed to be displayed. This behavior has
+  been updated to cleanly and obviously ``abort`` instead.
+* :bug:`494` Fixed regression bug affecting some `env` values such as
+  `env.port` under parallel mode. Symptoms included
+  `~fabric.contrib.project.rsync_project` bailing out due to a None port value
+  when run under `@parallel <fabric.decorators.parallel>`. Thanks to Rob 
Terhaar for the report.
+* :bug:`339` Don't show imported `~fabric.colors` members in :option:`--list
+  <-l>` output.  Thanks to Nick Trew for the report.
+* :release:`1.3.3 <2011-11-23>`
+* :release:`1.2.5 <2011-11-23>`
+* :release:`1.1.7 <2011-11-23>`
+* :bug:`441` Specifying a task module as a task on the command line no longer
+  blows up but presents the usual "no task by that name" error message instead.
+  Thanks to Mitchell Hashimoto for the catch.
+* :bug:`475` Allow escaping of equals signs in per-task args/kwargs.
+* :bug:`450` Improve traceback display when handling ``ImportError`` for
+  dependencies. Thanks to David Wolever for the patches.
+* :bug:`446` Add QNX to list of secondary-case `~fabric.contrib.files.sed`
+  targets. Thanks to Rodrigo Madruga for the tip.
+* :bug:`443` `~fabric.contrib.files.exists` didn't expand tildes; now it does.
+  Thanks to Riccardo Magliocchetti for the patch.
+* :bug:`437` `~fabric.decorators.with_settings` now correctly preserves the
+  wrapped function's docstring and other attributes. Thanks to Eric Buckley for
+  the catch and Luke Plant for the patch.
+* :bug:`400` Handle corner case of systems where ``pwd.getpwuid`` raises
+  ``KeyError`` for the user's UID instead of returning a valid string. Thanks
+  to Dougal Matthews for the catch.
+* :bug:`397` Some poorly behaved objects in third party modules triggered
+  exceptions during Fabric's "classic or new-style task?" test. A fix has been
+  added which tries to work around these.
+* :bug:`341` `~fabric.contrib.files.append` incorrectly failed to detect that
+  the line(s) given already existed in files hidden to the remote user, and
+  continued appending every time it ran. This has been fixed. Thanks to
+  Dominique Peretti for the catch and Martin Vilcans for the patch.
+* :bug:`342` Combining `~fabric.context_managers.cd` with
+  `~fabric.operations.put` and its ``use_sudo`` keyword caused an unrecoverable
+  error. This has been fixed. Thanks to Egor M for the report.
+* :bug:`482` Parallel mode should imply linewise output; omission of this
+  behavior was an oversight.
+* :bug:`230` Fix regression re: combo of no fabfile & arbitrary command use.
+  Thanks to Ali Saifee for the catch.
 * :release:`1.3.2 <2011-11-07>`
 * :release:`1.2.4 <2011-11-07>`
 * :release:`1.1.6 <2011-11-07>`
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Fabric-1.3.2/docs/usage/env.rst 
new/Fabric-1.3.4/docs/usage/env.rst
--- old/Fabric-1.3.2/docs/usage/env.rst 2011-11-08 02:26:17.000000000 +0100
+++ new/Fabric-1.3.4/docs/usage/env.rst 2012-01-13 00:35:47.000000000 +0100
@@ -295,7 +295,9 @@
 **Default:** ``False``
 
 Forces buffering by line instead of by character/byte, typically when running
-in parallel mode. May be activated via :option:`--linewise`.
+in parallel mode. May be activated via :option:`--linewise`. This option is
+implied by :ref:`env.parallel <env-parallel>` -- even if ``linewise`` is False,
+if ``parallel`` is True then linewise behavior will occur.
 
 .. seealso:: :ref:`linewise-output`
 
@@ -462,7 +464,8 @@
 
 **Default:** ``False``
 
-When ``True``, forces all tasks to run in parallel.
+When ``True``, forces all tasks to run in parallel. Implies :ref:`env.linewise
+<env-linewise>`.
 
 .. versionadded:: 1.3
 .. seealso:: :doc:`parallel`
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Fabric-1.3.2/docs/usage/fab.rst 
new/Fabric-1.3.4/docs/usage/fab.rst
--- old/Fabric-1.3.2/docs/usage/fab.rst 2011-11-08 02:26:17.000000000 +0100
+++ new/Fabric-1.3.4/docs/usage/fab.rst 2012-01-13 00:35:47.000000000 +0100
@@ -284,7 +284,7 @@
 * Use commas (``,``) to separate arguments from one another (may be escaped
   by using a backslash, i.e. ``\,``);
 * Use equals signs (``=``) for keyword arguments, or omit them for positional
-  arguments;
+  arguments. May also be escaped with backslashes.
 
 Additionally, since this process involves string parsing, all values will end
 up as Python strings, so plan accordingly. (We hope to improve upon this in
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Fabric-1.3.2/docs/usage/parallel.rst 
new/Fabric-1.3.4/docs/usage/parallel.rst
--- old/Fabric-1.3.2/docs/usage/parallel.rst    2011-11-08 02:26:17.000000000 
+0100
+++ new/Fabric-1.3.4/docs/usage/parallel.rst    2012-01-13 00:35:47.000000000 
+0100
@@ -154,11 +154,11 @@
 in parallel mode, as the multiple processes may write to your terminal's
 standard out stream simultaneously.
 
-To help offset this problem, you may set :ref:`env.linewise <env-linewise>` to
-``True`` or specify :option:`--linewise`. This will cause you to lose most of
-the benefits outlined in the above link Fabric's remote interactivity features,
-but as those do not map well to parallel invocations, it's typically a fair
-trade.
+To help offset this problem, Fabric's option for linewise output is
+automatically enabled whenever parallelism is active. This will cause you to
+lose most of the benefits outlined in the above link Fabric's remote
+interactivity features, but as those do not map well to parallel invocations,
+it's typically a fair trade.
 
 There's no way to avoid the multiple processes mixing up on a line-by-line
 basis, but you will at least be able to tell them apart by the host-string line
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Fabric-1.3.2/fabfile/__init__.py 
new/Fabric-1.3.4/fabfile/__init__.py
--- old/Fabric-1.3.2/fabfile/__init__.py        2011-11-08 02:26:01.000000000 
+0100
+++ new/Fabric-1.3.4/fabfile/__init__.py        2012-01-13 00:35:26.000000000 
+0100
@@ -7,13 +7,9 @@
 import nose
 
 from fabric.api import *
-# Need to import this as fabric.version for reload() purposes
-import fabric.version
-# But nothing is stopping us from making a convenient binding!
-_version = fabric.version.get_version
 
-
-import docs
+import docs, tag
+from utils import msg
 
 
 @task(default=True)
@@ -31,92 +27,13 @@
         abort("Nose encountered an error; you may be missing newly added test 
dependencies. Try running 'pip install -r requirements.txt'.")
 
 
-def code_version_is_tagged():
-    return local('git tag | egrep "^%s$"' % _version('short'))
-
-def update_code_version(force):
-    """
-    Update version data structure in-code and commit that change to git.
-
-    Normally, if the version file has not been modified, we abort assuming the
-    user quit without saving. Specify ``force=yes`` to override this.
-    """
-    version_file = "fabric/version.py"
-    raw_input("Work has been done since last tag, version update is needed. 
Hit Enter to load version info in your editor: ")
-    local("$EDITOR %s" % version_file)
-    # Try to detect whether user bailed out of the edit
-    if not local("git diff -- %s" % version_file) and not force:
-        abort("You seem to have aborted the file edit, so I'm aborting too.")
-    # Reload version module to get new version
-    reload(fabric.version)
-    # Commit the version update
-    local("git add %s" % version_file)
-    local("git commit -m \"Cut %s\"" % _version('verbose'))
-
-def commits_since_tag():
-    """
-    Has any work been done since the last tag?
-    """
-    return local("git log %s.." % _version('short'))
-
-
-@task
-def tag(force='no', push='no'):
-    """
-    Tag a new release.
-
-    Normally, if a Git tag exists matching the current version, and no Git
-    commits appear after that tag, we abort assuming the user is making a
-    mistake or forgot to commit their work.
-
-    To override this -- i.e. to re-tag and re-upload -- specify ``force=yes``.
-    We assume you know what you're doing if you use this.
-
-    By default we do not push the tag remotely; specify ``push=yes`` to force a
-    ``git push origin <tag>``.
-    """
-    force = force.lower() in ['y', 'yes']
-    with settings(warn_only=True):
-        # Does the current in-code version exist as a Git tag already?
-        # If so, this means we haven't updated the in-code version specifier
-        # yet, and need to do so.
-        if code_version_is_tagged():
-            # That is, if any work has been done since. Sanity check!
-            if not commits_since_tag() and not force:
-                abort("No work done since last tag!")
-            # Open editor, update version, commit that change to Git.
-            update_code_version(force)
-        # If the tag doesn't exist, the user has already updated version info
-        # and we can just move on.
-        else:
-            print("Version has already been updated, no need to edit...")
-        # At this point, we've incremented the in-code version and just need to
-        # tag it in Git.
-        f = 'f' if force else ''
-        local("git tag -%sam \"Fabric %s\" %s" % (
-            f,
-            _version('verbose'),
-            _version('short')
-        ))
-        # And push to the central server, if we were told to
-        if push.lower() in ['y', 'yes']:
-            local("git push origin %s" % _version('short'))
-
-
-@task
-def build():
-    """
-    Build (but don't upload) via setup.py
-    """
-    local('python setup.py sdist')
-
-
 @task
 def upload():
     """
     Build, register and upload to PyPI
     """
-    local('python setup.py sdist register upload')
+    with msg("Uploading to PyPI"):
+        local('python setup.py sdist register upload')
 
 
 @task
@@ -124,5 +41,5 @@
     """
     Tag/push, build, upload new version and build/upload documentation.
     """
-    tag(force=force, push='yes')
+    tag.tag(force=force, push='yes')
     upload()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Fabric-1.3.2/fabfile/tag.py 
new/Fabric-1.3.4/fabfile/tag.py
--- old/Fabric-1.3.2/fabfile/tag.py     1970-01-01 01:00:00.000000000 +0100
+++ new/Fabric-1.3.4/fabfile/tag.py     2012-01-13 00:35:26.000000000 +0100
@@ -0,0 +1,114 @@
+from __future__ import with_statement
+
+from contextlib import nested
+
+from fabric.api import *
+
+# Need to import this as fabric.version for reload() purposes
+import fabric.version
+# But nothing is stopping us from making a convenient binding!
+_version = fabric.version.get_version
+
+from utils import msg
+
+
+def _seek_version(cmd, txt):
+    with nested(hide('running'), msg(txt)):
+        cmd = cmd % _version('short')
+        return local(cmd, capture=True)
+
+def current_version_is_tagged():
+    return _seek_version(
+        'git tag | egrep "^%s$"',
+        "Searching for existing tag"
+    )
+
+def current_version_is_changelogged(filename):
+    return _seek_version(
+        'egrep "^\* :release:`%s " filename',
+        "Looking for changelog entry"
+    )
+
+def update_code(filename, force):
+    """
+    Update version data structure in-code and commit that change to git.
+
+    Normally, if the version file has not been modified, we abort assuming the
+    user quit without saving. Specify ``force=yes`` to override this.
+    """
+    raw_input("Version update in %r required! Press Enter to load $EDITOR." % 
filename)
+    with hide('running'):
+        local("$EDITOR %s" % filename)
+    # Try to detect whether user bailed out of the edit
+    with hide('running'):
+        has_diff = local("git diff -- %s" % filename, capture=True)
+    if not has_diff and not force:
+        abort("You seem to have aborted the file edit, so I'm aborting too.")
+    return filename
+
+def commits_since_last_tag():
+    """
+    Has any work been done since the last tag?
+    """
+    with hide('running'):
+        return local("git log %s.." % _version('short'), capture=True)
+
+
+@task(default=True)
+def tag(force='no', push='no'):
+    """
+    Tag a new release.
+
+    Normally, if a Git tag exists matching the current version, and no Git
+    commits appear after that tag, we abort assuming the user is making a
+    mistake or forgot to commit their work.
+
+    To override this -- i.e. to re-tag and re-upload -- specify ``force=yes``.
+    We assume you know what you're doing if you use this.
+
+    By default we do not push the tag remotely; specify ``push=yes`` to force a
+    ``git push origin <tag>``.
+    """
+    force = force.lower() in ['y', 'yes']
+    with settings(warn_only=True):
+        changed = []
+        # Does the current in-code version exist as a Git tag already?
+        # If so, this means we haven't updated the in-code version specifier
+        # yet, and need to do so.
+        if current_version_is_tagged():
+            # That is, if any work has been done since. Sanity check!
+            if not commits_since_last_tag() and not force:
+                abort("No work done since last tag!")
+            # Open editor, update version
+            version_file = "fabric/version.py"
+            changed.append(update_code(version_file, force))
+        # If the tag doesn't exist, the user has already updated version info
+        # and we can just move on.
+        else:
+            print("Version has already been updated, no need to edit...")
+        # Similar process but for the changelog.
+        changelog = "docs/changelog.rst"
+        if not current_version_is_changelogged(changelog):
+           changed.append(update_code(changelog, force))
+        else:
+           print("Changelog already updated, no need to edit...")
+        # Commit any changes
+        if changed:
+            with msg("Committing updated version and/or changelog"):
+                reload(fabric.version)
+                local("git add %s" % " ".join(changed))
+                local("git commit -m \"Cut %s\"" % _version('verbose'))
+
+        # At this point, we've incremented the in-code version and just need to
+        # tag it in Git.
+        f = 'f' if force else ''
+        with msg("Tagging"):
+            local("git tag -%sam \"Fabric %s\" %s" % (
+                f,
+                _version('normal'),
+                _version('short')
+            ))
+        # And push to the central server, if we were told to
+        if push.lower() in ['y', 'yes']:
+            with msg("Pushing"):
+                local("git push origin %s" % _version('short'))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Fabric-1.3.2/fabfile/utils.py 
new/Fabric-1.3.4/fabfile/utils.py
--- old/Fabric-1.3.2/fabfile/utils.py   1970-01-01 01:00:00.000000000 +0100
+++ new/Fabric-1.3.4/fabfile/utils.py   2011-11-24 00:27:42.000000000 +0100
@@ -0,0 +1,14 @@
+from __future__ import with_statement
+
+from contextlib import contextmanager
+
+from fabric.api import hide, puts
+
+
+@contextmanager
+def msg(txt):
+    puts(txt + "...", end='', flush=True)
+    with hide('everything'):
+        yield
+    puts("done.", show_prefix=False, flush=True)
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Fabric-1.3.2/fabric/contrib/files.py 
new/Fabric-1.3.4/fabric/contrib/files.py
--- old/Fabric-1.3.2/fabric/contrib/files.py    2011-10-24 00:34:53.000000000 
+0200
+++ new/Fabric-1.3.4/fabric/contrib/files.py    2011-11-23 20:23:30.000000000 
+0100
@@ -25,7 +25,7 @@
     behavior.
     """
     func = use_sudo and sudo or run
-    cmd = 'test -e "%s"' % path
+    cmd = 'test -e "$(echo %s)"' % path
     # If verbose, run normally
     if verbose:
         with settings(warn_only=True):
@@ -101,8 +101,10 @@
             from jinja2 import Environment, FileSystemLoader
             jenv = Environment(loader=FileSystemLoader(template_dir or '.'))
             text = jenv.get_template(filename).render(**context or {})
-        except ImportError, e:
-            abort("tried to use Jinja2 but was unable to import: %s" % e)
+        except ImportError:
+            import traceback
+            tb = traceback.format_exc()
+            abort(tb + "\nUnable to import Jinja2 -- see above.")
     else:
         with open(filename) as inputfile:
             text = inputfile.read()
@@ -164,7 +166,7 @@
 
     with hide('running', 'stdout'):
         platform = run("uname")
-    if platform in ('NetBSD', 'OpenBSD'):
+    if platform in ('NetBSD', 'OpenBSD', 'QNX'):
         # Attempt to protect against failures/collisions
         hasher = hashlib.sha1()
         hasher.update(env.host_string)
@@ -321,7 +323,7 @@
         text = [text]
     for line in text:
         regex = '^' + re.escape(line) + ('' if partial else '$')
-        if (exists(filename) and line
+        if (exists(filename, use_sudo=use_sudo) and line
             and contains(filename, regex, use_sudo=use_sudo)):
             continue
         line = line.replace("'", r'\'') if escape else line
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Fabric-1.3.2/fabric/decorators.py 
new/Fabric-1.3.4/fabric/decorators.py
--- old/Fabric-1.3.2/fabric/decorators.py       2011-11-08 02:26:17.000000000 
+0100
+++ new/Fabric-1.3.4/fabric/decorators.py       2012-01-13 00:35:47.000000000 
+0100
@@ -205,6 +205,7 @@
     .. versionadded:: 1.1
     """
     def outer(func):
+        @wraps(func)
         def inner(*args, **kwargs):
             with settings(**kw_settings):
                 return func(*args, **kwargs)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Fabric-1.3.2/fabric/io.py 
new/Fabric-1.3.4/fabric/io.py
--- old/Fabric-1.3.2/fabric/io.py       2011-11-08 02:26:17.000000000 +0100
+++ new/Fabric-1.3.4/fabric/io.py       2012-01-13 00:35:47.000000000 +0100
@@ -52,13 +52,14 @@
     reprompt = False
     initial_prefix_printed = False
     line = []
+    linewise = (env.linewise or env.parallel)
     while True:
         # Handle actual read/write
         byte = func(1)
         # Empty byte == EOS
         if byte == '':
             # If linewise, ensure we flush any leftovers in the buffer.
-            if env.linewise and line:
+            if linewise and line:
                 _flush(pipe, _prefix)
                 _flush(pipe, "".join(line))
             break
@@ -76,7 +77,7 @@
                 _prefix = ""
             # Print to user
             if printing:
-                if env.linewise:
+                if linewise:
                     # Print prefix + line after newline is seen
                     if _was_newline(_buffer, byte):
                         _flush(pipe, _prefix)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Fabric-1.3.2/fabric/main.py 
new/Fabric-1.3.4/fabric/main.py
--- old/Fabric-1.3.2/fabric/main.py     2011-11-08 02:26:17.000000000 +0100
+++ new/Fabric-1.3.4/fabric/main.py     2012-01-13 00:35:47.000000000 +0100
@@ -16,8 +16,10 @@
 import sys
 import types
 
-from fabric import api, state  # For checking callables against the API, & 
easy mocking
-from fabric.contrib import console, files, project  # Ditto
+# For checking callables against the API, & easy mocking
+from fabric import api, state, colors
+from fabric.contrib import console, files, project
+
 from fabric.network import denormalize, disconnect_all
 from fabric.state import env_options
 from fabric.tasks import Task, execute
@@ -26,7 +28,7 @@
 
 # One-time calculation of "all internal callables" to avoid doing this on every
 # check of a given fabfile callable (in is_classic_task()).
-_modules = [api, project, files, console]
+_modules = [api, project, files, console, colors]
 _internals = reduce(lambda x, y: x + filter(callable, vars(y).values()),
     _modules,
     []
@@ -116,11 +118,16 @@
     Takes (name, object) tuple, returns True if it's a non-Fab public callable.
     """
     name, func = tup
-    return (
-        callable(func)
-        and (func not in _internals)
-        and not name.startswith('_')
-    )
+    try:
+        is_classic = (
+            callable(func)
+            and (func not in _internals)
+            and not name.startswith('_')
+        )
+    # Handle poorly behaved __eq__ implementations
+    except (ValueError, TypeError):
+        is_classic = False
+    return is_classic
 
 
 def load_fabfile(path, importer=None):
@@ -351,6 +358,7 @@
         tasks.extend(map(join, _task_names(module)))
     return tasks
 
+
 def _print_docstring(docstrings, name):
     if not docstrings:
         return False
@@ -491,8 +499,9 @@
         if ':' in cmd:
             cmd, argstr = cmd.split(':', 1)
             for pair in _escape_split(',', argstr):
-                k, _, v = pair.partition('=')
-                if _:
+                result = _escape_split('=', pair)
+                if len(result) > 1:
+                    k, v = result
                     # Catch, interpret host/hosts/role/roles/exclude_hosts
                     # kwargs
                     if k in ['host', 'hosts', 'role', 'roles', 
'exclude_hosts']:
@@ -510,7 +519,7 @@
                     else:
                         kwargs[k] = v
                 else:
-                    args.append(k)
+                    args.append(result[0])
         cmds.append((cmd, args, kwargs, hosts, roles, exclude_hosts))
     return cmds
 
@@ -590,6 +599,7 @@
         # Load fabfile (which calls its module-level code, including
         # tweaks to env values) and put its commands in the shared commands
         # dict
+        default = None
         if fabfile:
             docstring, callables, default = load_fabfile(fabfile)
             state.commands.update(callables)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Fabric-1.3.2/fabric/network.py 
new/Fabric-1.3.4/fabric/network.py
--- old/Fabric-1.3.2/fabric/network.py  2011-11-08 02:26:17.000000000 +0100
+++ new/Fabric-1.3.4/fabric/network.py  2012-01-13 00:35:47.000000000 +0100
@@ -20,11 +20,12 @@
     warnings.simplefilter('ignore', DeprecationWarning)
     import ssh
 except ImportError, e:
-    print >> sys.stderr, """There was a problem importing our SSH library. 
Specifically:
-
-    %s
-
-Please make sure all dependencies are installed and importable.""" % e
+    import traceback
+    traceback.print_exc()
+    print >> sys.stderr, """
+There was a problem importing our SSH library (see traceback above).
+Please make sure all dependencies are installed and importable.
+""".rstrip()
     sys.exit(1)
 
 
@@ -296,7 +297,7 @@
     defaults to ``sys.stderr``.
     """
     from fabric.state import env
-    handle_prompt_abort()
+    handle_prompt_abort("a connection or sudo password")
     stream = stream or sys.stderr
     # Construct prompt
     default = "[%s] Login password" % env.host_string
@@ -335,7 +336,7 @@
     @wraps(func)
     def host_prompting_wrapper(*args, **kwargs):
         while not env.get('host_string', False):
-            handle_prompt_abort()
+            handle_prompt_abort("the target host connection string")
             host_string = raw_input("No hosts found. Please specify (single)"
                                     " host string for connection: ")
             env.update(to_dict(host_string))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Fabric-1.3.2/fabric/operations.py 
new/Fabric-1.3.4/fabric/operations.py
--- old/Fabric-1.3.2/fabric/operations.py       2011-11-08 02:26:17.000000000 
+0100
+++ new/Fabric-1.3.4/fabric/operations.py       2012-01-13 00:35:47.000000000 
+0100
@@ -248,7 +248,7 @@
             prompt('I seriously need an answer on this! ')
 
     """
-    handle_prompt_abort()
+    handle_prompt_abort("a user-specified prompt() call")
     # Store previous env value for later display, if necessary
     if key:
         previous_value = env.get(key)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Fabric-1.3.2/fabric/sftp.py 
new/Fabric-1.3.4/fabric/sftp.py
--- old/Fabric-1.3.2/fabric/sftp.py     2011-11-08 02:26:17.000000000 +0100
+++ new/Fabric-1.3.4/fabric/sftp.py     2012-01-13 00:35:47.000000000 +0100
@@ -8,6 +8,7 @@
 
 from fabric.state import output, connections, env
 from fabric.utils import warn
+from fabric.context_managers import settings
 
 
 class SFTP(object):
@@ -237,7 +238,9 @@
                 else:
                     self.ftp.chmod(remote_path, lmode)
         if use_sudo:
-            with hide('everything'):
+            # Temporarily nuke 'cwd' so sudo() doesn't "cd" its mv command.
+            # (The target path has already been cwd-ified elsewhere.)
+            with settings(hide('everything'), cwd=""):
                 sudo("mv \"%s\" \"%s\"" % (remote_path, target_path))
             # Revert to original remote_path for return value's sake
             remote_path = target_path
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Fabric-1.3.2/fabric/state.py 
new/Fabric-1.3.4/fabric/state.py
--- old/Fabric-1.3.2/fabric/state.py    2011-11-08 02:26:17.000000000 +0100
+++ new/Fabric-1.3.4/fabric/state.py    2012-01-13 00:35:47.000000000 +0100
@@ -72,7 +72,15 @@
     """
     if not win32:
         import pwd
-        return pwd.getpwuid(os.getuid())[0]
+        try:
+            username = pwd.getpwuid(os.getuid())[0]
+        # getpwuid raises KeyError if it cannot find a username for the given
+        # UID, e.g. on ep.io and similar "non VPS" style services. Rather than
+        # error out, just set the 'default' username to None. Can check for
+        # this value later if required.
+        except KeyError:
+            username = None
+        return username
     else:
         import win32api
         import win32security
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Fabric-1.3.2/fabric/task_utils.py 
new/Fabric-1.3.4/fabric/task_utils.py
--- old/Fabric-1.3.2/fabric/task_utils.py       2011-11-08 02:26:17.000000000 
+0100
+++ new/Fabric-1.3.4/fabric/task_utils.py       2012-01-13 00:35:47.000000000 
+0100
@@ -20,8 +20,12 @@
     try:
         result = _crawl(name, mapping)
         # Handle default tasks
-        if isinstance(result, _Dict) and getattr(result, 'default', False):
-            result = result.default
+        if isinstance(result, _Dict):
+            if getattr(result, 'default', False):
+                result = result.default
+            # Ensure task modules w/ no default are treated as bad targets
+            else:
+                result = None
         return result
     except (KeyError, TypeError):
         return None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Fabric-1.3.2/fabric/tasks.py 
new/Fabric-1.3.4/fabric/tasks.py
--- old/Fabric-1.3.2/fabric/tasks.py    2011-11-08 02:26:17.000000000 +0100
+++ new/Fabric-1.3.4/fabric/tasks.py    2012-01-13 00:35:47.000000000 +0100
@@ -197,36 +197,42 @@
             # Create per-run env with connection settings
             local_env = to_dict(host)
             local_env.update(my_env)
-            with settings(**local_env):
-                # Handle parallel execution
-                if requires_parallel(task):
-                    # Import multiprocessing if needed, erroring out usefully
-                    # if it can't.
-                    try:
-                        import multiprocessing
-                    except ImportError, e:
-                        msg = "At least one task needs to be run in parallel, 
but the\nmultiprocessing module cannot be imported:"
-                        msg += "\n\n\t%s\n\n" % e
-                        msg += "Please make sure the module is installed or 
that the above ImportError is\nfixed."
-                        abort(msg)
+            state.env.update(local_env)
+            # Handle parallel execution
+            if requires_parallel(task):
+                # Set a few more env flags for parallelism
+                state.env.parallel = True # triggers some extra aborts, etc
+                state.env.linewise = True # to mirror -P behavior
+                # Import multiprocessing if needed, erroring out usefully
+                # if it can't.
+                try:
+                    import multiprocessing
+                except ImportError:
+                    import traceback
+                    tb = traceback.format_exc()
+                    abort(tb + """
+At least one task needs to be run in parallel, but the
+multiprocessing module cannot be imported (see above
+traceback.) Please make sure the module is installed
+or that the above ImportError is fixed.""")
 
-                    # Wrap in another callable that nukes the child's cached
-                    # connection object, if needed, to prevent shared-socket
-                    # problems.
-                    def inner(*args, **kwargs):
-                        key = normalize_to_string(state.env.host_string)
-                        state.connections.pop(key, "")
-                        task.run(*args, **kwargs)
-                    # Stuff into Process wrapper
-                    p = multiprocessing.Process(target=inner, args=args,
-                        kwargs=new_kwargs)
-                    # Name/id is host string
-                    p.name = local_env['host_string']
-                    # Add to queue
-                    jobs.append(p)
-                # Handle serial execution
-                else:
-                    task.run(*args, **new_kwargs)
+                # Wrap in another callable that nukes the child's cached
+                # connection object, if needed, to prevent shared-socket
+                # problems.
+                def inner(*args, **kwargs):
+                    key = normalize_to_string(state.env.host_string)
+                    state.connections.pop(key, "")
+                    task.run(*args, **kwargs)
+                # Stuff into Process wrapper
+                p = multiprocessing.Process(target=inner, args=args,
+                    kwargs=new_kwargs)
+                # Name/id is host string
+                p.name = local_env['host_string']
+                # Add to queue
+                jobs.append(p)
+            # Handle serial execution
+            else:
+                task.run(*args, **new_kwargs)
 
         # If running in parallel, block until job queue is emptied
         if jobs:
@@ -241,5 +247,5 @@
 
     # Or just run once for local-only
     else:
-        with settings(**my_env):
-            task.run(*args, **new_kwargs)
+        state.env.update(my_env)
+        task.run(*args, **new_kwargs)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Fabric-1.3.2/fabric/utils.py 
new/Fabric-1.3.4/fabric/utils.py
--- old/Fabric-1.3.2/fabric/utils.py    2011-10-24 00:34:53.000000000 +0200
+++ new/Fabric-1.3.4/fabric/utils.py    2012-01-13 00:35:47.000000000 +0100
@@ -123,7 +123,12 @@
     return puts(text=text, show_prefix=show_prefix, end=end, flush=flush)
 
 
-def handle_prompt_abort():
+def handle_prompt_abort(prompt_for):
     import fabric.state
+    reason = "Needed to prompt for %s, but %%s" % prompt_for
+    # Explicit "don't prompt me bro"
     if fabric.state.env.abort_on_prompts:
-        abort("Needed to prompt, but abort-on-prompts was set to True!")
+        abort(reason % "abort-on-prompts was set to True")
+    # Implicit "parallel == stdin/prompts have ambiguous target"
+    if fabric.state.env.parallel:
+        abort(reason % "input would be ambiguous in parallel mode")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Fabric-1.3.2/fabric/version.py 
new/Fabric-1.3.4/fabric/version.py
--- old/Fabric-1.3.2/fabric/version.py  2011-11-08 02:26:17.000000000 +0100
+++ new/Fabric-1.3.4/fabric/version.py  2012-01-13 01:41:57.000000000 +0100
@@ -10,7 +10,7 @@
 from os.path import abspath, dirname
 
 
-VERSION = (1, 3, 2, 'final', 0)
+VERSION = (1, 3, 4, 'final', 0)
 
 
 def git_sha():
@@ -39,6 +39,7 @@
     * ``verbose``: like ``normal`` but fully explicit, e.g. "0.9 final". For
       tag commit messages, or anywhere that it's important to remove ambiguity
       between a branch and the first final release within that branch.
+    * ``all``: Returns all of the above, as a dict.
     """
     # Setup
     versions = {}
@@ -93,6 +94,11 @@
     try:
         return versions[form]
     except KeyError:
+        if form == 'all':
+            return versions
         raise TypeError('"%s" is not a valid form specifier.' % form)
 
 __version__ = get_version('short')
+
+if __name__ == "__main__":
+    print get_version('all')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Fabric-1.3.2/tests/test_main.py 
new/Fabric-1.3.4/tests/test_main.py
--- old/Fabric-1.3.2/tests/test_main.py 2011-11-08 02:26:17.000000000 +0100
+++ new/Fabric-1.3.4/tests/test_main.py 2012-01-13 00:35:47.000000000 +0100
@@ -74,13 +74,26 @@
     )
 
 
+def test_escaped_task_kwarg_split():
+    """
+    Allow backslashes to escape the = in x=y task kwargs
+    """
+    argstr = 
r"cmd:arg,escaped\,arg,nota\=kwarg,regular=kwarg,escaped=regular\=kwarg"
+    args = ['arg', 'escaped,arg', 'nota=kwarg']
+    kwargs = {'regular': 'kwarg', 'escaped': 'regular=kwarg'}
+    eq_(
+        parse_arguments([argstr])[0],
+        ('cmd', args, kwargs, [], [], []),
+    )
+
+
+
 #
 # Host/role decorators
 #
 
 # Allow calling Task.get_hosts as function instead (meh.)
 def get_hosts(command, *args):
-    print "calling get_hosts with args %r" % (args,)
     return WrappedCallableTask(command).get_hosts(*args)
 
 def eq_hosts(command, host_list, env=None):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Fabric-1.3.2/tests/test_tasks.py 
new/Fabric-1.3.4/tests/test_tasks.py
--- old/Fabric-1.3.2/tests/test_tasks.py        2011-11-08 02:26:17.000000000 
+0100
+++ new/Fabric-1.3.4/tests/test_tasks.py        2012-01-13 00:35:47.000000000 
+0100
@@ -291,20 +291,6 @@
                 task, hosts=hosts, roles=roles, exclude_hosts=exclude_hosts
             )
 
-    @with_fakes
-    def test_should_preserve_previous_settings(self):
-        """
-        should not overwrite env.user, etc after it finishes
-        """
-        outer = dict(user='jeff', host='localhost', port='123')
-        inner = dict(user='frank', host='fabfile.org', port='555')
-        def command():
-            dict_contains(superset=fabric.state.env, subset=inner)
-        with settings(**outer):
-            task = Fake(callable=True, expect_call=True).calls(command)
-            execute(task, host=from_dict(inner))
-            dict_contains(superset=fabric.state.env, subset=outer)
-
     @mock_streams('stdout')
     def test_should_print_executing_line_per_host(self):
         """
@@ -324,5 +310,6 @@
         """
         def task():
             pass
-        execute(task)
+        with settings(hosts=[]): # protect against really odd test bleed :(
+            execute(task)
         eq_(sys.stdout.getvalue(), "")

-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to