示例#1
0
文件: filesystem.py 项目: wizofe/rez
class FileSystemCombinedPackageFamilyResource(PackageFamilyResource):
    key = "filesystem.family.combined"
    repository_type = "filesystem"

    schema = Schema({
        Optional("versions"): [
            And(basestring, Use(Version))
        ],
        Optional("version_overrides"): {
            And(basestring, Use(VersionRange)): dict
        }
    })

    @property
    def ext(self):
        return self.get("ext")

    @property
    def filepath(self):
        filename = "%s.%s" % (self.name, self.ext)
        return os.path.join(self.location, filename)

    def _uri(self):
        return self.filepath

    def get_last_release_time(self):
        try:
            return os.path.getmtime(self.filepath)
        except OSError:
            return 0

    def iter_packages(self):
        # unversioned package
        if config.allow_unversioned_packages and not self.versions:
            package = self._repository.get_resource(
                FileSystemCombinedPackageResource.key,
                location=self.location,
                name=self.name,
                ext=self.ext)
            yield package
            return

        # versioned packages
        for version in self.versions:
            package = self._repository.get_resource(
                FileSystemCombinedPackageResource.key,
                location=self.location,
                name=self.name,
                ext=self.ext,
                version=str(version))
            yield package

    def _load(self):
        format_ = FileFormat[self.ext]
        data = load_from_file(self.filepath, format_)
        check_format_version(self.filepath, data)
        return data
示例#2
0
 def _to(value):
     if isinstance(value, dict):
         d = {}
         for k, v in value.iteritems():
             if isinstance(k, basestring):
                 k = Required(k) if required else Optional(k)
             d[k] = _to(v)
         if allow_custom_keys:
             d[Optional(basestring)] = modifier or object
         schema = Schema(d)
     elif modifier:
         schema = And(value, modifier)
     else:
         schema = value
     return schema
示例#3
0
def extensible_schema_dict(schema_dict):
    """Create schema dict that allows arbitrary extra keys.

    This helps to keep newer configs or package definitions compatible with
    older rez versions, that may not support newer schema fields.
    """
    result = {Optional(basestring): object}

    result.update(schema_dict)
    return result
示例#4
0
from rez.package_resources_ import help_schema, _commands_schema
from rez.package_repository import create_memory_package_repository
from rez.packages_ import Package
from rez.vendor.schema.schema import Schema, Optional, Or, Use, And
from rez.vendor.version.version import Version
from contextlib import contextmanager
import os


package_request_schema = Or(basestring,
                            And(PackageRequest, Use(str)))


package_schema = Schema({
    Required("name"):                   basestring,
    Optional("base"):                   basestring,
    Optional("version"):                Or(basestring,
                                           And(Version, Use(str))),
    Optional('description'):            basestring,
    Optional('authors'):                [basestring],

    Optional('requires'):               [package_request_schema],
    Optional('build_requires'):         [package_request_schema],
    Optional('private_build_requires'): [package_request_schema],
    Optional('variants'):               [[package_request_schema]],

    Optional('uuid'):                   basestring,
    Optional('config'):                 dict,
    Optional('tools'):                  [basestring],
    Optional('help'):                   help_schema,
示例#5
0
    kitten=dict(obi=dict(colors=["black", "white"], male=True, age=1.0),
                scully=dict(colors=["tabby"], male=False, age=0.5),
                mordor=dict(colors=["black"], male=True,
                            age="infinite")),  # bad data
    puppy=dict(taco=dict(colors=["brown"],
                         male=True,
                         age=0.6,
                         owner="joe.bloggs"),
               ringo=dict(colors=["white", "grey"], male=True, age=0.8)))

pet_schema = Schema({
    Required("name"): basestring,
    Required("colors"): And([basestring], Use(set)),
    Required("male"): bool,
    Required("age"): float,
    Optional("owner"): basestring
})


class BasePetResource(Resource):
    schema_error = PetResourceError

    def __init__(self, variables=None):
        super(BasePetResource, self).__init__(variables)
        self.validations = {}

    # tracks validations
    def _validate_key(self, key, attr, key_schema):
        self.validations[key] = self.validations.get(key, 0) + 1
        return self._validate_key_impl(key, attr, key_schema)
示例#6
0
# requirements of all package-related resources
#

base_resource_schema_dict = {Required("name"): basestring}

# package family
#

package_family_schema_dict = base_resource_schema_dict.copy()

# schema common to both package and variant
#

tests_schema = Schema({
    Optional(basestring):
    Or(
        Or(basestring, [basestring]), {
            "command":
            Or(basestring, [basestring]),
            Optional("requires"):
            [Or(PackageRequest, And(basestring, Use(PackageRequest)))]
        })
})

package_base_schema_dict = base_resource_schema_dict.copy()
package_base_schema_dict.update({
    # basics
    Optional("base"):
    basestring,
    Optional("version"):
示例#7
0
    'previous_revision']


version_schema = Or(basestring, And(Version, Use(str)))


package_request_schema = Or(basestring, And(PackageRequest, Use(str)))


source_code_schema = Or(SourceCode, And(basestring, Use(SourceCode)))


# package serialisation schema
package_serialise_schema = Schema({
    Required("name"):                   basestring,
    Optional("version"):                version_schema,
    Optional("description"):            basestring,
    Optional("authors"):                [basestring],
    Optional("tools"):                  [basestring],

    Optional('requires'):               [package_request_schema],
    Optional('build_requires'):         [package_request_schema],
    Optional('private_build_requires'): [package_request_schema],
    Optional('variants'):               [[package_request_schema]],

    Optional('pre_commands'):           source_code_schema,
    Optional('commands'):               source_code_schema,
    Optional('post_commands'):          source_code_schema,

    Optional("help"):                   help_schema,
    Optional("uuid"):                   basestring,
#------------------------------------------------------------------------------
# utility schemas
#------------------------------------------------------------------------------

help_schema = Or(
    basestring,  # single help entry
    [[basestring]])  # multiple help entries

#------------------------------------------------------------------------------
# schema dicts
#------------------------------------------------------------------------------

# requirements of all package-related resources
base_resource_schema_dict = {
    Required("name"): basestring,
    Optional("nice_name"): basestring
}

# package family
package_family_schema_dict = base_resource_schema_dict.copy()

# schema common to both package and variant
package_base_schema_dict = base_resource_schema_dict.copy()
package_base_schema_dict.update({
    # basics
    Optional("base"):
    basestring,
    Optional("version"):
    Version,
    Optional('description'):
    basestring,
示例#9
0
    'pre_commands', 'post_commands', 'help', 'config', 'uuid', 'timestamp',
    'release_message', 'changelog', 'vcs', 'revision', 'previous_version',
    'previous_revision', 'has_plugins', 'plugin_for', 'plugin_launch_commands'
]

version_schema = Or(basestring, And(Version, Use(str)))

package_request_schema = Or(basestring, And(PackageRequest, Use(str)))

source_code_schema = Or(SourceCode, And(basestring, Use(SourceCode)))

# package serialisation schema
package_serialise_schema = Schema({
    Required("name"):
    basestring,
    Optional("nice_name"):
    basestring,
    Optional("version"):
    version_schema,
    Optional("description"):
    basestring,
    Optional("authors"): [basestring],
    Optional("tools"): [basestring],
    Optional("tools_info"):
    dict,
    Optional("excluded_tools"): [basestring],
    Optional('requires'): [package_request_schema],
    Optional('build_requires'): [package_request_schema],
    Optional('private_build_requires'): [package_request_schema],
    Optional('variants'): [[package_request_schema]],
    Optional('has_plugins'):
示例#10
0
from rez.package_repository import create_memory_package_repository
from rez.packages_ import Package
from rez.package_py_utils import expand_requirement
from rez.vendor.schema.schema import Schema, Optional, Or, Use, And
from rez.vendor.version.version import Version
from contextlib import contextmanager
import os

# this schema will automatically harden request strings like 'python-*'; see
# the 'expand_requires' function for more info.
#
package_request_schema = Or(And(basestring, Use(expand_requirement)),
                            And(PackageRequest, Use(str)))

tests_schema = Schema({
    Optional(basestring):
    Or(
        Or(basestring, [basestring]), {
            "command": Or(basestring, [basestring]),
            Optional("requires"): [package_request_schema]
        })
})

package_schema = Schema({
    Required("name"):
    basestring,
    Optional("base"):
    basestring,
    Optional("version"):
    Or(basestring, And(Version, Use(str))),
    Optional('description'):
示例#11
0
class CommandReleaseHook(ReleaseHook):

    commands_schema = Schema({
        "command":
        basestring,
        Optional("args"):
        Or(And(basestring, Use(lambda x: x.strip().split())), [basestring]),
        Optional("user"):
        basestring
    })

    schema_dict = {
        "print_commands": bool,
        "print_output": bool,
        "print_error": bool,
        "cancel_on_error": bool,
        "stop_on_error": bool,
        "pre_build_commands": [commands_schema],
        "pre_release_commands": [commands_schema],
        "post_release_commands": [commands_schema]
    }

    @classmethod
    def name(cls):
        return "command"

    def __init__(self, source_path):
        super(CommandReleaseHook, self).__init__(source_path)

    def execute_command(self, cmd_name, cmd_arguments, user, errors):
        def _err(msg):
            errors.append(msg)
            if self.settings.print_error:
                print >> sys.stderr, msg

        def _execute(cmd, arguments):
            try:
                result = cmd(*(arguments or []))
                if self.settings.print_output:
                    print result.stdout.strip()
            except ErrorReturnCode as e:
                # `e` shows the command that was run
                msg = "command failed:\n%s" % str(e)
                _err(msg)
                return False
            return True

        if not os.path.isfile(cmd_name):
            cmd_full_path = which(cmd_name)
        else:
            cmd_full_path = cmd_name
        if not cmd_full_path:
            msg = "%s: command not found" % cmd_name
            _err(msg)
            return False

        run_cmd = Command(cmd_full_path)
        if user == 'root':
            with sudo:
                return _execute(run_cmd, cmd_arguments)
        elif user and user != getpass.getuser():
            raise NotImplementedError  # TODO
        else:
            return _execute(run_cmd, cmd_arguments)

    def _release(self, commands, errors=None):
        for conf in commands:
            if self.settings.print_commands or config.debug("package_release"):
                from subprocess import list2cmdline
                toks = [conf["command"]] + conf.get("args", [])
                msg = "running command: %s" % list2cmdline(toks)
                if self.settings.print_commands:
                    print msg
                else:
                    print_debug(msg)

            if not self.execute_command(cmd_name=conf.get("command"),
                                        cmd_arguments=conf.get("args"),
                                        user=conf.get("user"),
                                        errors=errors):
                if self.settings.stop_on_error:
                    return

    def pre_build(self, user, install_path, **kwargs):
        errors = []
        self._release(self.settings.pre_build_commands, errors=errors)
        if errors and self.settings.cancel_on_error:
            raise ReleaseHookCancellingError(
                "The following pre-build commands failed:\n%s" %
                '\n\n'.join(errors))

    def pre_release(self, user, install_path, **kwargs):
        errors = []
        self._release(self.settings.pre_release_commands, errors=errors)
        if errors and self.settings.cancel_on_error:
            raise ReleaseHookCancellingError(
                "The following pre-release commands failed:\n%s" %
                '\n\n'.join(errors))

    def post_release(self, user, install_path, variants, **kwargs):
        self._release(self.settings.post_release_commands)
示例#12
0
文件: command.py 项目: shiyi9/rez
class CommandReleaseHook(ReleaseHook):

    commands_schema = Schema({
        "command":
        basestring,
        Optional("args"):
        Or(And(basestring, Use(lambda x: x.strip().split())), [basestring]),
        Optional("pretty_args"):
        bool,
        Optional("user"):
        basestring,
        Optional("env"):
        dict
    })

    schema_dict = {
        "print_commands": bool,
        "print_output": bool,
        "print_error": bool,
        "cancel_on_error": bool,
        "stop_on_error": bool,
        "pre_build_commands": [commands_schema],
        "pre_release_commands": [commands_schema],
        "post_release_commands": [commands_schema]
    }

    @classmethod
    def name(cls):
        return "command"

    def __init__(self, source_path):
        super(CommandReleaseHook, self).__init__(source_path)

    def execute_command(self, cmd_name, cmd_arguments, user, errors, env=None):
        def _err(msg):
            errors.append(msg)
            if self.settings.print_error:
                print(msg, file=sys.stderr)

        kwargs = {}
        if env:
            kwargs["env"] = env

        def _execute(commands):
            process = Popen(commands, stdout=PIPE, stderr=STDOUT, **kwargs)
            stdout, _ = process.communicate()

            if process.returncode != 0:
                msg = "command failed:\n%s" % stdout
                _err(msg)
                return False
            if self.settings.print_output:
                print(stdout.strip())
            return True

        if not os.path.isfile(cmd_name):
            cmd_full_path = which(cmd_name)
        else:
            cmd_full_path = cmd_name
        if not cmd_full_path:
            msg = "%s: command not found" % cmd_name
            _err(msg)
            return False

        cmds = [cmd_full_path] + (cmd_arguments or [])
        if user == 'root':
            cmds = ['sudo'] + cmds
            return _execute(cmds)
        elif user and user != getpass.getuser():
            raise NotImplementedError  # TODO
        else:
            return _execute(cmds)

    def pre_build(self, user, install_path, variants=None, **kwargs):
        errors = []
        self._execute_commands(self.settings.pre_build_commands,
                               install_path=install_path,
                               package=self.package,
                               errors=errors,
                               variants=variants)

        if errors and self.settings.cancel_on_error:
            raise ReleaseHookCancellingError(
                "The following pre-build commands failed:\n%s" %
                '\n\n'.join(errors))

    def pre_release(self, user, install_path, variants=None, **kwargs):
        errors = []
        self._execute_commands(self.settings.pre_release_commands,
                               install_path=install_path,
                               package=self.package,
                               errors=errors,
                               variants=variants)

        if errors and self.settings.cancel_on_error:
            raise ReleaseHookCancellingError(
                "The following pre-release commands failed:\n%s" %
                '\n\n'.join(errors))

    def post_release(self, user, install_path, variants, **kwargs):
        # note that the package we use here is the *installed* package, not the
        # developer package (self.package). Otherwise, attributes such as 'root'
        # will be None
        errors = []
        if variants:
            package = variants[0].parent
        else:
            package = self.package

        self._execute_commands(self.settings.post_release_commands,
                               install_path=install_path,
                               package=package,
                               errors=errors,
                               variants=variants)
        if errors:
            print_debug("The following post-release commands failed:\n" +
                        '\n\n'.join(errors))

    def _execute_commands(self,
                          commands,
                          install_path,
                          package,
                          errors=None,
                          variants=None):
        release_dict = dict(path=install_path)
        variant_infos = []
        if variants:
            for variant in variants:
                if isinstance(variant, (int, long)):
                    variant_infos.append(variant)
                else:
                    package = variant.parent
                    var_dict = dict(variant.resource.variables)
                    # using '%s' will preserve potential str/unicode nature
                    var_dict['variant_requires'] = [
                        '%s' % x for x in variant.resource.variant_requires
                    ]
                    variant_infos.append(var_dict)
        formatter = scoped_formatter(system=system,
                                     release=release_dict,
                                     package=package,
                                     variants=variant_infos,
                                     num_variants=len(variant_infos))

        for conf in commands:
            program = conf["command"]

            env_ = None
            env = conf.get("env")
            if env:
                env_ = os.environ.copy()
                env_.update(env)

            # If we have, ie, a list, and format_pretty is True, it will be printed
            # as "1 2 3" instead of "[1, 2, 3]"
            formatter.__dict__['format_pretty'] = conf.get("pretty_args", True)

            args = conf.get("args", [])
            args = [formatter.format(x) for x in args]
            args = [expandvars(x, environ=env_) for x in args]

            if self.settings.print_commands or config.debug("package_release"):
                from subprocess import list2cmdline
                toks = [program] + args

                msgs = []
                msgs.append("running command: %s" % list2cmdline(toks))
                if env:
                    for key, value in env.iteritems():
                        msgs.append("    with: %s=%s" % (key, value))

                if self.settings.print_commands:
                    print('\n'.join(msgs))
                else:
                    for msg in msgs:
                        print_debug(msg)

            if not self.execute_command(cmd_name=program,
                                        cmd_arguments=args,
                                        user=conf.get("user"),
                                        errors=errors,
                                        env=env_):
                if self.settings.stop_on_error:
                    return
示例#13
0
from rez.vendor.schema.schema import Schema, Optional, Or, Use, And
from rez.vendor.six import six
from rez.vendor.version.version import Version
from contextlib import contextmanager
import os

basestring = six.string_types[0]

# this schema will automatically harden request strings like 'python-*'; see
# the 'expand_requires' function for more info.
#
package_request_schema = Or(And(basestring, Use(expand_requirement)),
                            And(PackageRequest, Use(str)))

tests_schema = Schema({
    Optional(basestring):
    Or(
        Or(basestring, [basestring]),
        extensible_schema_dict({
            "command":
            Or(basestring, [basestring]),
            Optional("requires"): [package_request_schema],
            Optional("run_on"):
            Or(basestring, [basestring]),
            Optional("on_variants"):
            Or(bool, {
                "type": "requires",
                "value": [package_request_schema]
            })
        }))
})
示例#14
0
    'release_message',
    'changelog',
    'vcs',
    'revision',
    'previous_version',
    'previous_revision']


version_schema = Or(basestring, And(Version, Use(str)))

package_request_schema = Or(basestring, And(PackageRequest, Use(str)))

source_code_schema = Or(SourceCode, And(basestring, Use(SourceCode)))

tests_schema = Schema({
    Optional(basestring): Or(
        Or(basestring, [basestring]),
        extensible_schema_dict({
            "command": Or(basestring, [basestring]),
            Optional("requires"): [package_request_schema],
            Optional("run_on"): Or(basestring, [basestring]),
            Optional("on_variants"): Or(
                bool,
                {
                    "type": "requires",
                    "value": [package_request_schema]
                }
            )
        })
    )
})
示例#15
0
base_resource_schema_dict = {
    Required("name"):                   basestring
}


# package family
#

package_family_schema_dict = base_resource_schema_dict.copy()


# schema common to both package and variant
#

tests_schema = Schema({
    Optional(basestring): Or(
        Or(basestring, [basestring]),
        {
            "command": Or(basestring, [basestring]),
            Optional("requires"): [
                Or(PackageRequest, And(basestring, Use(PackageRequest)))
            ]
        }
    )
})

package_base_schema_dict = base_resource_schema_dict.copy()
package_base_schema_dict.update({
    # basics
    Optional("base"):                   basestring,
    Optional("version"):                Version,
示例#16
0
    'variants', 'commands', 'pre_commands', 'post_commands', 'help', 'config',
    'uuid', 'timestamp', 'release_message', 'changelog', 'vcs', 'revision',
    'previous_version', 'previous_revision'
]

version_schema = Or(basestring, And(Version, Use(str)))

package_request_schema = Or(basestring, And(PackageRequest, Use(str)))

source_code_schema = Or(SourceCode, And(basestring, Use(SourceCode)))

# package serialisation schema
package_serialise_schema = Schema({
    Required("name"):
    basestring,
    Optional("version"):
    version_schema,
    Optional("description"):
    basestring,
    Optional("authors"): [basestring],
    Optional("tools"): [basestring],
    Optional('requires'): [package_request_schema],
    Optional('build_requires'): [package_request_schema],
    Optional('private_build_requires'): [package_request_schema],
    Optional('variants'): [[package_request_schema]],
    Optional('pre_commands'):
    source_code_schema,
    Optional('commands'):
    source_code_schema,
    Optional('post_commands'):
    source_code_schema,
示例#17
0
class CommandReleaseHook(ReleaseHook):

    commands_schema = Schema({
        "command":
        basestring,
        Optional("args"):
        Or(And(basestring, Use(lambda x: x.strip().split())), [basestring]),
        Optional("user"):
        basestring,
        Optional("env"):
        dict
    })

    schema_dict = {
        "print_commands": bool,
        "print_output": bool,
        "print_error": bool,
        "cancel_on_error": bool,
        "stop_on_error": bool,
        "pre_build_commands": [commands_schema],
        "pre_release_commands": [commands_schema],
        "post_release_commands": [commands_schema]
    }

    @classmethod
    def name(cls):
        return "command"

    def __init__(self, source_path):
        super(CommandReleaseHook, self).__init__(source_path)

    def execute_command(self, cmd_name, cmd_arguments, user, errors, env=None):
        def _err(msg):
            errors.append(msg)
            if self.settings.print_error:
                print >> sys.stderr, msg

        kwargs = {}
        if env:
            kwargs["_env"] = env

        def _execute(cmd, arguments):
            try:
                result = cmd(*(arguments or []), **kwargs)
                if self.settings.print_output:
                    print result.stdout.strip()
            except ErrorReturnCode as e:
                # `e` shows the command that was run
                msg = "command failed:\n%s" % str(e)
                _err(msg)
                return False
            return True

        if not os.path.isfile(cmd_name):
            cmd_full_path = which(cmd_name)
        else:
            cmd_full_path = cmd_name
        if not cmd_full_path:
            msg = "%s: command not found" % cmd_name
            _err(msg)
            return False

        run_cmd = Command(cmd_full_path)
        if user == 'root':
            with sudo:
                return _execute(run_cmd, cmd_arguments)
        elif user and user != getpass.getuser():
            raise NotImplementedError  # TODO
        else:
            return _execute(run_cmd, cmd_arguments)

    def pre_build(self, user, install_path, **kwargs):
        errors = []
        self._execute_commands(self.settings.pre_build_commands,
                               install_path=install_path,
                               package=self.package,
                               errors=errors)

        if errors and self.settings.cancel_on_error:
            raise ReleaseHookCancellingError(
                "The following pre-build commands failed:\n%s" %
                '\n\n'.join(errors))

    def pre_release(self, user, install_path, **kwargs):
        errors = []
        self._execute_commands(self.settings.pre_release_commands,
                               install_path=install_path,
                               package=self.package,
                               errors=errors)

        if errors and self.settings.cancel_on_error:
            raise ReleaseHookCancellingError(
                "The following pre-release commands failed:\n%s" %
                '\n\n'.join(errors))

    def post_release(self, user, install_path, variants, **kwargs):
        # note that the package we use here is the *installed* package, not the
        # developer package (self.package). Otherwise, attributes such as 'root'
        # will be None
        errors = []
        if variants:
            package = variants[0].parent
        else:
            package = self.package

        self._execute_commands(self.settings.post_release_commands,
                               install_path=install_path,
                               package=package,
                               errors=errors)
        if errors:
            print_debug("The following post-release commands failed:\n" +
                        '\n\n'.join(errors))

    def _execute_commands(self, commands, install_path, package, errors=None):
        release_dict = dict(path=install_path)
        formatter = scoped_formatter(system=system,
                                     release=release_dict,
                                     package=package)

        for conf in commands:
            program = conf["command"]

            env_ = None
            env = conf.get("env")
            if env:
                env_ = os.environ.copy()
                env_.update(env)

            args = conf.get("args", [])
            args = [formatter.format(x) for x in args]
            args = [expandvars(x, environ=env_) for x in args]

            if self.settings.print_commands or config.debug("package_release"):
                from subprocess import list2cmdline
                toks = [program] + args

                msgs = []
                msgs.append("running command: %s" % list2cmdline(toks))
                if env:
                    for key, value in env.iteritems():
                        msgs.append("    with: %s=%s" % (key, value))

                if self.settings.print_commands:
                    print '\n'.join(msgs)
                else:
                    for msg in msgs:
                        print_debug(msg)

            if not self.execute_command(cmd_name=program,
                                        cmd_arguments=args,
                                        user=conf.get("user"),
                                        errors=errors,
                                        env=env_):
                if self.settings.stop_on_error:
                    return
示例#18
0
from rez.packages_ import Package
from rez.package_py_utils import expand_requirement
from rez.vendor.schema.schema import Schema, Optional, Or, Use, And
from rez.vendor.version.version import Version
from contextlib import contextmanager
import os


# this schema will automatically harden request strings like 'python-*'; see
# the 'expand_requires' function for more info.
#
package_request_schema = Or(And(basestring, Use(expand_requirement)),
                            And(PackageRequest, Use(str)))

tests_schema = Schema({
    Optional(basestring): Or(
        Or(basestring, [basestring]),
        {
            "command": Or(basestring, [basestring]),
            Optional("requires"): [package_request_schema]
        }
    )
})


package_schema = Schema({
    Optional("requires_rez_version"):   And(basestring, Use(Version)),

    Required("name"):                   basestring,
    Optional("base"):                   basestring,
    Optional("version"):                Or(basestring,
示例#19
0
from rez.utils.formatting import PackageRequest
from rez.utils.data_utils import AttrDictWrapper
from rez.package_resources_ import help_schema, _commands_schema
from rez.package_repository import create_memory_package_repository
from rez.packages_ import Package
from rez.vendor.schema.schema import Schema, Optional, Or, Use, And
from rez.vendor.version.version import Version
from contextlib import contextmanager
import os

package_request_schema = Or(basestring, And(PackageRequest, Use(str)))

package_schema = Schema({
    Required("name"):
    basestring,
    Optional("nice_name"):
    basestring,
    Optional("base"):
    basestring,
    Optional("version"):
    Or(basestring, And(Version, Use(str))),
    Optional('description'):
    basestring,
    Optional('authors'): [basestring],
    Optional('requires'): [package_request_schema],
    Optional('build_requires'): [package_request_schema],
    Optional('private_build_requires'): [package_request_schema],
    Optional('variants'): [[package_request_schema]],
    Optional('has_plugins'):
    bool,
    Optional('plugin_for'): [basestring],