Skip to content

Commit affc2f9

Browse files
committed
test: update-python-resources formula
1 parent 1311730 commit affc2f9

4 files changed

Lines changed: 142 additions & 43 deletions

File tree

homebrew_releaser/formula.py

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -271,33 +271,23 @@ def _generate_class_name(repo_name: str) -> str:
271271

272272
@staticmethod
273273
def update_python_resources(formula_path: str, formula_name: str) -> None:
274-
"""Runs brew update-python-resources on the formula to add Python resources.
275-
276-
Args:
277-
formula_path: The path to the formula file
278-
formula_name: The name of the formula
279-
"""
274+
"""Runs brew update-python-resources on the formula to add Python resources."""
280275
logger = woodchips.get(LOGGER_NAME)
281276

282277
brew_path = shutil.which('brew')
283278
if not brew_path:
284279
raise SystemExit("brew not found in PATH")
285280

286281
try:
287-
logger.info(f'Running brew update-python-resources for {formula_name}...')
288-
output = subprocess.check_output( # nosec B603
282+
logger.info(f'Running brew update-python-resources for {formula_path}...')
283+
subprocess.check_output( # nosec B603
289284
[brew_path, 'update-python-resources', formula_path],
290285
stderr=subprocess.STDOUT,
291286
text=True,
292287
timeout=TIMEOUT,
293288
)
294-
logger.info(f'Successfully updated Python resources for {formula_name}')
295-
logger.debug(f'brew update-python-resources output:\n{output}')
289+
logger.info(f'Successfully updated Python resources for {formula_path}')
296290
except subprocess.TimeoutExpired as e:
297291
raise SystemExit from e
298292
except subprocess.CalledProcessError as e:
299-
raise SystemExit(
300-
"Failed to update Python resources: %s\nCommand output: %s\nCommand error: %s", e, e.stdout, e.stderr
301-
) from e
302-
except Exception as e:
303293
raise SystemExit(f'An error occurred while updating Python resources: {e}') from e

test/formulas/homebrew_releaser.rb

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# typed: true
2+
# frozen_string_literal: true
3+
4+
# This file was generated by Homebrew Releaser. DO NOT EDIT.
5+
class HomebrewReleaser < Formula
6+
include Language::Python::Virtualenv
7+
8+
desc "Release scripts, binaries, and executables to github"
9+
homepage "https://github.com/Justintime50/homebrew-releaser"
10+
url "https://github.com/justintime50/homebrew-releaser/archive/refs/tags/v1.0.0.tar.gz"
11+
sha256 "0000000000000000000000000000000000000000000000000000000000000000"
12+
license "MIT"
13+
14+
resource "certifi" do
15+
url "https://files.pythonhosted.org/packages/e8/9e/c05b3920a3b7d20d3d3310465f50348e5b3694f4f88c6daf736eef3024c4/certifi-2025.4.26.tar.gz"
16+
sha256 "0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6"
17+
end
18+
19+
resource "charset-normalizer" do
20+
url "https://files.pythonhosted.org/packages/e4/33/89c2ced2b67d1c2a61c19c6751aa8902d46ce3dacb23600a283619f5a12d/charset_normalizer-3.4.2.tar.gz"
21+
sha256 "5baececa9ecba31eff645232d59845c07aa030f0c81ee70184a90d35099a0e63"
22+
end
23+
24+
resource "chevron" do
25+
url "https://files.pythonhosted.org/packages/15/1f/ca74b65b19798895d63a6e92874162f44233467c9e7c1ed8afd19016ebe9/chevron-0.14.0.tar.gz"
26+
sha256 "87613aafdf6d77b6a90ff073165a61ae5086e21ad49057aa0e53681601800ebf"
27+
end
28+
29+
resource "idna" do
30+
url "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz"
31+
sha256 "12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"
32+
end
33+
34+
resource "pretty-tables" do
35+
url "https://files.pythonhosted.org/packages/f7/d6/327794663b3c94127da65714639d66029b7acf152bc63a2fe7976c068614/pretty-tables-2.0.3.tar.gz"
36+
sha256 "b98d5973c6677a4bda26e43322797764ef4c4333cc6c188be19a365e6d4c3a99"
37+
end
38+
39+
resource "requests" do
40+
url "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz"
41+
sha256 "55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"
42+
end
43+
44+
resource "urllib3" do
45+
url "https://files.pythonhosted.org/packages/8a/78/16493d9c386d8e60e442a35feac5e00f0913c0f4b7c217c11e8ec2ff53e0/urllib3-2.4.0.tar.gz"
46+
sha256 "414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466"
47+
end
48+
49+
resource "woodchips" do
50+
url "https://files.pythonhosted.org/packages/a2/b7/81330431738c0a92cb0e716512b132c184058eef6d9d8ff0bc75b5ca21fb/woodchips-1.0.0.tar.gz"
51+
sha256 "1837186797c933507ee4a822b17f7fec61db55ed6045c73b9d0350564984705c"
52+
end
53+
54+
def install
55+
virtualenv_install_with_resources
56+
end
57+
end

test/unit/test_formula.py

Lines changed: 79 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010
from homebrew_releaser.formula import Formula
1111

1212

13-
formula_path = 'test/formulas'
14-
13+
FORMULA_PATH = 'test/formulas'
1514
USERNAME = 'Justintime50'
1615
VERSION = '0.1.0'
1716
CHECKSUM = '0' * 64 # `brew audit` wants a 64 character number here, this would be true with real data
@@ -42,7 +41,7 @@
4241
'''
4342

4443

45-
def _record_formula(formula_path: str, formula_name: str, formula_data: str):
44+
def _record_formula(formula_path: str, formula_name: str, formula_data: str, skip_assertions: bool = False):
4645
"""Read from an existing formula file or create a new formula file if it's not present.
4746
4847
Tests using this function will generate a formula into a file (similar to how
@@ -56,8 +55,9 @@ def _record_formula(formula_path: str, formula_name: str, formula_data: str):
5655
full_formula_filename = os.path.join(formula_path, formula_name)
5756

5857
if os.path.isfile(full_formula_filename):
59-
with open(full_formula_filename, 'r') as formula_file:
60-
assert formula_data == formula_file.read()
58+
if skip_assertions is False:
59+
with open(full_formula_filename, 'r') as formula_file:
60+
assert formula_data == formula_file.read()
6161
else:
6262
os.makedirs(formula_path, exist_ok=True)
6363
with open(full_formula_filename, 'w') as formula_file:
@@ -104,7 +104,7 @@ def test_generate_formula():
104104
test=TEST,
105105
)
106106

107-
_record_formula(formula_path, formula_filename, formula)
107+
_record_formula(FORMULA_PATH, formula_filename, formula)
108108

109109
# The following assertions are explicitly listed as the "gold standard" for generic formula generation
110110
assert (
@@ -174,7 +174,7 @@ def test_generate_formula_no_article_description():
174174
test=None,
175175
)
176176

177-
_record_formula(formula_path, formula_filename, formula)
177+
_record_formula(FORMULA_PATH, formula_filename, formula)
178178

179179
assert 'desc "Release scripts, binaries, and executables to github"' in formula
180180

@@ -215,7 +215,7 @@ def test_generate_formula_formula_name_starts_description():
215215
test=None,
216216
)
217217

218-
_record_formula(formula_path, formula_filename, formula)
218+
_record_formula(FORMULA_PATH, formula_filename, formula)
219219

220220
assert 'desc "Is a tool"' in formula
221221

@@ -254,7 +254,7 @@ def test_generate_formula_no_depends_on():
254254
test=TEST,
255255
)
256256

257-
_record_formula(formula_path, formula_filename, formula)
257+
_record_formula(FORMULA_PATH, formula_filename, formula)
258258

259259
assert 'depends_on' not in formula
260260

@@ -293,7 +293,7 @@ def test_generate_formula_no_test():
293293
test=None,
294294
)
295295

296-
_record_formula(formula_path, formula_filename, formula)
296+
_record_formula(FORMULA_PATH, formula_filename, formula)
297297

298298
assert 'test do' not in formula
299299

@@ -334,7 +334,7 @@ def test_generate_formula_multiline_fields():
334334
test=MULTILINE_TEST,
335335
)
336336

337-
_record_formula(formula_path, formula_filename, formula)
337+
_record_formula(FORMULA_PATH, formula_filename, formula)
338338

339339
assert (
340340
'''
@@ -436,7 +436,7 @@ def test_generate_formula_complete_matrix():
436436
test=TEST,
437437
)
438438

