| 1 | # (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org) |
|---|
| 2 | # Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php |
|---|
| 3 | import os |
|---|
| 4 | import pkg_resources |
|---|
| 5 | |
|---|
| 6 | def add_plugin(egg_info_dir, plugin_name): |
|---|
| 7 | """ |
|---|
| 8 | Add the plugin to the given distribution (or spec), in |
|---|
| 9 | .egg-info/paster_plugins.txt |
|---|
| 10 | """ |
|---|
| 11 | fn = os.path.join(egg_info_dir, 'paster_plugins.txt') |
|---|
| 12 | if not os.path.exists(fn): |
|---|
| 13 | lines = [] |
|---|
| 14 | else: |
|---|
| 15 | f = open(fn) |
|---|
| 16 | lines = [l.strip() for l in f.readlines() if l.strip()] |
|---|
| 17 | f.close() |
|---|
| 18 | if plugin_name in lines: |
|---|
| 19 | # Nothing to do |
|---|
| 20 | return |
|---|
| 21 | lines.append(plugin_name) |
|---|
| 22 | if not os.path.exists(os.path.dirname(fn)): |
|---|
| 23 | os.makedirs(os.path.dirname(fn)) |
|---|
| 24 | f = open(fn, 'w') |
|---|
| 25 | for line in lines: |
|---|
| 26 | f.write(line) |
|---|
| 27 | f.write('\n') |
|---|
| 28 | f.close() |
|---|
| 29 | |
|---|
| 30 | def remove_plugin(egg_info_dir, plugin_name): |
|---|
| 31 | """ |
|---|
| 32 | Remove the plugin to the given distribution (or spec), in |
|---|
| 33 | .egg-info/paster_plugins.txt. Raises ValueError if the |
|---|
| 34 | plugin is not in the file. |
|---|
| 35 | """ |
|---|
| 36 | fn = os.path.join(egg_info_dir, 'paster_plugins.txt') |
|---|
| 37 | if not os.path.exists(fn): |
|---|
| 38 | raise ValueError( |
|---|
| 39 | "Cannot remove plugin from %s; file does not exist" |
|---|
| 40 | % fn) |
|---|
| 41 | f = open(fn) |
|---|
| 42 | lines = [l.strip() for l in f.readlines() if l.strip()] |
|---|
| 43 | f.close() |
|---|
| 44 | for line in lines: |
|---|
| 45 | # What about version specs? |
|---|
| 46 | if line.lower() == plugin_name.lower(): |
|---|
| 47 | break |
|---|
| 48 | else: |
|---|
| 49 | raise ValueError( |
|---|
| 50 | "Plugin %s not found in file %s (from: %s)" |
|---|
| 51 | % (plugin_name, fn, lines)) |
|---|
| 52 | lines.remove(line) |
|---|
| 53 | print 'writing', lines |
|---|
| 54 | f = open(fn, 'w') |
|---|
| 55 | for line in lines: |
|---|
| 56 | f.write(line) |
|---|
| 57 | f.write('\n') |
|---|
| 58 | f.close() |
|---|
| 59 | |
|---|
| 60 | def find_egg_info_dir(dir): |
|---|
| 61 | while 1: |
|---|
| 62 | try: |
|---|
| 63 | filenames = os.listdir(dir) |
|---|
| 64 | except OSError: |
|---|
| 65 | # Probably permission denied or something |
|---|
| 66 | return None |
|---|
| 67 | for fn in filenames: |
|---|
| 68 | if fn.endswith('.egg-info'): |
|---|
| 69 | return os.path.join(dir, fn) |
|---|
| 70 | parent = os.path.dirname(dir) |
|---|
| 71 | if parent == dir: |
|---|
| 72 | # Top-most directory |
|---|
| 73 | return None |
|---|
| 74 | dir = parent |
|---|
| 75 | |
|---|
| 76 | def resolve_plugins(plugin_list): |
|---|
| 77 | found = [] |
|---|
| 78 | while plugin_list: |
|---|
| 79 | plugin = plugin_list.pop() |
|---|
| 80 | try: |
|---|
| 81 | pkg_resources.require(plugin) |
|---|
| 82 | except pkg_resources.DistributionNotFound, e: |
|---|
| 83 | msg = '%sNot Found%s: %s (did you run python setup.py develop?)' |
|---|
| 84 | if str(e) != plugin: |
|---|
| 85 | e.args = (msg % (str(e) + ': ', ' for', plugin)), |
|---|
| 86 | else: |
|---|
| 87 | e.args = (msg % ('', '', plugin)), |
|---|
| 88 | raise |
|---|
| 89 | found.append(plugin) |
|---|
| 90 | dist = get_distro(plugin) |
|---|
| 91 | if dist.has_metadata('paster_plugins.txt'): |
|---|
| 92 | data = dist.get_metadata('paster_plugins.txt') |
|---|
| 93 | for add_plugin in parse_lines(data): |
|---|
| 94 | if add_plugin not in found: |
|---|
| 95 | plugin_list.append(add_plugin) |
|---|
| 96 | return map(get_distro, found) |
|---|
| 97 | |
|---|
| 98 | def get_distro(spec): |
|---|
| 99 | return pkg_resources.get_distribution(spec) |
|---|
| 100 | |
|---|
| 101 | def load_commands_from_plugins(plugins): |
|---|
| 102 | commands = {} |
|---|
| 103 | for plugin in plugins: |
|---|
| 104 | commands.update(pkg_resources.get_entry_map( |
|---|
| 105 | plugin, group='paste.paster_command')) |
|---|
| 106 | return commands |
|---|
| 107 | |
|---|
| 108 | def parse_lines(data): |
|---|
| 109 | result = [] |
|---|
| 110 | for line in data.splitlines(): |
|---|
| 111 | line = line.strip() |
|---|
| 112 | if line and not line.startswith('#'): |
|---|
| 113 | result.append(line) |
|---|
| 114 | return result |
|---|
| 115 | |
|---|
| 116 | def load_global_commands(): |
|---|
| 117 | commands = {} |
|---|
| 118 | for p in pkg_resources.iter_entry_points('paste.global_paster_command'): |
|---|
| 119 | commands[p.name] = p |
|---|
| 120 | return commands |
|---|
| 121 | |
|---|
| 122 | def egg_name(dist_name): |
|---|
| 123 | return pkg_resources.to_filename(pkg_resources.safe_name(dist_name)) |
|---|
| 124 | |
|---|
| 125 | def egg_info_dir(base_dir, dist_name): |
|---|
| 126 | all = [] |
|---|
| 127 | for dir_extension in ['.'] + os.listdir(base_dir): |
|---|
| 128 | full = os.path.join(base_dir, dir_extension, |
|---|
| 129 | egg_name(dist_name)+'.egg-info') |
|---|
| 130 | all.append(full) |
|---|
| 131 | if os.path.exists(full): |
|---|
| 132 | return full |
|---|
| 133 | raise IOError("No egg-info directory found (looked in %s)" |
|---|
| 134 | % ', '.join(all)) |
|---|