Skip to content

Commit d8084b2

Browse files
committed
Minor bug fixes in Cache Creator
1 parent 5a1c038 commit d8084b2

File tree

1 file changed

+49
-10
lines changed

1 file changed

+49
-10
lines changed

AddonCatalogCacheCreator.py

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"""Classes and utility functions to generate a remotely hosted cache of all addon catalog entries.
2525
Intended to be run by a server-side systemd timer to generate a file that is then loaded by the
2626
Addon Manager in each FreeCAD installation."""
27+
import enum
2728
import xml.etree.ElementTree
2829
from dataclasses import dataclass, asdict
2930
from typing import List, Optional
@@ -45,7 +46,7 @@
4546
"https://raw.githubusercontent.com/FreeCAD/FreeCAD-addons/master/AddonCatalog.json"
4647
)
4748
BASE_DIRECTORY = "./CatalogCache"
48-
MAX_COUNT = 10 # Do at most this many repos (for testing purposes)
49+
MAX_COUNT = 10000 # Do at most this many repos (for testing purposes this can be made smaller)
4950

5051
# Repos that are too large, or that should for some reason not be cloned here
5152
EXCLUDED_REPOS = ["parts_library"]
@@ -62,6 +63,14 @@ class CacheEntry:
6263
icon_data: str = ""
6364

6465

66+
class GitRefType(enum.IntEnum):
67+
"""Enum for the type of git ref (tag, branch, or hash)."""
68+
69+
TAG = 1
70+
BRANCH = 2
71+
HASH = 3
72+
73+
6574
class CatalogFetcher:
6675
"""Fetches the addon catalog from the given URL and returns an AddonCatalog object. Separated
6776
from the main class for easy mocking during tests. Note that every instantiation of this class
@@ -181,10 +190,15 @@ def generate_cache_entry_from_package_xml(
181190
return None
182191

183192
relative_icon_path = self.get_icon_from_metadata(metadata)
184-
absolute_icon_path = os.path.join(os.path.dirname(path_to_package_xml), relative_icon_path)
185-
if os.path.exists(absolute_icon_path):
186-
with open(absolute_icon_path, "rb") as f:
187-
cache_entry.icon_data = base64.b64encode(f.read()).decode("utf-8")
193+
if relative_icon_path is not None:
194+
absolute_icon_path = os.path.join(
195+
os.path.dirname(path_to_package_xml), relative_icon_path
196+
)
197+
if os.path.exists(absolute_icon_path):
198+
with open(absolute_icon_path, "rb") as f:
199+
cache_entry.icon_data = base64.b64encode(f.read()).decode("utf-8")
200+
else:
201+
print(f"ERROR: Could not find icon file {absolute_icon_path}")
188202
return cache_entry
189203

190204
def create_local_copy_of_single_addon_with_git(
@@ -246,6 +260,8 @@ def clone_or_update(name: str, url: str, branch: str) -> None:
246260
print(f"Updating {name}", flush=True)
247261
old_dir = os.getcwd()
248262
os.chdir(os.path.join(old_dir, name))
263+
# Determine if we are dealing with a tag, branch, or hash
264+
git_ref_type = CacheWriter.determine_git_ref_type(name, url, branch)
249265
command = ["git", "fetch"]
250266
completed_process = subprocess.run(command)
251267
if completed_process.returncode != 0:
@@ -256,11 +272,12 @@ def clone_or_update(name: str, url: str, branch: str) -> None:
256272
if completed_process.returncode != 0:
257273
os.chdir(old_dir)
258274
raise RuntimeError(f"git checkout failed for {name} branch {branch}")
259-
command = ["git", "merge", "--quiet"]
260-
completed_process = subprocess.run(command)
261-
if completed_process.returncode != 0:
262-
os.chdir(old_dir)
263-
raise RuntimeError(f"git merge failed for {name} branch {branch}")
275+
if git_ref_type == GitRefType.BRANCH:
276+
command = ["git", "merge", "--quiet"]
277+
completed_process = subprocess.run(command)
278+
if completed_process.returncode != 0:
279+
os.chdir(old_dir)
280+
raise RuntimeError(f"git merge failed for {name} branch {branch}")
264281
os.chdir(old_dir)
265282

266283
def find_file(
@@ -293,6 +310,28 @@ def get_icon_from_metadata(metadata: addonmanager_metadata.Metadata) -> Optional
293310
return icon
294311
return None
295312

313+
@staticmethod
314+
def determine_git_ref_type(name: str, url: str, branch: str) -> GitRefType:
315+
"""Determine if the given branch, tag, or hash is a tag, branch, or hash. Returns the type
316+
if determinable, otherwise raises a RuntimeError."""
317+
command = ["git", "show-ref", "--verify", f"refs/remotes/origin/{branch}"]
318+
completed_process = subprocess.run(command)
319+
if completed_process.returncode == 0:
320+
return GitRefType.BRANCH
321+
command = ["git", "show-ref", "--tags"]
322+
completed_process = subprocess.run(command, capture_output=True)
323+
completed_process_output = completed_process.stdout.decode("utf-8")
324+
if branch in completed_process_output:
325+
return GitRefType.TAG
326+
command = ["git", "rev-parse", branch]
327+
completed_process = subprocess.run(command)
328+
if completed_process.returncode == 0:
329+
return GitRefType.HASH
330+
raise RuntimeError(
331+
f"Could not determine if {branch} of {name} is a tag, branch, or hash. "
332+
f"Output was: {completed_process_output}"
333+
)
334+
296335

297336
if __name__ == "__main__":
298337
writer = CacheWriter()

0 commit comments

Comments
 (0)