Подтвердить что ты не робот

Автоматический номер версии как в setup.py(setuptools) И в исходном коде?

СИТУАЦИЯ:

У меня есть библиотека python, которая управляется git и в комплекте с distutils/setuptools. И я хочу автоматически генерировать номер версии на основе тегов git, как для setup.py sdist, так и для отдельных команд, а также для самой библиотеки.

Для первой задачи я могу использовать git describe или аналогичные решения (см. Как получить версию, определенную в setup.py(setuptools) в моем пакете?).

И когда, например, я нахожусь в теге "0,1" и вызывается "setup.py sdist", я получаю "mylib-0.1.tar.gz"; или "mylib-0.1-3-abcd.tar.gz", если я изменил код после тегов. Это нормально.

ПРОБЛЕМА:

Проблема возникает, когда я хочу, чтобы этот номер версии был доступен для самой библиотеки, поэтому он мог отправить ее в HTTP-заголовке User-Agent как "mylib/0.1-3-adcd".

Если я добавлю команду setup.py version, как в Как я могу получить версию, определенную в setup.py(setuptools) в моем пакете?, то эта версия .ppy генерируется ПОСЛЕ создания тега, поскольку он использует тег в качестве значения. Но в этом случае мне нужно сделать еще одну фиксацию после того, как тег версии сделан, чтобы сделать код согласованным. Который, по очереди, требует нового тега для дальнейшего связывания.

ВОПРОС:

Как разбить этот круг зависимостей (generate-commit-tag-generate-commit-tag -...)?

4b9b3361

Ответ 1

Вы также можете изменить зависимость: поместите версию в mylib/__init__.py, проанализируйте этот файл в файле setup.py, чтобы получить параметр версии, и используйте git tag $(setup.py -version) в командной строке для создания вашего тега.

git tag -a v$(python setup.py --version) -m 'description of version'

Есть ли что-то более сложное, что вы хотите сделать, что я не понял?

Ответ 2

Классическая проблема при использовании расширения ключевых слов;)

Ключ должен понять, что ваш тег является частью процесса управления выпуском, а не частью процесса разработки (и управления версиями).

Другими словами, вы не можете включать данные управления релизами в репозиторий разработки, из-за цикла, который вы проиллюстрируете в своем вопросе.

При создании пакета (который является "частью управления версиями" ) вам необходимо записать эту информацию в файл, который ваша библиотека будет искать и использовать (если указанный файл существует) для своего HTTP-заголовка User-Agent.

Ответ 3

Следуя решению OGHaza в аналогичный вопрос SO, я сохраняю файл _version.py, который я анализирую в setup.py. С помощью строки версии оттуда, тег git в setup.py. Затем я установил переменную версии установки в комбинацию строки версии плюс хэш-код git commit. Итак, вот соответствующая часть setup.py:

from setuptools import setup, find_packages
from codecs import open
from os import path
import subprocess

here = path.abspath(path.dirname(__file__))

import re, os
VERSIONFILE=os.path.join(here,"_version.py")
verstrline = open(VERSIONFILE, "rt").read()
VSRE = r"^__version__ = ['\"]([^'\"]*)['\"]"
mo = re.search(VSRE, verstrline, re.M)
if mo:
    verstr = mo.group(1)
else:
    raise RuntimeError("Unable to find version string in %s." % (VERSIONFILE,))
if os.path.exists(os.path.join(here, '.git')):
    cmd = 'git rev-parse --verify --short HEAD'
    git_hash = subprocess.check_output(cmd)
    # tag git
    gitverstr = 'v' + verstr
    tags =  subprocess.check_output('git tag')
    if not gitverstr in tags:
        cmd = 'git tag -a %s %s -m "tagged by setup.py to %s"' % (gitverstr, git_hash, verstr)        
        subprocess.check_output(cmd)
    # use the git hash in the setup
    verstr += ', git hash: %s' % git_hash

setup(
    name='a_package',
    version = verstr,
    ....

Ответ 4

Поскольку эта тема все еще жива и иногда попадает на результаты поиска, я хотел бы упомянуть еще одно решение, которое впервые появилось в 2012 году и теперь более или менее пригодно для использования:

https://github.com/warner/python-versioneer

Он работает по-разному, чем все упомянутые решения: вы добавляете теги git вручную, а библиотека (и setup.py) читает теги и динамически строит строку версии.

В строке версии содержится последний тег, расстояние от этого тега, текущий хеш-фиксация, "грязность" и другая информация. Он имеет несколько разных форматов.

Но у него по-прежнему нет имени ветки для так называемых "пользовательских сборок"; и расстояние фиксации иногда может сбивать с толку, когда две ветки основаны на одной и той же фиксации, поэтому лучше пометить и отпустить только одну выбранную ветвь (мастер).