aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bpkg/build-options.cli5
-rw-r--r--bpkg/build.cxx121
-rw-r--r--bpkg/rep-info-options.cli3
-rwxr-xr-xbpkg/test.sh280
-rw-r--r--tests/repository/1/satisfy/libbar-1.0.0.tar.gzbin0 -> 356 bytes
-rw-r--r--tests/repository/1/satisfy/libbar-1.1.0.tar.gzbin0 -> 360 bytes
-rw-r--r--tests/repository/1/satisfy/libbaz-1.0.0.tar.gzbin0 -> 359 bytes
-rw-r--r--tests/repository/1/satisfy/libbaz-1.1.0.tar.gzbin0 -> 363 bytes
-rw-r--r--tests/repository/1/satisfy/libfoo-0.0.0.tar.gzbin0 -> 348 bytes
-rw-r--r--tests/repository/1/satisfy/libfoo-1.0.0.tar.gzbin0 -> 348 bytes
-rw-r--r--tests/repository/1/satisfy/libfoo-1.1.0.tar.gzbin0 -> 349 bytes
-rw-r--r--tests/repository/1/satisfy/libfoo-1.1.0/build/bootstrap.build2
-rw-r--r--tests/repository/1/satisfy/libfoo-1.1.0/buildfile1
-rw-r--r--tests/repository/1/satisfy/libfoo-1.1.0/manifest7
-rw-r--r--tests/repository/1/satisfy/libfoo-1.2.0.tar.gzbin0 -> 350 bytes
-rw-r--r--tests/repository/1/satisfy/libfox-1.0.0.tar.gzbin0 -> 349 bytes
-rw-r--r--tests/repository/1/satisfy/repositories1
l---------tests/repository/1/satisfy/t1/libfoo-1.0.0.tar.gz1
l---------tests/repository/1/satisfy/t1/repositories1
l---------tests/repository/1/satisfy/t2/libbar-1.0.0.tar.gz1
l---------tests/repository/1/satisfy/t2/libfoo-1.0.0.tar.gz1
l---------tests/repository/1/satisfy/t2/repositories1
l---------tests/repository/1/satisfy/t3/libbaz-1.0.0.tar.gz1
l---------tests/repository/1/satisfy/t3/libfox-1.0.0.tar.gz1
-rw-r--r--tests/repository/1/satisfy/t3/repositories4
l---------tests/repository/1/satisfy/t4a/libfoo-1.1.0.tar.gz1
l---------tests/repository/1/satisfy/t4a/repositories1
l---------tests/repository/1/satisfy/t4b/libbar-1.1.0.tar.gz1
-rw-r--r--tests/repository/1/satisfy/t4b/repositories3
l---------tests/repository/1/satisfy/t4c/libbaz-1.1.0.tar.gz1
l---------tests/repository/1/satisfy/t4c/libfoo-1.0.0.tar.gz1
-rw-r--r--tests/repository/1/satisfy/t4c/repositories3
32 files changed, 409 insertions, 33 deletions
diff --git a/bpkg/build-options.cli b/bpkg/build-options.cli
index 9782f95..1a8c035 100644
--- a/bpkg/build-options.cli
+++ b/bpkg/build-options.cli
@@ -29,5 +29,10 @@ namespace bpkg
{
class build_options: configuration_options
{
+ bool --print-only|-p
+ {
+ "Print to \cb{STDOUT} what would be done without actually doing
+ anything."
+ };
};
}
diff --git a/bpkg/build.cxx b/bpkg/build.cxx
index a518000..b91609d 100644
--- a/bpkg/build.cxx
+++ b/bpkg/build.cxx
@@ -7,6 +7,7 @@
#include <map>
#include <list>
#include <iterator> // make_move_iterator()
+#include <iostream> // cout
#include <functional> // reference_wrapper
#include <butl/utility> // reverse_iterate()
@@ -88,6 +89,7 @@ namespace bpkg
//
std::pair<shared_ptr<available_package>, shared_ptr<repository>>
make_available (const common_options& options,
+ const dir_path& cd,
database& db,
const shared_ptr<selected_package>& sp)
{
@@ -102,12 +104,15 @@ namespace bpkg
// The package is in at least fetched state, which means we should
// be able to get its manifest.
//
- shared_ptr<available_package> ap (make_shared<available_package> (
+ const optional<path>& a (sp->archive);
+ const optional<dir_path>& d (sp->src_root);
+
+ package_manifest m (
sp->state == package_state::fetched
- ? pkg_verify (options, *sp->archive)
- : pkg_verify (*sp->src_root)));
+ ? pkg_verify (options, a->absolute () ? *a : cd / *a)
+ : pkg_verify (d->absolute () ? *d : cd / *d));
- return make_pair (move (ap), move (ar));
+ return make_pair (make_shared<available_package> (move (m)), move (ar));
}
// A "dependency-ordered" list of packages and their prerequisites.
@@ -191,9 +196,12 @@ namespace bpkg
//
bool
collect (const common_options& options,
+ const dir_path& cd,
database& db,
satisfied_package&& pkg)
{
+ tracer trace ("collect");
+
auto i (map_.find (pkg.available->id.name));
// If we already have an entry for this package name, then we
@@ -201,6 +209,8 @@ namespace bpkg
//
if (i != map_.end ())
{
+ const string& n (i->first);
+
// At the end we want p1 to point to the object that we keep
// and p2 to the object whose constraints we should copy.
//
@@ -244,11 +254,10 @@ namespace bpkg
//
if (auto c1 = test (p2, p1))
{
- const string& n (i->first);
const string& d1 (c1->dependent);
const string& d2 (c2->dependent);
- fail << "unable to satisfy package " << n << " constraints" <<
+ fail << "unable to satisfy constraints on package " << n <<
info << d1 << " depends on (" << n << " " << c1->value << ")" <<
info << d2 << " depends on (" << n << " " << c2->value << ")" <<
info << "available " << n << " " << p1->available->version <<
@@ -259,6 +268,9 @@ namespace bpkg
else
swap (p1, p2);
}
+
+ level4 ([&]{trace << "pick " << n << " " << p1->available->version
+ << " over " << p2->available->version;});
}
// See if we are replacing the object. If not, then we don't
@@ -285,6 +297,8 @@ namespace bpkg
{
string n (pkg.available->id.name); // Note: copy; see emplace() below.
+ level4 ([&]{trace << "add " << n << " " << pkg.available->version;});
+
// This is the first time we are adding this package name to the
// map. If it is already selected, then we need to make sure that
// packages that already depend on it (called dependents) are ok
@@ -401,7 +415,7 @@ namespace bpkg
info << "use 'pkg-purge --force' to remove";
if (satisfies (dsp->version, d.constraint))
- rp = make_available (options, db, dsp);
+ rp = make_available (options, cd, db, dsp);
else
// Remember that we may be forcing up/downgrade; we will deal
// with it below.
@@ -420,17 +434,21 @@ namespace bpkg
// (i.e., it wasn't already there) and we are forcing an upgrade,
// then warn. Downgrade -- outright refuse.
//
- if (collect (options, db, move (dp)) && force)
+ if (collect (options, cd, db, move (dp)) && force)
{
const version& v (rp.first->version);
- if (v > dsp->version)
- warn << "package " << name << " dependency " << d << " is forcing "
- << "upgrade of " << d.name << " to " << v;
- else
- fail << "package " << name << " dependency " << d << " is forcing "
- << "downgrade of " << d.name << " to " << v <<
- info << "explicitly request downgraded version to continue";
+ bool u (v > dsp->version);
+ bool c (d.constraint);
+ diag_record dr;
+
+ (u ? dr << warn : dr << fail)
+ << "package " << name << " dependency on "
+ << (c ? "(" : "") << d << (c ? ")" : "") << " is forcing "
+ << (u ? "up" : "down") << "grade of " << d.name << " to " << v;
+
+ if (!u)
+ dr << info << "explicitly specify version downgrade to continue";
}
}
@@ -438,10 +456,11 @@ namespace bpkg
}
// Order the previously-collected package with the specified name
- // returning its positions.
+ // returning its positions. If reorder is true, then reorder this
+ // package to be considered as "early" as possible.
//
iterator
- order (const string& name)
+ order (const string& name, bool reorder = true)
{
// Every package that we order should have already be collected.
//
@@ -450,10 +469,16 @@ namespace bpkg
// If this package is already in the list, then that would also
// mean all its prerequisites are in the list and we can just
- // return its position.
+ // return its position. Unless we want it reordered.
//
- if (mi->second.position != list_.end ())
- return mi->second.position;
+ iterator& pos (mi->second.position);
+ if (pos != list_.end ())
+ {
+ if (reorder)
+ list_.erase (pos);
+ else
+ return pos;
+ }
const satisfied_package& p (mi->second.package);
@@ -471,12 +496,18 @@ namespace bpkg
p.selected->version != p.available->version ||
p.selected->state != package_state::configured)
{
- for (const dependency_alternatives& da: p.available->dependencies)
+ // We are iterating in reverse so that when we iterate over
+ // the dependency list (also in reverse), prerequisites will
+ // be built in the order that is as close to the manifest as
+ // possible.
+ //
+ for (const dependency_alternatives& da:
+ reverse_iterate (p.available->dependencies))
{
assert (!da.conditional && da.size () == 1); // @@ TODO
const dependency& d (da.front ());
- iterator j (order (d.name));
+ iterator j (order (d.name, false));
// Figure out if j is before i, in which case set i to j. The
// goal here is to find the position of our first prerequisite.
@@ -487,7 +518,7 @@ namespace bpkg
}
}
- return mi->second.position = list_.insert (i, p);
+ return pos = list_.insert (i, p);
}
private:
@@ -630,6 +661,8 @@ namespace bpkg
fail << "unable to build broken package " << n <<
info << "use 'pkg-purge --force' to remove";
+ bool found (true);
+
// If the user asked for a specific version, then that's what
// we ought to be building.
//
@@ -646,7 +679,8 @@ namespace bpkg
if (sp != nullptr && sp->version == v)
break; // Derive ap from sp below.
- fail << "unknown package " << n << " " << v;
+ found = false;
+ break;
}
}
//
@@ -667,12 +701,30 @@ namespace bpkg
else
{
if (sp == nullptr)
- fail << "unknown package " << n;
+ found = false;
- // Derive ap from sp below.
+ // Otherwise, derive ap from sp below.
}
}
+ if (!found)
+ {
+ diag_record dr;
+
+ dr << fail << "unknown package " << n;
+ if (!v.empty ())
+ dr << " " << v;
+
+ // Let's help the new user out here a bit.
+ //
+ if (db.query_value<repository_count> () == 0)
+ dr << info << "configuration " << c << " has no repositories"
+ << info << "use 'bpkg rep-add' to add a repository";
+ else if (db.query_value<available_package_count> () == 0)
+ dr << info << "configuration " << c << " has no available packages"
+ << info << "use 'bpkg rep-fetch' to fetch available packages list";
+ }
+
// If the available_package object is still NULL, then it means
// we need to get one corresponding to the selected package.
//
@@ -680,7 +732,7 @@ namespace bpkg
{
assert (sp != nullptr);
- auto rp (make_available (o, db, sp));
+ auto rp (make_available (o, c, db, sp));
ap = rp.first;
ar = rp.second; // Could be NULL (orphan).
}
@@ -695,10 +747,10 @@ namespace bpkg
//
if (!v.empty ())
p.constraints.emplace_back (
- "<command line>",
+ "command line",
dependency_constraint {comparison::eq, v});
- pkgs.collect (o, db, move (p));
+ pkgs.collect (o, c, db, move (p));
names.push_back (n);
}
@@ -731,7 +783,16 @@ namespace bpkg
else
a = sp->version < ap->version ? "upgrade" : "downgrade";
- text << a << " " << ap->id.name << " " << ap->version;
+ if (o.print_only ())
+ cout << a << " " << ap->id.name << " " << ap->version << endl;
+ else
+ text << a << " " << ap->id.name << " " << ap->version;
+ }
+
+ if (o.print_only ())
+ {
+ t.commit ();
+ return;
}
t.commit ();
diff --git a/bpkg/rep-info-options.cli b/bpkg/rep-info-options.cli
index 2d3aa33..6af380f 100644
--- a/bpkg/rep-info-options.cli
+++ b/bpkg/rep-info-options.cli
@@ -18,7 +18,8 @@ The \cb{rep-info} command prints information about the specified repository.
By default it print the repository's name and location as the first line
followed by the list of prerequisite/complement repositories and the list
of available packages. This default behavior, however, can be altered in
-various ways using options listed below."
+various ways using options listed below. Note that the information is
+written to \cb{STDOUT}, not \cb{STDERR}."
*/
namespace bpkg
diff --git a/bpkg/test.sh b/bpkg/test.sh
index 4b2db6f..815fc89 100755
--- a/bpkg/test.sh
+++ b/bpkg/test.sh
@@ -29,7 +29,14 @@ function test ()
ops="-d $cfg"
fi
- $bpkg $cmd $ops $*
+ if [ -t 0 ]; then
+ $bpkg $cmd $ops $*
+ else
+ # There is no way to get the exit code in process substiution
+ # so spoil the output.
+ #
+ diff -u - <($bpkg $cmd $ops $* || echo "<invalid output>")
+ fi
if [ $? -ne 0 ]; then
error "failed: $bpkg $cmd $ops $*"
@@ -84,6 +91,8 @@ function gone ()
fi
}
+if false; then
+
##
## rep-create
##
@@ -584,7 +593,7 @@ test pkg-disfigure $pkg
test pkg-purge $pkg
##
-## Scenarios.
+## Low-level command scenarios.
##
# build package from remote repository
@@ -599,3 +608,270 @@ test pkg-update $pkg
test pkg-clean $pkg
test pkg-disfigure $pkg
test pkg-purge $pkg
+
+##
+## High-level commands.
+##
+
+fi
+
+##
+## build
+##
+
+# 1
+#
+test rep-create ../tests/repository/1/satisfy/t1
+test cfg-create --wipe
+
+fail build -p # package name expected
+fail build -p libfoo # unknown package
+fail build -p libfoo/1.0.0 # unknown package
+test build -p ../tests/repository/1/satisfy/libfoo-1.1.0.tar.gz <<EOF
+build libfoo 1.1.0
+EOF
+test build -p ../tests/repository/1/satisfy/libfoo-1.1.0 <<EOF
+build libfoo 1.1.0
+EOF
+
+test pkg-unpack -e ../tests/repository/1/satisfy/libfoo-1.1.0
+test build -p libfoo <<< "build libfoo 1.1.0"
+test build -p libfoo/1.1.0 <<< "build libfoo 1.1.0"
+test build -p libfoo libfoo <<< "build libfoo 1.1.0"
+test build -p libfoo libfoo/1.1.0 <<< "build libfoo 1.1.0"
+test build -p libfoo/1.1.0 libfoo <<< "build libfoo 1.1.0"
+test build -p libfoo/1.1.0 libfoo/1.1.0 <<< "build libfoo 1.1.0"
+fail build -p libfoo/1.0.0
+test pkg-purge libfoo
+
+test rep-add ../tests/repository/1/satisfy/t1
+test rep-fetch
+test build -p libfoo <<< "build libfoo 1.0.0"
+test build -p libfoo/1.0.0 <<< "build libfoo 1.0.0"
+test build -p libfoo libfoo <<< "build libfoo 1.0.0"
+test build -p libfoo libfoo/1.0.0 <<< "build libfoo 1.0.0"
+test build -p libfoo/1.0.0 libfoo <<< "build libfoo 1.0.0"
+test build -p libfoo/1.0.0 libfoo/1.0.0 <<< "build libfoo 1.0.0"
+fail build -p libfoo/1.1.0
+
+test pkg-unpack -e ../tests/repository/1/satisfy/libfoo-1.1.0
+test build -p libfoo <<< "build libfoo 1.1.0"
+test build -p libfoo/1.0.0 <<< "downgrade libfoo 1.0.0"
+fail build -p libfoo/0.0.0
+test pkg-purge libfoo
+
+test pkg-fetch -e ../tests/repository/1/satisfy/libfoo-0.0.0.tar.gz
+test pkg-unpack libfoo
+test build -p libfoo <<< "upgrade libfoo 1.0.0"
+test build -p libfoo/0.0.0 <<< "build libfoo 0.0.0"
+fail build -p libfoo/1.1.0
+test pkg-purge libfoo
+
+# 2 (libbar depends on libfoo)
+#
+test rep-create ../tests/repository/1/satisfy/t2
+test cfg-create --wipe
+test rep-add ../tests/repository/1/satisfy/t2
+test rep-fetch
+
+test build -p libbar <<EOF
+build libfoo 1.0.0
+build libbar 1.0.0
+EOF
+test build -p libbar libfoo <<EOF
+build libfoo 1.0.0
+build libbar 1.0.0
+EOF
+test build -p libbar libfoo/1.0.0 <<EOF
+build libfoo 1.0.0
+build libbar 1.0.0
+EOF
+test build -p libbar libfoo libbar/1.0.0 <<EOF
+build libfoo 1.0.0
+build libbar 1.0.0
+EOF
+fail build -p libbar libfoo/1.1.0
+
+test pkg-fetch -e ../tests/repository/1/satisfy/libfoo-0.0.0.tar.gz
+test pkg-unpack libfoo
+test build -p libbar <<EOF
+build libfoo 0.0.0
+build libbar 1.0.0
+EOF
+test build -p libbar libfoo <<EOF
+upgrade libfoo 1.0.0
+build libbar 1.0.0
+EOF
+test build -p libbar libfoo/0.0.0 <<EOF
+build libfoo 0.0.0
+build libbar 1.0.0
+EOF
+test pkg-purge libfoo
+
+test pkg-unpack -e ../tests/repository/1/satisfy/libfoo-1.1.0
+test build -p libbar <<EOF
+build libfoo 1.1.0
+build libbar 1.0.0
+EOF
+test build -p libbar libfoo <<EOF
+build libfoo 1.1.0
+build libbar 1.0.0
+EOF
+test build -p libbar libfoo/1.0.0 <<EOF
+downgrade libfoo 1.0.0
+build libbar 1.0.0
+EOF
+test pkg-purge libfoo
+
+# 3 (libbaz depends on libbar; libbar in prerequisite repository)
+#
+test rep-create ../tests/repository/1/satisfy/t3
+test cfg-create --wipe
+test rep-add ../tests/repository/1/satisfy/t3
+test rep-fetch
+
+# only in prerequisite repository
+#
+fail build -p libfoo
+fail build -p libbar
+fail build -p libbaz libbar
+
+test build -p libbaz <<EOF
+build libfoo 1.0.0
+build libbar 1.0.0
+build libbaz 1.0.0
+EOF
+
+test rep-add ../tests/repository/1/satisfy/t2
+test rep-fetch
+
+# order
+#
+test build -p libfox libfoo <<EOF
+build libfox 1.0.0
+build libfoo 1.0.0
+EOF
+
+test build -p libfoo libfox <<EOF
+build libfoo 1.0.0
+build libfox 1.0.0
+EOF
+
+test build -p libbaz libfoo <<EOF
+build libfoo 1.0.0
+build libbar 1.0.0
+build libbaz 1.0.0
+EOF
+
+test build -p libfoo libbaz <<EOF
+build libfoo 1.0.0
+build libbar 1.0.0
+build libbaz 1.0.0
+EOF
+
+test build -p libbaz libfox <<EOF
+build libfoo 1.0.0
+build libbar 1.0.0
+build libbaz 1.0.0
+build libfox 1.0.0
+EOF
+
+test build -p libfox libbaz <<EOF
+build libfox 1.0.0
+build libfoo 1.0.0
+build libbar 1.0.0
+build libbaz 1.0.0
+EOF
+
+test build -p libfox libfoo libbaz <<EOF
+build libfox 1.0.0
+build libfoo 1.0.0
+build libbar 1.0.0
+build libbaz 1.0.0
+EOF
+
+test build -p libfox libbaz libfoo <<EOF
+build libfox 1.0.0
+build libfoo 1.0.0
+build libbar 1.0.0
+build libbaz 1.0.0
+EOF
+
+test build -p libfoo libfox libbaz <<EOF
+build libfoo 1.0.0
+build libfox 1.0.0
+build libbar 1.0.0
+build libbaz 1.0.0
+EOF
+
+test build -p libfoo libbaz libfox <<EOF
+build libfoo 1.0.0
+build libbar 1.0.0
+build libbaz 1.0.0
+build libfox 1.0.0
+EOF
+
+# this one is contradictory: baz before fox but fox before foo
+#
+test build -p libbaz libfox libfoo <<EOF
+build libfox 1.0.0
+build libfoo 1.0.0
+build libbar 1.0.0
+build libbaz 1.0.0
+EOF
+
+test build -p libbaz libfoo libfox <<EOF
+build libfoo 1.0.0
+build libbar 1.0.0
+build libbaz 1.0.0
+build libfox 1.0.0
+EOF
+
+# 4 (libbaz depends on libfoo and libbar; libbar depends on libfoo >= 1.1.0)
+#
+test rep-create ../tests/repository/1/satisfy/t4a
+test rep-create ../tests/repository/1/satisfy/t4b
+test rep-create ../tests/repository/1/satisfy/t4c
+test cfg-create --wipe
+test rep-add ../tests/repository/1/satisfy/t4c
+test rep-fetch
+
+test build -p libbaz <<EOF
+build libfoo 1.1.0
+build libbar 1.1.0
+build libbaz 1.1.0
+EOF
+
+test build -p libfoo libbaz <<EOF
+build libfoo 1.1.0
+build libbar 1.1.0
+build libbaz 1.1.0
+EOF
+
+fail build -p libfoo/1.0.0 libbaz
+fail build -p libfoo/1.1.0 libbaz
+
+# upgrade warning
+#
+test pkg-fetch -e ../tests/repository/1/satisfy/libfoo-0.0.0.tar.gz
+test pkg-unpack libfoo
+test build -p libbaz <<EOF
+upgrade libfoo 1.1.0
+build libbar 1.1.0
+build libbaz 1.1.0
+EOF
+test pkg-purge libfoo
+
+# downgrade error
+#
+test pkg-fetch -e ../tests/repository/1/satisfy/libfoo-1.2.0.tar.gz
+test pkg-unpack libfoo
+fail build -p libbaz
+test rep-add ../tests/repository/1/satisfy/t4a
+test rep-fetch
+test build -p libfoo/1.1.0 libbaz <<EOF
+downgrade libfoo 1.1.0
+build libbar 1.1.0
+build libbaz 1.1.0
+EOF
+test pkg-purge libfoo
diff --git a/tests/repository/1/satisfy/libbar-1.0.0.tar.gz b/tests/repository/1/satisfy/libbar-1.0.0.tar.gz
new file mode 100644
index 0000000..5dc3a9b
--- /dev/null
+++ b/tests/repository/1/satisfy/libbar-1.0.0.tar.gz
Binary files differ
diff --git a/tests/repository/1/satisfy/libbar-1.1.0.tar.gz b/tests/repository/1/satisfy/libbar-1.1.0.tar.gz
new file mode 100644
index 0000000..881292e
--- /dev/null
+++ b/tests/repository/1/satisfy/libbar-1.1.0.tar.gz
Binary files differ
diff --git a/tests/repository/1/satisfy/libbaz-1.0.0.tar.gz b/tests/repository/1/satisfy/libbaz-1.0.0.tar.gz
new file mode 100644
index 0000000..1de32b2
--- /dev/null
+++ b/tests/repository/1/satisfy/libbaz-1.0.0.tar.gz
Binary files differ
diff --git a/tests/repository/1/satisfy/libbaz-1.1.0.tar.gz b/tests/repository/1/satisfy/libbaz-1.1.0.tar.gz
new file mode 100644
index 0000000..1aa72a8
--- /dev/null
+++ b/tests/repository/1/satisfy/libbaz-1.1.0.tar.gz
Binary files differ
diff --git a/tests/repository/1/satisfy/libfoo-0.0.0.tar.gz b/tests/repository/1/satisfy/libfoo-0.0.0.tar.gz
new file mode 100644
index 0000000..befd2a4
--- /dev/null
+++ b/tests/repository/1/satisfy/libfoo-0.0.0.tar.gz
Binary files differ
diff --git a/tests/repository/1/satisfy/libfoo-1.0.0.tar.gz b/tests/repository/1/satisfy/libfoo-1.0.0.tar.gz
new file mode 100644
index 0000000..28a6a90
--- /dev/null
+++ b/tests/repository/1/satisfy/libfoo-1.0.0.tar.gz
Binary files differ
diff --git a/tests/repository/1/satisfy/libfoo-1.1.0.tar.gz b/tests/repository/1/satisfy/libfoo-1.1.0.tar.gz
new file mode 100644
index 0000000..e03481f
--- /dev/null
+++ b/tests/repository/1/satisfy/libfoo-1.1.0.tar.gz
Binary files differ
diff --git a/tests/repository/1/satisfy/libfoo-1.1.0/build/bootstrap.build b/tests/repository/1/satisfy/libfoo-1.1.0/build/bootstrap.build
new file mode 100644
index 0000000..eb90fee
--- /dev/null
+++ b/tests/repository/1/satisfy/libfoo-1.1.0/build/bootstrap.build
@@ -0,0 +1,2 @@
+project = libfoo
+using config
diff --git a/tests/repository/1/satisfy/libfoo-1.1.0/buildfile b/tests/repository/1/satisfy/libfoo-1.1.0/buildfile
new file mode 100644
index 0000000..b3ec74f
--- /dev/null
+++ b/tests/repository/1/satisfy/libfoo-1.1.0/buildfile
@@ -0,0 +1 @@
+.:
diff --git a/tests/repository/1/satisfy/libfoo-1.1.0/manifest b/tests/repository/1/satisfy/libfoo-1.1.0/manifest
new file mode 100644
index 0000000..3453757
--- /dev/null
+++ b/tests/repository/1/satisfy/libfoo-1.1.0/manifest
@@ -0,0 +1,7 @@
+: 1
+name: libfoo
+version: 1.1.0
+summary: libfoo
+license: MIT
+url: http://example.org
+email: pkg@example.org
diff --git a/tests/repository/1/satisfy/libfoo-1.2.0.tar.gz b/tests/repository/1/satisfy/libfoo-1.2.0.tar.gz
new file mode 100644
index 0000000..80ce03b
--- /dev/null
+++ b/tests/repository/1/satisfy/libfoo-1.2.0.tar.gz
Binary files differ
diff --git a/tests/repository/1/satisfy/libfox-1.0.0.tar.gz b/tests/repository/1/satisfy/libfox-1.0.0.tar.gz
new file mode 100644
index 0000000..9ba7a31
--- /dev/null
+++ b/tests/repository/1/satisfy/libfox-1.0.0.tar.gz
Binary files differ
diff --git a/tests/repository/1/satisfy/repositories b/tests/repository/1/satisfy/repositories
new file mode 100644
index 0000000..5b70556
--- /dev/null
+++ b/tests/repository/1/satisfy/repositories
@@ -0,0 +1 @@
+: 1
diff --git a/tests/repository/1/satisfy/t1/libfoo-1.0.0.tar.gz b/tests/repository/1/satisfy/t1/libfoo-1.0.0.tar.gz
new file mode 120000
index 0000000..32e5a3c
--- /dev/null
+++ b/tests/repository/1/satisfy/t1/libfoo-1.0.0.tar.gz
@@ -0,0 +1 @@
+../libfoo-1.0.0.tar.gz \ No newline at end of file
diff --git a/tests/repository/1/satisfy/t1/repositories b/tests/repository/1/satisfy/t1/repositories
new file mode 120000
index 0000000..d965b15
--- /dev/null
+++ b/tests/repository/1/satisfy/t1/repositories
@@ -0,0 +1 @@
+../repositories \ No newline at end of file
diff --git a/tests/repository/1/satisfy/t2/libbar-1.0.0.tar.gz b/tests/repository/1/satisfy/t2/libbar-1.0.0.tar.gz
new file mode 120000
index 0000000..93e8c71
--- /dev/null
+++ b/tests/repository/1/satisfy/t2/libbar-1.0.0.tar.gz
@@ -0,0 +1 @@
+../libbar-1.0.0.tar.gz \ No newline at end of file
diff --git a/tests/repository/1/satisfy/t2/libfoo-1.0.0.tar.gz b/tests/repository/1/satisfy/t2/libfoo-1.0.0.tar.gz
new file mode 120000
index 0000000..32e5a3c
--- /dev/null
+++ b/tests/repository/1/satisfy/t2/libfoo-1.0.0.tar.gz
@@ -0,0 +1 @@
+../libfoo-1.0.0.tar.gz \ No newline at end of file
diff --git a/tests/repository/1/satisfy/t2/repositories b/tests/repository/1/satisfy/t2/repositories
new file mode 120000
index 0000000..d965b15
--- /dev/null
+++ b/tests/repository/1/satisfy/t2/repositories
@@ -0,0 +1 @@
+../repositories \ No newline at end of file
diff --git a/tests/repository/1/satisfy/t3/libbaz-1.0.0.tar.gz b/tests/repository/1/satisfy/t3/libbaz-1.0.0.tar.gz
new file mode 120000
index 0000000..189242a
--- /dev/null
+++ b/tests/repository/1/satisfy/t3/libbaz-1.0.0.tar.gz
@@ -0,0 +1 @@
+../libbaz-1.0.0.tar.gz \ No newline at end of file
diff --git a/tests/repository/1/satisfy/t3/libfox-1.0.0.tar.gz b/tests/repository/1/satisfy/t3/libfox-1.0.0.tar.gz
new file mode 120000
index 0000000..dcfd7aa
--- /dev/null
+++ b/tests/repository/1/satisfy/t3/libfox-1.0.0.tar.gz
@@ -0,0 +1 @@
+../libfox-1.0.0.tar.gz \ No newline at end of file
diff --git a/tests/repository/1/satisfy/t3/repositories b/tests/repository/1/satisfy/t3/repositories
new file mode 100644
index 0000000..d65b272
--- /dev/null
+++ b/tests/repository/1/satisfy/t3/repositories
@@ -0,0 +1,4 @@
+: 1
+location: ../t2
+:
+
diff --git a/tests/repository/1/satisfy/t4a/libfoo-1.1.0.tar.gz b/tests/repository/1/satisfy/t4a/libfoo-1.1.0.tar.gz
new file mode 120000
index 0000000..c004b2a
--- /dev/null
+++ b/tests/repository/1/satisfy/t4a/libfoo-1.1.0.tar.gz
@@ -0,0 +1 @@
+../libfoo-1.1.0.tar.gz \ No newline at end of file
diff --git a/tests/repository/1/satisfy/t4a/repositories b/tests/repository/1/satisfy/t4a/repositories
new file mode 120000
index 0000000..d965b15
--- /dev/null
+++ b/tests/repository/1/satisfy/t4a/repositories
@@ -0,0 +1 @@
+../repositories \ No newline at end of file
diff --git a/tests/repository/1/satisfy/t4b/libbar-1.1.0.tar.gz b/tests/repository/1/satisfy/t4b/libbar-1.1.0.tar.gz
new file mode 120000
index 0000000..b9a2de5
--- /dev/null
+++ b/tests/repository/1/satisfy/t4b/libbar-1.1.0.tar.gz
@@ -0,0 +1 @@
+../libbar-1.1.0.tar.gz \ No newline at end of file
diff --git a/tests/repository/1/satisfy/t4b/repositories b/tests/repository/1/satisfy/t4b/repositories
new file mode 100644
index 0000000..7b85e71
--- /dev/null
+++ b/tests/repository/1/satisfy/t4b/repositories
@@ -0,0 +1,3 @@
+: 1
+location: ../t4a
+:
diff --git a/tests/repository/1/satisfy/t4c/libbaz-1.1.0.tar.gz b/tests/repository/1/satisfy/t4c/libbaz-1.1.0.tar.gz
new file mode 120000
index 0000000..0edbce7
--- /dev/null
+++ b/tests/repository/1/satisfy/t4c/libbaz-1.1.0.tar.gz
@@ -0,0 +1 @@
+../libbaz-1.1.0.tar.gz \ No newline at end of file
diff --git a/tests/repository/1/satisfy/t4c/libfoo-1.0.0.tar.gz b/tests/repository/1/satisfy/t4c/libfoo-1.0.0.tar.gz
new file mode 120000
index 0000000..32e5a3c
--- /dev/null
+++ b/tests/repository/1/satisfy/t4c/libfoo-1.0.0.tar.gz
@@ -0,0 +1 @@
+../libfoo-1.0.0.tar.gz \ No newline at end of file
diff --git a/tests/repository/1/satisfy/t4c/repositories b/tests/repository/1/satisfy/t4c/repositories
new file mode 100644
index 0000000..26c0e93
--- /dev/null
+++ b/tests/repository/1/satisfy/t4c/repositories
@@ -0,0 +1,3 @@
+: 1
+location: ../t4b
+: