能否让pip install --find-links使用下载的sdist进行--editable依赖?
使用以下命令:
pip install -r requirements.txt -d sdists/
你可以轻松创建一个项目所需的依赖包的归档文件,方便分发给其他人。如果你的依赖包列表看起来像这样:
Django==1.3.1
django-tagging==0.3.1
django-robots==0.6.1
那么你就可以在不接触PyPI(Python包索引)的情况下安装这些依赖包,方法如下:
pip install -r requirements.txt --find-links sdists/ --no-index
那么,是否可以用同样的方法来处理--editable
的依赖包呢?比如:
-e hg+https://bitbucket.org/ubernostrum/django-contact-form/@1d3791fa4dfb#egg=django-contact-form
根据我的观察,pip install -d
可以顺利下载可编辑的依赖包,并为你创建一个sdist(源代码分发包),但是pip install --find-links
没有办法将下载的sdist与依赖文件中的相应行匹配,所以它会忽略下载的sdist,继续像往常一样从版本控制系统(VCS)中检出代码。
1 个回答
4
虽然看起来用PIP直接做到这一点是不太可能的,但有一种变通的方法可以实现同样的效果。这个变通的方法是从原始的需求文件和sdists目录自动生成一个第二个需求文件(这个文件只用于那个目录)。
一个简单的实现可能像这样(把它保存为一个叫“make_reqs.py”的文件):
#!/usr/bin/env python
import re
import sys
import os.path
pat = '.+#egg=(.+)'
allowed_exts = ['.zip', '.tar.gz', 'tar.bz2']
def find_version(sdists_dir, name):
files = [f for f in os.listdir(sdists_dir) if f.startswith(name)]
if len(files) != 1:
return ''
version = files[0].replace(name+'-', '')
for ext in allowed_exts:
version = version.replace(ext, '')
return version
def get_requirements(file_name, sdists_dir):
out_reqs = ['--find-links file://%s' % os.path.abspath(sdists_dir)]
with open(file_name) as req_file:
reqs = [l.strip() for l in req_file.readlines()]
for req in reqs:
match = re.match(pat, req)
if match and not req.startswith('#'):
name = match.group(1)
version = find_version(sdists_dir, name)
if version:
out_reqs.append('%s==%s' % (name, version))
else:
out_reqs.append(req)
else:
out_reqs.append(req)
return out_reqs
if __name__ == '__main__':
print '\n'.join(get_requirements(*sys.argv[1:]))
要使用这个脚本,你可以这样做:
python make_reqs.py requirements.txt /path/to/sdists > sdist_reqs.txt
pip install --no-index -r sdist_reqs.txt