Skip to content

Commit 90edfad

Browse files
authored
Merge pull request #21617 from mvdbeek/fix-toolshed-tests
Fix toolshed tests on Python 3.14
2 parents 8aa8f88 + 8e04871 commit 90edfad

5 files changed

Lines changed: 40 additions & 28 deletions

File tree

lib/galaxy/dependencies/pinned-requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,8 @@ markdown-it-py==4.0.0 ; python_full_version >= '3.11'
170170
markupsafe==3.0.3
171171
mcp==1.25.0 ; python_full_version >= '3.10'
172172
mdurl==0.1.2
173-
mercurial==7.1.2
173+
mercurial==7.1.2 ; python_version < '3.14'
174+
mercurial==7.2rc0 ; python_version >= '3.14'
174175
mistralai==1.9.11
175176
mistune==3.1.4
176177
more-itertools==10.8.0

lib/galaxy/tool_shed/metadata/metadata_generator.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,9 @@ def generate_metadata_for_changeset_revision(self):
392392
if invalid_tool_configs:
393393
metadata_dict["invalid_tools"] = invalid_tool_configs
394394
self.metadata_dict = metadata_dict
395-
remove_dir(work_dir)
395+
# Only remove work_dir if not resetting all metadata - in that case the caller handles cleanup
396+
if not self.resetting_all_metadata_on_repository:
397+
remove_dir(work_dir)
396398

