Esempio n. 1
0
    def install(self):
        egg=Eggs(self.buildout, self.options["recipe"], self.options)
        reqs,ws=egg.working_set()
        path=[pkg.location for pkg in ws]
        extra_paths = self.options.get('extra-paths', '')
        extra_paths = extra_paths.split()
        path.extend(extra_paths)

        output=WRAPPER_TEMPLATE % dict(
            syspath=",\n    ".join((repr(p) for p in path))
            )

        location=self.buildout["buildout"]["bin-directory"]
        if not os.path.exists(location):
            os.mkdir(location)
            self.options.created(location)

        target=os.path.join(location, self.name)
        f=open(target, "wt")
        f.write(output)
        f.close()
        os.chmod(target, 0755)
        self.options.created(target)

        return self.options.created()
Esempio n. 2
0
    def install(self):

        bin_dir = self.buildout['buildout']['bin-directory']

        egg = Eggs(self.buildout, self.options["recipe"], self.options)
        reqs, ws = egg.working_set()
        path = [pkg.location for pkg in ws]
        extra_paths = self.options.get('extra-paths', '')
        extra_paths = extra_paths.split()
        path.extend(extra_paths)

        template_vars = {'python': self.buildout['buildout']['executable'],
                         'pypath': ",\n    ".join((repr(p) for p in path)),
                         'config': self.options['ini_file'],
                         'buildout_dir': self.buildout['buildout']['directory'],
                         'script_path': bin_dir,
                         'script_name': self.options['script_name']
                         }

        wsgi_script = '%s/%s.wsgi' % (bin_dir, self.options['script_name'])

        open(wsgi_script,
             'w').writelines(WSGI_TEMPLATE % template_vars)

        os.chmod(wsgi_script,
                 stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR
                 | stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP
                 | stat.S_IROTH | stat.S_IXOTH
                )

        if self.options.get('apache_config', None):
            open(self.options['apache_config'],
                 'w').writelines(APACHE_SKEL_TEMPLATE % template_vars)

        return []
    def install(self):
        egg = Eggs(self.buildout, self.options["recipe"], self.options)
        reqs, ws = egg.working_set()
        path = [pkg.location for pkg in ws]
        extra_paths = self.options.get('extra-paths', '')
        extra_paths = extra_paths.split()
        path.extend(extra_paths)

        # Do not put None into 'quotes'
        # Everything else should be a string pointing to a pipeline
        app_name = self.options.get('app_name')
        if app_name is not None:
            app_name = '"%s"' % app_name

        gevent_patch_enabled = self.options.get('gevent-monkey-patch', '')
        # TODO: would be nice to also support selective patching, e.g. just
        # socket or just threading
        gevent_patch = ''
        if gevent_patch_enabled.lower() in ('true', 'yes'):
            gevent_patch = """
try:
    import gevent.monkey
    gevent.monkey.patch_all()
except ImportError:
    pass
"""

        output = WRAPPER_TEMPLATE % dict(
            config=self.options["config-file"],
            syspath=",\n    ".join((repr(p) for p in path)),
            app_name=app_name,
            gevent_monkey_patch=gevent_patch
            )

        target = self.options.get("target")

        if target is None:
            location = os.path.join(
                            self.buildout["buildout"]["parts-directory"],
                            self.name)
            if not os.path.exists(location):
                os.mkdir(location)
                self.options.created(location)
            target = os.path.join(location, "wsgi")
        else:
            if os.path.lexists(target) and not os.path.exists(target):
                # Can't write to a broken symlink, so remove it
                os.unlink(target)

        f = open(target, "wt")
        try:
            f.write(output)
        finally:
            f.close()

        exec_mask = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
        os.chmod(target, os.stat(target).st_mode | exec_mask)
        self.options.created(target)

        return self.options.created()
    def install(self):
        egg = Eggs(self.buildout, self.options["recipe"], self.options)
        reqs, ws = egg.working_set()
        path = [pkg.location for pkg in ws]
        extra_paths = self.options.get('extra-paths', '')
        extra_paths = extra_paths.split()
        path.extend(extra_paths)

        output = WRAPPER_TEMPLATE % dict(
            config=self.options["config-file"],
            syspath=",\n    ".join((repr(p) for p in path))
            )

        location = os.path.join(self.buildout["buildout"]["parts-directory"],
                              self.name)
        if not os.path.exists(location):
            os.mkdir(location)
            self.options.created(location)

        target = os.path.join(location, "wsgi")
        f = open(target, "wt")
        f.write(output)
        f.close()

        exec_mask = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
        os.chmod(target, os.stat(target).st_mode | exec_mask)
        self.options.created(target)

        return self.options.created()
