예제 #1
0
def fetch_custom(package_mapping):
    """Retrieve :term:`Wiz` definition from package mapping installed.

    Return the :term:`Wiz` definition extracted from a
    :file:`package_data/wiz.json` file found within the package installation
    path.

    :param package_mapping: mapping of the python package built as returned by
        :func:`qip.package.install`.

    :raise wiz.exception.WizError: if the :term:`Wiz` definition found is
        incorrect.

    :return: :class:`wiz.definition.Definition` instance fetched, or None if
        no definition was found.

    .. seealso:: :ref:`development/custom_definition`

    """
    logger = logging.getLogger(__name__ + ".retrieve")

    definition_path = os.path.join(package_mapping["location"],
                                   package_mapping["module_name"],
                                   "package_data", "wiz.json")

    if os.path.exists(definition_path):
        definition = wiz.load_definition(definition_path)
        logger.info("\tWiz definition extracted from '{}'.".format(
            package_mapping["identifier"]))
        return definition
예제 #2
0
def test_install_numpy_several_versions(temporary_directory, logger):
    """Install numpy.

    Like the previous test, install numpy version within 1.16.6 and 1.20.2 which
    covers all Python version supported by Qip. Then install numpy while
    excluding the latest versions supported by 2.7 and 3+ to force another
    version to get installed.

    """
    packages_path = os.path.join(temporary_directory, "packages")
    definitions_path = os.path.join(temporary_directory, "definitions")

    runner = CliRunner()
    result = runner.invoke(qip.command_line.main, [
        "install",
        "numpy >= 1.16.6, <= 1.20.2",
        "numpy != 1.16.6, < 1.20.2",
        "-o",
        packages_path,
        "-d",
        definitions_path,
    ])
    assert not result.exception
    assert result.exit_code == 0

    # Check log.
    logger.info.assert_called()
    logger.warning.assert_not_called()
    logger.error.assert_not_called()

    # Check definitions installed.
    definitions = os.listdir(definitions_path)
    assert len(definitions) == 2
    assert definitions[0] != definitions[1]

    assert re.match(r"^library-numpy-1..*.json$", definitions[0])
    path = os.path.join(definitions_path, definitions[0])
    assert os.path.isfile(path)
    definition1 = wiz.load_definition(path)

    assert re.match(r"^library-numpy-1..*.json$", definitions[1])
    path = os.path.join(definitions_path, definitions[1])
    assert os.path.isfile(path)
    definition2 = wiz.load_definition(path)

    # Ensure that definitions are correct.
    for definition in [definition1, definition2]:
        assert definition.qualified_identifier == "library::numpy"
        assert definition.install_root == packages_path
        assert definition.system is not None
        assert definition.requirements == []
        assert definition.environ == {
            "PYTHONPATH": "${INSTALL_LOCATION}:${PYTHONPATH}"
        }
        assert len(definition.variants) == 1
        assert len(definition.variants[0].requirements) == 1
        assert definition.variants[0].requirements[0].name == "python"

    assert definition1.version != definition2.version

    # Check packages installed.
    assert len(os.listdir(packages_path)) == 1
    path = os.path.join(packages_path, "numpy")
    assert os.path.isdir(path)

    versions = os.listdir(path)
    assert len(versions) == 2

    for version in versions:
        assert re.match(r"^numpy-1..*", version)
        lib_path = os.path.join(path, version, "lib", PY_LIB, "site-packages")
        module_path = os.path.join(lib_path, "numpy")
        assert os.path.isdir(lib_path)
        assert os.path.isdir(module_path)

        # Check that module can be imported.
        sys.path.insert(0, lib_path)
        importlib.import_module("numpy")
        del sys.path[0]
