Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
后端镜像
Pdm
提交
ce0478fc
P
Pdm
项目概览
后端镜像
/
Pdm
通知
0
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Pdm
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
ce0478fc
编写于
1月 19, 2020
作者:
F
frostming
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
write tests for update and remove
上级
57068eac
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
465 addition
and
91 deletion
+465
-91
pdm.lock
pdm.lock
+150
-33
pdm/cli/actions.py
pdm/cli/actions.py
+98
-17
pdm/cli/commands.py
pdm/cli/commands.py
+11
-12
pdm/installers.py
pdm/installers.py
+6
-4
pdm/project/__init__.py
pdm/project/__init__.py
+1
-1
pyproject.toml
pyproject.toml
+1
-1
tests/cli/test_actions.py
tests/cli/test_actions.py
+198
-23
未找到文件。
pdm.lock
浏览文件 @
ce0478fc
...
...
@@ -5,18 +5,6 @@ version = "19.3.1"
marker = "python_version >= \"2.7\" and python_version not in \"3.0, 3.1, 3.2, 3.3, 3.4\""
summary = "The PyPA recommended tool for installing Python packages."
[[package]]
name = "parver"
sections = ["default"]
version = "0.2.1"
marker = "python_version >= \"2.7\" and python_version not in \"3.0, 3.1, 3.2, 3.3\""
summary = "Parse and manipulate version numbers."
[package.dependencies]
arpeggio = "~=1.7"
attrs = ">=17.4.0"
six = "~=1.9"
[[package]]
name = "appdirs"
sections = ["default"]
...
...
@@ -147,13 +135,6 @@ summary = "TextUI colors for Python."
[package.dependencies]
colorama = "*"
[[package]]
name = "arpeggio"
sections = ["default"]
version = "1.9.2"
marker = "python_version >= \"2.7\" and python_version not in \"3.0, 3.1, 3.2, 3.3\""
summary = "Packrat parser interpreter"
[[package]]
name = "attrs"
sections = ["default", "dev"]
...
...
@@ -161,13 +142,6 @@ version = "19.3.0"
marker = "python_version >= \"2.7\""
summary = "Classes Without Boilerplate"
[[package]]
name = "six"
sections = ["default", "dev"]
version = "1.14.0"
marker = "python_version >= \"2.7\" and python_version not in \"3.0, 3.1, 3.2\""
summary = "Python 2 and 3 compatibility utilities"
[[package]]
name = "atomicwrites"
sections = ["dev"]
...
...
@@ -207,12 +181,19 @@ summary = "More routines for operating on iterables, beyond itertools"
name = "importlib-metadata"
sections = ["dev"]
version = "1.4.0"
marker = "python_version
>= \"3.5\" and python_version < \"3.8
\""
marker = "python_version
< \"3.8\" and python_version >= \"3.5
\""
summary = "Read metadata from Python packages"
[package.dependencies]
zipp = ">=0.5"
[[package]]
name = "six"
sections = ["default", "dev"]
version = "1.14.0"
marker = "python_version >= \"2.7\" and python_version not in \"3.0, 3.1, 3.2\""
summary = "Python 2 and 3 compatibility utilities"
[[package]]
name = "vistir"
sections = ["default"]
...
...
@@ -267,7 +248,7 @@ summary = "Easily download, build, install, upgrade, and uninstall Python packag
name = "zipp"
sections = ["dev"]
version = "1.0.0"
marker = "python_version
>= \"3.5\" and python_version < \"3.8
\""
marker = "python_version
< \"3.8\" and python_version >= \"3.5
\""
summary = "Backport of pathlib-compatible object wrapper for zip files"
[package.dependencies]
...
...
@@ -288,16 +269,152 @@ marker = "python_version >= \"2.7\" and python_version not in \"3.0, 3.1, 3.2\""
summary = "Python parsing module"
[metadata]
"pip 19.3.1" = [
{file = "pip-19.3.1-py2.py3-none-any.whl", hash = "sha256:6917c65fc3769ecdc61405d3dfd97afdedd75808d200b2838d7d961cebc0c2c7"},
{file = "pip-19.3.1.tar.gz", hash = "sha256:21207d76c1031e517668898a6b46a9fb1501c7a4710ef5dfd6a40ad9e6757ea7"},
"appdirs 1.4.3" = [
{file = "appdirs-1.4.3.tar.gz", hash = "sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92"},
{file = "appdirs-1.4.3-py2.py3-none-any.whl", hash = "sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e"},
]
"pip-shims 0.4.0" = [
{file = "pip_shims-0.4.0-py2.py3-none-any.whl", hash = "sha256:d4b720d85a8cbd81f72ea22e273ac72415f1e0b49cade597b815c63b351d9637"},
{file = "pip_shims-0.4.0.tar.gz", hash = "sha256:383e054386d15f7a33d619a9fc19d670575cdf88e05a4dab93f0a254696ce836"},
]
"distlib 0.3.0" = [
{file = "distlib-0.3.0.zip", hash = "sha256:2e166e231a26b36d6dfe35a48c4464346620f8645ed0ace01ee31822b288de21"},
]
"tomlkit 0.5.8" = [
{file = "tomlkit-0.5.8-py2.py3-none-any.whl", hash = "sha256:96e6369288571799a3052c1ef93b9de440e1ab751aa045f435b55e9d3bcd0690"},
{file = "tomlkit-0.5.8.tar.gz", hash = "sha256:32c10cc16ded7e4101c79f269910658cc2a0be5913f1252121c3cd603051c269"},
]
"pythonfinder 1.2.1" = [
{file = "pythonfinder-1.2.1-py2.py3-none-any.whl", hash = "sha256:cfbfe61b7bfc3b45b24f156e2bab76621ebc6ba92f69afbc16f76482d69d9802"},
{file = "pythonfinder-1.2.1.tar.gz", hash = "sha256:0a4f585abb76aa2fc97479cd12d10f7644aa1ab42b919747e04d33d7f9379425"},
]
"pytest-cov 2.8.1" = [
{file = "pytest-cov-2.8.1.tar.gz", hash = "sha256:cc6742d8bac45070217169f5f72ceee1e0e55b0221f54bcf24845972d3a47f2b"},
{file = "pytest_cov-2.8.1-py2.py3-none-any.whl", hash = "sha256:cdbdef4f870408ebdbfeb44e63e07eb18bb4619fae852f6e760645fa36172626"},
]
"click 7.0" = [
{file = "Click-7.0-py2.py3-none-any.whl", hash = "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13"},
{file = "Click-7.0.tar.gz", hash = "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"},
]
"pytest-mock 2.0.0" = [
{file = "pytest-mock-2.0.0.tar.gz", hash = "sha256:b35eb281e93aafed138db25c8772b95d3756108b601947f89af503f8c629413f"},
{file = "pytest_mock-2.0.0-py2.py3-none-any.whl", hash = "sha256:cb67402d87d5f53c579263d37971a164743dc33c159dfb4fb4a86f37c5552307"},
]
"pytest 5.3.3" = [
{file = "pytest-5.3.3-py3-none-any.whl", hash = "sha256:9f8d44f4722b3d06b41afaeb8d177cfbe0700f8351b1fc755dd27eedaa3eb9e0"},
{file = "pytest-5.3.3.tar.gz", hash = "sha256:f5d3d0e07333119fe7d4af4ce122362dc4053cdd34a71d2766290cf5369c64ad"},
]
"pluggy 0.13.1" = [
{file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"},
{file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"},
]
"vistir[spinner] 0.5.0" = [
{file = "vistir-0.5.0-py2.py3-none-any.whl", hash = "sha256:e47afdec8baf35032a8d17116765f751ecd2f2146d47e5af457c5de1fe5a334e"},
{file = "vistir-0.5.0.tar.gz", hash = "sha256:33f8e905d40a77276b3d5310c8b57c1479a4e46930042b4894fcf7ed60ad76c4"},
]
"crayons 0.3.0" = [
{file = "crayons-0.3.0.tar.gz", hash = "sha256:50e5fa729d313e2c607ae8bf7b53bb487652e10bd8e7a1e08c4bc8bf62755ffc"},
{file = "crayons-0.3.0-py2.py3-none-any.whl", hash = "sha256:8c9e4a3a607bc10e9a9140d496ecd16c6805088dd16c852c378f1f1d5db7aeb6"},
]
"attrs 19.3.0" = [
{file = "attrs-19.3.0-py2.py3-none-any.whl", hash = "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c"},
{file = "attrs-19.3.0.tar.gz", hash = "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"},
]
"atomicwrites 1.3.0" = [
{file = "atomicwrites-1.3.0.tar.gz", hash = "sha256:75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6"},
{file = "atomicwrites-1.3.0-py2.py3-none-any.whl", hash = "sha256:03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4"},
]
"wcwidth 0.1.8" = [
{file = "wcwidth-0.1.8.tar.gz", hash = "sha256:f28b3e8a6483e5d49e7f8949ac1a78314e740333ae305b4ba5defd3e74fb37a8"},
{file = "wcwidth-0.1.8-py2.py3-none-any.whl", hash = "sha256:8fd29383f539be45b20bd4df0dc29c20ba48654a41e661925e612311e9f3c603"},
]
"py 1.8.1" = [
{file = "py-1.8.1-py2.py3-none-any.whl", hash = "sha256:c20fdd83a5dbc0af9efd622bee9a5564e278f6380fffcacc43ba6f43db2813b0"},
{file = "py-1.8.1.tar.gz", hash = "sha256:5e27081401262157467ad6e7f851b7aa402c5852dbcb3dae06768434de5752aa"},
]
"cached-property 1.5.1" = [
{file = "cached-property-1.5.1.tar.gz", hash = "sha256:9217a59f14a5682da7c4b8829deadbfc194ac22e9908ccf7c8820234e80a1504"},
{file = "cached_property-1.5.1-py2.py3-none-any.whl", hash = "sha256:3a026f1a54135677e7da5ce819b0c690f156f37976f3e30c5430740725203d7f"},
]
"more-itertools 8.1.0" = [
{file = "more-itertools-8.1.0.tar.gz", hash = "sha256:c468adec578380b6281a114cb8a5db34eb1116277da92d7c46f904f0b52d3288"},
{file = "more_itertools-8.1.0-py3-none-any.whl", hash = "sha256:1a2a32c72400d365000412fe08eb4a24ebee89997c18d3d147544f70f5403b39"},
]
"importlib-metadata 1.4.0" = [
{file = "importlib_metadata-1.4.0-py2.py3-none-any.whl", hash = "sha256:bdd9b7c397c273bcc9a11d6629a38487cd07154fa255a467bf704cd2c258e359"},
{file = "importlib_metadata-1.4.0.tar.gz", hash = "sha256:f17c015735e1a88296994c0697ecea7e11db24290941983b08c9feb30921e6d8"},
]
"six 1.14.0" = [
{file = "six-1.14.0-py2.py3-none-any.whl", hash = "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c"},
{file = "six-1.14.0.tar.gz", hash = "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a"},
]
"vistir 0.5.0" = [
{file = "vistir-0.5.0-py2.py3-none-any.whl", hash = "sha256:e47afdec8baf35032a8d17116765f751ecd2f2146d47e5af457c5de1fe5a334e"},
{file = "vistir-0.5.0.tar.gz", hash = "sha256:33f8e905d40a77276b3d5310c8b57c1479a4e46930042b4894fcf7ed60ad76c4"},
]
"packaging 20.0" = [
{file = "packaging-20.0-py2.py3-none-any.whl", hash = "sha256:aec3fdbb8bc9e4bb65f0634b9f551ced63983a529d6a8931817d52fdd0816ddb"},
{file = "packaging-20.0.tar.gz", hash = "sha256:fe1d8331dfa7cc0a883b49d75fc76380b2ab2734b220fbb87d774e4fd4b851f8"},
]
"colorama 0.4.3" = [
{file = "colorama-0.4.3-py2.py3-none-any.whl", hash = "sha256:7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff"},
{file = "colorama-0.4.3.tar.gz", hash = "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"},
]
"wheel 0.33.6" = [
{file = "wheel-0.33.6-py2.py3-none-any.whl", hash = "sha256:f4da1763d3becf2e2cd92a14a7c920f0f00eca30fdde9ea992c836685b9faf28"},
{file = "wheel-0.33.6.tar.gz", hash = "sha256:10c9da68765315ed98850f8e048347c3eb06dd81822dc2ab1d4fde9dc9702646"},
]
"coverage 4.4.2" = [
{file = "coverage-4.4.2.tar.gz", hash = "sha256:309d91bd7a35063ec7a0e4d75645488bfab3f0b66373e7722f23da7f5b0f34cc"},
{file = "coverage-4.4.2-cp26-cp26m-macosx_10_10_x86_64.whl", hash = "sha256:d1ee76f560c3c3e8faada866a07a32485445e16ed2206ac8378bd90dadffb9f0"},
{file = "coverage-4.4.2-cp26-cp26m-manylinux1_i686.whl", hash = "sha256:007eeef7e23f9473622f7d94a3e029a45d55a92a1f083f0f3512f5ab9a669b05"},
{file = "coverage-4.4.2-cp26-cp26m-manylinux1_x86_64.whl", hash = "sha256:17307429935f96c986a1b1674f78079528833410750321d22b5fb35d1883828e"},
{file = "coverage-4.4.2-cp26-cp26mu-manylinux1_i686.whl", hash = "sha256:845fddf89dca1e94abe168760a38271abfc2e31863fbb4ada7f9a99337d7c3dc"},
{file = "coverage-4.4.2-cp26-cp26mu-manylinux1_x86_64.whl", hash = "sha256:3f4d0b3403d3e110d2588c275540649b1841725f5a11a7162620224155d00ba2"},
{file = "coverage-4.4.2-cp27-cp27m-macosx_10_12_intel.whl", hash = "sha256:4c4f368ffe1c2e7602359c2c50233269f3abe1c48ca6b288dcd0fb1d1c679733"},
{file = "coverage-4.4.2-cp27-cp27m-macosx_10_12_x86_64.whl", hash = "sha256:f8c55dd0f56d3d618dfacf129e010cbe5d5f94b6951c1b2f13ab1a2f79c284da"},
{file = "coverage-4.4.2-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:cdd92dd9471e624cd1d8c1a2703d25f114b59b736b0f1f659a98414e535ffb3d"},
{file = "coverage-4.4.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:2ad357d12971e77360034c1596011a03f50c0f9e1ecd12e081342b8d1aee2236"},
{file = "coverage-4.4.2-cp27-cp27m-win32.whl", hash = "sha256:700d7579995044dc724847560b78ac786f0ca292867447afda7727a6fbaa082e"},
{file = "coverage-4.4.2-cp27-cp27m-win_amd64.whl", hash = "sha256:66f393e10dd866be267deb3feca39babba08ae13763e0fc7a1063cbe1f8e49f6"},
{file = "coverage-4.4.2-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:e9a0e1caed2a52f15c96507ab78a48f346c05681a49c5b003172f8073da6aa6b"},
{file = "coverage-4.4.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:eea9135432428d3ca7ee9be86af27cb8e56243f73764a9b6c3e0bda1394916be"},
{file = "coverage-4.4.2-cp33-cp33m-macosx_10_10_x86_64.whl", hash = "sha256:5ff16548492e8a12e65ff3d55857ccd818584ed587a6c2898a9ebbe09a880674"},
{file = "coverage-4.4.2-cp33-cp33m-manylinux1_i686.whl", hash = "sha256:d00e29b78ff610d300b2c37049a41234d48ea4f2d2581759ebcf67caaf731c31"},
{file = "coverage-4.4.2-cp33-cp33m-manylinux1_x86_64.whl", hash = "sha256:87d942863fe74b1c3be83a045996addf1639218c2cb89c5da18c06c0fe3917ea"},
{file = "coverage-4.4.2-cp34-cp34m-macosx_10_10_x86_64.whl", hash = "sha256:358d635b1fc22a425444d52f26287ae5aea9e96e254ff3c59c407426f44574f4"},
{file = "coverage-4.4.2-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:81912cfe276e0069dca99e1e4e6be7b06b5fc8342641c6b472cb2fed7de7ae18"},
{file = "coverage-4.4.2-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:079248312838c4c8f3494934ab7382a42d42d5f365f0cf7516f938dbb3f53f3f"},
{file = "coverage-4.4.2-cp34-cp34m-win32.whl", hash = "sha256:b0059630ca5c6b297690a6bf57bf2fdac1395c24b7935fd73ee64190276b743b"},
{file = "coverage-4.4.2-cp34-cp34m-win_amd64.whl", hash = "sha256:493082f104b5ca920e97a485913de254cbe351900deed72d4264571c73464cd0"},
{file = "coverage-4.4.2-cp35-cp35m-macosx_10_10_x86_64.whl", hash = "sha256:e3ba9b14607c23623cf38f90b23f5bed4a3be87cbfa96e2e9f4eabb975d1e98b"},
{file = "coverage-4.4.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:82cbd3317320aa63c65555aa4894bf33a13fb3a77f079059eb5935eea415938d"},
{file = "coverage-4.4.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9721f1b7275d3112dc7ccf63f0553c769f09b5c25a26ee45872c7f5c09edf6c1"},
{file = "coverage-4.4.2-cp35-cp35m-win32.whl", hash = "sha256:bd4800e32b4c8d99c3a2c943f1ac430cbf80658d884123d19639bcde90dad44a"},
{file = "coverage-4.4.2-cp35-cp35m-win_amd64.whl", hash = "sha256:f29841e865590af72c4b90d7b5b8e93fd560f5dea436c1d5ee8053788f9285de"},
{file = "coverage-4.4.2-cp36-cp36m-macosx_10_12_x86_64.whl", hash = "sha256:f3a5c6d054c531536a83521c00e5d4004f1e126e2e2556ce399bef4180fbe540"},
{file = "coverage-4.4.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:dd707a21332615108b736ef0b8513d3edaf12d2a7d5fc26cd04a169a8ae9b526"},
{file = "coverage-4.4.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2e1a5c6adebb93c3b175103c2f855eda957283c10cf937d791d81bef8872d6ca"},
{file = "coverage-4.4.2-cp36-cp36m-win32.whl", hash = "sha256:f87f522bde5540d8a4b11df80058281ac38c44b13ce29ced1e294963dd51a8f8"},
{file = "coverage-4.4.2-cp36-cp36m-win_amd64.whl", hash = "sha256:a7cfaebd8f24c2b537fa6a271229b051cdac9c1734bb6f939ccfc7c055689baa"},
]
"setuptools 45.0.0" = [
{file = "setuptools-45.0.0-py2.py3-none-any.whl", hash = "sha256:001c474c175697a03e2afffd87d92411c89215be5f2cd3e0ab80a67726c0f4c2"},
{file = "setuptools-45.0.0.zip", hash = "sha256:c46d9c8f2289535457d36c676b541ca78f7dcb736b97d02f50d17f7f15b583cc"},
]
"zipp 1.0.0" = [
{file = "zipp-1.0.0-py2.py3-none-any.whl", hash = "sha256:8dda78f06bd1674bd8720df8a50bb47b6e1233c503a4eed8e7810686bde37656"},
{file = "zipp-1.0.0.tar.gz", hash = "sha256:d38fbe01bbf7a3593a32bc35a9c4453c32bc42b98c377f9bff7e9f8da157786c"},
]
"yaspin 0.16.0" = [
{file = "yaspin-0.16.0.tar.gz", hash = "sha256:efca3eb7162e575d3ab2e49743cd9bd1f5ec2adc7d85b9489ab145a3f6460ed4"},
{file = "yaspin-0.16.0-py2.py3-none-any.whl", hash = "sha256:e88bf9c9fe4ac588e3620588aadae655dfc20f1f7460338394ef4693bdc2b800"},
]
"pyparsing 2.4.6" = [
{file = "pyparsing-2.4.6-py2.py3-none-any.whl", hash = "sha256:c342dccb5250c08d45fd6f8b4a559613ca603b57498511740e65cd11a2e7dcec"},
{file = "pyparsing-2.4.6.tar.gz", hash = "sha256:4c830582a84fb022400b85429791bc551f1f4871c33f23e44f353119e92f969f"},
]
[root]
content_hash = "md5:
2cb630f9bbca74c542dd5f9af44d03e
b"
content_hash = "md5:
17695868674c09e56b01814bc5ec0fa
b"
meta_version = "0.0.1"
pdm/cli/actions.py
浏览文件 @
ce0478fc
import
itertools
import
time
from
typing
import
Dict
,
Iterable
,
Optional
,
Tupl
e
from
typing
import
Dict
,
Iterable
,
Optional
,
Sequenc
e
import
tomlkit
from
pkg_resources
import
safe_name
from
pdm.exceptions
import
PdmUsageError
from
pdm.installers
import
Synchronizer
from
pdm.models.candidates
import
Candidate
,
identify
from
pdm.models.requirements
import
parse_requirement
from
pdm.models.requirements
import
parse_requirement
,
strip_extras
from
pdm.models.specifiers
import
bump_version
,
get_specifier
from
pdm.project
import
Project
from
pdm.resolver
import
(
...
...
@@ -54,15 +56,13 @@ def format_lockfile(mapping, fetched_dependencies, summary_collection):
def
do_lock
(
project
:
Project
,
strategy
:
str
=
"reuse"
,
preferred_pins
:
Optional
[
Dict
[
str
,
Candidate
]]
=
None
,
strategy
:
str
=
"all"
,
tracked_names
:
Optional
[
Iterable
[
str
]]
=
None
,
)
->
Dict
[
str
,
Candidate
]:
"""Performs the locking process and update lockfile.
:param project: the project instance
:param strategy: update stratege: reuse/eager
:param preferred_pins: pins that will be reused if possible
:param strategy: update stratege: reuse/eager/all
:param tracked_names: required when using eager strategy
"""
# TODO: multiple dependency definitions for the same package.
...
...
@@ -70,12 +70,13 @@ def do_lock(
requirements
=
project
.
all_dependencies
allow_prereleases
=
project
.
allow_prereleases
requires_python
=
project
.
python_requires
if
not
preferred_pins
:
if
strategy
==
"all"
:
provider
=
BaseProvider
(
repository
,
requires_python
,
allow_prereleases
)
else
:
provider_class
=
(
ReusePinProvider
if
strategy
==
"reuse"
else
EagerUpdateProvider
)
preferred_pins
=
project
.
get_locked_candidates
(
"__all__"
)
provider
=
provider_class
(
preferred_pins
,
tracked_names
or
(),
...
...
@@ -100,7 +101,7 @@ def do_lock(
def
do_sync
(
project
:
Project
,
sections
:
Tuple
[
str
,
...
]
=
(),
sections
:
Sequence
[
str
]
=
(),
dev
:
bool
=
False
,
default
:
bool
=
True
,
dry_run
:
bool
=
False
,
...
...
@@ -131,7 +132,7 @@ def do_add(
project
:
Project
,
dev
:
bool
=
False
,
section
:
Optional
[
str
]
=
None
,
install
:
bool
=
True
,
sync
:
bool
=
True
,
save
:
str
=
"compatible"
,
strategy
:
str
=
"reuse"
,
editables
:
Iterable
[
str
]
=
(),
...
...
@@ -142,7 +143,7 @@ def do_add(
:param project: the project instance
:param dev: add to dev dependencies seciton
:param section: specify section to be add to
:param
install
: whether to install added packages
:param
sync
: whether to install added packages
:param save: save strategy
:param strategy: update strategy
:param editables: editable requirements
...
...
@@ -150,21 +151,18 @@ def do_add(
"""
if
not
editables
and
not
packages
:
raise
PdmUsageError
(
"Must specify at least one package or editable package."
)
if
dev
:
section
=
"dev"
section
=
"dev"
if
dev
else
section
or
"default"
tracked_names
=
set
()
requirements
=
{}
for
r
in
[
parse_requirement
(
line
,
True
)
for
line
in
editables
]
+
[
parse_requirement
(
line
)
for
line
in
packages
]:
key
=
identify
(
r
)
r
.
from_section
=
section
or
"default"
r
.
from_section
=
section
tracked_names
.
add
(
key
)
requirements
[
key
]
=
r
project
.
add_dependencies
(
requirements
)
resolved
=
do_lock
(
project
,
strategy
,
project
.
get_locked_candidates
(
"__all__"
),
tracked_names
)
resolved
=
do_lock
(
project
,
strategy
,
tracked_names
)
for
name
in
tracked_names
:
r
=
requirements
[
name
]
if
r
.
is_named
and
not
r
.
specifier
:
...
...
@@ -182,7 +180,7 @@ def do_add(
lockfile
[
"root"
][
"content_hash"
]
=
"md5:"
+
project
.
get_content_hash
(
"md5"
)
project
.
write_lockfile
(
lockfile
)
if
install
:
if
sync
:
do_sync
(
project
,
sections
=
(
section
,),
...
...
@@ -191,3 +189,86 @@ def do_add(
dry_run
=
False
,
clean
=
False
,
)
def
do_update
(
project
:
Project
,
dev
:
bool
=
False
,
sections
:
Sequence
[
str
]
=
(),
default
:
bool
=
True
,
strategy
:
str
=
"reuse"
,
packages
:
Sequence
[
str
]
=
(),
)
->
None
:
"""Update specified packages or all packages
:param project: The project instance
:param dev: whether to update dev dependencies
:param sections: update speicified sections
:param default: update default
:param strategy: update strategy (reuse/eager)
:param packages: specified packages to update
:return: None
"""
if
len
(
packages
)
>
0
and
(
len
(
sections
)
>
1
or
not
default
):
raise
PdmUsageError
(
"packages argument can't be used together with multple -s or --no-default."
)
if
not
packages
:
# pdm update with no packages given, same as 'lock' + 'sync'
do_lock
(
project
)
do_sync
(
project
,
sections
,
dev
,
default
,
clean
=
False
)
return
section
=
sections
[
0
]
if
sections
else
(
"dev"
if
dev
else
"default"
)
dependencies
=
project
.
get_dependencies
(
section
)
tracked_names
=
set
()
for
name
in
packages
:
key
=
safe_name
(
name
).
lower
()
matched_name
=
next
(
filter
(
lambda
k
:
strip_extras
(
name
)[
0
]
==
key
,
dependencies
.
keys
()),
None
,
)
if
not
matched_name
:
raise
PdmUsageError
(
f
"
{
name
}
is not found in
{
section
}
dependencies"
)
tracked_names
.
add
(
matched_name
)
do_lock
(
project
,
strategy
,
tracked_names
)
do_sync
(
project
,
sections
=
(
section
,),
default
=
False
,
clean
=
False
)
def
do_remove
(
project
:
Project
,
dev
:
bool
=
False
,
section
:
Optional
[
str
]
=
None
,
sync
:
bool
=
True
,
packages
:
Sequence
[
str
]
=
(),
):
"""Remove packages from working set and pyproject.toml
:param project: The project instance
:param dev: Remove package from dev-dependencies
:param section: Remove package from given section
:param sync: Whether perform syncing action
:param packages: Package names to be removed
:return: None
"""
if
not
packages
:
raise
PdmUsageError
(
"Must specify at least one package to remove."
)
section
=
"dev"
if
dev
else
section
or
"default"
toml_section
=
f
"
{
section
}
-dependencies"
if
section
!=
"default"
else
"dependencies"
if
toml_section
not
in
project
.
pyproject
:
raise
PdmUsageError
(
f
"No such section
{
toml_section
!
r
}
in pyproject.toml."
)
deps
=
project
.
pyproject
[
toml_section
]
for
name
in
packages
:
matched_name
=
next
(
filter
(
lambda
k
:
safe_name
(
k
).
lower
()
==
safe_name
(
name
).
lower
(),
deps
.
keys
()
),
None
,
)
if
not
matched_name
:
raise
PdmUsageError
(
f
"
{
name
!
r
}
does not exist under
{
toml_section
!
r
}
."
)
del
deps
[
matched_name
]
project
.
write_pyproject
()
do_lock
(
project
,
"reuse"
)
if
sync
:
do_sync
(
project
,
sections
=
(
section
,),
default
=
False
,
clean
=
True
)
pdm/cli/commands.py
浏览文件 @
ce0478fc
...
...
@@ -86,29 +86,28 @@ def sync(project, sections, dev, default, dry_run, clean):
)
@
click
.
option
(
"-s"
,
"--section"
,
help
=
"Specify target section to add into."
)
@
click
.
option
(
"--no-
install
"
,
"
install
"
,
"--no-
sync
"
,
"
sync
"
,
flag_value
=
False
,
default
=
True
,
help
=
"Only write pyproject.toml and do not
install packages
."
,
help
=
"Only write pyproject.toml and do not
sync the working set
."
,
)
@
save_strategy_option
@
update_strategy_option
@
click
.
option
(
"-e"
,
"editables"
,
multiple
=
True
,
help
=
"Specify editable packages."
)
@
click
.
argument
(
"packages"
,
nargs
=-
1
)
@
pass_project
def
add
(
project
,
dev
,
section
,
install
,
save
,
strategy
,
editables
,
packages
):
actions
.
do_add
(
project
,
dev
,
section
,
install
,
save
,
strategy
,
editables
,
packages
)
def
add
(
project
,
dev
,
section
,
sync
,
save
,
strategy
,
editables
,
packages
):
actions
.
do_add
(
project
,
dev
,
section
,
sync
,
save
,
strategy
,
editables
,
packages
)
@
cli
.
command
(
help
=
"Update packages in pyproject.toml"
)
@
sections_option
@
save_strategy_option
@
update_strategy_option
@
click
.
argument
(
"packages"
,
nargs
=-
1
)
@
pass_project
def
update
(
project
,
dev
,
sections
,
default
,
s
ave
,
s
trategy
,
packages
):
pass
def
update
(
project
,
dev
,
sections
,
default
,
strategy
,
packages
):
actions
.
do_update
(
project
,
dev
,
sections
,
default
,
strategy
,
packages
)
@
cli
.
command
(
help
=
"Remove packages from pyproject.toml"
)
...
...
@@ -121,13 +120,13 @@ def update(project, dev, sections, default, save, strategy, packages):
)
@
click
.
option
(
"-s"
,
"--section"
,
help
=
"Specify target section the package belongs to"
)
@
click
.
option
(
"--no-
install
"
,
"
install
"
,
"--no-
sync
"
,
"
sync
"
,
flag_value
=
False
,
default
=
True
,
help
=
"Only write pyproject.toml and do not uninstall packages."
,
)
@
click
.
argument
(
"packages"
,
nargs
=-
1
)
@
pass_project
def
remove
(
project
,
dev
,
section
,
install
,
packages
):
pass
def
remove
(
project
,
dev
,
section
,
sync
,
packages
):
actions
.
do_remove
(
project
,
dev
,
section
,
sync
,
packages
)
pdm/installers.py
浏览文件 @
ce0478fc
...
...
@@ -26,7 +26,9 @@ def _is_dist_editable(working_set: WorkingSet, dist: Distribution) -> bool:
return
False
def
_print_list_information
(
word
,
items
):
def
_print_list_information
(
word
,
items
,
dry
=
False
):
if
dry
:
word
=
"to be "
+
word
template
=
"{count} package{suffix} {word}: {items}"
suffix
=
"s"
if
len
(
items
)
>
1
else
""
count
=
len
(
items
)
...
...
@@ -159,8 +161,8 @@ class Synchronizer:
self
.
remove_distributions
(
to_remove
)
print
()
if
to_add
:
_print_list_information
(
"added"
,
to_add
)
_print_list_information
(
"added"
,
to_add
,
dry_run
)
if
to_update
:
_print_list_information
(
"updated"
,
to_update
)
_print_list_information
(
"updated"
,
to_update
,
dry_run
)
if
clean
and
to_remove
:
_print_list_information
(
"removed"
,
to_remove
)
_print_list_information
(
"removed"
,
to_remove
,
dry_run
)
pdm/project/__init__.py
浏览文件 @
ce0478fc
...
...
@@ -251,7 +251,7 @@ class Project:
data
=
original
*
parts
,
last
=
self
.
PDM_NAMESPACE
.
split
(
"."
)
for
part
in
parts
:
data
=
data
.
setdefault
(
part
,
tomlkit
.
table
()
)
data
=
data
.
setdefault
(
part
,
{}
)
data
[
last
]
=
self
.
pyproject
with
atomic_open_for_write
(
...
...
pyproject.toml
浏览文件 @
ce0478fc
...
...
@@ -5,7 +5,6 @@ python_requires = ">=3.7"
appdirs
=
"*"
click
=
"*"
distlib
=
"*"
parver
=
"<1.0.0,>=0.2.1"
pip
=
"<20.0.0,>=19.3.1"
pip_shims
=
"*"
pythonfinder
=
"*"
...
...
@@ -16,6 +15,7 @@ pytest = "*"
pytest-cov
=
"*"
pytest-mock
=
"*"
[tool.isort]
line_length
=
88
multi_line_output
=
3
...
...
tests/cli/test_actions.py
浏览文件 @
ce0478fc
from
pdm.cli.actions
import
do_add
import
pytest
from
pdm.cli.actions
import
do_add
,
do_update
,
do_sync
,
do_remove
from
collections
import
namedtuple
from
pdm.exceptions
import
PdmUsageError
Requirement
=
namedtuple
(
"Requirement"
,
"key"
)
Candidate
=
namedtuple
(
"Candidate"
,
"req,version"
)
def
make_candidate
(
name
,
version
):
req
=
Requirement
(
name
)
return
Candidate
(
req
=
req
,
version
=
version
)
def
test_sync_only_different
(
project
,
repository
,
synchronizer
,
capsys
):
synchronizer
.
install_candidates
(
[
make_candidate
(
"foo"
,
"0.1.0"
),
make_candidate
(
"chardet"
,
"3.0.1"
),
make_candidate
(
"idna"
,
"2.7"
),
]
)
do_add
(
project
,
packages
=
[
"requests"
])
out
,
_
=
capsys
.
readouterr
()
assert
"3 packages added"
in
out
assert
"1 package updated"
in
out
assert
"foo"
in
synchronizer
.
working_set
assert
synchronizer
.
working_set
[
"chardet"
]
==
"3.0.4"
def
test_sync_clean_packages
(
project
,
repository
,
synchronizer
):
synchronizer
.
install_candidates
(
[
make_candidate
(
"foo"
,
"0.1.0"
),
make_candidate
(
"chardet"
,
"3.0.1"
),
make_candidate
(
"idna"
,
"2.7"
),
]
)
do_add
(
project
,
packages
=
[
"requests"
],
sync
=
False
)
do_sync
(
project
,
clean
=
True
)
assert
"foo"
not
in
synchronizer
.
working_set
def
test_sync_dry_run
(
project
,
repository
,
synchronizer
):
synchronizer
.
install_candidates
(
[
make_candidate
(
"foo"
,
"0.1.0"
),
make_candidate
(
"chardet"
,
"3.0.1"
),
make_candidate
(
"idna"
,
"2.7"
),
]
)
do_add
(
project
,
packages
=
[
"requests"
],
sync
=
False
)
do_sync
(
project
,
clean
=
True
,
dry_run
=
True
)
assert
"foo"
in
synchronizer
.
working_set
assert
"requests"
not
in
synchronizer
.
working_set
assert
synchronizer
.
working_set
[
"chardet"
]
==
"3.0.1"
def
test_add_package
(
project
,
repository
,
synchronizer
,
is_dev
):
...
...
@@ -24,9 +81,9 @@ def test_add_package_to_custom_package(project, repository, synchronizer):
def
test_add_editable_package
(
project
,
repository
,
synchronizer
,
is_dev
,
vcs
):
do_add
(
project
,
is_dev
,
editables
=
[
"git+https://github.com/test-root/demo.git#egg=demo"
]
project
,
is_dev
,
editables
=
[
"git+https://github.com/test-root/demo.git#egg=demo"
],
)
section
=
"dev-dependencies"
if
is_dev
else
"dependencies"
assert
"demo"
in
project
.
pyproject
[
section
]
...
...
@@ -36,23 +93,23 @@ def test_add_editable_package(project, repository, synchronizer, is_dev, vcs):
def
test_add_no_install
(
project
,
repository
,
synchronizer
):
do_add
(
project
,
install
=
False
,
packages
=
[
"requests"
])
do_add
(
project
,
sync
=
False
,
packages
=
[
"requests"
])
for
package
in
(
"requests"
,
"idna"
,
"chardet"
,
"urllib3"
,
"certifi"
):
assert
package
not
in
synchronizer
.
working_set
def
test_add_package_save_exact
(
project
,
repository
):
do_add
(
project
,
install
=
False
,
save
=
"exact"
,
packages
=
[
"requests"
])
do_add
(
project
,
sync
=
False
,
save
=
"exact"
,
packages
=
[
"requests"
])
assert
project
.
pyproject
[
"dependencies"
][
"requests"
]
==
"==2.19.1"
def
test_add_package_save_wildcard
(
project
,
repository
):
do_add
(
project
,
install
=
False
,
save
=
"wildcard"
,
packages
=
[
"requests"
])
do_add
(
project
,
sync
=
False
,
save
=
"wildcard"
,
packages
=
[
"requests"
])
assert
project
.
pyproject
[
"dependencies"
][
"requests"
]
==
"*"
def
test_add_package_update_reuse
(
project
,
repository
):
do_add
(
project
,
install
=
False
,
save
=
"wildcard"
,
packages
=
[
"requests"
,
"pytz"
])
do_add
(
project
,
sync
=
False
,
save
=
"wildcard"
,
packages
=
[
"requests"
,
"pytz"
])
locked_candidates
=
project
.
get_locked_candidates
()
assert
locked_candidates
[
"requests"
].
version
==
"2.19.1"
...
...
@@ -62,14 +119,18 @@ def test_add_package_update_reuse(project, repository):
repository
.
add_candidate
(
"pytz"
,
"2019.6"
)
repository
.
add_candidate
(
"chardet"
,
"3.0.5"
)
repository
.
add_candidate
(
"requests"
,
"2.20.0"
)
repository
.
add_dependencies
(
"requests"
,
"2.20.0"
,
[
"certifi>=2017.4.17"
,
"chardet<3.1.0,>=3.0.2"
,
"idna<2.8,>=2.5"
,
"urllib3<1.24,>=1.21.1"
])
repository
.
add_dependencies
(
"requests"
,
"2.20.0"
,
[
"certifi>=2017.4.17"
,
"chardet<3.1.0,>=3.0.2"
,
"idna<2.8,>=2.5"
,
"urllib3<1.24,>=1.21.1"
,
],
)
do_add
(
project
,
install
=
False
,
save
=
"wildcard"
,
packages
=
[
"requests"
],
strategy
=
"reuse"
project
,
sync
=
False
,
save
=
"wildcard"
,
packages
=
[
"requests"
],
strategy
=
"reuse"
)
locked_candidates
=
project
.
get_locked_candidates
()
assert
locked_candidates
[
"requests"
].
version
==
"2.20.0"
...
...
@@ -78,7 +139,7 @@ def test_add_package_update_reuse(project, repository):
def
test_add_package_update_eager
(
project
,
repository
):
do_add
(
project
,
install
=
False
,
save
=
"wildcard"
,
packages
=
[
"requests"
,
"pytz"
])
do_add
(
project
,
sync
=
False
,
save
=
"wildcard"
,
packages
=
[
"requests"
,
"pytz"
])
locked_candidates
=
project
.
get_locked_candidates
()
assert
locked_candidates
[
"requests"
].
version
==
"2.19.1"
...
...
@@ -88,16 +149,130 @@ def test_add_package_update_eager(project, repository):
repository
.
add_candidate
(
"pytz"
,
"2019.6"
)
repository
.
add_candidate
(
"chardet"
,
"3.0.5"
)
repository
.
add_candidate
(
"requests"
,
"2.20.0"
)
repository
.
add_dependencies
(
"requests"
,
"2.20.0"
,
[
"certifi>=2017.4.17"
,
"chardet<3.1.0,>=3.0.2"
,
"idna<2.8,>=2.5"
,
"urllib3<1.24,>=1.21.1"
])
repository
.
add_dependencies
(
"requests"
,
"2.20.0"
,
[
"certifi>=2017.4.17"
,
"chardet<3.1.0,>=3.0.2"
,
"idna<2.8,>=2.5"
,
"urllib3<1.24,>=1.21.1"
,
],
)
do_add
(
project
,
install
=
False
,
save
=
"wildcard"
,
packages
=
[
"requests"
],
strategy
=
"eager"
project
,
sync
=
False
,
save
=
"wildcard"
,
packages
=
[
"requests"
],
strategy
=
"eager"
)
locked_candidates
=
project
.
get_locked_candidates
()
assert
locked_candidates
[
"requests"
].
version
==
"2.20.0"
assert
locked_candidates
[
"chardet"
].
version
==
"3.0.5"
assert
locked_candidates
[
"pytz"
].
version
==
"2019.3"
def
test_update_all_packages
(
project
,
repository
,
synchronizer
,
capsys
):
do_add
(
project
,
packages
=
[
"requests"
,
"pytz"
])
repository
.
add_candidate
(
"pytz"
,
"2019.6"
)
repository
.
add_candidate
(
"chardet"
,
"3.0.5"
)
repository
.
add_candidate
(
"requests"
,
"2.20.0"
)
repository
.
add_dependencies
(
"requests"
,
"2.20.0"
,
[
"certifi>=2017.4.17"
,
"chardet<3.1.0,>=3.0.2"
,
"idna<2.8,>=2.5"
,
"urllib3<1.24,>=1.21.1"
,
],
)
do_update
(
project
)
locked_candidates
=
project
.
get_locked_candidates
()
assert
locked_candidates
[
"requests"
].
version
==
"2.20.0"
assert
locked_candidates
[
"chardet"
].
version
==
"3.0.5"
assert
locked_candidates
[
"pytz"
].
version
==
"2019.6"
out
,
_
=
capsys
.
readouterr
()
assert
"3 packages updated"
in
out
do_sync
(
project
)
out
,
_
=
capsys
.
readouterr
()
assert
"All packages are synced to date"
in
out
def
test_update_specified_packages
(
project
,
repository
,
synchronizer
):
do_add
(
project
,
sync
=
False
,
packages
=
[
"requests"
,
"pytz"
])
repository
.
add_candidate
(
"pytz"
,
"2019.6"
)
repository
.
add_candidate
(
"chardet"
,
"3.0.5"
)
repository
.
add_candidate
(
"requests"
,
"2.20.0"
)
repository
.
add_dependencies
(
"requests"
,
"2.20.0"
,
[
"certifi>=2017.4.17"
,
"chardet<3.1.0,>=3.0.2"
,
"idna<2.8,>=2.5"
,
"urllib3<1.24,>=1.21.1"
,
],
)
do_update
(
project
,
packages
=
[
"requests"
])
locked_candidates
=
project
.
get_locked_candidates
()
assert
locked_candidates
[
"requests"
].
version
==
"2.20.0"
assert
locked_candidates
[
"chardet"
].
version
==
"3.0.4"
def
test_update_specified_packages_eager_mode
(
project
,
repository
,
synchronizer
):
do_add
(
project
,
sync
=
False
,
packages
=
[
"requests"
,
"pytz"
])
repository
.
add_candidate
(
"pytz"
,
"2019.6"
)
repository
.
add_candidate
(
"chardet"
,
"3.0.5"
)
repository
.
add_candidate
(
"requests"
,
"2.20.0"
)
repository
.
add_dependencies
(
"requests"
,
"2.20.0"
,
[
"certifi>=2017.4.17"
,
"chardet<3.1.0,>=3.0.2"
,
"idna<2.8,>=2.5"
,
"urllib3<1.24,>=1.21.1"
,
],
)
do_update
(
project
,
strategy
=
"eager"
,
packages
=
[
"requests"
])
locked_candidates
=
project
.
get_locked_candidates
()
assert
locked_candidates
[
"requests"
].
version
==
"2.20.0"
assert
locked_candidates
[
"chardet"
].
version
==
"3.0.5"
assert
locked_candidates
[
"pytz"
].
version
==
"2019.3"
def
test_remove_package
(
project
,
repository
,
synchronizer
,
is_dev
):
do_add
(
project
,
dev
=
is_dev
,
packages
=
[
"requests"
,
"pytz"
])
do_remove
(
project
,
dev
=
is_dev
,
packages
=
[
"pytz"
])
locked_candidates
=
project
.
get_locked_candidates
()
assert
"pytz"
not
in
locked_candidates
assert
"pytz"
not
in
synchronizer
.
working_set
def
test_remove_package_no_sync
(
project
,
repository
,
synchronizer
):
do_add
(
project
,
packages
=
[
"requests"
,
"pytz"
])
do_remove
(
project
,
sync
=
False
,
packages
=
[
"pytz"
])
locked_candidates
=
project
.
get_locked_candidates
()
assert
"pytz"
not
in
locked_candidates
assert
"pytz"
in
synchronizer
.
working_set
def
test_remove_package_not_exist
(
project
,
repository
,
synchronizer
):
do_add
(
project
,
packages
=
[
"requests"
,
"pytz"
])
with
pytest
.
raises
(
PdmUsageError
):
do_remove
(
project
,
sync
=
False
,
packages
=
[
"django"
])
def
test_add_remove_no_package
(
project
,
repository
):
with
pytest
.
raises
(
PdmUsageError
):
do_add
(
project
,
packages
=
())
with
pytest
.
raises
(
PdmUsageError
):
do_remove
(
project
,
packages
=
())
def
test_update_with_package_and_sections_argument
(
project
,
repository
,
synchronizer
):
do_add
(
project
,
packages
=
[
"requests"
,
"pytz"
])
with
pytest
.
raises
(
PdmUsageError
):
do_update
(
project
,
sections
=
(
"default"
,
"dev"
),
packages
=
(
"requests"
,))
with
pytest
.
raises
(
PdmUsageError
):
do_update
(
project
,
default
=
False
,
packages
=
(
"requests"
,))
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录