首先,让我们澄清pipenv install 命令只是pip 的包装。如果您使用--verbose 安装,您会发现它也只是使用pip install 并将软件包放在同一个激活的虚拟环境中。所以回答
我正在查看文档 https://pipenv.pypa.io/ 以了解当您运行 pip install 而不是 pipenv install 时实际发生了什么(即使是错误的)
只是pipenv-特定操作将不会完成。这包括更新 Pipfile 和 Pipfile.lock(这是首先使用 pipenv 的主要原因之一)以获得确定性构建。 Pipfile 你可以手动更新自己,但是对于 Pipfile.lock...你不能。
如果您运行 pipenv graph,它实际上会显示通过 pip 安装的包!
是的,因为正如我所说,他们都只使用pip。这两种方法都会将包安装在同一个虚拟环境中,pipenv graph 只是检查 same 环境。包将存储在lib/pythonX.Y/site-packages 下的文件夹中,无论是pipenv 还是普通pip。
现在开始你的实际问题:
但是我需要做些什么才能使这些反映在 Pipfile 中?
D Malan's comment of using pipenv clean 是一个好方法。来自文档:
$ pipenv clean --help
Usage: pipenv clean [OPTIONS]
Uninstalls all packages not specified in Pipfile.lock.
Options:
--bare Minimal output.
--dry-run Just output unneeded packages.
...
如上所述,您只需运行该命令即可检查是否存在不一致。添加--dry-run 命令以便它只报告,而不是实际上 卸载它们。
然后你可以为此编写一个脚本,比如这个 Bash 脚本:
#!/usr/local/bin/bash
echo "Checking if there are packages in venv not in Pipfile.lock"
# Get packages pipenv did not find in Pipfile.lock
# NOTE:
# Here, mapfile requires Bash 4.x syntax
# For alternatives: https://stackoverflow.com/a/32931403/2745495
mapfile -t packages < <(pipenv clean --dry-run)
if [ ${#packages[@]} -eq 0 ]; then
echo "All good!"
else
echo "Found ${#packages[@]} not in Pipfile.lock!"
for pkg in "${packages[@]}"; do
echo " ${pkg}"
done
echo ""
echo "Check if they need to be 'pipenv install'-ed or deleted with 'pipenv clean'"
# Make sure script exits with a non-zero code here
exit 1
fi
在带有pip install-ed 包(例如 mypy)和pipenv install-ed 包(例如 flake8)的测试环境中运行它:
(my-test-repo) $ pipenv graph
flake8==3.8.4
- mccabe [required: >=0.6.0,<0.7.0, installed: 0.6.1]
- pycodestyle [required: >=2.6.0a1,<2.7.0, installed: 2.6.0]
- pyflakes [required: >=2.2.0,<2.3.0, installed: 2.2.0]
mypy==0.790
- mypy-extensions [required: >=0.4.3,<0.5.0, installed: 0.4.3]
- typed-ast [required: >=1.4.0,<1.5.0, installed: 1.4.1]
- typing-extensions [required: >=3.7.4, installed: 3.7.4.3]
(my-test-repo) $ cat Pipfile.lock | grep mypy
(my-test-repo) $ ./check.sh
Checking if there are packages in venv not in Pipfile.lock
Found 4 not in Pipfile.lock!
typing-extensions
typed-ast
mypy
mypy-extensions
Check if they need to be 'pipenv install'-ed or deleted with 'pipenv clean'
(my-test-repo) $ pipenv install mypy
...
✔ Success!
Updated Pipfile.lock (e60379)!
Installing dependencies from Pipfile.lock (e60379)...
? ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 0/0 — 00:
(my-test-repo) $ ./check.sh
Checking if there are packages in venv not in Pipfile.lock
All good!
解决问题
您可能会使用此 Pipfile.lock 进行部署,以为您拥有所需的一切,而实际上您缺少包。
如果您使用 Git,请将脚本作为您的 git pre-commit hook 的一部分。
预提交钩子首先运行,甚至在您输入提交消息之前。它用于检查即将提交的快照、查看是否忘记了某些内容、确保测试运行或检查代码中需要检查的任何内容。 从这个钩子中退出非零值会中止提交,尽管您可以使用git commit --no-verify 绕过它。
(my-test-repo) $ cp check.sh .git/hooks/pre-commit
(my-test-repo) $ chmod +x .git/hooks/pre-commit
(my-test-repo) $ git add .
(my-test-repo) $ git commit
Checking if there are packages in venv not in Pipfile.lock
Found 4 not in Pipfile.lock!
typing-extensions
mypy
mypy-extensions
typed-ast
Check if they need to be 'pipenv install'-ed or deleted with 'pipenv clean'
(my-test-repo) $
发现不一致时会中止提交,从而防止您提交可能不完整的 Pipfile.lock。