Динамическое копирование данных пакета во время установки в setup.py - PullRequest
0 голосов
/ 22 января 2020

У меня есть структура каталогов, которая выглядит следующим образом:

.
├── bitbucket-pipelines.yml
├── MANIFEST.in
├── pylintrc
├── setup.cfg
├── setup.py
├── src
│   ├── bin
│   │   ├── __init__.py
│   │   └── project.py
│   ├── __init__.py
│   └── ml_project
│       ├── configurations
│       │   └── precommit
│       ├── core
│       │   ├── command
│       │   │   ├── abs_command.py
│       │   │   ├── __init__.py
│       │   │   ├── no_command.py
│       │   │   ├── precommit.py
│       │   │   ├── project_utils.py
│       │   │   ├── setupsrc.py
│       │   │   └── setuptox.py
│       │   ├── configurations
│       │   │   └── precommit
│       │   └── __init__.py
│       └── __init__.py
└── tox.ini

Когда я делаю упаковку для проекта, мое требование заключается в том, чтобы в основном скопировать файлы .gitlint и .pre-commit-config.yaml внутри * 1006. * папка моего ml_project пакета. configurations - это обычный каталог, а не пакет Python, поскольку он не содержит .py файлов.

Небольшое редактирование .gitlint и .pre-commit-config.yaml находятся на том же уровне, что и setup.py is.

Мой setup.py выглядит следующим образом:

"""Setup script."""

import io
import re
import os
import shutil
from setuptools import setup

PROJECT_NAME = "ml_project"
CONFIGURATIONS_DIR_NAME = "configurations"
FULL_CONFIG_DIR = os.path.join("src", PROJECT_NAME, CONFIGURATIONS_DIR_NAME)


def get_version() -> str:
    """Return the version stored in `ml_project/__init__.py:__version__`."""
    # see https://github.com/pallets/flask/blob/master/setup.py
    with io.open("src/ml_project/__init__.py", "rt", encoding="utf8") as init_file:
        return re.search(r'__version__ = "(.*?)"', init_file.read()).group(1)


def add_config_files_for_package(source_dir: str = None) -> None:
    if not source_dir:
        source_dir = os.path.dirname(os.path.abspath(__file__))
    config_files = {"precommit": [".gitlint", ".pre-commit-config.yaml"]}
    for config in config_files:
        config_dir = os.path.join(source_dir, FULL_CONFIG_DIR, config)
        for file in config_files[config]:
            shutil.copyfile(
                os.path.join(source_dir, file), os.path.join(config_dir, file)
            )


add_config_files_for_package()
setup(version=get_version())

Поэтому я использую функцию add_config_files_for_package для копирования при запуске python setup.py sdist.

У меня есть MANIFEST.in файл, который выглядит следующим образом:

include .gitlint
include .pre-commit-config.yaml
graft src/ml_project

И, наконец, ниже мой setup.cfg:

[options]
package_dir =
    =src
packages = find:
include_package_data = true
install_requires =
    click
    pre-commit
    pyyaml
    gitlint


[options.packages.find]
where = src

[options.entry_points]
console_scripts =
    project = bin.project:main

[options.extras_require]
tests =
    pytest
    pytest-mock
    pyfakefs
    pyyaml
    configparser
linting =
    pylint
testdocs =
    pydocstyle
pre-commit =
    pre-commit

[semantic_release]

version_variable = ml_project/__init__.py:__version__

Это работает нормально, но мой вопрос: есть ли лучший и более стандартный способ сделать это? Как вообще без написания этой функции?

Спасибо за любые указатели заранее.

1 Ответ

0 голосов
/ 23 января 2020

Как упоминалось в комментариях, было бы неплохо поместить эти файлы в каталог src/ml_project/configurations/precommit и создать symboli c ссылки на эти файлы в root проекта. Ссылки Symboli c должны хорошо работать с git, но некоторые платформы (например, Windows) не имеют хорошей поддержки для них.

Или копия этих файлов может быть просто еще одним шагом в процессе сборки (в конечном итоге с помощью пользовательской команды setuptools ), который должен запускаться из Makefile (например, или любого другого аналогичный инструмент) и из цепочек инструментов CI / CD (bitbucket-pipelines.yml в данном случае).

...