Esempio n. 1
0
    def from_path(cls, path):
        """Load a developer package.

        A developer package may for example be a package.yaml or package.py in a
        user's source directory.

        Args:
            path: Directory containing the package definition file.

        Returns:
            `Package` object.
        """
        name = None
        data = None

        for name_ in config.plugins.package_repository.filesystem.package_filenames:
            for format_ in (FileFormat.py, FileFormat.yaml):
                filepath = os.path.join(path, "%s.%s" % (name_, format_.extension))

                if os.path.isfile(filepath):
                    data = load_from_file(filepath, format_)
                    break
            if data:
                name = data.get("name")
                if name is not None or isinstance(name, basestring):
                    break

        if data is None:
            raise PackageMetadataError("No package definition file found at %s" % path)

        if name is None or not isinstance(name, basestring):
            raise PackageMetadataError(
                "Error in %r - missing or non-string field 'name'" % filepath)

        package = create_package(name, data, package_cls=cls)

        # preprocessing
        result = package._get_preprocessed(data)

        if result:
            package, data = result

        package.filepath = filepath

        # find all includes, this is needed at install time to copy the right
        # py sourcefiles into the package installation
        package.includes = set()

        def visit(d):
            for k, v in d.iteritems():
                if isinstance(v, SourceCode):
                    package.includes |= (v.includes or set())
                elif isinstance(v, dict):
                    visit(v)

        visit(data)

        package._validate_includes()

        return package
Esempio n. 2
0
 def test_1_memory_variant_parent(self):
     """Test that a package's variant's parent is the original package
     """
     desc = 'the foo package'
     package = create_package('foo', {'description': desc})
     self.assertEqual(package.description, desc)
     variant = package.iter_variants().next()
     parent_package = variant.parent
     self.assertEqual(package.description, desc)
Esempio n. 3
0
 def test_1_memory_variant_parent(self):
     """Test that a package's variant's parent is the original package
     """
     desc = 'the foo package'
     package = create_package('foo', {'description': desc})
     self.assertEqual(package.description, desc)
     variant = package.iter_variants().next()
     parent_package = variant.parent
     self.assertEqual(package.description, desc)
Esempio n. 4
0
    def test_4(self):
        """test package creation."""
        package_data = {
            "name":             "foo",
            "version":          "1.0.0",
            "description":      "something foo-like",
            "requires":         ["python-2.6+"]}

        package = create_package("foo", package_data)
        self.assertEqual(package.version, Version("1.0.0"))
        self.assertEqual(package.description, "something foo-like")
        self.assertEqual(package.requires, [PackageRequest("python-2.6+")])

        family = package.parent
        self.assertEqual(family.name, package.name)
        packages = list(family.iter_packages())
        self.assertEqual(len(packages), 1)
        self.assertEqual(package, packages[0])
Esempio n. 5
0
    def test_4(self):
        """test package creation."""
        package_data = {
            "name":             "foo",
            "version":          "1.0.0",
            "description":      "something foo-like",
            "requires":         ["python-2.6+"]}

        package = create_package("foo", package_data)
        self.assertEqual(package.version, Version("1.0.0"))
        self.assertEqual(package.description, "something foo-like")
        self.assertEqual(package.requires, [PackageRequest("python-2.6+")])

        family = package.parent
        self.assertEqual(family.name, package.name)
        packages = list(family.iter_packages())
        self.assertEqual(len(packages), 1)
        self.assertEqual(package, packages[0])
Esempio n. 6
0
    def from_path(cls, path):
        """Load a developer package.

        A developer package may for example be a package.yaml or package.py in a
        user's source directory.

        Args:
            path: Directory containing the package definition file.

        Returns:
            `Package` object.
        """
        name = None
        data = None

        for name_ in config.plugins.package_repository.filesystem.package_filenames:
            for format_ in (FileFormat.py, FileFormat.yaml):
                filepath = os.path.join(path,
                                        "%s.%s" % (name_, format_.extension))

                if os.path.isfile(filepath):
                    data = load_from_file(filepath, format_)
                    break
            if data:
                name = data.get("name")
                if name is not None or isinstance(name, basestring):
                    break

        if data is None:
            raise PackageMetadataError(
                "No package definition file found at %s" % path)

        if name is None or not isinstance(name, basestring):
            raise PackageMetadataError(
                "Error in %r - missing or non-string field 'name'" % filepath)

        package = create_package(name, data, package_cls=cls)

        # preprocessing
        result = package._get_preprocessed(data)

        if result:
            package, data = result

        package.filepath = filepath

        # find all includes, this is needed at install time to copy the right
        # py sourcefiles into the package installation
        package.includes = set()

        def visit(d):
            for k, v in d.iteritems():
                if isinstance(v, SourceCode):
                    package.includes |= (v.includes or set())
                elif isinstance(v, dict):
                    visit(v)

        visit(data)

        package._validate_includes()

        return package
Esempio n. 7
0
    def _get_preprocessed(self, data):
        """
        Returns:
            (DeveloperPackage, new_data) 2-tuple IFF the preprocess function
            changed the package; otherwise None.
        """
        from rez.serialise import process_python_objects
        from rez.utils.data_utils import get_dict_diff
        from copy import deepcopy

        with add_sys_paths(config.package_definition_build_python_paths):
            preprocess = getattr(self, "preprocess", None)

            if preprocess:
                preprocess_func = preprocess.func
                print_info("Applying preprocess from package.py")
            else:
                # load globally configured preprocess function
                dotted = self.config.package_preprocess_function

                if not dotted:
                    return None

                if '.' not in dotted:
                    print_error(
                        "Setting 'package_preprocess_function' must be of "
                        "form 'module[.module.module...].funcname'. Package  "
                        "preprocessing has not been applied.")
                    return None

                name, funcname = dotted.rsplit('.', 1)

                try:
                    module = __import__(name=name, fromlist=[funcname])
                except Exception as e:
                    print_error(
                        "Failed to load preprocessing function '%s': %s" %
                        (dotted, str(e)))
                    return None

                setattr(module, "InvalidPackageError", InvalidPackageError)
                preprocess_func = getattr(module, funcname)

                if not preprocess_func or not isfunction(isfunction):
                    print_error("Function '%s' not found" % dotted)
                    return None

                print_info("Applying preprocess function %s" % dotted)

            preprocessed_data = deepcopy(data)

            # apply preprocessing
            try:
                preprocess_func(this=self, data=preprocessed_data)
            except InvalidPackageError:
                raise
            except Exception as e:
                print_error("Failed to apply preprocess: %s: %s" %
                            (e.__class__.__name__, str(e)))
                return None

        # if preprocess added functions, these need to be converted to
        # SourceCode instances
        preprocessed_data = process_python_objects(preprocessed_data)

        if preprocessed_data == data:
            return None

        # recreate package from modified package data
        package = create_package(self.name,
                                 preprocessed_data,
                                 package_cls=self.__class__)

        # print summary of changed package attributes
        added, removed, changed = get_dict_diff(data, preprocessed_data)
        lines = ["Package attributes were changed in preprocessing:"]

        if added:
            lines.append("Added attributes: %s" % ['.'.join(x) for x in added])
        if removed:
            lines.append("Removed attributes: %s" %
                         ['.'.join(x) for x in removed])
        if changed:
            lines.append("Changed attributes: %s" %
                         ['.'.join(x) for x in changed])

        txt = '\n'.join(lines)
        print_info(txt)

        return package, preprocessed_data
Esempio n. 8
0
    def from_path(cls, path, format=None):
        """Load a developer package.

        A developer package may for example be a package.yaml or package.py in a
        user's source directory.

        Args:
            path: Directory containing the package definition file, or file
                path for the package file itself
            format: which FileFormat to use, or None to check both .py and .yaml

        Returns:
            `Package` object.
        """
        name = None
        data = None

        if format is None:
            formats = (FileFormat.py, FileFormat.yaml)
        else:
            formats = (format,)

        try:
            mode = os.stat(path).st_mode
        except (IOError, OSError):
            raise PackageMetadataError(
                "Path %r did not exist, or was not accessible" % path)
        is_dir = stat.S_ISDIR(mode)

        for name_ in config.plugins.package_repository.filesystem.package_filenames:
            for format_ in formats:
                if is_dir:
                    filepath = os.path.join(path, "%s.%s" % (name_,
                                                             format_.extension))
                    exists = os.path.isfile(filepath)
                else:
                    # if format was not specified, verify that it has the
                    # right extension before trying to load
                    if format is None:
                        if os.path.splitext(path)[1] != format_.extension:
                            continue
                    filepath = path
                    exists = True

                if exists:
                    data = load_from_file(filepath, format_, disable_memcache=True)
                    break
            if data:
                name = data.get("name")
                if name is not None or isinstance(name, basestring):
                    break

        if data is None:
            raise PackageMetadataError("No package definition file found at %s" % path)

        if name is None or not isinstance(name, basestring):
            raise PackageMetadataError(
                "Error in %r - missing or non-string field 'name'" % filepath)

        package = create_package(name, data, package_cls=cls)

        # preprocessing
        result = package._get_preprocessed(data)

        if result:
            package, data = result

        package.filepath = filepath

        # find all includes, this is needed at install time to copy the right
        # py sourcefiles into the package installation
        package.includes = set()

        def visit(d):
            for k, v in d.iteritems():
                if isinstance(v, SourceCode):
                    package.includes |= (v.includes or set())
                elif isinstance(v, dict):
                    visit(v)

        visit(data)

        package._validate_includes()

        return package
Esempio n. 9
0
    def _get_preprocessed(self, data):
        """
        Returns:
            (DeveloperPackage, new_data) 2-tuple IFF the preprocess function
            changed the package; otherwise None.
        """
        from rez.serialise import process_python_objects
        from rez.utils.data_utils import get_dict_diff_str
        from copy import deepcopy

        with add_sys_paths(config.package_definition_build_python_paths):
            preprocess_func = getattr(self, "preprocess", None)

            if preprocess_func:
                print_info("Applying preprocess from package.py")
            else:
                # load globally configured preprocess function
                dotted = self.config.package_preprocess_function

                if not dotted:
                    return None

                if '.' not in dotted:
                    print_error(
                        "Setting 'package_preprocess_function' must be of "
                        "form 'module[.module.module...].funcname'. Package  "
                        "preprocessing has not been applied.")
                    return None

                name, funcname = dotted.rsplit('.', 1)

                try:
                    module = __import__(name=name, fromlist=[funcname])
                except Exception as e:
                    print_error("Failed to load preprocessing function '%s': %s"
                                % (dotted, str(e)))
                    return None

                setattr(module, "InvalidPackageError", InvalidPackageError)
                preprocess_func = getattr(module, funcname)

                if not preprocess_func or not isfunction(isfunction):
                    print_error("Function '%s' not found" % dotted)
                    return None

                print_info("Applying preprocess function %s" % dotted)

            preprocessed_data = deepcopy(data)

            # apply preprocessing
            try:
                preprocess_func(this=self, data=preprocessed_data)
            except InvalidPackageError:
                raise
            except Exception as e:
                print_error("Failed to apply preprocess: %s: %s"
                            % (e.__class__.__name__, str(e)))
                return None

        # if preprocess added functions, these may need to be converted to
        # SourceCode instances
        preprocessed_data = process_python_objects(preprocessed_data)

        if preprocessed_data == data:
            return None

        # recreate package from modified package data
        package = create_package(self.name, preprocessed_data,
                                 package_cls=self.__class__)

        # print summary of changed package attributes
        txt = get_dict_diff_str(
            data,
            preprocessed_data,
            title="Package attributes were changed in preprocessing:"
        )
        print_info(txt)

        return package, preprocessed_data
Esempio n. 10
0
    def _get_preprocessed(self, data):
        """
        Returns:
            (DeveloperPackage, new_data) 2-tuple IF the preprocess function
            changed the package; otherwise None.
        """
        from rez.serialise import process_python_objects
        from rez.utils.data_utils import get_dict_diff_str
        from copy import deepcopy

        package_preprocess_mode = self.config.package_preprocess_mode

        def _get_package_level():
            return getattr(self, "preprocess", None)

        def _get_global_level():
            # load globally configured preprocess function
            package_preprocess_function = self.config.package_preprocess_function

            if not package_preprocess_function:
                return None

            elif isfunction(package_preprocess_function):
                preprocess_func = package_preprocess_function

            else:
                if '.' not in package_preprocess_function:
                    print_error(
                        "Setting 'package_preprocess_function' must be of "
                        "form 'module[.module.module...].funcname'. Package  "
                        "preprocessing has not been applied.")
                    return None

                elif isinstance(package_preprocess_function, basestring):
                    if '.' not in package_preprocess_function:
                        print_error(
                            "Setting 'package_preprocess_function' must be of "
                            "form 'module[.module.module...].funcname'. "
                            "Package preprocessing has not been applied."
                        )
                        return None

                    name, funcname = package_preprocess_function.rsplit('.', 1)

                    try:
                        module = __import__(name=name, fromlist=[funcname])
                    except Exception as e:
                        print_error(
                            "Failed to load preprocessing function '%s': %s"
                            % (package_preprocess_function, str(e))
                        )

                        return None

                    setattr(module, "InvalidPackageError", InvalidPackageError)
                    preprocess_func = getattr(module, funcname)

                else:
                    print_error(
                        "Invalid package_preprocess_function: %s" % package_preprocess_function
                    )
                    return None

            if not preprocess_func or not isfunction(preprocess_func):
                print_error("Function '%s' not found" % package_preprocess_function)
                return None

            return preprocess_func

        with add_sys_paths(config.package_definition_build_python_paths):

            preprocess_mode = PreprocessMode[self.config.package_preprocess_mode]
            package_preprocess = _get_package_level()
            global_preprocess = _get_global_level()

            if preprocess_mode == PreprocessMode.after:
                preprocessors = [global_preprocess, package_preprocess]
            elif preprocess_mode == PreprocessMode.before:
                preprocessors = [package_preprocess, global_preprocess]
            else:
                preprocessors = [package_preprocess or global_preprocess]

            preprocessed_data = deepcopy(data)

            for preprocessor in preprocessors:
                if not preprocessor:
                    continue

                level = "global" if preprocessor == global_preprocess else "local"
                print_info("Applying {0} preprocess function".format(level))

                # apply preprocessing
                try:
                    preprocessor(this=self, data=preprocessed_data)
                except InvalidPackageError:
                    raise
                except Exception as e:
                    print_error("Failed to apply preprocess: %s: %s"
                                % (e.__class__.__name__, str(e)))
                    return None

        # if preprocess added functions, these may need to be converted to
        # SourceCode instances
        preprocessed_data = process_python_objects(preprocessed_data)

        if preprocessed_data == data:
            return None

        # recreate package from modified package data
        package = create_package(self.name, preprocessed_data,
                                 package_cls=self.__class__)

        # print summary of changed package attributes
        txt = get_dict_diff_str(
            data,
            preprocessed_data,
            title="Package attributes were changed in preprocessing:"
        )
        print_info(txt)

        return package, preprocessed_data