Esempio n. 5
0
    def install(self):
        egg = Eggs(self.buildout, self.options["recipe"], self.options)
        reqs, ws = egg.working_set()
        path = [pkg.location for pkg in ws]
        extra_paths = self.options.get('extra-paths', '')
        extra_paths = extra_paths.split()
        path.extend(extra_paths)

        # Do not put None into 'quotes'
        # Everything else should be a string pointing to a pipeline
        app_name = self.options.get('app_name')
        if app_name is not None:
            app_name = '"%s"' % app_name

        env = self.options.get('env')
        if env:
            output = ENV_TEMPLATE
            for line in env.splitlines():
                key, value = line.split('=')
                output += "os.environ['%s'] = '%s'\n" % (key, value)
            output += '\n'
        else:
            output = ''

        output += WSGI_TEMPLATE % dict(
            configfile=self.options["config-file"],
            syspath=",\n    ".join((repr(p) for p in path)),
            app_name=app_name
            )

        target = self.options.get("target")
        if target is None:
            location = os.path.join(
                            self.buildout["buildout"]["parts-directory"],
                            self.name)
            if not os.path.exists(location):
                os.mkdir(location)
                self.options.created(location)
            target = os.path.join(location, "wsgi")
        else:
            self.options.created(target)

        f = open(target, "wt")
        f.write(output)
        f.close()

        exec_mask = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
        os.chmod(target, os.stat(target).st_mode | exec_mask)
        self.options.created(target)

        return self.options.created()
Esempio n. 6
0
    def install(self):
        egg = Eggs(self.buildout, self.options['recipe'], self.options)
        requirements, working_set = egg.working_set()
        sys_paths = [dist.location for dist in working_set]
        if sys_paths:
            sys_paths = ''.join("    '{}',\n".format(p) for p in sys_paths)
            sys_paths = '\n{}'.format(sys_paths)
        else:
            sys_paths = ''

        extra_settings = {}
        for k, v in self.options.items():
            include = (
                (k not in self.buildout['buildout']) and
                (k not in (
                    '_d', '_e', 'recipe', 'eggs', 'app-factory',
                    'settings-file', 'initialization'))
            )
            if include:
                extra_settings[k] = v
        if extra_settings:
            extra_settings = ''.join(
                "    '{}': '{}',\n"
                .format(k, v) for (k, v) in extra_settings.items())
            extra_settings = '\n{}'.format(extra_settings)
        else:
            extra_settings = ''

        initialization = self.options.get('initialization', '')
        if initialization:
            initialization = '\n{}\n'.format(initialization)

        contents = TEMPLATE.format(
            sys_paths=sys_paths,
            factory=self.options['app-factory'],
            settings_file=self.options['settings-file'],
            extra_settings=extra_settings,
            initialization=initialization,
        )

        output_file = self.options.get('output-file')
        if output_file is None:
            output_file = os.path.join(
                self.buildout['buildout']['directory'], 'application.wsgi')

        with open(output_file, 'w') as fp:
            fp.write(contents)

        self.options.created(output_file)
        return self.options.created()