예제 #3
0
def test_install_numpy(temporary_directory, logger):
    """Install numpy.

    Install numpy version within 1.16.6 and 1.20.2 which covers all Python
    version supported by Qip. numpy doesn't have any dependencies.

    """
    packages_path = os.path.join(temporary_directory, "packages")
    definitions_path = os.path.join(temporary_directory, "definitions")

    runner = CliRunner()
    result = runner.invoke(qip.command_line.main, [
        "install",
        "numpy >= 1.16.6, <= 1.20.2",
        "-o",
        packages_path,
        "-d",
        definitions_path,
    ])
    assert not result.exception
    assert result.exit_code == 0

    # Check log.
    logger.info.assert_called()
    logger.warning.assert_not_called()
    logger.error.assert_not_called()

    # Check definitions installed.
    definitions = os.listdir(definitions_path)
    assert len(definitions) == 1
    assert re.match(r"^library-numpy-1..*.json$", definitions[0])
    path = os.path.join(definitions_path, definitions[0])
    assert os.path.isfile(path)

    # Ensure that definition is correct.
    definition = wiz.load_definition(path)
    assert definition.qualified_identifier == "library::numpy"
    assert definition.install_root == packages_path
    assert definition.system is not None
    assert definition.requirements == []
    assert definition.environ == {
        "PYTHONPATH": "${INSTALL_LOCATION}:${PYTHONPATH}"
    }
    assert len(definition.variants) == 1
    assert len(definition.variants[0].requirements) == 1
    assert definition.variants[0].requirements[0].name == "python"

    # Check package installed.
    assert len(os.listdir(packages_path)) == 1
    path = os.path.join(packages_path, "numpy")
    assert os.path.isdir(path)

    versions = os.listdir(path)
    assert len(versions) == 1
    assert re.match(r"^numpy-1..*", versions[0])
    lib_path = os.path.join(path, versions[0], "lib", PY_LIB, "site-packages")
    module_path = os.path.join(lib_path, "numpy")
    assert os.path.isdir(lib_path)
    assert os.path.isdir(module_path)

    # Check that module can be imported.
    sys.path.insert(0, lib_path)
    importlib.import_module("numpy")
    del sys.path[0]
예제 #4
0
def test_install_skip_package_installed(temporary_directory, logger):
    """Skip existing package in output package."""
    packages_path = os.path.join(temporary_directory, "packages")
    definitions_path = os.path.join(temporary_directory, "definitions")

    # Create package to skip.
    os.makedirs(os.path.join(packages_path, "Foo", "Foo-1.2.0-py27"))

    runner = CliRunner()
    result = runner.invoke(
        qip.command_line.main, [
            "install", "-s",
            "foo >= 1, <= 2",
            "-o", packages_path,
            "-d", definitions_path,
        ]
    )
    assert not result.exception
    assert result.exit_code == 0

    # Check log.
    logger.info.assert_any_call("Packages installed: BIM-3.6.2")
    logger.warning.assert_called_once_with(
        "Skip 'Foo-1.2.0' which is already installed."
    )
    logger.error.assert_not_called()

    # Check package installed.
    expected_packages = [
        os.path.join("BIM", "BIM-3.6.2-py27"),
        os.path.join("Foo", "Foo-1.2.0-py27")
    ]

    for package in expected_packages:
        assert os.path.isdir(os.path.join(packages_path, package))

    # Check definitions installed.
    expected_definitions = ["library-bim-3.6.2.json"]

    definitions = os.listdir(definitions_path)
    assert sorted(definitions) == expected_definitions

    path = os.path.join(definitions_path, expected_definitions[0])
    definition = wiz.load_definition(path)
    assert definition.data() == {
        "identifier": "bim",
        "version": "3.6.2",
        "description": "Bim Python Package.",
        "namespace": "library",
        "install-root": packages_path,
        "environ": {
            "PYTHONPATH": "${INSTALL_LOCATION}:${PYTHONPATH}"
        },
        "variants": [
            {
                "identifier": "2.7",
                "install-location": (
                    "${INSTALL_ROOT}/BIM/BIM-3.6.2-py27/lib/python2.7/"
                    "site-packages"
                ),
                "requirements": [
                    "python >= 2.7, < 2.8",
                ]
            }
        ]
    }
