Пример #1
0
def execute():
    """ Main function. """
    args = docopt_arguments()
    term = TerminalView()

    # print list of installed templates
    if args['--list']:
        run_list()
        return

    # instanciate the class
    if args['<template>']:
        template = template_class_from_name(args['<template>'])

    # print info on a template
    if args['--info']:
        if args['<template>']:
            run_info(template)
        else:
            term.print_error_and_exit("Please specify a template")
        return

    # launch the template
    template.create(args['<project>'],
                    args['<template>'],
                    args['<substitution>'])
    term.print_info("Done!")
Пример #2
0
def run_list():
    """ Print the list of all available templates. """
    term = TerminalView()
    term.print_info("These are the available templates:")
    import pkgutil, projy.templates
    pkgpath = os.path.dirname(projy.templates.__file__)
    templates = [name for _, name, _ in pkgutil.iter_modules([pkgpath])]
    for name in templates:
        # the father of all templates, not a real usable one
        if (name != 'ProjyTemplate'):
            term.print_info(term.text_in_color(template_name_from_class_name(name), TERM_PINK))
Пример #3
0
def template_class_from_name(name):
    """ Return the template class object from agiven name. """
    # import the right template module
    term = TerminalView()
    template_name = name + 'Template'
    try:
        __import__('projy.templates.' + template_name)
        template_mod = sys.modules['projy.templates.' + template_name]
    except ImportError:
        term.print_error_and_exit("Unable to find {}".format(name))

    # import the class from the module
    try:
        template_class = getattr(template_mod, template_name)
    except AttributeError:
        term.print_error_and_exit("Unable to create a template {}".format(name))
    return template_class()
Пример #4
0
def run_info(template):
    """ Print information about a specific template. """
    template.project_name = 'TowelStuff' # fake project name, always the same
    name = template_name_from_class_name(template.__class__.__name__)
    term = TerminalView()
    term.print_info("Content of template {} with an example project " \
          "named 'TowelStuff':".format(term.text_in_color(name, TERM_GREEN)))

    dir_name = None
    for file_info in sorted(template.files(), key=lambda dir: dir[0]):
        directory = file_name = template_name = ''
        if file_info[0]:
            directory = file_info[0]
        if file_info[1]:
            file_name = file_info[1]
        if file_info[2]:
            template_name = '\t\t - ' + file_info[2]
        if (directory != dir_name):
            term.print_info('\n\t' + term.text_in_color(directory + '/', TERM_PINK))
            dir_name = directory

        term.print_info('\t\t' + term.text_in_color(file_name, TERM_YELLOW) + template_name)

    # print substitutions
    try:
        subs = template.substitutes().keys()
        if len(subs) > 0:
            subs.sort()
            term.print_info("\nSubstitutions of this template are: ")
            max_len = 0
            for key in subs:
                if max_len < len(key):
                    max_len = len(key)
            for key in subs:
                term.print_info(u"\t{0:{1}} -> {2}".
                format(key, max_len, template.substitutes()[key]))
    except AttributeError:
        pass
Пример #5
0
 def __init__(self):
     self.project_name = None
     self.template_name = None
     self.substitutes_dict = {}
     self.term = TerminalView()
