devpi-server 6.14.0__tar.gz → 6.15.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {devpi-server-6.14.0 → devpi-server-6.15.0}/CHANGELOG +10 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/MANIFEST.in +3 -1
- {devpi-server-6.14.0 → devpi-server-6.15.0}/PKG-INFO +11 -22
- devpi-server-6.15.0/devpi_server/__init__.py +1 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/config.py +28 -2
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/hookspecs.py +6 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/mirror.py +5 -4
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/model.py +2 -1
- devpi-server-6.15.0/devpi_server/py.typed +1 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/view_auth.py +15 -3
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server.egg-info/PKG-INFO +11 -22
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server.egg-info/SOURCES.txt +2 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/pyproject.toml +79 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/setup.py +1 -1
- devpi-server-6.15.0/test_devpi_server/py.typed +1 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_main.py +10 -2
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_model.py +2 -2
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_view_auth.py +18 -8
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_views.py +6 -6
- {devpi-server-6.14.0 → devpi-server-6.15.0}/tox.ini +1 -1
- devpi-server-6.14.0/devpi_server/__init__.py +0 -1
- {devpi-server-6.14.0 → devpi-server-6.15.0}/.flake8 +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/AUTHORS +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/LICENSE +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/README.rst +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/__main__.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/auth.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/auth_basic.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/auth_devpi.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/cfg/__init__.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/cfg/crontab.template +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/cfg/devpi.service.template +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/cfg/launchd-macos.txt.template +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/cfg/nginx-devpi-caching-http.conf.template +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/cfg/nginx-devpi-caching-location.conf.template +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/cfg/nginx-devpi-caching-proxy.conf.template +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/cfg/nginx-devpi-caching-server.conf.template +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/cfg/nginx-devpi.conf.template +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/cfg/supervisor-devpi.conf.template +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/cfg/supervisord.conf.template +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/cfg/windows-service.txt.template +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/exceptions.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/filestore.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/filestore_fs.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/fileutil.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/fsck.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/genconfig.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/importexport.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/init.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/interfaces.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/keyfs.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/keyfs_sqlite.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/keyfs_sqlite_fs.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/keyfs_types.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/log.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/main.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/markers.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/middleware.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/mythread.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/passwd.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/readonly.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/replica.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/sizeof.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/vendor/__init__.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/vendor/_pip.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/views.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server.egg-info/dependency_links.txt +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server.egg-info/entry_points.txt +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server.egg-info/not-zip-safe +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server.egg-info/requires.txt +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server.egg-info/top_level.txt +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/pytest_devpi_server/__init__.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/setup.cfg +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/__init__.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/conftest.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/example.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/functional.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/importexportdata/badindexname/dataindex.json +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/importexportdata/badusername/dataindex.json +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/importexportdata/basescycle/dataindex.json +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/importexportdata/createdmodified/dataindex.json +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/importexportdata/deletedbase/dataindex.json +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/importexportdata/mirrordata/dataindex.json +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/importexportdata/mirrordata/root/pypi/dddttt/0.1.dev1/dddttt-0.1.dev1.tar.gz +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/importexportdata/modifiedpypi/dataindex.json +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/importexportdata/nocreatedmodified/dataindex.json +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/importexportdata/normalization/dataindex.json +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/importexportdata/normalization/root/dev/hello.pkg/hello.pkg-1.0.tar.gz +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/importexportdata/normalization_merge/dataindex.json +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/importexportdata/normalization_merge/root/dev/hello-pkg/hello.pkg-1.1.tar.gz +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/importexportdata/normalization_merge/root/dev/hello.pkg/hello.pkg-1.0.tar.gz +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/importexportdata/norootpypi/dataindex.json +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/importexportdata/nouser/dataindex.json +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/importexportdata/removedindexplugin/dataindex.json +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/importexportdata/removedindexplugin/user/dev/pkg/pkg-1.0.tar.gz +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/importexportdata/toxresult_naming_scheme/dataindex.json +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/importexportdata/toxresult_naming_scheme/root/dev/hello/0.9/hello-0.9.tar.gz +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/importexportdata/toxresult_naming_scheme/root/dev/hello/sha256=ed7002b439e9ac845f22357d822bac1444730fbdb6016d3ec9432297b9ec9f73/hello-0.9.tar.gz.toxresult0 +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/importexportdata/toxresult_upload_default/dataindex.json +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/plugin.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/reqmock.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/simpypi.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_auth.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_authcheck.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_config.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_conftest.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_filestore.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_fileutil.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_fsck.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_genconfig.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_importexport.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_keyfs.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_keyfs_sqlite_fs.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_log.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_mirror.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_mirror_no_project_list.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_mythread.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_nginx.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_nginx_replica.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_permissions.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_readonly.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_replica.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_replica_functional.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_reqmock.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_stage_customizer.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_streaming.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_streaming_nginx.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_streaming_replica.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_streaming_replica_nginx.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_views_patch.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_views_push_external.py +0 -0
- {devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_views_status.py +0 -0
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
include .flake8 CHANGELOG *.ini *.rst LICENSE
|
|
2
|
-
recursive-include devpi_server
|
|
2
|
+
recursive-include devpi_server py.typed
|
|
3
|
+
recursive-include devpi_server *.template
|
|
4
|
+
recursive-include test_devpi_server py.typed
|
|
3
5
|
recursive-include test_devpi_server *.py
|
|
4
6
|
recursive-include test_devpi_server/importexportdata *.gz* *.json
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: devpi-server
|
|
3
|
-
Version: 6.
|
|
3
|
+
Version: 6.15.0
|
|
4
4
|
Summary: devpi-server: reliable private and pypi.org caching server
|
|
5
5
|
Home-page: https://devpi.net
|
|
6
6
|
Maintainer: Florian Schulze
|
|
@@ -105,6 +105,16 @@ Changelog
|
|
|
105
105
|
|
|
106
106
|
.. towncrier release notes start
|
|
107
107
|
|
|
108
|
+
6.15.0 (2025-05-18)
|
|
109
|
+
===================
|
|
110
|
+
|
|
111
|
+
Features
|
|
112
|
+
--------
|
|
113
|
+
|
|
114
|
+
- Add ``--connection-limit`` option to devpi-server passed on to waitress.
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
108
118
|
6.14.0 (2024-10-16)
|
|
109
119
|
===================
|
|
110
120
|
|
|
@@ -193,24 +203,3 @@ Bug Fixes
|
|
|
193
203
|
- Return json data if toxresult upload is forbidden.
|
|
194
204
|
|
|
195
205
|
|
|
196
|
-
|
|
197
|
-
6.11.0 (2024-04-20)
|
|
198
|
-
===================
|
|
199
|
-
|
|
200
|
-
Features
|
|
201
|
-
--------
|
|
202
|
-
|
|
203
|
-
- The ``devpi-fsck`` script now returns an error code when there have been missing files or checksum errors.
|
|
204
|
-
|
|
205
|
-
- Fix #983: Add plugin hook for mirror authentication header.
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
Bug Fixes
|
|
210
|
-
---------
|
|
211
|
-
|
|
212
|
-
- Preserve last modified of docs and toxresults during export/import.
|
|
213
|
-
|
|
214
|
-
- Fix #1033: Use ``int`` for ``--mirror-cache-expiry`` to fix value of ``proxy_cache_valid`` in nginx caching config.
|
|
215
|
-
|
|
216
|
-
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '6.15.0'
|
|
@@ -56,6 +56,24 @@ def get_pluginmanager(load_entrypoints=True):
|
|
|
56
56
|
return pm
|
|
57
57
|
|
|
58
58
|
|
|
59
|
+
def traced_pluggy_call(hook, **caller_kwargs):
|
|
60
|
+
firstresult = hook.spec.opts.get("firstresult", False) if hook.spec else False
|
|
61
|
+
results = []
|
|
62
|
+
plugin_names = []
|
|
63
|
+
hookimpls = hook._hookimpls if hasattr(hook, '_hookimpls') else hook.get_hookimpls()
|
|
64
|
+
for hook_impl in reversed(hookimpls):
|
|
65
|
+
args = [caller_kwargs[argname] for argname in hook_impl.argnames]
|
|
66
|
+
res = hook_impl.function(*args)
|
|
67
|
+
if res is not None:
|
|
68
|
+
results.append(res)
|
|
69
|
+
plugin_names.append(hook_impl.plugin_name)
|
|
70
|
+
if firstresult:
|
|
71
|
+
break
|
|
72
|
+
if firstresult:
|
|
73
|
+
results = results[0] if results else None
|
|
74
|
+
return (results, plugin_names)
|
|
75
|
+
|
|
76
|
+
|
|
59
77
|
def add_help_option(parser, pluginmanager):
|
|
60
78
|
parser.addoption(
|
|
61
79
|
"-h", "--help",
|
|
@@ -155,6 +173,11 @@ def add_web_options(parser, pluginmanager):
|
|
|
155
173
|
default=50,
|
|
156
174
|
help="number of threads to start for serving clients.")
|
|
157
175
|
|
|
176
|
+
parser.addoption(
|
|
177
|
+
"--connection-limit", type=int,
|
|
178
|
+
default=100,
|
|
179
|
+
help="maximum number of simultaneous client connections.")
|
|
180
|
+
|
|
158
181
|
parser.addoption(
|
|
159
182
|
"--trusted-proxy", type=str,
|
|
160
183
|
help="IP address of proxy we trust. See waitress documentation.")
|
|
@@ -446,8 +469,9 @@ def find_config_file():
|
|
|
446
469
|
config_files.append(config_file)
|
|
447
470
|
if len(config_files) > 1:
|
|
448
471
|
log.warning("Multiple configuration files found:\n%s", "\n".join(config_files))
|
|
449
|
-
if
|
|
450
|
-
return
|
|
472
|
+
if not config_files:
|
|
473
|
+
return None
|
|
474
|
+
return config_files[-1]
|
|
451
475
|
|
|
452
476
|
|
|
453
477
|
class InvalidConfigError(ValueError):
|
|
@@ -680,6 +704,8 @@ class Config(object):
|
|
|
680
704
|
kwargs["trusted_proxy_count"] = self.args.trusted_proxy_count
|
|
681
705
|
if self.args.trusted_proxy_headers is not None:
|
|
682
706
|
kwargs["trusted_proxy_headers"] = self.args.trusted_proxy_headers
|
|
707
|
+
if self.args.connection_limit is not None:
|
|
708
|
+
kwargs["connection_limit"] = self.args.connection_limit
|
|
683
709
|
return dict(kwargs=kwargs, addresses=addresses)
|
|
684
710
|
|
|
685
711
|
@cached_property
|
|
@@ -158,6 +158,12 @@ def devpiserver_get_identity(request, credentials):
|
|
|
158
158
|
"""
|
|
159
159
|
|
|
160
160
|
|
|
161
|
+
@hookspec
|
|
162
|
+
def devpiserver_identity_loaded(request, credential_plugin_name, identity_plugin_name, identity):
|
|
163
|
+
""" called when identity is loaded for a request.
|
|
164
|
+
"""
|
|
165
|
+
|
|
166
|
+
|
|
161
167
|
@hookspec(warn_on_impl=DeprecationWarning("Use new devpiserver_auth_request hook instead"))
|
|
162
168
|
def devpiserver_auth_user(userdict, username, password):
|
|
163
169
|
"""return dict containing authentication validation results.
|
|
@@ -120,9 +120,9 @@ class IndexParser:
|
|
|
120
120
|
appear later are ignored.
|
|
121
121
|
"""
|
|
122
122
|
entry = self.basename2link.get(newlink.basename)
|
|
123
|
-
if entry is None or not entry.hash_spec and (newlink.hash_spec or (
|
|
123
|
+
if entry is None or (not entry.hash_spec and (newlink.hash_spec or (
|
|
124
124
|
not entry.requires_python and newlink.requires_python
|
|
125
|
-
)):
|
|
125
|
+
))):
|
|
126
126
|
self.basename2link[newlink.basename] = newlink
|
|
127
127
|
threadlog.debug("indexparser: adding link %s", newlink)
|
|
128
128
|
else:
|
|
@@ -324,9 +324,9 @@ class MirrorStage(BaseStage):
|
|
|
324
324
|
if key == "mirror_cache_expiry":
|
|
325
325
|
try:
|
|
326
326
|
value = int(value)
|
|
327
|
-
except (TypeError, ValueError):
|
|
327
|
+
except (TypeError, ValueError) as e:
|
|
328
328
|
raise self.InvalidIndexconfig([
|
|
329
|
-
"'mirror_cache_expiry' option must be an integer"])
|
|
329
|
+
"'mirror_cache_expiry' option must be an integer"]) from e
|
|
330
330
|
return value
|
|
331
331
|
if key == "mirror_no_project_list":
|
|
332
332
|
return ensure_boolean(value)
|
|
@@ -334,6 +334,7 @@ class MirrorStage(BaseStage):
|
|
|
334
334
|
return ensure_boolean(value)
|
|
335
335
|
if key in ("custom_data", "description", "mirror_web_url_fmt", "title"):
|
|
336
336
|
return value
|
|
337
|
+
return None
|
|
337
338
|
|
|
338
339
|
def delete(self):
|
|
339
340
|
# delete all projects on this index
|
|
@@ -1770,7 +1770,8 @@ class SimplelinkMeta:
|
|
|
1770
1770
|
__slots__ = (
|
|
1771
1771
|
'__basename', '__cmpval', '__ext', '__hash_spec',
|
|
1772
1772
|
'__name', '__path', '__url', '__version',
|
|
1773
|
-
'
|
|
1773
|
+
'href', 'key', 'require_python', 'yanked',
|
|
1774
|
+
)
|
|
1774
1775
|
|
|
1775
1776
|
def __init__(self, link_info):
|
|
1776
1777
|
self.__basename = notset
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
partial
|
|
@@ -4,6 +4,7 @@ from devpi_common.types import ensure_unicode
|
|
|
4
4
|
from devpi_common.validation import normalize_name
|
|
5
5
|
from devpi_server.auth import Auth
|
|
6
6
|
from devpi_server.config import hookimpl
|
|
7
|
+
from devpi_server.config import traced_pluggy_call
|
|
7
8
|
from devpi_server.views import abort
|
|
8
9
|
from devpi_server.model import BaseStage
|
|
9
10
|
from devpi_server.model import UpstreamError
|
|
@@ -218,12 +219,23 @@ class DevpiSecurityPolicy:
|
|
|
218
219
|
return [('WWW-Authenticate', 'Basic realm="%s"' % self.realm)]
|
|
219
220
|
|
|
220
221
|
def _get_credentials(self, request):
|
|
221
|
-
return
|
|
222
|
+
return traced_pluggy_call(
|
|
223
|
+
self.hook.devpiserver_get_credentials,
|
|
224
|
+
request=request)
|
|
222
225
|
|
|
223
226
|
def load_identity(self, request):
|
|
224
|
-
credentials = self._get_credentials(request)
|
|
225
|
-
|
|
227
|
+
(credentials, plugin_names) = self._get_credentials(request)
|
|
228
|
+
credential_plugin_name = plugin_names[0] if plugin_names else None
|
|
229
|
+
(result, plugin_names) = traced_pluggy_call(
|
|
230
|
+
self.hook.devpiserver_get_identity,
|
|
226
231
|
request=request, credentials=credentials)
|
|
232
|
+
identity_plugin_name = plugin_names[0] if plugin_names else None
|
|
233
|
+
self.hook.devpiserver_identity_loaded(
|
|
234
|
+
request=request,
|
|
235
|
+
credential_plugin_name=credential_plugin_name,
|
|
236
|
+
identity_plugin_name=identity_plugin_name,
|
|
237
|
+
identity=result)
|
|
238
|
+
return result
|
|
227
239
|
|
|
228
240
|
def identity(self, request):
|
|
229
241
|
return self.identity_cache.get_or_create(request)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: devpi-server
|
|
3
|
-
Version: 6.
|
|
3
|
+
Version: 6.15.0
|
|
4
4
|
Summary: devpi-server: reliable private and pypi.org caching server
|
|
5
5
|
Home-page: https://devpi.net
|
|
6
6
|
Maintainer: Florian Schulze
|
|
@@ -105,6 +105,16 @@ Changelog
|
|
|
105
105
|
|
|
106
106
|
.. towncrier release notes start
|
|
107
107
|
|
|
108
|
+
6.15.0 (2025-05-18)
|
|
109
|
+
===================
|
|
110
|
+
|
|
111
|
+
Features
|
|
112
|
+
--------
|
|
113
|
+
|
|
114
|
+
- Add ``--connection-limit`` option to devpi-server passed on to waitress.
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
108
118
|
6.14.0 (2024-10-16)
|
|
109
119
|
===================
|
|
110
120
|
|
|
@@ -193,24 +203,3 @@ Bug Fixes
|
|
|
193
203
|
- Return json data if toxresult upload is forbidden.
|
|
194
204
|
|
|
195
205
|
|
|
196
|
-
|
|
197
|
-
6.11.0 (2024-04-20)
|
|
198
|
-
===================
|
|
199
|
-
|
|
200
|
-
Features
|
|
201
|
-
--------
|
|
202
|
-
|
|
203
|
-
- The ``devpi-fsck`` script now returns an error code when there have been missing files or checksum errors.
|
|
204
|
-
|
|
205
|
-
- Fix #983: Add plugin hook for mirror authentication header.
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
Bug Fixes
|
|
210
|
-
---------
|
|
211
|
-
|
|
212
|
-
- Preserve last modified of docs and toxresults during export/import.
|
|
213
|
-
|
|
214
|
-
- Fix #1033: Use ``int`` for ``--mirror-cache-expiry`` to fix value of ``proxy_cache_valid`` in nginx caching config.
|
|
215
|
-
|
|
216
|
-
|
|
@@ -36,6 +36,7 @@ devpi_server/mirror.py
|
|
|
36
36
|
devpi_server/model.py
|
|
37
37
|
devpi_server/mythread.py
|
|
38
38
|
devpi_server/passwd.py
|
|
39
|
+
devpi_server/py.typed
|
|
39
40
|
devpi_server/readonly.py
|
|
40
41
|
devpi_server/replica.py
|
|
41
42
|
devpi_server/sizeof.py
|
|
@@ -68,6 +69,7 @@ test_devpi_server/conftest.py
|
|
|
68
69
|
test_devpi_server/example.py
|
|
69
70
|
test_devpi_server/functional.py
|
|
70
71
|
test_devpi_server/plugin.py
|
|
72
|
+
test_devpi_server/py.typed
|
|
71
73
|
test_devpi_server/reqmock.py
|
|
72
74
|
test_devpi_server/simpypi.py
|
|
73
75
|
test_devpi_server/test_auth.py
|
|
@@ -2,6 +2,85 @@
|
|
|
2
2
|
extend = "../pyproject.toml"
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
[tool.ruff.format]
|
|
6
|
+
exclude = [
|
|
7
|
+
"devpi_server/__init__.py",
|
|
8
|
+
"devpi_server/auth.py",
|
|
9
|
+
"devpi_server/auth_basic.py",
|
|
10
|
+
"devpi_server/auth_devpi.py",
|
|
11
|
+
"devpi_server/config.py",
|
|
12
|
+
"devpi_server/exceptions.py",
|
|
13
|
+
"devpi_server/filestore.py",
|
|
14
|
+
"devpi_server/filestore_fs.py",
|
|
15
|
+
"devpi_server/fileutil.py",
|
|
16
|
+
"devpi_server/fsck.py",
|
|
17
|
+
"devpi_server/genconfig.py",
|
|
18
|
+
"devpi_server/hookspecs.py",
|
|
19
|
+
"devpi_server/importexport.py",
|
|
20
|
+
"devpi_server/init.py",
|
|
21
|
+
"devpi_server/interfaces.py",
|
|
22
|
+
"devpi_server/keyfs.py",
|
|
23
|
+
"devpi_server/keyfs_sqlite.py",
|
|
24
|
+
"devpi_server/keyfs_sqlite_fs.py",
|
|
25
|
+
"devpi_server/keyfs_types.py",
|
|
26
|
+
"devpi_server/log.py",
|
|
27
|
+
"devpi_server/main.py",
|
|
28
|
+
"devpi_server/markers.py",
|
|
29
|
+
"devpi_server/middleware.py",
|
|
30
|
+
"devpi_server/mirror.py",
|
|
31
|
+
"devpi_server/model.py",
|
|
32
|
+
"devpi_server/mythread.py",
|
|
33
|
+
"devpi_server/passwd.py",
|
|
34
|
+
"devpi_server/readonly.py",
|
|
35
|
+
"devpi_server/replica.py",
|
|
36
|
+
"devpi_server/sizeof.py",
|
|
37
|
+
"devpi_server/vendor/_pip.py",
|
|
38
|
+
"devpi_server/view_auth.py",
|
|
39
|
+
"devpi_server/views.py",
|
|
40
|
+
"pytest_devpi_server/__init__.py",
|
|
41
|
+
"setup.py",
|
|
42
|
+
"test_devpi_server/conftest.py",
|
|
43
|
+
"test_devpi_server/example.py",
|
|
44
|
+
"test_devpi_server/functional.py",
|
|
45
|
+
"test_devpi_server/plugin.py",
|
|
46
|
+
"test_devpi_server/reqmock.py",
|
|
47
|
+
"test_devpi_server/simpypi.py",
|
|
48
|
+
"test_devpi_server/test_auth.py",
|
|
49
|
+
"test_devpi_server/test_authcheck.py",
|
|
50
|
+
"test_devpi_server/test_config.py",
|
|
51
|
+
"test_devpi_server/test_conftest.py",
|
|
52
|
+
"test_devpi_server/test_filestore.py",
|
|
53
|
+
"test_devpi_server/test_fileutil.py",
|
|
54
|
+
"test_devpi_server/test_fsck.py",
|
|
55
|
+
"test_devpi_server/test_genconfig.py",
|
|
56
|
+
"test_devpi_server/test_importexport.py",
|
|
57
|
+
"test_devpi_server/test_keyfs.py",
|
|
58
|
+
"test_devpi_server/test_keyfs_sqlite_fs.py",
|
|
59
|
+
"test_devpi_server/test_log.py",
|
|
60
|
+
"test_devpi_server/test_main.py",
|
|
61
|
+
"test_devpi_server/test_mirror.py",
|
|
62
|
+
"test_devpi_server/test_mirror_no_project_list.py",
|
|
63
|
+
"test_devpi_server/test_model.py",
|
|
64
|
+
"test_devpi_server/test_mythread.py",
|
|
65
|
+
"test_devpi_server/test_nginx.py",
|
|
66
|
+
"test_devpi_server/test_nginx_replica.py",
|
|
67
|
+
"test_devpi_server/test_permissions.py",
|
|
68
|
+
"test_devpi_server/test_replica.py",
|
|
69
|
+
"test_devpi_server/test_replica_functional.py",
|
|
70
|
+
"test_devpi_server/test_reqmock.py",
|
|
71
|
+
"test_devpi_server/test_stage_customizer.py",
|
|
72
|
+
"test_devpi_server/test_streaming.py",
|
|
73
|
+
"test_devpi_server/test_streaming_nginx.py",
|
|
74
|
+
"test_devpi_server/test_streaming_replica.py",
|
|
75
|
+
"test_devpi_server/test_streaming_replica_nginx.py",
|
|
76
|
+
"test_devpi_server/test_view_auth.py",
|
|
77
|
+
"test_devpi_server/test_views.py",
|
|
78
|
+
"test_devpi_server/test_views_patch.py",
|
|
79
|
+
"test_devpi_server/test_views_push_external.py",
|
|
80
|
+
"test_devpi_server/test_views_status.py",
|
|
81
|
+
]
|
|
82
|
+
|
|
83
|
+
|
|
5
84
|
[tool.ruff.lint]
|
|
6
85
|
extend-ignore = [
|
|
7
86
|
"A001", # cleanup later - variable name shadows builtin
|
|
@@ -59,7 +59,7 @@ if __name__ == "__main__":
|
|
|
59
59
|
'Funding': 'https://github.com/sponsors/devpi',
|
|
60
60
|
'Source Code': 'https://github.com/devpi/devpi'
|
|
61
61
|
},
|
|
62
|
-
version='6.
|
|
62
|
+
version='6.15.0',
|
|
63
63
|
maintainer="Florian Schulze",
|
|
64
64
|
maintainer_email="mail@pyfidelity.com",
|
|
65
65
|
packages=[
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
partial
|
|
@@ -337,15 +337,23 @@ def test_init_server_directory(call_devpi_in_dir, tmpdir):
|
|
|
337
337
|
|
|
338
338
|
|
|
339
339
|
def test_serve_threads(monkeypatch, tmpdir):
|
|
340
|
-
def check_threads(app, host, port, threads, max_request_body_size):
|
|
340
|
+
def check_threads(app, host, port, threads, connection_limit, max_request_body_size):
|
|
341
341
|
assert threads == 100
|
|
342
342
|
monkeypatch.setattr("waitress.serve", check_threads)
|
|
343
343
|
from devpi_server.main import main
|
|
344
344
|
main(["devpi-server", "--threads", "100"])
|
|
345
345
|
|
|
346
346
|
|
|
347
|
+
def test_serve_connection_limit(monkeypatch, tmpdir):
|
|
348
|
+
def check_connection_limit(app, host, port, threads, connection_limit, max_request_body_size):
|
|
349
|
+
assert connection_limit == 200
|
|
350
|
+
monkeypatch.setattr("waitress.serve", check_connection_limit)
|
|
351
|
+
from devpi_server.main import main
|
|
352
|
+
main(["devpi-server", "--connection-limit", "200"])
|
|
353
|
+
|
|
354
|
+
|
|
347
355
|
def test_serve_max_body(monkeypatch, tmpdir):
|
|
348
|
-
def check_max_body(app, host, port, threads, max_request_body_size):
|
|
356
|
+
def check_max_body(app, host, port, threads, connection_limit, max_request_body_size):
|
|
349
357
|
assert max_request_body_size == 42
|
|
350
358
|
monkeypatch.setattr("waitress.serve", check_max_body)
|
|
351
359
|
from devpi_server.main import main
|
|
@@ -1513,10 +1513,10 @@ class TestUsers:
|
|
|
1513
1513
|
model.create_user("user2", password="password")
|
|
1514
1514
|
model.create_user("user3", password="password")
|
|
1515
1515
|
newusers = model.get_usernames().difference(baselist)
|
|
1516
|
-
assert newusers ==
|
|
1516
|
+
assert newusers == {"user1", "user2", "user3"}
|
|
1517
1517
|
model.get_user("user3").delete()
|
|
1518
1518
|
newusers = model.get_usernames().difference(baselist)
|
|
1519
|
-
assert newusers ==
|
|
1519
|
+
assert newusers == {"user1", "user2"}
|
|
1520
1520
|
|
|
1521
1521
|
def test_server_passwd(self, model, monkeypatch):
|
|
1522
1522
|
monkeypatch.setattr(getpass, "getpass", lambda x: "123")
|
|
@@ -12,6 +12,8 @@ class TestCredentialPlugin:
|
|
|
12
12
|
@pytest.fixture
|
|
13
13
|
def plugin(self):
|
|
14
14
|
class Plugin:
|
|
15
|
+
__name__ = 'TestCredentialPlugin'
|
|
16
|
+
|
|
15
17
|
@hookimpl
|
|
16
18
|
def devpiserver_get_credentials(self, request): # noqa: ARG002
|
|
17
19
|
return self.results.pop()
|
|
@@ -25,18 +27,20 @@ class TestCredentialPlugin:
|
|
|
25
27
|
def test_credential_plugin_no_credentials(self, blank_request, dsp, plugin):
|
|
26
28
|
plugin.results = [None]
|
|
27
29
|
request = blank_request()
|
|
28
|
-
assert dsp._get_credentials(request)
|
|
30
|
+
assert dsp._get_credentials(request) == (None, [])
|
|
29
31
|
|
|
30
32
|
def test_credential_plugin_got_credentials(self, blank_request, dsp, plugin):
|
|
31
33
|
plugin.results = [('foo', 'bar')]
|
|
32
34
|
request = blank_request()
|
|
33
|
-
assert dsp._get_credentials(request) == ('foo', 'bar')
|
|
35
|
+
assert dsp._get_credentials(request) == (('foo', 'bar'), ['TestCredentialPlugin'])
|
|
34
36
|
|
|
35
37
|
|
|
36
38
|
class TestCredentialPlugins:
|
|
37
39
|
@pytest.fixture
|
|
38
40
|
def plugin1(self):
|
|
39
41
|
class Plugin:
|
|
42
|
+
__name__ = 'TestCredentialPlugin1'
|
|
43
|
+
|
|
40
44
|
@hookimpl
|
|
41
45
|
def devpiserver_get_credentials(self, request): # noqa: ARG002
|
|
42
46
|
return self.results.pop()
|
|
@@ -45,6 +49,8 @@ class TestCredentialPlugins:
|
|
|
45
49
|
@pytest.fixture
|
|
46
50
|
def plugin2(self):
|
|
47
51
|
class Plugin:
|
|
52
|
+
__name__ = 'TestCredentialPlugin2'
|
|
53
|
+
|
|
48
54
|
@hookimpl
|
|
49
55
|
def devpiserver_get_credentials(self, request): # noqa: ARG002
|
|
50
56
|
return self.results.pop()
|
|
@@ -62,32 +68,36 @@ class TestCredentialPlugins:
|
|
|
62
68
|
plugin1.results = [None]
|
|
63
69
|
plugin2.results = [None]
|
|
64
70
|
request = blank_request()
|
|
65
|
-
assert dsp._get_credentials(request)
|
|
71
|
+
assert dsp._get_credentials(request) == (None, [])
|
|
66
72
|
|
|
67
73
|
def test_credential_plugins_got_one_credential(self, blank_request, dsp, plugin1, plugin2):
|
|
68
74
|
plugin1.results = [('foo', 'bar')]
|
|
69
75
|
plugin2.results = [None]
|
|
70
76
|
request = blank_request()
|
|
71
|
-
assert dsp._get_credentials(request) == ('foo', 'bar')
|
|
77
|
+
assert dsp._get_credentials(request) == (('foo', 'bar'), ['TestCredentialPlugin1'])
|
|
72
78
|
|
|
73
79
|
def test_credential_plugins_got_another_credential(self, blank_request, dsp, plugin1, plugin2):
|
|
74
80
|
plugin1.results = [None]
|
|
75
81
|
plugin2.results = [('foo', 'bar')]
|
|
76
82
|
request = blank_request()
|
|
77
|
-
assert dsp._get_credentials(request) == ('foo', 'bar')
|
|
83
|
+
assert dsp._get_credentials(request) == (('foo', 'bar'), ['TestCredentialPlugin2'])
|
|
78
84
|
|
|
79
85
|
def test_credential_plugins_got_two_credential(self, blank_request, dsp, plugin1, plugin2):
|
|
80
86
|
plugin1.results = [('ham', 'egg')]
|
|
81
87
|
plugin2.results = [('foo', 'bar')]
|
|
82
88
|
request = blank_request()
|
|
83
89
|
# one of them wins, depends on entry point order and is undefined
|
|
84
|
-
assert dsp._get_credentials(request) in [
|
|
90
|
+
assert dsp._get_credentials(request) in [
|
|
91
|
+
(('ham', 'egg'), ['TestCredentialPlugin1']),
|
|
92
|
+
(('foo', 'bar'), ['TestCredentialPlugin2'])]
|
|
85
93
|
|
|
86
94
|
|
|
87
95
|
class TestHeaderCredentialPlugin:
|
|
88
96
|
@pytest.fixture
|
|
89
97
|
def plugin(self):
|
|
90
98
|
class Plugin:
|
|
99
|
+
__name__ = 'TestHeaderCredentialPlugin'
|
|
100
|
+
|
|
91
101
|
@hookimpl
|
|
92
102
|
def devpiserver_get_credentials(self, request):
|
|
93
103
|
if 'X-Devpi-User' in request.headers:
|
|
@@ -101,13 +111,13 @@ class TestHeaderCredentialPlugin:
|
|
|
101
111
|
@pytest.mark.usefixtures("plugin")
|
|
102
112
|
def test_credential_plugin_no_credentials(self, blank_request, dsp):
|
|
103
113
|
request = blank_request()
|
|
104
|
-
assert dsp._get_credentials(request)
|
|
114
|
+
assert dsp._get_credentials(request) == (None, [])
|
|
105
115
|
|
|
106
116
|
@pytest.mark.usefixtures("plugin")
|
|
107
117
|
def test_credential_plugin_got_credentials(self, blank_request, dsp):
|
|
108
118
|
request = blank_request()
|
|
109
119
|
request.headers['X-Devpi-User'] = 'foo'
|
|
110
|
-
assert dsp._get_credentials(request) == ('foo', '')
|
|
120
|
+
assert dsp._get_credentials(request) == (('foo', ''), ['TestHeaderCredentialPlugin'])
|
|
111
121
|
|
|
112
122
|
|
|
113
123
|
class TestDevpiSecurityPolicy:
|
|
@@ -1980,7 +1980,7 @@ def test_delete_volatile_force(mapp, testapp):
|
|
|
1980
1980
|
|
|
1981
1981
|
|
|
1982
1982
|
@pytest.mark.nomocking
|
|
1983
|
-
def test_mirror_use_external_urls(mapp, simpypi, testapp
|
|
1983
|
+
def test_mirror_use_external_urls(mapp, simpypi, testapp):
|
|
1984
1984
|
indexconfig = dict(
|
|
1985
1985
|
type="mirror",
|
|
1986
1986
|
mirror_url=simpypi.simpleurl,
|
|
@@ -1989,18 +1989,18 @@ def test_mirror_use_external_urls(mapp, simpypi, testapp, xom):
|
|
|
1989
1989
|
volatile=True)
|
|
1990
1990
|
api = mapp.create_and_use(indexconfig=indexconfig)
|
|
1991
1991
|
name = "pytest"
|
|
1992
|
-
pkgver = "
|
|
1992
|
+
pkgver = f"{name}-2.6.zip"
|
|
1993
1993
|
simpypi.add_release(name, pkgver=pkgver)
|
|
1994
|
-
simpypi.add_file('
|
|
1995
|
-
r = testapp.get(api.index
|
|
1994
|
+
simpypi.add_file(f'/{name}/{pkgver}', b'123')
|
|
1995
|
+
r = testapp.get(f'{api.index}/+simple/{name}')
|
|
1996
1996
|
(link,) = sorted(
|
|
1997
|
-
x.get('href').replace('../../', '
|
|
1997
|
+
x.get('href').replace('../../', f'/{api.stagename}/')
|
|
1998
1998
|
for x in getlinks(r.text))
|
|
1999
1999
|
path = link[1:]
|
|
2000
2000
|
assert '2.6' in path
|
|
2001
2001
|
# we should get a redirect to the original URL
|
|
2002
2002
|
r = testapp.xget(302, link, follow=False)
|
|
2003
|
-
assert r.location == "
|
|
2003
|
+
assert r.location == f"{simpypi.baseurl}/pytest/pytest-2.6.zip"
|
|
2004
2004
|
with testapp.xom.keyfs.read_transaction():
|
|
2005
2005
|
assert not getentry(testapp, path).file_exists()
|
|
2006
2006
|
# now turn external urls off
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = '6.14.0'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/cfg/nginx-devpi-caching-http.conf.template
RENAMED
|
File without changes
|
|
File without changes
|
{devpi-server-6.14.0 → devpi-server-6.15.0}/devpi_server/cfg/nginx-devpi-caching-proxy.conf.template
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/importexportdata/nouser/dataindex.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_mirror_no_project_list.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{devpi-server-6.14.0 → devpi-server-6.15.0}/test_devpi_server/test_streaming_replica_nginx.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|