devpi-web 5.0.0__tar.gz → 5.0.1__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_web-5.0.0 → devpi_web-5.0.1}/CHANGELOG +10 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/CHANGELOG.short.rst +10 -11
- {devpi_web-5.0.0 → devpi_web-5.0.1}/PKG-INFO +11 -12
- devpi_web-5.0.1/devpi_web/__init__.py +1 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/doczip.py +6 -3
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web.egg-info/PKG-INFO +11 -12
- {devpi_web-5.0.0 → devpi_web-5.0.1}/tests/test_indexing.py +51 -0
- devpi_web-5.0.0/devpi_web/__init__.py +0 -1
- {devpi_web-5.0.0 → devpi_web-5.0.1}/.flake8 +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/LICENSE +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/MANIFEST.in +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/README.rst +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/clear_index.py +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/compat.py +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/config.py +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/description.py +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/hookspecs.py +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/indexing.py +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/macroregistry.py +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/macros.py +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/main.py +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/null_index.py +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/static/common.js +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/static/docview.js +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/static/favicon.ico +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/static/jquery-3.6.0.min.js +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/static/search.js +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/static/style.css +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/templates/doc.pt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/templates/error.pt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/templates/favicon.pt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/templates/footer.pt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/templates/footer_versions.pt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/templates/head.pt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/templates/header.pt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/templates/header_breadcrumbs.pt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/templates/header_search.pt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/templates/header_status.pt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/templates/html_head_css.pt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/templates/html_head_scripts.pt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/templates/index.pt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/templates/logo.pt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/templates/notfound.pt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/templates/project.pt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/templates/query_docs.pt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/templates/root.pt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/templates/root_above_user_index_list.pt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/templates/root_below_user_index_list.pt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/templates/search.pt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/templates/search_help.pt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/templates/status.pt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/templates/status_badge.pt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/templates/toxresult.pt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/templates/toxresults.pt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/templates/user.pt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/templates/version.pt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/views.py +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web/whoosh_index.py +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web.egg-info/SOURCES.txt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web.egg-info/dependency_links.txt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web.egg-info/entry_points.txt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web.egg-info/requires.txt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/devpi_web.egg-info/top_level.txt +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/mypy.ini +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/pyproject.toml +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/setup.cfg +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/tests/conftest.py +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/tests/test_macro_registry.py +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/tests/test_main.py +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/tests/test_theme.py +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/tests/test_views.py +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/tests/test_views_docs.py +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/tests/test_views_misc.py +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/tests/test_views_search.py +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/tests/test_views_toxresults.py +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/tests/test_whoosh_index.py +0 -0
- {devpi_web-5.0.0 → devpi_web-5.0.1}/tox.ini +0 -0
|
@@ -9,6 +9,16 @@ Changelog
|
|
|
9
9
|
|
|
10
10
|
.. towncrier release notes start
|
|
11
11
|
|
|
12
|
+
5.0.1 (2025-06-15)
|
|
13
|
+
==================
|
|
14
|
+
|
|
15
|
+
Bug Fixes
|
|
16
|
+
---------
|
|
17
|
+
|
|
18
|
+
- Fix traceback during unpacking of documentation in some cases.
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
12
22
|
5.0.0 (2025-06-12)
|
|
13
23
|
==================
|
|
14
24
|
|
|
@@ -106,14 +116,3 @@ Bug Fixes
|
|
|
106
116
|
- Fix #970: overwrite fixed html/body heights like ``100%`` in documentation iframe content.
|
|
107
117
|
|
|
108
118
|
|
|
109
|
-
|
|
110
|
-
4.2.1 (2023-07-02)
|
|
111
|
-
==================
|
|
112
|
-
|
|
113
|
-
Bug Fixes
|
|
114
|
-
---------
|
|
115
|
-
|
|
116
|
-
- Fix #953: Exception when browsers send ETag for documentation pages.
|
|
117
|
-
|
|
118
|
-
- Fix #980: Remove long deprecated backward compatibility for old pluggy versions to fix error with pluggy 1.1.0.
|
|
119
|
-
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: devpi-web
|
|
3
|
-
Version: 5.0.
|
|
3
|
+
Version: 5.0.1
|
|
4
4
|
Summary: devpi-web: a web view for devpi-server
|
|
5
5
|
Maintainer-email: Florian Schulze <mail@pyfidelity.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -87,6 +87,16 @@ Changelog
|
|
|
87
87
|
|
|
88
88
|
.. towncrier release notes start
|
|
89
89
|
|
|
90
|
+
5.0.1 (2025-06-15)
|
|
91
|
+
==================
|
|
92
|
+
|
|
93
|
+
Bug Fixes
|
|
94
|
+
---------
|
|
95
|
+
|
|
96
|
+
- Fix traceback during unpacking of documentation in some cases.
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
|
|
90
100
|
5.0.0 (2025-06-12)
|
|
91
101
|
==================
|
|
92
102
|
|
|
@@ -184,14 +194,3 @@ Bug Fixes
|
|
|
184
194
|
- Fix #970: overwrite fixed html/body heights like ``100%`` in documentation iframe content.
|
|
185
195
|
|
|
186
196
|
|
|
187
|
-
|
|
188
|
-
4.2.1 (2023-07-02)
|
|
189
|
-
==================
|
|
190
|
-
|
|
191
|
-
Bug Fixes
|
|
192
|
-
---------
|
|
193
|
-
|
|
194
|
-
- Fix #953: Exception when browsers send ETag for documentation pages.
|
|
195
|
-
|
|
196
|
-
- Fix #980: Remove long deprecated backward compatibility for old pluggy versions to fix error with pluggy 1.1.0.
|
|
197
|
-
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "5.0.1"
|
|
@@ -33,7 +33,9 @@ def locked_unpack_path(stage, name, version, *, remove_lock_file=False):
|
|
|
33
33
|
hash_path = unpack_path.with_suffix(".hash")
|
|
34
34
|
try:
|
|
35
35
|
hash_path.parent.mkdir(parents=True, exist_ok=True)
|
|
36
|
-
with hash_path.open("
|
|
36
|
+
with suppress(FileExistsError), hash_path.open("x"):
|
|
37
|
+
pass
|
|
38
|
+
with hash_path.open("r+") as hash_file:
|
|
37
39
|
if fcntl:
|
|
38
40
|
fcntl.flock(hash_file, fcntl.LOCK_EX)
|
|
39
41
|
try:
|
|
@@ -90,12 +92,13 @@ def unpack_docs(stage, name, version, entry):
|
|
|
90
92
|
# we are not losing the original zip file anyway
|
|
91
93
|
with locked_unpack_path(stage, name, version) as (hash_file, unpack_path):
|
|
92
94
|
hash_file.seek(0)
|
|
93
|
-
|
|
95
|
+
hash_spec = hash_file.read().strip()
|
|
96
|
+
if hash_spec == entry.best_available_hash_spec:
|
|
94
97
|
return unpack_path
|
|
95
98
|
if unpack_path.exists():
|
|
96
99
|
with suppress(FileNotFoundError):
|
|
97
100
|
# there is a rare possibility of a race condition here
|
|
98
|
-
|
|
101
|
+
shutil.rmtree(unpack_path)
|
|
99
102
|
if not entry.file_exists():
|
|
100
103
|
return unpack_path
|
|
101
104
|
with entry.file_open_read() as f, Archive(f) as archive:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: devpi-web
|
|
3
|
-
Version: 5.0.
|
|
3
|
+
Version: 5.0.1
|
|
4
4
|
Summary: devpi-web: a web view for devpi-server
|
|
5
5
|
Maintainer-email: Florian Schulze <mail@pyfidelity.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -87,6 +87,16 @@ Changelog
|
|
|
87
87
|
|
|
88
88
|
.. towncrier release notes start
|
|
89
89
|
|
|
90
|
+
5.0.1 (2025-06-15)
|
|
91
|
+
==================
|
|
92
|
+
|
|
93
|
+
Bug Fixes
|
|
94
|
+
---------
|
|
95
|
+
|
|
96
|
+
- Fix traceback during unpacking of documentation in some cases.
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
|
|
90
100
|
5.0.0 (2025-06-12)
|
|
91
101
|
==================
|
|
92
102
|
|
|
@@ -184,14 +194,3 @@ Bug Fixes
|
|
|
184
194
|
- Fix #970: overwrite fixed html/body heights like ``100%`` in documentation iframe content.
|
|
185
195
|
|
|
186
196
|
|
|
187
|
-
|
|
188
|
-
4.2.1 (2023-07-02)
|
|
189
|
-
==================
|
|
190
|
-
|
|
191
|
-
Bug Fixes
|
|
192
|
-
---------
|
|
193
|
-
|
|
194
|
-
- Fix #953: Exception when browsers send ETag for documentation pages.
|
|
195
|
-
|
|
196
|
-
- Fix #980: Remove long deprecated backward compatibility for old pluggy versions to fix error with pluggy 1.1.0.
|
|
197
|
-
|
|
@@ -65,6 +65,57 @@ def test_doc_unpack_cleanup(mapp, testapp):
|
|
|
65
65
|
assert not path.joinpath("foo.html").exists()
|
|
66
66
|
|
|
67
67
|
|
|
68
|
+
@pytest.mark.with_notifier
|
|
69
|
+
def test_doc_unpack_hash_mismatch(caplog, mapp):
|
|
70
|
+
from devpi_web.doczip import get_unpack_path
|
|
71
|
+
from devpi_web.doczip import locked_unpack_path
|
|
72
|
+
from devpi_web.doczip import unpack_docs
|
|
73
|
+
api = mapp.create_and_use()
|
|
74
|
+
content = zip_dict({
|
|
75
|
+
"index.html": "<html><body>2.6</body></html>"})
|
|
76
|
+
mapp.set_versiondata({"name": "pkg1", "version": "2.6"})
|
|
77
|
+
mapp.upload_doc("pkg1.zip", content, "pkg1", "2.6", code=200,
|
|
78
|
+
waithooks=True)
|
|
79
|
+
with mapp.xom.keyfs.read_transaction():
|
|
80
|
+
stage = mapp.xom.model.getstage(api.stagename)
|
|
81
|
+
linkstore = stage.get_linkstore_perstage("pkg1", "2.6")
|
|
82
|
+
(link,) = linkstore.get_links(rel='doczip')
|
|
83
|
+
path = unpack_docs(stage, 'pkg1', '2.6', link.entry)
|
|
84
|
+
assert path.exists()
|
|
85
|
+
# make sure there is a path that is not existing in the zip,
|
|
86
|
+
# so we can test for its removal
|
|
87
|
+
foo_path = path.joinpath("foo.html")
|
|
88
|
+
assert not foo_path.exists()
|
|
89
|
+
foo_path.touch()
|
|
90
|
+
assert foo_path.exists()
|
|
91
|
+
with mapp.xom.keyfs.read_transaction():
|
|
92
|
+
# now mess with the hash file and make it bigger than the hash_spec,
|
|
93
|
+
# as there was a problem with writing the file correctly before
|
|
94
|
+
bad_hash = "foo" * 300
|
|
95
|
+
with locked_unpack_path(stage, "pkg1", "2.6") as (hash_file, _unpack_path):
|
|
96
|
+
hash_file.seek(0)
|
|
97
|
+
hash_file.write(bad_hash)
|
|
98
|
+
hash_path = get_unpack_path(stage, "pkg1", "2.6").with_suffix(".hash")
|
|
99
|
+
# make sure it is set correctly to the bad value
|
|
100
|
+
assert hash_path.read_text() == bad_hash
|
|
101
|
+
stage = mapp.xom.model.getstage(api.stagename)
|
|
102
|
+
linkstore = stage.get_linkstore_perstage("pkg1", "2.6")
|
|
103
|
+
(link,) = linkstore.get_links(rel='doczip')
|
|
104
|
+
caplog.clear()
|
|
105
|
+
unpack_docs(stage, 'pkg1', '2.6', link.entry)
|
|
106
|
+
assert len(caplog.getrecords("unpacked")) == 1
|
|
107
|
+
assert hash_path.read_text() == link.entry.best_available_hash_spec
|
|
108
|
+
# unpack again
|
|
109
|
+
new_path = unpack_docs(stage, 'pkg1', '2.6', link.entry)
|
|
110
|
+
assert len(caplog.getrecords("unpacked")) == 1
|
|
111
|
+
assert new_path == path
|
|
112
|
+
assert new_path.exists()
|
|
113
|
+
assert "2.6" in new_path.joinpath("index.html").read_text()
|
|
114
|
+
# the hash was written more than once
|
|
115
|
+
assert new_path.with_suffix(".hash").read_text() == link.entry.best_available_hash_spec
|
|
116
|
+
assert not foo_path.exists()
|
|
117
|
+
|
|
118
|
+
|
|
68
119
|
@pytest.mark.with_notifier
|
|
69
120
|
def test_empty_doczip(mapp):
|
|
70
121
|
from devpi_server.filestore import get_hashes
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "5.0.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
|
|
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
|