Source code for invirtualenv.config

# Copyright (c) 2016, Yahoo Inc.
# Copyrights licensed under the BSD License
# See the accompanying LICENSE.txt file for terms.

"""
Functions for handling the configuration settings
"""
from argparse import ArgumentDefaultsHelpFormatter, ArgumentParser
import getpass
import io
import logging
import os
import tempfile
# noinspection PyUnresolvedReferences,PyPackageRequirements
from six.moves.configparser import ConfigParser
from jinja2 import Template

from .package import package_scripts_directory
from .plugin import config_defaults, config_types, config_update
from .utility import str_to_bool, str_to_list, str_format_env
from .virtualenv import default_virtualenv_directory


logger = logging.getLogger(__name__)  # pylint: disable=C0103


# Config file that is part of the package
PACKAGE_DEFAULT_CONFIG = os.path.join(
    os.path.dirname(__file__), 'deploy_default.conf'
)

CONFIG_PATH = [
    PACKAGE_DEFAULT_CONFIG,

    # Any deploy.conf files in the current directory
    'deploy.conf'
]


[docs]def cast_types(configuration, types_dict=None): """ Update in place the configuration dictionary with inferred values if they aren't specified. Parameters ---------- configuration : dict config_types : dict, optional Types dictionary, defaults to value from config_types() """ if not types_dict: types_dict = config_types() for section, settings in configuration.items(): for key, value in settings.items(): try: setting_type = types_dict[section][key] if setting_type is bool: setting_type = str_to_bool elif setting_type is list: setting_type = str_to_list configuration[section][key] = setting_type(value) logger.debug( 'Forced value %r of type %r to type %r, result is %r', value, type(value), setting_type, configuration[section][key] ) except (KeyError, TypeError): pass
[docs]def get_configuration(configuration=None): """ Parse a configuration file Parameters ---------- configuration : str or list, optional A configuration file or list of configuration files to parse, defaults to the deploy_default.conf file in the package and deploy.conf in the current working directory. Returns ------- configparser The parsed configuration """ if not configuration: # pragma: no cover configuration = [ # Config file that is part of the package # PACKAGE_DEFAULT_CONFIG, # Any deploy.conf files in the current directory 'deploy.conf' ] config = ConfigParser() # Set the config defaults try: config.read_string(config_defaults()) except AttributeError: config.readfp(io.BytesIO(config_defaults())) logger.debug('Working with default dict: %r', config_defaults()) config.read(configuration) return config
[docs]def get_configuration_dict(configuration=None, value_types=None): """ Parse the configuration files Parameters ---------- configuration : str or list, optional A configuration file or list of configuration files to parse, defaults to the deploy_default.conf file in the package and deploy.conf in the current working directory. value_types : dict, optional Dictionary containing classes to apply to specific items Returns ------- dict Configuration dictionary """ if not value_types: # pragma: no cover value_types = config_types() config = get_configuration(configuration) result_dict = {} for section in config.sections(): result_dict[section] = {} for key, val in config.items(section): result_dict[section][key] = str_format_env(val) config_update(result_dict) if 'locations' not in result_dict.keys(): result_dict['locations'] = {} result_dict['locations']['package_scripts'] = package_scripts_directory() if not result_dict['global'].get('virtualenv_dir', None): result_dict['global']['virtualenv_dir'] = \ default_virtualenv_directory() cast_types(result_dict) return result_dict
[docs]def generate_parsed_config_file(source=None, dest=None): """ Generate a conf file with the environment variables expanded Parameters ---------- source : str, optional The path to the source file dest : str, optional The path to the desired destination file Returns ------- str Path to the generated config file """ config_data = None if not source: # pragma: no cover source = 'deploy.conf' if isinstance(source, list): source = source[0] with open(source) as config_data_handle: config_data = config_data_handle.read() if not config_data: # pragma: no cover return None template = Template(config_data) result = template.render(**os.environ) if not dest: with tempfile.NamedTemporaryFile( delete=False, suffix='.conf' ) as dest_handle: dest_handle.write(result.encode()) dest = dest_handle.name else: with open(dest, 'w') as new_conf_handle: new_conf_handle.write(result) return dest
[docs]def parse_arguments(configuration=None): """ Parse the command line arguments Parameters ---------- configuration : list, optional A list of config files to parse, defaults to the packaged deploy_default.conf and the deploy.conf file in the current directory. Returns ------- argparse namespace object With the configuration based on the passed command line arguments and defaults from the deploy_default.conf file in the package. """ config = get_configuration_dict( configuration, config_types() ) virtualenvuser = config['global']['virtualenv_user'] if not virtualenvuser: # pragma: no cover virtualenvuser = getpass.getuser() parser = ArgumentParser( description='Deploy a python application into a virtualenv', formatter_class=ArgumentDefaultsHelpFormatter ) parser.add_argument( 'name', nargs='?', default=config['global']['name'], help='VirtualEnv name' ) parser.add_argument( '--python', '-p', default=config['global']['basepython'], help='The Python interpreter to use, e.g., --python=python3.5 ' 'will use the python3.5 interpreter to create the new ' 'environment. The default is the interpreter that virtualenv ' 'was installed with.' ) parser.add_argument( '--requirement', '-r', default=[], action='append', help='Install from the given requirements file. This option can be ' 'used multiple times.' ) parser.add_argument( '--virtualenvdir', default=config['global']['virtualenv_dir'], help='Directory to build the virtualenv' ) parser.add_argument( '--virtualenvuser', default=virtualenvuser, help='The user to create the virtualenv' ) parser.add_argument( '--virtualenvgroup', default=config['global']['virtualenv_group'], help='The group to create the virtualenv' ) parser.add_argument( '--virtualenvversion_package', default=config['global']['virtualenv_version_package'], help='Version the virtualenv based on the version of a package' ) parser.add_argument( '--install_os_packages', default=config['global']['install_os_packages'], help='Install OS packages' ) parser.add_argument( '--verbose', action='store_true', default=False, help='More verbose output' ) parser.add_argument( '--upgrade', action='store_true', default=False, help='Upgrade packages when installing' ) return parser.parse_args()