From fb93b1cd9413ce71b57323e5e1c34167aa146d91 Mon Sep 17 00:00:00 2001 From: Xuwznln <18435084+Xuwznln@users.noreply.github.com> Date: Mon, 13 Oct 2025 01:35:28 +0800 Subject: [PATCH] fix startup env check. add auto install during one-key installation --- .github/workflows/conda-pack-build.yml | 55 +++++++++++++------------- scripts/verify_installation.py | 34 +++++++++++++--- unilabos/app/main.py | 8 ++-- 3 files changed, 58 insertions(+), 39 deletions(-) diff --git a/.github/workflows/conda-pack-build.yml b/.github/workflows/conda-pack-build.yml index be938651..a966d7d6 100644 --- a/.github/workflows/conda-pack-build.yml +++ b/.github/workflows/conda-pack-build.yml @@ -73,7 +73,6 @@ jobs: channels: conda-forge,robostack-staging,uni-lab,defaults channel-priority: flexible activate-environment: unilab - auto-activate-base: true auto-update-conda: false show-channel-urls: true @@ -82,7 +81,7 @@ jobs: run: | echo Installing unilabos and dependencies to unilab environment... echo Using mamba for faster and more reliable dependency resolution... - mamba install uni-lab::unilabos conda-pack -c uni-lab -c robostack-staging -c conda-forge -y + mamba install -n unilab uni-lab::unilabos conda-pack -c uni-lab -c robostack-staging -c conda-forge -y - name: Install conda-pack, unilabos and dependencies (Unix) if: steps.should_build.outputs.should_build == 'true' && matrix.platform != 'win-64' @@ -90,15 +89,15 @@ jobs: run: | echo "Installing unilabos and dependencies to unilab environment..." echo "Using mamba for faster and more reliable dependency resolution..." - mamba install uni-lab::unilabos conda-pack -c uni-lab -c robostack-staging -c conda-forge -y + mamba install -n unilab uni-lab::unilabos conda-pack -c uni-lab -c robostack-staging -c conda-forge -y - name: Get latest ros-humble-unilabos-msgs version (Windows) if: steps.should_build.outputs.should_build == 'true' && matrix.platform == 'win-64' id: msgs_version_win run: | echo Checking installed ros-humble-unilabos-msgs version... - conda list ros-humble-unilabos-msgs - for /f "tokens=2" %%i in ('conda list ros-humble-unilabos-msgs --json ^| python -c "import sys, json; pkgs=json.load(sys.stdin); print(pkgs[0]['version'] if pkgs else 'not-found')"') do set VERSION=%%i + conda list -n unilab ros-humble-unilabos-msgs + for /f "tokens=2" %%i in ('conda list -n unilab ros-humble-unilabos-msgs --json ^| python -c "import sys, json; pkgs=json.load(sys.stdin); print(pkgs[0]['version'] if pkgs else 'not-found')"') do set VERSION=%%i echo installed_version=%VERSION% >> %GITHUB_OUTPUT% echo Installed ros-humble-unilabos-msgs version: %VERSION% @@ -108,7 +107,7 @@ jobs: shell: bash run: | echo "Checking installed ros-humble-unilabos-msgs version..." - VERSION=$(conda list ros-humble-unilabos-msgs --json | python -c "import sys, json; pkgs=json.load(sys.stdin); print(pkgs[0]['version'] if pkgs else 'not-found')") + VERSION=$(conda list -n unilab ros-humble-unilabos-msgs --json | python -c "import sys, json; pkgs=json.load(sys.stdin); print(pkgs[0]['version'] if pkgs else 'not-found')") echo "installed_version=$VERSION" >> $GITHUB_OUTPUT echo "Installed ros-humble-unilabos-msgs version: $VERSION" @@ -119,7 +118,7 @@ jobs: mamba search ros-humble-unilabos-msgs -c uni-lab -c robostack-staging -c conda-forge || echo Search completed echo. echo Updating ros-humble-unilabos-msgs to latest version... - mamba update ros-humble-unilabos-msgs -c uni-lab -c robostack-staging -c conda-forge -y || echo Already at latest version + mamba update -n unilab ros-humble-unilabos-msgs -c uni-lab -c robostack-staging -c conda-forge -y || echo Already at latest version - name: Check for newer ros-humble-unilabos-msgs (Unix) if: steps.should_build.outputs.should_build == 'true' && matrix.platform != 'win-64' @@ -129,28 +128,28 @@ jobs: mamba search ros-humble-unilabos-msgs -c uni-lab -c robostack-staging -c conda-forge || echo "Search completed" echo "" echo "Updating ros-humble-unilabos-msgs to latest version..." - mamba update ros-humble-unilabos-msgs -c uni-lab -c robostack-staging -c conda-forge -y || echo "Already at latest version" + mamba update -n unilab ros-humble-unilabos-msgs -c uni-lab -c robostack-staging -c conda-forge -y || echo "Already at latest version" - name: Install latest unilabos from source (Windows) if: steps.should_build.outputs.should_build == 'true' && matrix.platform == 'win-64' run: | echo Uninstalling existing unilabos... - pip uninstall unilabos -y || echo unilabos not installed via pip + conda run -n unilab pip uninstall unilabos -y || echo unilabos not installed via pip echo Installing unilabos from source (branch: ${{ github.event.inputs.branch }})... - pip install . + conda run -n unilab pip install . echo Verifying installation... - pip show unilabos + conda run -n unilab pip show unilabos - name: Install latest unilabos from source (Unix) if: steps.should_build.outputs.should_build == 'true' && matrix.platform != 'win-64' shell: bash run: | echo "Uninstalling existing unilabos..." - pip uninstall unilabos -y || echo "unilabos not installed via pip" + conda run -n unilab pip uninstall unilabos -y || echo "unilabos not installed via pip" echo "Installing unilabos from source (branch: ${{ github.event.inputs.branch }})..." - pip install . + conda run -n unilab pip install . echo "Verifying installation..." - pip show unilabos + conda run -n unilab pip show unilabos - name: Display environment info (Windows) if: steps.should_build.outputs.should_build == 'true' && matrix.platform == 'win-64' @@ -159,10 +158,10 @@ jobs: conda env list echo. echo === Installed Packages === - conda list | findstr /C:"unilabos" /C:"ros-humble-unilabos-msgs" || conda list + conda list -n unilab | findstr /C:"unilabos" /C:"ros-humble-unilabos-msgs" || conda list -n unilab echo. echo === Python Packages === - pip list | findstr unilabos || pip list + conda run -n unilab pip list | findstr unilabos || conda run -n unilab pip list - name: Display environment info (Unix) if: steps.should_build.outputs.should_build == 'true' && matrix.platform != 'win-64' @@ -172,22 +171,22 @@ jobs: conda env list echo "" echo "=== Installed Packages ===" - conda list | grep -E "(unilabos|ros-humble-unilabos-msgs)" || conda list + conda list -n unilab | grep -E "(unilabos|ros-humble-unilabos-msgs)" || conda list -n unilab echo "" echo "=== Python Packages ===" - pip list | grep unilabos || pip list + conda run -n unilab pip list | grep unilabos || conda run -n unilab pip list - name: Verify environment integrity (Windows) if: steps.should_build.outputs.should_build == 'true' && matrix.platform == 'win-64' run: | echo Verifying Python version... - python -c "import sys; print(f'Python version: {sys.version}')" + conda run -n unilab python -c "import sys; print(f'Python version: {sys.version}')" echo Verifying unilabos import... - python -c "import unilabos; print(f'UniLabOS version: {unilabos.__version__}')" || echo Warning: Could not import unilabos + conda run -n unilab python -c "import unilabos; print(f'UniLabOS version: {unilabos.__version__}')" || echo Warning: Could not import unilabos echo Checking critical packages... - python -c "import rclpy; print('ROS2 rclpy: OK')" - echo Running comprehensive verification script... - python scripts\verify_installation.py || echo Warning: Verification script reported issues + conda run -n unilab python -c "import rclpy; print('ROS2 rclpy: OK')" + echo Running comprehensive verification script with auto-install... + conda run -n unilab python scripts\verify_installation.py --auto-install || echo Warning: Verification script reported issues echo Environment verification complete! - name: Verify environment integrity (Unix) @@ -195,13 +194,13 @@ jobs: shell: bash run: | echo "Verifying Python version..." - python -c "import sys; print(f'Python version: {sys.version}')" + conda run -n unilab python -c "import sys; print(f'Python version: {sys.version}')" echo "Verifying unilabos import..." - python -c "import unilabos; print(f'UniLabOS version: {unilabos.__version__}')" || echo "Warning: Could not import unilabos" + conda run -n unilab python -c "import unilabos; print(f'UniLabOS version: {unilabos.__version__}')" || echo "Warning: Could not import unilabos" echo "Checking critical packages..." - python -c "import rclpy; print('ROS2 rclpy: OK')" - echo "Running comprehensive verification script..." - python scripts/verify_installation.py || echo "Warning: Verification script reported issues" + conda run -n unilab python -c "import rclpy; print('ROS2 rclpy: OK')" + echo "Running comprehensive verification script with auto-install..." + conda run -n unilab python scripts/verify_installation.py --auto-install || echo "Warning: Verification script reported issues" echo "Environment verification complete!" - name: Pack conda environment (Windows) diff --git a/scripts/verify_installation.py b/scripts/verify_installation.py index 438f7ebc..e47cf8aa 100644 --- a/scripts/verify_installation.py +++ b/scripts/verify_installation.py @@ -8,7 +8,10 @@ This script verifies that UniLabOS and its dependencies are correctly installed. Run this script after installing the conda-pack environment to ensure everything works. Usage: - python verify_installation.py + python verify_installation.py [--auto-install] + + Options: + --auto-install Automatically install missing packages Or in the conda environment: conda activate unilab @@ -17,14 +20,15 @@ Usage: import sys import os +import argparse # IMPORTANT: Set UTF-8 encoding BEFORE any other imports # This ensures all subsequent imports (including unilabos) can output UTF-8 characters if sys.platform == "win32": # Method 1: Reconfigure stdout/stderr to use UTF-8 with error handling try: - sys.stdout.reconfigure(encoding="utf-8", errors="replace") - sys.stderr.reconfigure(encoding="utf-8", errors="replace") + sys.stdout.reconfigure(encoding="utf-8", errors="replace") # type: ignore + sys.stderr.reconfigure(encoding="utf-8", errors="replace") # type: ignore except (AttributeError, OSError): pass @@ -49,7 +53,7 @@ CHECK_MARK = "[OK]" CROSS_MARK = "[FAIL]" -def check_package(package_name: str, display_name: str = None) -> bool: +def check_package(package_name: str, display_name: str | None = None) -> bool: """ Check if a package can be imported. @@ -87,9 +91,25 @@ def check_python_version() -> bool: def main(): """Run all verification checks.""" + # Parse command line arguments + parser = argparse.ArgumentParser( + description="Verify UniLabOS installation", + formatter_class=argparse.RawDescriptionHelpFormatter, + ) + parser.add_argument( + "--auto-install", + action="store_true", + help="Automatically install missing packages", + ) + args = parser.parse_args() + print("=" * 60) print("UniLabOS Installation Verification") print("=" * 60) + if args.auto_install: + print("Mode: Auto-install missing packages") + else: + print("Mode: Verification only") print() all_passed = True @@ -113,14 +133,16 @@ def main(): print(f" {CHECK_MARK} UniLabOS installed") - # Check environment without auto-install (verification only) + # Check environment with optional auto-install # Set show_details=False to suppress detailed Chinese output that may cause encoding issues - env_check_passed = check_environment(auto_install=False, show_details=False) + env_check_passed = check_environment(auto_install=args.auto_install, show_details=False) if env_check_passed: print(f" {CHECK_MARK} All required packages available") else: print(f" {CROSS_MARK} Some optional packages are missing") + if not args.auto_install: + print(" Hint: Run with --auto-install to automatically install missing packages") except ImportError: print(f" {CROSS_MARK} UniLabOS not installed") all_passed = False diff --git a/unilabos/app/main.py b/unilabos/app/main.py index 2f7f825e..110ca040 100644 --- a/unilabos/app/main.py +++ b/unilabos/app/main.py @@ -11,18 +11,14 @@ from typing import Dict, Any, List import networkx as nx import yaml -from unilabos.ros.nodes.resource_tracker import ResourceTreeSet, ResourceDict - # 首先添加项目根目录到路径 current_dir = os.path.dirname(os.path.abspath(__file__)) unilabos_dir = os.path.dirname(os.path.dirname(current_dir)) if unilabos_dir not in sys.path: sys.path.append(unilabos_dir) -from unilabos.config.config import load_config, BasicConfig, HTTPConfig from unilabos.utils.banner_print import print_status, print_unilab_banner -from unilabos.resources.graphio import modify_to_backend_format - +from unilabos.config.config import load_config, BasicConfig, HTTPConfig def load_config_from_file(config_path): if config_path is None: @@ -268,6 +264,8 @@ def main(): from unilabos.app.web import http_client from unilabos.app.web import start_server from unilabos.app.register import register_devices_and_resources + from unilabos.resources.graphio import modify_to_backend_format + from unilabos.ros.nodes.resource_tracker import ResourceTreeSet, ResourceDict # 显示启动横幅 print_unilab_banner(args_dict)