μ κ·Έμ§ μκ³ κΈ°μ‘΄ Pipfile.lock
μμ requirements.txt
νμΌμ μμ±νλ λ°©λ²μ 무μμ
λκΉ?
pipenv lock -r
λ₯Ό μ€ννλ©΄ κΈ°μ‘΄ Pipfile.lock
λ₯Ό 무μνκ³ λ€μ μ κΈ νλ‘μΈμ€λ₯Ό μνν©λλ€.
μ΄μ λν ν΄κ²° λ°©λ²μ΄ μμ΅λλ€.
$ pipenv sync
$ pipenv run pip freeze
λ΄ νΉμ μν©μμ λλ λ컀 μ΄λ―Έμ§λ₯Ό λ§λ€κ³ requirements.txt
in Dockerfile
λ₯Ό μ¬μ©νκ³ μμ΅λλ€. requirements.txt
λ₯Ό μμ±ν μ μλλ‘ νΈμ€νΈ λ¨Έμ μ κ°μ νκ²½μ μμ±νλ κ²μ νΌνκ³ μΆμ΅λλ€.
Pipenvλ μ΄μ λν λ°©λ²μ μ 곡νμ§ μμ΅λλ€. pipfile-requirements μ κ°μ λ€λ₯Έ pipfile μ νΈλ¦¬ν° λΌμ΄λΈλ¬λ¦¬λ₯Ό μ°Ύμ μ μμ΅λλ€.
λΉμ μ μ€νν μ μμ΅λλ€
pipenv run pip freeze > requirements.txt
λΉμ μ μ€νν μ μμ΅λλ€
pipenv run pip freeze > requirements.txt
κ·Έκ²μ΄ 첫 λ²μ§Έ κ²μλ¬Όμμ ν΄κ²° λ°©λ²μΌλ‘ μΈκΈ ν κ²μ λλ€.
κ·Έλ¬λ μ΄κ²μ pipenv νκ²½μ΄ λκΈ°νλ κ²½μ°μλ§ μλν©λλ€(λͺ¨λ ν¨ν€μ§κ° μ€μΉλ¨).
Pipfile.lock
μμ μ§μ μ’
μμ±μ μΆμΆνλ κ²μ΄ λ νΈλ¦¬ν©λλ€.
jq -r '.default
| to_entries[]
| .key + .value.version' \
Pipfile.lock > requirements.txt
LOL, λλ μ΄λ―Έ κ·Έ λΌμ΄λΈλ¬λ¦¬μ λν΄ μΈκΈνμ΅λλ€.
μ λ κ°μΈμ μΌλ‘ μ μ© λΌμ΄λΈλ¬λ¦¬κ° μλ κ²μ μ«μ΄ν©λλ€. λν νμμ΄ μ΄λ―Έ jq
λλ κΈ°ν λ²μ© λꡬλ₯Ό μ€μΉνμ κ°λ₯μ±μ΄ λ λμ΅λλ€.
λΉμ μ μ¬μ§μ΄ μ€νν μ μμ΅λλ€
pipenv lock --requirements > requirements.txt
λ΄κ° μ΄ κ²μ²λΌ μμλλ‘ μλνμ§ μμ΅λλ€.
pipenv lock -r
λ₯Ό μ€ννλ©΄ κΈ°μ‘΄Pipfile.lock
λ₯Ό 무μνκ³ λ€μ μ κΈ νλ‘μΈμ€λ₯Ό μνν©λλ€.
μ¦, μ
λ°μ΄νΈλ₯Ό μννμ¬ μ μ¬μ μΌλ‘ λ°°ν¬λ₯Ό νκ΄΄ν μ μμ΅λλ€. requirements.txt
λ₯Ό μμ±νμ¬ Dockerfileμμ λ컀 μ΄λ―Έμ§λ₯Ό λΉλνλ λ° μ¬μ©νλ€κ³ μμν΄ λ³΄μμμ€. μμ© νλ‘κ·Έλ¨μ λ‘컬μμ μλνμ§λ§ pipenv lock
#$ λ₯Ό μ¬μ©νμ¬ $ requirements.txt
λ₯Ό μμ±νλ©΄ μꡬ μ¬νμ΄ νΈνλμ§ μκ±°λ μμλ λ²μ μΌλ‘ μ
λ°μ΄νΈλ μ μμ΅λλ€(ν¬κ·ν κ²½μ°μ΄μ§λ§). κ·Έλ¦¬κ³ λΉμ μ μ΄λ―Έμ§λ₯Ό μ€ννκΈ° μ μ μ΄κ²μ μμ§ λͺ»ν κ²μ
λλ€. λ°λΌμ pipenv lock
λ₯Ό μ€νν ν μ±μ λ€μ ν
μ€νΈν΄μΌ ν©λλ€.
jq
λ₯Ό μ¬μ©νμ§ μμΌλ €λ©΄ pipenv sync
(μ
λ°μ΄νΈνμ§ μμ)λ‘ μ²« λ²μ§Έ κ²μλ¬Όμμ μ μν μ κ·Ό λ°©μμ μ¬μ©νλ κ²μ΄ μ’μ΅λλ€.
@Zebradil κ·νμ jq
oneliner μ κ·Ό λ°©μμ μ΄λ―Έ jq
λ₯Ό μ€μΉνκΈ° λλ¬Έμ @frostming μ체 pipfile-requirements
ν¨ν€μ§(100κ° μ΄μμ λΌμΈ νμ΄μ¬ μ½λ)λ³΄λ€ ν¨μ¬ κ°λ¨ν©λλ€. λ€λ₯Έ μ’
μμ±μ μμ΅λλ€. νμμ
λλ€. νλ₯ν©λλ€.
κ·Έλ¬λ λͺ κ°μ§ git μ»€λ° νμ pipenv lock --requirements
μΆλ ₯κ³Ό jq
Pipfile.lock
νμΌμ ν΅ν΄ μμ§νκ³ μΆλ ₯νλ κ²μ μ°¨μ΄μ μ λ°κ²¬νμ΅λλ€.
jq
μΆλ ₯μλ -i https://pypi.org/simple
κ° λ§¨ μ²μ νμΌλ‘ ν¬ν¨λμ§ μκ³ pipenv lock --r
κ° νμ 맨 μ²μ νμΌλ‘ μ½μ
λλ κ²κ³Όλ λμ‘°μ μ
λλ€.jq
μΆλ ₯μλ ν¨ν€μ§μ λν μ£Όμμ΄ ν¬ν¨λμ§ μμ΅λλ€. μ: pipenv lock --r
μΆλ ₯μλ appnope==0.1.0 ; sys_platform == 'darwin'
νμ΄ μμ§λ§ jq
μΆλ ₯μμλ appnope==0.1.0
μ
λλ€. λ λ€λ₯Έ μλ pipenv lock -r
κ° pexpect==4.7.0 ; sys_platform != 'win32'
$λ₯Ό μμ±νλ λ°λ©΄ jq
λ pexpect==4.7.0
$λ₯Ό μμ±νλλ° μ΄κ²μ΄ μ€μνμ§ μλμ§ νμ€νμ§ μμ΅λλ€.jq
Pipfile.lock
νμΌμμ ν¨ν€μ§ μμλ₯Ό μ·¨νλ κ²μΌλ‘ μΆμ λλ©° νμ μνλ²³κ³Ό λ¬Έμ κΈΈμ΄μ μ€λ¦μ°¨μμΌλ‘ μ λ ¬λ©λλ€. μλ₯Ό λ€μ΄ flask
λ flask-sqlalchemy
μμ μμ΅λλ€. flask-XXXXX
ν¨ν€μ§μΈ λ°λ©΄ pipenv lock --r
$ λ flask-sqlalchemy
flask
$ λ₯Ό μΆλ ₯ν©λλ€. μ΄λ Pipfile.lock
μ μμμ λ€λ¦
λλ€. μ΄κ²μ μ΅μ git diffλ₯Ό μμ±νμ§ μκΈ° λλ¬Έμ μ£Όμ μ±κ°μ¬μ
λλ€. λλ μ΄κ²μ΄ pipenv
μ λ²κ·ΈλΌκ³ μκ°ν©λλ€.μλ νμΈμ @yeλ , λ°©λ²μ μ λΉκ΅νμ΅λλ€. μ¬λλ€μ΄ νΉμ μν©μ μ ν©ν μ루μ μ μ ννκ³ κ²½κ³ λ₯Ό νΌνλ λ° λμμ΄ λ μ μμ΅λλ€.
λ€, λ§μνμ κ²μ²λΌ jq
λ‘ μ μλ μ κ·Ό λ°©μμ κΈ°λ₯μ΄ μ νμ μ
λλ€. μ£Όμ λ° ν¨ν€μ§ μμΈ URLμ μΆκ°νλλ‘ νμ₯ν μ μμ§λ§ μ§κΈμ κ·Έλ΄ νμκ° μμ΅λλ€.
μμ±λ requirements.txtμ μ°¨μ΄κ° λ°μνμ§ μλλ‘ νλ €λ©΄ λ§€λ² λμΌν μ κ·Ό λ°©μμ μ¬μ©νλ κ²μ κ³ λ €ν΄μΌ ν©λλ€. λΉμ·ν λ°©μμΌλ‘ λ€λ₯Έ μ½λ μμ μ§μ λꡬλ₯Ό μ¬μ©νλ©΄ κ²°κ³Όκ° μΌκ΄λμ§ μμ μ μμ΅λλ€. κ·Έλμ μ λ μ¬κΈ°μ λ¬Έμ κ° μλ€κ³ λ΄ λλ€.
λΉμ μ μ€νν μ μμ΅λλ€
pipenv run pip freeze > requirements.txt
κ·Έκ²μ΄ 첫 λ²μ§Έ κ²μλ¬Όμμ ν΄κ²° λ°©λ²μΌλ‘ μΈκΈ ν κ²μ λλ€.
κ·Έλ¬λ μ΄κ²μ pipenv νκ²½μ΄ λκΈ°νλ κ²½μ°μλ§ μλν©λλ€(λͺ¨λ ν¨ν€μ§κ° μ€μΉλ¨).
Pipfile.lock
μμ μ§μ μ’ μμ±μ μΆμΆνλ κ²μ΄ λ νΈλ¦¬ν©λλ€.jq -r '.default | to_entries[] | .key + .value.version' \ Pipfile.lock > requirements.txt
μλ ,
μ루μ
μ κ°μ¬λ립λλ€. λλ κ°μ λ¬Έμ μ λΆλͺμ³€μ§ pipenv lock -r
μ μν΄ μμ±λ μμ€μ μ μλ νμν©λλ€. μ: -i, --extra-index-url. κ°μΈ μμ€λ‘ μμ
νκΈ° λλ¬Έμ
λλ€.
@Zebradil λ§μνμ κ² κ°μλ°μ.
κ·Έλμ νμ΄μ¬μμ ν΄λΉ κΈ°λ₯μ ν¬ν¨νλ λ λ€λ₯Έ μ΅μν μ μ’ μμ± μλ μ€ν¬λ¦½νΈλ₯Ό λ§λ€μμ΅λλ€. λν Pipfileμμ μμ€λ₯Ό κ·Έλ κ² μ μν κ²½μ° env varsλ₯Ό νμ₯ν©λλ€.
λꡬλ μ§ μ΄ν΄λ³΄κ³ μΆλ€λ©΄ μ¬κΈ°μ λ¨κ²¨ λκ² μ΅λλ€. https://gist.github.com/rcastill/dab85c234dd10fa7af56755116c75aee
λ€λ₯Έ μ¬λμκ² λμμ΄ λλ κ²½μ° κ²°κ³Όμ ν΄μλ₯Ό ν¬ν¨νλ λ°©λ²μ λ€μκ³Ό κ°μ΅λλ€.
jq --raw-output '.default | to_entries[] | .key + .value.version + (.value.hashes | map(" --hash=\(.)") | join(""))' Pipfile.lock
μ΄λ κ² νλ©΄ λ€μκ³Ό κ°μ νλͺ©μ΄ μμ±λ©λλ€.
paramiko==2.6.0 --hash=sha256:99f0179bdc176281d21961a003ffdb2ec369daac1a1007241f53374e3766576cf --hash=sha256:f4b2edfa0d226b
pip
κ° ν΄μλ₯Ό μ μ©νλλ‘ ν©λλ€.
μλ μꡬ μ¬ν νμΌμ μλ μꡬ μ¬νλ§ ν¬ν¨νλ €λ κ²½μ°( ==
λ₯Ό μ¬μ©νμ¬ νΉμ λ²μ μ μ΄λ―Έ μ 겨 μλ κ²½μ°):
jq --raw-output '.default | to_entries[] | .key + .value.version + (.value.hashes | map(" --hash=\(.)") | join(""))' Pipfile.lock | grep --file=<(grep --only-matching --perl-regexp '^.*(?===)' requirements.txt | tr '[:upper:]' '[:lower:]') > new.txt && mv new.txt requirements.txt
tr
λ requirements.txt νμΌμ λμλ¬Έμκ° νΌν©λ ν¨ν€μ§ μ΄λ¦μ΄ ν¬ν¨λ μ μμ§λ§ Pipfileμμ pipenv install -r requirements.txt
κ° μλ¬Έμμ΄κΈ° λλ¬Έμ νμν©λλ€.
λ€μμ Pipfile
(μ κΈ νμΌ μλ)λ₯Ό requirements.txt νμΌλ‘ λ³ννλ €λ κ²½μ°λ₯Ό μν μμ νμ΄μ¬ μ€ν¬λ¦½νΈμ
λλ€.
import configparser
def main():
parser = configparser.ConfigParser()
parser.read("Pipfile")
packages = "packages"
with open("requirements.txt", "w") as f:
for key in parser[packages]:
value = parser[packages][key]
f.write(key + value.replace("\"", "") + "\n")
if __name__ == "__main__":
main()
@frostming μλ νμΈμ, https://github.com/frostming/pipfile-requirements κ° μ μ©νμ§λ§ μ pipenvμ ν΅ν©λμ§ μμμ΅λκΉ?
@linusguan μ΄ λꡬλ ν° pipenv λΌμ΄λΈλ¬λ¦¬λ₯Ό μ€μΉνκ³ μΆμ§ μμ μ¬λλ€μ μν΄ μ‘΄μ¬ν©λλ€. pipenvλ₯Ό μ€μΉν λ pipenv lock -r
λ₯Ό μ¬μ©ν μ μμ΅λλ€.
@frostming pipfile.lock μ μ§μνμ§ μλ λ€λ₯Έ λꡬμ ν¨κ» μ¬μ©νλ κ²μ΄ λ§€μ° μ μ©νλ€λ κ²μ μμμ΅λλ€.
pipenv lock -r
μ λ¬Έμ λ pipfile.lockμ μ
λ°μ΄νΈνλ―λ‘ λ€λ₯Έ λꡬμ ν¨κ» κ²°μ μ λΉλλ₯Ό μμ±νλ λ° μ¬μ©ν μ μλ€λ κ²μ
λλ€. pipenv lock -r --ignore-pipfile
μ κ°μ κ²μ΄ μ΄μμ μ
λλ€.
λ€μμ ν΄μκ° μλ Pipfile.lock νμΌμμ requirements.txtλ₯Ό μμ±νλ λ λ€λ₯Έ νμ΄μ¬ μ€ν¬λ¦½νΈμ λλ€.
import os
import json
__dir__ = os.path.dirname(os.path.realpath(__file__))
def read_json_file(path):
with open(path) as f:
return json.load(f)
def main():
root = read_json_file(os.path.join(__dir__, 'Pipfile.lock'))
for name, pkg in root["default"].items():
version = pkg["version"]
sep = lambda i: "" if i == len(pkg["hashes"]) - 1 else " \\"
hashes = [f'--hash={t}{sep(i)}' for i, t in enumerate(pkg["hashes"])]
tail = '' if len(hashes) == 0 else f' {hashes[0]}'
print(f'{name} {version}{tail}')
for h in hashes[1:]:
print(f' {h}')
if __name__ == "__main__":
main()
@Zebradil κ°μ¬ν©λλ€! κ·νμ μ루μ μ μ λ§ μ μκ² ν¨κ³Όμ μ΄μμ΅λλ€.
brew install jq
λ₯Ό μ¬μ©νμ¬ $ jq
λꡬλ₯Ό μ€μΉν©λλ€.Pipfile.lock
requirements.txt
λ₯Ό μμ±νμ΅λλ€.--keep-outdated
νλκ·Έλ‘ ν΄κ²°ν μ μλ κ² κ°μ΅λλ€. μλλ©΄ μ κ° μλͺ» μκ³ μλ κ²μ
λκΉ?
pipenv lock --keep-outdated -d -r > requirements.txt
μΆμ : μ΄ λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν΄ μ§μ¦λκ² μ₯ν©ν νλκ·Έμ λλ€.
λΆννλ @jacobisaliveandwell --keep-outdated νλκ·Έκ° νμ μ’ μμ±μ μ λ°μ΄νΈνλ κ²μΌλ‘ λνλ©λλ€. https://github.com/pypa/pipenv/issues/3975
@paytonrules λ²κ·Έμ§λ§ νλκ·Έμ μ μ μ μ¬μ ν ββμ΄ λ¬Έμ μ λν λ΅μ λλ€.
μΆμ : κ·Έκ²μ λν΄ μμ§μκ°λ½μ μΉμΈ νμκ° μμ΅λλ€ :-(
λͺ
μλ ν΄κ²° λ°©λ²κ³Ό μ°¨μ΄μ μ΄ μμμ μΈκΈνκ³ μΆμ΅λλ€.
pipenv run pip freeze
λ λμλ¬Έμλ₯Ό ꡬλΆνλ ν¨ν€μ§ μ΄λ¦μ λ°νν©λλ€(μ: PyYAML
).
pipenv lock --requirements
λ λͺ¨λ μλ¬Έμ ν¨ν€μ§ μ΄λ¦μ λ°νν©λλ€(μ: pyyaml
).
@Darkless012 μ΄λ₯Ό μ€λͺ νλ λ€λ₯Έ ν°μΌμ μ΄κ³ μ΄ λ¬Έμ λ₯Ό κ΄λ ¨μΌλ‘ μ°Έμ‘°ν΄μΌ ν©λλ€.
λκ΅°κ°κ° jqλ₯Ό μ€μΉν μ μκ±°λ μ€μΉνκΈ°λ₯Ό μνμ§ μλ κ²½μ°λ₯Ό λλΉνμ¬ μμν bash, ν¨ν€μ§λ§, λ€λ₯Έ κ²μ μμ΅λλ€.
cat Pipfile.lock \
| grep -B1 '"hashes"\|"version": ' \
| grep -v '"markers": \|"hashes": ' \
| grep ": {\|version" \
| sed -e 's/: {$//g' \
| tr '\n' ',' | tr -s ' ' ' ' \
| sed -e 's/, "version": "//g;s/", "/ /g;s/"//g;s/,//g' \
| tr ' ' '\n' \
| grep -v "^$" > requirements.txt
pip install --require-hashes
κ° μλνλλ‘ Pipfileμ ν΄μλ₯Ό requirements.txt(μ: νλ«νΌ strκ³Ό κ°μ κ²μΌλ‘ μ 곡)λ‘ λ³΅μ¬νλ κ²μ΄ μμ΅λκΉ?
$ pip install --help
# ...
--require-hashes Require a hash to check each requirement against, for repeatable installs. This option is implied when any package in a
requirements file has a --hash option.
Pipenv.lock(poety.lockλ ν¬ν¨) νμΌμ requirements.txt(raw requirements.txt λλ pip-tools νΈν κ°λ₯)λ‘ λ³νν μ μλ micropipenvλ₯Ό μ¬μ©ν μ μμ΅λλ€. https://github.com/thoth-station/micropipenv/#micropipenv -requirements--micropipenv-req μ°Έμ‘°
κ°μ₯ μ μ©ν λκΈ
λΉμ μ μ€νν μ μμ΅λλ€