Example #1
0
    def test_variant_install(self):
        """test variant installation."""
        repo_path = os.path.join(self.root, "packages")
        if not os.path.exists(repo_path):
            os.makedirs(repo_path)

        def _data(obj):
            d = obj.validated_data()
            keys = package_release_keys + ("base", )
            for key in keys:
                d.pop(key, None)
            return d

        # package with variants and package without
        dev_pkgs_list = (("developer", "developer_changed"),
                         ("developer_novar", "developer_novar_changed"))

        for path1, path2 in dev_pkgs_list:
            path = os.path.join(self.packages_base_path, path1)
            package = get_developer_package(path)

            # install variants of the developer package into new repo
            variant = next(package.iter_variants())
            result = variant.install(repo_path, dry_run=True)
            self.assertEqual(result, None)

            for variant in package.iter_variants():
                variant.install(repo_path)

            variant = next(package.iter_variants())
            result = variant.install(repo_path, dry_run=True)
            self.assertNotEqual(result, None)

            # now there should be a package that matches the dev package
            installed_package = get_package(package.name,
                                            package.version,
                                            paths=[repo_path])
            data = _data(package)
            data_ = _data(installed_package)
            self.assertDictEqual(data, data_)

            # make a change in the dev pkg, outside of the variants.
            path = os.path.join(self.packages_base_path, path2)
            package = get_developer_package(path)

            # install a variant again. Even though the variant is already installed,
            # this should update the package, because data outside the variant changed.
            variant = next(package.iter_variants())
            result = variant.install(repo_path, dry_run=True)
            self.assertEqual(result, None)
            variant.install(repo_path)

            # check that the change was applied. This effectively also checks that the
            # variant order hasn't changed.
            installed_package = get_package(package.name,
                                            package.version,
                                            paths=[repo_path])
            data = _data(package)
            data_ = _data(installed_package)
            self.assertDictEqual(data, data_)
Example #2
0
def _make_package(help_=tuple()):
    """Make a Rez package with the given help attribute for testing.

    Args:
        help_ (str or list[list[str, str]]):
            A single help string or a list of display + help string
            pairs. The left of the pair is the text users might see. The
            right side is either an absolute or relative path on-disk or
            a website URL.

    Returns:
        :class:`rez.packages.DeveloperPackage`: The generated package.

    """
    directory = tempfile.mkdtemp(suffix="_make_package")
    atexit.register(functools.partial(shutil.rmtree, directory))

    name = "does_not_matter"
    version = "1.0.0"

    with package_maker.make_package(name, directory) as maker:
        maker.name = name
        maker.version = version
        maker.help = help_

    return packages_.get_developer_package(
        os.path.join(directory, name, version))
Example #3
0
def _FWD__spawn_build_shell(working_dir,
                            build_path,
                            variant_index,
                            install,
                            install_path=None):
    # This spawns a shell that the user can run the build command in directly
    context = ResolvedContext.load(os.path.join(build_path, "build.rxt"))
    package = get_developer_package(working_dir)
    variant = package.get_variant(variant_index)
    config.override("prompt", "BUILD>")

    actions_callback = functools.partial(CustomBuildSystem._add_build_actions,
                                         context=context,
                                         package=package,
                                         variant=variant,
                                         build_type=BuildType.local,
                                         install=install,
                                         build_path=build_path,
                                         install_path=install_path)

    post_actions_callback = functools.partial(
        CustomBuildSystem.add_pre_build_commands,
        variant=variant,
        build_type=BuildType.local,
        install=install,
        build_path=build_path,
        install_path=install_path)

    retcode, _, _ = context.execute_shell(
        block=True,
        cwd=build_path,
        actions_callback=actions_callback,
        post_actions_callback=post_actions_callback)

    sys.exit(retcode)
