Skip to content

Commit 59bc1bc

Browse files
hroncokfrenzymadness
authored andcommitted
Allow passing explicit releasever
I do not have "fedora-40" repos configured. I only have the normal fedora repos. Now I can use this like this: $ python fedora_revdep_check.py --repo={fedora,updates}{,-source} --releasever=43 python-dotenv 1.2.2
1 parent 17bd4d3 commit 59bc1bc

2 files changed

Lines changed: 96 additions & 30 deletions

File tree

fedora_revdep_check.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,18 @@
3737
class FedoraRevDepChecker:
3838
"""Check reverse dependencies for Fedora package updates."""
3939

40-
def __init__(self, verbose=False, base=None, repos=None):
40+
def __init__(self, verbose=False, base=None, repos=None, releasever=None):
4141
"""Initialize the checker with DNF base and cached repo data.
4242
4343
Args:
4444
verbose: Enable verbose output
4545
base: Optional DNF base object for testing (if None, creates real DNF base)
4646
repos: List of repository IDs to enable (default: ['rawhide', 'rawhide-source', 'koji', 'koji-source'])
47+
releasever: Fedora release version (e.g. '44', 'rawhide'). Auto-detected from repos if not set.
4748
"""
4849
self.verbose = verbose
4950
self.base = base
51+
self.releasever = releasever
5052
self.repos = repos if repos is not None else ['rawhide', 'rawhide-source', 'koji', 'koji-source']
5153
if self.base is None:
5254
self._init_dnf()
@@ -114,19 +116,17 @@ def _init_dnf(self):
114116
print("Initializing DNF 5 and loading repository metadata...")
115117
self.base = libdnf5.base.Base()
116118

117-
# Detect releasever from first repo name, or use 'rawhide' as default
118-
# Extract version from repo names like 'fedora-40', 'f40', or use 'rawhide'
119-
releasever = 'rawhide'
120-
if self.repos:
121-
first_repo = self.repos[0]
122-
# Check if repo contains a version number
123-
import re
124-
version_match = re.search(r'(\d+)', first_repo)
125-
if version_match:
126-
releasever = version_match.group(1)
127-
elif 'rawhide' not in first_repo.lower():
128-
# If no version found and not rawhide, still use rawhide as fallback
129-
releasever = 'rawhide'
119+
# Use explicitly provided releasever, or detect from repo names
120+
if self.releasever:
121+
releasever = self.releasever
122+
else:
123+
releasever = 'rawhide'
124+
if self.repos:
125+
first_repo = self.repos[0]
126+
import re
127+
version_match = re.search(r'(\d+)', first_repo)
128+
if version_match:
129+
releasever = version_match.group(1)
130130

