0001# (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org)
0002# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
0003import os
0004import pkg_resources
0005
0006def add_plugin(egg_info_dir, plugin_name):
0007    """
0008    Add the plugin to the given distribution (or spec), in
0009    .egg-info/paster_plugins.txt
0010    """
0011    fn = os.path.join(egg_info_dir, 'paster_plugins.txt')
0012    if not os.path.exists(fn):
0013        lines = []
0014    else:
0015        f = open(fn)
0016        lines = [l.strip() for l in f.readlines() if l.strip()]
0017        f.close()
0018    if plugin_name in lines:
0019        # Nothing to do
0020        return
0021    lines.append(plugin_name)
0022    if not os.path.exists(os.path.dirname(fn)):
0023        os.makedirs(os.path.dirname(fn))
0024    f = open(fn, 'w')
0025    for line in lines:
0026        f.write(line)
0027        f.write('\n')
0028    f.close()
0029
0030def remove_plugin(egg_info_dir, plugin_name):
0031    """
0032    Remove the plugin to the given distribution (or spec), in
0033    .egg-info/paster_plugins.txt.  Raises ValueError if the
0034    plugin is not in the file.
0035    """
0036    fn = os.path.join(egg_info_dir, 'paster_plugins.txt')
0037    if not os.path.exists(fn):
0038        raise ValueError(
0039            "Cannot remove plugin from %s; file does not exist"
0040            % fn)
0041    f = open(fn)
0042    lines = [l.strip() for l in f.readlines() if l.strip()]
0043    f.close()
0044    for line in lines:
0045        # What about version specs?
0046        if line.lower() == plugin_name.lower():
0047            break
0048    else:
0049        raise ValueError(
0050            "Plugin %s not found in file %s (from: %s)"
0051            % (plugin_name, fn, lines))
0052    lines.remove(line)
0053    print 'writing', lines
0054    f = open(fn, 'w')
0055    for line in lines:
0056        f.write(line)
0057        f.write('\n')
0058    f.close()
0059
0060def find_egg_info_dir(dir):
0061    while 1:
0062        try:
0063            filenames = os.listdir(dir)
0064        except OSError:
0065            # Probably permission denied or something
0066            return None
0067        for fn in filenames:
0068            if fn.endswith('.egg-info'):
0069                return os.path.join(dir, fn)
0070        parent = os.path.dirname(dir)
0071        if parent == dir:
0072            # Top-most directory
0073            return None
0074        dir = parent
0075
0076def resolve_plugins(plugin_list):
0077    found = []
0078    while plugin_list:
0079        plugin = plugin_list.pop()
0080        try:
0081            pkg_resources.require(plugin)
0082        except pkg_resources.DistributionNotFound, e:
0083            msg = '%sNot Found%s: %s (did you run python setup.py develop?)'
0084            if str(e) != plugin:
0085                e.args = (msg % (str(e) + ': ', ' for', plugin)),
0086            else:
0087                e.args = (msg % ('', '', plugin)),
0088            raise
0089        found.append(plugin)
0090        dist = get_distro(plugin)
0091        if dist.has_metadata('paster_plugins.txt'):
0092            data = dist.get_metadata('paster_plugins.txt')
0093            for add_plugin in parse_lines(data):
0094                if add_plugin not in found:
0095                    plugin_list.append(add_plugin)
0096    return map(get_distro, found)
0097
0098def get_distro(spec):
0099    return pkg_resources.get_distribution(spec)
0100
0101def load_commands_from_plugins(plugins):
0102    commands = {}
0103    for plugin in plugins:
0104        commands.update(pkg_resources.get_entry_map(
0105            plugin, group='paste.paster_command'))
0106    return commands
0107
0108def parse_lines(data):
0109    result = []
0110    for line in data.splitlines():
0111        line = line.strip()
0112        if line and not line.startswith('#'):
0113            result.append(line)
0114    return result
0115
0116def load_global_commands():
0117    commands = {}
0118    for p in pkg_resources.iter_entry_points('paste.global_paster_command'):
0119        commands[p.name] = p
0120    return commands
0121
0122def egg_name(dist_name):
0123    return pkg_resources.to_filename(pkg_resources.safe_name(dist_name))
0124
0125def egg_info_dir(base_dir, dist_name):
0126    all = []
0127    for dir_extension in ['.'] + os.listdir(base_dir):
0128        full = os.path.join(base_dir, dir_extension,
0129                            egg_name(dist_name)+'.egg-info')
0130        all.append(full)
0131        if os.path.exists(full):
0132            return full
0133    raise IOError("No egg-info directory found (looked in %s)"
0134                  % ', '.join(all))