<commit_before>import logging
import re

from ... import constants
from ...notifier import notify

DUSTY_CONFIG_REGEX = re.compile('\# BEGIN section for Dusty.*\# END section for Dusty\n', flags=re.DOTALL | re.MULTILINE)

def _read_hosts(filepath):
    with open(filepath, 'r') as f:
        return f.read()

def _write_hosts(filepath, contents):
    with open(filepath, 'w') as f:
        f.write(contents)

def _remove_current_dusty_config(hosts):
    return DUSTY_CONFIG_REGEX.sub("", hosts)

def _dusty_hosts_config(hosts_spec):
    """Return a string of all host rules required to match
    the given spec. This string is wrapped in the Dusty hosts
    header and footer so it can be easily removed later."""
    rules = '# BEGIN section for Dusty\n'
    for spec in hosts_spec:
        rules += '{} {}\n'.format(spec['forwarded_ip'], spec['host_address'])
    rules += '# END section for Dusty\n'
    return rules

def update_hosts_from_port_spec(port_spec):
    hosts_spec = port_spec['hosts_file']
    logging.info('Updating hosts file to match spec: {}'.format(hosts_spec))
    current_hosts = _read_hosts(constants.HOSTS_PATH)
    cleared_hosts = _remove_current_dusty_config(current_hosts)
    updated_hosts = cleared_hosts + _dusty_hosts_config(hosts_spec)
    _write_hosts(constants.HOSTS_PATH, updated_hosts)<commit_msg>Docstrings for non-trivial functions<commit_after>import logging
import re

from ... import constants
from ...notifier import notify

DUSTY_CONFIG_REGEX = re.compile('\# BEGIN section for Dusty.*\# END section for Dusty\n', flags=re.DOTALL | re.MULTILINE)

def _read_hosts(filepath):
    with open(filepath, 'r') as f:
        return f.read()

def _write_hosts(filepath, contents):
    with open(filepath, 'w') as f:
        f.write(contents)

def _remove_current_dusty_config(hosts):
    """Given a string representing the contents of a hosts
    file, this function strips out the Dusty config section
    denominated by the Dusty header and footer. Returns
    the stripped string."""
    return DUSTY_CONFIG_REGEX.sub("", hosts)

def _dusty_hosts_config(hosts_spec):
    """Return a string of all host rules required to match
    the given spec. This string is wrapped in the Dusty hosts
    header and footer so it can be easily removed later."""
    rules = '# BEGIN section for Dusty\n'
    for spec in hosts_spec:
        rules += '{} {}\n'.format(spec['forwarded_ip'], spec['host_address'])
    rules += '# END section for Dusty\n'
    return rules

def update_hosts_from_port_spec(port_spec):
    """Given a port spec, update the hosts file specified at
    constants.HOST_PATH to contain the port mappings specified
    in the spec. Any existing Dusty configurations are replaced."""
    hosts_spec = port_spec['hosts_file']
    logging.info('Updating hosts file to match spec: {}'.format(hosts_spec))
    current_hosts = _read_hosts(constants.HOSTS_PATH)
    cleared_hosts = _remove_current_dusty_config(current_hosts)
    updated_hosts = cleared_hosts + _dusty_hosts_config(hosts_spec)
    _write_hosts(constants.HOSTS_PATH, updated_hosts)
{'fraction_non_alphanumeric': 0.0965651328580687, 'fraction_numerical': 0.0, 'mean_word_length': 4.1708542713567835, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '3284984', 'n_tokens_mistral': 1005, 'n_tokens_neox': 944, 'n_words': 293}