diff --git a/build/lib/pyboot/stereotype.py b/build/lib/pyboot/stereotype.py index 8876111..fdf119b 100644 --- a/build/lib/pyboot/stereotype.py +++ b/build/lib/pyboot/stereotype.py @@ -24,9 +24,9 @@ def ensure_component_subclass(cls, type_name, name): all_component_classes = {} all_component_comments = {} -def register_component_type(component_type, comment=None): +def register_component_type(component_type): all_component_classes[component_type] = {} - all_component_comments[component_type] = comment + all_component_comments[component_type] = {} # --- Classes --- # @@ -34,7 +34,7 @@ def component(component_type, component_name, comment=None): def decorator(cls): cls = ensure_component_subclass(cls, "COMPONENT", component_name) if component_type not in all_component_classes: - register_component_type(component_type, comment) + register_component_type(component_type) all_component_classes[component_type][component_name] = cls all_component_comments[component_type][component_name] = comment return cls @@ -91,10 +91,10 @@ def server(server_name, comment=None): # --- Utils --- # -register_component_type("RUNNER", "Runner") -register_component_type("FACTORY", "Factory") -register_component_type("CLIENT", "Client") -register_component_type("SERVER", "Server") +register_component_type("RUNNER") +register_component_type("FACTORY") +register_component_type("CLIENT") +register_component_type("SERVER") def get_all_component_classes(): return all_component_classes diff --git a/build/lib/pyboot/utils/project.py b/build/lib/pyboot/utils/project.py index 7d76c0d..df2001f 100644 --- a/build/lib/pyboot/utils/project.py +++ b/build/lib/pyboot/utils/project.py @@ -2,8 +2,57 @@ import os import sys import yaml import importlib +import fnmatch class Project: + @staticmethod + def _load_pbignore(root_path): + """Load .pbignore file and return list of ignore patterns""" + pbignore_path = os.path.join(root_path, '.pbignore') + ignore_patterns = [] + + if os.path.exists(pbignore_path): + try: + with open(pbignore_path, 'r', encoding='utf-8') as f: + for line in f: + line = line.strip() + # Skip empty lines and comments + if line and not line.startswith('#'): + ignore_patterns.append(line) + except Exception as e: + print(f"Warning: Could not read .pbignore file: {e}") + + return ignore_patterns + + @staticmethod + def _should_ignore(path, ignore_patterns, root_path): + """Check if a path should be ignored based on .pbignore patterns""" + if not ignore_patterns: + return False + + # Get relative path from root + try: + rel_path = os.path.relpath(path, root_path) + except ValueError: + # If path is not relative to root, don't ignore + return False + + # Normalize path separators + rel_path = rel_path.replace(os.sep, '/') + + for pattern in ignore_patterns: + # Handle directory patterns (ending with /) + if pattern.endswith('/'): + pattern = pattern[:-1] + if fnmatch.fnmatch(rel_path, pattern) or fnmatch.fnmatch(rel_path, pattern + '/*'): + return True + else: + # Handle file/directory patterns + if fnmatch.fnmatch(rel_path, pattern) or fnmatch.fnmatch(os.path.basename(rel_path), pattern): + return True + + return False + @staticmethod def scan_project(root_path): sys.path.append(root_path) @@ -13,20 +62,37 @@ class Project: parent_dir = os.path.dirname(root_path) sys.path.insert(0, parent_dir) + # Load .pbignore patterns + ignore_patterns = Project._load_pbignore(root_path) + def import_all_modules(path, package_name): for root, dirs, files in os.walk(path): + # Check if current directory should be ignored + if Project._should_ignore(root, ignore_patterns, root_path): + dirs[:] = [] # Don't traverse into ignored directories + continue + relative_path = os.path.relpath(root, root_path) if relative_path == '.': module_package = package_name else: module_package = f"{package_name}.{relative_path.replace(os.sep, '.')}" + for file in files: if file.endswith(".py") and file != "__init__.py": + file_path = os.path.join(root, file) + # Check if file should be ignored + if Project._should_ignore(file_path, ignore_patterns, root_path): + continue + module_name = file[:-3] full_module_name = f"{module_package}.{module_name}" if full_module_name not in sys.modules: importlib.import_module(full_module_name) - dirs[:] = [d for d in dirs if not d.startswith('.')] + + # Filter out ignored directories from further traversal + dirs[:] = [d for d in dirs if not d.startswith('.') and + not Project._should_ignore(os.path.join(root, d), ignore_patterns, root_path)] package_name = os.path.basename(root_path) import_all_modules(root_path, package_name) diff --git a/pyboot.egg-info/PKG-INFO b/pyboot.egg-info/PKG-INFO index 17c3bb8..01ad79b 100644 --- a/pyboot.egg-info/PKG-INFO +++ b/pyboot.egg-info/PKG-INFO @@ -1,9 +1,10 @@ -Metadata-Version: 2.4 +Metadata-Version: 1.0 Name: pyboot -Version: 0.1 -Requires-Dist: pyyaml -Requires-Dist: psutil -Requires-Dist: GPUtil -Requires-Dist: flask -Requires-Dist: flask_cors -Dynamic: requires-dist +Version: 0.2 +Summary: UNKNOWN +Home-page: UNKNOWN +Author: UNKNOWN +Author-email: UNKNOWN +License: UNKNOWN +Description: UNKNOWN +Platform: UNKNOWN diff --git a/pyboot.egg-info/entry_points.txt b/pyboot.egg-info/entry_points.txt index 24dc2cd..15b41ef 100644 --- a/pyboot.egg-info/entry_points.txt +++ b/pyboot.egg-info/entry_points.txt @@ -1,3 +1,4 @@ [console_scripts] pb = pyboot.boot:main pyboot = pyboot.boot:main + diff --git a/pyboot/stereotype.py b/pyboot/stereotype.py index 8876111..fdf119b 100644 --- a/pyboot/stereotype.py +++ b/pyboot/stereotype.py @@ -24,9 +24,9 @@ def ensure_component_subclass(cls, type_name, name): all_component_classes = {} all_component_comments = {} -def register_component_type(component_type, comment=None): +def register_component_type(component_type): all_component_classes[component_type] = {} - all_component_comments[component_type] = comment + all_component_comments[component_type] = {} # --- Classes --- # @@ -34,7 +34,7 @@ def component(component_type, component_name, comment=None): def decorator(cls): cls = ensure_component_subclass(cls, "COMPONENT", component_name) if component_type not in all_component_classes: - register_component_type(component_type, comment) + register_component_type(component_type) all_component_classes[component_type][component_name] = cls all_component_comments[component_type][component_name] = comment return cls @@ -91,10 +91,10 @@ def server(server_name, comment=None): # --- Utils --- # -register_component_type("RUNNER", "Runner") -register_component_type("FACTORY", "Factory") -register_component_type("CLIENT", "Client") -register_component_type("SERVER", "Server") +register_component_type("RUNNER") +register_component_type("FACTORY") +register_component_type("CLIENT") +register_component_type("SERVER") def get_all_component_classes(): return all_component_classes diff --git a/pyboot/utils/project.py b/pyboot/utils/project.py index 7d76c0d..df2001f 100644 --- a/pyboot/utils/project.py +++ b/pyboot/utils/project.py @@ -2,8 +2,57 @@ import os import sys import yaml import importlib +import fnmatch class Project: + @staticmethod + def _load_pbignore(root_path): + """Load .pbignore file and return list of ignore patterns""" + pbignore_path = os.path.join(root_path, '.pbignore') + ignore_patterns = [] + + if os.path.exists(pbignore_path): + try: + with open(pbignore_path, 'r', encoding='utf-8') as f: + for line in f: + line = line.strip() + # Skip empty lines and comments + if line and not line.startswith('#'): + ignore_patterns.append(line) + except Exception as e: + print(f"Warning: Could not read .pbignore file: {e}") + + return ignore_patterns + + @staticmethod + def _should_ignore(path, ignore_patterns, root_path): + """Check if a path should be ignored based on .pbignore patterns""" + if not ignore_patterns: + return False + + # Get relative path from root + try: + rel_path = os.path.relpath(path, root_path) + except ValueError: + # If path is not relative to root, don't ignore + return False + + # Normalize path separators + rel_path = rel_path.replace(os.sep, '/') + + for pattern in ignore_patterns: + # Handle directory patterns (ending with /) + if pattern.endswith('/'): + pattern = pattern[:-1] + if fnmatch.fnmatch(rel_path, pattern) or fnmatch.fnmatch(rel_path, pattern + '/*'): + return True + else: + # Handle file/directory patterns + if fnmatch.fnmatch(rel_path, pattern) or fnmatch.fnmatch(os.path.basename(rel_path), pattern): + return True + + return False + @staticmethod def scan_project(root_path): sys.path.append(root_path) @@ -13,20 +62,37 @@ class Project: parent_dir = os.path.dirname(root_path) sys.path.insert(0, parent_dir) + # Load .pbignore patterns + ignore_patterns = Project._load_pbignore(root_path) + def import_all_modules(path, package_name): for root, dirs, files in os.walk(path): + # Check if current directory should be ignored + if Project._should_ignore(root, ignore_patterns, root_path): + dirs[:] = [] # Don't traverse into ignored directories + continue + relative_path = os.path.relpath(root, root_path) if relative_path == '.': module_package = package_name else: module_package = f"{package_name}.{relative_path.replace(os.sep, '.')}" + for file in files: if file.endswith(".py") and file != "__init__.py": + file_path = os.path.join(root, file) + # Check if file should be ignored + if Project._should_ignore(file_path, ignore_patterns, root_path): + continue + module_name = file[:-3] full_module_name = f"{module_package}.{module_name}" if full_module_name not in sys.modules: importlib.import_module(full_module_name) - dirs[:] = [d for d in dirs if not d.startswith('.')] + + # Filter out ignored directories from further traversal + dirs[:] = [d for d in dirs if not d.startswith('.') and + not Project._should_ignore(os.path.join(root, d), ignore_patterns, root_path)] package_name = os.path.basename(root_path) import_all_modules(root_path, package_name) diff --git a/setup.py b/setup.py index 0a6712d..418b63d 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup( name="pyboot", - version="0.1", + version="0.2", packages=find_packages(), package_data={ 'pyboot': ['templates/*.py',"ui/server/*.py", "ui/client/*",