示例#1
0
def install(version=None, packages=None):
    """Install COMPAS for Rhino.

    Parameters
    ----------
    version : {'5.0', '6.0', '7.0'}, optional
        The version number of Rhino.
        Default is ``'6.0'``.
    packages : list of str, optional
        List of packages to install or None to use default package list.
        Default is ``['compas', 'compas_rhino', 'compas_ghpython']``.

    Examples
    --------
    .. code-block:: python

        import compas_rhino
        compas_rhino.install('6.0')

    .. code-block:: bash

        python -m compas_rhino.install -v 6.0

    """

    if version not in ('5.0', '6.0', '7.0'):
        version = '6.0'

    packages = _filter_installable_packages(version, packages)

    ipylib_path = compas_rhino._get_ironpython_lib_path(version)
    scripts_path = compas_rhino._get_scripts_path(version)

    print('Installing COMPAS packages to Rhino {0} scripts folder:'.format(
        version))
    print('Location scripts folder: {}'.format(scripts_path))
    print()

    results = []
    symlinks_to_install = []
    symlinks_to_uninstall = []
    exit_code = 0

    for package in packages:
        package_path = compas_rhino._get_package_path(
            importlib.import_module(package))
        symlink_path = os.path.join(scripts_path, package)
        symlinks_to_install.append(
            dict(name=package, source_path=package_path, link=symlink_path))
        symlinks_to_uninstall.append(dict(name=package, link=symlink_path))

        # Handle legacy install location
        legacy_path = os.path.join(ipylib_path, package)
        if os.path.exists(legacy_path):
            symlinks_to_uninstall.append(dict(name=package, link=legacy_path))

    # First uninstall existing copies of packages requested for installation
    symlinks = [link['link'] for link in symlinks_to_uninstall]
    uninstall_results = compas._os.remove_symlinks(symlinks)

    for uninstall_data, success in zip(symlinks_to_uninstall,
                                       uninstall_results):
        if not success:
            results.append(
                (uninstall_data['name'],
                 'ERROR: Cannot remove symlink, try to run as administrator.'))

    # Handle legacy bootstrapper
    if not compas_rhino._try_remove_bootstrapper(ipylib_path):
        results.append((
            'compas_bootstrapper',
            'ERROR: Cannot remove legacy compas_bootstrapper, try to run as administrator.'
        ))

    # Ready to start installing
    symlinks = [(link['source_path'], link['link'])
                for link in symlinks_to_install]
    install_results = compas._os.create_symlinks(symlinks)

    for install_data, success in zip(symlinks_to_install, install_results):
        result = 'OK' if success else 'ERROR: Cannot create symlink, try to run as administrator.'
        results.append((install_data['name'], result))

    if not all(install_results):
        exit_code = -1

    if exit_code == -1:
        results.append((
            'compas_bootstrapper',
            'WARNING: One or more packages failed, will not install bootstrapper, try uninstalling first'
        ))
    else:
        try:
            _update_bootstrapper(scripts_path, packages)
            results.append(('compas_bootstrapper', 'OK'))
        except:  # noqa: E722
            results.append((
                'compas_bootstrapper',
                'ERROR: Could not create compas_bootstrapper to auto-determine Python environment'
            ))

    for package, status in results:
        print('   {} {}'.format(package.ljust(20), status))

        if status != 'OK':
            exit_code = -1

    print('\nCompleted.')
    if exit_code != 0:
        sys.exit(exit_code)
