trac-ticketlinks / trac /

# -*- coding: iso8859-1 -*-
# Copyright (C) 2005 Edgewall Software
# Copyright (C) 2005 Christopher Lenz <>
# All rights reserved.
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at
# This software consists of voluntary contributions made by many
# individuals. For the exact contribution history, see the revision
# history and logs, available at
# Author: Christopher Lenz <>

import os
import sys

    import pkg_resources
except ImportError:
    pkg_resources = None

TRAC_META = 'trac_plugin.txt'

__all__ = ['load_components']

def normalize_path(s):
  return os.path.normcase(os.path.abspath(s))

def paths_equal(path1, path2):
  return normalize_path(path1) == normalize_path(path2)

def load_components(env):

    loaded_components = []

    def load_module(name):
         if name not in loaded_components:
                 module = __import__(name)
                 return module
             except ImportError, e:
                 env.log.error('Component module %s not found',
                               name, exc_info=True)

    plugins_dir = os.path.join(env.path, 'plugins')

    def enable_modules(egg_path, modules):
        """Automatically enable any components provided by plugins loaded from
        the environment plugins directory."""
        if paths_equal(os.path.dirname(egg_path), os.path.realpath(plugins_dir)):
            for module in modules:
                env.config.setdefault('components', module + '.*', 'enabled')

    # Load components from the environment plugins directory
    if pkg_resources is not None: # But only if setuptools is installed!
        if hasattr(pkg_resources, 'Environment'):
            # setuptools >= 0.6
            pkg_env = pkg_resources.Environment([plugins_dir] + sys.path)
            for name in pkg_env:
                egg = pkg_env[name][0]
                modules = []

                for name in egg.get_entry_map('trac.plugins'):
                    # Load plugins declared via the `trac.plugins` entry point.
                    # This is the only supported option going forward, the
                    # others will be dropped at some point in the future.
                    env.log.debug('Loading plugin %s from %s', name,
                        entry_point = egg.get_entry_info('trac.plugins', name)
                        if entry_point.module_name not in loaded_components:
                    except ImportError, e:
                        env.log.error('Failed to load plugin %s from %s', name,
                                      egg.location, exc_info=True)

                    # Support for pre-entry-point plugins
                    if egg.has_metadata('trac_plugin.txt'):
                        env.log.debug('Loading plugin %s from %s', name,
                        for module in egg.get_metadata_lines('trac_plugin.txt'):
                            if load_module(module):

                if modules:
                    enable_modules(egg.location, modules)

            # setuptools < 0.6
            distributions = pkg_resources.AvailableDistributions([plugins_dir] \
                                                                 + sys.path)
            for name in distributions:
                egg = distributions[name][0]
                modules = []
                if egg.metadata.has_metadata(TRAC_META):
                    for module in egg.metadata.get_metadata_lines(TRAC_META):
                        if load_module(module):

                if modules:
                    enable_modules(egg.path, modules)

    elif os.path.exists(plugins_dir) and os.listdir(plugins_dir):
        env.log.warning('setuptools is required for plugin deployment')

    # Load default components
    from trac.db_default import default_components
    for module in default_components:
        if not module in loaded_components:
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.