Skip to content

Commit 4207322

Browse files
committed
chore: unclass App
1 parent 71f0781 commit 4207322

3 files changed

Lines changed: 221 additions & 217 deletions

File tree

homebrew_releaser/app.py

Lines changed: 190 additions & 192 deletions
Original file line numberDiff line numberDiff line change
@@ -66,202 +66,200 @@
6666
) # Must check for string `false` since GitHub Actions passes the bool as a string
6767

6868

69-
class App:
70-
@staticmethod
71-
def run_github_action():
72-
"""Runs the complete GitHub Action workflow.
73-
74-
1. Setup logging
75-
2. Grab the details about the tap
76-
3. Download the archive(s)
77-
4. Generate checksum(s)
78-
5. Generate the new formula
79-
6. Update README table (optional)
80-
7. Add, commit, and push updated formula to GitHub
81-
"""
82-
App.setup_logger()
83-
logger = woodchips.get(LOGGER_NAME)
84-
85-
logger.info(f'Starting Homebrew Releaser v{__version__}...')
86-
App.check_required_env_variables()
87-
88-
logger.info('Setting up git environment...')
89-
setup_git(COMMIT_OWNER, COMMIT_EMAIL, HOMEBREW_OWNER, HOMEBREW_TAP)
90-
91-
logger.info(f'Collecting data about {GITHUB_REPO}...')
92-
repository = make_github_get_request(url=f'{GITHUB_BASE_URL}/repos/{GITHUB_OWNER}/{GITHUB_REPO}').json()
93-
latest_release = make_github_get_request(
94-
url=f'https://api.github.com/repos/{GITHUB_OWNER}/{GITHUB_REPO}/releases/latest'
95-
).json()
96-
assets = latest_release['assets']
97-
version = VERSION or latest_release['tag_name']
98-
version_no_v = version.lstrip('v')
99-
logger.info(f'Latest release ({version}) successfully identified!')
100-
101-
logger.info('Generating tar archive checksum(s)...')
102-
archive_urls = []
103-
archive_checksum_entries = ''
104-
105-
# Auto-generated tar URL must come first for later use (order is important)
106-
if repository["private"]:
107-
logger.debug('Repository is private. Using auto-generated release tarball and zipball REST API endpoints.')
108-
archive_base_url = f'{GITHUB_BASE_URL}/repos/{GITHUB_OWNER}/{GITHUB_REPO}'
109-
auto_generated_release_tar = f'{archive_base_url}/tarball/{version}'
110-
auto_generated_release_zip = f'{archive_base_url}/zipball/{version}'
111-
else:
112-
logger.debug('Repository is public. Using auto-generated release tarball and zipball public URLs.')
113-
archive_base_url = f'https://github.com/{GITHUB_OWNER}/{GITHUB_REPO}/archive/refs/tags/{version}'
114-
auto_generated_release_tar = f'{archive_base_url}.tar.gz'
115-
auto_generated_release_zip = f'{archive_base_url}.zip'
116-
117-
archive_urls.append(auto_generated_release_tar)
118-
archive_urls.append(auto_generated_release_zip)
119-
120-
target_browser_download_base_url = (
121-
f'https://github.com/{GITHUB_OWNER}/{GITHUB_REPO}/releases/download/{version}/{GITHUB_REPO}-{version_no_v}'
122-
)
123-
if TARGET_DARWIN_AMD64:
124-
archive_urls.append(f'{target_browser_download_base_url}-darwin-amd64.tar.gz')
125-
if TARGET_DARWIN_ARM64:
126-
archive_urls.append(f'{target_browser_download_base_url}-darwin-arm64.tar.gz')
127-
if TARGET_LINUX_AMD64:
128-
archive_urls.append(f'{target_browser_download_base_url}-linux-amd64.tar.gz')
129-
if TARGET_LINUX_ARM64:
130-
archive_urls.append(f'{target_browser_download_base_url}-linux-arm64.tar.gz')
131-
132-
checksums = []
133-
for archive_url in archive_urls:
134-
if not assets:
135-
assets = [0] # Populate `assets` so that if we don't have any, we can use the auto generated checksums
136-
for asset in assets:
137-
# Download the asset url so private repos work but use the brower URL for name and path in formula
138-
if archive_url == auto_generated_release_tar or archive_url == auto_generated_release_zip:
139-
download_url = archive_url
140-
else:
141-
download_url = asset['url']
142-
143-
if (
144-
archive_url == auto_generated_release_tar
145-
or archive_url == auto_generated_release_zip
146-
or archive_url == asset['browser_download_url']
147-
):
148-
# For REST API requests, we should not stream archive file, but it is fine for browser URLs
149-
stream = False if archive_url.find("api.github.com") != -1 else True
150-
downloaded_filename = App.download_archive(download_url, stream)
151-
checksum = calculate_checksum(downloaded_filename)
152-
archive_filename = get_filename_from_path(archive_url)
153-
archive_checksum_entries += f'{checksum} {archive_filename}\n'
154-
checksums.append(
155-
{
156-
archive_filename: {
157-
'checksum': checksum,
158-
'url': archive_url,
159-
}
160-
},
161-
)
162-
# We break here so we don't include duplicate checksums for the auto generated URLs
163-
break
164-
165-
write_file(CHECKSUM_FILE, archive_checksum_entries)
166-
167-
logger.info(f'Generating Homebrew formula for {GITHUB_REPO}...')
168-
template = generate_formula_data(
169-
GITHUB_OWNER,
170-
GITHUB_REPO,
171-
repository,
172-
checksums,
173-
INSTALL,
174-
auto_generated_release_tar,
175-
DEPENDS_ON,
176-
TEST,
177-
DOWNLOAD_STRATEGY,
178-
CUSTOM_REQUIRE,
179-
FORMULA_INCLUDES,
180-
UPDATE_PYTHON_RESOURCES,
181-
version_no_v if VERSION else None,
182-
)
183-
184-
formula_filename = f'{repository["name"]}.rb'
185-
formula_dir = get_working_dir(os.path.join(HOMEBREW_TAP, FORMULA_FOLDER))
186-
formula_filepath = os.path.join(formula_dir, formula_filename)
187-
write_file(formula_filepath, template, 'w')
188-
189-
if UPDATE_PYTHON_RESOURCES:
190-
logger.info('Attempting to update Python resources in the formula...')
191-
setup_homebrew_tap(HOMEBREW_OWNER, HOMEBREW_TAP, formula_dir)
192-
update_python_resources(formula_dir, formula_filename)
193-
if DEBUG:
194-
with open(formula_filepath, 'r') as formula_file:
195-
formula_content = formula_file.read()
196-
logger.debug(formula_content)
197-
else:
198-
logger.debug('Skipping update to Python resources.')
199-
200-
if UPDATE_README_TABLE:
201-
logger.info('Attempting to update the README\'s project table...')
202-
update_readme(HOMEBREW_TAP)
203-
else:
204-
logger.debug('Skipping update to project README.')
205-
206-
# Although users can skip a commit, still commit (but don't push) to dry-run the commit for debugging purposes
207-
add_git(HOMEBREW_TAP)
208-
commit_git(HOMEBREW_TAP, GITHUB_REPO, version)
209-
210-
if SKIP_COMMIT:
211-
logger.info(f'Skipping upload of checksum.txt to {HOMEBREW_TAP}.')
212-
logger.info(f'Skipping push to {HOMEBREW_TAP}.')
213-
else:
214-
logger.info(f'Attempting to upload checksum.txt to the latest release of {GITHUB_REPO}...')
215-
upload_checksum_file(latest_release)
216-
logger.info(f'Attempting to release {version} of {GITHUB_REPO} to {HOMEBREW_TAP}...')
217-
push_git(HOMEBREW_TAP, HOMEBREW_OWNER)
218-
logger.info(f'Successfully released {version} of {GITHUB_REPO} to {HOMEBREW_TAP}!')
219-
220-
@staticmethod
221-
def setup_logger():
222-
"""Setup a `woodchips` logger instance."""
223-
logging_level = 'DEBUG' if DEBUG else 'INFO'
224-
225-
logger = woodchips.Logger(
226-
name=LOGGER_NAME,
227-
level=logging_level,
228-
)
229-
logger.log_to_console(formatter='%(asctime)s - %(levelname)s - %(message)s')
230-
231-
@staticmethod
232-
def check_required_env_variables():
233-
"""Checks that all required env variables are set."""
234-
logger = woodchips.get(LOGGER_NAME)
235-
236-
required_env_variables = [
237-
GITHUB_TOKEN,
238-
HOMEBREW_OWNER,
239-
HOMEBREW_TAP,
240-
INSTALL,
241-
]
242-
243-
for env_variable in required_env_variables:
244-
if not env_variable:
245-
raise SystemExit(
246-
'You must provide all necessary environment variables. Please reference the Homebrew Releaser documentation.' # noqa
69+
def run_github_action():
70+
"""Runs the complete GitHub Action workflow.
71+
72+
1. Setup logging
73+
2. Grab the details about the tap
74+
3. Download the archive(s)
75+
4. Generate checksum(s)
76+
5. Generate the new formula
77+
6. Update README table (optional)
78+
7. Add, commit, and push updated formula to GitHub
79+
"""
80+
_setup_logger()
81+
logger = woodchips.get(LOGGER_NAME)
82+
83+
logger.info(f'Starting Homebrew Releaser v{__version__}...')
84+
_check_required_env_variables()
85+
86+
logger.info('Setting up git environment...')
87+
setup_git(COMMIT_OWNER, COMMIT_EMAIL, HOMEBREW_OWNER, HOMEBREW_TAP)
88+
89+
logger.info(f'Collecting data about {GITHUB_REPO}...')
90+
repository = make_github_get_request(url=f'{GITHUB_BASE_URL}/repos/{GITHUB_OWNER}/{GITHUB_REPO}').json()
91+
latest_release = make_github_get_request(
92+
url=f'https://api.github.com/repos/{GITHUB_OWNER}/{GITHUB_REPO}/releases/latest'
93+
).json()
94+
assets = latest_release['assets']
95+
version = VERSION or latest_release['tag_name']
96+
version_no_v = version.lstrip('v')
97+
logger.info(f'Latest release ({version}) successfully identified!')
98+
99+
logger.info('Generating tar archive checksum(s)...')
100+
archive_urls = []
101+
archive_checksum_entries = ''
102+
103+
# Auto-generated tar URL must come first for later use (order is important)
104+
if repository["private"]:
105+
logger.debug('Repository is private. Using auto-generated release tarball and zipball REST API endpoints.')
106+
archive_base_url = f'{GITHUB_BASE_URL}/repos/{GITHUB_OWNER}/{GITHUB_REPO}'
107+
auto_generated_release_tar = f'{archive_base_url}/tarball/{version}'
108+
auto_generated_release_zip = f'{archive_base_url}/zipball/{version}'
109+
else:
110+
logger.debug('Repository is public. Using auto-generated release tarball and zipball public URLs.')
111+
archive_base_url = f'https://github.com/{GITHUB_OWNER}/{GITHUB_REPO}/archive/refs/tags/{version}'
112+
auto_generated_release_tar = f'{archive_base_url}.tar.gz'
113+
auto_generated_release_zip = f'{archive_base_url}.zip'
114+
115+
archive_urls.append(auto_generated_release_tar)
116+
archive_urls.append(auto_generated_release_zip)
117+
118+
target_browser_download_base_url = (
119+
f'https://github.com/{GITHUB_OWNER}/{GITHUB_REPO}/releases/download/{version}/{GITHUB_REPO}-{version_no_v}'
120+
)
121+
if TARGET_DARWIN_AMD64:
122+
archive_urls.append(f'{target_browser_download_base_url}-darwin-amd64.tar.gz')
123+
if TARGET_DARWIN_ARM64:
124+
archive_urls.append(f'{target_browser_download_base_url}-darwin-arm64.tar.gz')
125+
if TARGET_LINUX_AMD64:
126+
archive_urls.append(f'{target_browser_download_base_url}-linux-amd64.tar.gz')
127+
if TARGET_LINUX_ARM64:
128+
archive_urls.append(f'{target_browser_download_base_url}-linux-arm64.tar.gz')
129+
130+
checksums = []
131+
for archive_url in archive_urls:
132+
if not assets:
133+
assets = [0] # Populate `assets` so that if we don't have any, we can use the auto generated checksums
134+
for asset in assets:
135+
# Download the asset url so private repos work but use the brower URL for name and path in formula
136+
if archive_url == auto_generated_release_tar or archive_url == auto_generated_release_zip:
137+
download_url = archive_url
138+
else:
139+
download_url = asset['url']
140+
141+
if (
142+
archive_url == auto_generated_release_tar
143+
or archive_url == auto_generated_release_zip
144+
or archive_url == asset['browser_download_url']
145+
):
146+
# For REST API requests, we should not stream archive file, but it is fine for browser URLs
147+
stream = False if archive_url.find("api.github.com") != -1 else True
148+
downloaded_filename = _download_archive(download_url, stream)
149+
checksum = calculate_checksum(downloaded_filename)
150+
archive_filename = get_filename_from_path(archive_url)
151+
archive_checksum_entries += f'{checksum} {archive_filename}\n'
152+
checksums.append(
153+
{
154+
archive_filename: {
155+
'checksum': checksum,
156+
'url': archive_url,
157+
}
158+
},
247159
)
248-
logger.debug('All required environment variables are present.')
249-
250-
@staticmethod
251-
def download_archive(url: str, stream: Optional[bool] = False) -> str:
252-
"""Gets an archive (eg: zip, tar) from GitHub and saves it locally."""
253-
response = make_github_get_request(
254-
url=url,
255-
stream=stream,
256-
)
257-
filename = get_filename_from_path(url)
258-
write_file(filename, response.content, 'wb')
259-
260-
return filename
160+
# We break here so we don't include duplicate checksums for the auto generated URLs
161+
break
162+
163+
write_file(CHECKSUM_FILE, archive_checksum_entries)
164+
165+
logger.info(f'Generating Homebrew formula for {GITHUB_REPO}...')
166+
template = generate_formula_data(
167+
GITHUB_OWNER,
168+
GITHUB_REPO,
169+
repository,
170+
checksums,
171+
INSTALL,
172+
auto_generated_release_tar,
173+
DEPENDS_ON,
174+
TEST,
175+
DOWNLOAD_STRATEGY,
176+
CUSTOM_REQUIRE,
177+
FORMULA_INCLUDES,
178+
UPDATE_PYTHON_RESOURCES,
179+
version_no_v if VERSION else None,
180+
)
181+
182+
formula_filename = f'{repository["name"]}.rb'
183+
formula_dir = get_working_dir(os.path.join(HOMEBREW_TAP, FORMULA_FOLDER))
184+
formula_filepath = os.path.join(formula_dir, formula_filename)
185+
write_file(formula_filepath, template, 'w')
186+
187+
if UPDATE_PYTHON_RESOURCES:
188+
logger.info('Attempting to update Python resources in the formula...')
189+
setup_homebrew_tap(HOMEBREW_OWNER, HOMEBREW_TAP, formula_dir)
190+
update_python_resources(formula_dir, formula_filename)
191+
if DEBUG:
192+
with open(formula_filepath, 'r') as formula_file:
193+
formula_content = formula_file.read()
194+
logger.debug(formula_content)
195+
else:
196+
logger.debug('Skipping update to Python resources.')
197+
198+
if UPDATE_README_TABLE:
199+
logger.info('Attempting to update the README\'s project table...')
200+
update_readme(HOMEBREW_TAP)
201+
else:
202+
logger.debug('Skipping update to project README.')
203+
204+
# Although users can skip a commit, still commit (but don't push) to dry-run the commit for debugging purposes
205+
add_git(HOMEBREW_TAP)
206+
commit_git(HOMEBREW_TAP, GITHUB_REPO, version)
207+
208+
if SKIP_COMMIT:
209+
logger.info(f'Skipping upload of checksum.txt to {HOMEBREW_TAP}.')
210+
logger.info(f'Skipping push to {HOMEBREW_TAP}.')
211+
else:
212+
logger.info(f'Attempting to upload checksum.txt to the latest release of {GITHUB_REPO}...')
213+
upload_checksum_file(latest_release)
214+
logger.info(f'Attempting to release {version} of {GITHUB_REPO} to {HOMEBREW_TAP}...')
215+
push_git(HOMEBREW_TAP, HOMEBREW_OWNER)
216+
logger.info(f'Successfully released {version} of {GITHUB_REPO} to {HOMEBREW_TAP}!')
217+
218+
219+
def _setup_logger():
220+
"""Setup a `woodchips` logger instance."""
221+
logging_level = 'DEBUG' if DEBUG else 'INFO'
222+
223+
logger = woodchips.Logger(
224+
name=LOGGER_NAME,
225+
level=logging_level,
226+
)
227+
logger.log_to_console(formatter='%(asctime)s - %(levelname)s - %(message)s')
228+
229+
230+
def _check_required_env_variables():
231+
"""Checks that all required env variables are set."""
232+
logger = woodchips.get(LOGGER_NAME)
233+
234+
required_env_variables = [
235+
GITHUB_TOKEN,
236+
HOMEBREW_OWNER,
237+
HOMEBREW_TAP,
238+
INSTALL,
239+
]
240+
241+
for env_variable in required_env_variables:
242+
if not env_variable:
243+
raise SystemExit(
244+
'You must provide all necessary environment variables. Please reference the Homebrew Releaser documentation.' # noqa
245+
)
246+
logger.debug('All required environment variables are present.')
247+
248+
249+
def _download_archive(url: str, stream: Optional[bool] = False) -> str:
250+
"""Gets an archive (eg: zip, tar) from GitHub and saves it locally."""
251+
response = make_github_get_request(
252+
url=url,
253+
stream=stream,
254+
)
255+
filename = get_filename_from_path(url)
256+
write_file(filename, response.content, 'wb')
257+
258+
return filename
261259

262260

263261
def main():
264-
App.run_github_action()
262+
run_github_action()
265263

266264

267265
if __name__ == '__main__':

0 commit comments

Comments
 (0)