示例#2
0
def uninstall(version=None, packages=None):
    """Uninstall COMPAS from Rhino.

    Parameters
    ----------
    version : {'5.0', '6.0', '7.0', '8.0'}, optional
        The version number of Rhino.
        Default is ``'7.0'``.
    packages : list of str, optional
        List of packages to uninstall.
        Default is to uninstall all packages installed by the COMPAS installer.

    Examples
    --------
    .. code-block:: python

        import compas_rhino
        compas_rhino.uninstall()

    .. code-block:: bash

        python -m compas_rhino.uninstall

    """
    version = compas_rhino._check_rhino_version(version)

    # We install COMPAS packages in the scripts folder
    # instead of directly as IPy module.
    scripts_path = compas_rhino._get_rhino_scripts_path(version)

    # This is for old installs
    ipylib_path = compas_rhino._get_rhino_ironpython_lib_path(version)

    # Filter the provided list of packages
    # If no packages are provided
    # this first collects all installable packages from the environment.
    packages = _filter_installed_packages(version, packages)

    # Also remove all broken symlinks
    # because ... they're broken!
    for name in os.listdir(scripts_path):
        path = os.path.join(scripts_path, name)
        if os.path.islink(path):
            if not os.path.exists(path):
                if name not in packages:
                    packages.append(name)

    # Collect paths for removal based on package names
    symlinks_to_uninstall = []

    for package in packages:
        symlink_path = os.path.join(scripts_path, package)
        symlinks_to_uninstall.append(dict(name=package, link=symlink_path))

        # Handle legacy install location
        # This does not always work,
        # and especially not in cases where it is in any case not necessary :)
        if ipylib_path:
            legacy_path = os.path.join(ipylib_path, package)
            if os.path.exists(legacy_path):
                symlinks_to_uninstall.append(
                    dict(name=package, link=legacy_path))

    # There is nothing to uninstall
    if not symlinks_to_uninstall:
        print(
            '\nNo packages to uninstall from Rhino {0} scripts folder: \n{1}.'.
            format(version, scripts_path))
        return

    # -------------------------
    # Start uninstalling
    # -------------------------

    uninstalled_packages = []
    results = []
    exit_code = 0

    symlinks = [link['link'] for link in symlinks_to_uninstall]
    uninstall_results = compas._os.remove_symlinks(symlinks)

    for uninstall_data, success in zip(symlinks_to_uninstall,
                                       uninstall_results):
        if success:
            uninstalled_packages.append(uninstall_data['name'])
            result = 'OK'
        else:
            result = 'ERROR: Cannot remove symlink, try to run as administrator.'

        results.append((uninstall_data['name'], result))

    if not all(uninstall_results):
        exit_code = -1

    if exit_code == -1:
        results.append((
            'compas_bootstrapper',
            'WARNING: One or more packages failed, will not uninstall bootstrapper.'
        ))

    else:
        if compas_rhino._try_remove_bootstrapper(scripts_path):
            results.append(('compas_bootstrapper', 'OK'))
        else:
            results.append((
                'compas_bootstrapper',
                'ERROR: Cannot remove compas_bootstrapper, try to run as administrator.'
            ))

        # Handle legacy bootstrapper
        # Again, only if possible...
        if ipylib_path:
            if not compas_rhino._try_remove_bootstrapper(ipylib_path):
                results.append((
                    'compas_bootstrapper',
                    'ERROR: Cannot remove legacy compas_bootstrapper, try to run as administrator.'
                ))

    # -------------------------
    # Output results
    # -------------------------

    print('Uninstalling COMPAS packages from Rhino {0} scripts folder: \n{1}'.
          format(version, scripts_path))
    print(
        '\nThe following packages have been detected and will be uninstalled:\n'
    )

    for package, status in results:
        print('   {} {}'.format(package.ljust(20), status))

        if status != 'OK':
            exit_code = -1

    if exit_code == 0 and uninstalled_packages:
        print('\nRunning post-uninstallation steps...\n')

        if not _run_post_execution_steps(
                after_rhino_uninstall(uninstalled_packages)):
            exit_code = -1

    print('\nUninstall completed.')

    if exit_code != 0:
        sys.exit(exit_code)