Пример #6
0
class ProjyTemplate:
    """ Base template class for a Projy project creation. """

    def __init__(self):
        self.project_name = None
        self.template_name = None
        self.substitutes_dict = {}
        self.term = TerminalView()


    def create(self, project_name, template_name, substitutions):
        """ Launch the project creation. """
        self.project_name = project_name
        self.template_name = template_name

        # create substitutions dictionary from user arguments
        # TODO: check what is given
        for subs in substitutions:
            current_sub = subs.split(',')
            current_key = current_sub[0].strip()
            current_val = current_sub[1].strip()
            self.substitutes_dict[current_key] = current_val

        self.term.print_info(u"Creating project '{0}' with template {1}"
            .format(self.term.text_in_color(project_name, TERM_PINK), template_name))

        self.make_directories()
        self.make_files()
        self.make_posthook()


    def make_directories(self):
        """ Create the directories of the template. """

        # get the directories from the template
        directories = []
        try:
            directories = self.directories()
        except AttributeError:
            self.term.print_info(u"No directory in the template.")

        working_dir = os.getcwd()
        # iteratively create the directories
        for directory in directories:
            dir_name = working_dir + '/' + directory
            if not os.path.isdir(dir_name):
                try:
                    os.makedirs(dir_name)
                except OSError as error:
                    if error.errno != errno.EEXIST:
                        raise
            else:
                self.term.print_error_and_exit(u"The directory {0} already exists."
                         .format(directory))

            self.term.print_info(u"Creating directory '{0}'"
                                 .format(self.term.text_in_color(directory, TERM_GREEN)))


    def make_files(self):
        """ Create the files of the template.  """

        # get the files from the template
        files = []
        try:
            files = self.files()
        except AttributeError:
            self.term.print_info(u"No file in the template. Weird, but why not?")

        # get the substitutes intersecting the template and the cli
        try:
            for key in self.substitutes().keys():
                if key not in self.substitutes_dict:
                    self.substitutes_dict[key] = self.substitutes()[key]

        except AttributeError:
            self.term.print_info(u"No substitute in the template.")

        working_dir = os.getcwd()
        # iteratively create the files
        for directory, name, template_file in files:
            if directory:
                filepath = working_dir + '/' + directory + '/' + name
                filename = directory + '/' + name
            else:
                filepath = working_dir + '/' + name
                filename = name

            # open the file to write into
            try:
                output = open(filepath, 'w')
            except IOError:
                self.term.print_error_and_exit(u"Can't create destination"\
                                                " file: {0}".format(filepath))

            # open the template to read from
            if template_file:
                input_file = join(dirname(__file__), template_file + '.txt')

                # write each line of input file into output file,
                # templatized with substitutes
                try:
                    with open(input_file, 'r') as line:
                        template_line = Template(line.read())
                        try:
                            output.write(template_line.
                                safe_substitute(self.substitutes_dict).encode('utf-8'))
                        except TypeError:
                            output.write(template_line.
                                safe_substitute(self.substitutes_dict))
                    output.close()
                except IOError:
                    self.term.print_error_and_exit(u"Can't create template file"\
                                                   ": {0}".format(input_file))
            else:
                output.close() # the file is empty, but still created

            self.term.print_info(u"Creating file '{0}'"
                             .format(self.term.text_in_color(filename, TERM_YELLOW)))


    def make_posthook(self):
        """ Run the post hook into the project directory. """
        print(id(self.posthook), self.posthook)
        print(id(super(self.__class__, self).posthook), super(self.__class__, self).posthook)
        import ipdb;ipdb.set_trace()
        if self.posthook:
            os.chdir(self.project_name) # enter the project main directory
            self.posthook()


    def replace_in_file(self, file_path, old_exp, new_exp):
        """ In the given file, replace all 'old_exp' by 'new_exp'. """
        self.term.print_info(u"Making replacement into {}"
                                 .format(self.term.text_in_color(file_path,
                                                                 TERM_GREEN)))
        # write the new version into a temporary file
        tmp_file = tempfile.NamedTemporaryFile(mode='w+t', delete=False)
        for filelineno, line in enumerate(io.open(file_path, encoding="utf-8")):
            if old_exp in line:
                line = line.replace(old_exp, new_exp)
            try:
                tmp_file.write(line.encode('utf-8'))
            except TypeError:
                tmp_file.write(line)

        name = tmp_file.name # keep the name
        tmp_file.close()
        shutil.copy(name, file_path) # replace the original one
        os.remove(name)


    def touch(self, filename):
        """ A simple equivalent of the well known shell 'touch' command. """
        with file(filename, 'a'):
            os.utime(filename, None)


    def posthook(self):
        """ Empty post-hook, to be inherited. """
        pass