Example #4
0
    def __init__(self, working_dir, opts=None, package=None,
                 write_build_scripts=False, verbose=False, build_args=[],
                 child_build_args=[]):
        """Create a build system instance.

        Args:
            working_dir: Directory to build source from.
            opts: argparse.Namespace object which may contain constructor
                params, as set by our bind_cli() classmethod.
            package (`DeveloperPackage`): Package to build. If None, defaults to
                the package in the working directory.
            write_build_scripts: If True, create build scripts rather than
                perform the full build. The user can then run these scripts to
                place themselves into a build environment and invoke the build
                system directly.
            build_args: Extra cli build arguments.
            child_build_args: Extra cli args for child build system, ignored if
                there is no child build system.
        """
        self.working_dir = working_dir
        if not self.is_valid_root(working_dir):
            raise BuildSystemError(
                "Not a valid working directory for build system %r: %s"
                % (self.name(), working_dir))

        self.package = package or get_developer_package(working_dir)

        self.write_build_scripts = write_build_scripts
        self.build_args = build_args
        self.child_build_args = child_build_args
        self.verbose = verbose

        self.opts = opts
Example #5
0
    def test_4(self):
        """Test package config overrides."""
        conf = os.path.join(self.config_path, "test2.py")
        config2 = Config([self.root_config_file, conf])

        with _replace_config(config2):
            pkg = get_developer_package(self.config_path)
            c = pkg.config
            self._test_basic(c)

            # check overrides from package.py are working
            os.environ["REZ_BUILD_DIRECTORY"] = "foo"  # should have no effect
            self.assertEqual(c.build_directory, "weeble")
            self.assertEqual(c.plugins.release_vcs.tag_name, "tag")

            # check list modification is working
            self.assertEqual(c.release_hooks, ["foo", "bah"])

            # check list modification within plugin settings is working
            self.assertEqual(c.plugins.release_hook.emailer.recipients,
                             ["*****@*****.**", "*****@*****.**"])

            # check system expansion in package overridden setting works
            expected_value = "*****@*****.**" % system.user
            self.assertEqual(c.plugins.release_hook.emailer.sender, expected_value)

            # check env-var expansion in package overridden setting works
            os.environ["FUNK"] = "dude"
            expected_value = ["FOO", "BAH_dude", "EEK"]
            self.assertEqual(c.parent_variables, expected_value)

            self._test_overrides(c)
Example #6
0
    def is_valid_root(cls, path, package=None):
        if package is None:
            try:
                package = get_developer_package(path)
            except PackageMetadataError:
                return False

        return (getattr(package, "build_command", None) is not None)
Example #7
0
def get_current_developer_package():
    from rez.packages import get_developer_package

    global _package

    if _package is None:
        _package = get_developer_package(os.getcwd())

    return _package
Example #8
0
    def __init__(self, source_path):
        """Create a release hook.

        Args:
            source_path: Path containing source that was released.
        """
        self.source_path = source_path
        self.package = get_developer_package(source_path)
        self.type_settings = self.package.config.plugins.release_hook
        self.settings = self.type_settings.get(self.name())
Example #9
0
    def test_developer_dynamic_global_preprocess_string(self):
        """test developer package with a global preprocess function as string"""
        # a developer package with features such as expanding requirements,
        # global preprocessing
        self.update_settings(
            {"package_preprocess_function": "global_preprocess.inject_data"})

        path = os.path.join(self.packages_base_path,
                            "developer_dynamic_global_preprocess")
        package = get_developer_package(path)

        self.assertEqual(package.description, "This.")
        self.assertEqual(package.added_by_global_preprocess, True)
Example #10
0
 def test_developer_pkg(self):
     """test developer package."""
     path = os.path.join(self.packages_base_path, "developer")
     package = get_developer_package(path)
     expected_data = dict(name="foo",
                          version=Version("3.0.1"),
                          description="a foo type thing.",
                          authors=["joe.bloggs"],
                          requires=[PackageRequest('bah-1.2+<2')],
                          variants=[[PackageRequest('floob-4.1')],
                                    [PackageRequest('floob-2.0')]],
                          uuid="28d94bcd1a934bb4999bcf70a21106cc")
     data = package.validated_data()
     self.assertDictEqual(data, expected_data)
