简体   繁体   English

使用 setup.py 从 git at tag 安装 python 包

[英]Installing python package from git at tag with setup.py

I have a package (foo) in a private git repo.我在私有 git 仓库中有一个包 (foo)。 I want to install foo for use by another package, bar, via bar's setup.py.我想通过 bar 的 setup.py 安装 foo 以供另一个包 bar 使用。 I want a specific version - the versioning in setup.py for foo matches its git tags (0.3.2, the git tag is v0.3.2)我想要一个特定的版本 - setup.py 中 foo 的版本匹配它的 git 标签(0.3.2,git 标签是 v0.3.2)

The setup.py for bar looks like this: bar 的 setup.py 如下所示:

#!/usr/bin/env python
  
from setuptools import setup, find_packages

setup(name='bar',
        install_requires=['foo@ git+ssh://git@github.com/fergusmac/foo.git@v0.3.2#subdirectory=somedir']
    )

I have also tried added the version explicitly at the end:我还尝试在最后明确添加版本:

install_requires=['foo@ git+ssh://git@github.com/fergusmac/foo.git@v0.3.2#subdirectory=somedir==0.3.2']

I currently have version 0.3.1 installed in my venv.我目前在我的 venv 中安装了 0.3.1 版。 When I try to install this setup.py, via pip install .当我尝试通过pip install .安装这个 setup.py 时pip install . , or pip install . -U , 或pip install . -U pip install . -U the version isn't upgraded - the repo isn't even checked out: pip install . -U版本没有升级 - repo 甚至没有签出:

Requirement already satisfied, skipping upgrade: foo@ git+ssh://git@github.com/fergusmac/foo.git@v0.3.2#subdirectory=src==0.3.2 from 
git+ssh://****@github.com/fergusmac/foo.git@v0.3.2#subdirectory=src==0.3.2 in 
./venv/lib/python3.8/site-packages (from bar==0.0.0) (0.3.1)

However, when I use pip to install foo directly, the upgrade is done:但是,当我直接使用pip安装foo时,升级就完成了:

pip install git+ssh://git@github.com/fergusmac/foo.git@v0.3.2#subdirectory=src

Collecting git+ssh://****@github.com/fergusmac/foo.git@v0.3.2#subdirectory=src
  Cloning ssh://****@github.com/fergusmac/foo.git (to revision v0.3.2) to /tmp/pip-req-build-gxj2duq6
  Running command git clone -q 'ssh://****@github.com/fergusmac/foo.git' /tmp/pip-req-build-gxj2duq6
  Running command git checkout -q 40fa65eb75fc26541c90ee9e489ae6dd5538db1f
  Running command git submodule update --init --recursive -q
...
Installing collected packages: foo
  Attempting uninstall: foo
    Found existing installation: foo0.3.1
    Uninstalling foo-0.3.1:
      Successfully uninstalled foo-0.3.1
    Running setup.py install for foo... done
Successfully installed foo-0.3.2

I can't understand why installing with setup.py gives different behaviour.我不明白为什么用 setup.py 安装会产生不同的行为。 How do I ensure that it checks out the repo and looks for the correct version?我如何确保它检查回购并寻找正确的版本?

Follow up question - how would I specify 'check master branch for foo and install whatever version is there if it is higher than the current installed version'?后续问题 - 我将如何指定“检查 foo 的主分支并安装任何版本,如果它高于当前安装的版本”?

You're asking a precise and valid question, but I'm not confident that a satisfying answer will come.你问的是一个准确而有效的问题,但我不相信会出现令人满意的答案。 I'm not sure why what you're doing isn't working, but using direct URL dependencies with pip and setuptools is a new and rather complicated feature, and is possibly buggy/lacking on setuptools' side.我不确定为什么您所做的不起作用,但是使用 pip 和 setuptools 的直接 URL 依赖项是一个新的且相当复杂的功能,并且在 setuptools 方面可能存在错误/缺乏。

What I assume you want to do is have the package foo as a dependencies of bar - you don't actually need to use the PEP 508 direct URL specifier format.我假设您想要做的是将包foo作为bar的依赖项 - 您实际上不需要使用PEP 508直接 URL 说明符格式。 Instead you can provide either pip or setuptools with (relative) paths as dependency specifiers, and then use Git submodules to populate those paths.相反,您可以提供带有(相对)路径作为依赖项说明符的pipsetuptools ,然后使用 Git 子模块来填充这些路径。 For example:例如:

git submodule add git@github.com/fergusmac/foo.git
pip install ./foo

This will install whatever revision of foo was checked out when you added the submodule.这将安装您添加子模块时检出的 foo 的任何版本。 As this answer explains, you can change the checked-out revision of the submodule and then install it like so:正如这个答案所解释的,您可以更改子模块的检出版本,然后像这样安装它:

cd foo
git checkout v0.3.2
cd ..
pip install ./foo

For setuptools you can specify it like this:对于 setuptools,您可以像这样指定它:

from pathlib import Path

...

setup(
    name='bar',
    install_requires=[
        f'foo @ file://localhost/{Path(__file__).parent}/foo/',
    ],
)

Path(__file__).parent is the directory containing bar's setup.py file. Path(__file__).parent是包含 bar 的setup.py文件的目录。 The path that follows that bit (eg /foo/ in this case) should be the location of foo's submodule relative to the directory containing bar's setup.py file.该位/foo/的路径(例如/foo/在这种情况下)应该是 foo 的子模块相对于包含 bar 的setup.py文件的目录的位置。


Follow up question - how would I specify 'check master branch for foo and install whatever version is there if it is higher than the current installed version'?后续问题 - 我将如何指定“检查 foo 的主分支并安装任何版本,如果它高于当前安装的版本”?

Checkout master in the submodule, then install via pip install --upgrade .在子模块中签出master ,然后通过pip install --upgrade . (assuming . is the project directory for bar). (假设.是 bar 的项目目录)。


See also: https://softwareengineering.stackexchange.com/a/365583/271937另见: https : //softwareengineering.stackexchange.com/a/365583/271937

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM