Add contains()
and append()
convenience functions
basically stolen from Fabric v1 source code
This commit is contained in:
parent
bac78764d0
commit
72c03a8ac9
|
@ -38,4 +38,4 @@ from .core import (
|
|||
set_timezone,
|
||||
UNSPECIFIED,
|
||||
)
|
||||
from .util import exists
|
||||
from .util import exists, contains, append
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2018 Lance Edgar
|
||||
# Copyright © 2010-2019 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -24,7 +24,127 @@
|
|||
Misc. Utilities
|
||||
"""
|
||||
|
||||
from __future__ import unicode_literals, absolute_import
|
||||
|
||||
def exists(c, path, use_sudo=False):
|
||||
"""
|
||||
Return True if given path exists on the current remote host.
|
||||
|
||||
If ``use_sudo`` is True, will use `sudo` instead of `run`.
|
||||
|
||||
.. note::
|
||||
|
||||
This function is derived from one copied from fabric v1.
|
||||
"""
|
||||
func = c.sudo if use_sudo else c.run
|
||||
cmd = 'stat %s' % _expand_path(c, path)
|
||||
return not func(cmd, warn=True).failed
|
||||
|
||||
|
||||
def contains(c, filename, text, exact=False, use_sudo=False, escape=True,
|
||||
shell=False, case_sensitive=True):
|
||||
"""
|
||||
NOTE: This was copied from the upstream ``fabric.contrib.files`` (v1) module.
|
||||
|
||||
Return True if ``filename`` contains ``text`` (which may be a regex.)
|
||||
|
||||
By default, this function will consider a partial line match (i.e. where
|
||||
``text`` only makes up part of the line it's on). Specify ``exact=True`` to
|
||||
change this behavior so that only a line containing exactly ``text``
|
||||
results in a True return value.
|
||||
|
||||
This function leverages ``egrep`` on the remote end (so it may not follow
|
||||
Python regular expression syntax perfectly), and skips ``env.shell``
|
||||
wrapper by default.
|
||||
|
||||
If ``use_sudo`` is True, will use `sudo` instead of `run`.
|
||||
|
||||
If ``escape`` is False, no extra regular expression related escaping is
|
||||
performed (this includes overriding ``exact`` so that no ``^``/``$`` is
|
||||
added.)
|
||||
|
||||
The ``shell`` argument will be eventually passed to ``run/sudo``. See
|
||||
description of the same argument in ``~fabric.contrib.sed`` for details.
|
||||
|
||||
If ``case_sensitive`` is False, the `-i` flag will be passed to ``egrep``.
|
||||
"""
|
||||
func = use_sudo and c.sudo or c.run
|
||||
if escape:
|
||||
text = _escape_for_regex(text)
|
||||
if exact:
|
||||
text = "^%s$" % text
|
||||
# TODO: do we need to bother hiding things here?
|
||||
# with settings(hide('everything'), warn_only=True):
|
||||
egrep_cmd = 'egrep "%s" %s' % (text, _expand_path(c, filename))
|
||||
if not case_sensitive:
|
||||
egrep_cmd = egrep_cmd.replace('egrep', 'egrep -i', 1)
|
||||
return not func(egrep_cmd, shell=shell, warn=True).failed
|
||||
|
||||
|
||||
def append(c, filename, text, use_sudo=False, partial=False, escape=True,
|
||||
shell=False):
|
||||
"""
|
||||
NOTE: This was copied from the upstream ``fabric.contrib.files`` (v1) module.
|
||||
|
||||
Append string (or list of strings) ``text`` to ``filename``.
|
||||
|
||||
When a list is given, each string inside is handled independently (but in
|
||||
the order given.)
|
||||
|
||||
If ``text`` is already found in ``filename``, the append is not run, and
|
||||
None is returned immediately. Otherwise, the given text is appended to the
|
||||
end of the given ``filename`` via e.g. ``echo '$text' >> $filename``.
|
||||
|
||||
The test for whether ``text`` already exists defaults to a full line match,
|
||||
e.g. ``^<text>$``, as this seems to be the most sensible approach for the
|
||||
"append lines to a file" use case. You may override this and force partial
|
||||
searching (e.g. ``^<text>``) by specifying ``partial=True``.
|
||||
|
||||
Because ``text`` is single-quoted, single quotes will be transparently
|
||||
backslash-escaped. This can be disabled with ``escape=False``.
|
||||
|
||||
If ``use_sudo`` is True, will use `sudo` instead of `run`.
|
||||
|
||||
The ``shell`` argument will be eventually passed to ``run/sudo``. See
|
||||
description of the same argumnet in ``~fabric.contrib.sed`` for details.
|
||||
"""
|
||||
func = use_sudo and c.sudo or c.run
|
||||
# Normalize non-list input to be a list
|
||||
# TODO: do we need to check for six.something here?
|
||||
# if isinstance(text, basestring):
|
||||
if isinstance(text, str):
|
||||
text = [text]
|
||||
for line in text:
|
||||
regex = '^' + _escape_for_regex(line) + ('' if partial else '$')
|
||||
if (exists(c, filename, use_sudo=use_sudo) and line
|
||||
and contains(c, filename, regex, use_sudo=use_sudo, escape=False,
|
||||
shell=shell)):
|
||||
continue
|
||||
line = line.replace("'", r"'\\''") if escape else line
|
||||
func("echo '%s' >> %s" % (line, _expand_path(c, filename)))
|
||||
|
||||
|
||||
def _escape_for_regex(text):
|
||||
"""
|
||||
NOTE: This was copied from the upstream ``fabric.contrib.files`` (v1) module.
|
||||
|
||||
Escape ``text`` to allow literal matching using egrep
|
||||
"""
|
||||
re_specials = '\\^$|(){}[]*+?.'
|
||||
sh_specials = '\\$`"'
|
||||
re_chars = []
|
||||
sh_chars = []
|
||||
|
||||
for c in text:
|
||||
if c in re_specials:
|
||||
re_chars.append('\\')
|
||||
re_chars.append(c)
|
||||
|
||||
for c in re_chars:
|
||||
if c in sh_specials:
|
||||
sh_chars.append('\\')
|
||||
sh_chars.append(c)
|
||||
|
||||
return ''.join(sh_chars)
|
||||
|
||||
|
||||
def is_win(c):
|
||||
|
@ -58,18 +178,3 @@ def _expand_path(c, path):
|
|||
This function is derived from one copied from fabric v1.
|
||||
"""
|
||||
return path if is_win(c) else '"$(echo %s)"' % path
|
||||
|
||||
|
||||
def exists(c, path, use_sudo=False):
|
||||
"""
|
||||
Return True if given path exists on the current remote host.
|
||||
|
||||
If ``use_sudo`` is True, will use `sudo` instead of `run`.
|
||||
|
||||
.. note::
|
||||
|
||||
This function is derived from one copied from fabric v1.
|
||||
"""
|
||||
func = c.sudo if use_sudo else c.run
|
||||
cmd = 'stat %s' % _expand_path(c, path)
|
||||
return not func(cmd, warn=True).failed
|
||||
|
|
Loading…
Reference in a new issue