439-
_record_formula(formula_path, formula_filename, formula)
439+
_record_formula(FORMULA_PATH, formula_filename, formula)
440440

441441
assert formula.count('url') == 5
442442
assert formula.count('sha256') == 5
@@ -498,7 +498,7 @@ def test_generate_formula_darwin_matrix():
498498
test=None,
499499
)
500500

501-
_record_formula(formula_path, formula_filename, formula)
501+
_record_formula(FORMULA_PATH, formula_filename, formula)
502502

503503
assert 'on_macos' in formula
504504
assert 'on_intel' in formula
@@ -558,7 +558,7 @@ def test_generate_formula_linux_matrix():
558558
test=None,
559559
)
560560

561-
_record_formula(formula_path, formula_filename, formula)
561+
_record_formula(FORMULA_PATH, formula_filename, formula)
562562

563563
assert 'on_macos' not in formula
564564
assert 'on_intel' in formula
@@ -619,7 +619,7 @@ def test_one_of_each_matrix():
619619
test=None,
620620
)
621621

622-
_record_formula(formula_path, formula_filename, formula)
622+
_record_formula(FORMULA_PATH, formula_filename, formula)
623623

624624
assert 'on_macos' in formula
625625
assert 'on_intel' in formula
@@ -666,7 +666,7 @@ def test_generate_formula_string_false_configs():
666666
test=None,
667667
)
668668