예제 #5
0
def test_install_ignore_registries(temporary_directory, registry_path, logger):
    """Install packages while ignoring existing definition in registry."""
    packages_path = os.path.join(temporary_directory, "packages")
    definitions_path = os.path.join(temporary_directory, "definitions")

    # Export definition to ignore.
    wiz.export_definition(registry_path, {
        "identifier": "foo",
        "version": "1.2.0",
        "description": "Foo Python Package.",
        "namespace": "library",
        "install-root": "/path/to/foo",
        "environ": {
            "PYTHONPATH": "${INSTALL_LOCATION}:${PYTHONPATH}"
        },
        "variants": [
            {
                "identifier": "2.7",
                "install-location": (
                    "${INSTALL_ROOT}/Foo/Foo-1.2.0-py27/lib/python2.7/"
                    "site-packages"
                ),
                "requirements": [
                    "python >= 2.7, < 2.8",
                    "library::bim[2.7] >=3.4, <5"
                ]
            }
        ]
    })

    runner = CliRunner()
    result = runner.invoke(
        qip.command_line.main, [
            "install", "-I",
            "foo >= 1, <= 2",
            "-o", packages_path,
            "-d", definitions_path,
        ]
    )
    assert not result.exception
    assert result.exit_code == 0

    # Check log.
    logger.info.assert_any_call("Packages installed: BIM-3.6.2, Foo-1.2.0")
    logger.warning.assert_not_called()
    logger.error.assert_not_called()

    # Check package installed.
    expected_packages = [
        os.path.join("BIM", "BIM-3.6.2-py27"),
    ]

    for package in expected_packages:
        assert os.path.isdir(os.path.join(packages_path, package))

    # Check definitions installed.
    expected_definitions = [
        "library-bim-3.6.2.json",
        "library-foo-1.2.0.json"
    ]

    definitions = os.listdir(definitions_path)
    assert sorted(definitions) == expected_definitions

    path = os.path.join(definitions_path, expected_definitions[0])
    definition = wiz.load_definition(path)
    assert definition.data() == {
        "identifier": "bim",
        "version": "3.6.2",
        "description": "Bim Python Package.",
        "namespace": "library",
        "install-root": packages_path,
        "environ": {
            "PYTHONPATH": "${INSTALL_LOCATION}:${PYTHONPATH}"
        },
        "variants": [
            {
                "identifier": "2.7",
                "install-location": (
                    "${INSTALL_ROOT}/BIM/BIM-3.6.2-py27/lib/python2.7/"
                    "site-packages"
                ),
                "requirements": [
                    "python >= 2.7, < 2.8",
                ]
            }
        ]
    }

    path = os.path.join(definitions_path, expected_definitions[1])
    definition = wiz.load_definition(path)
    assert definition.data() == {
        "identifier": "foo",
        "version": "1.2.0",
        "description": "Foo Python Package.",
        "namespace": "library",
        "install-root": packages_path,
        "command": {
            "foo": "python -m foo"
        },
        "environ": {
            "PYTHONPATH": "${INSTALL_LOCATION}:${PYTHONPATH}"
        },
        "variants": [
            {
                "identifier": "2.7",
                "install-location": (
                    "${INSTALL_ROOT}/Foo/Foo-1.2.0-py27/lib/python2.7/"
                    "site-packages"
                ),
                "requirements": [
                    "python >= 2.7, < 2.8",
                    "library::bim[2.7] >=3.4, <5"
                ]
            }
        ]
    }
예제 #6
0
def test_install(temporary_directory, logger):
    """Install packages with all dependencies."""
    packages_path = os.path.join(temporary_directory, "packages")
    definitions_path = os.path.join(temporary_directory, "definitions")

    runner = CliRunner()
    result = runner.invoke(
        qip.command_line.main, [
            "install",
            "foo >= 1, <= 2",
            "bar == 0.1.0",
            "-o", packages_path,
            "-d", definitions_path,
        ]
    )
    assert not result.exception
    assert result.exit_code == 0

    # Check log.
    logger.info.assert_any_call(
        "Packages installed: Bar-0.1.0, BIM-3.6.2, Foo-1.2.0"
    )
    logger.warning.assert_not_called()
    logger.error.assert_not_called()

    # Check package installed.
    expected_packages = [
        os.path.join("BIM", "BIM-3.6.2-py27"),
        os.path.join("Bar", "Bar-0.1.0-py27-centos7"),
        os.path.join("Foo", "Foo-1.2.0-py27")
    ]

    for package in expected_packages:
        assert os.path.isdir(os.path.join(packages_path, package))

    # Check definitions installed.
    expected_definitions = [
        "library-bar-0.1.0-M2Uq9Esezm-m00VeWkTzkQIu3T4.json",
        "library-bim-3.6.2.json",
        "library-foo-1.2.0.json",
    ]

    definitions = os.listdir(definitions_path)
    assert sorted(definitions) == expected_definitions

    path = os.path.join(definitions_path, expected_definitions[0])
    definition = wiz.load_definition(path)
    assert definition.data() == {
        "identifier": "bar",
        "version": "0.1.0",
        "description": "Bar Python Package.",
        "namespace": "library",
        "install-root": packages_path,
        "system": {
            "platform": "linux",
            "os": "centos >= 7, < 8",
            "arch": "x86_64"
        },
        "environ": {
            "PYTHONPATH": "${INSTALL_LOCATION}:${PYTHONPATH}"
        },
        "variants": [
            {
                "identifier": "2.7",
                "install-location": (
                    "${INSTALL_ROOT}/Bar/Bar-0.1.0-py27-centos7/lib/python2.7/"
                    "site-packages"
                ),
                "requirements": [
                    "python >= 2.7, < 2.8",
                    "library::foo[2.7]"
                ]
            }
        ]
    }

    path = os.path.join(definitions_path, expected_definitions[1])
    definition = wiz.load_definition(path)
    assert definition.data() == {
        "identifier": "bim",
        "version": "3.6.2",
        "description": "Bim Python Package.",
        "namespace": "library",
        "install-root": packages_path,
        "environ": {
            "PYTHONPATH": "${INSTALL_LOCATION}:${PYTHONPATH}"
        },
        "variants": [
            {
                "identifier": "2.7",
                "install-location": (
                    "${INSTALL_ROOT}/BIM/BIM-3.6.2-py27/lib/python2.7/"
                    "site-packages"
                ),
                "requirements": [
                    "python >= 2.7, < 2.8",
                ]
            }
        ]
    }

    path = os.path.join(definitions_path, expected_definitions[2])
    definition = wiz.load_definition(path)
    assert definition.data() == {
        "identifier": "foo",
        "version": "1.2.0",
        "description": "Foo Python Package.",
        "namespace": "library",
        "install-root": packages_path,
        "command": {
            "foo": "python -m foo"
        },
        "environ": {
            "PYTHONPATH": "${INSTALL_LOCATION}:${PYTHONPATH}"
        },
        "variants": [
            {
                "identifier": "2.7",
                "install-location": (
                    "${INSTALL_ROOT}/Foo/Foo-1.2.0-py27/lib/python2.7/"
                    "site-packages"
                ),
                "requirements": [
                    "python >= 2.7, < 2.8",
                    "library::bim[2.7] >=3.4, <5"
                ]
            }
        ]
    }
