mirror of
https://github.com/saltstack/salt.git
synced 2025-04-16 17:50:20 +00:00
Move salt.utils.istextfile to salt.utils.files.is_text_file
Moves the original function to `salt.utils.files.py`, adds a deprecation warning to the original function, and updates all of the istextfile references in salt code.
This commit is contained in:
parent
3c454d4156
commit
1279556873
7 changed files with 75 additions and 58 deletions
|
@ -126,8 +126,8 @@ def _binary_replace(old, new):
|
|||
This function should only be run AFTER it has been determined that the
|
||||
files differ.
|
||||
'''
|
||||
old_isbin = not salt.utils.istextfile(old)
|
||||
new_isbin = not salt.utils.istextfile(new)
|
||||
old_isbin = not salt.utils.files.is_text_file(old)
|
||||
new_isbin = not salt.utils.files.is_text_file(new)
|
||||
if any((old_isbin, new_isbin)):
|
||||
if all((old_isbin, new_isbin)):
|
||||
return u'Replace binary file'
|
||||
|
@ -1436,7 +1436,7 @@ def comment_line(path,
|
|||
raise SaltInvocationError('File not found: {0}'.format(path))
|
||||
|
||||
# Make sure it is a text file
|
||||
if not salt.utils.istextfile(path):
|
||||
if not salt.utils.files.is_text_file(path):
|
||||
raise SaltInvocationError(
|
||||
'Cannot perform string replacements on a binary file: {0}'.format(path))
|
||||
|
||||
|
@ -2180,7 +2180,7 @@ def replace(path,
|
|||
else:
|
||||
raise SaltInvocationError('File not found: {0}'.format(path))
|
||||
|
||||
if not salt.utils.istextfile(path):
|
||||
if not salt.utils.files.is_text_file(path):
|
||||
raise SaltInvocationError(
|
||||
'Cannot perform string replacements on a binary file: {0}'
|
||||
.format(path)
|
||||
|
@ -2497,7 +2497,7 @@ def blockreplace(path,
|
|||
'Only one of append and prepend_if_not_found is permitted'
|
||||
)
|
||||
|
||||
if not salt.utils.istextfile(path):
|
||||
if not salt.utils.files.is_text_file(path):
|
||||
raise SaltInvocationError(
|
||||
'Cannot perform string replacements on a binary file: {0}'
|
||||
.format(path)
|
||||
|
|
|
@ -4366,7 +4366,7 @@ def comment(name, regex, char='#', backup='.bak'):
|
|||
ret['result'] = __salt__['file.search'](name, unanchor_regex, multiline=True)
|
||||
|
||||
if slines != nlines:
|
||||
if not salt.utils.istextfile(name):
|
||||
if not salt.utils.files.is_text_file(name):
|
||||
ret['changes']['diff'] = 'Replace binary file'
|
||||
else:
|
||||
# Changes happened, add them
|
||||
|
@ -4478,7 +4478,7 @@ def uncomment(name, regex, char='#', backup='.bak'):
|
|||
)
|
||||
|
||||
if slines != nlines:
|
||||
if not salt.utils.istextfile(name):
|
||||
if not salt.utils.files.is_text_file(name):
|
||||
ret['changes']['diff'] = 'Replace binary file'
|
||||
else:
|
||||
# Changes happened, add them
|
||||
|
@ -4721,7 +4721,7 @@ def append(name,
|
|||
nlines = list(slines)
|
||||
nlines.extend(append_lines)
|
||||
if slines != nlines:
|
||||
if not salt.utils.istextfile(name):
|
||||
if not salt.utils.files.is_text_file(name):
|
||||
ret['changes']['diff'] = 'Replace binary file'
|
||||
else:
|
||||
# Changes happened, add them
|
||||
|
@ -4746,7 +4746,7 @@ def append(name,
|
|||
nlines = nlines.splitlines()
|
||||
|
||||
if slines != nlines:
|
||||
if not salt.utils.istextfile(name):
|
||||
if not salt.utils.files.is_text_file(name):
|
||||
ret['changes']['diff'] = 'Replace binary file'
|
||||
else:
|
||||
# Changes happened, add them
|
||||
|
@ -4914,7 +4914,7 @@ def prepend(name,
|
|||
if __opts__['test']:
|
||||
nlines = test_lines + slines
|
||||
if slines != nlines:
|
||||
if not salt.utils.istextfile(name):
|
||||
if not salt.utils.files.is_text_file(name):
|
||||
ret['changes']['diff'] = 'Replace binary file'
|
||||
else:
|
||||
# Changes happened, add them
|
||||
|
@ -4957,7 +4957,7 @@ def prepend(name,
|
|||
nlines = nlines.splitlines(True)
|
||||
|
||||
if slines != nlines:
|
||||
if not salt.utils.istextfile(name):
|
||||
if not salt.utils.files.is_text_file(name):
|
||||
ret['changes']['diff'] = 'Replace binary file'
|
||||
else:
|
||||
# Changes happened, add them
|
||||
|
|
|
@ -983,48 +983,6 @@ def arg_lookup(fun, aspec=None):
|
|||
return ret
|
||||
|
||||
|
||||
@jinja_filter('is_text_file')
|
||||
def istextfile(fp_, blocksize=512):
|
||||
'''
|
||||
Uses heuristics to guess whether the given file is text or binary,
|
||||
by reading a single block of bytes from the file.
|
||||
If more than 30% of the chars in the block are non-text, or there
|
||||
are NUL ('\x00') bytes in the block, assume this is a binary file.
|
||||
'''
|
||||
# Late import to avoid circular import.
|
||||
import salt.utils.files
|
||||
|
||||
int2byte = (lambda x: bytes((x,))) if six.PY3 else chr
|
||||
text_characters = (
|
||||
b''.join(int2byte(i) for i in range(32, 127)) +
|
||||
b'\n\r\t\f\b')
|
||||
try:
|
||||
block = fp_.read(blocksize)
|
||||
except AttributeError:
|
||||
# This wasn't an open filehandle, so treat it as a file path and try to
|
||||
# open the file
|
||||
try:
|
||||
with salt.utils.files.fopen(fp_, 'rb') as fp2_:
|
||||
block = fp2_.read(blocksize)
|
||||
except IOError:
|
||||
# Unable to open file, bail out and return false
|
||||
return False
|
||||
if b'\x00' in block:
|
||||
# Files with null bytes are binary
|
||||
return False
|
||||
elif not block:
|
||||
# An empty file is considered a valid text file
|
||||
return True
|
||||
try:
|
||||
block.decode('utf-8')
|
||||
return True
|
||||
except UnicodeDecodeError:
|
||||
pass
|
||||
|
||||
nontext = block.translate(None, text_characters)
|
||||
return float(len(nontext)) / len(block) <= 0.30
|
||||
|
||||
|
||||
@jinja_filter('sorted_ignorecase')
|
||||
def isorted(to_sort):
|
||||
'''
|
||||
|
@ -3046,6 +3004,28 @@ def mkstemp(*args, **kwargs):
|
|||
return salt.utils.files.mkstemp(*args, **kwargs)
|
||||
|
||||
|
||||
@jinja_filter('is_text_file')
|
||||
def istextfile(fp_, blocksize=512):
|
||||
'''
|
||||
Uses heuristics to guess whether the given file is text or binary,
|
||||
by reading a single block of bytes from the file.
|
||||
If more than 30% of the chars in the block are non-text, or there
|
||||
are NUL ('\x00') bytes in the block, assume this is a binary file.
|
||||
|
||||
.. deprecated:: Oxygen
|
||||
'''
|
||||
# Late import to avoid circular import.
|
||||
import salt.utils.files
|
||||
|
||||
salt.utils.versions.warn_until(
|
||||
'Neon',
|
||||
'Use of \'salt.utils.istextfile\' detected. This function has been moved '
|
||||
'to \'salt.utils.files.is_text_file\' as of Salt Oxygen. This warning will '
|
||||
'be removed in Salt Neon.'
|
||||
)
|
||||
return salt.utils.files.is_text_file(fp_, blocksize=blocksize)
|
||||
|
||||
|
||||
def str_version_to_evr(verstring):
|
||||
'''
|
||||
Split the package version string into epoch, version and release.
|
||||
|
|
|
@ -498,3 +498,42 @@ def safe_filepath(file_path_name):
|
|||
return os.sep.join([drive, path])
|
||||
else:
|
||||
return path
|
||||
|
||||
|
||||
@jinja_filter('is_text_file')
|
||||
def is_text_file(fp_, blocksize=512):
|
||||
'''
|
||||
Uses heuristics to guess whether the given file is text or binary,
|
||||
by reading a single block of bytes from the file.
|
||||
If more than 30% of the chars in the block are non-text, or there
|
||||
are NUL ('\x00') bytes in the block, assume this is a binary file.
|
||||
'''
|
||||
int2byte = (lambda x: bytes((x,))) if six.PY3 else chr
|
||||
text_characters = (
|
||||
b''.join(int2byte(i) for i in range(32, 127)) +
|
||||
b'\n\r\t\f\b')
|
||||
try:
|
||||
block = fp_.read(blocksize)
|
||||
except AttributeError:
|
||||
# This wasn't an open filehandle, so treat it as a file path and try to
|
||||
# open the file
|
||||
try:
|
||||
with fopen(fp_, 'rb') as fp2_:
|
||||
block = fp2_.read(blocksize)
|
||||
except IOError:
|
||||
# Unable to open file, bail out and return false
|
||||
return False
|
||||
if b'\x00' in block:
|
||||
# Files with null bytes are binary
|
||||
return False
|
||||
elif not block:
|
||||
# An empty file is considered a valid text file
|
||||
return True
|
||||
try:
|
||||
block.decode('utf-8')
|
||||
return True
|
||||
except UnicodeDecodeError:
|
||||
pass
|
||||
|
||||
nontext = block.translate(None, text_characters)
|
||||
return float(len(nontext)) / len(block) <= 0.30
|
||||
|
|
|
@ -8,7 +8,6 @@ from __future__ import absolute_import
|
|||
import os
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
import salt.utils.files
|
||||
|
||||
# Import 3rd-party libs
|
||||
|
@ -28,7 +27,7 @@ def find(path, saltenv='base'):
|
|||
if os.path.isfile(full):
|
||||
# Add it to the dict
|
||||
with salt.utils.files.fopen(full, 'rb') as fp_:
|
||||
if salt.utils.istextfile(fp_):
|
||||
if salt.utils.files.is_text_file(fp_):
|
||||
ret.append({full: 'txt'})
|
||||
else:
|
||||
ret.append({full: 'bin'})
|
||||
|
|
|
@ -9,7 +9,6 @@ from __future__ import absolute_import
|
|||
import os
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
import salt.utils.files
|
||||
|
||||
# Import 3rd-party libs
|
||||
|
@ -29,7 +28,7 @@ def find(path, saltenv='base'):
|
|||
if os.path.isfile(full):
|
||||
# Add it to the dict
|
||||
with salt.utils.files.fopen(full, 'rb') as fp_:
|
||||
if salt.utils.istextfile(fp_):
|
||||
if salt.utils.files.is_text_file(fp_):
|
||||
ret.append({full: 'txt'})
|
||||
else:
|
||||
ret.append({full: 'bin'})
|
||||
|
|
|
@ -1181,7 +1181,7 @@ class TestFileState(TestCase, LoaderModuleMockMixin):
|
|||
ret.update({'name': name})
|
||||
with patch.object(salt.utils.files, 'fopen',
|
||||
MagicMock(mock_open(read_data=''))):
|
||||
with patch.object(salt.utils, 'istextfile', mock_f):
|
||||
with patch.object(salt.utils.files, 'is_text_file', mock_f):
|
||||
with patch.dict(filestate.__opts__, {'test': True}):
|
||||
change = {'diff': 'Replace binary file'}
|
||||
comt = ('File {0} is set to be updated'
|
||||
|
|
Loading…
Add table
Reference in a new issue