131131
# Configure releasever
132132
vars_map = self.base.get_vars()
@@ -679,6 +679,7 @@ def main():
679679
%(prog)s python-requests 2.32.0 --verbose
680680
%(prog)s pytest 8.0.0 --repo fedora --repo fedora-source
681681
%(prog)s numpy 2.0.0 --repo fedora-40 --repo fedora-40-source
682+
%(prog)s pytest 8.0.0 --releasever 44
682683
"""
683684
)
684685

@@ -690,11 +691,14 @@ def main():
690691
help='Repository ID to enable (can be specified multiple times). '
691692
'Default: rawhide, rawhide-source, koji, and koji-source. '
692693
'Known repositories will be auto-configured if not in /etc/yum.repos.d/')
694+
parser.add_argument('--releasever',
695+
help='Fedora release version (e.g. 44, rawhide). '
696+
'Auto-detected from repo names if not specified.')
693697

694698
args = parser.parse_args()
695699

696700
try:
697-
checker = FedoraRevDepChecker(verbose=args.verbose, repos=args.repos)
701+
checker = FedoraRevDepChecker(verbose=args.verbose, repos=args.repos, releasever=args.releasever)
698702
results = checker.simulate_version_change(args.srpm_name, args.new_version)
699703
checker.print_results(results)
700704

tests/e2e/test_full_workflow.py

Lines changed: 77 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,68 @@
99
from fedora_revdep_check import main, FedoraRevDepChecker
1010

1111

12+
class TestReleasever:
13+
"""Test --releasever CLI argument and auto-detection logic."""
14+
15+
def test_releasever_passed_to_checker(self, monkeypatch, mock_dnf_base):
16+
"""Test that --releasever CLI arg is passed through to FedoraRevDepChecker."""
17+
monkeypatch.setattr('sys.argv', ['fedora-revdep-check', 'pytest', '8.0.0', '--releasever', '44'])
18+
19+
captured_releasever = []
20+
original_init = FedoraRevDepChecker.__init__
21+
22+
def mock_init(self, verbose=False, base=None, repos=None, releasever=None):
23+
captured_releasever.append(releasever)
24+
original_init(self, verbose=verbose, base=mock_dnf_base if base is None else base, repos=repos, releasever=releasever)
25+
26+
monkeypatch.setattr(FedoraRevDepChecker, '__init__', mock_init)
27+
main()
28+
29+
assert captured_releasever == ['44']
30+
31+
def test_releasever_none_when_not_specified(self, monkeypatch, mock_dnf_base):
32+
"""Test that releasever is None when --releasever is not passed."""
33+
monkeypatch.setattr('sys.argv', ['fedora-revdep-check', 'pytest', '8.0.0'])
34+
35+
captured_releasever = []
36+
original_init = FedoraRevDepChecker.__init__
37+
38+
def mock_init(self, verbose=False, base=None, repos=None, releasever=None):
39+
captured_releasever.append(releasever)
40+
original_init(self, verbose=verbose, base=mock_dnf_base if base is None else base, repos=repos, releasever=releasever)
41+
42+
monkeypatch.setattr(FedoraRevDepChecker, '__init__', mock_init)
43+
main()
44+
45+
assert captured_releasever == [None]
46+
47+
def test_releasever_rawhide(self, monkeypatch, mock_dnf_base):
48+
"""Test that --releasever accepts 'rawhide'."""
49+
monkeypatch.setattr('sys.argv', ['fedora-revdep-check', 'pytest', '8.0.0', '--releasever', 'rawhide'])
50+
51+
captured_releasever = []
52+
original_init = FedoraRevDepChecker.__init__
53+
54+
def mock_init(self, verbose=False, base=None, repos=None, releasever=None):
55+
captured_releasever.append(releasever)
56+
original_init(self, verbose=verbose, base=mock_dnf_base if base is None else base, repos=repos, releasever=releasever)
57+
58+
monkeypatch.setattr(FedoraRevDepChecker, '__init__', mock_init)
59+
main()
60+
61+
assert captured_releasever == ['rawhide']
62+
63+
def test_releasever_stored_on_instance(self, mock_dnf_base):
64+
"""Test that releasever is stored on the checker instance."""
65+
checker = FedoraRevDepChecker(verbose=False, base=mock_dnf_base, releasever='42')
66+
assert checker.releasever == '42'
67+
68+
def test_releasever_default_is_none(self, mock_dnf_base):
69+
"""Test that releasever defaults to None."""
70+
checker = FedoraRevDepChecker(verbose=False, base=mock_dnf_base)
71+
assert checker.releasever is None
72+
73+
1274
class TestFullWorkflow:
1375
"""Test complete CLI workflow through main() function."""
1476

@@ -19,8 +81,8 @@ def test_main_with_conflicts_exit_code_one(self, monkeypatch, jupyterlab_base, c
1981
# Mock FedoraRevDepChecker to use test base
2082
original_init = FedoraRevDepChecker.__init__
2183

22-
def mock_init(self, verbose=False, base=None, repos=None):
23-
original_init(self, verbose=verbose, base=jupyterlab_base if base is None else base, repos=repos)
84+
def mock_init(self, verbose=False, base=None, repos=None, releasever=None):
85+
original_init(self, verbose=verbose, base=jupyterlab_base if base is None else base, repos=repos, releasever=releasever)
2486

2587
monkeypatch.setattr(FedoraRevDepChecker, '__init__', mock_init)
2688

@@ -40,8 +102,8 @@ def test_main_verbose_flag(self, monkeypatch, mock_pytest_base, capsys):
40102

41103
original_init = FedoraRevDepChecker.__init__
42104

43-
def mock_init(self, verbose=False, base=None, repos=None):
44-
original_init(self, verbose=verbose, base=mock_pytest_base if base is None else base, repos=repos)
105+
def mock_init(self, verbose=False, base=None, repos=None, releasever=None):
106+
original_init(self, verbose=verbose, base=mock_pytest_base if base is None else base, repos=repos, releasever=releasever)
45107

46108
monkeypatch.setattr(FedoraRevDepChecker, '__init__', mock_init)
47109

@@ -58,8 +120,8 @@ def test_main_nonexistent_package(self, monkeypatch, mock_dnf_base, capsys):
58120

59121
original_init = FedoraRevDepChecker.__init__
60122

61-
def mock_init(self, verbose=False, base=None, repos=None):
62-
original_init(self, verbose=verbose, base=mock_dnf_base if base is None else base, repos=repos)
123+
def mock_init(self, verbose=False, base=None, repos=None, releasever=None):
124+
original_init(self, verbose=verbose, base=mock_dnf_base if base is None else base, repos=repos, releasever=releasever)
63125

64126
monkeypatch.setattr(FedoraRevDepChecker, '__init__', mock_init)
65127

@@ -77,7 +139,7 @@ def test_main_exception_handling(self, monkeypatch, capsys):
77139
monkeypatch.setattr('sys.argv', ['fedora-revdep-check', 'test', '1.0.0'])
78140

79141
# Mock FedoraRevDepChecker to raise an exception
80-
def mock_init(self, verbose=False, base=None, repos=None):
142+
def mock_init(self, verbose=False, base=None, repos=None, releasever=None):
81143
raise RuntimeError("Test error message")
82144

83145
monkeypatch.setattr(FedoraRevDepChecker, '__init__', mock_init)
@@ -96,8 +158,8 @@ def test_main_output_format_consistency(self, monkeypatch, jupyterlab_base, caps
96158

97159
original_init = FedoraRevDepChecker.__init__
98160

99-
def mock_init(self, verbose=False, base=None, repos=None):
100-
original_init(self, verbose=verbose, base=jupyterlab_base if base is None else base, repos=repos)
161+
def mock_init(self, verbose=False, base=None, repos=None, releasever=None):
162+
original_init(self, verbose=verbose, base=jupyterlab_base if base is None else base, repos=repos, releasever=releasever)
101163

102164
monkeypatch.setattr(FedoraRevDepChecker, '__init__', mock_init)
103165

@@ -118,8 +180,8 @@ def test_main_deterministic_output(self, monkeypatch, jupyterlab_base):
118180

119181
original_init = FedoraRevDepChecker.__init__
120182

121-
def mock_init(self, verbose=False, base=None, repos=None):
122-
original_init(self, verbose=verbose, base=jupyterlab_base if base is None else base, repos=repos)
183+
def mock_init(self, verbose=False, base=None, repos=None, releasever=None):
184+
original_init(self, verbose=verbose, base=jupyterlab_base if base is None else base, repos=repos, releasever=releasever)
123185

124186
monkeypatch.setattr(FedoraRevDepChecker, '__init__', mock_init)
125187

@@ -147,8 +209,8 @@ def test_main_exit_code_zero_for_already_broken_only(self, monkeypatch, mock_dnf
147209

148210
original_init = FedoraRevDepChecker.__init__
149211

150-
def mock_init(self, verbose=False, base=None, repos=None):
151-
original_init(self, verbose=verbose, base=mock_dnf_base if base is None else base, repos=repos)
212+
def mock_init(self, verbose=False, base=None, repos=None, releasever=None):
213+
original_init(self, verbose=verbose, base=mock_dnf_base if base is None else base, repos=repos, releasever=releasever)
152214

153215
def mock_simulate(self, srpm_name, new_version):
154216
return {
@@ -185,8 +247,8 @@ def test_main_exit_code_one_for_mixed_conflicts(self, monkeypatch, mock_dnf_base
185247

186248
original_init = FedoraRevDepChecker.__init__
187249

188-
def mock_init(self, verbose=False, base=None, repos=None):
189-
original_init(self, verbose=verbose, base=mock_dnf_base if base is None else base, repos=repos)
250+
def mock_init(self, verbose=False, base=None, repos=None, releasever=None):
251+
original_init(self, verbose=verbose, base=mock_dnf_base if base is None else base, repos=repos, releasever=releasever)
190252

191253
# Mock simulate_version_change to return mixed conflicts
192254
def mock_simulate(self, srpm_name, new_version):

0 commit comments

Comments
 (0)