Esempio n. 7
0
    def install(self):
        egg = Eggs(self.buildout, self.options["recipe"], self.options)
        reqs, ws = egg.working_set()
        path = [pkg.location for pkg in ws]
        extra_paths = self.options.get('extra-paths', '')
        extra_paths = extra_paths.split()
        path.extend(extra_paths)

        # Do not put None into 'quotes'
        # Everything else should be a string pointing to a pipeline
        app_name = self.options.get('app_name')
        if app_name is not None:
            app_name = '"%s"' % app_name

        env = self.options.get('env')
        if env:
            output = ENV_TEMPLATE
            for line in env.splitlines():
                key, value = line.split('=')
                output += "os.environ['%s'] = '%s'\n" % (key, value)
            output += '\n'
        else:
            output = ''

        output += WSGI_TEMPLATE % dict(configfile=self.options["config-file"],
                                       syspath=",\n    ".join(
                                           (repr(p) for p in path)),
                                       app_name=app_name)

        target = self.options.get("target")
        if target is None:
            location = os.path.join(
                self.buildout["buildout"]["parts-directory"], self.name)
            if not os.path.exists(location):
                os.mkdir(location)
                self.options.created(location)
            target = os.path.join(location, "wsgi")
        else:
            self.options.created(target)

        f = open(target, "wt")
        f.write(output)
        f.close()

        exec_mask = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
        os.chmod(target, os.stat(target).st_mode | exec_mask)
        self.options.created(target)

        return self.options.created()
    def install(self):
        egg = Eggs(self.buildout, self.options["recipe"], self.options)
        reqs, ws = egg.working_set()
        path = [pkg.location for pkg in ws]
        extra_paths = self.options.get('extra-paths', '')
        extra_paths = extra_paths.split()
        path.extend(extra_paths)

        # Do not put None into 'quotes'
        # Everything else should be a string pointing to a pipeline
        app_name = self.options.get('app_name')
        if app_name is not None:
            app_name = '"%s"' % app_name

        output = WRAPPER_TEMPLATE % dict(
            config=self.options["config-file"],
            syspath=",\n    ".join((repr(p) for p in path)),
            app_name=app_name
            )

        target = self.options.get("target")

        if target is None:
            location = os.path.join(
                            self.buildout["buildout"]["parts-directory"],
                            self.name)
            if not os.path.exists(location):
                os.mkdir(location)
                self.options.created(location)
            target = os.path.join(location, "wsgi")
        else:
            if os.path.lexists(target) and not os.path.exists(target):
                # Can't write to a broken symlink, so remove it
                os.unlink(target)

        f = open(target, "wt")
        try:
            f.write(output)
        finally:
            f.close()

        exec_mask = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
        os.chmod(target, os.stat(target).st_mode | exec_mask)
        self.options.created(target)

        return self.options.created()
    def install(self):
        egg = Eggs(self.buildout, self.options["recipe"], self.options)
        reqs, ws = egg.working_set()
        path = [pkg.location for pkg in ws]
        extra_paths = self.options.get('extra-paths', '')
        extra_paths = extra_paths.split()
        path.extend(extra_paths)

        # Do not put None into 'quotes'
        # Everything else should be a string pointing to a pipeline
        app_name = self.options.get('app_name')
        if app_name is not None:
            app_name = '"%s"' % app_name

        output = WRAPPER_TEMPLATE % dict(config=self.options["config-file"],
                                         syspath=",\n    ".join(
                                             (repr(p) for p in path)),
                                         app_name=app_name)

        target = self.options.get("target")

        if target is None:
            location = os.path.join(
                self.buildout["buildout"]["parts-directory"], self.name)
            if not os.path.exists(location):
                os.mkdir(location)
                self.options.created(location)
            target = os.path.join(location, "wsgi")
        else:
            if os.path.lexists(target) and not os.path.exists(target):
                # Can't write to a broken symlink, so remove it
                os.unlink(target)

        f = open(target, "wt")
        try:
            f.write(output)
        finally:
            f.close()

        exec_mask = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
        os.chmod(target, os.stat(target).st_mode | exec_mask)
        self.options.created(target)

        return self.options.created()
Esempio n. 10
0
    def __init__(self, buildout, name, options):
        self.__name = name
        self.__logger = logging.getLogger(name)

        eggs = options['eggs']
        eggs = eggs.split('\n')
        eggs = list(egg.strip() for egg in eggs)
        for egg in eggs:
            self.__logger.info('egg: %s', egg)

        from zc.recipe.egg.egg import Eggs
        eggs_recipe = Eggs(buildout, name, options)
        req, ws = eggs_recipe.working_set()
        for dist in ws:
            self.__logger.debug('dist: %s %s at %s', dist, dist.key, dist.location)
        dist_locations = dict((dist.key, dist.location) for dist in ws)
        egg_path = list(dist_locations[egg] for egg in eggs)
        for p in egg_path:
            self.__logger.info('egg-path: %s', p)
        options['egg-path'] = ' '.join(egg_path)
