diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index de36220..a814bf6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,6 +4,7 @@ on: push: branches: - main + - autometa pull_request_target: jobs: @@ -31,16 +32,23 @@ jobs: python -m pip install -U pycodestyle==2.12.1 autopep8 python -m pip install -U -r test/pip_reqs.txt + - name: pull changes + run: git pull --rebase origin ${{ github.head_ref }} - name: Apply AutoPEP8 run: | autopep8 --in-place --recursive --max-line-length=100 . - + - name: Commit AutoPEP8 uses: stefanzweifel/git-auto-commit-action@v5 with: commit_message: "[ci] auto-format" branch: ${{ github.head_ref }} - + - name: Apply Plugin Metadata + run: | + LAST_COMMIT_HASH=$(git log --pretty=format:'%H' -n 1) + CHANGED_FILES=$(git diff-tree --no-commit-id --name-only -r "$LAST_COMMIT_HASH") + python test/auto_apply_plugin_metadata.py "$CHANGED_FILES" + - name: Apply Version Metadata run: | python test/auto_apply_version_metadata.py $(git log --pretty=format:'%h' -n 1) diff --git a/plugin_manager.py b/plugin_manager.py index f251c45..270148b 100644 --- a/plugin_manager.py +++ b/plugin_manager.py @@ -29,7 +29,8 @@ from datetime import datetime # Modules used for overriding AllSettingsWindow import logging -PLUGIN_MANAGER_VERSION = "1.1.3" +PLUGIN_MANAGER_VERSION = "1.2.0" +plugman = dict(version=PLUGIN_MANAGER_VERSION) REPOSITORY_URL = "https://github.com/bombsquad-community/plugin-manager" # Current tag can be changed to "staging" or any other branch in # plugin manager repo for testing purpose. diff --git a/plugins/utilities/allow_invisible_models.py b/plugins/utilities/allow_invisible_models.py index ec8355f..987ae92 100644 --- a/plugins/utilities/allow_invisible_models.py +++ b/plugins/utilities/allow_invisible_models.py @@ -5,6 +5,16 @@ import bascenev1 as bs original_getmesh = bs.getmesh +plugman = dict( + plugin_name="allow_invisible_models", + description="Shake as many stiies of you as possible", + external_url="https://www.youtube.com/watch?v=dQw4w9WgXcQ", + author=["Loup", "brostos"], + discord="mydiscord", + email="dontclickthelink@pleasedont.com", + version="1.0.0" +) + def get_mesh_gracefully(mesh): if mesh is not None: diff --git a/test/auto_apply_plugin_metadata.py b/test/auto_apply_plugin_metadata.py new file mode 100644 index 0000000..4719870 --- /dev/null +++ b/test/auto_apply_plugin_metadata.py @@ -0,0 +1,142 @@ +from urllib.request import urlopen +import sys +import json +import ast +plugman = dict( + version="1.2.0" +) + + +DEBUG = True + + +def debug_print(*args, **kwargs): + if DEBUG: + print(*args, **kwargs) + + +def get_latest_version(plugin_name, category): + base_url = "https://github.com/bombsquad-community/plugin-manager/raw/main/" + endpoints = { + "minigames": "plugins/minigames.json", + "utilities": "plugins/utilities.json", + "maps": "plugins/maps.json", + "plugman": "index.json" + } + + try: + with urlopen(f"{base_url}{endpoints[category]}") as response: + data = json.loads(response.read().decode('utf-8')) + + # Handle plugman separately + if category == "plugman": + version = next(iter(data.get("versions"))) + return version + + # For plugins + plugin = data.get("plugins", {}).get(plugin_name) + if not plugin: + return None + + # Get latest version from versions dict + if "versions" in plugin and isinstance(plugin["versions"], dict): + latest_version = next(iter(plugin["versions"])) # Gets first key + return latest_version + + except Exception as e: + raise e + + +def update_plugman_json(version): + with open("index.json", "r+") as file: + data = json.load(file) + plugman_version = int(get_latest_version("plugin_manager", "plugman").replace(".", "")) + current_version = int(version["version"].replace(".", "")) + + if current_version > plugman_version: + with open("index.json", "r+") as file: + data = json.load(file) + data[current_version] = None + data["versions"] = dict( + sorted(data["versions"].items(), reverse=True) + ) + + +def update_plugin_json(plugin_info, category): + name = plugin_info["plugin_name"] + + with open(f"plugins/{category}/{category}.json", "r+") as file: + data = json.load(file) + try: + # Check if plugin is already in the json + plugin = data["plugins"][name] + plugman_version = int(get_latest_version(name, category).replace(".", "")) + current_version = int(plugin_info["version"].replace(".", "")) + # Ensure the version is always greater from the already released version + if current_version > plugman_version: + plugin["versions"][plugin_info["version"]] = None + # Ensure latest version appears first + plugin["versions"] = dict( + sorted(plugin["versions"].items(), reverse=True) + ) + plugin["description"] = plugin_info["description"] + plugin["external_url"] = plugin_info["external_url"] + plugin["authors"] = plugin_info["authors"] + elif current_version < plugman_version: + raise Exception("Version cant be lower than the previous") + except KeyError: + data["plugins"][name] = { + "description": plugin_info["description"], + "external_url": plugin_info["external_url"], + "authors": plugin_info["authors"], + "versions": {plugin_info["version"]: None}, + } + + file.seek(0) + json.dump(data, file, indent=2, ensure_ascii=False) + # Ensure old content is removed + file.truncate() + + +def extract_plugman(plugins): + for plugin in plugins: + if "plugins/" in plugin: + debug_print(plugin) + try: + # Split the path and get the part after 'plugins/' + parts = plugin.split("plugins/")[1].split("/") + category = parts[0] # First part after plugins/ + except ValueError: + if "plugin_manager" in plugin: + continue + with open(plugin, "r") as f: + tree = ast.parse(f.read()) + + for node in ast.walk(tree): + if isinstance(node, ast.Assign) and len(node.targets) == 1: + target = node.targets[0] + if isinstance(target, ast.Name) and target.id == "plugman": + if isinstance(node.value, ast.Dict): + # Standard dictionary format {key: value} + return ast.literal_eval(node.value) + elif ( + isinstance(node.value, ast.Call) + and isinstance(node.value.func, ast.Name) + and node.value.func.id == "dict" + ): + # dict() constructor format + result = {} + for kw in node.value.keywords: + result[kw.arg] = ast.literal_eval(kw.value) + if category: + update_plugin_json(result, category=category) + else: + update_plugman_json(result) + raise ValueError( + "Variable plugman not found in the file or has unsupported format." + ) + + +if __name__ == "__main__": + plugins = sys.argv + extract_plugman(plugins)