Now it's also possible to supply arrays via e.g.:
require foo [ bar=[ 1 2 "3 3" ] ]
or equivalently:
require foo [[ bar=[[ 1 2 "3 3" ]] ]]
Allowing the latter notation makes it possible to have a regular variable with
the value "[":
require foo [[ bar=[ ]]
Arrays must be declared either as required via e.g.:
myexparam bar[]
or as optional with a default value via e.g.:
myexparam bar=[ 1 2 "3 3" ]
Furthermore unit tests are now included in the attached patch.
Unfortunately due to a limitation in bash and the way this is implemented,
using exparam to access a variable in a subshell from a function that is
called outside global scope will not work. So this code for example:
foo_pkg_setup() {
var=$(exparam bar)
}
will result in the error message "exparam is banned outside exlibs". Therefore
this patch allows us to access a variable with this code:
foo_pkg_setup() {
exparam -v var bar
}
which assigns the value of bar (or bar[0] in case bar is an exlib array) to
the variable var. To access an array one can either use an index (exparam
bar[0], exparam bar[1], etc.) or transfer all elements of bar to an array:
foo_pkg_setup() {
exparam -a array bar[*]
}
The number of elements can be retrieved via exparam bar[#] and exparam bar is
equivalent to exparam bar[0]. Any exparam command allows -v or -a arguments to
assign the output to a variable or an array.
--
Bo Andresen
diff --git a/paludis/repositories/e/Makefile.am b/paludis/repositories/e/Makefile.am
index 402a30e..033741e 100644
--- a/paludis/repositories/e/Makefile.am
+++ b/paludis/repositories/e/Makefile.am
@@ -177,6 +177,20 @@ e_repository_TEST_ever_LDADD = \
e_repository_TEST_ever_CXXFLAGS = $(AM_CXXFLAGS) -I$(top_srcdir) @PALUDIS_CXXFLAGS_NO_DEBUGGING@
+e_repository_TEST_exlibs = e_repository_TEST_exlibs.cc
+
+e_repository_TEST_exlibs_LDADD = \
+ libpaludisereposito...@[email protected] \
+ $(top_builddir)/paludis/repositories/fake/libpaludisfakereposito...@[email protected] \
+ $(top_builddir)/paludis/util/libpaludisut...@[email protected] \
+ $(top_builddir)/paludis/util/test_extras.o \
+ $(top_builddir)/paludis/libpalud...@[email protected] \
+ $(top_builddir)/paludis/environments/test/libpaludistestenvironme...@[email protected] \
+ $(top_builddir)/test/libtest.a \
+ $(DYNAMIC_LD_LIBS)
+
+e_repository_TEST_exlibs_CXXFLAGS = $(AM_CXXFLAGS) -I$(top_srcdir) @PALUDIS_CXXFLAGS_NO_DEBUGGING@
+
vdb_repository_TEST_SOURCES = vdb_repository_TEST.cc
vdb_repository_TEST_LDADD = \
@@ -357,6 +371,9 @@ EXTRA_DIST = \
e_repository_TEST_ever.cc \
e_repository_TEST_ever_setup.sh \
e_repository_TEST_ever_cleanup.sh \
+ e_repository_TEST_exlibs.cc \
+ e_repository_TEST_exlibs_setup.sh \
+ e_repository_TEST_exlibs_cleanup.sh \
e_repository_params-se.hh \
e_repository_params-se.cc \
e_repository_params.se \
@@ -401,6 +418,7 @@ BUILT_SOURCES = \
check_SCRIPTS = \
e_repository_TEST_setup.sh e_repository_TEST_cleanup.sh \
e_repository_TEST_ever_setup.sh e_repository_TEST_ever_cleanup.sh \
+ e_repository_TEST_exlibs_setup.sh e_repository_TEST_exlibs_cleanup.sh \
xml_things_TEST_setup.sh xml_things_TEST_cleanup.sh \
vdb_repository_TEST_setup.sh vdb_repository_TEST_cleanup.sh \
exndbam_repository_TEST_setup.sh exndbam_repository_TEST_cleanup.sh \
@@ -488,6 +506,7 @@ TESTS = \
dep_spec_pretty_printer_TEST \
e_repository_TEST \
e_repository_TEST_ever \
+ e_repository_TEST_exlibs \
e_repository_sets_TEST \
ebuild_flat_metadata_cache_TEST \
exndbam_repository_TEST \
diff --git a/paludis/repositories/e/e_repository_TEST_exlibs.cc b/paludis/repositories/e/e_repository_TEST_exlibs.cc
new file mode 100644
index 0000000..8ac1b8a
--- /dev/null
+++ b/paludis/repositories/e/e_repository_TEST_exlibs.cc
@@ -0,0 +1,182 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008, 2009 Ciaran McCreesh
+ * Copyright (c) 2009 Bo Ãrsted Andresen
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/repositories/e/e_repository.hh>
+#include <paludis/repositories/e/e_repository_exceptions.hh>
+#include <paludis/repositories/e/e_repository_id.hh>
+#include <paludis/repositories/e/vdb_repository.hh>
+#include <paludis/repositories/e/eapi.hh>
+#include <paludis/repositories/e/dep_spec_pretty_printer.hh>
+#include <paludis/repositories/fake/fake_installed_repository.hh>
+#include <paludis/repositories/fake/fake_package_id.hh>
+#include <paludis/environments/test/test_environment.hh>
+#include <paludis/util/system.hh>
+#include <paludis/util/simple_visitor_cast.hh>
+#include <paludis/util/map.hh>
+#include <paludis/util/make_shared_ptr.hh>
+#include <paludis/util/make_named_values.hh>
+#include <paludis/util/set.hh>
+#include <paludis/package_id.hh>
+#include <paludis/metadata_key.hh>
+#include <paludis/action.hh>
+#include <paludis/stringify_formatter.hh>
+#include <paludis/user_dep_spec.hh>
+#include <paludis/generator.hh>
+#include <paludis/filter.hh>
+#include <paludis/filtered_generator.hh>
+#include <paludis/selection.hh>
+#include <paludis/repository_factory.hh>
+#include <paludis/choice.hh>
+#include <test/test_framework.hh>
+#include <test/test_runner.hh>
+#include <tr1/functional>
+#include <set>
+#include <string>
+
+#include "config.h"
+
+using namespace test;
+using namespace paludis;
+
+namespace
+{
+ std::string from_keys(const std::tr1::shared_ptr<const Map<std::string, std::string> > & m,
+ const std::string & k)
+ {
+ Map<std::string, std::string>::ConstIterator mm(m->find(k));
+ if (m->end() == mm)
+ return "";
+ else
+ return mm->second;
+ }
+
+ void dummy_used_this_for_config_protect(const std::string &)
+ {
+ }
+
+ WantPhase want_all_phases(const std::string &)
+ {
+ return wp_yes;
+ }
+
+ enum ExpectedResult
+ {
+ success,
+ throws_UnsupportedActionError,
+ throws_InstallActionError
+ };
+
+ struct ExlibsTest : TestCase
+ {
+ const std::string test;
+ int expected_result;
+
+ ExlibsTest(const std::string & s, const ExpectedResult e) :
+ TestCase(s),
+ test(s),
+ expected_result(e)
+ {
+ }
+
+ unsigned max_run_time() const
+ {
+ return 3000;
+ }
+
+ bool repeatable() const
+ {
+ return false;
+ }
+
+ void run()
+ {
+ TestEnvironment env;
+ env.set_paludis_command("/bin/false");
+ std::tr1::shared_ptr<Map<std::string, std::string> > keys(new Map<std::string, std::string>);
+ keys->insert("format", "ebuild");
+ keys->insert("names_cache", "/var/empty");
+ keys->insert("location", stringify(FSEntry::cwd() / "e_repository_TEST_exlibs_dir" / "repo1"));
+ keys->insert("profiles", stringify(FSEntry::cwd() / "e_repository_TEST_exlibs_dir" / "repo1/profiles/profile"));
+ keys->insert("layout", "exheres");
+ keys->insert("eapi_when_unknown", "exheres-0");
+ keys->insert("eapi_when_unspecified", "exheres-0");
+ keys->insert("profile_eapi", "exheres-0");
+ keys->insert("distdir", stringify(FSEntry::cwd() / "e_repository_TEST_exlibs_dir" / "distdir"));
+ keys->insert("builddir", stringify(FSEntry::cwd() / "e_repository_TEST_exlibs_dir" / "build"));
+ std::tr1::shared_ptr<Repository> repo(ERepository::repository_factory_create(&env,
+ std::tr1::bind(from_keys, keys, std::tr1::placeholders::_1)));
+ env.package_database()->add_repository(1, repo);
+
+ std::tr1::shared_ptr<FakeInstalledRepository> installed_repo(new FakeInstalledRepository(&env, RepositoryName("installed")));
+ env.package_database()->add_repository(2, installed_repo);
+
+ InstallAction action(make_named_values<InstallActionOptions>(
+ value_for<n::destination>(installed_repo),
+ value_for<n::used_this_for_config_protect>(&dummy_used_this_for_config_protect),
+ value_for<n::want_phase>(&want_all_phases)
+ ));
+
+ const std::tr1::shared_ptr<const PackageID> id(*env[selection::RequireExactlyOne(generator::Matches(
+ PackageDepSpec(parse_user_package_dep_spec("cat/" + test,
+ &env, UserPackageDepSpecOptions())), MatchPackageOptions()))]->last());
+ TEST_CHECK(id);
+ switch (expected_result)
+ {
+ case success:
+ id->perform_action(action);
+ break;
+ case throws_InstallActionError:
+ TEST_CHECK_THROWS(id->perform_action(action), InstallActionError);
+ break;
+ case throws_UnsupportedActionError:
+ TEST_CHECK_THROWS(id->perform_action(action), UnsupportedActionError);
+ break;
+ }
+ }
+ };
+}
+
+namespace test_cases
+{
+ ExlibsTest test_require_success("require-success", success);
+ ExlibsTest test_require_fail("require-fail", throws_UnsupportedActionError);
+ ExlibsTest test_require_param("require-param", success);
+ ExlibsTest test_require_param_empty("require-param-empty", success);
+ ExlibsTest test_require_param_missing("require-param-missing", throws_UnsupportedActionError);
+ ExlibsTest test_require_param_undeclared("require-param-undeclared", throws_UnsupportedActionError);
+ ExlibsTest test_require_params("require-params", success);
+ ExlibsTest test_require_params_unaligned("require-params-unaligned", throws_UnsupportedActionError);
+ ExlibsTest test_require_multiple_params("require-multiple-params", success);
+ ExlibsTest test_require_multiple_params_spaces("require-multiple-params-spaces", success);
+ ExlibsTest test_require_param_default("require-param-default", success);
+ ExlibsTest test_require_param_default_spaces("require-multiple-params-default-spaces", success);
+ ExlibsTest test_exparam_banned("exparam-banned", throws_UnsupportedActionError);
+ ExlibsTest test_exparam_undeclared("exparam-undeclared", throws_InstallActionError);
+ ExlibsTest test_exparam_subshell("exparam-subshell", throws_InstallActionError); // cookies to he who finds a way to make this test succeed :(
+ ExlibsTest test_exarray("exarray", success);
+ ExlibsTest test_exarray_spaces("exarray-spaces", success);
+ ExlibsTest test_exarray_default("exarray-default", success);
+ ExlibsTest test_exarray_default_spaces("exarray-default-spaces", success);
+ ExlibsTest test_noarray("noarray", success);
+ ExlibsTest test_noarray_bad("noarray-bad", throws_UnsupportedActionError);
+ ExlibsTest test_scalar_required("scalar-required", throws_UnsupportedActionError);
+ ExlibsTest test_array_required("array-required", throws_UnsupportedActionError);
+}
+
diff --git a/paludis/repositories/e/e_repository_TEST_exlibs_cleanup.sh b/paludis/repositories/e/e_repository_TEST_exlibs_cleanup.sh
new file mode 100755
index 0000000..df39b52
--- /dev/null
+++ b/paludis/repositories/e/e_repository_TEST_exlibs_cleanup.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+# vim: set ft=sh sw=4 sts=4 et :
+
+if [ -d e_repository_TEST_exlibs_dir ] ; then
+ rm -fr e_repository_TEST_exlibs_dir
+else
+ true
+fi
+
diff --git a/paludis/repositories/e/e_repository_TEST_exlibs_setup.sh b/paludis/repositories/e/e_repository_TEST_exlibs_setup.sh
new file mode 100755
index 0000000..f1099fd
--- /dev/null
+++ b/paludis/repositories/e/e_repository_TEST_exlibs_setup.sh
@@ -0,0 +1,381 @@
+#!/usr/bin/env bash
+# vim: set ft=sh sw=4 sts=4 et :
+
+mkdir e_repository_TEST_exlibs_dir || exit 1
+cd e_repository_TEST_exlibs_dir || exit 1
+
+mkdir -p root/etc
+
+mkdir -p vdb
+touch vdb/THISISTHEVDB
+
+mkdir -p build
+ln -s build symlinked_build
+
+mkdir -p distdir
+
+mkdir -p repo1/{profiles/profile,metadata,eclass} || exit 1
+cd repo1 || exit 1
+echo "test-repo-1" >> profiles/repo_name || exit 1
+echo "cat" >> metadata/categories.conf || exit 1
+cat <<END > profiles/profile/make.defaults
+CHOST="i286-badger-linux-gnu"
+SUBOPTIONS="LINGUAS"
+LINGUAS="en en_GB en...@utf-8"
+USERLAND="GNU"
+OPTIONS="weasel spinach"
+END
+mkdir -p "packages/cat/require-success"
+cat <<'END' > packages/cat/require-success/foo.exlib || exit 1
+DESCRIPTION="The Long Description"
+SUMMARY="The Short Description"
+HOMEPAGE="http://example.com/"
+SLOT="0"
+LICENCES="GPL-2"
+export_exlib_phases src_unpack
+
+foo_src_unpack() {
+ [[ ${FOO} == true ]] || die "FOO unset"
+ touch ${PN}.foo
+}
+END
+cat <<'END' > packages/cat/require-success/require-success-1.ebuild || exit 1
+require foo
+PLATFORMS="test"
+FOO=true
+
+src_install() {
+ [[ ${SUMMARY} == "The Short Description" ]] || die "Bad SUMMARY"
+ [[ -e ${PN}.foo ]] || die "foo_src_unpack did not run"
+}
+END
+mkdir -p "packages/cat/require-fail"
+cat <<'END' > packages/cat/require-fail/require-fail-1.ebuild || exit 1
+require non-existant
+PLATFORMS="test"
+END
+mkdir -p "exlibs"
+cat <<'END' > exlibs/foo.exlib || exit 1
+SUMMARY="Short description"
+SLOT="0"
+END
+cat <<'END' > exlibs/foo-bar.exlib || exit 1
+SLOT="0"
+myexparam bar
+SUMMARY=$(exparam bar)
+END
+cat <<'END' > exlibs/foo-bar-baz.exlib || exit 1
+SLOT="0"
+myexparam bar=baz
+SUMMARY=$(exparam bar)
+END
+cat <<'END' > exlibs/monkey.exlib
+myexparam blah
+DESCRIPTION=$(exparam blah)
+END
+mkdir -p "packages/cat/require-param"
+cat <<'END' > packages/cat/require-param/require-param-1.ebuild || exit 1
+require foo-bar [ bar=baz ]
+PLATFORMS="test"
+
+pkg_setup() {
+ [[ ${SUMMARY} == baz ]] || die "Bad SUMMARY"
+}
+END
+mkdir -p "packages/cat/require-param-empty"
+cat <<'END' > packages/cat/require-param-empty/require-param-empty-1.ebuild || exit 1
+require foo-bar [ bar= ]
+PLATFORMS="test"
+
+pkg_setup() {
+ [[ -z ${SUMMARY} && ${SUMMARY+set} == set ]] || die "Bad SUMMARY"
+}
+END
+mkdir -p "packages/cat/require-param-missing"
+cat <<'END' > packages/cat/require-param-missing/require-param-missing-1.ebuild || exit 1
+require foo-bar
+PLATFORMS="test"
+END
+mkdir -p "packages/cat/require-param-undeclared"
+cat <<'END' > packages/cat/require-param-undeclared/require-param-undeclared-1.ebuild || exit 1
+require foo [ bar=baz ]
+PLATFORMS="test"
+END
+mkdir -p "packages/cat/require-params"
+cat <<'END' > packages/cat/require-params/require-params-1.ebuild || exit 1
+require foo-bar [[[ bar=baz ]]] monkey [ blah=bleh ]
+PLATFORMS="test"
+
+pkg_setup() {
+ [[ ${SUMMARY} == baz ]] || die "Bad SUMMARY"
+ [[ ${DESCRIPTION} == bleh ]] || die "Bad DESCRIPTION"
+}
+END
+mkdir -p "packages/cat/require-params-unaligned"
+cat <<'END' > packages/cat/require-params-unaligned/require-params-unaligned-1.ebuild || exit 1
+require foo-bar [[[ bar=baz ] monkey [ blah=bleh ]
+PLATFORMS="test"
+
+pkg_setup() {
+ [[ ${SUMMARY} == baz ]] || die "Bad SUMMARY"
+ [[ ${DESCRIPTION} == bleh ]] || die "Bad DESCRIPTION"
+}
+END
+mkdir -p "packages/cat/require-multiple-params"
+cat <<'END' > packages/cat/require-multiple-params/foo.exlib || exit 1
+myexparam foo
+myexparam bar
+SUMMARY=$(exparam foo)$(exparam bar)
+END
+cat <<'END' > packages/cat/require-multiple-params/require-multiple-params-1.ebuild || exit 1
+require foo [ foo=1 bar=2 ]
+PLATFORMS="test"
+
+pkg_setup() {
+ [[ ${SUMMARY} == 12 ]] || die "Bad SUMMARY"
+}
+END
+mkdir -p "packages/cat/require-multiple-params-spaces"
+cat <<'END' > packages/cat/require-multiple-params-spaces/foo.exlib || exit 1
+myexparam foo
+myexparam bar
+SUMMARY=$(exparam foo)-$(exparam bar)
+END
+cat <<'END' > packages/cat/require-multiple-params-spaces/require-multiple-params-spaces-1.ebuild || exit 1
+require foo [ foo="f o o " bar=" b a r" ]
+PLATFORMS="test"
+
+pkg_setup() {
+ [[ ${SUMMARY} == "f o o - b a r" ]] || die "Bad SUMMARY"
+}
+END
+mkdir -p "packages/cat/require-param-default"
+cat <<'END' > packages/cat/require-param-default/require-param-default-1.ebuild || exit 1
+require foo-bar-baz
+PLATFORMS="test"
+
+pkg_setup() {
+ [[ ${SUMMARY} == baz ]] || die "Bad SUMMARY"
+}
+END
+mkdir -p "packages/cat/require-multiple-params-default-spaces"
+cat <<'END' > packages/cat/require-multiple-params-default-spaces/foo.exlib || exit 1
+myexparam foo="f o o "
+myexparam bar=" b a r"
+SUMMARY=$(exparam foo)-$(exparam bar)
+END
+cat <<'END' > packages/cat/require-multiple-params-default-spaces/require-multiple-params-default-spaces-1.ebuild || exit 1
+require foo
+PLATFORMS="test"
+
+pkg_setup() {
+ [[ ${SUMMARY} == "f o o - b a r" ]] || die "Bad SUMMARY"
+}
+END
+mkdir -p "packages/cat/exparam-banned"
+cat <<'END' > packages/cat/exparam-banned/exparam-banned-1.ebuild || exit 1
+PLATFORMS="test"
+exparam foo
+END
+mkdir -p "packages/cat/exparam-undeclared"
+cat <<'END' > packages/cat/exparam-undeclared/foo.exlib || exit 1
+get_bar() {
+ exparam bar
+}
+END
+cat <<'END' > packages/cat/exparam-undeclared/exparam-undeclared-1.ebuild || exit 1
+require foo
+PLATFORMS="test"
+
+pkg_setup() {
+ [[ $(get_bar) == baz ]]
+}
+END
+mkdir -p "packages/cat/exparam-subshell"
+cat <<'END' > packages/cat/exparam-subshell/foo.exlib || exit 1
+myexparam bar
+check_bar() {
+ [[ $(exparam bar) == baz ]] || die "exparam in subshell failed"
+}
+END
+cat <<'END' > packages/cat/exparam-subshell/exparam-subshell-1.ebuild || exit 1
+require foo [ bar=baz ]
+
+pkg_setup() {
+ check_bar
+}
+END
+mkdir -p "packages/cat/exarray"
+cat <<'END' > packages/cat/exarray/foo.exlib || exit 1
+myexparam bar[]
+
+check_foo() {
+ exparam bar[#] | grep -q ^3$ || die "Bad bar[#]"
+ exparam bar[0] | grep -q ^1$ || die "Bad bar[0]"
+ exparam bar[1] | grep -q ^2$ || die "Bad bar[1]"
+ exparam bar[2] | grep -q ^3$ || die "Bad bar[2]"
+ exparam bar[3] | grep -q ^$ || die "Bad bar[3]"
+ exparam -a FOOA bar[*]
+ exparam -v FOOV bar[*]
+ exparam -a FOOA0 bar
+ exparam -v FOO bar
+ exparam -v FOO0 bar[0]
+ exparam -v FOO1 bar[1]
+ exparam -v FOO2 bar[2]
+ exparam -v FOO3 bar[3]
+ exparam -v FOOC bar[#]
+}
+END
+cat <<'END' > packages/cat/exarray/exarray-1.ebuild || exit 1
+require foo [ bar=[ 1 2 3 ] ]
+PLATFORMS="test"
+
+pkg_setup() {
+ check_foo || die "check_foo returned errror"
+ [[ ${#fo...@]} -eq 3 ]] || die "Wrong number of elements, ${#fo...@]} in fo...@]"
+ [[ ${FOOA[0]} == 1 ]] || die "Bad FOOA[0]"
+ [[ ${FOOA[1]} == 2 ]] || die "Bad FOOA[1]"
+ [[ ${FOOA[2]} == 3 ]] || die "Bad FOOA[2]"
+ [[ ${fo...@]} == "1 2 3" ]] || die "fo...@] != 1 2 3"
+ [[ ${#fo...@]} -eq 1 ]] || die "Wrong number of elements, ${#fo...@]} in fo...@]"
+ [[ ${fo...@]} == "1 2 3" ]] || die "fo...@] != 1 2 3"
+ [[ ${FOOA0} == 1 ]] || die "Bad FOOA0"
+ [[ $(declare -p FOOA0) == declare\ -a\ FOOA0=* ]] || die "FOOA0 is not an array"
+ [[ ${FOO} == 1 ]] || die "Bad FOO"
+ [[ ${FOO0} == 1 ]] || die "Bad FOO0"
+ [[ ${FOO1} == 2 ]] || die "Bad FOO1"
+ [[ ${FOO2} == 3 ]] || die "Bad FOO2"
+ [[ -z ${FOO3} ]] || die "Bad FOO3"
+ [[ ${FOOC} -eq 3 ]] || die "Bad FOOC"
+}
+END
+mkdir -p "packages/cat/exarray-spaces"
+cat <<'END' > packages/cat/exarray-spaces/foo.exlib || exit 1
+myexparam bar[]
+
+check_foo() {
+ exparam bar[#] | grep -q ^3$ || die "Bad bar[#]"
+ exparam bar[0] | grep -q '^1 1$' || die "Bad bar[0]"
+ exparam bar[1] | grep -q '^2 2$' || die "Bad bar[1]"
+ exparam bar[2] | grep -q '^3 3$' || die "Bad bar[2]"
+ exparam bar[3] | grep -q ^$ || die "Bad bar[3]"
+ exparam -a FOO bar[*]
+}
+END
+cat <<'END' > packages/cat/exarray-spaces/exarray-spaces-1.ebuild || exit 1
+require foo [ bar=[ "1 1" "2 2" "3 3" ] ]
+PLATFORMS="test"
+
+pkg_setup() {
+ check_foo || die "check_foo returned errror"
+ [[ ${#f...@]} -eq 3 ]] || die "Wrong number of elements, ${#f...@]} in f...@]"
+ [[ ${FOO[0]} == "1 1" ]] || die "Bad FOO[0]"
+ [[ ${FOO[1]} == "2 2" ]] || die "Bad FOO[1]"
+ [[ ${FOO[2]} == "3 3" ]] || die "Bad FOO[2]"
+ [[ ${f...@]} == "1 1 2 2 3 3" ]] || die "f...@] != 1 1 2 2 3 3"
+}
+END
+mkdir -p "packages/cat/exarray-default"
+cat <<'END' > packages/cat/exarray-default/foo.exlib || exit 1
+myexparam bar=[ 1 2 3 ]
+
+check_foo() {
+ exparam bar[#] | grep -q ^3$ || die "Bad bar[#]"
+ exparam bar[0] | grep -q ^1$ || die "Bad bar[0]"
+ exparam bar[1] | grep -q ^2$ || die "Bad bar[1]"
+ exparam bar[2] | grep -q ^3$ || die "Bad bar[2]"
+ exparam bar[3] | grep -q ^$ || die "Bad bar[3]"
+ exparam -a FOO bar[*]
+}
+END
+cat <<'END' > packages/cat/exarray-default/exarray-default-1.ebuild || exit 1
+require foo
+PLATFORMS="test"
+
+pkg_setup() {
+ check_foo || die "check_foo returned errror"
+ [[ ${#f...@]} -eq 3 ]] || die "Wrong number of elements, ${#f...@]} in f...@]"
+ [[ ${FOO[0]} == 1 ]] || die "Bad FOO[0]"
+ [[ ${FOO[1]} == 2 ]] || die "Bad FOO[1]"
+ [[ ${FOO[2]} == 3 ]] || die "Bad FOO[2]"
+ [[ ${f...@]} == "1 2 3" ]] || die "f...@] != 1 2 3"
+}
+END
+mkdir -p "packages/cat/exarray-default-spaces"
+cat <<'END' > packages/cat/exarray-default-spaces/foo.exlib || exit 1
+myexparam bar=[ "1 1" "2 2" "3 3" ]
+
+check_foo() {
+ exparam bar[#] | grep -q ^3$ || die "Bad bar[#]"
+ exparam bar[0] | grep -q '^1 1$' || die "Bad bar[0]"
+ exparam bar[1] | grep -q '^2 2$' || die "Bad bar[1]"
+ exparam bar[2] | grep -q '^3 3$' || die "Bad bar[2]"
+ exparam bar[3] | grep -q ^$ || die "Bad bar[3]"
+ exparam -a FOO bar[*]
+}
+END
+cat <<'END' > packages/cat/exarray-default-spaces/exarray-default-spaces-1.ebuild || exit 1
+require foo
+PLATFORMS="test"
+
+pkg_setup() {
+ check_foo || die "check_foo returned errror"
+ [[ ${#f...@]} -eq 3 ]] || die "Wrong number of elements, ${#f...@]} in f...@]"
+ [[ ${FOO[0]} == "1 1" ]] || die "Bad FOO[0]"
+ [[ ${FOO[1]} == "2 2" ]] || die "Bad FOO[1]"
+ [[ ${FOO[2]} == "3 3" ]] || die "Bad FOO[2]"
+ [[ ${f...@]} == "1 1 2 2 3 3" ]] || die "f...@] != 1 1 2 2 3 3"
+}
+END
+mkdir -p "packages/cat/noarray"
+cat <<'END' > packages/cat/noarray/foo.exlib || exit 1
+myexparam bar
+SUMMARY=$(exparam bar)
+END
+cat <<'END' > packages/cat/noarray/noarray-1.ebuild || exit 1
+require foo [[ bar=[ ]]
+
+pkg_setup() {
+ [[ ${SUMMARY} == "[" ]] || die "Bad SUMMARY"
+}
+END
+mkdir -p "packages/cat/noarray-bad"
+cat <<'END' > packages/cat/noarray-bad/foo.exlib || exit 1
+myexparam bar
+SUMMARY=$(exparam bar)
+END
+cat <<'END' > packages/cat/noarray-bad/noarray-bad-1.ebuild || exit 1
+require foo [ bar=[ ]
+
+pkg_setup() {
+ [[ ${SUMMARY} == "[" ]] || die "Bad SUMMARY"
+}
+END
+mkdir -p "packages/cat/scalar-required"
+cat <<'END' > packages/cat/scalar-required/foo.exlib || exit 1
+myexparam bar
+SUMMARY=$(exparam bar)
+END
+cat <<'END' > packages/cat/scalar-required/scalar-required-1.ebuild || exit 1
+require foo [ bar=[ baz ] ]
+
+pkg_setup() {
+ [[ ${SUMMARY} == "baz" ]] || die "Bad SUMMARY"
+}
+END
+mkdir -p "packages/cat/array-required"
+cat <<'END' > packages/cat/array-required/foo.exlib || exit 1
+myexparam bar[]
+SUMMARY=$(exparam bar)
+END
+cat <<'END' > packages/cat/array-required/array-required-1.ebuild || exit 1
+require foo [ bar=baz ]
+
+pkg_setup() {
+ [[ ${SUMMARY} == "baz" ]] || die "Bad SUMMARY"
+}
+END
+cd ..
+
+cd ..
+
diff --git a/paludis/repositories/e/ebuild/ebuild.bash b/paludis/repositories/e/ebuild/ebuild.bash
index 7853237..8fa7ca6 100755
--- a/paludis/repositories/e/ebuild/ebuild.bash
+++ b/paludis/repositories/e/ebuild/ebuild.bash
@@ -285,6 +285,7 @@ ebuild_scrub_environment()
echo E_${v}
done )
unset -v ${!PALUDIS_*}
+ unset -v ${!EXPARAMVAR_*}
unset -v $(
for v in ${!SANDBOX_*}; do
diff --git a/paludis/repositories/e/ebuild/exheres-0/exlib_functions.bash b/paludis/repositories/e/ebuild/exheres-0/exlib_functions.bash
index 2cae338..b750d7c 100644
--- a/paludis/repositories/e/ebuild/exheres-0/exlib_functions.bash
+++ b/paludis/repositories/e/ebuild/exheres-0/exlib_functions.bash
@@ -2,6 +2,7 @@
# vim: set sw=4 sts=4 et :
# Copyright (c) 2007, 2008 Ciaran McCreesh
+# Copyright (c) 2009 Bo Ãrsted Andresen
#
# This file is part of the Paludis package manager. Paludis is free software;
# you can redistribute it and/or modify it under the terms of the GNU General
@@ -29,17 +30,124 @@ export_exlib_phases()
done
}
+exparam()
+{
+ die "exparam is banned outside exlibs"
+}
+
+exparam_var_name()
+{
+ echo EXPARAMVAR_${1//-/__dash__}
+}
+
+exparam_print()
+{
+ case "${1}" in
+ -a) eval "${2}=( \"\${${3}}\" )" ;;
+ -v) eval "${2}=\"\${${3}}\"" ;;
+ *) eval "echo \"\${${1}}\"" ;;
+ esac
+}
+
+exparam_internal()
+{
+ local i e=${1} a to_var v a_v=$(exparam_var_name ${1})__ALLDECLS__
+ shift
+ if [[ ${1} == -[av] ]]; then
+ [[ ${#} -eq 3 ]] || die "exparam ${1} requires exactly three arguments"
+ a=${1}
+ to_var=${2}
+ shift 2
+ else
+ [[ ${#} -eq 1 ]] || die "exparam requires exactly one argument"
+ fi
+ v=$(exparam_var_name ${e})_${1%\[*}
+ if [[ ${1} == *\[*\] ]]; then
+ has "${1%\[*}[]" ${!a_v} || die "${e}.exlib has no ${1%\[*} array"
+ i=${1#*\[}
+ i=${i%\]}
+ case "${i}" in
+ "#") exparam_print ${to_var:+${a} "${to_var}"} "#${v}[*]" ;;
+ "*") exparam_print ${to_var:+${a} "${to_var}"} "${...@]" ;;
+ +([[:digit:]])) exparam_print ${to_var:+${a} "${to_var}"} "${v}[${i}]" ;;
+ *) die "Invalid index in exparam ${1}" ;;
+ esac
+ else
+ has "${1}" ${!a_v%\[\]} || die "${e}.exlib has no ${1} parameter"
+ exparam_print ${to_var:+${a} "${to_var}"} "${v}"
+ fi
+}
+
+myexparam()
+{
+ [[ -z "${CURRENT_EXLIB}" ]] && die "myexparam called but CURRENT_EXLIB undefined"
+
+ local v=${1%%=*} a_v="$(exparam_var_name ${CURRENT_EXLIB})__ALLDECLS__"
+ [[ ${1} == *=\[ && ${#} -gt 1 ]] && v+="[]"
+ printf -v "${a_v}" "%s %s" "${!a_v}" "${v}"
+
+ v=$(exparam_var_name ${CURRENT_EXLIB})_${v%\[\]}
+ if [[ -z ${!v+set} && ${1} == *=* ]]; then
+ if [[ ${1} == *=\[ && ${#} -gt 1 ]]; then
+ shift
+ local i a=()
+ while [[ ${#} -gt 1 ]]; do
+ a+=( "${1}" )
+ shift
+ done
+ [[ ${1} == \] ]] || die "Array encountered with no closing ]"
+ eval "${v}=( \"\$...@]}\" )"
+ else
+ printf -v "${v}" "%s" "${1#*=}"
+ fi
+ fi
+}
+
require()
{
ebuild_notice "debug" "Command 'require $...@}', using EXLIBSDIRS '${EXLIBSDIRS}'"
- local e ee location v v_qa
- for e in "$@" ; do
+ local exlibs e ee p a=() location v a_v v_qa
+ # parse exlib parameters
+ while [[ -n $@ ]]; do
+ if [[ ${1} == +(\[) ]]; then
+ [[ -z ${e} ]] && die "\"${1}\" encountered with no preceding exlib"
+ p=${1}
+ shift
+ while [[ -n ${1} && ${1} != ${p//\[/\]} ]]; do
+ v="${1%%=*}"
+ if [[ ${1#*=} == ${p} ]]; then
+ v+="[]"
+ a=()
+ shift
+ while [[ -n ${1} && ${1} != ${p//\[/\]} ]]; do
+ a+=( "${1}" )
+ shift
+ done
+ [[ ${1} == ${p//\[/\]} ]] || die "\"${p}\" encountered with no closing \"${p//\[/\]}\" for array ${v}"
+ eval "$(exparam_var_name ${e})_${v%\[\]}=( \"\$...@]}\" )"
+ else
+ printf -v "$(exparam_var_name ${e})_${1%%=*}" "%s" "${1#*=}"
+ fi
+ a_v="$(exparam_var_name ${e})__ALL__"
+ printf -v "${a_v}" "%s %s" "${!a_v}" "${v}"
+ shift
+ done
+ [[ ${1} == ${p//\[/\]} ]] || die "\"${p}\" encountered with no closing \"${p//\[/\]}\""
+ else
+ e=${1}
+ exlibs+=" ${e}"
+ fi
+ shift
+ done
+ # source exlibs
+ for e in ${exlibs}; do
location=
for ee in ${EXLIBSDIRS} ; do
[[ -f "${ee}/${e}.exlib" ]] && location="${ee}/${e}.exlib"
done
local old_CURRENT_EXLIB="${CURRENT_EXLIB}"
export CURRENT_EXLIB="${e}"
+ alias exparam="exparam_internal ${CURRENT_EXLIB}"
for v in ${PALUDIS_SOURCE_MERGED_VARIABLES} ${PALUDIS_BRACKET_MERGED_VARIABLES} ; do
local c_v="current_${v}" u_v="unset_${v}"
@@ -88,7 +196,34 @@ require()
fi
done
+ # die on required exlib parameters that haven't been supplied
+ local c_v v
+ a_v=$(exparam_var_name ${CURRENT_EXLIB})__ALLDECLS__
+ for v in ${!a_v}; do
+ c_v=$(exparam_var_name ${CURRENT_EXLIB})_${v%\[\]}
+ if [[ -n ${!c_v+set} ]]; then
+ if [[ $(eval "declare -p ${c_v}") == declare\ -a\ ${c_v}=* ]]; then
+ [[ ${v} == *\[\] ]] || die "${CURRENT_EXLIB}.exlib requires a scalar ${v} parameter but got an array"
+ else
+ [[ ${v} != *\[\] ]] || die "${CURRENT_EXLIB}.exlib requires an array ${v} but got a scalar"
+ fi
+ else
+ die "${CURRENT_EXLIB}.exlib requires a ${v} parameter"
+ fi
+ done
+
+ # die on supplied exlib parameters which haven't been declared
+ v=$(exparam_var_name ${CURRENT_EXLIB})__ALL__
+ for v in ${!v}; do
+ has ${v} ${!a_v} || die "${CURRENT_EXLIB}.exlib takes no ${v} parameter"
+ done
+
export CURRENT_EXLIB="${old_CURRENT_EXLIB}"
+ if [[ -n ${CURRENT_EXLIB} ]]; then
+ alias exparam="exparam_internal ${CURRENT_EXLIB}"
+ else
+ unalias exparam
+ fi
done
}
_______________________________________________
Exherbo-dev mailing list
[email protected]
http://lists.exherbo.org/mailman/listinfo/exherbo-dev