diff --git a/blenderpack.py b/blenderpack.py index 800da1c..6a402fa 100755 --- a/blenderpack.py +++ b/blenderpack.py @@ -17,33 +17,19 @@ log = logging.getLogger(__name__) REQUIRED_KEYS = set(['name', 'blender', 'version']) SCHEMA_VERSION = 1 -def report(msg): - print("blenderpack:", msg, file=sys.stderr) - -def fatal_report(msg, code=1, ex=None): - if __name__ == '__main__': - # report("fatal: %s" % msg) - log.fatal(msg) - exit(code) - elif ex is not None: - raise Exception(msg) from ex - else: - raise RuntimeError("blenderpack: Unhandled fatal exception: %s" % msg) - +class BadAddon(Exception): + pass def fetch(url): # TODO: do conditional request re = requests.get(url) print(re.json()) -def parse_blinfo(source, addon_name="unknown"): + +def parse_blinfo(source: str) -> dict: """Parse a python file and return its bl_info dict, if there is one (else return None)""" - try: - tree = ast.parse(source) - except SyntaxError as ex: - log.warning('Skipping addon: SyntaxError in %s: %s', addon_name, ex) - return None + tree = ast.parse(source) for body in tree.body: if body.__class__ != ast.Assign: @@ -55,15 +41,14 @@ def parse_blinfo(source, addon_name="unknown"): return ast.literal_eval(body.value) - log.warning('Unable to find bl_info dict in %s', addon_name) - return None + raise BadAddon('No bl_info found') def extract_blinfo(path): """Extract bl_info dict from addon at path (can be single file, module, or zip)""" source = None - # get last component of path, even with trailing slash + # get last component of path, including when the path ends with trailing slash addon_name = os.path.split(path.rstrip(os.path.sep))[1] if os.path.isdir(path): @@ -86,7 +71,7 @@ def extract_blinfo(path): if source == None: raise RuntimeError("Could not read addon '%s'" % addon_name) - return parse_blinfo(source, addon_name) + return parse_blinfo(source) @@ -96,36 +81,33 @@ def make_repo(outpath): repo_data = {} package_data = [] - try: - for addon in os.listdir(outpath): - package_datum = {} - addon_path = os.path.join(outpath, addon) + if not os.path.exists(outpath): + raise FileNotFoundError - try: - bl_info = extract_blinfo(addon_path) - if not bl_info: - raise Exception("No bl_info found in %s" % addon) - except Exception as err: - fatal_report('Could not extract bl_info from {}: {}'.format(addon_path, err)) + for addon in os.listdir(outpath): + package_datum = {} + addon_path = os.path.join(outpath, addon) - if not REQUIRED_KEYS.issubset(set(bl_info)): - fatal_report( - "Required key(s) '{}' not found in bl_info of '{}'".format( - "', '".join(REQUIRED_KEYS.difference(set(bl_info))), addon), - ex=Exception() - ) + try: + bl_info = extract_blinfo(addon_path) + except BadAddon as err: + log.warning('Could not extract bl_info from {}: {}'.format(addon_path, err)) + continue - package_datum['bl_info'] = bl_info - package_datum['type'] = 'addon' - package_data.append(package_datum) + if not REQUIRED_KEYS.issubset(set(bl_info)): + log.warning( + "Required key(s) '{}' not found in bl_info of '{}'".format( + "', '".join(REQUIRED_KEYS.difference(set(bl_info))), addon) + ) - repo_data['packages'] = package_data - with open(os.path.join(outpath, "repo.json"), 'w', encoding='utf-8') as repo_file: - json.dump(repo_data, repo_file, indent=4, sort_keys=True) + package_datum['bl_info'] = bl_info + package_datum['type'] = 'addon' + package_data.append(package_datum) + repo_data['packages'] = package_data - except FileNotFoundError: - fatal_report("No such file or directory: '%s'" % outpath) + with open(os.path.join(outpath, "repo.json"), 'w', encoding='utf-8') as repo_file: + json.dump(repo_data, repo_file, indent=4, sort_keys=True) diff --git a/tests/test_blenderpack.py b/tests/test_blenderpack.py index 0d3528f..f95768c 100644 --- a/tests/test_blenderpack.py +++ b/tests/test_blenderpack.py @@ -2,6 +2,7 @@ import unittest import os.path +import json import blenderpack class test_blenderpack_make_repo(unittest.TestCase): diff --git a/tests/test_helpers/addons/repo.json b/tests/test_helpers/addons/repo.json deleted file mode 100644 index 86db477..0000000 --- a/tests/test_helpers/addons/repo.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "packages": [ - { - "bl_info": { - "author": "Multiple Authors", - "blender": [ - 2, - 76, - 0 - ], - "category": "Add Curve", - "description": "Add extra curve object types", - "location": "View3D > Add > Curve > Extra Objects", - "name": "Extra Objects", - "version": [ - 0, - 1, - 2 - ], - "warning": "", - "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Curve/Curve_Objects" - }, - "type": "addon" - }, - { - "bl_info": { - "author": "testscreenings, PKHG, TrumanBlending", - "blender": [ - 2, - 59, - 0 - ], - "category": "Add Curve", - "description": "Adds generated ivy to a mesh object starting at the 3D cursor", - "location": "View3D > Add > Curve", - "name": "IvyGen", - "version": [ - 0, - 1, - 2 - ], - "warning": "", - "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Curve/Ivy_Gen" - }, - "type": "addon" - }, - { - "bl_info": { - "author": "Multiple Authors", - "blender": [ - 2, - 76, - 0 - ], - "category": "Add Curve", - "description": "Add extra curve object types", - "location": "View3D > Add > Curve > Extra Objects", - "name": "Extra Objects", - "version": [ - 0, - 1, - 2 - ], - "warning": "", - "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Curve/Curve_Objects" - }, - "type": "addon" - } - ] -} \ No newline at end of file