def test_invalid_absolute_decrement_minor(self): """Don't set the minor version, explicitly because it is a negative value.""" directory = tempfile.mkdtemp(suffix="_test_increment_minor") self.delete_item_later(directory) with open(os.path.join(directory, "package.py"), "w") as handler: handler.write( textwrap.dedent("""\ name = "foo" version = "12.5.7" """)) package = finder.get_nearest_rez_package(directory) with self.assertRaises(ValueError): rez_bump_api.bump(package, minor=-4, absolute=True)
def test_invalid_001(self): """Check that there is always at least some version information provided.""" directory = tempfile.mkdtemp(suffix="_test_increment_minor") self.delete_item_later(directory) with open(os.path.join(directory, "package.py"), "w") as handler: handler.write( textwrap.dedent("""\ name = "foo" version = "12.5.7" """)) package = finder.get_nearest_rez_package(directory) with self.assertRaises(ValueError): rez_bump_api.bump(package)
def _bump(package, increment, new_dependencies): rez_bump_api.bump(package, **{increment: 1}) with open(package.filepath, "r") as handler: code = handler.read() new_code = api.add_to_attribute("requires", new_dependencies, code) with filesystem.make_path_writable( os.path.dirname(os.path.dirname(package.filepath))): with serialise.open_file_for_write(package.filepath) as handler: handler.write(new_code) root = finder.get_package_root(package) return finder.get_nearest_rez_package(root)
def test_absolute_increment_minor(self): """Set the minor version, explicitly.""" directory = tempfile.mkdtemp(suffix="_test_increment_minor") self.delete_item_later(directory) with open(os.path.join(directory, "package.py"), "w") as handler: handler.write( textwrap.dedent("""\ name = "foo" version = "12.5.7" """)) package = finder.get_nearest_rez_package(directory) rez_bump_api.bump(package, minor=3, absolute=True) with open(package.filepath, "r") as handler: code = handler.read() expected = textwrap.dedent("""\ name = "foo" version = "12.3.7" """) self.assertEquals(expected, code)
def test_decrement_minor(self): """Lower the value of a package's version without knowing what that version is.""" directory = tempfile.mkdtemp(suffix="_test_increment_minor") self.delete_item_later(directory) with open(os.path.join(directory, "package.py"), "w") as handler: handler.write( textwrap.dedent("""\ name = "foo" version = "12.5.7" """)) package = finder.get_nearest_rez_package(directory) rez_bump_api.bump(package, minor=-4) with open(package.filepath, "r") as handler: code = handler.read() expected = textwrap.dedent("""\ name = "foo" version = "12.1.7" """) self.assertEquals(expected, code)
def test_normalize_and_increment_002(self): """Reset all of the number tokens below whatever was incremented.""" directory = tempfile.mkdtemp(suffix="_test_normalize_and_increment") self.delete_item_later(directory) with open(os.path.join(directory, "package.py"), "w") as handler: handler.write( textwrap.dedent("""\ name = "foo" version = "12.5.beta.7" """)) package = finder.get_nearest_rez_package(directory) rez_bump_api.bump(package, minor=1, normalize=True) with open(package.filepath, "r") as handler: code = handler.read() expected = textwrap.dedent("""\ name = "foo" version = "12.6.beta.0" """) self.assertEquals(expected, code)
def test_complex_details(self): """Write a really complex package.py file out, reliably, with a new version.""" directory = tempfile.mkdtemp(suffix="_test_complex_details") self.delete_item_later(directory) with open(os.path.join(directory, "package.py"), "w") as handler: handler.write( textwrap.dedent("""\ name = "my_complex_rez_package" description = ( "Abominable whitespace " "because we can." ) authors = [ "Some first / last name", "John Doe", ] version = "1.0.0" # I am commented information help = [ ["README", "README.md"], ["Home Page", "http://google.com"], ] @late() def requires(): if in_context(): return ["foo"] return ["bar"] variants = [ ["python-2.7", "more_packages", "here"], ["python-3"], ] def commands(): import os env.THING.set("something_here") env.PYTHONPATH.append(os.path.join("{root}", "python")) """)) package = finder.get_nearest_rez_package(directory) rez_bump_api.bump(package, minor=3) with open(package.filepath, "r") as handler: code = handler.read() expected = textwrap.dedent("""\ name = "my_complex_rez_package" description = ( "Abominable whitespace " "because we can." ) authors = [ "Some first / last name", "John Doe", ] version = "1.3.0" # I am commented information help = [ ["README", "README.md"], ["Home Page", "http://google.com"], ] @late() def requires(): if in_context(): return ["foo"] return ["bar"] variants = [ ["python-2.7", "more_packages", "here"], ["python-3"], ] def commands(): import os env.THING.set("something_here") env.PYTHONPATH.append(os.path.join("{root}", "python")) """) self.assertEquals(expected, code)
def replace( # pylint: disable=too-many-arguments package, configuration, deprecate, requirements, bump=True, force_requirements_bump=False, ): """Replace as many Rez packages listed in `deprecate` with those listed in `requirements`. These packages get added / removed from `package` and written to-disk. This function isn't guaranteed to replace anything in `package`. It all depends on if, after changing the Python imports of the Python files in `configuration` if it looks like a dependency in `deprecate` isn't needed anymore, only then is it removed. Likewise, if the changed imports don't use anything in `requirements` then no new Rez packages will be added as dependencies to `package`, either. Args: package (:class:`rez.packges_.DeveloperPackage`): Some Rez package whose requirements may change as a result of this function getting ran. Requirements that originally existed may be removed. New requirements may be added. configuration (:attr:`move_break.cli.Configuration`): The user-provided options to the `move_break` package. It controls which Python modules will get their imports changed and how the imports will be changed. deprecate (iter[tuple[:class:`rez.vendor.version.requirement.Requirement`, tuple[str]]]): Each Rez package that is (assumed to already be) a dependency of `package` and the Python import namespaces that the package takes up. requirements (iter[tuple[:class:`rez.vendor.version.requirement.Requirement`, tuple[str]]]): Each Rez package that we'd like to add as dependencies to `package` followed by the Python dot-separated namespaces that each Rez package defines. bump (bool, optional): If True and `package` or its contents are modified, increment the minor version of `package` to reflect the new changes. If False, don't change the minor version of the Rez package even after new changes were made. Default is True. force_requirements_bump (bool, optional): If True, bump each requirement, even if nothing about any Python module has changed on-disk. If False, only bump the Rez package requirement if changes have been made. Default is False. """ # Replace Python imports in all of the paths in `configuration` overwritten_paths = move_break_api.move_imports( configuration.paths, configuration.namespaces, partial=configuration.partial_matches, import_types=configuration.types, aliases=configuration.aliases, continue_on_syntax_error=configuration.continue_on_syntax_error, ) if not overwritten_paths and not force_requirements_bump: return imported_namespaces = dependency_analyzer.get_imported_namespaces( configuration.paths, convert_relative_imports=False) namespaces = {module.get_namespace() for module in imported_namespaces} _remove_deprecated_packages(package, namespaces, deprecate) changed = _add_new_requirement_packages( package, namespaces, requirements, force=force_requirements_bump, ) if bump and changed and package.version: rez_bump_api.bump(package, minor=1, normalize=True)