669-
_record_formula(formula_path, formula_filename, formula)
669+
_record_formula(FORMULA_PATH, formula_filename, formula)
670670

671671
assert 'on_macos' not in formula
672672
assert 'on_intel' not in formula
@@ -707,7 +707,7 @@ def test_generate_formula_empty_fields():
707707
test=None,
708708
)
709709

710-
_record_formula(formula_path, formula_filename, formula)
710+
_record_formula(FORMULA_PATH, formula_filename, formula)
711711

712712
assert 'desc "NA"' in formula
713713
assert 'license' not in formula
@@ -785,7 +785,7 @@ def test_generate_formula_download_strategy():
785785
custom_require='../formula_imports/mock_download_strategy',
786786
)
787787

788-
_record_formula(formula_path, formula_filename, formula)
788+
_record_formula(FORMULA_PATH, formula_filename, formula)
789789

790790
assert formula.count(', using: CustomDownloadStrategy') == 5
791791
assert 'require_relative "../formula_imports/mock_download_strategy"' in formula
@@ -824,7 +824,7 @@ def test_generate_formula_override_version():
824824
version='9.8.7',
825825
)
826826

827-
_record_formula(formula_path, formula_filename, formula)
827+
_record_formula(FORMULA_PATH, formula_filename, formula)
828828

829829
assert '9.8.7' in formula
830830

@@ -862,9 +862,60 @@ def test_generate_formula_formula_includes():
862862
formula_includes='include Language::Python::Virtualenv',
863863
)
864864

