Как написать плагин брюк для сборки, который добавляет код заголовка в исходный код Python на python_binary - PullRequest
0 голосов
/ 17 января 2019

Я создаю плагин брюк, который должен модифицировать код из спецификации «sources» в цели python_binary, чтобы в заголовке было немного лишнего кода. Я не могу понять, как создать / перенаправить штаны в промежуточный файл.

Причина, по которой я это делаю, заключается в том, что, насколько я могу судить ,antsbuild не поддерживает идею файлов .pth. Я думаю, что не стоит поддерживать это, но мы переходим от проекта на основе setuptools, который использует .pth к брюкам, и поэтому необходимо изменить sys.path, чтобы он поддерживал правильный путь (исправляя фактические пути на диске для рассматриваемая библиотека не возможна, поскольку сторонний инструмент генерирует код библиотеки и макет для нас).

Учитывая приведенный ниже код, MyPythonBinary пытается изменить исходный код, включив в него несколько дополнительных строк в начале файла. Проблема в том, что «источники» ссылаются на фактический исходный файл, но я хочу написать промежуточный файл с моими изменениями и перенаправить «источники» в этот промежуточный файл.

Я знаю, что "sources" - это разновидность FilesetWithSpec, но выяснить, как правильно их создать, чтобы я мог записать в другой промежуточный файл, было немного сложно. Кто-нибудь может мне помочь?

from pants.backend.python.targets.python_binary import PythonBinary
from six import string_types

import os

PATCH_CODE = """
import MyOtherLibrary
if os.path.dirname(MyOtherLibrary.__file__) not in sys.path:
    sys.path.append(os.path.dirname(MyOtherLibrary.__file__))
"""


class MyPythonBinary(PythonBinary):
    def __init__(self, *args, **kwargs):
        if 'sources' in kwargs:
            sources = kwargs['sources']
            assert len(sources.files) == 1,\
                "sources.files must contain a single file"

            # I know this is nasty.  I got it from debugging.
            source_file = sources.snapshot.path_stats[0].stat.path
            self._patch_source(source_file, PATCH_CODE)

            # recreate the filespec but pointing to an intermediate file
            # kwargs['sources'] = None
        super(MyPythonBinary, self).__init__(*args, **kwargs)

    def _patch_source(self, source_file, prepend=""):
        """
        Patches source code in C{source_file} with the contents of C{prepend},
        storing the results in a temporary source file.
        @type source_file: string_types
        @param source_file: path to the file containing the source code
        @type prepend: string_types
        @param prepend: Code to prepend
        """
        assert isinstance(source_file, string_types)
        assert isinstance(prepend, string_types)

        with open(source_file, 'w+') as fout:
            fout.seek(0)
            fout.write(prepend)

Приведенный выше код добавляет код из PATCH_CODE в исходный файл вместо промежуточного файла. Штаны не знает о новом промежуточном файле.

...