aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2021-04-16 22:04:22 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2021-04-19 18:35:30 +0300
commitf0c4ddcc96ae4eea5e158359bc21f51c3261bdd2 (patch)
treef2d12cb67395a4be2053379958b94d8ec6d333d9
parente4c22fd4b9ba9782acd0c0a10866cbeaf8be694d (diff)
Match package spec local repository locations in pkg-build case-insensitively on Windows
-rw-r--r--bpkg/database.cxx10
-rw-r--r--bpkg/package.hxx10
-rw-r--r--bpkg/package.xml6
-rw-r--r--bpkg/pkg-build.cxx29
-rw-r--r--tests/pkg-build.testscript33
5 files changed, 80 insertions, 8 deletions
diff --git a/bpkg/database.cxx b/bpkg/database.cxx
index 7ba19f0..e355860 100644
--- a/bpkg/database.cxx
+++ b/bpkg/database.cxx
@@ -41,15 +41,21 @@ namespace bpkg
// Register the data migration functions.
//
-#if 0
template <odb::schema_version v>
using migration_entry = odb::data_migration_entry<v, DB_SCHEMA_VERSION_BASE>;
static const migration_entry<8>
migrate_v8 ([] (odb::database& db)
{
+ for (shared_ptr<repository> r: pointer_result (db.query<repository> ()))
+ {
+ if (!r->name.empty ()) // Non-root repository?
+ {
+ r->local = r->location.local ();
+ db.update (r);
+ }
+ }
});
-#endif
database
open (const dir_path& d, tracer& tr, bool create)
diff --git a/bpkg/package.hxx b/bpkg/package.hxx
index e7379b3..ad45fa8 100644
--- a/bpkg/package.hxx
+++ b/bpkg/package.hxx
@@ -27,7 +27,7 @@
//
#define DB_SCHEMA_VERSION_BASE 6
-#pragma db model version(DB_SCHEMA_VERSION_BASE, 7, closed)
+#pragma db model version(DB_SCHEMA_VERSION_BASE, 8, closed)
namespace bpkg
{
@@ -390,11 +390,19 @@ namespace bpkg
optional<string> certificate; // PEM representation.
fragments_type fragments;
+ // While we could potentially calculate this flag on the fly, that would
+ // complicate the database queries significantly.
+ //
+ optional<bool> local; // nullopt for root repository.
+
public:
explicit
repository (repository_location l): location (move (l))
{
name = location.canonical_name ();
+
+ if (!name.empty ()) // Non-root?
+ local = location.local ();
}
// Database mapping.
diff --git a/bpkg/package.xml b/bpkg/package.xml
index 2b94c71..55e3a9a 100644
--- a/bpkg/package.xml
+++ b/bpkg/package.xml
@@ -1,4 +1,10 @@
<changelog xmlns="http://www.codesynthesis.com/xmlns/odb/changelog" database="sqlite" version="1">
+ <changeset version="8">
+ <alter-table name="repository">
+ <add-column name="local" type="INTEGER" null="true"/>
+ </alter-table>
+ </changeset>
+
<changeset version="7">
<alter-table name="available_package_dependencies">
<add-column name="type" type="TEXT" null="true"/>
diff --git a/bpkg/pkg-build.cxx b/bpkg/pkg-build.cxx
index 9d9b384..082696e 100644
--- a/bpkg/pkg-build.cxx
+++ b/bpkg/pkg-build.cxx
@@ -2620,17 +2620,38 @@ namespace bpkg
{
using query = query<repository>;
- auto q (db.query<repository> (query::location.url == l));
- auto i (q.begin ());
+ // For case-insensitive filesystems (Windows) we need to match the
+ // location case-insensitively against the local repository URLs
+ // and case-sensitively against the remote ones.
+ //
+ // Note that the root repository will never be matched, since its
+ // location is empty.
+ //
+ const auto& url (query::location.url);
+
+#ifndef _WIN32
+ query q (url == l);
+#else
+ string u (url.table ());
+ u += '.';
+ u += url.column ();
+
+ query q (
+ (!query::local && url == l) ||
+ ( query::local && u + " COLLATE nocase = " + query::_val (l)));
+#endif
+
+ auto rs (db.query<repository> (q));
+ auto i (rs.begin ());
- if (i != q.end ())
+ if (i != rs.end ())
{
r = i.load ();
// Fallback to parsing the location if several repositories
// match.
//
- if (++i != q.end ())
+ if (++i != rs.end ())
r = nullptr;
}
}
diff --git a/tests/pkg-build.testscript b/tests/pkg-build.testscript
index 6fe5eb9..50db679 100644
--- a/tests/pkg-build.testscript
+++ b/tests/pkg-build.testscript
@@ -159,6 +159,7 @@ pkg_unpack += -d cfg 2>!
rep_add += -d cfg 2>!
rep_remove += -d cfg 2>!
rep_fetch += -d cfg --auth all --trust-yes 2>!
+rep_list += -d cfg
# Let's disable the progress indication that complicates stderr output
# validation.
@@ -3757,7 +3758,7 @@ test.options += --no-progress
}
}
-: ignore-case
+: ignore-case-pkg
:
{
test.arguments += --yes --auth all --trust-yes
@@ -3792,6 +3793,36 @@ test.options += --no-progress
$pkg_drop libbar
}
+: ignore-case-rep
+:
+: Test that package spec local repository location is matched
+: case-insensitively on Windows.
+:
+if (!$remote && !$posix)
+{
+ $clone_cfg;
+
+ $* "libbar@$rep/t5" 2>>~%EOE%;
+ added pkg:build2.org/pkg-build/t5
+ fetching pkg:build2.org/pkg-build/t5
+ fetched libbar/1.2.0
+ unpacked libbar/1.2.0
+ configured libbar/1.2.0
+ %info: .+ is up to date%
+ updated libbar/1.2.0
+ EOE
+
+ $* "libbar@$rep/T5" 2>>~%EOE%;
+ fetching pkg:build2.org/pkg-build/t5
+ %info: .+ is up to date%
+ updated libbar/1.2.0
+ EOE
+
+ $rep_list >~'%pkg:build2\.org/pkg-build/t5 .+t5%';
+
+ $pkg_drop libbar
+}
+
: git-rep
:
if! $git_supported