Esempio n. 11
0
    def __init__(self, buildout, name, options):
        self.__name = name
        self.__logger = logging.getLogger(name)

        eggs = options['eggs']
        eggs = eggs.split('\n')
        eggs = list(egg.strip() for egg in eggs)
        for egg in eggs:
            self.__logger.info('egg: %s', egg)

        from zc.recipe.egg.egg import Eggs
        eggs_recipe = Eggs(buildout, name, options)
        req, ws = eggs_recipe.working_set()
        for dist in ws:
            self.__logger.debug('dist: %s %s at %s', dist, dist.key,
                                dist.location)
        dist_locations = dict((dist.key, dist.location) for dist in ws)
        egg_path = list(dist_locations[egg] for egg in eggs)
        for p in egg_path:
            self.__logger.info('egg-path: %s', p)
        options['egg-path'] = ' '.join(egg_path)
    def install(self):

        bin_dir = self.buildout["buildout"]["bin-directory"]

        egg = Eggs(self.buildout, self.options["recipe"], self.options)
        reqs, ws = egg.working_set()
        path = [pkg.location for pkg in ws]
        extra_paths = self.options.get("extra-paths", "")
        extra_paths = extra_paths.split()
        path.extend(extra_paths)

        template_vars = {
            "python": self.buildout["buildout"]["executable"],
            "pypath": ",\n    ".join((repr(p) for p in path)),
            "config": self.options["ini_file"],
            "buildout_dir": self.buildout["buildout"]["directory"],
            "script_path": bin_dir,
            "script_name": self.options["script_name"],
        }

        wsgi_script = "%s/%s.wsgi" % (bin_dir, self.options["script_name"])

        open(wsgi_script, "w").writelines(WSGI_TEMPLATE % template_vars)

        os.chmod(
            wsgi_script,
            stat.S_IRUSR
            | stat.S_IWUSR
            | stat.S_IXUSR
            | stat.S_IRGRP
            | stat.S_IWGRP
            | stat.S_IXGRP
            | stat.S_IROTH
            | stat.S_IXOTH,
        )

        if self.options.get("apache_config", None):
            open(self.options["apache_config"], "w").writelines(APACHE_SKEL_TEMPLATE % template_vars)

        return []
Esempio n. 13
0
    def install(self):
        egg = Eggs(self.buildout, self.options["recipe"], self.options)
        reqs, ws = egg.working_set()
        path = [pkg.location for pkg in ws]
        extra_paths = self.options.get('extra-paths', '')
        extra_paths = extra_paths.split()
        path.extend(extra_paths)

        output = WRAPPER_TEMPLATE % dict(
            wsgi_module=self.options["wsgi-module"],
            syspath=",\n    ".join((repr(p) for p in path)),
            initialization=self.options.get('initialization', ''),
            finalization=self.options.get('finalization', ''),
            )

        target = self.options.get("target")
        if target is None:
            location = os.path.join(
                            self.buildout["buildout"]["parts-directory"],
                            self.name)
            if not os.path.exists(location):
                os.mkdir(location)
                self.options.created(location)
            target = os.path.join(location, "wsgi")
        else:
            outputdir, filename = os.path.split(os.path.realpath(target))
            if not os.path.exists(outputdir) and self.make_target_dir:
                os.makedirs(outputdir)
            self.options.created(target)

        f = open(target, "wt")
        f.write(output)
        f.close()

        exec_mask = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
        os.chmod(target, os.stat(target).st_mode | exec_mask)
        self.options.created(target)

        return self.options.created()
Esempio n. 14
0
    def install(self):

        bin_dir = self.buildout['buildout']['bin-directory']

        egg = Eggs(self.buildout, self.options["recipe"], self.options)
        reqs, ws = egg.working_set()
        path = [pkg.location for pkg in ws]
        extra_paths = self.options.get('extra-paths', '')
        extra_paths = extra_paths.split()
        path.extend(extra_paths)

        template_vars = {
            'python': self.buildout['buildout']['executable'],
            'pypath': ",\n    ".join((repr(p) for p in path)),
            'config': self.options['ini_file'],
            'buildout_dir': self.buildout['buildout']['directory'],
            'script_path': bin_dir,
            'script_name': self.options['script_name'],
            'initialization': self.options.get('initialization', ''),
        }

        wsgi_script = '%s/%s.wsgi' % (bin_dir, self.options['script_name'])

        open(wsgi_script,
             'w').writelines(WSGI_TEMPLATE % template_vars)

        os.chmod(wsgi_script,
            stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR
            | stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP
            | stat.S_IROTH | stat.S_IXOTH)

        if self.options.get('apache_config', None):
            open(self.options['apache_config'],
                 'w').writelines(APACHE_SKEL_TEMPLATE % template_vars)

        return []