397399
def generate_package_dependency_metadata(self, elem, valid_tool_dependencies_dict, invalid_tool_dependencies_dict):
398400
"""

lib/tool_shed/metadata/repository_metadata_manager.py

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -799,14 +799,24 @@ def reset_all_metadata_on_repository_in_tool_shed(self, repository_clone_url=Non
799799
metadata_dict = None
800800
ancestor_changeset_revision = None
801801
ancestor_metadata_dict = None
802-
for changeset in self.repository.get_changesets_for_setting_metadata(self.app):
803-
work_dir = tempfile.mkdtemp(prefix="tmp-toolshed-ramorits")
804-
ctx = repo[changeset]
805-
log.debug("Cloning repository changeset revision: %s", str(ctx.rev()))
806-
assert self.repository_clone_url
807-
repository_clone_url = repository_clone_url or self.repository_clone_url
808-
cloned_ok, error_message = hg_util.clone_repository(repository_clone_url, work_dir, str(ctx.rev()))
809-
if cloned_ok:
802+
803+
# Clone repository once, then update for each changeset revision.
804+
work_dir = tempfile.mkdtemp(prefix="tmp-toolshed-ramorits")
805+
assert self.repository_clone_url
806+
repository_clone_url = repository_clone_url or self.repository_clone_url
807+
log.debug("Cloning repository for metadata reset")
808+
cloned_ok, error_message = hg_util.clone_repository(repository_clone_url, work_dir)
809+
if not cloned_ok:
810+
log.error(f"Failed to clone repository: {error_message}")
811+
basic_util.remove_dir(work_dir)
812+
self._clean_repository_metadata(changeset_revisions)
813+
return
814+
815+
try:
816+
for changeset in self.repository.get_changesets_for_setting_metadata(self.app):
817+
ctx = repo[changeset]
818+
log.debug("Updating to changeset revision: %s", str(ctx.rev()))
819+
hg_util.update_repository(work_dir, str(ctx.rev()))
810820
log.debug("Generating metadata for changeset revision: %s", str(ctx.rev()))
811821
self.set_changeset_revision(str(ctx))
812822
self.set_repository_files_dir(work_dir)
@@ -823,11 +833,11 @@ def reset_all_metadata_on_repository_in_tool_shed(self, repository_clone_url=Non
823833
# self.SUBSET - ancestor metadata is a subset of current metadata, so continue from current
824834
# self.NOT_EQUAL_AND_NOT_SUBSET - ancestor metadata is neither equal to nor a subset of current
825835
# metadata, so persist ancestor metadata.
826-
log.info(f"amd {ancestor_metadata_dict}")
836+
log.debug(f"amd {ancestor_metadata_dict}")
827837
comparison = self.compare_changeset_revisions(
828838
ancestor_changeset_revision, ancestor_metadata_dict
829839
)
830-
log.info(f"comparison {comparison}")
840+
log.debug(f"comparison {comparison}")
831841
if comparison in [self.NO_METADATA, self.EQUAL, self.SUBSET]:
832842
ancestor_changeset_revision = self.changeset_revision
833843
ancestor_metadata_dict = self.metadata_dict
@@ -858,6 +868,7 @@ def reset_all_metadata_on_repository_in_tool_shed(self, repository_clone_url=Non
858868
changeset_revisions.append(metadata_changeset_revision)
859869
ancestor_changeset_revision = None
860870
ancestor_metadata_dict = None
871+
finally:
861872
basic_util.remove_dir(work_dir)
862873
# Delete all repository_metadata records for this repository that do not have a changeset_revision
863874
# value in changeset_revisions.

lib/tool_shed/webapp/controllers/repository.py

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@
44
import string
55
import tempfile
66
from datetime import date
7+
from typing import Any
78

89
from mercurial import (
9-
cmdutil,
10-
commands,
1110
mdiff,
1211
patch,
1312
)
@@ -74,15 +73,15 @@
7473
malicious_error_can_push = " Correct this changeset as soon as possible, it potentially produces malicious behavior or contains inappropriate content."
7574

7675

77-
def get_mercurial_default_options_dict(command):
78-
"""Borrowed from repoman - get default parameters for a mercurial command."""
79-
possible = cmdutil.findpossible(command, commands.table)
80-
# Mercurial >= 3.4 returns a tuple whose first element is the old return dict
81-
if type(possible) is tuple:
82-
possible = possible[0]
83-
if len(possible) != 1:
84-
raise Exception(f'unable to find mercurial command "{command}"')
85-
return {r[1].replace(b"-", b"_"): r[2] for r in next(iter(possible.values()))[1][1]}
76+
def get_mercurial_default_options_dict(command: str) -> dict[str, Any]:
77+
"""Get default parameters for a mercurial command."""
78+
# Use mdiff.diffopts defaults directly instead of introspecting command table
79+
# (the old cmdutil.findpossible API was removed in Mercurial 7.2)
80+
if command == "diff":
81+
# Convert byte keys to strings but preserve value types (int, bool)
82+
# as mdiff.diffopts expects properly typed values
83+
return {(k.decode("utf-8") if isinstance(k, bytes) else k): v for k, v in mdiff.diffopts.defaults.items()}
84+
raise Exception(f'unable to find mercurial command "{command}"')
8685

8786

8887
class RepositoryController(BaseUIController, ratings_util.ItemRatings):
@@ -2366,10 +2365,8 @@ def view_changeset(self, trans, id, ctx_str, **kwd):
23662365
else:
23672366
ctx_child = None
23682367
diffs = []
2369-
options_dict = get_mercurial_default_options_dict(b"diff")
2370-
# Not quite sure if the following settings make any difference, but with a combination of them and the size check on each
2371-
# diff, we don't run out of memory when viewing the changelog of the cisortho2 repository on the test tool shed.
2372-
options_dict = {util.unicodify(k): util.unicodify(v) for k, v in options_dict.items()}
2368+
# Get default diff options with string keys and properly typed values
2369+
options_dict = get_mercurial_default_options_dict("diff")
23732370
options_dict["maxfile"] = basic_util.MAXDIFFSIZE
23742371
options_dict["maxtotal"] = basic_util.MAXDIFFSIZE
23752372
diffopts = mdiff.diffopts(**options_dict)

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ dependencies = [
5757
"Mako",
5858
"Markdown",
5959
"MarkupSafe",
60-
"mercurial>=6.8.2", # Python 3.13 support
60+
"mercurial>=6.8.2 ; python_version<'3.14'", # Python 3.13 support
61+
"mercurial>=7.2rc0 ; python_version>='3.14'", # Python 3.14 support
6162
"mrcfile",
6263
"more-itertools",
6364
"msal",

0 commit comments

Comments
 (0)