|
| 1 | +# noqa: D300,D400 |
| 2 | +# Copyright (c) 2016, Aaron Christianson |
| 3 | +# All rights reserved. |
| 4 | +# |
| 5 | +# Redistribution and use in source and binary forms, with or without |
| 6 | +# modification, are permitted provided that the following conditions are |
| 7 | +# met: |
| 8 | +# |
| 9 | +# 1. Redistributions of source code must retain the above copyright |
| 10 | +# notice, this list of conditions and the following disclaimer. |
| 11 | +# |
| 12 | +# 2. Redistributions in binary form must reproduce the above copyright |
| 13 | +# notice, this list of conditions and the following disclaimer in the |
| 14 | +# documentation and/or other materials provided with the distribution. |
| 15 | +# |
| 16 | +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS |
| 17 | +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
| 18 | +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
| 19 | +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 20 | +# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 21 | +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED |
| 22 | +# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| 23 | +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
| 24 | +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| 25 | +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| 26 | +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | +''' |
| 28 | +Monkey patch setuptools to write faster console_scripts with this format: |
| 29 | +
|
| 30 | + import sys |
| 31 | + from mymodule import entry_function |
| 32 | + sys.exit(entry_function()) |
| 33 | +
|
| 34 | +This is better. |
| 35 | +
|
| 36 | +(c) 2016, Aaron Christianson |
| 37 | +http://github.com/ninjaaron/fast-entry_points |
| 38 | +''' |
| 39 | +from setuptools.command import easy_install |
| 40 | +import re |
| 41 | +TEMPLATE = r''' |
| 42 | +# -*- coding: utf-8 -*- |
| 43 | +# EASY-INSTALL-ENTRY-SCRIPT: '{3}','{4}','{5}' |
| 44 | +__requires__ = '{3}' |
| 45 | +import re |
| 46 | +import sys |
| 47 | +
|
| 48 | +from {0} import {1} |
| 49 | +
|
| 50 | +if __name__ == '__main__': |
| 51 | + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) |
| 52 | + sys.exit({2}()) |
| 53 | +'''.lstrip() |
| 54 | + |
| 55 | + |
| 56 | +@classmethod |
| 57 | +def get_args(cls, dist, header=None): # noqa: D205,D400 |
| 58 | + """ |
| 59 | + Yield write_script() argument tuples for a distribution's |
| 60 | + console_scripts and gui_scripts entry points. |
| 61 | + """ |
| 62 | + if header is None: |
| 63 | + # pylint: disable=E1101 |
| 64 | + header = cls.get_header() |
| 65 | + spec = str(dist.as_requirement()) |
| 66 | + for type_ in 'console', 'gui': |
| 67 | + group = type_ + '_scripts' |
| 68 | + for name, ep in dist.get_entry_map(group).items(): |
| 69 | + # ensure_safe_name |
| 70 | + if re.search(r'[\\/]', name): |
| 71 | + raise ValueError("Path separators not allowed in script names") |
| 72 | + script_text = TEMPLATE.format( |
| 73 | + ep.module_name, ep.attrs[0], '.'.join(ep.attrs), |
| 74 | + spec, group, name) |
| 75 | + # pylint: disable=E1101 |
| 76 | + args = cls._get_script_args(type_, name, header, script_text) |
| 77 | + for res in args: |
| 78 | + yield res |
| 79 | + |
| 80 | + |
| 81 | +# pylint: disable=E1101 |
| 82 | +easy_install.ScriptWriter.get_args = get_args |
| 83 | + |
| 84 | + |
| 85 | +def main(): |
| 86 | + import os |
| 87 | + import re |
| 88 | + import shutil |
| 89 | + import sys |
| 90 | + dests = sys.argv[1:] or ['.'] |
| 91 | + filename = re.sub(r'\.pyc$', '.py', __file__) |
| 92 | + |
| 93 | + for dst in dests: |
| 94 | + shutil.copy(filename, dst) |
| 95 | + manifest_path = os.path.join(dst, 'MANIFEST.in') |
| 96 | + setup_path = os.path.join(dst, 'setup.py') |
| 97 | + |
| 98 | + # Insert the include statement to MANIFEST.in if not present |
| 99 | + with open(manifest_path, 'a+') as manifest: |
| 100 | + manifest.seek(0) |
| 101 | + manifest_content = manifest.read() |
| 102 | + if 'include fastentrypoints.py' not in manifest_content: |
| 103 | + manifest.write(('\n' if manifest_content else '') + |
| 104 | + 'include fastentrypoints.py') |
| 105 | + |
| 106 | + # Insert the import statement to setup.py if not present |
| 107 | + with open(setup_path, 'a+') as setup: |
| 108 | + setup.seek(0) |
| 109 | + setup_content = setup.read() |
| 110 | + if 'import fastentrypoints' not in setup_content: |
| 111 | + setup.seek(0) |
| 112 | + setup.truncate() |
| 113 | + setup.write('import fastentrypoints\n' + setup_content) |
0 commit comments