Esempio n. 1
0
    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
Esempio n. 2
0
    def update_copy_ignore_globs(self, globs):
        """ Update the ignore glob patterns to include the list provided.

        ** Usage: **

        .. code-block:: python

            from facio.template import Template
            t = Template('foo', '/path/to/foo')
            globs = [
                '*.png',
                '*.gif',
            ]
            t.update_copy_ignore_globs(globs)

        :param globs: A list of globs
        :type globs: list
        """

        try:
            self.copy_ignore_globs += globs
        except AttributeError:
            if not isinstance(globs, list):
                self.copy_ignore_globs = []
            else:
                self.copy_ignore_globs = globs
        except TypeError:
            raise FacioException('Failed to add {0} to ignore globs '
                                 'list'.format(globs))
Esempio n. 3
0
File: vcs.py Progetto: krak3n/Facio
    def clone(self):
        """ Clone the hg repository into a temporary directory. """

        try:
            from sh import hg
        except ImportError:
            raise FacioException('Mercurial must be installed to use hg+ '
                                 'template paths')

        temp_diretory = self.get_temp_directory()

        self.out('Mercurial Cloning {0} to {1}'.format(self.path,
                                                       temp_diretory))

        try:
            hg = hg.bake(_cwd=temp_diretory)
            hg.clone(self.path, temp_diretory)
        except:
            raise FacioException('Failed to clone hg repository '
                                 'at {0}'.format(self.path))

        return temp_diretory
Esempio n. 4
0
File: vcs.py Progetto: krak3n/Facio
    def clone(self):
        """ Clone the git repository into a temporary directory. """

        try:
            from sh import git
        except ImportError:
            raise FacioException('Git must be installed to use git+ '
                                 'template paths')

        temp_diretory = self.get_temp_directory()

        self.out('Git Cloning {0} to {1}'.format(self.path, temp_diretory))

        try:
            git = git.bake(_cwd=temp_diretory)
            git.clone(self.path, temp_diretory)
            git.fetch('--all')
            git.checkout('master')
        except:
            raise FacioException('Failed to clone git repository '
                                 'at {0}'.format(self.path))

        return temp_diretory
Esempio n. 5
0
    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
Esempio n. 6
0
 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)
Esempio n. 7
0
    def copy(self, callback=None):
        """ Copy template from origin path to ``state.get_project_root()``.

        :param callback: A callback function to be called after
                         copy is complete
        :type callback: function -- default None

        :returns: bool
        """

        self.out('Copying {0} to {1}'.format(self.origin,
                                             state.get_project_root()))

        ignore = shutil.ignore_patterns(*self.get_copy_ignore_globs())
        try:
            shutil.copytree(self.origin,
                            state.get_project_root(),
                            ignore=ignore)
        except shutil.Error:
            raise FacioException('Failed to copy {0} to {1}'.format(
                self.origin, state.get_project_root()))
        except OSError:
            # If we get an OSError either the template path does not exist or
            # the project root already exists. Check the later first and then
            # check if the template path is git+ or hg+ and clone, finally
            # raising exceptions

            if not os.path.isdir(state.get_project_root()):

                supported_vcs = [
                    ('git+', GitVCS),
                    ('hg+', MercurialVCS),
                ]

                for prefix, cls in supported_vcs:
                    if self.origin.startswith(prefix):
                        vcs = cls(self.origin)
                        new_path = vcs.clone()
                        if not new_path:
                            raise FacioException(
                                'New path to template not returned by '
                                '{0}.clone()'.format(vcs.__class__.__name__))
                        self.origin = new_path
                        break
                else:
                    # Loop feel through so path is not prefixed with git+ or
                    # +hg so it must be a path that does not exist
                    raise FacioException('{0} does not exist'.format(
                        self.origin))

                # The loop broke so we can call self.copy again
                if self.COPY_ATTEMPT <= self.COPY_ATTEMPT_LIMIT:
                    self.COPY_ATTEMPT += 1
                    self.copy(callback=vcs.remove_tmp_dir)
                else:
                    raise FacioException('Failed to copy template after '
                                         '{0} attempts'.format(
                                             self.COPY_ATTEMPT))

            else:
                # project root exists, raise exception
                raise FacioException('{0} already exists'.format(
                    state.get_project_root()))

        # Call callback if callable
        if callable(callback):
            callback(origin=self.origin, destination=state.get_project_root())

        return True
Esempio n. 8
0
import fnmatch
import os
import re
import shutil

from codecs import open
from facio.base import BaseFacio
from facio.exceptions import FacioException
from facio.state import state
from facio.vcs import GitVCS, MercurialVCS

try:
    from jinja2 import Environment, FileSystemLoader
except ImportError:  # pragma: no cover
    raise FacioException('Jinja2 must be installed to use Facio')

# Regex for extracting context variable name from file or directory name
get_var_name_pattern = re.compile(r'\{\{(\w+)\}\}')


class Template(BaseFacio):

    COPY_ATTEMPT_LIMIT = 5
    COPY_ATTEMPT = 1

    def __init__(self, origin):
        """ Constructor for Template Class sets the project template origin.
        It also sets the default ignore globs.

        :param origin: The origin path to the template
Esempio n. 9
0
File: vcs.py Progetto: krak3n/Facio
    def clone(self):
        """ This class should be overridden in VCS subclass, if not a
        FacioException will be raised. """

        raise FacioException('The clone method on BaseVCS needs to be '
                             'overridden.')