Example #11
0
def get_current_developer_package():
    from rez.packages import get_developer_package
    from rez.exceptions import PackageMetadataError

    global _package

    if _package is None:
        try:
            _package = get_developer_package(os.getcwd())
        except PackageMetadataError:
            # no package, or bad package
            pass

    return _package
Example #12
0
def get_valid_build_systems(working_dir, package=None):
    """Returns the build system classes that could build the source in given dir.

    Args:
        working_dir (str): Dir containing the package definition and potentially
            build files.
        package (`Package`): Package to be built. This may or may not be needed
            to determine the build system. For eg, cmake just has to look for
            a CMakeLists.txt file, whereas the 'build_command' package field
            must be present for the 'custom' build system type.

    Returns:
        List of class: Valid build system class types.
    """
    from rez.plugin_managers import plugin_manager
    from rez.exceptions import PackageMetadataError

    try:
        package = package or get_developer_package(working_dir)
    except PackageMetadataError:
        # no package, or bad package
        pass

    if package:
        if getattr(package, "build_command", None) is not None:
            buildsys_name = "custom"
        else:
            buildsys_name = getattr(package, "build_system", None)

        # package explicitly specifies build system
        if buildsys_name:
            cls = plugin_manager.get_plugin_class('build_system',
                                                  buildsys_name)
            return [cls]

    # detect valid build systems
    clss = []
    for buildsys_name in get_buildsys_types():
        cls = plugin_manager.get_plugin_class('build_system', buildsys_name)
        if cls.is_valid_root(working_dir, package=package):
            clss.append(cls)

    # Sometimes files for multiple build systems can be present, because one
    # build system uses another (a 'child' build system) - eg, cmake uses
    # make. Detect this case and ignore files from the child build system.
    #
    child_clss = set(x.child_build_system() for x in clss)
    clss = list(set(clss) - child_clss)

    return clss
Example #13
0
    def __init__(self, pkg_root, vcs_root=None):
        if vcs_root is None:
            result = self.find_vcs_root(pkg_root)
            if not result:
                raise ReleaseVCSError("Could not find %s repository for the "
                                      "path %s" % (self.name(), pkg_root))
            vcs_root = result[0]
        else:
            assert(self.is_valid_root(vcs_root))

        self.vcs_root = vcs_root
        self.pkg_root = pkg_root
        self.package = get_developer_package(pkg_root)
        self.type_settings = self.package.config.plugins.release_vcs
        self.settings = self.type_settings.get(self.name())
Example #14
0
    def test_developer_dynamic_global_preprocess_func(self):
        """test developer package with a global preprocess function as function"""

        # a developer package with features such as expanding requirements,
        # global preprocessing
        def preprocess(this, data):
            data["dynamic_attribute_added"] = {'test': True}

        self.update_settings({"package_preprocess_function": preprocess})

        path = os.path.join(self.packages_base_path,
                            "developer_dynamic_global_preprocess")
        package = get_developer_package(path)

        self.assertEqual(package.description, "This.")
        self.assertEqual(package.dynamic_attribute_added, {'test': True})
Example #15
0
    def test_developer_dynamic_local_preprocess(self):
        """test developer package with a local preprocess function"""
        # a developer package with features such as expanding requirements,
        # early-binding attribute functions, and preprocessing

        # Here we will also verifies that the local preprocess function wins over
        # the global one.
        self.update_settings(
            {"package_preprocess_function": "global_preprocess.inject_data"})

        path = os.path.join(self.packages_base_path,
                            "developer_dynamic_local_preprocess")
        package = get_developer_package(path)

        self.assertEqual(package.description, "This.")
        self.assertEqual(package.requires, [PackageRequest('versioned-3')])
        self.assertEqual(package.authors, ["tweedle-dee", "tweedle-dum"])
        self.assertFalse(hasattr(package, "added_by_global_preprocess"))
        self.assertEqual(package.added_by_local_preprocess, True)
Example #16
0
    def test_developer_dynamic_after(self):
        """test developer package with both global and local preprocess in after mode"""
        # a developer package with features such as expanding requirements,
        # global preprocessing
        def preprocess(this, data):
            data["dynamic_attribute_added"] = {'value_set_by': 'global'}
            data["added_by_global_preprocess"] = True

        self.update_settings(
            {
                "package_preprocess_function": preprocess,
                "package_preprocess_mode": "after"
            }
        )

        path = os.path.join(self.packages_base_path, "developer_dynamic_local_preprocess_additive")
        package = get_developer_package(path)

        self.assertEqual(package.description, "This.")
        self.assertEqual(package.authors, ["tweedle-dee", "tweedle-dum"])
        self.assertEqual(package.dynamic_attribute_added, {'value_set_by': 'local'})
        self.assertEqual(package.added_by_global_preprocess, True)
        self.assertEqual(package.added_by_local_preprocess, True)
Example #17
0
def command(opts, parser, extra_arg_groups=None):
    from rez.packages import get_developer_package
    from rez.serialise import FileFormat
    from rez.exceptions import PackageMetadataError
    import os.path
    import os
    import sys

    if opts.PATH:
        path = os.path.expanduser(opts.PATH)
    else:
        path = os.getcwd()

    try:
        package = get_developer_package(path, format=FileFormat.yaml)
    except PackageMetadataError:
        package = None

    if package is None:
        print("Couldn't load the package at %r" % path, file=sys.stderr)
        sys.exit(1)

    package.print_info(format_=FileFormat.py)
Example #18
0
def build_eggs(  # pylint: disable=too-many-arguments
        source,
        destination,
        eggs,
        symlink=linker.must_symlink(),
        symlink_folders=linker.must_symlink_folders(),
        symlink_files=linker.must_symlink_files(),
        data_patterns=None,
):
    """Copy or symlink all items in ``source`` to ``destination``.

    Args:
        source (str):
            The absolute path to the root directory of the Rez package.
        destination (str):
            The location where the built files will be copied or symlinked from.
        eggs (iter[str], optional):
            The local paths which will be compressed into .egg (zip) files. Default is None.
        symlink (bool, optional):
            If True, symlinking will always happen. It implies
            If ``symlink_folders`` and ``symlink_files`` are both True.
            If False, symlinking is not guaranteed to always happen.
        symlink_folders (bool, optional):
            If True and ``source`` is a folder, make a symlink from
            ``destination`` which points back to ``source``. If False,
            run ``command`` instead.
        symlink_files (bool, optional):
            If True and ``source`` is a file, make a symlink from
            ``destination`` which points back to ``source``. If False,
            run ``command`` instead.

    """
    _validate_egg_names(eggs)

    if not data_patterns:
        data_patterns = set()

    package = packages.get_developer_package(
        os.path.dirname(os.environ["REZ_BUILD_PROJECT_FILE"]))
    platform = _get_platform()

    if platform:
        platforms = [platform]
    else:
        # This is apparently a common value to many "Linux, Windows, etc"
        platforms = ["any"]

    setuptools_data = _SetuptoolsData(
        package_name=os.environ["REZ_BUILD_PROJECT_NAME"],
        version=os.environ["REZ_BUILD_PROJECT_VERSION"],
        description=os.environ["REZ_BUILD_PROJECT_DESCRIPTION"],
        author=", ".join(package.authors or []),
        url=_find_api_documentation(package.help or []),
        python_requires=_get_python_requires(),
        platforms=platforms,
    )

    for name in eggs:
        _run_command(
            functools.partial(
                _build_eggs,
                name=name,
                setuptools_data=setuptools_data,
                data_patterns=data_patterns,
            ),
            os.path.join(source, name),
            os.path.join(destination, name + ".egg"),
            symlink,
            symlink_folders,
            symlink_files,
        )