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. If :term:`extra requirement keywords <extras_require>` are called, :term:`Wiz` definition containing each keyword will also be fetched and merged together into one definition. :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__ + ".fetch_custom") definitions = [] for key in [None] + package_mapping["extra"]: name = "wiz.json" if not key else "wiz-{}.json".format(key) path = os.path.join(package_mapping["location"], package_mapping["module_name"], "package_data", name) if os.path.exists(path): try: definition = wiz.definition.load(path) except wiz.exception.DefinitionError: # Initiate identifier with package key if necessary. definition = wiz.definition.load(path, mapping={ "identifier": package_mapping["key"], }) definitions.append(definition) if len(definitions): definition = definitions[0] data = definition.data(copy_data=False) # Update first definition with data fetched from other definitions. for _definition in definitions[1:]: wiz.utility.deep_update(data, _definition.data(copy_data=False)) logger.info("\tWiz definition extracted from '{}'.".format( package_mapping["identifier"])) return definition
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", ] } ] }
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" ] } ] }
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" ] } ] }
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]"] }] }