Sử dụng setuptools
vàpbr
Không có cách tiêu chuẩn để quản lý phiên bản, nhưng cách tiêu chuẩn để quản lý các gói của bạn là setuptools
.
Giải pháp tốt nhất tôi tìm thấy tổng thể để quản lý phiên bản là sử dụng setuptools
với pbr
tiện ích mở rộng. Đây là cách quản lý phiên bản tiêu chuẩn của tôi.
Thiết lập dự án của bạn để đóng gói đầy đủ có thể là quá mức cần thiết cho các dự án đơn giản, nhưng nếu bạn cần quản lý phiên bản, có lẽ bạn đang ở cấp độ phù hợp để chỉ thiết lập mọi thứ. Làm như vậy cũng làm cho gói của bạn đáng tin cậy tại PyPi để mọi người có thể tải xuống và sử dụng nó với Pip.
PBR chuyển hầu hết siêu dữ liệu ra khỏi các setup.py
công cụ và vào một setup.cfg
tệp sau đó được sử dụng làm nguồn cho hầu hết siêu dữ liệu, có thể bao gồm phiên bản. Điều này cho phép siêu dữ liệu được đóng gói thành một tệp thực thi bằng cách sử dụng một cái gì đó như pyinstaller
nếu cần (nếu vậy, bạn có thể sẽ cần thông tin này ) và tách siêu dữ liệu khỏi các tập lệnh thiết lập / quản lý gói khác. Bạn có thể trực tiếp cập nhật chuỗi phiên bản setup.cfg
theo cách thủ công và nó sẽ được kéo vào *.egg-info
thư mục khi xây dựng các bản phát hành gói của bạn. Tập lệnh của bạn sau đó có thể truy cập phiên bản từ siêu dữ liệu bằng nhiều phương pháp khác nhau (các quy trình này được nêu trong các phần bên dưới).
Khi sử dụng Git cho VCS / SCM, thiết lập này thậm chí còn tốt hơn, vì nó sẽ thu được rất nhiều siêu dữ liệu từ Git để repo của bạn có thể là nguồn sự thật chính của bạn cho một số siêu dữ liệu, bao gồm phiên bản, tác giả, thay đổi, v.v ... Đối với phiên bản cụ thể, nó sẽ tạo một chuỗi phiên bản cho cam kết hiện tại dựa trên các thẻ git trong repo.
Vì PBR sẽ lấy phiên bản, tác giả, thay đổi và thông tin khác trực tiếp từ repo git của bạn, do đó, một số siêu dữ liệu setup.cfg
có thể bị bỏ qua và tự động tạo bất cứ khi nào phân phối được tạo cho gói của bạn (sử dụng setup.py
)
Phiên bản hiện tại thời gian thực
setuptools
sẽ lấy thông tin mới nhất trong thời gian thực bằng cách sử dụng setup.py
:
python setup.py --version
Điều này sẽ lấy phiên bản mới nhất từ setup.cfg
tệp hoặc từ repo git, dựa trên cam kết mới nhất đã được thực hiện và các thẻ tồn tại trong repo. Lệnh này không cập nhật phiên bản trong một bản phân phối.
Cập nhật phiên bản
Khi bạn tạo phân phối với setup.py
(ví py setup.py sdist
dụ: chẳng hạn), thì tất cả thông tin hiện tại sẽ được trích xuất và lưu trữ trong phân phối. Điều này về cơ bản chạy setup.py --version
lệnh và sau đó lưu thông tin phiên bản đó vào package.egg-info
thư mục trong một tập hợp các tệp lưu trữ siêu dữ liệu phân phối.
Lưu ý về quy trình cập nhật dữ liệu meta phiên bản:
Nếu bạn không sử dụng pbr để lấy dữ liệu phiên bản từ git, thì chỉ cần cập nhật trực tiếp setup.cfg của bạn với thông tin phiên bản mới (đủ dễ, nhưng đảm bảo đây là một phần tiêu chuẩn của quy trình phát hành của bạn).
Nếu bạn đang sử dụng git và bạn không cần tạo phân phối nguồn hoặc nhị phân (sử dụng python setup.py sdist
hoặc một trong các python setup.py bdist_xxx
lệnh), cách đơn giản nhất để cập nhật thông tin git repo vào <mypackage>.egg-info
thư mục siêu dữ liệu của bạn là chỉ cần chạy python setup.py install
lệnh. Điều này sẽ chạy tất cả các hàm PBR liên quan đến việc lấy siêu dữ liệu từ git repo và cập nhật .egg-info
thư mục cục bộ của bạn , cài đặt các tệp thực thi tập lệnh cho bất kỳ điểm nhập nào bạn đã xác định và các chức năng khác bạn có thể thấy từ đầu ra khi bạn chạy lệnh này.
Lưu ý rằng .egg-info
thư mục thường được loại trừ khỏi việc được lưu trữ trong chính git repo trong các .gitignore
tệp Python tiêu chuẩn (chẳng hạn như từ Gitignore.IO ), vì nó có thể được tạo từ nguồn của bạn. Nếu nó bị loại trừ, hãy đảm bảo bạn có "quy trình phát hành" tiêu chuẩn để cập nhật siêu dữ liệu cục bộ trước khi phát hành và bất kỳ gói nào bạn tải lên PyPi.org hoặc phân phối khác phải bao gồm dữ liệu này để có phiên bản chính xác. Nếu bạn muốn repo Git chứa thông tin này, bạn có thể loại trừ các tệp cụ thể khỏi bị bỏ qua (tức là thêm !*.egg-info/PKG_INFO
vào .gitignore
)
Truy cập phiên bản từ tập lệnh
Bạn có thể truy cập siêu dữ liệu từ bản dựng hiện tại trong các tập lệnh Python trong chính gói đó. Ví dụ, đối với phiên bản, có một số cách để làm điều này tôi đã tìm thấy cho đến nay:
## This one is a new built-in as of Python 3.8.0 should become the standard
from importlib-metadata import version
v0 = version("mypackage")
print('v0 {}'.format(v0))
## I don't like this one because the version method is hidden
import pkg_resources # part of setuptools
v1 = pkg_resources.require("mypackage")[0].version
print('v1 {}'.format(v1))
# Probably best for pre v3.8.0 - the output without .version is just a longer string with
# both the package name, a space, and the version string
import pkg_resources # part of setuptools
v2 = pkg_resources.get_distribution('mypackage').version
print('v2 {}'.format(v2))
## This one seems to be slower, and with pyinstaller makes the exe a lot bigger
from pbr.version import VersionInfo
v3 = VersionInfo('mypackage').release_string()
print('v3 {}'.format(v3))
Bạn có thể đặt một trong những thứ này trực tiếp trong __init__.py
gói của bạn để trích xuất thông tin phiên bản như sau, tương tự như một số câu trả lời khác:
__all__ = (
'__version__',
'my_package_name'
)
import pkg_resources # part of setuptools
__version__ = pkg_resources.get_distribution("mypackage").version