Source code for facio.config

# -*- coding: utf-8 -*-

"""
.. module:: facio.config
   :synopsis: Facio configuration classes
"""

import os
import re

from docopt import docopt
from facio import get_version
from facio.base import BaseFacio
from facio.exceptions import FacioException
from facio.state import state
from six.moves import configparser as ConfigParser
from textwrap import dedent


HOOKS_FILE_NAME = '.facio.hooks.yml'
CONFIG_FILE_NAME = '.facio.cfg'


[docs]class CommandLineInterface(object): """ Facio Facio is a project scaffolding tool originally developed for Django and expanded to be framework agnostic. You can use Facio to bootstrap any sort of project. Documentation: https://facio.readthedocs.org Usage: facio <project_name> [--template <path>|--select] [--vars <variables>] Options: -h --help Show this help text. --version Show version. -t --template <path> Template path, can be repository link (git+ / hg+) or a template name defined in ~/.facio.cfg. -s --select Lists templates in ~/.facio.cfg prompting you to select a template from this list. --vars <variables> Comma separated key=value pairs of values to be used in processing templates. Example: facio hello_world -t git+git@github.com:you/django.git --vars foo=bar """
[docs] def start(self): self.arguments = docopt( dedent(self.__doc__), version='Facio {0}'.format(get_version())) self.validate_project_name(self.arguments.get('<project_name>'))
[docs] def validate_project_name(self, name): if not re.match('^\w+$', name): raise FacioException('Project names can only contain numbers ' 'letters and underscores') else: state.set_project_name(name)
[docs]class ConfigurationFile(BaseFacio): """ Load the ~/.facio.cfg ini style configuration file, providing an easily queryable dict representation of the config attributes. """
[docs] def read(self, name=CONFIG_FILE_NAME): """ Parse the config file using ConfigParser module. :param name: The file name to read in the users home dir -- optional :type name: str :returns: ConfirgParser or bool """ path = os.path.expanduser('~/{0}'.format(name)) parser = ConfigParser.ConfigParser() try: parser.readfp(open(path)) except IOError: self.warning('{0} Not found'.format(path)) except ConfigParser.Error: raise FacioException('Unable to parse {0}'.format(path)) else: self.out('Loaded {0}'.format(path)) return parser
[docs]class Settings(BaseFacio): default_template_path = os.path.join(os.path.dirname( os.path.realpath(__file__)), 'default') def __init__(self, interface, config): """ Facio settings class. Taking aguments passed into the cli interface and configurable options into a single callable class. :param interface: The docopt command line interface :type interface: dict :param config: Parsed config file :type config: False or ConfigParser object """ self.interface = interface self.config = config
[docs] def get_template_path(self): """ Obtain the template with from the command line interface or from prompting the user to choose a template from the config file. :returns: str or bool """ templates = [] template = self.interface.arguments.get('--template', False) select = self.interface.arguments.get('--select', False) try: templates = self.config.items('template') except ConfigParser.NoSectionError: if select: raise FacioException('Missing [template] section ' 'in Facio configuration file.') # Path or template name alias if template: try: path = [p for n, p in templates if n == template][0] except IndexError: return template else: return path # Select template from configuration file if select: tries = 5 self.out('Please select a template:') for i, item in enumerate(templates, start=1): name, path = item self.out('{0}) {1}: {2}'.format(i, name, path)) for n in range(1, (tries + 1)): try: prompt = 'Please enter the number of '\ 'the template ({0} of {1} tries'\ '): '.format(n, tries) num = int(self.gather(prompt)) if num == 0: raise ValueError name, path = templates[(num - 1)] return path except (ValueError, TypeError, IndexError): self.error('Please enter a valid number') raise FacioException('A template was not selected') # Default template return Settings.default_template_path
[docs] def get_variables(self): """ Returns dict of variables passed into command line interface. :returns: dict """ variable_dict = {} variables = self.interface.arguments.get('--vars') if variables: for pair in variables.split(','): key, value = pair.split('=') variable_dict[key] = value return variable_dict
[docs] def copy_ignore_globs(self): """ Returns list of of file copy ignore globs from configuration file. :returns: list """ try: globs = self.config.get('files', 'copy_ignore') except ConfigParser.NoSectionError: return [] except ConfigParser.NoOptionError: return [] else: return globs.split(',')
[docs] def render_ignore_globs(self): """ Returns list of of file render ignore globs from configuration file. :returns: list """ try: globs = self.config.get('files', 'render_ignore') except ConfigParser.NoSectionError: return [] except ConfigParser.NoOptionError: return [] else: return globs.split(',')

Related Topics