865-
_record_formula(formula_path, formula_filename, formula)
865+
_record_formula(FORMULA_PATH, formula_filename, formula)
866+
867+
assert 'include Language::Python::Virtualenv' in formula
868+
869+
870+
def test_generate_formula_update_python_resources():
871+
"""Tests that we generate the formula content correctly when using the update_python_resources param.
872+
873+
NOTE: See docstring in `_record_formula` for more details on how recording formulas works.
874+
875+
NOTE: This test is unique since we call a subprocess to update our formula after we've generated it, will
876+
require a different test flow than the others.
877+
"""
878+
formula_filename = 'homebrew_releaser.rb'
879+
repo_name = 'homebrew-releaser'
880+
mock_tar_url = f'https://github.com/justintime50/{repo_name}/archive/refs/tags/v1.0.0.tar.gz'
881+
882+
repository = {
883+
'description': DESCRIPTION,
884+
'license': LICENSE,
885+
}
886+
887+
formula = Formula.generate_formula_data(
888+
owner=USERNAME,
889+
repo_name=repo_name,
890+
repository=repository,
891+
checksums=[
892+
{
893+
f'{repo_name}.tar.gz': {
894+
'checksum': CHECKSUM,
895+
'url': (
896+
f'https://github.com/justintime50/{repo_name}/releases/download/1.0.0/{repo_name}-1.0.0.tar.gz' # noqa
897+
),
898+
},
899+
}
900+
],
901+
install='virtualenv_install_with_resources',
902+
tar_url=mock_tar_url,
903+
formula_includes='include Language::Python::Virtualenv',
904+
)
905+
906+
update_resources = False
907+
full_formula_filename = os.path.join(os.getcwd(), FORMULA_PATH, formula_filename)
908+
if not os.path.isfile(full_formula_filename):
909+
update_resources = True
910+
_record_formula(FORMULA_PATH, formula_filename, formula, skip_assertions=True)
911+
if update_resources:
912+
Formula.update_python_resources(full_formula_filename, repo_name)
913+
with open(full_formula_filename, 'r') as formula_file:
914+
formula = formula_file.read()
866915

867916
assert 'include Language::Python::Virtualenv' in formula
917+
assert 'resource "requests" do' in formula
918+
assert 'virtualenv_install_with_resources' in formula
868919

869920

870921
@pytest.mark.parametrize(
@@ -885,19 +936,20 @@ def test_generate_class_name(repo_name, expected_class_name):
885936
assert class_name == expected_class_name
886937

887938

888-
@patch('subprocess.check_output', side_effect=Exception('Test error'))
939+
@patch(
940+
'subprocess.check_output',
941+
side_effect=subprocess.CalledProcessError(cmd='subprocess.check_output', returncode=1),
942+
)
889943
def test_update_python_resources_error(mock_subprocess):
890-
formula_path = '/path/to/formula.rb'
944+
FORMULA_PATH = '/path/to/formula.rb'
891945
formula_name = 'test-formula'
892946

893-
with pytest.raises(SystemExit) as error:
894-
Formula.update_python_resources(formula_path, formula_name)
895-
896-
assert str(error.value) == 'An error occurred while updating Python resources: Test error'
947+
with pytest.raises(SystemExit):
948+
Formula.update_python_resources(FORMULA_PATH, formula_name)
897949

898950
brew_path = shutil.which('brew')
899951
mock_subprocess.assert_called_once_with(
900-
[brew_path, 'update-python-resources', formula_path],
952+
[brew_path, 'update-python-resources', FORMULA_PATH],
901953
stderr=subprocess.STDOUT,
902954
text=True,
903955
timeout=TIMEOUT,

test/unit/test_readme_updater.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ def test_format_formula_data():
7575
"""
7676
formulas = ReadmeUpdater.format_formula_data('./test')
7777

78-
assert len(formulas) == 15
79-
assert formulas[0] == {
78+
assert len(formulas) == 16
79+
assert formulas[1] == {
8080
'name': 'test-generate-formula',
8181
'desc': 'Tool to release scripts, binaries, and executables to github',
8282
'homepage': 'https://github.com/Justintime50/test-generate-formula',

0 commit comments

Comments
 (0)