Add sed()
convenience function
copied from fabric1 src
This commit is contained in:
parent
85baacecc1
commit
baea97957c
|
@ -37,4 +37,4 @@ from .core import (
|
||||||
set_timezone,
|
set_timezone,
|
||||||
UNSPECIFIED,
|
UNSPECIFIED,
|
||||||
)
|
)
|
||||||
from .util import exists, contains, append
|
from .util import exists, contains, append, sed
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
Misc. Utilities
|
Misc. Utilities
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import hashlib
|
||||||
|
|
||||||
|
|
||||||
def exists(c, path, use_sudo=False):
|
def exists(c, path, use_sudo=False):
|
||||||
"""
|
"""
|
||||||
|
@ -192,3 +194,77 @@ def get_home_path(c, user=None):
|
||||||
home = c.run('getent passwd {} | cut -d: -f6'.format(user)).stdout.strip()
|
home = c.run('getent passwd {} | cut -d: -f6'.format(user)).stdout.strip()
|
||||||
home = home.rstrip('/')
|
home = home.rstrip('/')
|
||||||
return home
|
return home
|
||||||
|
|
||||||
|
|
||||||
|
def sed(c, filename, before, after, limit='', use_sudo=False, backup='.bak',
|
||||||
|
flags='',
|
||||||
|
# shell=False,
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
NOTE: This was copied from the upstream ``fabric.contrib.files`` (v1) module.
|
||||||
|
|
||||||
|
Run a search-and-replace on ``filename`` with given regex patterns.
|
||||||
|
|
||||||
|
Equivalent to ``sed -i<backup> -r -e "/<limit>/ s/<before>/<after>/<flags>g"
|
||||||
|
<filename>``. Setting ``backup`` to an empty string will, disable backup
|
||||||
|
file creation.
|
||||||
|
|
||||||
|
For convenience, ``before`` and ``after`` will automatically escape forward
|
||||||
|
slashes, single quotes and parentheses for you, so you don't need to
|
||||||
|
specify e.g. ``http:\/\/foo\.com``, instead just using ``http://foo\.com``
|
||||||
|
is fine.
|
||||||
|
|
||||||
|
If ``use_sudo`` is True, will use `sudo` instead of `run`.
|
||||||
|
|
||||||
|
..
|
||||||
|
The ``shell`` argument will be eventually passed to `run`/`sudo`. It
|
||||||
|
defaults to False in order to avoid problems with many nested levels of
|
||||||
|
quotes and backslashes. However, setting it to True may help when using
|
||||||
|
``~fabric.operations.cd`` to wrap explicit or implicit ``sudo`` calls.
|
||||||
|
(``cd`` by it's nature is a shell built-in, not a standalone command, so it
|
||||||
|
should be called within a shell.)
|
||||||
|
|
||||||
|
Other options may be specified with sed-compatible regex flags -- for
|
||||||
|
example, to make the search and replace case insensitive, specify
|
||||||
|
``flags="i"``. The ``g`` flag is always specified regardless, so you do not
|
||||||
|
need to remember to include it when overriding this parameter.
|
||||||
|
"""
|
||||||
|
func = use_sudo and c.sudo or c.run
|
||||||
|
# Characters to be escaped in both
|
||||||
|
for char in "/'":
|
||||||
|
before = before.replace(char, r'\%s' % char)
|
||||||
|
after = after.replace(char, r'\%s' % char)
|
||||||
|
# Characters to be escaped in replacement only (they're useful in regexen
|
||||||
|
# in the 'before' part)
|
||||||
|
for char in "()":
|
||||||
|
after = after.replace(char, r'\%s' % char)
|
||||||
|
if limit:
|
||||||
|
limit = r'/%s/ ' % limit
|
||||||
|
context = {
|
||||||
|
'script': r"'%ss/%s/%s/%sg'" % (limit, before, after, flags),
|
||||||
|
'filename': _expand_path(c, filename),
|
||||||
|
'backup': backup
|
||||||
|
}
|
||||||
|
# Test the OS because of differences between sed versions
|
||||||
|
|
||||||
|
# with hide('running', 'stdout'):
|
||||||
|
# platform = run("uname", shell=False, pty=False)
|
||||||
|
platform = c.run("uname", pty=False, echo=False, hide=True)
|
||||||
|
if platform in ('NetBSD', 'OpenBSD', 'QNX'):
|
||||||
|
# Attempt to protect against failures/collisions
|
||||||
|
hasher = hashlib.sha1()
|
||||||
|
hasher.update(c.host_string) # TODO: what did env.host_string become?
|
||||||
|
hasher.update(filename)
|
||||||
|
context['tmp'] = "/tmp/%s" % hasher.hexdigest()
|
||||||
|
# Use temp file to work around lack of -i
|
||||||
|
expr = r"""cp -p %(filename)s %(tmp)s \
|
||||||
|
&& sed -r -e %(script)s %(filename)s > %(tmp)s \
|
||||||
|
&& cp -p %(filename)s %(filename)s%(backup)s \
|
||||||
|
&& mv %(tmp)s %(filename)s"""
|
||||||
|
else:
|
||||||
|
context['extended_regex'] = '-E' if platform == 'Darwin' else '-r'
|
||||||
|
expr = r"sed -i%(backup)s %(extended_regex)s -e %(script)s %(filename)s"
|
||||||
|
command = expr % context
|
||||||
|
return func(command,
|
||||||
|
# shell=shell
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in a new issue