class Paludis::Environment

Represents a working environment, which contains an available packages database and provides various methods for querying package visibility and options.

Public Instance Methods

[](Selection) → Array of PackageID click to toggle source

Fetch PackageID instances using the supplied Selection.

VALUE
    environment_square_brackets(VALUE self, VALUE selection)
    {
        try
        {
            std::shared_ptr<const PackageIDSequence> ids(value_to_environment(self)->operator[] (value_to_selection(selection)));
            VALUE result(rb_ary_new());
            for (PackageIDSequence::ConstIterator i(ids->begin()), i_end(ids->end()) ;
                    i != i_end ; ++i)
                rb_ary_push(result, package_id_to_value(*i));
            return result;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     set(set_name) -> DepSpec
     *
     * Fetch a named package set as a DepSpec.
     */
    VALUE
    environment_set(VALUE self, VALUE set_name)
    {
        try
        {
            SetName s(StringValuePtr(set_name));
            std::shared_ptr<const SetSpecTree> set = (value_to_environment(self)->set(s));
            if (set)
                return dep_tree_to_value<SetSpecTree>(set);
            else
                return Qnil;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     accept_license(license, package_id) -> true or false
     *
     * Do we accept a particular license for a particular package?
     */

    VALUE
    environment_accept_license(VALUE self, VALUE license, VALUE p)
    {
        try
        {
            return value_to_environment(self)->accept_license(
                    std::string(StringValuePtr(license)), (value_to_package_id(p))) ? Qtrue : Qfalse;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     accept_keywords(keywords, package_id) -> true or false
     *
     * Do we accept any of the specified keywords for a particular package?
     */

    VALUE
    environment_accept_keywords(VALUE self, VALUE keywords, VALUE p)
    {
        if (rb_obj_is_kind_of(keywords, rb_cArray))
        {
            try
            {
                std::shared_ptr<KeywordNameSet> knc (std::make_shared<KeywordNameSet>());
                long len = NUM2LONG(rb_funcall(keywords,rb_intern("length"),0));
                for (long i = 0; i < len; i++)
                {
                    // Stupid macros won't let me do it on one line.
                    VALUE kw = rb_ary_entry(keywords, i);
                    knc->insert(KeywordName(StringValuePtr(kw)));
                }
                return value_to_environment(self)->accept_keywords(knc, value_to_package_id(p)) ? Qtrue : Qfalse;
            }
            catch (const std::exception & e)
            {
                exception_to_ruby_exception(e);
            }
        }
        else
        {
            rb_raise(rb_eTypeError, "Can't convert %s into Array", rb_obj_classname(keywords));
        }
    }

    /*
     * call-seq:
     *     mirrors(mirror_name) -> Array
     *
     * Return the mirror URI prefixes for a named mirror.
     */
    VALUE
    environment_mirrors(VALUE self, VALUE mirror)
    {
        try
        {
            VALUE result(rb_ary_new());
            std::shared_ptr<const MirrorsSequence> m(value_to_environment(self)->mirrors(StringValuePtr(mirror)));
            for (MirrorsSequence::ConstIterator i(m->begin()), i_end(m->end()) ; i != i_end ; i++)
                rb_ary_push(result, rb_str_new2(stringify(*i).c_str()));
            return result;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    VALUE
    environment_distribution(VALUE self)
    {
        return rb_str_new2(value_to_environment(self)->distribution().c_str());

    }

    template <typename T_, const std::shared_ptr<const T_> (Environment::* m_) () const>
    struct EnvironmentKey
    {
        static VALUE
        fetch(VALUE self)
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);
            return (((**self_ptr).*m_)()) ? metadata_key_to_value(((**self_ptr).*m_)()) : Qnil;
        }
    };

    std::shared_ptr<PaludisEnvironment>
    value_to_paludis_environment(VALUE v)
    {
        if (rb_obj_is_kind_of(v, c_paludis_environment))
        {
            std::shared_ptr<Environment> * v_ptr;
            Data_Get_Struct(v, std::shared_ptr<Environment>, v_ptr);
            return std::static_pointer_cast<PaludisEnvironment>(*v_ptr);
        }
        else
        {
            rb_raise(rb_eTypeError, "Can't convert %s into PaludisEnvironment", rb_obj_classname(v));
        }
    }

    VALUE
    paludis_environment_init(int, VALUE*, VALUE self)
    {
        return self;
    }

    /*
     * call-seq:
     *     PaludisEnvironment.new -> PaludisEnvironment
     *     PaludisEnvironment.new(config_suffix) -> PaludisEnvironment
     *
     * Create a new PaludisEnvironment, with the specified config suffix if any, otherwise the empty suffix.
     */
    VALUE
    paludis_environment_new(int argc, VALUE* argv, VALUE self)
    {
        try
        {
            std::string config_suffix;
            if (1 == argc)
                config_suffix = StringValuePtr(argv[0]);
            else if (0 != argc)
                rb_raise(rb_eArgError, "PaludisEnvironment.new expects one or zero arguments, but got %d", argc);

            std::shared_ptr<Environment> * e = new std::shared_ptr<Environment>(std::make_shared<PaludisEnvironment>(config_suffix));
            VALUE tdata(Data_Wrap_Struct(self, 0, &Common<std::shared_ptr<Environment> >::free, e));
            rb_obj_call_init(tdata, argc, argv);
            return tdata;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     TestEnvironment.new -> TestEnvironment
     *
     * Create a new TestEnvironment.
     */
    VALUE
    test_environment_new(VALUE self)
    {
        try
        {
            std::shared_ptr<Environment> * e = new std::shared_ptr<Environment>(std::make_shared<TestEnvironment>());
            VALUE tdata(Data_Wrap_Struct(self, 0, &Common<std::shared_ptr<Environment> >::free, e));
            rb_obj_call_init(tdata, 0, &self);
            return tdata;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     config_dir -> String
     *
     * Configuration directory used by this PaludisEnvironment.
     */
    VALUE
    paludis_environment_config_dir(VALUE self)
    {
        return rb_str_new2(value_to_paludis_environment(self)->config_dir().c_str());
    }

    /*
     * call-seq:
     *     create(spec) -> Environment
     *
     * Create an environment from the given spec.
     * A spec consisits of <b>class:suffix</b> both of which may be omitted. <b>class</b> is the environment class,
     * e.g. paludis or portage, <b>suffix</b> is the configuration directory suffix.
     *
     */
    VALUE
    environment_factory_create(VALUE, VALUE spec)
    {
        try
        {
            std::shared_ptr<Environment> * e = new std::shared_ptr<Environment>(EnvironmentFactory::get_instance()->create(
                        StringValuePtr(spec)));

            VALUE tdata(Data_Wrap_Struct(c_environment, 0, &Common<std::shared_ptr<Environment> >::free, e));
            return tdata;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     fetch_unique_qualified_package_name(package_name) -> QualifiedPackageName
     *     fetch_unique_qualified_package_name(package_name, filter) -> QualifiedPackageName
     *
     * Disambiguate a package name.  If a filter is specified, limit
     * the potential results to packages that match.
     */
    VALUE
    environment_fetch_unique_qualified_package_name(int argc, VALUE *argv, VALUE self)
    {
        try
        {
            if (1 == argc || 2 == argc)
            {
                std::shared_ptr<Environment> * self_ptr;
                Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);
                return qualified_package_name_to_value((*self_ptr)->fetch_unique_qualified_package_name(
                                PackageNamePart(StringValuePtr(argv[0])), 2 == argc ? value_to_filter(argv[1]) : filter::All()));
            }
            else
                rb_raise(rb_eArgError, "fetch_unique_qualified_package_name expects one or two arguments, but got %d",argc);
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     repositories -> Array
     *     repositories {|repository| block } -> Nil
     *
     *  Returns all the repositories in the package database, either as an Array, or as
     *  the parameters to a block.
     */
    VALUE
    environment_repositories(VALUE self)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            if (rb_block_given_p())
            {
                for (Environment::RepositoryConstIterator r((*self_ptr)->begin_repositories()),
                        r_end((*self_ptr)->end_repositories()) ; r != r_end ; ++r)
                    rb_yield(repository_to_value(*r));
                return Qnil;
            }
            VALUE result(rb_ary_new());
            for (Environment::RepositoryConstIterator r((*self_ptr)->begin_repositories()),
                    r_end((*self_ptr)->end_repositories()) ; r != r_end ; ++r)
                rb_ary_push(result, repository_to_value(*r));

            return result;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     fetch_repository(repository_name) -> Repository
     *
     *  Fetch a named repository.
     */
    VALUE
    environment_fetch_repository(VALUE self, VALUE name)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return repository_to_value((*self_ptr)->fetch_repository(RepositoryName(StringValuePtr(name))));
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     more_important_than(repository_name_a, repository_name_b) -> bool
     *
     * True if repository_name_a is more important than repository_name_b .
     */
    VALUE
    environment_more_important_than(VALUE self, VALUE name1, VALUE name2)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return (*self_ptr)->more_important_than(RepositoryName(StringValuePtr(name1)),
                    RepositoryName(StringValuePtr(name2))) ? Qtrue : Qfalse;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     has_repository_named?(repository_name) -> true or false
     *
     *  Do we have a named repository?
     */
    VALUE
    environment_has_repository_named(VALUE self, VALUE name)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return ((*self_ptr)->has_repository_named(RepositoryName(StringValuePtr(name)))) ? true : false;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     add_repository(importance, repository) -> nil
     *
     *  Add a repository.
     */
    VALUE
    environment_add_repository(VALUE self, VALUE importance, VALUE repo_v)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            std::shared_ptr<Repository> repo(value_to_repository(repo_v));

            (*self_ptr)->add_repository(NUM2INT(importance), repo);
            return Qnil;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }


    void do_register_environment()
    {
        rb_require("singleton");

        /*
         * Document-class: Paludis::Environment
         *
         * Represents a working environment, which contains an available packages database and provides
         * various methods for querying package visibility and options.
         */
        c_environment = rb_define_class_under(c_paludis_module, "Environment", rb_cObject);
        rb_funcall(c_environment, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        rb_define_method(c_environment, "set", environment_set, 1);
        rb_define_method(c_environment, "distribution", environment_distribution, 0);
        rb_define_method(c_environment, "accept_license", environment_accept_license, 2);
        rb_define_method(c_environment, "accept_keywords", environment_accept_keywords, 2);
        rb_define_method(c_environment, "mirrors", environment_mirrors, 1);
        rb_define_method(c_environment, "[]", environment_square_brackets, 1);
        rb_define_method(c_environment, "format_key",                EnvironmentKey<MetadataValueKey<std::string> , Environment::format_key>::fetch, 0);
        rb_define_method(c_environment, "config_location_key",                template_methods, 0);
        rb_define_method(c_environment, "preferred_root_key",                template_methods, 0);
        rb_define_method(c_environment, "fetch_unique_qualified_package_name",                environment_fetch_unique_qualified_package_name, -1);
        rb_define_method(c_environment, "repositories",                environment_repositories, 0);
        rb_define_method(c_environment, "fetch_repository",                environment_fetch_repository, 1);
        rb_define_method(c_environment, "more_important_than",                environment_more_important_than, 2);
        rb_define_method(c_environment, "has_repository_named?",                environment_has_repository_named, 1);
        rb_define_method(c_environment, "add_repository",                environment_add_repository, 2);

        /*
         * Document-class: Paludis::PaludisEnvironment
         *
         * An Environment that corresponds to the normal operating evironment.
         */
        c_paludis_environment = rb_define_class_under(c_paludis_module, "PaludisEnvironment", c_environment);
        rb_define_singleton_method(c_paludis_environment, "new", paludis_environment_new, -1);
        rb_define_method(c_paludis_environment, "initialize", paludis_environment_init, -1);
        rb_define_method(c_paludis_environment, "config_dir", paludis_environment_config_dir, 0);

        /*
         * Document-class: Paludis::TestEnvironment
         *
         * A crude test environment.
         */
        c_test_environment = rb_define_class_under(c_paludis_module, "TestEnvironment", c_environment);
        rb_define_singleton_method(c_test_environment, "new", test_environment_new, 0);

        /*
         * Document-class: Paludis::EnvironmentFactory
         *
         * A class that holds methods to create environments.
         *
         * To access the default environment use create("")
         */
        c_environment_factory = rb_define_class_under(c_paludis_module, "EnvironmentFactory", rb_cObject);
        rb_funcall(rb_const_get(rb_cObject, rb_intern("Singleton")), rb_intern("included"), 1, c_environment_factory);
        rb_define_method(c_environment_factory, "create", environment_factory_create, 1);
    }
}
accept_keywords(keywords, package_id) → true or false click to toggle source

Do we accept any of the specified keywords for a particular package?

VALUE
    environment_accept_keywords(VALUE self, VALUE keywords, VALUE p)
    {
        if (rb_obj_is_kind_of(keywords, rb_cArray))
        {
            try
            {
                std::shared_ptr<KeywordNameSet> knc (std::make_shared<KeywordNameSet>());
                long len = NUM2LONG(rb_funcall(keywords,rb_intern("length"),0));
                for (long i = 0; i < len; i++)
                {
                    // Stupid macros won't let me do it on one line.
                    VALUE kw = rb_ary_entry(keywords, i);
                    knc->insert(KeywordName(StringValuePtr(kw)));
                }
                return value_to_environment(self)->accept_keywords(knc, value_to_package_id(p)) ? Qtrue : Qfalse;
            }
            catch (const std::exception & e)
            {
                exception_to_ruby_exception(e);
            }
        }
        else
        {
            rb_raise(rb_eTypeError, "Can't convert %s into Array", rb_obj_classname(keywords));
        }
    }

    /*
     * call-seq:
     *     mirrors(mirror_name) -> Array
     *
     * Return the mirror URI prefixes for a named mirror.
     */
    VALUE
    environment_mirrors(VALUE self, VALUE mirror)
    {
        try
        {
            VALUE result(rb_ary_new());
            std::shared_ptr<const MirrorsSequence> m(value_to_environment(self)->mirrors(StringValuePtr(mirror)));
            for (MirrorsSequence::ConstIterator i(m->begin()), i_end(m->end()) ; i != i_end ; i++)
                rb_ary_push(result, rb_str_new2(stringify(*i).c_str()));
            return result;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    VALUE
    environment_distribution(VALUE self)
    {
        return rb_str_new2(value_to_environment(self)->distribution().c_str());

    }

    template <typename T_, const std::shared_ptr<const T_> (Environment::* m_) () const>
    struct EnvironmentKey
    {
        static VALUE
        fetch(VALUE self)
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);
            return (((**self_ptr).*m_)()) ? metadata_key_to_value(((**self_ptr).*m_)()) : Qnil;
        }
    };

    std::shared_ptr<PaludisEnvironment>
    value_to_paludis_environment(VALUE v)
    {
        if (rb_obj_is_kind_of(v, c_paludis_environment))
        {
            std::shared_ptr<Environment> * v_ptr;
            Data_Get_Struct(v, std::shared_ptr<Environment>, v_ptr);
            return std::static_pointer_cast<PaludisEnvironment>(*v_ptr);
        }
        else
        {
            rb_raise(rb_eTypeError, "Can't convert %s into PaludisEnvironment", rb_obj_classname(v));
        }
    }

    VALUE
    paludis_environment_init(int, VALUE*, VALUE self)
    {
        return self;
    }

    /*
     * call-seq:
     *     PaludisEnvironment.new -> PaludisEnvironment
     *     PaludisEnvironment.new(config_suffix) -> PaludisEnvironment
     *
     * Create a new PaludisEnvironment, with the specified config suffix if any, otherwise the empty suffix.
     */
    VALUE
    paludis_environment_new(int argc, VALUE* argv, VALUE self)
    {
        try
        {
            std::string config_suffix;
            if (1 == argc)
                config_suffix = StringValuePtr(argv[0]);
            else if (0 != argc)
                rb_raise(rb_eArgError, "PaludisEnvironment.new expects one or zero arguments, but got %d", argc);

            std::shared_ptr<Environment> * e = new std::shared_ptr<Environment>(std::make_shared<PaludisEnvironment>(config_suffix));
            VALUE tdata(Data_Wrap_Struct(self, 0, &Common<std::shared_ptr<Environment> >::free, e));
            rb_obj_call_init(tdata, argc, argv);
            return tdata;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     TestEnvironment.new -> TestEnvironment
     *
     * Create a new TestEnvironment.
     */
    VALUE
    test_environment_new(VALUE self)
    {
        try
        {
            std::shared_ptr<Environment> * e = new std::shared_ptr<Environment>(std::make_shared<TestEnvironment>());
            VALUE tdata(Data_Wrap_Struct(self, 0, &Common<std::shared_ptr<Environment> >::free, e));
            rb_obj_call_init(tdata, 0, &self);
            return tdata;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     config_dir -> String
     *
     * Configuration directory used by this PaludisEnvironment.
     */
    VALUE
    paludis_environment_config_dir(VALUE self)
    {
        return rb_str_new2(value_to_paludis_environment(self)->config_dir().c_str());
    }

    /*
     * call-seq:
     *     create(spec) -> Environment
     *
     * Create an environment from the given spec.
     * A spec consisits of <b>class:suffix</b> both of which may be omitted. <b>class</b> is the environment class,
     * e.g. paludis or portage, <b>suffix</b> is the configuration directory suffix.
     *
     */
    VALUE
    environment_factory_create(VALUE, VALUE spec)
    {
        try
        {
            std::shared_ptr<Environment> * e = new std::shared_ptr<Environment>(EnvironmentFactory::get_instance()->create(
                        StringValuePtr(spec)));

            VALUE tdata(Data_Wrap_Struct(c_environment, 0, &Common<std::shared_ptr<Environment> >::free, e));
            return tdata;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     fetch_unique_qualified_package_name(package_name) -> QualifiedPackageName
     *     fetch_unique_qualified_package_name(package_name, filter) -> QualifiedPackageName
     *
     * Disambiguate a package name.  If a filter is specified, limit
     * the potential results to packages that match.
     */
    VALUE
    environment_fetch_unique_qualified_package_name(int argc, VALUE *argv, VALUE self)
    {
        try
        {
            if (1 == argc || 2 == argc)
            {
                std::shared_ptr<Environment> * self_ptr;
                Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);
                return qualified_package_name_to_value((*self_ptr)->fetch_unique_qualified_package_name(
                                PackageNamePart(StringValuePtr(argv[0])), 2 == argc ? value_to_filter(argv[1]) : filter::All()));
            }
            else
                rb_raise(rb_eArgError, "fetch_unique_qualified_package_name expects one or two arguments, but got %d",argc);
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     repositories -> Array
     *     repositories {|repository| block } -> Nil
     *
     *  Returns all the repositories in the package database, either as an Array, or as
     *  the parameters to a block.
     */
    VALUE
    environment_repositories(VALUE self)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            if (rb_block_given_p())
            {
                for (Environment::RepositoryConstIterator r((*self_ptr)->begin_repositories()),
                        r_end((*self_ptr)->end_repositories()) ; r != r_end ; ++r)
                    rb_yield(repository_to_value(*r));
                return Qnil;
            }
            VALUE result(rb_ary_new());
            for (Environment::RepositoryConstIterator r((*self_ptr)->begin_repositories()),
                    r_end((*self_ptr)->end_repositories()) ; r != r_end ; ++r)
                rb_ary_push(result, repository_to_value(*r));

            return result;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     fetch_repository(repository_name) -> Repository
     *
     *  Fetch a named repository.
     */
    VALUE
    environment_fetch_repository(VALUE self, VALUE name)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return repository_to_value((*self_ptr)->fetch_repository(RepositoryName(StringValuePtr(name))));
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     more_important_than(repository_name_a, repository_name_b) -> bool
     *
     * True if repository_name_a is more important than repository_name_b .
     */
    VALUE
    environment_more_important_than(VALUE self, VALUE name1, VALUE name2)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return (*self_ptr)->more_important_than(RepositoryName(StringValuePtr(name1)),
                    RepositoryName(StringValuePtr(name2))) ? Qtrue : Qfalse;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     has_repository_named?(repository_name) -> true or false
     *
     *  Do we have a named repository?
     */
    VALUE
    environment_has_repository_named(VALUE self, VALUE name)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return ((*self_ptr)->has_repository_named(RepositoryName(StringValuePtr(name)))) ? true : false;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     add_repository(importance, repository) -> nil
     *
     *  Add a repository.
     */
    VALUE
    environment_add_repository(VALUE self, VALUE importance, VALUE repo_v)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            std::shared_ptr<Repository> repo(value_to_repository(repo_v));

            (*self_ptr)->add_repository(NUM2INT(importance), repo);
            return Qnil;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }


    void do_register_environment()
    {
        rb_require("singleton");

        /*
         * Document-class: Paludis::Environment
         *
         * Represents a working environment, which contains an available packages database and provides
         * various methods for querying package visibility and options.
         */
        c_environment = rb_define_class_under(c_paludis_module, "Environment", rb_cObject);
        rb_funcall(c_environment, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        rb_define_method(c_environment, "set", environment_set, 1);
        rb_define_method(c_environment, "distribution", environment_distribution, 0);
        rb_define_method(c_environment, "accept_license", environment_accept_license, 2);
        rb_define_method(c_environment, "accept_keywords", environment_accept_keywords, 2);
        rb_define_method(c_environment, "mirrors", environment_mirrors, 1);
        rb_define_method(c_environment, "[]", environment_square_brackets, 1);
        rb_define_method(c_environment, "format_key",                EnvironmentKey<MetadataValueKey<std::string> , Environment::format_key>::fetch, 0);
        rb_define_method(c_environment, "config_location_key",                template_methods, 0);
        rb_define_method(c_environment, "preferred_root_key",                template_methods, 0);
        rb_define_method(c_environment, "fetch_unique_qualified_package_name",                environment_fetch_unique_qualified_package_name, -1);
        rb_define_method(c_environment, "repositories",                environment_repositories, 0);
        rb_define_method(c_environment, "fetch_repository",                environment_fetch_repository, 1);
        rb_define_method(c_environment, "more_important_than",                environment_more_important_than, 2);
        rb_define_method(c_environment, "has_repository_named?",                environment_has_repository_named, 1);
        rb_define_method(c_environment, "add_repository",                environment_add_repository, 2);

        /*
         * Document-class: Paludis::PaludisEnvironment
         *
         * An Environment that corresponds to the normal operating evironment.
         */
        c_paludis_environment = rb_define_class_under(c_paludis_module, "PaludisEnvironment", c_environment);
        rb_define_singleton_method(c_paludis_environment, "new", paludis_environment_new, -1);
        rb_define_method(c_paludis_environment, "initialize", paludis_environment_init, -1);
        rb_define_method(c_paludis_environment, "config_dir", paludis_environment_config_dir, 0);

        /*
         * Document-class: Paludis::TestEnvironment
         *
         * A crude test environment.
         */
        c_test_environment = rb_define_class_under(c_paludis_module, "TestEnvironment", c_environment);
        rb_define_singleton_method(c_test_environment, "new", test_environment_new, 0);

        /*
         * Document-class: Paludis::EnvironmentFactory
         *
         * A class that holds methods to create environments.
         *
         * To access the default environment use create("")
         */
        c_environment_factory = rb_define_class_under(c_paludis_module, "EnvironmentFactory", rb_cObject);
        rb_funcall(rb_const_get(rb_cObject, rb_intern("Singleton")), rb_intern("included"), 1, c_environment_factory);
        rb_define_method(c_environment_factory, "create", environment_factory_create, 1);
    }
}
accept_license(license, package_id) → true or false click to toggle source

Do we accept a particular license for a particular package?

VALUE
    environment_accept_license(VALUE self, VALUE license, VALUE p)
    {
        try
        {
            return value_to_environment(self)->accept_license(
                    std::string(StringValuePtr(license)), (value_to_package_id(p))) ? Qtrue : Qfalse;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     accept_keywords(keywords, package_id) -> true or false
     *
     * Do we accept any of the specified keywords for a particular package?
     */

    VALUE
    environment_accept_keywords(VALUE self, VALUE keywords, VALUE p)
    {
        if (rb_obj_is_kind_of(keywords, rb_cArray))
        {
            try
            {
                std::shared_ptr<KeywordNameSet> knc (std::make_shared<KeywordNameSet>());
                long len = NUM2LONG(rb_funcall(keywords,rb_intern("length"),0));
                for (long i = 0; i < len; i++)
                {
                    // Stupid macros won't let me do it on one line.
                    VALUE kw = rb_ary_entry(keywords, i);
                    knc->insert(KeywordName(StringValuePtr(kw)));
                }
                return value_to_environment(self)->accept_keywords(knc, value_to_package_id(p)) ? Qtrue : Qfalse;
            }
            catch (const std::exception & e)
            {
                exception_to_ruby_exception(e);
            }
        }
        else
        {
            rb_raise(rb_eTypeError, "Can't convert %s into Array", rb_obj_classname(keywords));
        }
    }

    /*
     * call-seq:
     *     mirrors(mirror_name) -> Array
     *
     * Return the mirror URI prefixes for a named mirror.
     */
    VALUE
    environment_mirrors(VALUE self, VALUE mirror)
    {
        try
        {
            VALUE result(rb_ary_new());
            std::shared_ptr<const MirrorsSequence> m(value_to_environment(self)->mirrors(StringValuePtr(mirror)));
            for (MirrorsSequence::ConstIterator i(m->begin()), i_end(m->end()) ; i != i_end ; i++)
                rb_ary_push(result, rb_str_new2(stringify(*i).c_str()));
            return result;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    VALUE
    environment_distribution(VALUE self)
    {
        return rb_str_new2(value_to_environment(self)->distribution().c_str());

    }

    template <typename T_, const std::shared_ptr<const T_> (Environment::* m_) () const>
    struct EnvironmentKey
    {
        static VALUE
        fetch(VALUE self)
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);
            return (((**self_ptr).*m_)()) ? metadata_key_to_value(((**self_ptr).*m_)()) : Qnil;
        }
    };

    std::shared_ptr<PaludisEnvironment>
    value_to_paludis_environment(VALUE v)
    {
        if (rb_obj_is_kind_of(v, c_paludis_environment))
        {
            std::shared_ptr<Environment> * v_ptr;
            Data_Get_Struct(v, std::shared_ptr<Environment>, v_ptr);
            return std::static_pointer_cast<PaludisEnvironment>(*v_ptr);
        }
        else
        {
            rb_raise(rb_eTypeError, "Can't convert %s into PaludisEnvironment", rb_obj_classname(v));
        }
    }

    VALUE
    paludis_environment_init(int, VALUE*, VALUE self)
    {
        return self;
    }

    /*
     * call-seq:
     *     PaludisEnvironment.new -> PaludisEnvironment
     *     PaludisEnvironment.new(config_suffix) -> PaludisEnvironment
     *
     * Create a new PaludisEnvironment, with the specified config suffix if any, otherwise the empty suffix.
     */
    VALUE
    paludis_environment_new(int argc, VALUE* argv, VALUE self)
    {
        try
        {
            std::string config_suffix;
            if (1 == argc)
                config_suffix = StringValuePtr(argv[0]);
            else if (0 != argc)
                rb_raise(rb_eArgError, "PaludisEnvironment.new expects one or zero arguments, but got %d", argc);

            std::shared_ptr<Environment> * e = new std::shared_ptr<Environment>(std::make_shared<PaludisEnvironment>(config_suffix));
            VALUE tdata(Data_Wrap_Struct(self, 0, &Common<std::shared_ptr<Environment> >::free, e));
            rb_obj_call_init(tdata, argc, argv);
            return tdata;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     TestEnvironment.new -> TestEnvironment
     *
     * Create a new TestEnvironment.
     */
    VALUE
    test_environment_new(VALUE self)
    {
        try
        {
            std::shared_ptr<Environment> * e = new std::shared_ptr<Environment>(std::make_shared<TestEnvironment>());
            VALUE tdata(Data_Wrap_Struct(self, 0, &Common<std::shared_ptr<Environment> >::free, e));
            rb_obj_call_init(tdata, 0, &self);
            return tdata;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     config_dir -> String
     *
     * Configuration directory used by this PaludisEnvironment.
     */
    VALUE
    paludis_environment_config_dir(VALUE self)
    {
        return rb_str_new2(value_to_paludis_environment(self)->config_dir().c_str());
    }

    /*
     * call-seq:
     *     create(spec) -> Environment
     *
     * Create an environment from the given spec.
     * A spec consisits of <b>class:suffix</b> both of which may be omitted. <b>class</b> is the environment class,
     * e.g. paludis or portage, <b>suffix</b> is the configuration directory suffix.
     *
     */
    VALUE
    environment_factory_create(VALUE, VALUE spec)
    {
        try
        {
            std::shared_ptr<Environment> * e = new std::shared_ptr<Environment>(EnvironmentFactory::get_instance()->create(
                        StringValuePtr(spec)));

            VALUE tdata(Data_Wrap_Struct(c_environment, 0, &Common<std::shared_ptr<Environment> >::free, e));
            return tdata;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     fetch_unique_qualified_package_name(package_name) -> QualifiedPackageName
     *     fetch_unique_qualified_package_name(package_name, filter) -> QualifiedPackageName
     *
     * Disambiguate a package name.  If a filter is specified, limit
     * the potential results to packages that match.
     */
    VALUE
    environment_fetch_unique_qualified_package_name(int argc, VALUE *argv, VALUE self)
    {
        try
        {
            if (1 == argc || 2 == argc)
            {
                std::shared_ptr<Environment> * self_ptr;
                Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);
                return qualified_package_name_to_value((*self_ptr)->fetch_unique_qualified_package_name(
                                PackageNamePart(StringValuePtr(argv[0])), 2 == argc ? value_to_filter(argv[1]) : filter::All()));
            }
            else
                rb_raise(rb_eArgError, "fetch_unique_qualified_package_name expects one or two arguments, but got %d",argc);
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     repositories -> Array
     *     repositories {|repository| block } -> Nil
     *
     *  Returns all the repositories in the package database, either as an Array, or as
     *  the parameters to a block.
     */
    VALUE
    environment_repositories(VALUE self)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            if (rb_block_given_p())
            {
                for (Environment::RepositoryConstIterator r((*self_ptr)->begin_repositories()),
                        r_end((*self_ptr)->end_repositories()) ; r != r_end ; ++r)
                    rb_yield(repository_to_value(*r));
                return Qnil;
            }
            VALUE result(rb_ary_new());
            for (Environment::RepositoryConstIterator r((*self_ptr)->begin_repositories()),
                    r_end((*self_ptr)->end_repositories()) ; r != r_end ; ++r)
                rb_ary_push(result, repository_to_value(*r));

            return result;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     fetch_repository(repository_name) -> Repository
     *
     *  Fetch a named repository.
     */
    VALUE
    environment_fetch_repository(VALUE self, VALUE name)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return repository_to_value((*self_ptr)->fetch_repository(RepositoryName(StringValuePtr(name))));
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     more_important_than(repository_name_a, repository_name_b) -> bool
     *
     * True if repository_name_a is more important than repository_name_b .
     */
    VALUE
    environment_more_important_than(VALUE self, VALUE name1, VALUE name2)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return (*self_ptr)->more_important_than(RepositoryName(StringValuePtr(name1)),
                    RepositoryName(StringValuePtr(name2))) ? Qtrue : Qfalse;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     has_repository_named?(repository_name) -> true or false
     *
     *  Do we have a named repository?
     */
    VALUE
    environment_has_repository_named(VALUE self, VALUE name)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return ((*self_ptr)->has_repository_named(RepositoryName(StringValuePtr(name)))) ? true : false;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     add_repository(importance, repository) -> nil
     *
     *  Add a repository.
     */
    VALUE
    environment_add_repository(VALUE self, VALUE importance, VALUE repo_v)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            std::shared_ptr<Repository> repo(value_to_repository(repo_v));

            (*self_ptr)->add_repository(NUM2INT(importance), repo);
            return Qnil;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }


    void do_register_environment()
    {
        rb_require("singleton");

        /*
         * Document-class: Paludis::Environment
         *
         * Represents a working environment, which contains an available packages database and provides
         * various methods for querying package visibility and options.
         */
        c_environment = rb_define_class_under(c_paludis_module, "Environment", rb_cObject);
        rb_funcall(c_environment, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        rb_define_method(c_environment, "set", environment_set, 1);
        rb_define_method(c_environment, "distribution", environment_distribution, 0);
        rb_define_method(c_environment, "accept_license", environment_accept_license, 2);
        rb_define_method(c_environment, "accept_keywords", environment_accept_keywords, 2);
        rb_define_method(c_environment, "mirrors", environment_mirrors, 1);
        rb_define_method(c_environment, "[]", environment_square_brackets, 1);
        rb_define_method(c_environment, "format_key",                EnvironmentKey<MetadataValueKey<std::string> , Environment::format_key>::fetch, 0);
        rb_define_method(c_environment, "config_location_key",                template_methods, 0);
        rb_define_method(c_environment, "preferred_root_key",                template_methods, 0);
        rb_define_method(c_environment, "fetch_unique_qualified_package_name",                environment_fetch_unique_qualified_package_name, -1);
        rb_define_method(c_environment, "repositories",                environment_repositories, 0);
        rb_define_method(c_environment, "fetch_repository",                environment_fetch_repository, 1);
        rb_define_method(c_environment, "more_important_than",                environment_more_important_than, 2);
        rb_define_method(c_environment, "has_repository_named?",                environment_has_repository_named, 1);
        rb_define_method(c_environment, "add_repository",                environment_add_repository, 2);

        /*
         * Document-class: Paludis::PaludisEnvironment
         *
         * An Environment that corresponds to the normal operating evironment.
         */
        c_paludis_environment = rb_define_class_under(c_paludis_module, "PaludisEnvironment", c_environment);
        rb_define_singleton_method(c_paludis_environment, "new", paludis_environment_new, -1);
        rb_define_method(c_paludis_environment, "initialize", paludis_environment_init, -1);
        rb_define_method(c_paludis_environment, "config_dir", paludis_environment_config_dir, 0);

        /*
         * Document-class: Paludis::TestEnvironment
         *
         * A crude test environment.
         */
        c_test_environment = rb_define_class_under(c_paludis_module, "TestEnvironment", c_environment);
        rb_define_singleton_method(c_test_environment, "new", test_environment_new, 0);

        /*
         * Document-class: Paludis::EnvironmentFactory
         *
         * A class that holds methods to create environments.
         *
         * To access the default environment use create("")
         */
        c_environment_factory = rb_define_class_under(c_paludis_module, "EnvironmentFactory", rb_cObject);
        rb_funcall(rb_const_get(rb_cObject, rb_intern("Singleton")), rb_intern("included"), 1, c_environment_factory);
        rb_define_method(c_environment_factory, "create", environment_factory_create, 1);
    }
}
add_repository(importance, repository) → nil click to toggle source

Add a repository.

VALUE
    environment_add_repository(VALUE self, VALUE importance, VALUE repo_v)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            std::shared_ptr<Repository> repo(value_to_repository(repo_v));

            (*self_ptr)->add_repository(NUM2INT(importance), repo);
            return Qnil;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }


    void do_register_environment()
    {
        rb_require("singleton");

        /*
         * Document-class: Paludis::Environment
         *
         * Represents a working environment, which contains an available packages database and provides
         * various methods for querying package visibility and options.
         */
        c_environment = rb_define_class_under(c_paludis_module, "Environment", rb_cObject);
        rb_funcall(c_environment, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        rb_define_method(c_environment, "set", environment_set, 1);
        rb_define_method(c_environment, "distribution", environment_distribution, 0);
        rb_define_method(c_environment, "accept_license", environment_accept_license, 2);
        rb_define_method(c_environment, "accept_keywords", environment_accept_keywords, 2);
        rb_define_method(c_environment, "mirrors", environment_mirrors, 1);
        rb_define_method(c_environment, "[]", environment_square_brackets, 1);
        rb_define_method(c_environment, "format_key",                EnvironmentKey<MetadataValueKey<std::string> , Environment::format_key>::fetch, 0);
        rb_define_method(c_environment, "config_location_key",                template_methods, 0);
        rb_define_method(c_environment, "preferred_root_key",                template_methods, 0);
        rb_define_method(c_environment, "fetch_unique_qualified_package_name",                environment_fetch_unique_qualified_package_name, -1);
        rb_define_method(c_environment, "repositories",                environment_repositories, 0);
        rb_define_method(c_environment, "fetch_repository",                environment_fetch_repository, 1);
        rb_define_method(c_environment, "more_important_than",                environment_more_important_than, 2);
        rb_define_method(c_environment, "has_repository_named?",                environment_has_repository_named, 1);
        rb_define_method(c_environment, "add_repository",                environment_add_repository, 2);

        /*
         * Document-class: Paludis::PaludisEnvironment
         *
         * An Environment that corresponds to the normal operating evironment.
         */
        c_paludis_environment = rb_define_class_under(c_paludis_module, "PaludisEnvironment", c_environment);
        rb_define_singleton_method(c_paludis_environment, "new", paludis_environment_new, -1);
        rb_define_method(c_paludis_environment, "initialize", paludis_environment_init, -1);
        rb_define_method(c_paludis_environment, "config_dir", paludis_environment_config_dir, 0);

        /*
         * Document-class: Paludis::TestEnvironment
         *
         * A crude test environment.
         */
        c_test_environment = rb_define_class_under(c_paludis_module, "TestEnvironment", c_environment);
        rb_define_singleton_method(c_test_environment, "new", test_environment_new, 0);

        /*
         * Document-class: Paludis::EnvironmentFactory
         *
         * A class that holds methods to create environments.
         *
         * To access the default environment use create("")
         */
        c_environment_factory = rb_define_class_under(c_paludis_module, "EnvironmentFactory", rb_cObject);
        rb_funcall(rb_const_get(rb_cObject, rb_intern("Singleton")), rb_intern("included"), 1, c_environment_factory);
        rb_define_method(c_environment_factory, "create", environment_factory_create, 1);
    }
}
distribution() click to toggle source
VALUE
    environment_distribution(VALUE self)
    {
        return rb_str_new2(value_to_environment(self)->distribution().c_str());

    }

    template <typename T_, const std::shared_ptr<const T_> (Environment::* m_) () const>
    struct EnvironmentKey
    {
        static VALUE
        fetch(VALUE self)
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);
            return (((**self_ptr).*m_)()) ? metadata_key_to_value(((**self_ptr).*m_)()) : Qnil;
        }
    };

    std::shared_ptr<PaludisEnvironment>
    value_to_paludis_environment(VALUE v)
    {
        if (rb_obj_is_kind_of(v, c_paludis_environment))
        {
            std::shared_ptr<Environment> * v_ptr;
            Data_Get_Struct(v, std::shared_ptr<Environment>, v_ptr);
            return std::static_pointer_cast<PaludisEnvironment>(*v_ptr);
        }
        else
        {
            rb_raise(rb_eTypeError, "Can't convert %s into PaludisEnvironment", rb_obj_classname(v));
        }
    }

    VALUE
    paludis_environment_init(int, VALUE*, VALUE self)
    {
        return self;
    }

    /*
     * call-seq:
     *     PaludisEnvironment.new -> PaludisEnvironment
     *     PaludisEnvironment.new(config_suffix) -> PaludisEnvironment
     *
     * Create a new PaludisEnvironment, with the specified config suffix if any, otherwise the empty suffix.
     */
    VALUE
    paludis_environment_new(int argc, VALUE* argv, VALUE self)
    {
        try
        {
            std::string config_suffix;
            if (1 == argc)
                config_suffix = StringValuePtr(argv[0]);
            else if (0 != argc)
                rb_raise(rb_eArgError, "PaludisEnvironment.new expects one or zero arguments, but got %d", argc);

            std::shared_ptr<Environment> * e = new std::shared_ptr<Environment>(std::make_shared<PaludisEnvironment>(config_suffix));
            VALUE tdata(Data_Wrap_Struct(self, 0, &Common<std::shared_ptr<Environment> >::free, e));
            rb_obj_call_init(tdata, argc, argv);
            return tdata;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     TestEnvironment.new -> TestEnvironment
     *
     * Create a new TestEnvironment.
     */
    VALUE
    test_environment_new(VALUE self)
    {
        try
        {
            std::shared_ptr<Environment> * e = new std::shared_ptr<Environment>(std::make_shared<TestEnvironment>());
            VALUE tdata(Data_Wrap_Struct(self, 0, &Common<std::shared_ptr<Environment> >::free, e));
            rb_obj_call_init(tdata, 0, &self);
            return tdata;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     config_dir -> String
     *
     * Configuration directory used by this PaludisEnvironment.
     */
    VALUE
    paludis_environment_config_dir(VALUE self)
    {
        return rb_str_new2(value_to_paludis_environment(self)->config_dir().c_str());
    }

    /*
     * call-seq:
     *     create(spec) -> Environment
     *
     * Create an environment from the given spec.
     * A spec consisits of <b>class:suffix</b> both of which may be omitted. <b>class</b> is the environment class,
     * e.g. paludis or portage, <b>suffix</b> is the configuration directory suffix.
     *
     */
    VALUE
    environment_factory_create(VALUE, VALUE spec)
    {
        try
        {
            std::shared_ptr<Environment> * e = new std::shared_ptr<Environment>(EnvironmentFactory::get_instance()->create(
                        StringValuePtr(spec)));

            VALUE tdata(Data_Wrap_Struct(c_environment, 0, &Common<std::shared_ptr<Environment> >::free, e));
            return tdata;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     fetch_unique_qualified_package_name(package_name) -> QualifiedPackageName
     *     fetch_unique_qualified_package_name(package_name, filter) -> QualifiedPackageName
     *
     * Disambiguate a package name.  If a filter is specified, limit
     * the potential results to packages that match.
     */
    VALUE
    environment_fetch_unique_qualified_package_name(int argc, VALUE *argv, VALUE self)
    {
        try
        {
            if (1 == argc || 2 == argc)
            {
                std::shared_ptr<Environment> * self_ptr;
                Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);
                return qualified_package_name_to_value((*self_ptr)->fetch_unique_qualified_package_name(
                                PackageNamePart(StringValuePtr(argv[0])), 2 == argc ? value_to_filter(argv[1]) : filter::All()));
            }
            else
                rb_raise(rb_eArgError, "fetch_unique_qualified_package_name expects one or two arguments, but got %d",argc);
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     repositories -> Array
     *     repositories {|repository| block } -> Nil
     *
     *  Returns all the repositories in the package database, either as an Array, or as
     *  the parameters to a block.
     */
    VALUE
    environment_repositories(VALUE self)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            if (rb_block_given_p())
            {
                for (Environment::RepositoryConstIterator r((*self_ptr)->begin_repositories()),
                        r_end((*self_ptr)->end_repositories()) ; r != r_end ; ++r)
                    rb_yield(repository_to_value(*r));
                return Qnil;
            }
            VALUE result(rb_ary_new());
            for (Environment::RepositoryConstIterator r((*self_ptr)->begin_repositories()),
                    r_end((*self_ptr)->end_repositories()) ; r != r_end ; ++r)
                rb_ary_push(result, repository_to_value(*r));

            return result;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     fetch_repository(repository_name) -> Repository
     *
     *  Fetch a named repository.
     */
    VALUE
    environment_fetch_repository(VALUE self, VALUE name)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return repository_to_value((*self_ptr)->fetch_repository(RepositoryName(StringValuePtr(name))));
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     more_important_than(repository_name_a, repository_name_b) -> bool
     *
     * True if repository_name_a is more important than repository_name_b .
     */
    VALUE
    environment_more_important_than(VALUE self, VALUE name1, VALUE name2)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return (*self_ptr)->more_important_than(RepositoryName(StringValuePtr(name1)),
                    RepositoryName(StringValuePtr(name2))) ? Qtrue : Qfalse;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     has_repository_named?(repository_name) -> true or false
     *
     *  Do we have a named repository?
     */
    VALUE
    environment_has_repository_named(VALUE self, VALUE name)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return ((*self_ptr)->has_repository_named(RepositoryName(StringValuePtr(name)))) ? true : false;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     add_repository(importance, repository) -> nil
     *
     *  Add a repository.
     */
    VALUE
    environment_add_repository(VALUE self, VALUE importance, VALUE repo_v)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            std::shared_ptr<Repository> repo(value_to_repository(repo_v));

            (*self_ptr)->add_repository(NUM2INT(importance), repo);
            return Qnil;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }


    void do_register_environment()
    {
        rb_require("singleton");

        /*
         * Document-class: Paludis::Environment
         *
         * Represents a working environment, which contains an available packages database and provides
         * various methods for querying package visibility and options.
         */
        c_environment = rb_define_class_under(c_paludis_module, "Environment", rb_cObject);
        rb_funcall(c_environment, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        rb_define_method(c_environment, "set", environment_set, 1);
        rb_define_method(c_environment, "distribution", environment_distribution, 0);
        rb_define_method(c_environment, "accept_license", environment_accept_license, 2);
        rb_define_method(c_environment, "accept_keywords", environment_accept_keywords, 2);
        rb_define_method(c_environment, "mirrors", environment_mirrors, 1);
        rb_define_method(c_environment, "[]", environment_square_brackets, 1);
        rb_define_method(c_environment, "format_key",                EnvironmentKey<MetadataValueKey<std::string> , Environment::format_key>::fetch, 0);
        rb_define_method(c_environment, "config_location_key",                template_methods, 0);
        rb_define_method(c_environment, "preferred_root_key",                template_methods, 0);
        rb_define_method(c_environment, "fetch_unique_qualified_package_name",                environment_fetch_unique_qualified_package_name, -1);
        rb_define_method(c_environment, "repositories",                environment_repositories, 0);
        rb_define_method(c_environment, "fetch_repository",                environment_fetch_repository, 1);
        rb_define_method(c_environment, "more_important_than",                environment_more_important_than, 2);
        rb_define_method(c_environment, "has_repository_named?",                environment_has_repository_named, 1);
        rb_define_method(c_environment, "add_repository",                environment_add_repository, 2);

        /*
         * Document-class: Paludis::PaludisEnvironment
         *
         * An Environment that corresponds to the normal operating evironment.
         */
        c_paludis_environment = rb_define_class_under(c_paludis_module, "PaludisEnvironment", c_environment);
        rb_define_singleton_method(c_paludis_environment, "new", paludis_environment_new, -1);
        rb_define_method(c_paludis_environment, "initialize", paludis_environment_init, -1);
        rb_define_method(c_paludis_environment, "config_dir", paludis_environment_config_dir, 0);

        /*
         * Document-class: Paludis::TestEnvironment
         *
         * A crude test environment.
         */
        c_test_environment = rb_define_class_under(c_paludis_module, "TestEnvironment", c_environment);
        rb_define_singleton_method(c_test_environment, "new", test_environment_new, 0);

        /*
         * Document-class: Paludis::EnvironmentFactory
         *
         * A class that holds methods to create environments.
         *
         * To access the default environment use create("")
         */
        c_environment_factory = rb_define_class_under(c_paludis_module, "EnvironmentFactory", rb_cObject);
        rb_funcall(rb_const_get(rb_cObject, rb_intern("Singleton")), rb_intern("included"), 1, c_environment_factory);
        rb_define_method(c_environment_factory, "create", environment_factory_create, 1);
    }
}
fetch_repository(repository_name) → Repository click to toggle source

Fetch a named repository.

VALUE
    environment_fetch_repository(VALUE self, VALUE name)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return repository_to_value((*self_ptr)->fetch_repository(RepositoryName(StringValuePtr(name))));
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     more_important_than(repository_name_a, repository_name_b) -> bool
     *
     * True if repository_name_a is more important than repository_name_b .
     */
    VALUE
    environment_more_important_than(VALUE self, VALUE name1, VALUE name2)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return (*self_ptr)->more_important_than(RepositoryName(StringValuePtr(name1)),
                    RepositoryName(StringValuePtr(name2))) ? Qtrue : Qfalse;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     has_repository_named?(repository_name) -> true or false
     *
     *  Do we have a named repository?
     */
    VALUE
    environment_has_repository_named(VALUE self, VALUE name)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return ((*self_ptr)->has_repository_named(RepositoryName(StringValuePtr(name)))) ? true : false;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     add_repository(importance, repository) -> nil
     *
     *  Add a repository.
     */
    VALUE
    environment_add_repository(VALUE self, VALUE importance, VALUE repo_v)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            std::shared_ptr<Repository> repo(value_to_repository(repo_v));

            (*self_ptr)->add_repository(NUM2INT(importance), repo);
            return Qnil;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }


    void do_register_environment()
    {
        rb_require("singleton");

        /*
         * Document-class: Paludis::Environment
         *
         * Represents a working environment, which contains an available packages database and provides
         * various methods for querying package visibility and options.
         */
        c_environment = rb_define_class_under(c_paludis_module, "Environment", rb_cObject);
        rb_funcall(c_environment, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        rb_define_method(c_environment, "set", environment_set, 1);
        rb_define_method(c_environment, "distribution", environment_distribution, 0);
        rb_define_method(c_environment, "accept_license", environment_accept_license, 2);
        rb_define_method(c_environment, "accept_keywords", environment_accept_keywords, 2);
        rb_define_method(c_environment, "mirrors", environment_mirrors, 1);
        rb_define_method(c_environment, "[]", environment_square_brackets, 1);
        rb_define_method(c_environment, "format_key",                EnvironmentKey<MetadataValueKey<std::string> , Environment::format_key>::fetch, 0);
        rb_define_method(c_environment, "config_location_key",                template_methods, 0);
        rb_define_method(c_environment, "preferred_root_key",                template_methods, 0);
        rb_define_method(c_environment, "fetch_unique_qualified_package_name",                environment_fetch_unique_qualified_package_name, -1);
        rb_define_method(c_environment, "repositories",                environment_repositories, 0);
        rb_define_method(c_environment, "fetch_repository",                environment_fetch_repository, 1);
        rb_define_method(c_environment, "more_important_than",                environment_more_important_than, 2);
        rb_define_method(c_environment, "has_repository_named?",                environment_has_repository_named, 1);
        rb_define_method(c_environment, "add_repository",                environment_add_repository, 2);

        /*
         * Document-class: Paludis::PaludisEnvironment
         *
         * An Environment that corresponds to the normal operating evironment.
         */
        c_paludis_environment = rb_define_class_under(c_paludis_module, "PaludisEnvironment", c_environment);
        rb_define_singleton_method(c_paludis_environment, "new", paludis_environment_new, -1);
        rb_define_method(c_paludis_environment, "initialize", paludis_environment_init, -1);
        rb_define_method(c_paludis_environment, "config_dir", paludis_environment_config_dir, 0);

        /*
         * Document-class: Paludis::TestEnvironment
         *
         * A crude test environment.
         */
        c_test_environment = rb_define_class_under(c_paludis_module, "TestEnvironment", c_environment);
        rb_define_singleton_method(c_test_environment, "new", test_environment_new, 0);

        /*
         * Document-class: Paludis::EnvironmentFactory
         *
         * A class that holds methods to create environments.
         *
         * To access the default environment use create("")
         */
        c_environment_factory = rb_define_class_under(c_paludis_module, "EnvironmentFactory", rb_cObject);
        rb_funcall(rb_const_get(rb_cObject, rb_intern("Singleton")), rb_intern("included"), 1, c_environment_factory);
        rb_define_method(c_environment_factory, "create", environment_factory_create, 1);
    }
}
fetch_unique_qualified_package_name(package_name) → QualifiedPackageName click to toggle source
fetch_unique_qualified_package_name(package_name, filter) → QualifiedPackageName

Disambiguate a package name. If a filter is specified, limit the potential results to packages that match.

VALUE
    environment_fetch_unique_qualified_package_name(int argc, VALUE *argv, VALUE self)
    {
        try
        {
            if (1 == argc || 2 == argc)
            {
                std::shared_ptr<Environment> * self_ptr;
                Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);
                return qualified_package_name_to_value((*self_ptr)->fetch_unique_qualified_package_name(
                                PackageNamePart(StringValuePtr(argv[0])), 2 == argc ? value_to_filter(argv[1]) : filter::All()));
            }
            else
                rb_raise(rb_eArgError, "fetch_unique_qualified_package_name expects one or two arguments, but got %d",argc);
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     repositories -> Array
     *     repositories {|repository| block } -> Nil
     *
     *  Returns all the repositories in the package database, either as an Array, or as
     *  the parameters to a block.
     */
    VALUE
    environment_repositories(VALUE self)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            if (rb_block_given_p())
            {
                for (Environment::RepositoryConstIterator r((*self_ptr)->begin_repositories()),
                        r_end((*self_ptr)->end_repositories()) ; r != r_end ; ++r)
                    rb_yield(repository_to_value(*r));
                return Qnil;
            }
            VALUE result(rb_ary_new());
            for (Environment::RepositoryConstIterator r((*self_ptr)->begin_repositories()),
                    r_end((*self_ptr)->end_repositories()) ; r != r_end ; ++r)
                rb_ary_push(result, repository_to_value(*r));

            return result;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     fetch_repository(repository_name) -> Repository
     *
     *  Fetch a named repository.
     */
    VALUE
    environment_fetch_repository(VALUE self, VALUE name)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return repository_to_value((*self_ptr)->fetch_repository(RepositoryName(StringValuePtr(name))));
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     more_important_than(repository_name_a, repository_name_b) -> bool
     *
     * True if repository_name_a is more important than repository_name_b .
     */
    VALUE
    environment_more_important_than(VALUE self, VALUE name1, VALUE name2)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return (*self_ptr)->more_important_than(RepositoryName(StringValuePtr(name1)),
                    RepositoryName(StringValuePtr(name2))) ? Qtrue : Qfalse;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     has_repository_named?(repository_name) -> true or false
     *
     *  Do we have a named repository?
     */
    VALUE
    environment_has_repository_named(VALUE self, VALUE name)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return ((*self_ptr)->has_repository_named(RepositoryName(StringValuePtr(name)))) ? true : false;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     add_repository(importance, repository) -> nil
     *
     *  Add a repository.
     */
    VALUE
    environment_add_repository(VALUE self, VALUE importance, VALUE repo_v)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            std::shared_ptr<Repository> repo(value_to_repository(repo_v));

            (*self_ptr)->add_repository(NUM2INT(importance), repo);
            return Qnil;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }


    void do_register_environment()
    {
        rb_require("singleton");

        /*
         * Document-class: Paludis::Environment
         *
         * Represents a working environment, which contains an available packages database and provides
         * various methods for querying package visibility and options.
         */
        c_environment = rb_define_class_under(c_paludis_module, "Environment", rb_cObject);
        rb_funcall(c_environment, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        rb_define_method(c_environment, "set", environment_set, 1);
        rb_define_method(c_environment, "distribution", environment_distribution, 0);
        rb_define_method(c_environment, "accept_license", environment_accept_license, 2);
        rb_define_method(c_environment, "accept_keywords", environment_accept_keywords, 2);
        rb_define_method(c_environment, "mirrors", environment_mirrors, 1);
        rb_define_method(c_environment, "[]", environment_square_brackets, 1);
        rb_define_method(c_environment, "format_key",                EnvironmentKey<MetadataValueKey<std::string> , Environment::format_key>::fetch, 0);
        rb_define_method(c_environment, "config_location_key",                template_methods, 0);
        rb_define_method(c_environment, "preferred_root_key",                template_methods, 0);
        rb_define_method(c_environment, "fetch_unique_qualified_package_name",                environment_fetch_unique_qualified_package_name, -1);
        rb_define_method(c_environment, "repositories",                environment_repositories, 0);
        rb_define_method(c_environment, "fetch_repository",                environment_fetch_repository, 1);
        rb_define_method(c_environment, "more_important_than",                environment_more_important_than, 2);
        rb_define_method(c_environment, "has_repository_named?",                environment_has_repository_named, 1);
        rb_define_method(c_environment, "add_repository",                environment_add_repository, 2);

        /*
         * Document-class: Paludis::PaludisEnvironment
         *
         * An Environment that corresponds to the normal operating evironment.
         */
        c_paludis_environment = rb_define_class_under(c_paludis_module, "PaludisEnvironment", c_environment);
        rb_define_singleton_method(c_paludis_environment, "new", paludis_environment_new, -1);
        rb_define_method(c_paludis_environment, "initialize", paludis_environment_init, -1);
        rb_define_method(c_paludis_environment, "config_dir", paludis_environment_config_dir, 0);

        /*
         * Document-class: Paludis::TestEnvironment
         *
         * A crude test environment.
         */
        c_test_environment = rb_define_class_under(c_paludis_module, "TestEnvironment", c_environment);
        rb_define_singleton_method(c_test_environment, "new", test_environment_new, 0);

        /*
         * Document-class: Paludis::EnvironmentFactory
         *
         * A class that holds methods to create environments.
         *
         * To access the default environment use create("")
         */
        c_environment_factory = rb_define_class_under(c_paludis_module, "EnvironmentFactory", rb_cObject);
        rb_funcall(rb_const_get(rb_cObject, rb_intern("Singleton")), rb_intern("included"), 1, c_environment_factory);
        rb_define_method(c_environment_factory, "create", environment_factory_create, 1);
    }
}
has_repository_named?(repository_name) → true or false click to toggle source

Do we have a named repository?

VALUE
    environment_has_repository_named(VALUE self, VALUE name)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return ((*self_ptr)->has_repository_named(RepositoryName(StringValuePtr(name)))) ? true : false;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     add_repository(importance, repository) -> nil
     *
     *  Add a repository.
     */
    VALUE
    environment_add_repository(VALUE self, VALUE importance, VALUE repo_v)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            std::shared_ptr<Repository> repo(value_to_repository(repo_v));

            (*self_ptr)->add_repository(NUM2INT(importance), repo);
            return Qnil;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }


    void do_register_environment()
    {
        rb_require("singleton");

        /*
         * Document-class: Paludis::Environment
         *
         * Represents a working environment, which contains an available packages database and provides
         * various methods for querying package visibility and options.
         */
        c_environment = rb_define_class_under(c_paludis_module, "Environment", rb_cObject);
        rb_funcall(c_environment, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        rb_define_method(c_environment, "set", environment_set, 1);
        rb_define_method(c_environment, "distribution", environment_distribution, 0);
        rb_define_method(c_environment, "accept_license", environment_accept_license, 2);
        rb_define_method(c_environment, "accept_keywords", environment_accept_keywords, 2);
        rb_define_method(c_environment, "mirrors", environment_mirrors, 1);
        rb_define_method(c_environment, "[]", environment_square_brackets, 1);
        rb_define_method(c_environment, "format_key",                EnvironmentKey<MetadataValueKey<std::string> , Environment::format_key>::fetch, 0);
        rb_define_method(c_environment, "config_location_key",                template_methods, 0);
        rb_define_method(c_environment, "preferred_root_key",                template_methods, 0);
        rb_define_method(c_environment, "fetch_unique_qualified_package_name",                environment_fetch_unique_qualified_package_name, -1);
        rb_define_method(c_environment, "repositories",                environment_repositories, 0);
        rb_define_method(c_environment, "fetch_repository",                environment_fetch_repository, 1);
        rb_define_method(c_environment, "more_important_than",                environment_more_important_than, 2);
        rb_define_method(c_environment, "has_repository_named?",                environment_has_repository_named, 1);
        rb_define_method(c_environment, "add_repository",                environment_add_repository, 2);

        /*
         * Document-class: Paludis::PaludisEnvironment
         *
         * An Environment that corresponds to the normal operating evironment.
         */
        c_paludis_environment = rb_define_class_under(c_paludis_module, "PaludisEnvironment", c_environment);
        rb_define_singleton_method(c_paludis_environment, "new", paludis_environment_new, -1);
        rb_define_method(c_paludis_environment, "initialize", paludis_environment_init, -1);
        rb_define_method(c_paludis_environment, "config_dir", paludis_environment_config_dir, 0);

        /*
         * Document-class: Paludis::TestEnvironment
         *
         * A crude test environment.
         */
        c_test_environment = rb_define_class_under(c_paludis_module, "TestEnvironment", c_environment);
        rb_define_singleton_method(c_test_environment, "new", test_environment_new, 0);

        /*
         * Document-class: Paludis::EnvironmentFactory
         *
         * A class that holds methods to create environments.
         *
         * To access the default environment use create("")
         */
        c_environment_factory = rb_define_class_under(c_paludis_module, "EnvironmentFactory", rb_cObject);
        rb_funcall(rb_const_get(rb_cObject, rb_intern("Singleton")), rb_intern("included"), 1, c_environment_factory);
        rb_define_method(c_environment_factory, "create", environment_factory_create, 1);
    }
}
mirrors(mirror_name) → Array click to toggle source

Return the mirror URI prefixes for a named mirror.

VALUE
    environment_mirrors(VALUE self, VALUE mirror)
    {
        try
        {
            VALUE result(rb_ary_new());
            std::shared_ptr<const MirrorsSequence> m(value_to_environment(self)->mirrors(StringValuePtr(mirror)));
            for (MirrorsSequence::ConstIterator i(m->begin()), i_end(m->end()) ; i != i_end ; i++)
                rb_ary_push(result, rb_str_new2(stringify(*i).c_str()));
            return result;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    VALUE
    environment_distribution(VALUE self)
    {
        return rb_str_new2(value_to_environment(self)->distribution().c_str());

    }

    template <typename T_, const std::shared_ptr<const T_> (Environment::* m_) () const>
    struct EnvironmentKey
    {
        static VALUE
        fetch(VALUE self)
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);
            return (((**self_ptr).*m_)()) ? metadata_key_to_value(((**self_ptr).*m_)()) : Qnil;
        }
    };

    std::shared_ptr<PaludisEnvironment>
    value_to_paludis_environment(VALUE v)
    {
        if (rb_obj_is_kind_of(v, c_paludis_environment))
        {
            std::shared_ptr<Environment> * v_ptr;
            Data_Get_Struct(v, std::shared_ptr<Environment>, v_ptr);
            return std::static_pointer_cast<PaludisEnvironment>(*v_ptr);
        }
        else
        {
            rb_raise(rb_eTypeError, "Can't convert %s into PaludisEnvironment", rb_obj_classname(v));
        }
    }

    VALUE
    paludis_environment_init(int, VALUE*, VALUE self)
    {
        return self;
    }

    /*
     * call-seq:
     *     PaludisEnvironment.new -> PaludisEnvironment
     *     PaludisEnvironment.new(config_suffix) -> PaludisEnvironment
     *
     * Create a new PaludisEnvironment, with the specified config suffix if any, otherwise the empty suffix.
     */
    VALUE
    paludis_environment_new(int argc, VALUE* argv, VALUE self)
    {
        try
        {
            std::string config_suffix;
            if (1 == argc)
                config_suffix = StringValuePtr(argv[0]);
            else if (0 != argc)
                rb_raise(rb_eArgError, "PaludisEnvironment.new expects one or zero arguments, but got %d", argc);

            std::shared_ptr<Environment> * e = new std::shared_ptr<Environment>(std::make_shared<PaludisEnvironment>(config_suffix));
            VALUE tdata(Data_Wrap_Struct(self, 0, &Common<std::shared_ptr<Environment> >::free, e));
            rb_obj_call_init(tdata, argc, argv);
            return tdata;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     TestEnvironment.new -> TestEnvironment
     *
     * Create a new TestEnvironment.
     */
    VALUE
    test_environment_new(VALUE self)
    {
        try
        {
            std::shared_ptr<Environment> * e = new std::shared_ptr<Environment>(std::make_shared<TestEnvironment>());
            VALUE tdata(Data_Wrap_Struct(self, 0, &Common<std::shared_ptr<Environment> >::free, e));
            rb_obj_call_init(tdata, 0, &self);
            return tdata;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     config_dir -> String
     *
     * Configuration directory used by this PaludisEnvironment.
     */
    VALUE
    paludis_environment_config_dir(VALUE self)
    {
        return rb_str_new2(value_to_paludis_environment(self)->config_dir().c_str());
    }

    /*
     * call-seq:
     *     create(spec) -> Environment
     *
     * Create an environment from the given spec.
     * A spec consisits of <b>class:suffix</b> both of which may be omitted. <b>class</b> is the environment class,
     * e.g. paludis or portage, <b>suffix</b> is the configuration directory suffix.
     *
     */
    VALUE
    environment_factory_create(VALUE, VALUE spec)
    {
        try
        {
            std::shared_ptr<Environment> * e = new std::shared_ptr<Environment>(EnvironmentFactory::get_instance()->create(
                        StringValuePtr(spec)));

            VALUE tdata(Data_Wrap_Struct(c_environment, 0, &Common<std::shared_ptr<Environment> >::free, e));
            return tdata;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     fetch_unique_qualified_package_name(package_name) -> QualifiedPackageName
     *     fetch_unique_qualified_package_name(package_name, filter) -> QualifiedPackageName
     *
     * Disambiguate a package name.  If a filter is specified, limit
     * the potential results to packages that match.
     */
    VALUE
    environment_fetch_unique_qualified_package_name(int argc, VALUE *argv, VALUE self)
    {
        try
        {
            if (1 == argc || 2 == argc)
            {
                std::shared_ptr<Environment> * self_ptr;
                Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);
                return qualified_package_name_to_value((*self_ptr)->fetch_unique_qualified_package_name(
                                PackageNamePart(StringValuePtr(argv[0])), 2 == argc ? value_to_filter(argv[1]) : filter::All()));
            }
            else
                rb_raise(rb_eArgError, "fetch_unique_qualified_package_name expects one or two arguments, but got %d",argc);
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     repositories -> Array
     *     repositories {|repository| block } -> Nil
     *
     *  Returns all the repositories in the package database, either as an Array, or as
     *  the parameters to a block.
     */
    VALUE
    environment_repositories(VALUE self)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            if (rb_block_given_p())
            {
                for (Environment::RepositoryConstIterator r((*self_ptr)->begin_repositories()),
                        r_end((*self_ptr)->end_repositories()) ; r != r_end ; ++r)
                    rb_yield(repository_to_value(*r));
                return Qnil;
            }
            VALUE result(rb_ary_new());
            for (Environment::RepositoryConstIterator r((*self_ptr)->begin_repositories()),
                    r_end((*self_ptr)->end_repositories()) ; r != r_end ; ++r)
                rb_ary_push(result, repository_to_value(*r));

            return result;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     fetch_repository(repository_name) -> Repository
     *
     *  Fetch a named repository.
     */
    VALUE
    environment_fetch_repository(VALUE self, VALUE name)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return repository_to_value((*self_ptr)->fetch_repository(RepositoryName(StringValuePtr(name))));
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     more_important_than(repository_name_a, repository_name_b) -> bool
     *
     * True if repository_name_a is more important than repository_name_b .
     */
    VALUE
    environment_more_important_than(VALUE self, VALUE name1, VALUE name2)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return (*self_ptr)->more_important_than(RepositoryName(StringValuePtr(name1)),
                    RepositoryName(StringValuePtr(name2))) ? Qtrue : Qfalse;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     has_repository_named?(repository_name) -> true or false
     *
     *  Do we have a named repository?
     */
    VALUE
    environment_has_repository_named(VALUE self, VALUE name)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return ((*self_ptr)->has_repository_named(RepositoryName(StringValuePtr(name)))) ? true : false;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     add_repository(importance, repository) -> nil
     *
     *  Add a repository.
     */
    VALUE
    environment_add_repository(VALUE self, VALUE importance, VALUE repo_v)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            std::shared_ptr<Repository> repo(value_to_repository(repo_v));

            (*self_ptr)->add_repository(NUM2INT(importance), repo);
            return Qnil;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }


    void do_register_environment()
    {
        rb_require("singleton");

        /*
         * Document-class: Paludis::Environment
         *
         * Represents a working environment, which contains an available packages database and provides
         * various methods for querying package visibility and options.
         */
        c_environment = rb_define_class_under(c_paludis_module, "Environment", rb_cObject);
        rb_funcall(c_environment, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        rb_define_method(c_environment, "set", environment_set, 1);
        rb_define_method(c_environment, "distribution", environment_distribution, 0);
        rb_define_method(c_environment, "accept_license", environment_accept_license, 2);
        rb_define_method(c_environment, "accept_keywords", environment_accept_keywords, 2);
        rb_define_method(c_environment, "mirrors", environment_mirrors, 1);
        rb_define_method(c_environment, "[]", environment_square_brackets, 1);
        rb_define_method(c_environment, "format_key",                EnvironmentKey<MetadataValueKey<std::string> , Environment::format_key>::fetch, 0);
        rb_define_method(c_environment, "config_location_key",                template_methods, 0);
        rb_define_method(c_environment, "preferred_root_key",                template_methods, 0);
        rb_define_method(c_environment, "fetch_unique_qualified_package_name",                environment_fetch_unique_qualified_package_name, -1);
        rb_define_method(c_environment, "repositories",                environment_repositories, 0);
        rb_define_method(c_environment, "fetch_repository",                environment_fetch_repository, 1);
        rb_define_method(c_environment, "more_important_than",                environment_more_important_than, 2);
        rb_define_method(c_environment, "has_repository_named?",                environment_has_repository_named, 1);
        rb_define_method(c_environment, "add_repository",                environment_add_repository, 2);

        /*
         * Document-class: Paludis::PaludisEnvironment
         *
         * An Environment that corresponds to the normal operating evironment.
         */
        c_paludis_environment = rb_define_class_under(c_paludis_module, "PaludisEnvironment", c_environment);
        rb_define_singleton_method(c_paludis_environment, "new", paludis_environment_new, -1);
        rb_define_method(c_paludis_environment, "initialize", paludis_environment_init, -1);
        rb_define_method(c_paludis_environment, "config_dir", paludis_environment_config_dir, 0);

        /*
         * Document-class: Paludis::TestEnvironment
         *
         * A crude test environment.
         */
        c_test_environment = rb_define_class_under(c_paludis_module, "TestEnvironment", c_environment);
        rb_define_singleton_method(c_test_environment, "new", test_environment_new, 0);

        /*
         * Document-class: Paludis::EnvironmentFactory
         *
         * A class that holds methods to create environments.
         *
         * To access the default environment use create("")
         */
        c_environment_factory = rb_define_class_under(c_paludis_module, "EnvironmentFactory", rb_cObject);
        rb_funcall(rb_const_get(rb_cObject, rb_intern("Singleton")), rb_intern("included"), 1, c_environment_factory);
        rb_define_method(c_environment_factory, "create", environment_factory_create, 1);
    }
}
more_important_than(repository_name_a, repository_name_b) → bool click to toggle source

True if repository_name_a is more important than repository_name_b .

VALUE
    environment_more_important_than(VALUE self, VALUE name1, VALUE name2)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return (*self_ptr)->more_important_than(RepositoryName(StringValuePtr(name1)),
                    RepositoryName(StringValuePtr(name2))) ? Qtrue : Qfalse;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     has_repository_named?(repository_name) -> true or false
     *
     *  Do we have a named repository?
     */
    VALUE
    environment_has_repository_named(VALUE self, VALUE name)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return ((*self_ptr)->has_repository_named(RepositoryName(StringValuePtr(name)))) ? true : false;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     add_repository(importance, repository) -> nil
     *
     *  Add a repository.
     */
    VALUE
    environment_add_repository(VALUE self, VALUE importance, VALUE repo_v)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            std::shared_ptr<Repository> repo(value_to_repository(repo_v));

            (*self_ptr)->add_repository(NUM2INT(importance), repo);
            return Qnil;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }


    void do_register_environment()
    {
        rb_require("singleton");

        /*
         * Document-class: Paludis::Environment
         *
         * Represents a working environment, which contains an available packages database and provides
         * various methods for querying package visibility and options.
         */
        c_environment = rb_define_class_under(c_paludis_module, "Environment", rb_cObject);
        rb_funcall(c_environment, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        rb_define_method(c_environment, "set", environment_set, 1);
        rb_define_method(c_environment, "distribution", environment_distribution, 0);
        rb_define_method(c_environment, "accept_license", environment_accept_license, 2);
        rb_define_method(c_environment, "accept_keywords", environment_accept_keywords, 2);
        rb_define_method(c_environment, "mirrors", environment_mirrors, 1);
        rb_define_method(c_environment, "[]", environment_square_brackets, 1);
        rb_define_method(c_environment, "format_key",                EnvironmentKey<MetadataValueKey<std::string> , Environment::format_key>::fetch, 0);
        rb_define_method(c_environment, "config_location_key",                template_methods, 0);
        rb_define_method(c_environment, "preferred_root_key",                template_methods, 0);
        rb_define_method(c_environment, "fetch_unique_qualified_package_name",                environment_fetch_unique_qualified_package_name, -1);
        rb_define_method(c_environment, "repositories",                environment_repositories, 0);
        rb_define_method(c_environment, "fetch_repository",                environment_fetch_repository, 1);
        rb_define_method(c_environment, "more_important_than",                environment_more_important_than, 2);
        rb_define_method(c_environment, "has_repository_named?",                environment_has_repository_named, 1);
        rb_define_method(c_environment, "add_repository",                environment_add_repository, 2);

        /*
         * Document-class: Paludis::PaludisEnvironment
         *
         * An Environment that corresponds to the normal operating evironment.
         */
        c_paludis_environment = rb_define_class_under(c_paludis_module, "PaludisEnvironment", c_environment);
        rb_define_singleton_method(c_paludis_environment, "new", paludis_environment_new, -1);
        rb_define_method(c_paludis_environment, "initialize", paludis_environment_init, -1);
        rb_define_method(c_paludis_environment, "config_dir", paludis_environment_config_dir, 0);

        /*
         * Document-class: Paludis::TestEnvironment
         *
         * A crude test environment.
         */
        c_test_environment = rb_define_class_under(c_paludis_module, "TestEnvironment", c_environment);
        rb_define_singleton_method(c_test_environment, "new", test_environment_new, 0);

        /*
         * Document-class: Paludis::EnvironmentFactory
         *
         * A class that holds methods to create environments.
         *
         * To access the default environment use create("")
         */
        c_environment_factory = rb_define_class_under(c_paludis_module, "EnvironmentFactory", rb_cObject);
        rb_funcall(rb_const_get(rb_cObject, rb_intern("Singleton")), rb_intern("included"), 1, c_environment_factory);
        rb_define_method(c_environment_factory, "create", environment_factory_create, 1);
    }
}
repositories → Array click to toggle source
repositories {|repository| block } → Nil

Returns all the repositories in the package database, either as an Array, or as the parameters to a block.

VALUE
    environment_repositories(VALUE self)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            if (rb_block_given_p())
            {
                for (Environment::RepositoryConstIterator r((*self_ptr)->begin_repositories()),
                        r_end((*self_ptr)->end_repositories()) ; r != r_end ; ++r)
                    rb_yield(repository_to_value(*r));
                return Qnil;
            }
            VALUE result(rb_ary_new());
            for (Environment::RepositoryConstIterator r((*self_ptr)->begin_repositories()),
                    r_end((*self_ptr)->end_repositories()) ; r != r_end ; ++r)
                rb_ary_push(result, repository_to_value(*r));

            return result;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     fetch_repository(repository_name) -> Repository
     *
     *  Fetch a named repository.
     */
    VALUE
    environment_fetch_repository(VALUE self, VALUE name)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return repository_to_value((*self_ptr)->fetch_repository(RepositoryName(StringValuePtr(name))));
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     more_important_than(repository_name_a, repository_name_b) -> bool
     *
     * True if repository_name_a is more important than repository_name_b .
     */
    VALUE
    environment_more_important_than(VALUE self, VALUE name1, VALUE name2)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return (*self_ptr)->more_important_than(RepositoryName(StringValuePtr(name1)),
                    RepositoryName(StringValuePtr(name2))) ? Qtrue : Qfalse;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     has_repository_named?(repository_name) -> true or false
     *
     *  Do we have a named repository?
     */
    VALUE
    environment_has_repository_named(VALUE self, VALUE name)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return ((*self_ptr)->has_repository_named(RepositoryName(StringValuePtr(name)))) ? true : false;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     add_repository(importance, repository) -> nil
     *
     *  Add a repository.
     */
    VALUE
    environment_add_repository(VALUE self, VALUE importance, VALUE repo_v)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            std::shared_ptr<Repository> repo(value_to_repository(repo_v));

            (*self_ptr)->add_repository(NUM2INT(importance), repo);
            return Qnil;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }


    void do_register_environment()
    {
        rb_require("singleton");

        /*
         * Document-class: Paludis::Environment
         *
         * Represents a working environment, which contains an available packages database and provides
         * various methods for querying package visibility and options.
         */
        c_environment = rb_define_class_under(c_paludis_module, "Environment", rb_cObject);
        rb_funcall(c_environment, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        rb_define_method(c_environment, "set", environment_set, 1);
        rb_define_method(c_environment, "distribution", environment_distribution, 0);
        rb_define_method(c_environment, "accept_license", environment_accept_license, 2);
        rb_define_method(c_environment, "accept_keywords", environment_accept_keywords, 2);
        rb_define_method(c_environment, "mirrors", environment_mirrors, 1);
        rb_define_method(c_environment, "[]", environment_square_brackets, 1);
        rb_define_method(c_environment, "format_key",                EnvironmentKey<MetadataValueKey<std::string> , Environment::format_key>::fetch, 0);
        rb_define_method(c_environment, "config_location_key",                template_methods, 0);
        rb_define_method(c_environment, "preferred_root_key",                template_methods, 0);
        rb_define_method(c_environment, "fetch_unique_qualified_package_name",                environment_fetch_unique_qualified_package_name, -1);
        rb_define_method(c_environment, "repositories",                environment_repositories, 0);
        rb_define_method(c_environment, "fetch_repository",                environment_fetch_repository, 1);
        rb_define_method(c_environment, "more_important_than",                environment_more_important_than, 2);
        rb_define_method(c_environment, "has_repository_named?",                environment_has_repository_named, 1);
        rb_define_method(c_environment, "add_repository",                environment_add_repository, 2);

        /*
         * Document-class: Paludis::PaludisEnvironment
         *
         * An Environment that corresponds to the normal operating evironment.
         */
        c_paludis_environment = rb_define_class_under(c_paludis_module, "PaludisEnvironment", c_environment);
        rb_define_singleton_method(c_paludis_environment, "new", paludis_environment_new, -1);
        rb_define_method(c_paludis_environment, "initialize", paludis_environment_init, -1);
        rb_define_method(c_paludis_environment, "config_dir", paludis_environment_config_dir, 0);

        /*
         * Document-class: Paludis::TestEnvironment
         *
         * A crude test environment.
         */
        c_test_environment = rb_define_class_under(c_paludis_module, "TestEnvironment", c_environment);
        rb_define_singleton_method(c_test_environment, "new", test_environment_new, 0);

        /*
         * Document-class: Paludis::EnvironmentFactory
         *
         * A class that holds methods to create environments.
         *
         * To access the default environment use create("")
         */
        c_environment_factory = rb_define_class_under(c_paludis_module, "EnvironmentFactory", rb_cObject);
        rb_funcall(rb_const_get(rb_cObject, rb_intern("Singleton")), rb_intern("included"), 1, c_environment_factory);
        rb_define_method(c_environment_factory, "create", environment_factory_create, 1);
    }
}
set(set_name) → DepSpec click to toggle source

Fetch a named package set as a DepSpec.

VALUE
    environment_set(VALUE self, VALUE set_name)
    {
        try
        {
            SetName s(StringValuePtr(set_name));
            std::shared_ptr<const SetSpecTree> set = (value_to_environment(self)->set(s));
            if (set)
                return dep_tree_to_value<SetSpecTree>(set);
            else
                return Qnil;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     accept_license(license, package_id) -> true or false
     *
     * Do we accept a particular license for a particular package?
     */

    VALUE
    environment_accept_license(VALUE self, VALUE license, VALUE p)
    {
        try
        {
            return value_to_environment(self)->accept_license(
                    std::string(StringValuePtr(license)), (value_to_package_id(p))) ? Qtrue : Qfalse;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     accept_keywords(keywords, package_id) -> true or false
     *
     * Do we accept any of the specified keywords for a particular package?
     */

    VALUE
    environment_accept_keywords(VALUE self, VALUE keywords, VALUE p)
    {
        if (rb_obj_is_kind_of(keywords, rb_cArray))
        {
            try
            {
                std::shared_ptr<KeywordNameSet> knc (std::make_shared<KeywordNameSet>());
                long len = NUM2LONG(rb_funcall(keywords,rb_intern("length"),0));
                for (long i = 0; i < len; i++)
                {
                    // Stupid macros won't let me do it on one line.
                    VALUE kw = rb_ary_entry(keywords, i);
                    knc->insert(KeywordName(StringValuePtr(kw)));
                }
                return value_to_environment(self)->accept_keywords(knc, value_to_package_id(p)) ? Qtrue : Qfalse;
            }
            catch (const std::exception & e)
            {
                exception_to_ruby_exception(e);
            }
        }
        else
        {
            rb_raise(rb_eTypeError, "Can't convert %s into Array", rb_obj_classname(keywords));
        }
    }

    /*
     * call-seq:
     *     mirrors(mirror_name) -> Array
     *
     * Return the mirror URI prefixes for a named mirror.
     */
    VALUE
    environment_mirrors(VALUE self, VALUE mirror)
    {
        try
        {
            VALUE result(rb_ary_new());
            std::shared_ptr<const MirrorsSequence> m(value_to_environment(self)->mirrors(StringValuePtr(mirror)));
            for (MirrorsSequence::ConstIterator i(m->begin()), i_end(m->end()) ; i != i_end ; i++)
                rb_ary_push(result, rb_str_new2(stringify(*i).c_str()));
            return result;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    VALUE
    environment_distribution(VALUE self)
    {
        return rb_str_new2(value_to_environment(self)->distribution().c_str());

    }

    template <typename T_, const std::shared_ptr<const T_> (Environment::* m_) () const>
    struct EnvironmentKey
    {
        static VALUE
        fetch(VALUE self)
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);
            return (((**self_ptr).*m_)()) ? metadata_key_to_value(((**self_ptr).*m_)()) : Qnil;
        }
    };

    std::shared_ptr<PaludisEnvironment>
    value_to_paludis_environment(VALUE v)
    {
        if (rb_obj_is_kind_of(v, c_paludis_environment))
        {
            std::shared_ptr<Environment> * v_ptr;
            Data_Get_Struct(v, std::shared_ptr<Environment>, v_ptr);
            return std::static_pointer_cast<PaludisEnvironment>(*v_ptr);
        }
        else
        {
            rb_raise(rb_eTypeError, "Can't convert %s into PaludisEnvironment", rb_obj_classname(v));
        }
    }

    VALUE
    paludis_environment_init(int, VALUE*, VALUE self)
    {
        return self;
    }

    /*
     * call-seq:
     *     PaludisEnvironment.new -> PaludisEnvironment
     *     PaludisEnvironment.new(config_suffix) -> PaludisEnvironment
     *
     * Create a new PaludisEnvironment, with the specified config suffix if any, otherwise the empty suffix.
     */
    VALUE
    paludis_environment_new(int argc, VALUE* argv, VALUE self)
    {
        try
        {
            std::string config_suffix;
            if (1 == argc)
                config_suffix = StringValuePtr(argv[0]);
            else if (0 != argc)
                rb_raise(rb_eArgError, "PaludisEnvironment.new expects one or zero arguments, but got %d", argc);

            std::shared_ptr<Environment> * e = new std::shared_ptr<Environment>(std::make_shared<PaludisEnvironment>(config_suffix));
            VALUE tdata(Data_Wrap_Struct(self, 0, &Common<std::shared_ptr<Environment> >::free, e));
            rb_obj_call_init(tdata, argc, argv);
            return tdata;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     TestEnvironment.new -> TestEnvironment
     *
     * Create a new TestEnvironment.
     */
    VALUE
    test_environment_new(VALUE self)
    {
        try
        {
            std::shared_ptr<Environment> * e = new std::shared_ptr<Environment>(std::make_shared<TestEnvironment>());
            VALUE tdata(Data_Wrap_Struct(self, 0, &Common<std::shared_ptr<Environment> >::free, e));
            rb_obj_call_init(tdata, 0, &self);
            return tdata;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     config_dir -> String
     *
     * Configuration directory used by this PaludisEnvironment.
     */
    VALUE
    paludis_environment_config_dir(VALUE self)
    {
        return rb_str_new2(value_to_paludis_environment(self)->config_dir().c_str());
    }

    /*
     * call-seq:
     *     create(spec) -> Environment
     *
     * Create an environment from the given spec.
     * A spec consisits of <b>class:suffix</b> both of which may be omitted. <b>class</b> is the environment class,
     * e.g. paludis or portage, <b>suffix</b> is the configuration directory suffix.
     *
     */
    VALUE
    environment_factory_create(VALUE, VALUE spec)
    {
        try
        {
            std::shared_ptr<Environment> * e = new std::shared_ptr<Environment>(EnvironmentFactory::get_instance()->create(
                        StringValuePtr(spec)));

            VALUE tdata(Data_Wrap_Struct(c_environment, 0, &Common<std::shared_ptr<Environment> >::free, e));
            return tdata;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     fetch_unique_qualified_package_name(package_name) -> QualifiedPackageName
     *     fetch_unique_qualified_package_name(package_name, filter) -> QualifiedPackageName
     *
     * Disambiguate a package name.  If a filter is specified, limit
     * the potential results to packages that match.
     */
    VALUE
    environment_fetch_unique_qualified_package_name(int argc, VALUE *argv, VALUE self)
    {
        try
        {
            if (1 == argc || 2 == argc)
            {
                std::shared_ptr<Environment> * self_ptr;
                Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);
                return qualified_package_name_to_value((*self_ptr)->fetch_unique_qualified_package_name(
                                PackageNamePart(StringValuePtr(argv[0])), 2 == argc ? value_to_filter(argv[1]) : filter::All()));
            }
            else
                rb_raise(rb_eArgError, "fetch_unique_qualified_package_name expects one or two arguments, but got %d",argc);
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     repositories -> Array
     *     repositories {|repository| block } -> Nil
     *
     *  Returns all the repositories in the package database, either as an Array, or as
     *  the parameters to a block.
     */
    VALUE
    environment_repositories(VALUE self)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            if (rb_block_given_p())
            {
                for (Environment::RepositoryConstIterator r((*self_ptr)->begin_repositories()),
                        r_end((*self_ptr)->end_repositories()) ; r != r_end ; ++r)
                    rb_yield(repository_to_value(*r));
                return Qnil;
            }
            VALUE result(rb_ary_new());
            for (Environment::RepositoryConstIterator r((*self_ptr)->begin_repositories()),
                    r_end((*self_ptr)->end_repositories()) ; r != r_end ; ++r)
                rb_ary_push(result, repository_to_value(*r));

            return result;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     fetch_repository(repository_name) -> Repository
     *
     *  Fetch a named repository.
     */
    VALUE
    environment_fetch_repository(VALUE self, VALUE name)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return repository_to_value((*self_ptr)->fetch_repository(RepositoryName(StringValuePtr(name))));
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     more_important_than(repository_name_a, repository_name_b) -> bool
     *
     * True if repository_name_a is more important than repository_name_b .
     */
    VALUE
    environment_more_important_than(VALUE self, VALUE name1, VALUE name2)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return (*self_ptr)->more_important_than(RepositoryName(StringValuePtr(name1)),
                    RepositoryName(StringValuePtr(name2))) ? Qtrue : Qfalse;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     has_repository_named?(repository_name) -> true or false
     *
     *  Do we have a named repository?
     */
    VALUE
    environment_has_repository_named(VALUE self, VALUE name)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            return ((*self_ptr)->has_repository_named(RepositoryName(StringValuePtr(name)))) ? true : false;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     add_repository(importance, repository) -> nil
     *
     *  Add a repository.
     */
    VALUE
    environment_add_repository(VALUE self, VALUE importance, VALUE repo_v)
    {
        try
        {
            std::shared_ptr<Environment> * self_ptr;
            Data_Get_Struct(self, std::shared_ptr<Environment>, self_ptr);

            std::shared_ptr<Repository> repo(value_to_repository(repo_v));

            (*self_ptr)->add_repository(NUM2INT(importance), repo);
            return Qnil;
        }
        catch (const std::exception & e)
        {
            exception_to_ruby_exception(e);
        }
    }


    void do_register_environment()
    {
        rb_require("singleton");

        /*
         * Document-class: Paludis::Environment
         *
         * Represents a working environment, which contains an available packages database and provides
         * various methods for querying package visibility and options.
         */
        c_environment = rb_define_class_under(c_paludis_module, "Environment", rb_cObject);
        rb_funcall(c_environment, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        rb_define_method(c_environment, "set", environment_set, 1);
        rb_define_method(c_environment, "distribution", environment_distribution, 0);
        rb_define_method(c_environment, "accept_license", environment_accept_license, 2);
        rb_define_method(c_environment, "accept_keywords", environment_accept_keywords, 2);
        rb_define_method(c_environment, "mirrors", environment_mirrors, 1);
        rb_define_method(c_environment, "[]", environment_square_brackets, 1);
        rb_define_method(c_environment, "format_key",                EnvironmentKey<MetadataValueKey<std::string> , Environment::format_key>::fetch, 0);
        rb_define_method(c_environment, "config_location_key",                template_methods, 0);
        rb_define_method(c_environment, "preferred_root_key",                template_methods, 0);
        rb_define_method(c_environment, "fetch_unique_qualified_package_name",                environment_fetch_unique_qualified_package_name, -1);
        rb_define_method(c_environment, "repositories",                environment_repositories, 0);
        rb_define_method(c_environment, "fetch_repository",                environment_fetch_repository, 1);
        rb_define_method(c_environment, "more_important_than",                environment_more_important_than, 2);
        rb_define_method(c_environment, "has_repository_named?",                environment_has_repository_named, 1);
        rb_define_method(c_environment, "add_repository",                environment_add_repository, 2);

        /*
         * Document-class: Paludis::PaludisEnvironment
         *
         * An Environment that corresponds to the normal operating evironment.
         */
        c_paludis_environment = rb_define_class_under(c_paludis_module, "PaludisEnvironment", c_environment);
        rb_define_singleton_method(c_paludis_environment, "new", paludis_environment_new, -1);
        rb_define_method(c_paludis_environment, "initialize", paludis_environment_init, -1);
        rb_define_method(c_paludis_environment, "config_dir", paludis_environment_config_dir, 0);

        /*
         * Document-class: Paludis::TestEnvironment
         *
         * A crude test environment.
         */
        c_test_environment = rb_define_class_under(c_paludis_module, "TestEnvironment", c_environment);
        rb_define_singleton_method(c_test_environment, "new", test_environment_new, 0);

        /*
         * Document-class: Paludis::EnvironmentFactory
         *
         * A class that holds methods to create environments.
         *
         * To access the default environment use create("")
         */
        c_environment_factory = rb_define_class_under(c_paludis_module, "EnvironmentFactory", rb_cObject);
        rb_funcall(rb_const_get(rb_cObject, rb_intern("Singleton")), rb_intern("included"), 1, c_environment_factory);
        rb_define_method(c_environment_factory, "create", environment_factory_create, 1);
    }
}