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)