示例#3
0
def uninstall(version=None, packages=None):
    """Uninstall COMPAS from Rhino.

    Parameters
    ----------
    version : {'5.0', '6.0', '7.0'}, optional
        The version number of Rhino.
        Default is ``'6.0'``.
    packages : list of str, optional
        List of packages to uninstall.
        Default is to uninstall all packages installed by the COMPAS installer.

    Examples
    --------
    .. code-block:: python

        import compas_rhino
        compas_rhino.uninstall('6.0')

    .. code-block:: bash

        python -m compas_rhino.uninstall -v 6.0

    """
    if version not in ('5.0', '6.0', '7.0'):
        version = '6.0'

    packages = _filter_installed_packages(version, packages)

    ipylib_path = compas_rhino._get_ironpython_lib_path(version)
    scripts_path = compas_rhino._get_scripts_path(version)

    print('Uninstalling COMPAS packages from Rhino {0} scripts folder:'.format(version))
    print('Location scripts folder: {}'.format(scripts_path))
    print()

    print('The following packages have been detected and will be uninstalled:')

    results = []
    symlinks_to_uninstall = []
    exit_code = 0

    for package in packages:
        symlink_path = os.path.join(scripts_path, package)
        if os.path.exists(symlink_path):
            symlinks_to_uninstall.append(dict(name=package, link=symlink_path))

        legacy_path = os.path.join(ipylib_path, package)
        if os.path.exists(legacy_path):
            symlinks_to_uninstall.append(dict(name=package, link=legacy_path))

    symlinks = [link['link'] for link in symlinks_to_uninstall]
    uninstall_results = compas._os.remove_symlinks(symlinks)

    for uninstall_data, success in zip(symlinks_to_uninstall, uninstall_results):
        result = 'OK' if success else 'ERROR: Cannot remove symlink, try to run as administrator.'
        results.append((uninstall_data['name'], result))

    if not all(uninstall_results):
        exit_code = -1

    if exit_code == -1:
        results.append(('compas_bootstrapper', 'WARNING: One or more packages failed, will not uninstall bootstrapper.'))
    else:
        if compas_rhino._try_remove_bootstrapper(scripts_path):
            results.append(('compas_bootstrapper', 'OK'))
        else:
            results.append(('compas_bootstrapper', 'ERROR: Cannot remove compas_bootstrapper, try to run as administrator.'))

        if not compas_rhino._try_remove_bootstrapper(ipylib_path):
            results.append(('compas_bootstrapper', 'ERROR: Cannot remove legacy compas_bootstrapper, try to run as administrator.'))

    for package, status in results:
        print('   {} {}'.format(package.ljust(20), status))

        if status != 'OK':
            exit_code = -1

    print('\nUninstall completed.')
    if exit_code != 0:
        sys.exit(exit_code)