Esempio n. 15
0
    def install(self):
        egg = Eggs(self.buildout, self.options["recipe"], self.options)
        reqs, ws = egg.working_set()
        path = [pkg.location for pkg in ws]
        extra_paths = self.options.get('extra-paths', '')
        extra_paths = extra_paths.split()
        path.extend(extra_paths)

        output = WRAPPER_TEMPLATE % dict(
            syspath=",\n    ".join((repr(p) for p in path)))

        location = self.buildout["buildout"]["bin-directory"]
        if not os.path.exists(location):
            os.mkdir(location)
            self.options.created(location)

        target = os.path.join(location, self.name)
        f = open(target, "wt")
        f.write(output)
        f.close()
        os.chmod(target, 0755)
        self.options.created(target)

        return self.options.created()
Esempio n. 16
0
def make_wsgi_script(recipe, buildout):
    """Build the script for Apache/mod_wsgi
    """
    # Late import: zc.recipe.egg may not be installed when executing 1st
    # function
    from zc.recipe.egg.egg import Eggs
    app_egg = recipe['egg']
    wsgi_filepath = recipe['script']
    app_mod, app_obj = recipe['app'].rsplit('.', 1)  # 'a.b.c.d' -> 'a.b.c', 'd'
    working_dir = recipe['working_dir']
    relative_paths = recipe["relative-paths"]

    reqs, ws = Eggs(buildout, app_egg, recipe).working_set()
    egg_paths = [pkg.location for pkg in ws]

    if relative_paths == "false":
        src_egg_paths = ',\n'.join(["    '{0}'".format(path) for path in egg_paths])
    else:
        src_egg_paths = ',\n'.join(["join(base, '{0}')".format("/".join(path.split("/")[-2:])) for path in egg_paths])
        src_egg_paths = "base, \n%s" % src_egg_paths

    with open(wsgi_filepath, 'w') as fh:
        fh.write(WSGISCRIPT_TEMPLATE.format(src_egg_paths, app_mod, app_obj, working_dir))
    return
Esempio n. 17
0
    def install(self):
        """
        Recipe install function.
        """

        # Helper functions

        def split(s):
            """
            Template filter splitting on any whitespace.
            """

            return re.split("\s+", s.strip())

        def as_bool(s):
            """
            Template filter which translates the given string into a boolean.
            """

            return s.lower() in ("yes", "true", "1", "on")

        def strip_dict(d):
            """
            Strips the values of a dictionary in place. All values are assumed
            to be strings. The same dictionary object is returned.
            """

            for k, v in d.iteritems():
                d[k] = v.strip()
            return d

        # Validate template and target lists
        template_files = split(self.options["template-file"])
        target_files = split(self.options["target-file"])
        if len(template_files) != len(target_files):
            raise zc.buildout.UserError(
                    "The number of template and target files must match")

        # Validate and normalise target executable option
        target_executables = split(self.options.get("target-executable",
                                                    "false"))
        target_executables = [as_bool(v) for v in target_executables]
        if len(target_executables) == 1:
            value = target_executables[0]
            target_executables = (value for i in xrange(len(template_files)))
        else:
            if len(target_executables) != len(template_files):
                raise zc.buildout.UserError("The number of target executables"
                        "must 0, 1 or match the number of template files")

        # Assemble lists
        files = zip(template_files, target_files, target_executables)

        # Assemble template context
        context = strip_dict(dict(self.options))

        # Handle eggs specially
        if "eggs" in context:
            log.info("Making working set out of the eggs")
            eggs = Eggs(self.buildout, self.options["recipe"], self.options)
            names, eggs = eggs.working_set()
            context["eggs"] = eggs

        # Make options from other parts available.
        part_options = self.buildout
        if 'parts' not in context.keys():
            context.update({'parts': part_options})
        else:
            log.error("You should not use parts as a name of a variable,"
                      " since it is used internally by this receipe")
            raise zc.buildout.UserError("parts used as a variable in %s"
                                        % self.name)

        # Set up jinja2 environment
        jinja2_env = self._jinja2_env(filters={
            "split": split,
            "as_bool": as_bool,
            "type": type,
        })

        # Load, render, and save files
        for template_file, target_file, executable in files:
            template = self._load_template(jinja2_env, template_file)
            output = template.render(**context)

            # Make target file
            target_file = os.path.abspath(target_file)
            self._ensure_dir(os.path.dirname(target_file))

            fp = open(target_file, "wt")
            fp.write(output)
            fp.close()

            # Chmod target file
            if executable:
                os.chmod(target_file, 0755)

            self.options.created(target_file)

        return self.options.created()
Esempio n. 18
0
    def install(self):
        """
        Recipe install function.
        """

        # Helper functions

        def split(s):
            """
            Template filter splitting on any whitespace.
            """

            return re.split("\s+", s.strip())

        def as_bool(s):
            """
            Template filter which translates the given string into a boolean.
            """

            return s.lower() in ("yes", "true", "1", "on")

        def strip_dict(d):
            """
            Strips the values of a dictionary in place. All values are assumed
            to be strings. The same dictionary object is returned.
            """

            for k, v in d.iteritems():
                d[k] = v.strip()
            return d

        # Validate template and target lists
        template_file_option = self.options.get(
                "template-file",
                self.options.get("input")
                )
        target_file_option = self.options.get(
                "target-file",
                self.options.get("output")
                )
        template_files = split(template_file_option)
        target_files = split(target_file_option)
        if len(template_files) != len(target_files):
            raise zc.buildout.UserError(
                    "The number of template and target files must match")

        # Validate and normalise target executable option
        target_executables = split(self.options.get("target-executable",
                                                    "false"))
        target_executables = [as_bool(v) for v in target_executables]
        if len(target_executables) == 1:
            value = target_executables[0]
            target_executables = (value for i in xrange(len(template_files)))
        else:
            if len(target_executables) != len(template_files):
                raise zc.buildout.UserError("The number of target executables"
                        "must 0, 1 or match the number of template files")

        # Assemble lists
        files = zip(template_files, target_files, target_executables)

        # Assemble template context
        context = strip_dict(dict(self.options))

        # Handle eggs specially
        if "eggs" in context:
            log.info("Making working set out of the eggs")
            eggs = Eggs(self.buildout, self.options["recipe"], self.options)
            names, eggs = eggs.working_set()
            context["eggs"] = eggs

        # Make recursive dict to be enable access dashed values.
        context['context'] = context

        # Make options from other parts available.
        part_options = dict(self.buildout)
        if 'parts' not in context.keys():
            context.update({'parts': part_options})
        else:
            log.error("You should not use parts as a name of a variable,"
                      " since it is used internally by this receipe")
            raise zc.buildout.UserError("parts used as a variable in %s"
                                        % self.name)

        filters = self.options.get('jinja2_filters')
        if filters:
            jinja2_filters = {}
            filters = filters.split()
            for filter_ in filters:
                try:
                    jinja2_filters[filter_.split('.')[-1]] = resolve_dotted(filter_)
                except ImportError, e:
                    raise zc.buildout.UserError("Filter '%s' not found.\n%s"
                                                % (filter_, e))
    def install(self):
        """
        Recipe install function.
        """

        parse_list = lambda s: s.strip().split()

        # Validate template and target lists
        template_files = parse_list(self.options["template-file"])
        target_files = parse_list(self.options["target-file"])
        if len(template_files) != len(target_files):
            raise zc.buildout.UserError(
                    "The number of template and target files must match")

        # Validate and normalise target executable option
        target_executables = parse_list(self.options.get("target-executable", "false"))
        target_executables = [as_bool(v) for v in target_executables]
        if len(target_executables) == 1:
            value = target_executables[0]
            target_executables = (value for i in range(len(template_files)))
        else:
            if len(target_executables) != len(template_files):
                raise zc.buildout.UserError("The number of target executables"
                        "must 0, 1 or match the number of template files")

        # Assemble lists
        files = zip(template_files, target_files, target_executables)

        # Assemble template context
        context = {k: v.strip() for k, v in self.options.items()}

        # Handle eggs specially
        if "eggs" in context:
            log.info("Making working set out of the eggs")
            eggs = Eggs(self.buildout, self.options["recipe"], self.options)
            names, eggs = eggs.working_set()
            context["eggs"] = eggs

        # Make options from other parts available.
        part_options = self.buildout
        if 'parts' not in context:
            context.update({'parts': part_options})
        else:
            log.error("You should not use parts as a name of a variable,"
                      " since it is used internally by this receipe")
            raise zc.buildout.UserError("parts used as a variable in {}".format(self.name))

        # Set up jinja2 environment
        jinja2_env = self.create_jinja2_env(
            filters={
                "as_bool":     as_bool,
                "shell_quote": quote,
            },
            builtins={
                "randomstring": randomstring,
            })

        # Load, render, and save files
        for template_file, target_file, executable in files:
            template = get_template(jinja2_env, template_file)
            output = template.render(**context)

            # Make target file
            target_file = os.path.abspath(target_file)
            ensure_dir(os.path.dirname(target_file))

            fp = open(target_file, "wt")
            fp.write(output)
            fp.close()

            # Chmod target file
            if executable:
                os.chmod(target_file, 0o755)

            self.options.created(target_file)

        return self.options.created()
Esempio n. 20
0
    def install(self):
        """
        Recipe install function.
        """

        # Helper functions

        def split(s):
            """
            Template filter splitting on any whitespace.
            """

            return re.split(r'\s+', s.strip())

        def as_bool(s):
            """
            Template filter which translates the given string into a boolean.
            """

            return s.lower() in ("yes", "true", "1", "on")

        def strip_dict(d):
            """
            Strips the values of a dictionary in place. All values are assumed
            to be strings. The same dictionary object is returned.
            """

            for k, v in d.items():
                d[k] = v.strip()
            return d

        # Validate template and target lists
        template_file_option = self.options.get(
            "template-file",
            self.options.get("input"),
        )
        target_file_option = self.options.get(
            "target-file",
            self.options.get("output"),
        )
        template_files = split(template_file_option)
        target_files = split(target_file_option)
        if len(template_files) != len(target_files):
            raise zc.buildout.UserError(
                "The number of template and target files must match")

        # Validate and normalise target executable option
        target_executables = split(
            self.options.get("target-executable", "false"))
        target_executables = [as_bool(v) for v in target_executables]
        if len(target_executables) == 1:
            value = target_executables[0]
            target_executables = (value for i in range(len(template_files)))
        else:
            if len(target_executables) != len(template_files):
                raise zc.buildout.UserError(
                    "The number of target executables"
                    "must 0, 1 or match the number of template files")

        # Assemble lists
        files = zip(template_files, target_files, target_executables)

        # Assemble template context
        context = strip_dict(dict(self.options))

        # Handle eggs specially
        if "eggs" in context:
            log.info("Making working set out of the eggs")
            eggs = Eggs(self.buildout, self.options["recipe"], self.options)
            names, eggs = eggs.working_set()
            context["eggs"] = eggs

        # Make recursive dict to be enable access dashed values.
        context['context'] = context

        # Make options from other parts available.
        part_options = SafeBuildout(self.buildout)
        if 'parts' not in context.keys():
            context.update({'parts': part_options})
        else:
            log.error("You should not use parts as a name of a variable,"
                      " since it is used internally by this recipe")
            raise zc.buildout.UserError("parts used as a variable in %s" %
                                        self.name)

        filters = self.options.get('jinja2_filters')
        if filters:
            jinja2_filters = {}
            filters = filters.split()
            for filter_ in filters:
                try:
                    jinja2_filters[filter_.split('.')[-1]] = resolve_dotted(
                        filter_)
                except ImportError as e:
                    raise zc.buildout.UserError("Filter '%s' not found.\n%s" %
                                                (filter_, e))
        else:
            jinja2_filters = {}

        filters = {
            "split": split,
            "as_bool": as_bool,
            "type": type,
            "eval": eval,
            "re_escape": re.escape,
        }
        filters.update(jinja2_filters)

        # Set up jinja2 environment
        jinja2_env = self._jinja2_env(filters=filters)

        # Load, render, and save files
        for template_file, target_file, executable in files:
            template = self._load_template(jinja2_env, template_file)
            output = template.render(**context)

            # Make target file
            target_file = os.path.abspath(target_file)
            self._ensure_dir(os.path.dirname(target_file))

            fp = open(target_file, "wt")
            fp.write(output)
            fp.close()

            # Chmod target file
            if executable:
                os.chmod(target_file, 0o755)

            self.options.created(target_file)

        return self.options.created()