<commit_before># pyinfra
# File: pyinfra/modules/util/files.py
# Desc: common functions for handling the filesystem

from __future__ import unicode_literals


def ensure_mode_int(mode):
    # Already an int (/None)?
    if isinstance(mode, int) or mode is None:
        return mode

    try:
        # Try making an int ('700' -> 700)
        return int(mode)

    except (TypeError, ValueError):
        pass

    # Return as-is (ie +x which we don't need to normalise, it always gets run)
    return mode


def sed_replace(state, filename, line, replace, flags=None):
    flags = ''.join(flags) if flags else ''

    line = line.replace('/', '\/')
    replace = replace.replace('/', '\/')

    return 'sed -i "s/{0}/{1}/{2}" {3}'.format(
        line, replace, flags, filename
    )


def chmod(target, mode, recursive=False):
    return 'chmod {0}{1} {2}'.format(('-R ' if recursive else ''), mode, target)


def chown(target, user, group=None, recursive=False):
    command = 'chown'
    user_group = None

    if user and group:
        user_group = '{0}:{1}'.format(user, group)

    elif user:
        user_group = user

    elif group:
        command = 'chgrp'
        user_group = group

    return '{0}{1} {2} {3}'.format(
        command,
        ' -R' if recursive else '',
        user_group,
        target
    )<commit_msg>util/files: support chown-ing symlinks<commit_after># pyinfra
# File: pyinfra/modules/util/files.py
# Desc: common functions for handling the filesystem

from __future__ import unicode_literals


def ensure_mode_int(mode):
    # Already an int (/None)?
    if isinstance(mode, int) or mode is None:
        return mode

    try:
        # Try making an int ('700' -> 700)
        return int(mode)

    except (TypeError, ValueError):
        pass

    # Return as-is (ie +x which we don't need to normalise, it always gets run)
    return mode


def sed_replace(state, filename, line, replace, flags=None):
    flags = ''.join(flags) if flags else ''

    line = line.replace('/', '\/')
    replace = replace.replace('/', '\/')

    return 'sed -i "s/{0}/{1}/{2}" {3}'.format(
        line, replace, flags, filename
    )


def chmod(target, mode, recursive=False):
    return 'chmod {0}{1} {2}'.format(('-R ' if recursive else ''), mode, target)


def chown(target, user, group=None, recursive=False, dereference=True):
    command = 'chown'
    user_group = None

    if user and group:
        user_group = '{0}:{1}'.format(user, group)

    elif user:
        user_group = user

    elif group:
        command = 'chgrp'
        user_group = group

    return '{0}{1}{2} {3} {4}'.format(
        command,
        ' -R' if recursive else '',
        ' -h' if not dereference else '',
        user_group,
        target
    )
{'fraction_non_alphanumeric': 0.13919016630513376, 'fraction_numerical': 0.014099783080260303, 'mean_word_length': 2.533844189016603, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5298733', 'n_tokens_mistral': 928, 'n_tokens_neox': 875, 'n_words': 275}