示例#4
0
def install(version=None, packages=None, clean=False):
    """Install COMPAS for Rhino.

    Parameters
    ----------
    version : {'5.0', '6.0', '7.0', '8.0'}, optional
        The version number of Rhino.
        Default is ``'7.0'``.
    packages : list of str, optional
        List of packages to install or None to use default package list.
        Default is the result of ``installable_rhino_packages``,
        which collects all installable packages in the current environment.
    clean : bool, optional
        If ``True``, this will clean up the entire scripts folder and remove
        also existing symlinks that are not importable in the current environment.

    Examples
    --------
    .. code-block:: python

        import compas_rhino.install
        compas_rhino.install.install()

    .. code-block:: bash

        python -m compas_rhino.install

    """
    version = compas_rhino._check_rhino_version(version)

    # We install COMPAS packages in the scripts folder
    # instead of directly as IPy module.
    scripts_path = compas_rhino._get_rhino_scripts_path(version)

    # This is for old installs
    ipylib_path = compas_rhino._get_rhino_ironpython_lib_path(version)

    # Filter the provided list of packages
    # If no packages are provided
    # this first collects all installable packages from the environment.
    packages = _filter_installable_packages(version, packages)

    results = []
    symlinks_to_install = []
    symlinks_to_uninstall = []
    exit_code = 0

    # check all installable packages
    # add the packages that can't be imported from the current env to the list of symlinks to uninstall
    # and remove the package name from the list of installable packages
    # make a copy of the list to avoid problems with removing items
    # note: perhaps this should already happen in the filter function...
    for name in packages[:]:
        try:
            importlib.import_module(name)
        except ImportError:
            path = os.path.join(scripts_path, name)
            symlinks_to_uninstall.append(dict(name=name, link=path))
            packages.remove(name)

    # Also remove all broken symlinks from the scripts folder
    # because ... they're broken!
    # If it is an actual folder or a file, leave it alone
    # because probably someone put it there on purpose.
    for name in os.listdir(scripts_path):
        path = os.path.join(scripts_path, name)
        if os.path.islink(path):
            if not os.path.exists(path):
                symlinks_to_uninstall.append(dict(name=name, link=path))
                try:
                    importlib.import_module(name)
                except ImportError:
                    pass
                else:
                    if name not in packages:
                        packages.append(name)

    # If the scripts folder is supposed to be cleaned
    # also remove all existing symlinks that cannot be imported
    # and reinstall symlinks that can be imported
    if clean:
        for name in os.listdir(scripts_path):
            path = os.path.join(scripts_path, name)
            if os.path.islink(path):
                if os.path.exists(path):
                    try:
                        importlib.import_module(name)
                    except ImportError:
                        path = os.path.join(scripts_path, name)
                        symlinks_to_uninstall.append(dict(name=name,
                                                          link=path))
                    else:
                        if name not in packages:
                            packages.append(name)

    # add all of the packages in the list of installable packages
    # to the list of symlinks to uninstall
    # and to the list of symlinks to install
    for package in packages:
        symlink_path = os.path.join(scripts_path, package)
        symlinks_to_uninstall.append(dict(name=package, link=symlink_path))

        package_path = compas_rhino._get_package_path(
            importlib.import_module(package))
        symlinks_to_install.append(
            dict(name=package, source_path=package_path, link=symlink_path))

        # Handle legacy install location
        # This does not always work,
        # and especially not in cases where it is not necessary :)
        if ipylib_path:
            legacy_path = os.path.join(ipylib_path, package)
            if os.path.exists(legacy_path):
                symlinks_to_uninstall.append(
                    dict(name=package, link=legacy_path))

    # -------------------------
    # Uninstall first
    # -------------------------

    symlinks = [link['link'] for link in symlinks_to_uninstall]
    uninstall_results = compas._os.remove_symlinks(symlinks)

    # Let the user know if some symlinks could not be removed.
    for uninstall_data, success in zip(symlinks_to_uninstall,
                                       uninstall_results):
        if not success:
            results.append(
                (uninstall_data['name'],
                 'ERROR: Cannot remove symlink, try to run as administrator.'))

    # Handle legacy bootstrapper
    # Again, only if possible...
    if ipylib_path:
        if not compas_rhino._try_remove_bootstrapper(ipylib_path):
            results.append((
                'compas_bootstrapper',
                'ERROR: Cannot remove legacy compas_bootstrapper, try to run as administrator.'
            ))

    # -------------------------
    # Ready to start installing
    # -------------------------

    # create new symlinks and register the results
    symlinks = [(link['source_path'], link['link'])
                for link in symlinks_to_install]
    install_results = compas._os.create_symlinks(symlinks)

    # set the exit code based on the installation results
    if not all(install_results):
        exit_code = -1

    # make a list of installed packages
    # based on the installation results
    # and update the general results list
    installed_packages = []
    for install_data, success in zip(symlinks_to_install, install_results):
        if success:
            installed_packages.append(install_data['name'])
            result = 'OK'
        else:
            result = 'ERROR: Cannot create symlink, try to run as administrator.'
        results.append((install_data['name'], result))

    # finalize the general results list with info about the bootstrapper
    if exit_code == -1:
        results.append((
            'compas_bootstrapper',
            'WARNING: One or more packages failed, will not install bootstrapper, try uninstalling first'
        ))
    else:
        try:
            _update_bootstrapper(scripts_path, packages)
            results.append(('compas_bootstrapper', 'OK'))
        except:  # noqa: E722
            results.append((
                'compas_bootstrapper',
                'ERROR: Could not create compas_bootstrapper to auto-determine Python environment'
            ))

    # output the outcome of the installation process
    # perhaps we should more info here
    print('Installing COMPAS packages to Rhino {0} scripts folder:'.format(
        version))
    print('{}\n'.format(scripts_path))

    for package, status in results:
        print('   {} {}'.format(package.ljust(20), status))
        if status != 'OK':
            exit_code = -1

    if exit_code == 0 and len(installed_packages):
        print('\nRunning post-installation steps...\n')
        if not _run_post_execution_steps(
                after_rhino_install(installed_packages)):
            exit_code = -1

    print('\nInstall completed.')
    if exit_code != 0:
        sys.exit(exit_code)

    global INSTALLED_VERSION
    INSTALLED_VERSION = version