예제 #7
0
def test_install_with_optional_dependencies(temporary_directory, logger):
    """Install packages with optional dependencies."""
    packages_path = os.path.join(temporary_directory, "packages")
    definitions_path = os.path.join(temporary_directory, "definitions")

    runner = CliRunner()
    result = runner.invoke(qip.command_line.main, [
        "install",
        "bim[test1]",
        "-o",
        packages_path,
        "-d",
        definitions_path,
    ])
    assert not result.exception
    assert result.exit_code == 0

    # Check log.
    logger.info.assert_any_call(
        "Packages installed: Baz-4.5.2, BIM-test1-3.6.2")
    logger.warning.assert_not_called()
    logger.error.assert_not_called()

    # Check package installed.
    expected_packages = [
        os.path.join("BIM", "BIM-test1-3.6.2-py27"),
        os.path.join("Baz", "Baz-4.5.2-py27"),
    ]

    for package in expected_packages:
        assert os.path.isdir(os.path.join(packages_path, package))

    # Check definitions installed.
    expected_definitions = [
        "library-baz-4.5.2.json",
        "library-bim-test1-3.6.2.json",
    ]

    definitions = os.listdir(definitions_path)
    assert sorted(definitions) == expected_definitions

    path = os.path.join(definitions_path, expected_definitions[0])
    definition = wiz.load_definition(path)
    assert definition.data() == {
        "identifier":
        "baz",
        "version":
        "4.5.2",
        "description":
        "Baz Python Package.",
        "namespace":
        "library",
        "install-root":
        packages_path,
        "environ": {
            "PYTHONPATH": "${INSTALL_LOCATION}:${PYTHONPATH}"
        },
        "variants": [{
            "identifier":
            "2.7",
            "install-location":
            ("${INSTALL_ROOT}/Baz/Baz-4.5.2-py27/lib/python2.7/"
             "site-packages"),
            "requirements": [
                "python >= 2.7, < 2.8",
            ]
        }]
    }

    path = os.path.join(definitions_path, expected_definitions[1])
    definition = wiz.load_definition(path)
    assert definition.data() == {
        "identifier":
        "bim-test1",
        "version":
        "3.6.2",
        "description":
        "Bim Python Package.",
        "namespace":
        "library",
        "install-root":
        packages_path,
        "command": {
            "bim1": "python -m bim"
        },
        "environ": {
            "PYTHONPATH": "${INSTALL_LOCATION}:${PYTHONPATH}"
        },
        "variants": [{
            "identifier":
            "2.7",
            "install-location":
            ("${INSTALL_ROOT}/BIM/BIM-test1-3.6.2-py27/lib/python2.7/"
             "site-packages"),
            "requirements": ["python >= 2.7, < 2.8", "library::baz[2.7]"]
        }]
    }